[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-304-ge5136e9

Jeremy Allison jra at samba.org
Fri Mar 13 01:14:40 GMT 2009


The branch, master has been updated
       via  e5136e984922570ce9992c642c340dd3e937fc4e (commit)
      from  bace42d586f2e4364e5b66ccc80a0b19749b5e1c (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit e5136e984922570ce9992c642c340dd3e937fc4e
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 12 17:59:24 2009 -0700

    Remove the static "struct client_connection" mess which is part of
    the problem that stops libsmbclient being thread safe. Subsidiary
    DFS connections are now hung off a list inside the cli_state struct.
    Much more to do in order to get libsmbclient to thread safety, but
    this is a good start.
    Jeremy.

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

Summary of changes:
 source3/client/client.c    |   22 +++---
 source3/include/client.h   |    7 ++
 source3/include/proto.h    |    4 +-
 source3/lib/netapi/cm.c    |   28 +++++---
 source3/libsmb/clidfs.c    |  162 +++++++++++++++-----------------------------
 source3/libsmb/clientgen.c |   28 +++++++-
 source3/libsmb/clilist.c   |    5 +-
 7 files changed, 117 insertions(+), 139 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/client/client.c b/source3/client/client.c
index aaa9e35..6491f39 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -1419,7 +1419,7 @@ static bool do_altname(const char *name)
 
 static int cmd_quit(void)
 {
-	cli_cm_shutdown();
+	cli_shutdown(cli);
 	exit(0);
 	/* NOTREACHED */
 	return 0;
@@ -1714,7 +1714,7 @@ static int do_put(const char *rname, const char *lname, bool reput)
 	}
 
 	if (f == x_stdin) {
-		cli_cm_shutdown();
+		cli_shutdown(cli);
 		exit(0);
 	}
 
@@ -3815,7 +3815,7 @@ static int cmd_logon(void)
 
 static int cmd_list_connect(void)
 {
-	cli_cm_display();
+	cli_cm_display(cli);
 	return 0;
 }
 
@@ -4526,7 +4526,7 @@ static int process(const char *base_directory)
 	if (base_directory && *base_directory) {
 		rc = do_cd(base_directory);
 		if (rc) {
-			cli_cm_shutdown();
+			cli_shutdown(cli);
 			return rc;
 		}
 	}
@@ -4537,7 +4537,7 @@ static int process(const char *base_directory)
 		process_stdin();
 	}
 
-	cli_cm_shutdown();
+	cli_shutdown(cli);
 	return rc;
 }
 
@@ -4568,7 +4568,7 @@ static int do_host_query(const char *query_host)
 		/* Workgroups simply don't make sense over anything
 		   else but port 139... */
 
-		cli_cm_shutdown();
+		cli_shutdown(cli);
 		cli = cli_cm_open(talloc_tos(), NULL,
 				query_host, "IPC$", true, smb_encrypt,
 				max_protocol, 139, name_type);
@@ -4581,7 +4581,7 @@ static int do_host_query(const char *query_host)
 
 	list_servers(lp_workgroup());
 
-	cli_cm_shutdown();
+	cli_shutdown(cli);
 
 	return(0);
 }
@@ -4609,14 +4609,14 @@ static int do_tar_op(const char *base_directory)
 	if (base_directory && *base_directory)  {
 		ret = do_cd(base_directory);
 		if (ret) {
-			cli_cm_shutdown();
+			cli_shutdown(cli);
 			return ret;
 		}
 	}
 
 	ret=process_tar();
 
-	cli_cm_shutdown();
+	cli_shutdown(cli);
 
 	return(ret);
 }
@@ -4663,12 +4663,12 @@ static int do_message_op(struct user_auth_info *auth_info)
 
 	if (!cli_session_request(cli, &calling, &called)) {
 		d_printf("session request failed\n");
-		cli_cm_shutdown();
+		cli_shutdown(cli);
 		return 1;
 	}
 
 	send_message(get_cmdline_auth_info_username(auth_info));
-	cli_cm_shutdown();
+	cli_shutdown(cli);
 
 	return 0;
 }
diff --git a/source3/include/client.h b/source3/include/client.h
index 646d54a..eae22fd 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -167,6 +167,10 @@ struct smb_trans_enc_state {
 };
 
 struct cli_state {
+	/**
+	 * A list of subsidiary connections for DFS.
+	 */
+        struct cli_state *prev, *next;
 	int port;
 	int fd;
 	/* Last read or write error. */
@@ -276,6 +280,9 @@ struct cli_state {
 	 * chained async_req.
 	 */
 	struct cli_request *chain_accumulator;
+
+	/* Where (if anywhere) this is mounted under DFS. */
+	char *dfs_mountpoint;
 };
 
 typedef struct file_info {
diff --git a/source3/include/proto.h b/source3/include/proto.h
index c8a066f..40024c5 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2355,7 +2355,6 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c,
 			const char *password,
 			const char *domain,
 			const char *sharename);
-const char *cli_cm_get_mntpoint(struct cli_state *c);
 struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
 				struct cli_state *referring_cli,
 				const char *server,
@@ -2365,8 +2364,7 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
 				int max_protocol,
 				int port,
 				int name_type);
-void cli_cm_shutdown(void);
-void cli_cm_display(void);
+void cli_cm_display(const struct cli_state *c);
 void cli_cm_set_credentials(struct user_auth_info *auth_info);
 void cli_cm_set_port(int port_number);
 void cli_cm_set_dest_name_type(int type);
diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c
index 233255f..43ebed6 100644
--- a/source3/lib/netapi/cm.c
+++ b/source3/lib/netapi/cm.c
@@ -73,19 +73,10 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
 /********************************************************************
 ********************************************************************/
 
-WERROR libnetapi_shutdown_cm(struct libnetapi_ctx *ctx)
-{
-	cli_cm_shutdown();
-
-	return WERR_OK;
-}
-
-/********************************************************************
-********************************************************************/
-
 struct client_pipe_connection {
 	struct client_pipe_connection *prev, *next;
 	struct rpc_pipe_client *pipe;
+	struct cli_state *cli;
 };
 
 static struct client_pipe_connection *pipe_connections;
@@ -93,6 +84,20 @@ static struct client_pipe_connection *pipe_connections;
 /********************************************************************
 ********************************************************************/
 
+WERROR libnetapi_shutdown_cm(struct libnetapi_ctx *ctx)
+{
+	struct client_pipe_connection *p;
+
+	for (p = pipe_connections; p; p = p->next) {
+		cli_shutdown(p->cli);
+	}
+
+	return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
 static NTSTATUS pipe_cm_find(struct cli_state *cli,
 			     const struct ndr_syntax_id *interface,
 			     struct rpc_pipe_client **presult)
@@ -138,6 +143,7 @@ static NTSTATUS pipe_cm_connect(TALLOC_CTX *mem_ctx,
 		return status;
 	}
 
+	p->cli = cli;
 	DLIST_ADD(pipe_connections, p);
 
 	*presult = p->pipe;
@@ -193,5 +199,3 @@ WERROR libnetapi_open_pipe(struct libnetapi_ctx *ctx,
 
 	return WERR_OK;
 }
-
-
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 1153d8d..8544d55 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -3,7 +3,7 @@
    client connect/disconnect routines
    Copyright (C) Andrew Tridgell                  1994-1998
    Copyright (C) Gerald (Jerry) Carter            2004
-   Copyright (C) Jeremy Allison                   2007
+   Copyright (C) Jeremy Allison                   2007-2009
 
    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
@@ -32,12 +32,6 @@
    as a separator when looking at the pathname part.... JRA.
 ********************************************************************/
 
-struct client_connection {
-	struct client_connection *prev, *next;
-	struct cli_state *cli;
-	char *mount;
-};
-
 static struct cm_cred_struct {
 	char *username;
 	char *password;
@@ -49,8 +43,6 @@ static struct cm_cred_struct {
 
 static void cm_set_password(const char *newpass);
 
-static struct client_connection *connections;
-
 static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 				struct cli_state *cli,
 				const char *sharename,
@@ -96,7 +88,7 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c,
 
 	return status;
 }
-	
+
 /********************************************************************
  Return a connection to a server.
 ********************************************************************/
@@ -301,52 +293,20 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
 /****************************************************************************
 ****************************************************************************/
 
-static void cli_cm_set_mntpoint(struct cli_state *c, const char *mnt)
-{
-	struct client_connection *p;
-	int i;
-
-	for (p=connections,i=0; p; p=p->next,i++) {
-		if (strequal(p->cli->desthost, c->desthost) &&
-				strequal(p->cli->share, c->share)) {
-			break;
-		}
-	}
-
-	if (p) {
-		char *name = clean_name(NULL, mnt);
-		if (!name) {
-			return;
-		}
-		TALLOC_FREE(p->mount);
-		p->mount = talloc_strdup(p, name);
-		TALLOC_FREE(name);
-	}
-}
-
-/****************************************************************************
-****************************************************************************/
-
-const char *cli_cm_get_mntpoint(struct cli_state *c)
+static void cli_set_mntpoint(struct cli_state *cli, const char *mnt)
 {
-	struct client_connection *p;
-	int i;
-
-	for (p=connections,i=0; p; p=p->next,i++) {
-		if (strequal(p->cli->desthost, c->desthost) &&
-				strequal(p->cli->share, c->share)) {
-			break;
-		}
-	}
-
-	if (p) {
-		return p->mount;
+	char *name = clean_name(NULL, mnt);
+	if (!name) {
+		return;
 	}
-	return NULL;
+	TALLOC_FREE(cli->dfs_mountpoint);
+	cli->dfs_mountpoint = talloc_strdup(cli, name);
+	TALLOC_FREE(name);
 }
 
 /********************************************************************
- Add a new connection to the list
+ Add a new connection to the list.
+ referring_cli == NULL means a new initial connection.
 ********************************************************************/
 
 static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
@@ -359,53 +319,62 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
 					int port,
 					int name_type)
 {
-	struct client_connection *node;
-
-	/* NB This must be the null context here... JRA. */
-	node = TALLOC_ZERO_ARRAY(NULL, struct client_connection, 1);
-	if (!node) {
-		return NULL;
-	}
+	struct cli_state *cli;
 
-	node->cli = do_connect(ctx, server, share,
+	cli = do_connect(ctx, server, share,
 				show_hdr, force_encrypt, max_protocol,
 				port, name_type);
 
-	if ( !node->cli ) {
-		TALLOC_FREE( node );
+	if (!cli ) {
 		return NULL;
 	}
 
-	DLIST_ADD( connections, node );
-
-	cli_cm_set_mntpoint(node->cli, "");
+	/* Enter into the list. */
+	if (referring_cli) {
+		DLIST_ADD_END(referring_cli, cli, struct cli_state *);
+	}
 
 	if (referring_cli && referring_cli->posix_capabilities) {
 		uint16 major, minor;
 		uint32 caplow, caphigh;
-		if (cli_unix_extensions_version(node->cli, &major,
+		if (cli_unix_extensions_version(cli, &major,
 					&minor, &caplow, &caphigh)) {
-			cli_set_unix_extensions_capabilities(node->cli,
+			cli_set_unix_extensions_capabilities(cli,
 					major, minor,
 					caplow, caphigh);
 		}
 	}
 
-	return node->cli;
+	return cli;
 }
 
 /********************************************************************
- Return a connection to a server.
+ Return a connection to a server on a particular share.
 ********************************************************************/
 
-static struct cli_state *cli_cm_find(const char *server, const char *share)
+static struct cli_state *cli_cm_find(struct cli_state *cli,
+				const char *server,
+				const char *share)
 {
-	struct client_connection *p;
+	struct cli_state *p;
 
-	for (p=connections; p; p=p->next) {
-		if ( strequal(server, p->cli->desthost) &&
-				strequal(share,p->cli->share)) {
-			return p->cli;
+	if (cli == NULL) {
+		return NULL;
+	}
+
+	/* Search to the start of the list. */
+	for (p = cli; p; p = p->prev) {
+		if (strequal(server, p->desthost) &&
+				strequal(share,p->share)) {
+			return p;
+		}
+	}
+
+	/* Search to the end of the list. */
+	for (p = cli->next; p; p = p->next) {
+		if (strequal(server, p->desthost) &&
+				strequal(share,p->share)) {
+			return p;
 		}
 	}
 
@@ -413,8 +382,7 @@ static struct cli_state *cli_cm_find(const char *server, const char *share)
 }
 
 /****************************************************************************
- Open a client connection to a \\server\share.  Set's the current *cli
- global variable as a side-effect (but only if the connection is successful).
+ Open a client connection to a \\server\share.
 ****************************************************************************/
 
 struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
@@ -427,50 +395,28 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
 				int port,
 				int name_type)
 {
-	struct cli_state *c;
+	/* Try to reuse an existing connection in this list. */
+	struct cli_state *c = cli_cm_find(referring_cli, server, share);
 
-	/* try to reuse an existing connection */
+	if (c) {
+		return c;
+	}
 
-	c = cli_cm_find(server, share);
-	if (!c) {
-		c = cli_cm_connect(ctx, referring_cli,
+	return cli_cm_connect(ctx, referring_cli,
 				server, share, show_hdr, force_encrypt,
 				max_protocol, port, name_type);
-	}
-
-	return c;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_shutdown(void)
-{
-	struct client_connection *p, *x;
-
-	for (p=connections; p;) {
-		cli_shutdown(p->cli);
-		x = p;
-		p = p->next;
-
-		TALLOC_FREE(x);
-	}
-
-	connections = NULL;
-	return;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-void cli_cm_display(void)
+void cli_cm_display(const struct cli_state *cli)
 {
-	struct client_connection *p;
 	int i;
 
-	for ( p=connections,i=0; p; p=p->next,i++ ) {
+	for (i=0; cli; cli = cli->next,i++ ) {
 		d_printf("%d:\tserver=%s, share=%s\n",
-			i, p->cli->desthost, p->cli->share );
+			i, cli->desthost, cli->share );
 	}
 }
 
@@ -998,7 +944,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
 		return false;
 	}
 
-	cli_cm_set_mntpoint(*targetcli, newmount);
+	cli_set_mntpoint(*targetcli, newmount);
 
 	/* Check for another dfs referral, note that we are not
 	   checking for loops here. */
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 2983f77..7c42da4 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -425,7 +425,7 @@ void cli_init_creds(struct cli_state *cli, const char *username, const char *dom
 }
 
 /****************************************************************************
- Initialise a client structure. Always returns a malloc'ed struct.
+ Initialise a client structure. Always returns a talloc'ed struct.
  Set the signing state (used from the command line).
 ****************************************************************************/
 
@@ -446,6 +446,11 @@ struct cli_state *cli_initialise_ex(int signing_state)
 		return NULL;
 	}
 
+	cli->dfs_mountpoint = talloc_strdup(cli, "");
+	if (!cli->dfs_mountpoint) {
+		TALLOC_FREE(cli);
+		return NULL;
+	}
 	cli->port = 0;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list