The Samba-Bugzilla – Attachment 15290 Details for
Bug 13972
Different Device Id for GlusterFS FUSE mount is causing data loss in CTDB cluster
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch for master
patch-fix-bug-13972.patch (text/plain), 6.55 KB, created by
Michael Adam
on 2019-07-07 12:04:47 UTC
(
hide
)
Description:
patch for master
Filename:
MIME Type:
Creator:
Michael Adam
Created:
2019-07-07 12:04:47 UTC
Size:
6.55 KB
patch
obsolete
>From 52ef5a39f70ad191b752eb9d5b8d0d26108fe19d Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Sat, 18 May 2019 11:28:54 +0200 >Subject: [PATCH] vfs:glusterfs_fuse: ensure fileids are constant across nodes > >Instead of adding a new gluster-specific mode to the fileid module, >this patches provides a fileid algorithm as part of the glusterfs_fuse >vfs module. This can not be configured further, simply adding the >glusterfs_fuse vfs module to the vfs objects configuration will enable >the new fileid mode. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13972 > >Signed-off-by: Michael Adam <obnox@samba.org> >Signed-off-by: Guenther Deschner <gd@samba.org> >--- > docs-xml/manpages/vfs_glusterfs_fuse.8.xml | 8 + > source3/modules/vfs_glusterfs_fuse.c | 193 ++++++++++++++++++++- > 2 files changed, 200 insertions(+), 1 deletion(-) > >diff --git a/docs-xml/manpages/vfs_glusterfs_fuse.8.xml b/docs-xml/manpages/vfs_glusterfs_fuse.8.xml >index b9f7f42c6f2..f2aa624353e 100644 >--- a/docs-xml/manpages/vfs_glusterfs_fuse.8.xml >+++ b/docs-xml/manpages/vfs_glusterfs_fuse.8.xml >@@ -48,6 +48,14 @@ > case of an exisiting filename. > </para> > >+ <para> >+ Furthermore, this module implements a substitute file-id >+ mechanism. The default file-id mechanism is not working >+ correctly for gluster fuse mount re-exports, so in order to >+ avoid data loss, users exporting gluster fuse mounts with >+ Samba should enable this module. >+ </para> >+ > <para> > This module can be combined with other modules, but it > should be the last module in the <command>vfs objects</command> >diff --git a/source3/modules/vfs_glusterfs_fuse.c b/source3/modules/vfs_glusterfs_fuse.c >index 51515aa0df4..c621f9abf8e 100644 >--- a/source3/modules/vfs_glusterfs_fuse.c >+++ b/source3/modules/vfs_glusterfs_fuse.c >@@ -59,10 +59,201 @@ static int vfs_gluster_fuse_get_real_filename(struct vfs_handle_struct *handle, > return 0; > } > >+struct device_mapping_entry { >+ SMB_DEV_T device; /* the local device, for reference */ >+ uint64_t mapped_device; /* the mapped device */ >+}; >+ >+struct vfs_glusterfs_fuse_handle_data { >+ unsigned num_mapped_devices; >+ struct device_mapping_entry *mapped_devices; >+}; >+ >+/* a 64 bit hash, based on the one in tdb, copied from vfs_fileied */ >+static uint64_t vfs_glusterfs_fuse_uint64_hash(const uint8_t *s, size_t len) >+{ >+ uint64_t value; /* Used to compute the hash value. */ >+ uint32_t i; /* Used to cycle through random values. */ >+ >+ /* Set the initial value from the key size. */ >+ for (value = 0x238F13AFLL * len, i=0; i < len; i++) >+ value = (value + (((uint64_t)s[i]) << (i*5 % 24))); >+ >+ return (1103515243LL * value + 12345LL); >+} >+ >+static void vfs_glusterfs_fuse_load_devices( >+ struct vfs_glusterfs_fuse_handle_data *data) >+{ >+ FILE *f; >+ struct mntent *m; >+ >+ data->num_mapped_devices = 0; >+ TALLOC_FREE(data->mapped_devices); >+ >+ f = setmntent("/etc/mtab", "r"); >+ if (!f) { >+ return; >+ } >+ >+ while ((m = getmntent(f))) { >+ struct stat st; >+ char *p; >+ uint64_t mapped_device; >+ >+ if (stat(m->mnt_dir, &st) != 0) { >+ /* TODO: log? */ >+ continue; >+ } >+ >+ /* strip the host part off of the fsname */ >+ p = strrchr(m->mnt_fsname, ':'); >+ if (p == NULL) { >+ p = m->mnt_fsname; >+ } else { >+ /* TODO: consider the case of '' ? */ >+ p++; >+ } >+ >+ mapped_device = vfs_glusterfs_fuse_uint64_hash( >+ (const uint8_t *)p, >+ strlen(p)); >+ >+ data->mapped_devices = talloc_realloc(data, >+ data->mapped_devices, >+ struct device_mapping_entry, >+ data->num_mapped_devices + 1); >+ if (data->mapped_devices == NULL) { >+ goto nomem; >+ } >+ >+ data->mapped_devices[data->num_mapped_devices].device = >+ st.st_dev; >+ data->mapped_devices[data->num_mapped_devices].mapped_device = >+ mapped_device; >+ >+ data->num_mapped_devices++; >+ } >+ >+ endmntent(f); >+ return; >+ >+nomem: >+ data->num_mapped_devices = 0; >+ TALLOC_FREE(data->mapped_devices); >+ >+ endmntent(f); >+ return; >+} >+ >+static int vfs_glusterfs_fuse_map_device_cached( >+ struct vfs_glusterfs_fuse_handle_data *data, >+ SMB_DEV_T device, >+ uint64_t *mapped_device) >+{ >+ unsigned i; >+ >+ for (i = 0; i < data->num_mapped_devices; i++) { >+ if (data->mapped_devices[i].device == device) { >+ *mapped_device = data->mapped_devices[i].mapped_device; >+ return 0; >+ } >+ } >+ >+ return -1; >+} >+ >+static int vfs_glusterfs_fuse_map_device( >+ struct vfs_glusterfs_fuse_handle_data *data, >+ SMB_DEV_T device, >+ uint64_t *mapped_device) >+{ >+ int ret; >+ >+ ret = vfs_glusterfs_fuse_map_device_cached(data, device, mapped_device); >+ if (ret == 0) { >+ return 0; >+ } >+ >+ vfs_glusterfs_fuse_load_devices(data); >+ >+ ret = vfs_glusterfs_fuse_map_device_cached(data, device, mapped_device); >+ >+ return ret; >+} >+ >+static struct file_id vfs_glusterfs_fuse_file_id_create( >+ struct vfs_handle_struct *handle, >+ const SMB_STRUCT_STAT *sbuf) >+{ >+ struct vfs_glusterfs_fuse_handle_data *data; >+ struct file_id id; >+ uint64_t mapped_device; >+ int ret; >+ >+ ZERO_STRUCT(id); >+ >+ id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf); >+ >+ SMB_VFS_HANDLE_GET_DATA(handle, data, >+ struct vfs_glusterfs_fuse_handle_data, >+ return id); >+ >+ ret = vfs_glusterfs_fuse_map_device(data, sbuf->st_ex_dev, >+ &mapped_device); >+ if (ret == 0) { >+ id.devid = mapped_device; >+ } else { >+ DBG_WARNING("Failed to map device [%jx], falling back to " >+ "standard file_id [%jx]", >+ (uintmax_t)sbuf->st_ex_dev, >+ (uintmax_t)id.devid); >+ } >+ >+ DBG_DEBUG("Returning dev [%jx] inode [%jx]\n", >+ (uintmax_t)id.devid, (uintmax_t)id.inode); >+ >+ return id; >+} >+ >+static int vfs_glusterfs_fuse_connect(struct vfs_handle_struct *handle, >+ const char *service, const char *user) >+{ >+ struct vfs_glusterfs_fuse_handle_data *data; >+ int ret = SMB_VFS_NEXT_CONNECT(handle, service, user); >+ >+ if (ret < 0) { >+ return ret; >+ } >+ >+ data = talloc_zero(handle->conn, struct vfs_glusterfs_fuse_handle_data); >+ if (data == NULL) { >+ DBG_ERR("talloc_zero() failed.\n"); >+ SMB_VFS_NEXT_DISCONNECT(handle); >+ return -1; >+ } >+ >+ /* >+ * Fill the cache in the tree connect, so that the first file/dir access >+ * has chances of being fast... >+ */ >+ vfs_glusterfs_fuse_load_devices(data); >+ >+ SMB_VFS_HANDLE_SET_DATA(handle, data, NULL, >+ struct vfs_glusterfs_fuse_handle_data, >+ return -1); >+ >+ DBG_DEBUG("vfs_glusterfs_fuse_connect(): connected to service[%s]\n", >+ service); >+ >+ return 0; >+} >+ > struct vfs_fn_pointers glusterfs_fuse_fns = { > >- /* File Operations */ >+ .connect_fn = vfs_glusterfs_fuse_connect, > .get_real_filename_fn = vfs_gluster_fuse_get_real_filename, >+ .file_id_create_fn = vfs_glusterfs_fuse_file_id_create, > }; > > static_decl_vfs; >-- >2.21.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 13972
: 15290 |
15365
|
15366
|
15419
|
15428