summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-10-05 07:41:50 +0200
committerMax Kellermann <max@duempel.org>2014-10-05 07:41:50 +0200
commitb1a252a64d39d17618d2d00ac341684b6f290ef6 (patch)
tree10eff9b871e5bf9a6a7b8934ada5cf8a23920218 /src
parentfb90b64bac49d6efadc2db021cf0fbf65c9d66a6 (diff)
lib/nfs/Base: kludge to reduce number of NFS mounts
Creating a NfsStorage sets its own export_name as the "base". Now NfsFileReader can use this information to derive the export_name to be mounted, instead of guessing. This solves the "too many connection" problem on the NFS server while updating the database.
Diffstat (limited to 'src')
-rw-r--r--src/lib/nfs/Base.cxx61
-rw-r--r--src/lib/nfs/Base.hxx46
-rw-r--r--src/lib/nfs/FileReader.cxx24
-rw-r--r--src/storage/plugins/NfsStorage.cxx3
4 files changed, 127 insertions, 7 deletions
diff --git a/src/lib/nfs/Base.cxx b/src/lib/nfs/Base.cxx
new file mode 100644
index 000000000..3004cd11b
--- /dev/null
+++ b/src/lib/nfs/Base.cxx
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "Base.hxx"
+
+#include <assert.h>
+#include <string.h>
+
+static char nfs_base_server[64];
+static char nfs_base_export_name[256];
+static size_t nfs_base_export_name_length;
+
+void
+nfs_set_base(const char *server, const char *export_name)
+{
+ assert(server != nullptr);
+ assert(export_name != nullptr);
+
+ const size_t server_length = strlen(server);
+ const size_t export_name_length = strlen(export_name);
+
+ if (server_length >= sizeof(nfs_base_server) ||
+ export_name_length > sizeof(nfs_base_export_name))
+ return;
+
+ memcpy(nfs_base_server, server, server_length + 1);
+ memcpy(nfs_base_export_name, export_name, export_name_length);
+ nfs_base_export_name_length = export_name_length;
+}
+
+const char *
+nfs_check_base(const char *server, const char *path)
+{
+ assert(server != nullptr);
+ assert(path != nullptr);
+
+ return strcmp(nfs_base_server, server) == 0 &&
+ memcmp(nfs_base_export_name, path,
+ nfs_base_export_name_length) == 0 &&
+ (path[nfs_base_export_name_length] == 0 ||
+ path[nfs_base_export_name_length] == '/')
+ ? path + nfs_base_export_name_length
+ : nullptr;
+}
diff --git a/src/lib/nfs/Base.hxx b/src/lib/nfs/Base.hxx
new file mode 100644
index 000000000..3a92a86d3
--- /dev/null
+++ b/src/lib/nfs/Base.hxx
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_NFS_BASE_HXX
+#define MPD_NFS_BASE_HXX
+
+#include "check.h"
+#include "Compiler.h"
+
+/**
+ * Set the "base" NFS server and export name. This will be the
+ * default export that will be mounted if a file within this export is
+ * being opened, instead of guessing the mount point.
+ *
+ * This is a kludge that is not truly thread-safe.
+ */
+void
+nfs_set_base(const char *server, const char *export_name);
+
+/**
+ * Check if the given server and path are inside the "base"
+ * server/export_name. If yes, then a pointer to the portion of
+ * "path" after the export_name is returned; otherwise, nullptr is
+ * returned.
+ */
+gcc_pure
+const char *
+nfs_check_base(const char *server, const char *path);
+
+#endif
diff --git a/src/lib/nfs/FileReader.cxx b/src/lib/nfs/FileReader.cxx
index d2be46f8e..4837e1f0e 100644
--- a/src/lib/nfs/FileReader.cxx
+++ b/src/lib/nfs/FileReader.cxx
@@ -20,6 +20,7 @@
#include "config.h"
#include "FileReader.hxx"
#include "Glue.hxx"
+#include "Base.hxx"
#include "Connection.hxx"
#include "Domain.hxx"
#include "event/Call.hxx"
@@ -100,14 +101,23 @@ NfsFileReader::Open(const char *uri, Error &error)
server = std::string(uri, slash);
uri = slash;
- slash = strrchr(uri + 1, '/');
- if (slash == nullptr || slash[1] == 0) {
- error.Set(nfs_domain, "Malformed nfs:// URI");
- return false;
- }
- export_name = std::string(uri, slash);
- path = slash;
+ const char *new_path = nfs_check_base(server.c_str(), uri);
+ if (new_path != nullptr) {
+ export_name = std::string(uri, new_path);
+ if (*new_path == 0)
+ new_path = "/";
+ path = new_path;
+ } else {
+ slash = strrchr(uri + 1, '/');
+ if (slash == nullptr || slash[1] == 0) {
+ error.Set(nfs_domain, "Malformed nfs:// URI");
+ return false;
+ }
+
+ export_name = std::string(uri, slash);
+ path = slash;
+ }
state = State::DEFER;
DeferredMonitor::Schedule();
diff --git a/src/storage/plugins/NfsStorage.cxx b/src/storage/plugins/NfsStorage.cxx
index 1c712f68f..40625fc9a 100644
--- a/src/storage/plugins/NfsStorage.cxx
+++ b/src/storage/plugins/NfsStorage.cxx
@@ -23,6 +23,7 @@
#include "storage/StorageInterface.hxx"
#include "storage/FileInfo.hxx"
#include "lib/nfs/Domain.hxx"
+#include "lib/nfs/Base.hxx"
#include "fs/AllocatedPath.hxx"
#include "util/Error.hxx"
#include "thread/Mutex.hxx"
@@ -256,6 +257,8 @@ CreateNfsStorageURI(const char *base, Error &error)
return nullptr;
}
+ nfs_set_base(server.c_str(), mount);
+
return new NfsStorage(base, ctx);
}