Latest Time Machine Patch

Ralph Böhme slow at samba.org
Fri Sep 15 23:23:27 UTC 2017


Hi Kevin,

On Fri, Sep 15, 2017 at 06:47:43PM +0000, Kevin Anderson wrote:
> The "volume_caps" variable should be "caps".

oops, my fault, sorry! Fixed in the attached patchset.

Fwiw, I removed forcing "strict sync = yes" as that will be the default setting
in 4.7.

-slow
-------------- next part --------------
From bc989050715cab5b0571e3a3dbba42c0a4eba1e3 Mon Sep 17 00:00:00 2001
From: Kevin Anderson <andersonkw2 at gmail.com>
Date: Mon, 14 Nov 2016 19:14:44 +0100
Subject: [PATCH 1/3] vfs_fruit: Add Time Machine support

Add a configuration option to disable/enable Time Machine support via
the FULLSYNC AAPL flag.

Signed-off-by: Kevin Anderson <andersonkw2 at gmail.com>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 libcli/smb/smb2_create_ctx.h |  1 +
 source3/modules/vfs_fruit.c  | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/libcli/smb/smb2_create_ctx.h b/libcli/smb/smb2_create_ctx.h
index cb194f5c536..0e0b713e55c 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_fruit.c b/source3/modules/vfs_fruit.c
index 3ba59967482..5c1a2fcd2ae 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -139,6 +139,7 @@ struct fruit_config_data {
 	bool posix_rename;
 	bool aapl_zero_file_id;
 	const char *model;
+	bool time_machine;
 
 	/*
 	 * Additional options, all enabled by default,
@@ -1570,6 +1571,9 @@ static int init_fruit_config(vfs_handle_struct *handle)
 	config->readdir_attr_max_access = lp_parm_bool(
 		SNUM(handle->conn), "readdir_attr", "aapl_max_access", true);
 
+	config->time_machine = lp_parm_bool(
+		SNUM(handle->conn), FRUIT_PARAM_TYPE_NAME, "time machine", false);
+
 	config->model = lp_parm_const_string(
 		-1, FRUIT_PARAM_TYPE_NAME, "model", "MacSamba");
 
@@ -2206,6 +2210,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);
@@ -2637,6 +2645,14 @@ static int fruit_connect(vfs_handle_struct *handle,
 			"0x0d:0xf00d");
 	}
 
+	if (config->time_machine) {
+		DBG_NOTICE("Enabling durable handles for Time Machine "
+			   "support on [%s]\n", service);
+		lp_do_parameter(SNUM(handle->conn), "durable handles", "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;
 }
 
-- 
2.13.5


From ff17ab3671d97f4cbeeae3fa2f339874d9bc0e67 Mon Sep 17 00:00:00 2001
From: Kevin Anderson <andersonkw2 at gmail.com>
Date: Sun, 23 Oct 2016 20:32:27 -0400
Subject: [PATCH 2/3] docs/vfs_fruit: Add Time Machine support

Add the capability to advertise FULLSYNC volume capabilities
to clients that request them. This is mainly used for supporting
Mac OS Time Machine backups from clients. The capability does
not perform any additional action.

Signed-off-by: Kevin Anderson <andersonkw2 at gmail.com>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 docs-xml/manpages/vfs_fruit.8.xml | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/docs-xml/manpages/vfs_fruit.8.xml b/docs-xml/manpages/vfs_fruit.8.xml
index c5ffc828fc3..244ee2abb2a 100644
--- a/docs-xml/manpages/vfs_fruit.8.xml
+++ b/docs-xml/manpages/vfs_fruit.8.xml
@@ -307,6 +307,38 @@
 	  </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>
+	      </itemizedlist>
+
+	    </listitem>
+	  </varlistentry>
+
+	  <varlistentry>
 	    <term>readdir_attr:aapl_rsize = yes | no</term>
 	    <listitem>
 	      <para>Return resource fork size in SMB2 FIND responses.</para>
-- 
2.13.5


From 1f99c7a533a5ff0c8766384674433658b0981430 Mon Sep 17 00:00:00 2001
From: Omri Mor <omri50 at gmail.com>
Date: Thu, 14 Sep 2017 17:56:37 -0700
Subject: [PATCH 3/3] s3/smbd: register TimeMachine shares with avahi

This commit adds support for automatically adding the required
_adisk._tcp mdns resource record registrations based on the setting of
"fruit:time machine".

Signed-off-by: Omri Mor <omri50 at gmail.com>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/avahi_register.c | 49 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 3 deletions(-)

diff --git a/source3/smbd/avahi_register.c b/source3/smbd/avahi_register.c
index c118e61ccc2..055b0cc8bcf 100644
--- a/source3/smbd/avahi_register.c
+++ b/source3/smbd/avahi_register.c
@@ -18,12 +18,23 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+/*
+ * Avahi aborts on allocation failure (OOM),
+ * unless a custom allocator which doesn't do so has been set.
+ *
+ * This is particularly important for the avahi_string_list_*() functions,
+ * which return NULL on allocation failure.
+ * Since it should abort on allocation failure (before returning NULL),
+ * we don't check the result.
+ */
+
 #include "includes.h"
 #include "smbd/smbd.h"
 
 #include <avahi-client/client.h>
 #include <avahi-client/publish.h>
 #include <avahi-common/error.h>
+#include <avahi-common/strlst.h>
 
 struct avahi_state_struct {
 	struct AvahiPoll *poll;
@@ -70,7 +81,12 @@ static void avahi_client_callback(AvahiClient *c, AvahiClientState status,
 	int error;
 
 	switch (status) {
-	case AVAHI_CLIENT_S_RUNNING:
+	case AVAHI_CLIENT_S_RUNNING: {
+		int snum;
+		int num_services = lp_numservices();
+		int dk = 0;
+		AvahiStringList *adisk = NULL;
+
 		DBG_DEBUG("AVAHI_CLIENT_S_RUNNING\n");
 
 		state->entry_group = avahi_entry_group_new(
@@ -94,15 +110,42 @@ static void avahi_client_callback(AvahiClient *c, AvahiClientState status,
 			break;
 		}
 
+		for (snum = 0; snum < num_services; snum++) {
+			if (lp_snum_ok(snum) &&
+			    lp_parm_bool(snum, "fruit", "time machine", false))
+			{
+				adisk = avahi_string_list_add_printf(
+					    adisk, "dk%d=adVN=%s,adVF=0x82",
+					    dk++, lp_const_servicename(snum));
+			}
+		}
+		if (dk > 0) {
+			adisk = avahi_string_list_add(adisk, "sys=adVF=0x100");
+			error = avahi_entry_group_add_service_strlst(
+				state->entry_group, AVAHI_IF_UNSPEC,
+				AVAHI_PROTO_UNSPEC, 0, lp_netbios_name(),
+				"_adisk._tcp", NULL, NULL, 0, adisk);
+			avahi_string_list_free(adisk);
+			adisk = NULL;
+			if (error != AVAHI_OK) {
+				DBG_DEBUG("avahi_entry_group_add_service_strlst "
+					  "failed: %s\n", avahi_strerror(error));
+				avahi_entry_group_free(state->entry_group);
+				state->entry_group = NULL;
+				break;
+			}
+		}
+
 		error = avahi_entry_group_commit(state->entry_group);
 		if (error != AVAHI_OK) {
-			DBG_DEBUG("avahi_entry_group_commit failed: %s\n",
-				  avahi_strerror(error));
+			DBG_DEBUG("avahi_entry_group_commit failed: "
+				  "%s\n", avahi_strerror(error));
 			avahi_entry_group_free(state->entry_group);
 			state->entry_group = NULL;
 			break;
 		}
 		break;
+	}
 	case AVAHI_CLIENT_FAILURE:
 		error = avahi_client_errno(c);
 
-- 
2.13.5



More information about the samba-technical mailing list