Patch to add support for advertising FULLSYNC to Mac OSX Clients

Kevin Anderson andersonkw2 at gmail.com
Thu Jul 6 00:57:09 UTC 2017


Hi Ralph,

> attached is a patch (on top of a current TM patchset) which forces every SMB2
> FLUSH request to take at least 1 ms which will trigger an request-went-async
> SMB2 response to the client.
> 
> Can you please test this with a macOS client? Please check whether the patch
> really produced async resonses for the SMB2 FLUSHes.
>

Was the intent of this patch just to see if an async response would cause an
error on the client? If so it appears the TimeMachine client does the right
thing and handles the errors appropriately along with the async smb flush.

I applied the patch with 2 changes. Those changes were changing msleep to smb_msleep
(patch was missing an include or smb_msleep is what was intented) and changing volume_caps
to caps in config-time_machine since they didn't match the variable on master.

Ultimately with the patch applied it took a significant amount of time for a backup which I
assume was intended. I saved a PCAP and can send that if you have a preferred method. Based
on my interpretation, I see a flush request from the client sent as a sync command, a response
from the server with a STATUS_PENDING error message with the async bit set, and finally an async
flush response is sent to the client.

I also looked again at my home server with my previous patch applied (without the smb_msleep call)
and I see a similar async command and response as what I stated above for some of the flush
responses which has been working without any issues. I think the reason I didn't notice
it before was because I was doing the packet capture analysis against a machine with an SSD
rather than a spinning disk which allowed the flush requests to complete without going async.

Thanks,
Kevin Anderson 

 
diff --git a/docs-xml/manpages/vfs_fruit.8.xml b/docs-xml/manpages/vfs_fruit.8.xml
index 0bddd4a..3455644 100644
--- a/docs-xml/manpages/vfs_fruit.8.xml
+++ b/docs-xml/manpages/vfs_fruit.8.xml
@@ -298,6 +298,39 @@
          </varlistentry>

          <varlistentry>
+           <term>fruit:time machine = [ yes | no ]</term>
+           <listitem>
+             <para>Controls if Time Machine support via the FULLSYNC volume
+             capability is advertised to clients.</para>
+
+             <itemizedlist>
+               <listitem><para><command>no (default)</command> Disables
+               advertising Time Machine support and the FULLSYNC volume
+               capability to clients.</para></listitem>
+
+               <listitem><para><command>yes</command> - Enables advertising
+               Time Machine support and the FULLSYNC volume capability to
+               clients. This is necessary for supporting Time Machine backups
+               from Mac OSX clients. This value only advertises the capability
+               and does nothing else with the sync requests from clients.
+               </para></listitem>
+
+             </itemizedlist>
+
+             <para>This option enforces the following settings per share (or
+             for all shares if enabled globally):</para>
+             <itemizedlist>
+               <listitem><para><command>durable handles = yes</command></para></listitem>
+               <listitem><para><command>kernel oplocks = no</command></para></listitem>
+               <listitem><para><command>kernel share modes = no</command></para></listitem>
+               <listitem><para><command>posix locking = no</command></para></listitem>
+               <listitem><para><command>strict sync = yes</command></para></listitem>
+             </itemizedlist>
+
+           </listitem>
+         </varlistentry>
+
+         <varlistentry>
            <term>readdir_attr:aapl_rsize = yes | no</term>
            <listitem>
              <para>Return resource fork size in SMB2 FIND responses.</para>
diff --git a/libcli/smb/smb2_create_ctx.h b/libcli/smb/smb2_create_ctx.h
index cb194f5..0e0b713 100644
--- a/libcli/smb/smb2_create_ctx.h
+++ b/libcli/smb/smb2_create_ctx.h
@@ -42,5 +42,6 @@
 /* "AAPL" Volume Capabilities bitmap */
 #define SMB2_CRTCTX_AAPL_SUPPORT_RESOLVE_ID 1
 #define SMB2_CRTCTX_AAPL_CASE_SENSITIVE     2
+#define SMB2_CRTCTX_AAPL_FULL_SYNC          4

 #endif
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 111a0c3..a3c6056 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1024,6 +1024,9 @@ static void vfs_fsync_do(void *private_data)

        PROFILE_TIMESTAMP(&start_time);

+       /* Force an interim async repsonse */
+       smb_msleep(1000);
+
        do {
                state->ret = fsync(state->fd);
        } while ((state->ret == -1) && (errno == EINTR));
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index b49ee1c..19dda9a 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -138,6 +138,7 @@ struct fruit_config_data {
        bool veto_appledouble;
        bool posix_rename;
        bool aapl_zero_file_id;
+       bool time_machine;

        /*
         * Additional options, all enabled by default,
@@ -1607,6 +1608,9 @@ static int init_fruit_config(vfs_handle_struct *handle)
        config->use_aapl = lp_parm_bool(
                -1, FRUIT_PARAM_TYPE_NAME, "aapl", true);

+       config->time_machine = lp_parm_bool(
+               -1, FRUIT_PARAM_TYPE_NAME, "time machine", false);
+
        config->unix_info_enabled = lp_parm_bool(
                -1, FRUIT_PARAM_TYPE_NAME, "nfs_aces", true);

@@ -2177,6 +2181,7 @@ static NTSTATUS check_aapl(vfs_handle_struct *handle,
        DATA_BLOB blob = data_blob_talloc(req, NULL, 0);
        uint64_t req_bitmap, client_caps;
        uint64_t server_caps = SMB2_CRTCTX_AAPL_UNIX_BASED;
+       uint64_t volume_caps = 0;
        smb_ucs2_t *model;
        size_t modellen;

@@ -2261,6 +2266,10 @@ static NTSTATUS check_aapl(vfs_handle_struct *handle,
                        break;
                }

+               if (config->time_machine) {
+                       caps |= SMB2_CRTCTX_AAPL_FULL_SYNC;
+               }
+
                SBVAL(p, 0, caps);

                ok = data_blob_append(req, &blob, p, 8);
@@ -2689,6 +2698,13 @@ static int fruit_connect(vfs_handle_struct *handle,
                        "0x0d:0xf00d");
        }

+       if (config->time_machine) {
+               lp_do_parameter(SNUM(handle->conn), "durable handles", "yes");
+               lp_do_parameter(SNUM(handle->conn), "strict sync", "yes");
+               lp_do_parameter(SNUM(handle->conn), "kernel oplocks", "no");
+               lp_do_parameter(SNUM(handle->conn), "kernel share modes", "no");
+               lp_do_parameter(SNUM(handle->conn), "posix locking", "no");
+       }
        return rc;
 }



More information about the samba-technical mailing list