vfs_fileid: add fileid:algorithm = hostname
authorRalph Boehme <slow@samba.org>
Thu, 4 Jan 2018 15:59:54 +0000 (16:59 +0100)
committerJeremy Allison <jra@samba.org>
Fri, 5 Jan 2018 23:07:17 +0000 (00:07 +0100)
Using fileid:algorithm = hostname makes fileid generate
fileids based on the hostname. This breaks cluster lock coherence.

Based-on-a-patch-by: Christian Ambach <ambi@samba.org>
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
docs-xml/manpages/vfs_fileid.8.xml
source3/modules/vfs_fileid.c

index 568756ba519e3f5b301b50458ae686058f798a75..6a09f16cf794ec8b2e7b36aa1927733568b5a4b9 100644 (file)
@@ -60,9 +60,9 @@
                <varlistentry>
                <term>fileid:algorithm = ALGORITHM</term>
                <listitem>
-               <para>Available algorithms are <command>fsname</command>
-               and <command>fsid</command>. The default value is
-               <command>fsname</command>.
+               <para>Available algorithms are <command>fsname</command>,
+               <command>fsid</command> and <command>hostname</command>. The
+               default value is <command>fsname</command>.
                </para>
                <para>The <command>fsname</command> algorithm generates
                device id by hashing the kernel device name.
                the device id from the <command>f_fsid</command> returned
                from the <command>statfs()</command> syscall.
                </para>
+               <para>The <command>hostname</command> algorithm generates device
+               id by hashing the hostname. This can be used to deliberately
+               break lock coherency in a cluster.
+               </para>
                </listitem>
                </varlistentry>
 
index d3aa4e4057d41cd24bf78b9fd5cd11b533e35db7..76f08f31a9e7ac63c851d364b24debb4e7c6a6b0 100644 (file)
@@ -209,6 +209,35 @@ static uint64_t fileid_device_mapping_fsname(struct fileid_handle_data *data,
        return m->devid;
 }
 
+/* a device mapping using a hostname */
+static uint64_t fileid_device_mapping_hostname(struct fileid_handle_data *data,
+                                              const SMB_STRUCT_STAT *sbuf)
+{
+       char hostname[HOST_NAME_MAX+1];
+       char *devname = NULL;
+       uint64_t id;
+       size_t devname_len;
+       int rc;
+
+       rc = gethostname(hostname, HOST_NAME_MAX+1);
+       if (rc != 0) {
+               DBG_ERR("gethostname failed\n");
+               return UINT64_MAX;
+       }
+
+       devname = talloc_asprintf(talloc_tos(), "%s%lu",
+                                 hostname, sbuf->st_ex_dev);
+       if (devname == NULL) {
+               DBG_ERR("talloc_asprintf failed\n");
+               return UINT64_MAX;
+       }
+       devname_len = talloc_array_length(devname) - 1;
+       TALLOC_FREE(devname);
+
+       id = fileid_uint64_hash((uint8_t *)devname, devname_len);
+       return id;
+}
+
 /* device mapping functions using a fsid */
 static uint64_t fileid_device_mapping_fsid(struct fileid_handle_data *data,
                                           const SMB_STRUCT_STAT *sbuf)
@@ -275,6 +304,8 @@ static int fileid_connect(struct vfs_handle_struct *handle,
                data->device_mapping_fn = fileid_device_mapping_fsname;
        } else if (strcmp("fsid", algorithm) == 0) {
                data->device_mapping_fn = fileid_device_mapping_fsid;
+       } else if (strcmp("hostname", algorithm) == 0) {
+               data->device_mapping_fn = fileid_device_mapping_hostname;
        } else {
                SMB_VFS_NEXT_DISCONNECT(handle);
                DEBUG(0,("fileid_connect(): unknown algorithm[%s]\n", algorithm));