[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-test-1938-g7da6c67

Alexander Bokovoy ab at samba.org
Wed Feb 6 16:42:13 GMT 2008


The branch, v3-2-test has been updated
       via  7da6c675440b0253ab37ee6097f769a2e45c7b7b (commit)
       via  9827d5ff416479408b19a8964c2321ea2517aa74 (commit)
       via  f59d3786abcc53065c838a2fa82ec2f4b577b16f (commit)
       via  974cf508fb5ba2ba3bd8fe7ae79710c9396d1d06 (commit)
       via  d46fc35dd4e22ecd777800a8cdb6c31763d0fac4 (commit)
       via  d841a3fc999c5ebd9e9d54b2bd5099b1b50402b1 (commit)
       via  863b5ed07aca0978aeaf919d7c51204a95ce03e0 (commit)
       via  8afb7133e956ec963ac55720fb297b4d5b44702c (commit)
       via  5efb57d904e25e68b09a567e260292439ad9c095 (commit)
       via  58dce4cdf277c8c68865185d9d8b4faea996dd3e (commit)
       via  42d06d41bf2e9fb094f6064dc04f549d880b5f8d (commit)
       via  cf1f90ad7a79dbe5926018790bb50d4e3b36cc7b (commit)
      from  7b15c75a6bacf783eb73568ed003e4b16d6ebd68 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit 7da6c675440b0253ab37ee6097f769a2e45c7b7b
Author: Alexander Bokovoy <ab at samba.org>
Date:   Wed Feb 6 09:10:50 2008 +0300

    Change the file time before we change the file mode.
    
    This doesn't matter for most applications, but for offline files it matters as it allows you to set
    files offline from windows clients even with HSM systems that refuse to offline newly created files.
    Merge from Tridge's v3-0-ctdb tree.

commit 9827d5ff416479408b19a8964c2321ea2517aa74
Author: Alexander Bokovoy <ab at samba.org>
Date:   Wed Feb 6 09:09:23 2008 +0300

    Allow actual call to set file offline
    
    Dos mode calculation was masking out FILE_ATTRIBUTE_OFFLINE so that code to set file offline
    was never called before. Merge from Tridge's v3-0-ctdb git tree.

commit f59d3786abcc53065c838a2fa82ec2f4b577b16f
Merge: 974cf508fb5ba2ba3bd8fe7ae79710c9396d1d06 7b15c75a6bacf783eb73568ed003e4b16d6ebd68
Author: Alexander Bokovoy <ab at samba.org>
Date:   Wed Feb 6 08:58:20 2008 +0300

    Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into dmapi-integration

commit 974cf508fb5ba2ba3bd8fe7ae79710c9396d1d06
Merge: d46fc35dd4e22ecd777800a8cdb6c31763d0fac4 7d369906ec37caebaa4e2097874997fa257f1a31
Author: Alexander Bokovoy <ab at samba.org>
Date:   Thu Jan 31 16:44:57 2008 +0300

    Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into dmapi-integration

commit d46fc35dd4e22ecd777800a8cdb6c31763d0fac4
Merge: d841a3fc999c5ebd9e9d54b2bd5099b1b50402b1 cb0fad1c97e1b590791fc0661f8ada1cdaa69318
Author: Alexander Bokovoy <ab at samba.org>
Date:   Thu Jan 31 16:08:57 2008 +0300

    Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into dmapi-integration

commit d841a3fc999c5ebd9e9d54b2bd5099b1b50402b1
Merge: 863b5ed07aca0978aeaf919d7c51204a95ce03e0 6bbe0fde6ebb5c1ea00ea24d3bdbffbf6f246bd6
Author: Alexander Bokovoy <ab at samba.org>
Date:   Wed Jan 30 12:00:15 2008 +0300

    Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into dmapi-integration

commit 863b5ed07aca0978aeaf919d7c51204a95ce03e0
Author: Alexander Bokovoy <ab at samba.org>
Date:   Tue Jan 29 18:33:22 2008 +0300

    Fix typos and replace statvfs call with fs_capabilities()

commit 8afb7133e956ec963ac55720fb297b4d5b44702c
Author: Alexander Bokovoy <ab at samba.org>
Date:   Tue Jan 29 18:01:23 2008 +0300

    Fix BOOL introduced by last commit

commit 5efb57d904e25e68b09a567e260292439ad9c095
Author: Alexander Bokovoy <ab at samba.org>
Date:   Tue Jan 29 17:43:49 2008 +0300

    Merge DMAPI fixes from Tridge
    
    Support cases when existing DMAPI session is stale. In this case we are creating another one.
    The code differs from 3-0_ctdb branch in that we fail when it is not possible to create more
    sessions and pretend that file is offline. This allows to escape endless loop in vfs_tsmsm.c.

commit 58dce4cdf277c8c68865185d9d8b4faea996dd3e
Merge: bc0b68709cbbdd71996a39e23fe8305e1f144f31 42d06d41bf2e9fb094f6064dc04f549d880b5f8d
Author: Alexander Bokovoy <ab at samba.org>
Date:   Tue Jan 29 16:19:21 2008 +0300

    Merge branch 'ctdb-merge' into dmapi-integration

commit 42d06d41bf2e9fb094f6064dc04f549d880b5f8d
Merge: cf1f90ad7a79dbe5926018790bb50d4e3b36cc7b f1d7de462cf0f64648a3a1fc6f0c64a7bbdb3c2a
Author: Alexander Bokovoy <ab at samba.org>
Date:   Thu Jan 24 14:06:22 2008 +0300

    Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into ctdb-merge

commit cf1f90ad7a79dbe5926018790bb50d4e3b36cc7b
Author: Alexander Bokovoy <ab at samba.org>
Date:   Fri Jan 18 17:34:21 2008 +0300

    Merge DMAPI fixes from CTDB Samba

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

Summary of changes:
 source/modules/vfs_tsmsm.c |  128 ++++++++++++++---------
 source/smbd/dmapi.c        |  247 +++++++++++++++++++++-----------------------
 source/smbd/dosmode.c      |   32 ++++--
 source/smbd/reply.c        |   12 +-
 source/smbd/server.c       |    6 -
 5 files changed, 221 insertions(+), 204 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/modules/vfs_tsmsm.c b/source/modules/vfs_tsmsm.c
index 2805488..791e8cf 100644
--- a/source/modules/vfs_tsmsm.c
+++ b/source/modules/vfs_tsmsm.c
@@ -3,8 +3,8 @@
   Samba VFS module for handling offline files
   with Tivoli Storage Manager Space Management
 
-  (c) Alexander Bokovoy, 2007
-  (c) Andrew Tridgell, 2007
+  (c) Alexander Bokovoy, 2007, 2008
+  (c) Andrew Tridgell, 2007, 2008
   
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -21,18 +21,20 @@
  */
 /*
   This VFS module accepts following options:
-  tsmsm: hsm script = <path to hsm script> (/bin/true by default, i.e. does nothing)
+  tsmsm: hsm script = <path to hsm script> (default does nothing)
          hsm script should point to a shell script which accepts two arguments:
 	 <operation> <filepath>
 	 where <operation> is currently 'offline' to set offline status of the <filepath>
 
   tsmsm: online ratio = ratio to check reported size against actual file size (0.5 by default)
+  tsmsm: attribute name = name of DMAPI attribute that is present when a file is offline. 
+  Default is "IBMobj" (which is what GPFS uses)
 
   The TSMSM VFS module tries to avoid calling expensive DMAPI calls with some heuristics
   based on the fact that number of blocks reported of a file multiplied by 512 will be
   bigger than 'online ratio' of actual size for online (non-migrated) files.
 
-  If checks fail, we call DMAPI and ask for specific IBM attribute which present for
+  If checks fail, we call DMAPI and ask for specific attribute which present for
   offline (migrated) files. If this attribute presents, we consider file offline.
  */
 
@@ -62,72 +64,66 @@
 
 /* optimisation tunables - used to avoid the DMAPI slow path */
 #define FILE_IS_ONLINE_RATIO      0.5
+
+/* default attribute name to look for */
 #define DM_ATTRIB_OBJECT "IBMObj"
-#define DM_ATTRIB_MIGRATED "IBMMig"
 
 struct tsmsm_struct {
-	dm_sessid_t sid;
 	float online_ratio;
 	char *hsmscript;
+	const char *attrib_name;
 };
 
-#define TSM_STRINGIFY(a) #a
-#define TSM_TOSTRING(a) TSM_STRINGIFY(a)
-
 static void tsmsm_free_data(void **pptr) {
 	struct tsmsm_struct **tsmd = (struct tsmsm_struct **)pptr;
 	if(!tsmd) return;
 	TALLOC_FREE(*tsmd);
 }
 
+/* 
+   called when a client connects to a share
+*/
 static int tsmsm_connect(struct vfs_handle_struct *handle,
 			 const char *service,
 			 const char *user) {
 	struct tsmsm_struct *tsmd = TALLOC_ZERO_P(handle, struct tsmsm_struct);
-	const char *hsmscript, *tsmname;
 	const char *fres;
+	const char *tsmname;
 	
 	if (!tsmd) {
 		DEBUG(0,("tsmsm_connect: out of memory!\n"));
 		return -1;
 	}
 
-	tsmd->sid = *(dm_sessid_t*) dmapi_get_current_session();
-
-	if (tsmd->sid == DM_NO_SESSION) {
+	if (!dmapi_have_session()) {
 		DEBUG(0,("tsmsm_connect: no DMAPI session for Samba is available!\n"));
 		TALLOC_FREE(tsmd);
 		return -1;
 	}
 
 	tsmname = (handle->param ? handle->param : "tsmsm");
-	hsmscript = lp_parm_const_string(SNUM(handle->conn), tsmname,
-					 "hsm script", NULL);
-	if (hsmscript) {
-		tsmd->hsmscript = talloc_strdup(tsmd, hsmscript);
-		if(!tsmd->hsmscript) {
-			DEBUG(1, ("tsmsm_connect: can't allocate memory for hsm script path"));
-			TALLOC_FREE(tsmd);
-			return -1;
-		}
-	} else {
-		DEBUG(1, ("tsmsm_connect: can't call hsm script because it "
-			  "is not set to anything in the smb.conf\n"
-			  "Use %s: 'hsm script = path' to set it\n",
-			  tsmname));
-		TALLOC_FREE(tsmd);
-		return -1;
-	}
+	
+	/* Get 'hsm script' and 'dmapi attribute' parameters to tsmd context */
+	tsmd->hsmscript = lp_parm_talloc_string(SNUM(handle->conn), tsmname,
+						"hsm script", NULL);
+	talloc_steal(tsmd, tsmd->hsmscript);
+	
+	tsmd->attrib_name = lp_parm_talloc_string(SNUM(handle->conn), tsmname, 
+						  "dmapi attribute", DM_ATTRIB_OBJECT);
+	talloc_steal(tsmd, tsmd->attrib_name);
 
+	/* retrieve 'online ratio'. In case of error default to FILE_IS_ONLINE_RATIO */
 	fres = lp_parm_const_string(SNUM(handle->conn), tsmname, 
-				    "online ratio", TSM_TOSTRING(FILE_IS_ONLINE_RATIO));
-	tsmd->online_ratio = strtof(fres, NULL);
-	if((tsmd->online_ratio == (float)0) || ((errno == ERANGE) &&
-						((tsmd->online_ratio == HUGE_VALF) ||
-						 (tsmd->online_ratio == HUGE_VALL)))) {
-		DEBUG(1, ("tsmsm_connect: error while getting online ratio from smb.conf."
-			  "Default to %s.\n", TSM_TOSTRING(FILE_IS_ONLINE_RATIO)));
+				    "online ratio", NULL);
+	if (fres == NULL) {
 		tsmd->online_ratio = FILE_IS_ONLINE_RATIO;
+	} else {
+		tsmd->online_ratio = strtof(fres, NULL);
+		if (tsmd->online_ratio > 1.0 ||
+		    tsmd->online_ratio <= 0.0) {
+			DEBUG(1, ("tsmsm_connect: invalid online ration %f - using %f.\n",
+				  tsmd->online_ratio, (float)FILE_IS_ONLINE_RATIO));
+		}
 	}
 
         /* Store the private data. */
@@ -140,12 +136,14 @@ static bool tsmsm_is_offline(struct vfs_handle_struct *handle,
 			    const char *path,
 			    SMB_STRUCT_STAT *stbuf) {
 	struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
+	const dm_sessid_t *dmsession_id;
 	void *dmhandle = NULL;
 	size_t dmhandle_len = 0;
 	size_t rlen;
 	dm_attrname_t dmname;
-	int ret;
+	int ret, lerrno;
 	bool offline;
+	char buf[1];
 
         /* if the file has more than FILE_IS_ONLINE_RATIO of blocks available,
 	   then assume it is not offline (it may not be 100%, as it could be sparse) */
@@ -154,7 +152,14 @@ static bool tsmsm_is_offline(struct vfs_handle_struct *handle,
 			  path, stbuf->st_blocks, stbuf->st_size, tsmd->online_ratio));
 		return false;
 	}
-	
+
+	dmsession_id = dmapi_get_current_session();
+	if (dmsession_id == NULL) {
+		DEBUG(2, ("tsmsm_is_offline: no DMAPI session available? "
+			  "Assume file is online.\n"));
+		return false;
+	}
+
         /* using POSIX capabilities does not work here. It's a slow path, so 
 	 * become_root() is just as good anyway (tridge) 
 	 */
@@ -173,12 +178,30 @@ static bool tsmsm_is_offline(struct vfs_handle_struct *handle,
 	}
 
 	memset(&dmname, 0, sizeof(dmname));
-	strlcpy((char *)&dmname.an_chars[0], DM_ATTRIB_OBJECT, sizeof(dmname.an_chars));
-
-	ret = dm_get_dmattr(tsmd->sid, dmhandle, dmhandle_len, 
-			    DM_NO_TOKEN, &dmname, 0, NULL, &rlen);
+	strlcpy((char *)&dmname.an_chars[0], tsmd->attrib_name, sizeof(dmname.an_chars));
+
+	lerrno = 0;
+
+	do {
+		ret = dm_get_dmattr(*dmsession_id, dmhandle, dmhandle_len, 
+				    DM_NO_TOKEN, &dmname, sizeof(buf), buf, &rlen);
+		if (ret == -1 && errno == EINVAL) {
+			DEBUG(0, ("Stale DMAPI session, re-creating it.\n"));
+			lerrno = EINVAL;
+			if (dmapi_new_session()) {
+				dmsession_id = dmapi_get_current_session();
+			} else {
+				DEBUG(0, 
+				      ("Unable to re-create DMAPI session, assuming offline (%s) - %s\n", 
+				       path, strerror(errno)));
+				offline = true;
+				dm_handle_free(dmhandle, dmhandle_len);
+				goto done;
+			}
+		}
+	} while (ret == -1 && lerrno == EINVAL);
 
-	/* its offline if the IBMObj attribute exists */
+	/* its offline if the specified DMAPI attribute exists */
 	offline = (ret == 0 || (ret == -1 && errno == E2BIG));
 
 	DEBUG(10,("dm_get_dmattr %s ret=%d (%s)\n", path, ret, strerror(errno)));
@@ -280,6 +303,12 @@ static int tsmsm_set_offline(struct vfs_handle_struct *handle,
 	int result = 0;
 	char *command;
 
+	if (tsmd->hsmscript == NULL) {
+		/* no script enabled */
+		DEBUG(1, ("tsmsm_set_offline: No tsmsm:hsmscript configured\n"));
+		return 0;
+	}
+
 	/* Now, call the script */
 	command = talloc_asprintf(tsmd, "%s offline \"%s\"", tsmd->hsmscript, path);
 	if(!command) {
@@ -294,14 +323,9 @@ static int tsmsm_set_offline(struct vfs_handle_struct *handle,
 	return result;
 }
 
-static bool tsmsm_statvfs(struct vfs_handle_struct *handle,  const char *path, vfs_statvfs_struct *statbuf)
+static uint32_t tsmsm_fs_capabilities(struct vfs_handle_struct *handle)
 {
-	bool result;
-
-	result = SMB_VFS_NEXT_STATVFS(handle, path, statbuf);
-	statbuf->FsCapabilities | = FILE_SUPPORTS_REMOTE_STORAGE | FILE_SUPPORTS_REPARSE_POINTS;
-
-	return result;
+	return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_SUPPORTS_REMOTE_STORAGE | FILE_SUPPORTS_REPARSE_POINTS;
 }
 
 static vfs_op_tuple vfs_tsmsm_ops[] = {
@@ -310,7 +334,7 @@ static vfs_op_tuple vfs_tsmsm_ops[] = {
 
 	{SMB_VFS_OP(tsmsm_connect),	SMB_VFS_OP_CONNECT,
 	 SMB_VFS_LAYER_TRANSPARENT},
-	{SMB_VFS_OP(tsmsm_statvfs),	SMB_VFS_OP_STATVFS,
+	{SMB_VFS_OP(tsmsm_fs_capabilities),	SMB_VFS_OP_FS_CAPABILITIES,
 	 SMB_VFS_LAYER_TRANSPARENT},
 	{SMB_VFS_OP(tsmsm_aio_force),	SMB_VFS_OP_AIO_FORCE,
 	 SMB_VFS_LAYER_TRANSPARENT},
diff --git a/source/smbd/dmapi.c b/source/smbd/dmapi.c
index 620baf1..fab0d5f 100644
--- a/source/smbd/dmapi.c
+++ b/source/smbd/dmapi.c
@@ -25,9 +25,9 @@
 
 #ifndef USE_DMAPI
 
-int dmapi_init_session(void) { return -1; }
 uint32 dmapi_file_flags(const char * const path) { return 0; }
 bool dmapi_have_session(void) { return False; }
+const void * dmapi_get_current_session(void) { return NULL; }
 
 #else /* USE_DMAPI */
 
@@ -47,98 +47,75 @@ bool dmapi_have_session(void) { return False; }
 #define DMAPI_TRACE 10
 
 static dm_sessid_t samba_dmapi_session = DM_NO_SESSION;
+static unsigned session_num;
 
-/* Initialise the DMAPI interface. Make sure that we only end up initialising
- * once per process to avoid resource leaks across different DMAPI
- * implementations.
- */
-static int init_dmapi_service(void)
-{
-	static pid_t lastpid;
-
-	pid_t mypid;
-
-	mypid = sys_getpid();
-	if (mypid != lastpid) {
-		char *version;
-
-		lastpid = mypid;
-		if (dm_init_service(&version) < 0) {
-			return -1;
-		}
-
-		DEBUG(0, ("Initializing DMAPI: %s\n", version));
-	}
-
-	return 0;
-}
-
-bool dmapi_have_session(void)
-{
-	return samba_dmapi_session != DM_NO_SESSION;
-}
-
-static dm_sessid_t *realloc_session_list(dm_sessid_t * sessions, int count)
-{
-	dm_sessid_t *nsessions;
-
-	nsessions = TALLOC_REALLOC_ARRAY(NULL, sessions, dm_sessid_t, count);
-	if (nsessions == NULL) {
-		TALLOC_FREE(sessions);
-		return NULL;
-	}
-
-	return nsessions;
-}
-
-/* Initialise DMAPI session. The session is persistant kernel state, so it
- * might already exist, in which case we merely want to reconnect to it. This
- * function should be called as root.
- */
-int dmapi_init_session(void)
+/* 
+   Initialise DMAPI session. The session is persistant kernel state, 
+   so it might already exist, in which case we merely want to 
+   reconnect to it. This function should be called as root.
+*/
+static int dmapi_init_session(void)
 {
 	char	buf[DM_SESSION_INFO_LEN];
 	size_t	buflen;
-
-	uint	    nsessions = 10;
+	uint	    nsessions = 5;
 	dm_sessid_t *sessions = NULL;
+	char    *version;
+	char    *session_name;
+	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
 
 	int i, err;
 
-	/* If we aren't root, something in the following will fail due to lack
-	 * of privileges. Aborting seems a little extreme.
-	 */
-	SMB_WARN(getuid() == 0, "dmapi_init_session must be called as root");
+	if (session_num == 0) {
+		session_name = DMAPI_SESSION_NAME;
+	} else {
+		session_name = talloc_asprintf(tmp_ctx, "%s%u", DMAPI_SESSION_NAME,
+					       session_num);
+	}
 
-	samba_dmapi_session = DM_NO_SESSION;
-	if (init_dmapi_service() < 0) {
+	if (session_name == NULL) {
+		DEBUG(0,("Out of memory in dmapi_init_session\n"));
+		talloc_free(tmp_ctx);
 		return -1;
 	}
+ 
 
-retry:
-
-	if ((sessions = realloc_session_list(sessions, nsessions)) == NULL) {
+	if (dm_init_service(&version) < 0) {
+		DEBUG(0, ("dm_init_service failed - disabling DMAPI\n"));
+		talloc_free(tmp_ctx);
 		return -1;
 	}
 
-	err = dm_getall_sessions(nsessions, sessions, &nsessions);
-	if (err < 0) {
-		if (errno == E2BIG) {
-			nsessions *= 2;
-			goto retry;
+	ZERO_STRUCT(buf);
+
+	/* Fetch kernel DMAPI sessions until we get any of them */
+	do {
+		dm_sessid_t *new_sessions;
+		nsessions *= 2;
+		new_sessions = TALLOC_REALLOC_ARRAY(tmp_ctx, sessions, 
+						    dm_sessid_t, nsessions);
+		if (new_sessions == NULL) {
+			talloc_free(tmp_ctx);
+			return -1;
 		}
 
+		sessions = new_sessions;
+		err = dm_getall_sessions(nsessions, sessions, &nsessions);
+	} while (err == -1 && errno == E2BIG);
+
+	if (err == -1) {
 		DEBUGADD(DMAPI_TRACE,
 			("failed to retrieve DMAPI sessions: %s\n",
 			strerror(errno)));
-		TALLOC_FREE(sessions);
+		talloc_free(tmp_ctx);
 		return -1;
 	}
 
+	/* Look through existing kernel DMAPI sessions to find out ours */
 	for (i = 0; i < nsessions; ++i) {
 		err = dm_query_session(sessions[i], sizeof(buf), buf, &buflen);
 		buf[sizeof(buf) - 1] = '\0';
-		if (err == 0 && strcmp(DMAPI_SESSION_NAME, buf) == 0) {
+		if (err == 0 && strcmp(session_name, buf) == 0) {
 			samba_dmapi_session = sessions[i];
 			DEBUGADD(DMAPI_TRACE,
 				("attached to existing DMAPI session "
@@ -147,106 +124,121 @@ retry:
 		}
 	}
 
-	TALLOC_FREE(sessions);
-
 	/* No session already defined. */
 	if (samba_dmapi_session == DM_NO_SESSION) {
 		err = dm_create_session(DM_NO_SESSION, 
-					CONST_DISCARD(char *, DMAPI_SESSION_NAME),
+					session_name,
 					&samba_dmapi_session);
 		if (err < 0) {
 			DEBUGADD(DMAPI_TRACE,
 				("failed to create new DMAPI session: %s\n",
 				strerror(errno)));
 			samba_dmapi_session = DM_NO_SESSION;
+			talloc_free(tmp_ctx);
 			return -1;
 		}
 
-		DEBUGADD(DMAPI_TRACE,
-			("created new DMAPI session named '%s'\n",
-			DMAPI_SESSION_NAME));
+		DEBUG(0, ("created new DMAPI session named '%s' for %s\n",
+			  session_name, version));
 	}
 
-	/* Note that we never end the DMAPI session. This enables child
-	 * processes to continue to use the session after we exit. It also lets
-	 * you run a second Samba server on different ports without any
-	 * conflict.
+	if (samba_dmapi_session != DM_NO_SESSION) {
+		set_effective_capability(DMAPI_ACCESS_CAPABILITY);
+	}
+
+	/* 
+	   Note that we never end the DMAPI session. It gets re-used if possiblie. 
+	   DMAPI session is a kernel resource that is usually lives until server reboot
+	   and doesn't get destroed when an application finishes.
+
+	   However, we free list of references to DMAPI sessions we've got from the kernel
+	   as it is not needed anymore once we have found (or created) our session.
 	 */
 
+	talloc_free(tmp_ctx);
 	return 0;
 }
 
-/* Reattach to an existing dmapi session. Called from service processes that
- * might not be running as root.
- */
-static int reattach_dmapi_session(void)
+/*
+  Return a pointer to our DMAPI session, if available.
+  This assumes that you have called dmapi_have_session() first.
+*/
+const void *dmapi_get_current_session(void)
 {
-	char	buf[DM_SESSION_INFO_LEN];
-	size_t	buflen;
-
-	if (samba_dmapi_session != DM_NO_SESSION ) {
-		become_root();
-
-		/* NOTE: On Linux, this call opens /dev/dmapi, costing us a
-		 * file descriptor. Ideally, we would close this when we fork.
-		 */
-		if (init_dmapi_service() < 0) {
-			samba_dmapi_session = DM_NO_SESSION;
-			unbecome_root();
-			return -1;
-		}
+	if (samba_dmapi_session == DM_NO_SESSION) {
+		return NULL;
+	}
 
-		if (dm_query_session(samba_dmapi_session, sizeof(buf),
-			    buf, &buflen) < 0) {
-			/* Session is stale. Disable DMAPI. */
-			samba_dmapi_session = DM_NO_SESSION;
-			unbecome_root();
-			return -1;
-		}
+	return (void *)&samba_dmapi_session;
+}
+	
+/*
+  dmapi_have_session() must be the first DMAPI call you make in Samba. It will
+  initialize DMAPI, if available, and tell you if you can get a DMAPI session.
+  This should be called in the client-specific child process.
+*/
 
-		set_effective_capability(DMAPI_ACCESS_CAPABILITY);
+bool dmapi_have_session(void)
+{
+	static bool initialized;
+	if (!initialized) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list