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:
parent
1d2d0c34fc
commit
857745655b
@ -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>
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user