gfapi: glfs_set_volfile_server() now entertains multiple calls

Previous API:

glfs_set_volfile_server (..., const char *host, ...) - single call

New API's:

glfs_set_volfile_server (..., const char *host1, ...)
glfs_set_volfile_server (..., const char *host2, ...)

Multiple calls to this function with different volfile servers,
port or transport-type would create a list of volfile servers
which would be polled during `volfile_fetch_attempts()`

glfs_unset_volfile_server (..., const char *host, ...) to remove
a server from the list (this is provided for future usage)

Change-Id: I313efbd3efbd0214e2a71465f33195788df406cc
BUG: 986429
Signed-off-by: Harshavardhana <harsha@harshavardhana.net>
Reviewed-on: http://review.gluster.org/7317
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Niels de Vos <ndevos@redhat.com>
Reviewed-by: Anand Avati <avati@redhat.com>
This commit is contained in:
Harshavardhana 2014-03-22 01:33:06 -07:00 committed by Anand Avati
parent e7dcc7f824
commit 0c1d78f5c5
6 changed files with 192 additions and 55 deletions

View File

@ -5,8 +5,8 @@ import ctypes.util
api = ctypes.CDLL(ctypes.util.find_library("gfapi"))
api.glfs_get_volfile.argtypes = [ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_ulong]
ctypes.c_void_p,
ctypes.c_ulong]
api.glfs_get_volfile.restype = ctypes.c_long;
def get_volfile (host, volume):

View File

@ -23,10 +23,10 @@ enum glfs_mem_types_ {
glfs_mt_glfs_io_t,
glfs_mt_volfile_t,
glfs_mt_xlator_cmdline_option_t,
glfs_mt_server_cmdline_t,
glfs_mt_glfs_object_t,
glfs_mt_readdirbuf_t,
glfs_mt_end
};
#endif

View File

@ -425,36 +425,85 @@ mgmt_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
void *data)
{
xlator_t *this = NULL;
cmd_args_t *cmd_args = NULL;
glusterfs_ctx_t *ctx = NULL;
server_cmdline_t *server = NULL;
rpc_transport_t *rpc_trans = NULL;
struct glfs *fs = NULL;
int ret = 0;
this = mydata;
ctx = this->ctx;
rpc_trans = rpc->conn.trans;
ctx = this->ctx;
if (!ctx)
goto out;
fs = ((xlator_t *)ctx->master)->private;
cmd_args = &ctx->cmd_args;
switch (event) {
case RPC_CLNT_DISCONNECT:
if (!ctx->active) {
cmd_args->max_connect_attempts--;
gf_log ("glfs-mgmt", GF_LOG_ERROR,
"failed to connect with remote-host: %s",
strerror (errno));
gf_log ("glfs-mgmt", GF_LOG_INFO,
"%d connect attempts left",
cmd_args->max_connect_attempts);
if (0 >= cmd_args->max_connect_attempts) {
errno = ENOTCONN;
glfs_init_done (fs, -1);
}
}
break;
gf_log ("glfs-mgmt", GF_LOG_ERROR,
"failed to connect with remote-host: %s (%s)",
ctx->cmd_args.volfile_server,
strerror (errno));
server = ctx->cmd_args.curr_server;
if (server->list.next == &ctx->cmd_args.volfile_servers) {
errno = ENOTCONN;
gf_log("glfs-mgmt", GF_LOG_INFO,
"Exhausted all volfile servers");
glfs_init_done (fs, -1);
break;
}
server = list_entry (server->list.next, typeof(*server),
list);
ctx->cmd_args.curr_server = server;
ctx->cmd_args.volfile_server_port = server->port;
ctx->cmd_args.volfile_server = server->volfile_server;
ctx->cmd_args.volfile_server_transport = server->transport;
ret = dict_set_int32 (rpc_trans->options,
"remote-port",
server->port);
if (ret != 0) {
gf_log ("glfs-mgmt", GF_LOG_ERROR,
"failed to set remote-port: %d",
server->port);
errno = ENOTCONN;
glfs_init_done (fs, -1);
break;
}
ret = dict_set_str (rpc_trans->options,
"remote-host",
server->volfile_server);
if (ret != 0) {
gf_log ("glfs-mgmt", GF_LOG_ERROR,
"failed to set remote-host: %s",
server->volfile_server);
errno = ENOTCONN;
glfs_init_done (fs, -1);
break;
}
ret = dict_set_str (rpc_trans->options,
"transport-type",
server->transport);
if (ret != 0) {
gf_log ("glfs-mgmt", GF_LOG_ERROR,
"failed to set transport-type: %s",
server->transport);
errno = ENOTCONN;
glfs_init_done (fs, -1);
break;
}
gf_log ("glfs-mgmt", GF_LOG_INFO,
"connecting to next volfile server %s"
" at port %d with transport: %s",
server->volfile_server, server->port,
server->transport);
}
break;
case RPC_CLNT_CONNECT:
rpc_clnt_set_connected (&((struct rpc_clnt*)ctx->mgmt)->conn);
@ -556,4 +605,3 @@ glfs_mgmt_init (struct glfs *fs)
out:
return ret;
}

View File

@ -131,6 +131,8 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
INIT_LIST_HEAD (&pool->all_frames);
INIT_LIST_HEAD (&ctx->cmd_args.xlator_options);
INIT_LIST_HEAD (&ctx->cmd_args.volfile_servers);
LOCK_INIT (&pool->lock);
ctx->pool = pool;
@ -312,6 +314,108 @@ enomem:
return -1;
}
int
glfs_unset_volfile_server (struct glfs *fs, const char *transport,
const char *host, const int port)
{
cmd_args_t *cmd_args = NULL;
server_cmdline_t *server = NULL;
int ret = -1;
if (!transport || !host || !port) {
errno = EINVAL;
return ret;
}
cmd_args = &fs->ctx->cmd_args;
list_for_each_entry(server, &cmd_args->curr_server->list, list) {
if ((!strcmp(server->volfile_server, host) &&
!strcmp(server->transport, transport) &&
(server->port == port))) {
list_del (&server->list);
ret = 0;
goto out;
}
}
out:
return ret;
}
int
glfs_set_volfile_server (struct glfs *fs, const char *transport,
const char *host, int port)
{
cmd_args_t *cmd_args = NULL;
server_cmdline_t *server = NULL;
server_cmdline_t *tmp = NULL;
int ret = -1;
if (!transport || !host || !port) {
errno = EINVAL;
return ret;
}
cmd_args = &fs->ctx->cmd_args;
cmd_args->max_connect_attempts = 1;
server = GF_CALLOC (1, sizeof (server_cmdline_t),
glfs_mt_server_cmdline_t);
if (!server) {
errno = ENOMEM;
goto out;
}
INIT_LIST_HEAD (&server->list);
server->volfile_server = gf_strdup (host);
if (!server->volfile_server) {
errno = ENOMEM;
goto out;
}
server->transport = gf_strdup (transport);
if (!server->transport) {
errno = ENOMEM;
goto out;
}
server->port = port;
if (!cmd_args->volfile_server) {
cmd_args->volfile_server = server->volfile_server;
cmd_args->volfile_server_transport = server->transport;
cmd_args->volfile_server_port = server->port;
cmd_args->curr_server = server;
}
list_for_each_entry(tmp, &cmd_args->volfile_servers, list) {
if ((!strcmp(tmp->volfile_server, host) &&
!strcmp(tmp->transport, transport) &&
(tmp->port == port))) {
errno = EEXIST;
ret = -1;
goto out;
}
}
list_add_tail (&server->list, &cmd_args->volfile_servers);
ret = 0;
out:
if (ret == -1) {
if (server) {
GF_FREE (server->volfile_server);
GF_FREE (server->transport);
GF_FREE (server);
}
}
return ret;
}
int glfs_setfsuid (uid_t fsuid)
{
return syncopctx_setfsuid (&fsuid);
@ -463,26 +567,6 @@ glfs_set_volfile (struct glfs *fs, const char *volfile)
}
int
glfs_set_volfile_server (struct glfs *fs, const char *transport,
const char *host, int port)
{
cmd_args_t *cmd_args = NULL;
cmd_args = &fs->ctx->cmd_args;
if (vol_assigned (cmd_args))
return -1;
cmd_args->volfile_server = gf_strdup (host);
cmd_args->volfile_server_transport = gf_strdup (transport);
cmd_args->volfile_server_port = port;
cmd_args->max_connect_attempts = 2;
return 0;
}
int
glfs_set_logging (struct glfs *fs, const char *logfile, int loglevel)
{

View File

@ -115,12 +115,12 @@ int glfs_set_volfile (glfs_t *fs, const char *volfile);
/*
SYNOPSIS
glfs_set_volfile_server: Specify the address of management server.
glfs_set_volfile_server: Specify the list of addresses for management server.
DESCRIPTION
This function specifies the address of the management server (glusterd)
to connect, and establish the volume configuration. The @volname
This function specifies the list of addresses for the management server
(glusterd) to connect, and establish the volume configuration. The @volname
parameter passed to glfs_new() is the volume which will be virtually
mounted as the glfs_t object. All operations performed by the CLI at
the management server will automatically be reflected in the 'virtual
@ -136,19 +136,22 @@ int glfs_set_volfile (glfs_t *fs, const char *volfile);
@transport: String specifying the transport used to connect to the
management daemon. Specifying NULL will result in the usage
of the default (tcp) transport type. Permitted values
are those what you specify as transport-type in a volume
specification file (e.g "tcp", "rdma", "unix".)
of the default (tcp) transport type. Permitted values
are those what you specify as transport-type in a volume
specification file (e.g "tcp", "rdma" etc.)
@host: String specifying the address of where to find the management
daemon. Depending on the transport type this would either be
an FQDN (e.g: "storage01.company.com"), ASCII encoded IP
address "192.168.22.1", or a UNIX domain socket path (e.g
"/tmp/glusterd.socket".)
@host: String specifying the address where to find the management daemon.
This would either be
- FQDN (e.g: "storage01.company.com") or
- ASCII (e.g: "192.168.22.1")
NOTE: This API is special, multiple calls to this function with different
volfile servers, port or transport-type would create a list of volfile
servers which would be polled during `volfile_fetch_attempts()`
@port: The TCP port number where gluster management daemon is listening.
Specifying 0 uses the default port number GF_DEFAULT_BASE_PORT.
This parameter is unused if you are using a UNIX domain socket.
This parameter is unused if you are using a UNIX domain socket.
RETURN VALUES
@ -158,9 +161,9 @@ int glfs_set_volfile (glfs_t *fs, const char *volfile);
*/
int glfs_set_volfile_server (glfs_t *fs, const char *transport,
const char *host, int port) __THROW;
const char *host, int port) __THROW;
int glfs_unset_volfile_server (glfs_t *fs, const char *transport,
const char *host, int port) __THROW;
/*
SYNOPSIS

View File

@ -325,6 +325,8 @@ typedef struct _xlator_cmdline_option xlator_cmdline_option_t;
struct _server_cmdline {
struct list_head list;
char *volfile_server;
char *transport;
int port;
};
typedef struct _server_cmdline server_cmdline_t;