[SCM] Samba Shared Repository - branch master updated

Anoop C S anoopcs at samba.org
Thu Sep 12 16:52:02 UTC 2024


The branch, master has been updated
       via  12ad4832a74 docs_xml/vfs_ceph_new: Add new proxy option
       via  095ece43a2e wscript_build: Do not link vfs_ceph_new against libcephfs
       via  962a40a6ff5 vfs_ceph_new: Use function pointers for API calls
       via  d5926cf492b vfs_ceph_new: Pass module config to userperm helpers
       via  250af54250b vfs_ceph_new: Hold a config reference in vfs_ceph_fh
       via  8c1d774c7e2 vfs_ceph_new: Call vfs_ceph_userperm_new with handle->conn
       via  e4fc1df4b44 vfs_ceph_new: Populate function pointers with addresses
       via  0d2ad13d8e5 vfs_ceph_new: Add required function pointers to config
       via  47812a27911 vfs_ceph_new: Dynamically open library for 'proxy' mode
       via  90464bdcafd vfs_ceph_new: Introduce new parametric option 'proxy'
       via  f1d418181d1 vfs_ceph_new: Add a new struct to hold ceph module config
      from  0cedd74e47a vfs_ceph_new: implement DFS hooks using libcephfs low-level APIs

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 12ad4832a74a6fba3fb8954a8630b900f5763f18
Author: Anoop C S <anoopcs at samba.org>
Date:   Thu Sep 5 11:45:19 2024 +0530

    docs_xml/vfs_ceph_new: Add new proxy option
    
    Update man page to describe new 'proxy' module option.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Signed-off-by: Anoop C S <anoopcs at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    
    Autobuild-User(master): Anoop C S <anoopcs at samba.org>
    Autobuild-Date(master): Thu Sep 12 16:51:14 UTC 2024 on atb-devel-224

commit 095ece43a2edbdeb498e8bef07bdf09f9836bb40
Author: Anoop C S <anoopcs at samba.org>
Date:   Sun Sep 8 12:52:59 2024 +0530

    wscript_build: Do not link vfs_ceph_new against libcephfs
    
    vfs_ceph_new dynamically loads the appropriate libcephfs shared
    libraries which means that we don't statically link against it.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Signed-off-by: Anoop C S <anoopcs at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 962a40a6ff51f33adc39e466f1479dfb35ac0926
Author: Anoop C S <anoopcs at samba.org>
Date:   Thu Sep 5 15:20:28 2024 +0530

    vfs_ceph_new: Use function pointers for API calls
    
    Replace direct function calls with pointers holding their equivalent
    addresses.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Signed-off-by: Anoop C S <anoopcs at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit d5926cf492b1cb81c90b27e0537ec3f1b1a10f80
Author: Anoop C S <anoopcs at samba.org>
Date:   Thu Sep 5 15:16:54 2024 +0530

    vfs_ceph_new: Pass module config to userperm helpers
    
    userperm helpers will switch to function references instead of direct
    invocation of APIs. This would mean the matching config structure is
    passed to those helpers.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Signed-off-by: Anoop C S <anoopcs at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 250af54250bed87928250b95db663ff13cc1f42a
Author: Anoop C S <anoopcs at samba.org>
Date:   Thu Sep 5 14:01:37 2024 +0530

    vfs_ceph_new: Hold a config reference in vfs_ceph_fh
    
    This is required to perform the cleanup when fsp extension destructor is
    called as part of VFS_REMOVE_FSP_EXTENSION where mount information and
    function references are to be used in upcoming changes.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Signed-off-by: Anoop C S <anoopcs at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 8c1d774c7e206bb413284d500c5aa950ac3dd3d5
Author: Anoop C S <anoopcs at samba.org>
Date:   Thu Sep 5 14:50:48 2024 +0530

    vfs_ceph_new: Call vfs_ceph_userperm_new with handle->conn
    
    vfs_ceph_userperm_new() only need connection structure from handle
    for fetching the current unix token. Therefore modify the signature
    to accept just handle->conn.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Signed-off-by: Anoop C S <anoopcs at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit e4fc1df4b4486f5eed095135f905bdbf10bb1793
Author: Guenther Deschner <gd at samba.org>
Date:   Thu Sep 5 13:40:27 2024 +0530

    vfs_ceph_new: Populate function pointers with addresses
    
    Use dlysm() for assigning addresses to already declared libcephfs
    low-level API function pointers.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Pair-Programmed-With: Anoop C S <anoopcs at samba.org>
    Signed-off-by: Guenther Deschner <gd at samba.org>
    Signed-off-by: Anoop C S <anoopcs at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 0d2ad13d8e5191f4b01584afa0bcdbf1114042b8
Author: Guenther Deschner <gd at samba.org>
Date:   Thu Sep 5 13:31:13 2024 +0530

    vfs_ceph_new: Add required function pointers to config
    
    Declare necessary libcephfs low-level APIs as function pointers to be
    assigned with corresponding loadable addresses.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Pair-Programmed-With: Anoop C S <anoopcs at samba.org>
    Signed-off-by: Guenther Deschner <gd at samba.org>
    Signed-off-by: Anoop C S <anoopcs at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 47812a279118befbaeffdd6c81e3d49b071f04c5
Author: Guenther Deschner <gd at samba.org>
Date:   Thu Sep 5 13:19:52 2024 +0530

    vfs_ceph_new: Dynamically open library for 'proxy' mode
    
    Use dlopen() to load either of the shared libraries(libcephfs.so or
    libcephfs_proxy.so) based on the configuration for 'proxy' module
    parameter. Further down the line we will define the required APIs
    as function pointers within the config structure.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Pair-Programmed-With: Anoop C S <anoopcs at samba.org>
    Signed-off-by: Guenther Deschner <gd at samba.org>
    Signed-off-by: Anoop C S <anoopcs at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 90464bdcafda0f0f0e4d2b549fd1675c076ee188
Author: Guenther Deschner <gd at samba.org>
Date:   Thu Sep 5 13:13:38 2024 +0530

    vfs_ceph_new: Introduce new parametric option 'proxy'
    
    Provide early support for consuming yet to come libcephfs proxy[1] for
    optimized resource utilization. For better control we make use of an
    additional module specific option 'proxy' to specify the intent to load
    proxy library. With the default value 'no' a regular cephfs connection
    is established. There is also an 'auto' mode which can fall back to the
    regular connection if proxy requirements are not met.
    
    [1] https://github.com/ceph/ceph/pull/58376
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Signed-off-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit f1d418181d12bd513204cf2b77c37990939e2041
Author: Guenther Deschner <gd at samba.org>
Date:   Thu Sep 5 12:19:52 2024 +0530

    vfs_ceph_new: Add a new struct to hold ceph module config
    
    Consolidate all required configuration related data under a dedicated
    structure named vfs_ceph_config. As of now it includes the location of
    configuration file, file system name, ceph client user id and mount
    related information. This is expected to grow in future with more
    details as and when required. Apart from that small cleanups are also
    done to make code more robust.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703
    
    Pair-Programmed-With: Anoop C S <anoopcs at samba.org>
    Signed-off-by: Guenther Deschner <gd at samba.org>
    Signed-off-by: Anoop C S <anoopcs at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 docs-xml/manpages/vfs_ceph_new.8.xml |  29 ++
 source3/modules/vfs_ceph_new.c       | 968 +++++++++++++++++++++++++----------
 source3/modules/wscript_build        |   2 +-
 3 files changed, 740 insertions(+), 259 deletions(-)


Changeset truncated at 500 lines:

diff --git a/docs-xml/manpages/vfs_ceph_new.8.xml b/docs-xml/manpages/vfs_ceph_new.8.xml
index b0640a591a5..eaf5b66cceb 100644
--- a/docs-xml/manpages/vfs_ceph_new.8.xml
+++ b/docs-xml/manpages/vfs_ceph_new.8.xml
@@ -152,6 +152,35 @@
 		</listitem>
 		</varlistentry>
 
+		<varlistentry>
+		<term>ceph_new:proxy = [ yes | no | auto ]</term>
+		<listitem>
+		<para>
+			Allows one to indicate use of the libcephfs proxy library
+			for optimized resource utilization, allowing more simultaneous
+			client connections. Prerequisites include the presence of
+			<emphasis>libcephfs_proxy.so.X</emphasis> shared library file
+			under loadable locations for dynamic linker and an active(running)
+			<emphasis>libcephfsd</emphasis> daemon.
+		</para>
+
+		<itemizedlist>
+			<listitem><para><constant>no</constant> (default) - Do
+			not use the proxy library but regular connection through
+			<emphasis>libcephfs.so.X</emphasis>.</para></listitem>
+
+			<listitem><para><constant>yes</constant> - Always use
+			the proxy library and fail the client connection request
+			if prerequisites are unmet.</para></listitem>
+
+			<listitem><para><constant>auto</constant> - Attempt to
+			use the proxy library but fall back to the regular cephfs
+			connection if prerequisites are unmet.</para></listitem>
+
+		</itemizedlist>
+
+		</listitem>
+		</varlistentry>
 	</variablelist>
 
 </refsect1>
diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c
index 389113b5bd3..53f673583fe 100644
--- a/source3/modules/vfs_ceph_new.c
+++ b/source3/modules/vfs_ceph_new.c
@@ -78,6 +78,87 @@ static ssize_t lstatus_code(intmax_t ret)
 	return (ssize_t)ret;
 }
 
+enum vfs_cephfs_proxy_mode {
+	VFS_CEPHFS_PROXY_NO = 0,
+	VFS_CEPHFS_PROXY_YES,
+	VFS_CEPHFS_PROXY_AUTO
+};
+
+static const struct enum_list enum_vfs_cephfs_proxy_vals[] = {
+	{VFS_CEPHFS_PROXY_NO, "No"},
+	{VFS_CEPHFS_PROXY_NO, "False"},
+	{VFS_CEPHFS_PROXY_NO, "0"},
+	{VFS_CEPHFS_PROXY_NO, "Off"},
+	{VFS_CEPHFS_PROXY_NO, "disable"},
+	{VFS_CEPHFS_PROXY_YES, "Yes"},
+	{VFS_CEPHFS_PROXY_YES, "True"},
+	{VFS_CEPHFS_PROXY_YES, "1"},
+	{VFS_CEPHFS_PROXY_YES, "On"},
+	{VFS_CEPHFS_PROXY_YES, "enable"},
+	{VFS_CEPHFS_PROXY_AUTO, "auto"},
+	{-1, NULL}
+};
+
+#define CEPH_FN(_name) typeof(_name) *_name ## _fn
+
+struct vfs_ceph_config {
+	const char *conf_file;
+	const char *user_id;
+	const char *fsname;
+	struct cephmount_cached *mount_entry;
+	struct ceph_mount_info *mount;
+	enum vfs_cephfs_proxy_mode proxy;
+	void *libhandle;
+
+	CEPH_FN(ceph_ll_lookup_inode);
+	CEPH_FN(ceph_ll_walk);
+	CEPH_FN(ceph_ll_getattr);
+	CEPH_FN(ceph_ll_setattr);
+	CEPH_FN(ceph_ll_releasedir);
+	CEPH_FN(ceph_ll_create);
+	CEPH_FN(ceph_ll_lookup);
+	CEPH_FN(ceph_ll_open);
+	CEPH_FN(ceph_ll_opendir);
+	CEPH_FN(ceph_ll_mkdir);
+	CEPH_FN(ceph_ll_rmdir);
+	CEPH_FN(ceph_ll_unlink);
+	CEPH_FN(ceph_ll_symlink);
+	CEPH_FN(ceph_ll_readlink);
+	CEPH_FN(ceph_ll_put);
+	CEPH_FN(ceph_ll_read);
+	CEPH_FN(ceph_ll_write);
+	CEPH_FN(ceph_ll_lseek);
+	CEPH_FN(ceph_ll_fsync);
+	CEPH_FN(ceph_ll_fallocate);
+	CEPH_FN(ceph_ll_link);
+	CEPH_FN(ceph_ll_rename);
+	CEPH_FN(ceph_ll_mknod);
+	CEPH_FN(ceph_ll_getxattr);
+	CEPH_FN(ceph_ll_setxattr);
+	CEPH_FN(ceph_ll_listxattr);
+	CEPH_FN(ceph_ll_removexattr);
+	CEPH_FN(ceph_ll_lookup_root);
+	CEPH_FN(ceph_ll_statfs);
+	CEPH_FN(ceph_ll_close);
+
+	CEPH_FN(ceph_chdir);
+	CEPH_FN(ceph_conf_get);
+	CEPH_FN(ceph_conf_read_file);
+	CEPH_FN(ceph_conf_set);
+	CEPH_FN(ceph_create);
+	CEPH_FN(ceph_getcwd);
+	CEPH_FN(ceph_init);
+	CEPH_FN(ceph_mount);
+	CEPH_FN(ceph_release);
+	CEPH_FN(ceph_select_filesystem);
+	CEPH_FN(ceph_unmount);
+	CEPH_FN(ceph_userperm_destroy);
+	CEPH_FN(ceph_userperm_new);
+	CEPH_FN(ceph_version);
+	CEPH_FN(ceph_readdir);
+	CEPH_FN(ceph_rewinddir);
+};
+
 /*
  * Track unique connections, as virtual mounts, to cephfs file systems.
  * Individual mount-entries will be set on the handle->data attribute, but
@@ -156,58 +237,50 @@ static int cephmount_cache_remove(struct cephmount_cached *entry)
 	return 0;
 }
 
-static char *cephmount_get_cookie(TALLOC_CTX * mem_ctx, const int snum)
+static char *cephmount_get_cookie(TALLOC_CTX * mem_ctx,
+				  struct vfs_ceph_config *config)
 {
-	const char *conf_file =
-	    lp_parm_const_string(snum, "ceph_new", "config_file", ".");
-	const char *user_id =
-	    lp_parm_const_string(snum, "ceph_new", "user_id", "");
-	const char *fsname =
-	    lp_parm_const_string(snum, "ceph_new", "filesystem", "");
-	return talloc_asprintf(mem_ctx, "(%s/%s/%s)", conf_file, user_id,
-			       fsname);
+	return talloc_asprintf(mem_ctx, "(%s/%s/%s)",
+			       config->conf_file,
+			       config->user_id,
+			       config->fsname);
 }
 
-static struct ceph_mount_info *cephmount_mount_fs(const int snum)
+static struct ceph_mount_info *cephmount_mount_fs(
+	struct vfs_ceph_config *config)
 {
 	int ret;
 	char buf[256];
 	struct ceph_mount_info *mnt = NULL;
 	/* if config_file and/or user_id are NULL, ceph will use defaults */
-	const char *conf_file =
-	    lp_parm_const_string(snum, "ceph_new", "config_file", NULL);
-	const char *user_id =
-	    lp_parm_const_string(snum, "ceph_new", "user_id", NULL);
-	const char *fsname =
-	    lp_parm_const_string(snum, "ceph_new", "filesystem", NULL);
 
 	DBG_DEBUG("[CEPH] calling: ceph_create\n");
-	ret = ceph_create(&mnt, user_id);
+	ret = config->ceph_create_fn(&mnt, config->user_id);
 	if (ret) {
 		errno = -ret;
 		return NULL;
 	}
 
 	DBG_DEBUG("[CEPH] calling: ceph_conf_read_file with %s\n",
-		  (conf_file == NULL ? "default path" : conf_file));
-	ret = ceph_conf_read_file(mnt, conf_file);
+		  (config->conf_file == NULL ? "default path" : config->conf_file));
+	ret = config->ceph_conf_read_file_fn(mnt, config->conf_file);
 	if (ret) {
 		goto err_cm_release;
 	}
 
 	DBG_DEBUG("[CEPH] calling: ceph_conf_get\n");
-	ret = ceph_conf_get(mnt, "log file", buf, sizeof(buf));
+	ret = config->ceph_conf_get_fn(mnt, "log file", buf, sizeof(buf));
 	if (ret < 0) {
 		goto err_cm_release;
 	}
 
 	/* libcephfs disables POSIX ACL support by default, enable it... */
-	ret = ceph_conf_set(mnt, "client_acl_type", "posix_acl");
+	ret = config->ceph_conf_set_fn(mnt, "client_acl_type", "posix_acl");
 	if (ret < 0) {
 		goto err_cm_release;
 	}
 	/* tell libcephfs to perform local permission checks */
-	ret = ceph_conf_set(mnt, "fuse_default_permissions", "false");
+	ret = config->ceph_conf_set_fn(mnt, "fuse_default_permissions", "false");
 	if (ret < 0) {
 		goto err_cm_release;
 	}
@@ -216,21 +289,21 @@ static struct ceph_mount_info *cephmount_mount_fs(const int snum)
 	 * In ceph, multiple file system support has been stable since
 	 * 'pacific'. Permit different shares to access different file systems.
 	 */
-	if (fsname != NULL) {
-		ret = ceph_select_filesystem(mnt, fsname);
+	if (config->fsname != NULL) {
+		ret = config->ceph_select_filesystem_fn(mnt, config->fsname);
 		if (ret < 0) {
 			goto err_cm_release;
 		}
 	}
 
 	DBG_DEBUG("[CEPH] calling: ceph_mount\n");
-	ret = ceph_mount(mnt, NULL);
+	ret = config->ceph_mount_fn(mnt, NULL);
 	if (ret >= 0) {
 		goto cm_done;
 	}
 
       err_cm_release:
-	ceph_release(mnt);
+	config->ceph_release_fn(mnt);
 	mnt = NULL;
 	DBG_DEBUG("[CEPH] Error mounting fs: %s\n", strerror(-ret));
       cm_done:
@@ -243,6 +316,162 @@ static struct ceph_mount_info *cephmount_mount_fs(const int snum)
 	return mnt;
 }
 
+#define CHECK_CEPH_FN(hnd, func) \
+	do { \
+		config->func ## _fn = dlsym(hnd, #func); \
+		if (config->func ## _fn == NULL) { \
+			if (dlclose(hnd)) { \
+				DBG_ERR("%s\n", dlerror()); \
+			} \
+			errno = ENOSYS; \
+			return false; \
+		} \
+	} while(0);
+
+static bool vfs_cephfs_load_lib(struct vfs_ceph_config *config)
+{
+	void *libhandle = NULL;
+	const char *libname = "libcephfs.so.2";
+	const char *libname_proxy = "libcephfs_proxy.so.2";
+
+	switch (config->proxy) {
+	case VFS_CEPHFS_PROXY_YES:
+	case VFS_CEPHFS_PROXY_AUTO:
+		libhandle = dlopen(libname_proxy, RTLD_NOW);
+		if (libhandle == NULL) {
+			if (config->proxy == VFS_CEPHFS_PROXY_YES) {
+				DBG_ERR("%s\n", dlerror());
+				return false;
+			}
+			DBG_DEBUG("%s, trying %s\n", dlerror(), libname);
+			FALL_THROUGH;
+		} else {
+			break;
+		}
+	case VFS_CEPHFS_PROXY_NO:
+	default:
+		libhandle = dlopen(libname, RTLD_LAZY);
+		if (libhandle == NULL) {
+			DBG_ERR("%s\n", dlerror());
+			return false;
+		}
+		break;
+	}
+
+	CHECK_CEPH_FN(libhandle, ceph_ll_lookup_inode);
+	CHECK_CEPH_FN(libhandle, ceph_ll_walk);
+	CHECK_CEPH_FN(libhandle, ceph_ll_getattr);
+	CHECK_CEPH_FN(libhandle, ceph_ll_setattr);
+	CHECK_CEPH_FN(libhandle, ceph_ll_releasedir);
+	CHECK_CEPH_FN(libhandle, ceph_ll_create);
+	CHECK_CEPH_FN(libhandle, ceph_ll_open);
+	CHECK_CEPH_FN(libhandle, ceph_ll_opendir);
+	CHECK_CEPH_FN(libhandle, ceph_ll_mkdir);
+	CHECK_CEPH_FN(libhandle, ceph_ll_rmdir);
+	CHECK_CEPH_FN(libhandle, ceph_ll_unlink);
+	CHECK_CEPH_FN(libhandle, ceph_ll_symlink);
+	CHECK_CEPH_FN(libhandle, ceph_ll_readlink);
+	CHECK_CEPH_FN(libhandle, ceph_ll_put);
+	CHECK_CEPH_FN(libhandle, ceph_ll_read);
+	CHECK_CEPH_FN(libhandle, ceph_ll_write);
+	CHECK_CEPH_FN(libhandle, ceph_ll_lseek);
+	CHECK_CEPH_FN(libhandle, ceph_ll_fsync);
+	CHECK_CEPH_FN(libhandle, ceph_ll_fallocate);
+	CHECK_CEPH_FN(libhandle, ceph_ll_link);
+	CHECK_CEPH_FN(libhandle, ceph_ll_rename);
+	CHECK_CEPH_FN(libhandle, ceph_ll_mknod);
+	CHECK_CEPH_FN(libhandle, ceph_ll_getxattr);
+	CHECK_CEPH_FN(libhandle, ceph_ll_setxattr);
+	CHECK_CEPH_FN(libhandle, ceph_ll_listxattr);
+	CHECK_CEPH_FN(libhandle, ceph_ll_removexattr);
+	CHECK_CEPH_FN(libhandle, ceph_ll_lookup);
+	CHECK_CEPH_FN(libhandle, ceph_ll_lookup_root);
+	CHECK_CEPH_FN(libhandle, ceph_ll_statfs);
+	CHECK_CEPH_FN(libhandle, ceph_ll_close);
+
+	CHECK_CEPH_FN(libhandle, ceph_chdir);
+	CHECK_CEPH_FN(libhandle, ceph_conf_get);
+	CHECK_CEPH_FN(libhandle, ceph_conf_read_file);
+	CHECK_CEPH_FN(libhandle, ceph_conf_set);
+	CHECK_CEPH_FN(libhandle, ceph_create);
+	CHECK_CEPH_FN(libhandle, ceph_getcwd);
+	CHECK_CEPH_FN(libhandle, ceph_init);
+	CHECK_CEPH_FN(libhandle, ceph_mount);
+	CHECK_CEPH_FN(libhandle, ceph_release);
+	CHECK_CEPH_FN(libhandle, ceph_select_filesystem);
+	CHECK_CEPH_FN(libhandle, ceph_unmount);
+	CHECK_CEPH_FN(libhandle, ceph_userperm_destroy);
+	CHECK_CEPH_FN(libhandle, ceph_userperm_new);
+	CHECK_CEPH_FN(libhandle, ceph_version);
+	CHECK_CEPH_FN(libhandle, ceph_readdir);
+	CHECK_CEPH_FN(libhandle, ceph_rewinddir);
+
+	config->libhandle = libhandle;
+
+	return true;
+}
+
+static int vfs_ceph_config_destructor(struct vfs_ceph_config *config)
+{
+	if (config->libhandle) {
+		if (dlclose(config->libhandle)) {
+			DBG_ERR("%s\n", dlerror());
+		}
+	}
+
+	return 0;
+}
+
+static bool vfs_ceph_load_config(struct vfs_handle_struct *handle,
+				 struct vfs_ceph_config **config)
+{
+	struct vfs_ceph_config *config_tmp = NULL;
+	int snum = SNUM(handle->conn);
+	const char *module_name = "ceph_new";
+	bool ok;
+
+	if (SMB_VFS_HANDLE_TEST_DATA(handle)) {
+		SMB_VFS_HANDLE_GET_DATA(handle, config_tmp,
+					struct vfs_ceph_config,
+					return false);
+		goto done;
+	}
+
+	config_tmp = talloc_zero(handle->conn, struct vfs_ceph_config);
+	if (config_tmp == NULL) {
+		errno = ENOMEM;
+		return false;
+	}
+	talloc_set_destructor(config_tmp, vfs_ceph_config_destructor);
+
+	config_tmp->conf_file	= lp_parm_const_string(snum, module_name,
+						       "config_file", ".");
+	config_tmp->user_id	= lp_parm_const_string(snum, module_name,
+						       "user_id", "");
+	config_tmp->fsname	= lp_parm_const_string(snum, module_name,
+						       "filesystem", "");
+	config_tmp->proxy	= lp_parm_enum(snum, module_name, "proxy",
+					       enum_vfs_cephfs_proxy_vals,
+					       VFS_CEPHFS_PROXY_NO);
+	if (config_tmp->proxy == -1) {
+		DBG_ERR("value for proxy: mode unknown\n");
+		return false;
+	}
+
+	ok = vfs_cephfs_load_lib(config_tmp);
+	if (!ok) {
+		return false;
+	}
+
+	SMB_VFS_HANDLE_SET_DATA(handle, config_tmp, NULL,
+				struct vfs_ceph_config, return false);
+
+done:
+	*config = config_tmp;
+
+	return true;
+}
+
 /* Check for NULL pointer parameters in vfs_ceph_* functions */
 
 /* We don't want to have NULL function pointers lying around.  Someone
@@ -254,9 +483,17 @@ static int vfs_ceph_connect(struct vfs_handle_struct *handle,
 {
 	int ret = 0;
 	struct cephmount_cached *entry = NULL;
-	struct ceph_mount_info *cmount = NULL;
-	int snum = SNUM(handle->conn);
-	char *cookie = cephmount_get_cookie(handle, snum);
+	struct ceph_mount_info *mount = NULL;
+	char *cookie;
+	struct vfs_ceph_config *config = NULL;
+	bool ok;
+
+	ok = vfs_ceph_load_config(handle, &config);
+	if (!ok) {
+		return -1;
+	}
+
+	cookie = cephmount_get_cookie(handle, config);
 	if (cookie == NULL) {
 		return -1;
 	}
@@ -266,18 +503,20 @@ static int vfs_ceph_connect(struct vfs_handle_struct *handle,
 		goto connect_ok;
 	}
 
-	cmount = cephmount_mount_fs(snum);
-	if (cmount == NULL) {
+	mount = cephmount_mount_fs(config);
+	if (mount == NULL) {
 		ret = -1;
 		goto connect_fail;
 	}
-	ret = cephmount_cache_add(cookie, cmount, &entry);
+
+	ret = cephmount_cache_add(cookie, mount, &entry);
 	if (ret != 0) {
 		goto connect_fail;
 	}
 
 connect_ok:
-	handle->data = entry;
+	config->mount = entry->mount;
+	config->mount_entry = entry;
 	DBG_WARNING("Connection established with the server: %s\n", cookie);
 
 	/*
@@ -289,53 +528,55 @@ connect_fail:
 	return ret;
 }
 
-static struct ceph_mount_info *cmount_of(const struct vfs_handle_struct *handle)
-{
-	const struct cephmount_cached *entry = handle->data;
-
-	return entry->mount;
-}
-
 static void vfs_ceph_disconnect(struct vfs_handle_struct *handle)
 {
-	struct ceph_mount_info *cmount = cmount_of(handle);
+	struct ceph_mount_info *mount = NULL;
 	int ret = 0;
+	struct vfs_ceph_config *config = NULL;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config, return);
 
-	ret = cephmount_cache_remove(handle->data);
+	mount = config->mount;
+
+	ret = cephmount_cache_remove(config->mount_entry);
 	if (ret > 0) {
 		DBG_DEBUG("[CEPH] mount cache entry still in use\n");
 		return;
 	}
 
-	ret = ceph_unmount(cmount);
+	ret = config->ceph_unmount_fn(mount);
 	if (ret < 0) {
 		DBG_ERR("[CEPH] failed to unmount: %s\n", strerror(-ret));
 	}
 
-	ret = ceph_release(cmount);
+	ret = config->ceph_release_fn(mount);
 	if (ret < 0) {
 		DBG_ERR("[CEPH] failed to release: %s\n", strerror(-ret));
 	}
-	handle->data = NULL;
+
+	config->mount_entry = NULL;
+
+	TALLOC_FREE(config);
 }
 
 /* Ceph user-credentials */
-static struct UserPerm *vfs_ceph_userperm_new(
-	const struct vfs_handle_struct *handle)
+static struct UserPerm *vfs_ceph_userperm_new(struct vfs_ceph_config *config,
+	struct connection_struct *conn)
 {
 	const struct security_unix_token *unix_token = NULL;
 
-	unix_token = get_current_utok(handle->conn);
-	return ceph_userperm_new(unix_token->uid,
-				 unix_token->gid,
-				 unix_token->ngroups,
-				 unix_token->groups);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list