1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

support volfile fetch from multiple glusterd nodes

glusterfs:volfile_server option can be used in smb.conf to define where
to fetch the volfile from. Currently it supports only a single IP or a
hostname. The default is 'localhost'.

glfs_set_volfile_server() has been enhanced in gfapi to support
multiple invocations. A list is maintained in libgfapi which gets
appended on every invocation. When glfs_init is performed, libgfapi
would first try to fetch the volfile from glusterd on that node.
However, on failure to fetch the volfile, it would proceed to contact
glusterd on every node in the list until it gets the volfile or
exhausts the list. This enhacement was done in Gluster commit [2].
This commit is available in 3.6, 3.7, 3.8 versions of Gluster.

As we cannot have multiple lines having the same key of
glusterfs:volfile_server in a share definition in smb.conf, we propose
a scheme like this:

where value of glusterfs:volfile_server could be list of white space seperated
elements where each element could be unix+/path/to/socket/file or
[tcp+]IP|hostname|\[IPv6\][:port].

Note the restriction on naming a IPv6 host, it follows the same
restriction that is based on IPv6 naming in URL as per RFC 2732[1].

[1] http://www.ietf.org/rfc/rfc2732.txt
[2] 0c1d78f5c52c69268ec3a1d8d5fcb1a1bf15f243

Signed-off-by: Raghavendra Talur <rtalur@redhat.com>

Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>

Autobuild-User(master): Günther Deschner <gd@samba.org>
Autobuild-Date(master): Fri Oct 14 17:09:24 CEST 2016 on sn-devel-144
This commit is contained in:
Raghavendra Talur 2016-08-25 16:03:55 +05:30 committed by Günther Deschner
parent 1d2d0c34fc
commit 857745655b
2 changed files with 130 additions and 14 deletions

View File

@ -131,7 +131,19 @@
<listitem>
<para>
Defines which volfile server to use, defaults to
localhost.
localhost. It could be list of white space
seperated elements where each element could be
</para>
<para>
1. unix+/path/to/socket/file
</para>
<para>
2. [tcp+]IP|hostname|\[IPv6\][:port]
</para>
<para>
Note the restriction on naming a IPv6 host, it follows
the same restriction that is based on IPv6 naming in
URL as per RFC 2732.
</para>
</listitem>
</varlistentry>
@ -153,7 +165,7 @@
<title>VERSION</title>
<para>
This man page is correct for version 4.2.0 of the Samba suite.
This man page is correct for version 4.6.0 of the Samba suite.
</para>
</refsect1>

View File

@ -157,13 +157,116 @@ static void glfs_clear_preopened(glfs_t *fs)
}
}
static int vfs_gluster_set_volfile_servers(glfs_t *fs,
const char *volfile_servers)
{
char *server = NULL;
int server_count = 0;
int server_success = 0;
int ret = -1;
TALLOC_CTX *frame = talloc_stackframe();
DBG_INFO("servers list %s\n", volfile_servers);
while (next_token_talloc(frame, &volfile_servers, &server, " \t")) {
char *transport = NULL;
char *host = NULL;
int port = 0;
server_count++;
DBG_INFO("server %d %s\n", server_count, server);
/* Determine the transport type */
if (strncmp(server, "unix+", 5) == 0) {
port = 0;
transport = talloc_strdup(frame, "unix");
if (!transport) {
errno = ENOMEM;
goto out;
}
host = talloc_strdup(frame, server + 5);
if (!host) {
errno = ENOMEM;
goto out;
}
} else {
char *p = NULL;
char *port_index = NULL;
if (strncmp(server, "tcp+", 4) == 0) {
server += 4;
}
/* IPv6 is enclosed in []
* ':' before ']' is part of IPv6
* ':' after ']' indicates port
*/
p = server;
if (server[0] == '[') {
server++;
p = index(server, ']');
if (p == NULL) {
/* Malformed IPv6 */
continue;
}
p[0] = '\0';
p++;
}
port_index = index(p, ':');
if (port_index == NULL) {
port = 0;
} else {
port = atoi(port_index + 1);
port_index[0] = '\0';
}
transport = talloc_strdup(frame, "tcp");
if (!transport) {
errno = ENOMEM;
goto out;
}
host = talloc_strdup(frame, server);
if (!host) {
errno = ENOMEM;
goto out;
}
}
DBG_INFO("Calling set volfile server with params "
"transport=%s, host=%s, port=%d\n", transport,
host, port);
ret = glfs_set_volfile_server(fs, transport, host, port);
if (ret < 0) {
DBG_WARNING("Failed to set volfile_server "
"transport=%s, host=%s, port=%d (%s)\n",
transport, host, port, strerror(errno));
} else {
server_success++;
}
}
out:
if (server_count == 0) {
ret = -1;
} else if (server_success < server_count) {
DBG_WARNING("Failed to set %d out of %d servers parsed\n",
server_count - server_success, server_count);
ret = 0;
}
TALLOC_FREE(frame);
return ret;
}
/* Disk Operations */
static int vfs_gluster_connect(struct vfs_handle_struct *handle,
const char *service,
const char *user)
{
const char *volfile_server;
const char *volfile_servers;
const char *volume;
char *logfile;
int loglevel;
@ -181,10 +284,11 @@ static int vfs_gluster_connect(struct vfs_handle_struct *handle,
loglevel = lp_parm_int(SNUM(handle->conn), "glusterfs", "loglevel", -1);
volfile_server = lp_parm_const_string(SNUM(handle->conn), "glusterfs",
"volfile_server", NULL);
if (volfile_server == NULL) {
volfile_server = DEFAULT_VOLFILE_SERVER;
volfile_servers = lp_parm_talloc_string(tmp_ctx, SNUM(handle->conn),
"glusterfs", "volfile_server",
NULL);
if (volfile_servers == NULL) {
volfile_servers = DEFAULT_VOLFILE_SERVER;
}
volume = lp_parm_const_string(SNUM(handle->conn), "glusterfs", "volume",
@ -204,9 +308,10 @@ static int vfs_gluster_connect(struct vfs_handle_struct *handle,
goto done;
}
ret = glfs_set_volfile_server(fs, "tcp", volfile_server, 0);
ret = vfs_gluster_set_volfile_servers(fs, volfile_servers);
if (ret < 0) {
DEBUG(0, ("Failed to set volfile_server %s\n", volfile_server));
DBG_ERR("Failed to set volfile_servers from list %s\n",
volfile_servers);
goto done;
}
@ -248,17 +353,16 @@ static int vfs_gluster_connect(struct vfs_handle_struct *handle,
goto done;
}
done:
talloc_free(tmp_ctx);
if (ret < 0) {
if (fs)
glfs_fini(fs);
return -1;
} else {
DEBUG(0, ("%s: Initialized volume from server %s\n",
volume, volfile_server));
DBG_ERR("%s: Initialized volume from servers %s\n",
volume, volfile_servers);
handle->data = fs;
return 0;
}
talloc_free(tmp_ctx);
return ret;
}
static void vfs_gluster_disconnect(struct vfs_handle_struct *handle)