diff options
Diffstat (limited to 'api/src')
-rw-r--r-- | api/src/glfs-handleops.c | 160 | ||||
-rw-r--r-- | api/src/glfs-handles.h | 11 | ||||
-rw-r--r-- | api/src/glfs-internal.h | 3 | ||||
-rw-r--r-- | api/src/glfs-mem-types.h | 2 | ||||
-rw-r--r-- | api/src/glfs-mgmt.c | 82 | ||||
-rw-r--r-- | api/src/glfs.c | 135 | ||||
-rw-r--r-- | api/src/glfs.h | 33 |
7 files changed, 368 insertions, 58 deletions
diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c index 65642697e..b97590239 100644 --- a/api/src/glfs-handleops.c +++ b/api/src/glfs-handleops.c @@ -218,6 +218,59 @@ out: } int +glfs_h_getxattrs (struct glfs *fs, struct glfs_object *object, const char *name, + void *value, size_t size) +{ + int ret = 0; + xlator_t *subvol = NULL; + inode_t *inode = NULL; + loc_t loc = {0, }; + dict_t *xattr = NULL; + + /* validate in args */ + if ((fs == NULL) || (object == NULL)) { + errno = EINVAL; + return -1; + } + + __glfs_entry_fs (fs); + + /* get the active volume */ + subvol = glfs_active_subvol (fs); + if (!subvol) { + ret = -1; + errno = EIO; + goto out; + } + + /* get/refresh the in arg objects inode in correlation to the xlator */ + inode = glfs_resolve_inode (fs, subvol, object); + if (!inode) { + errno = ESTALE; + goto out; + } + + /* populate loc */ + GLFS_LOC_FILL_INODE (inode, loc, out); + + ret = syncop_getxattr (subvol, &loc, &xattr, name); + DECODE_SYNCOP_ERR (ret); + + if (ret) + goto out; + + ret = glfs_getxattr_process (value, size, xattr, name); + +out: + if (inode) + inode_unref (inode); + + glfs_subvol_done (fs, subvol); + + return ret; +} + +int glfs_h_setattrs (struct glfs *fs, struct glfs_object *object, struct stat *stat, int valid) { @@ -271,6 +324,113 @@ out: return ret; } +int +glfs_h_setxattrs (struct glfs *fs, struct glfs_object *object, const char *name, + const void *value, size_t size, int flags) +{ + int ret = -1; + xlator_t *subvol = NULL; + inode_t *inode = NULL; + loc_t loc = {0, }; + dict_t *xattr = NULL; + + /* validate in args */ + if ((fs == NULL) || (object == NULL) || (stat == NULL)) { + errno = EINVAL; + return -1; + } + + __glfs_entry_fs (fs); + + /* get the active volume */ + subvol = glfs_active_subvol (fs); + if (!subvol) { + ret = -1; + errno = EIO; + goto out; + } + + /* get/refresh the in arg objects inode in correlation to the xlator */ + inode = glfs_resolve_inode (fs, subvol, object); + if (!inode) { + errno = ESTALE; + goto out; + } + + xattr = dict_for_key_value (name, value, size); + if (!xattr) { + ret = -1; + errno = ENOMEM; + goto out; + } + + /* populate loc */ + GLFS_LOC_FILL_INODE (inode, loc, out); + + /* fop/op */ + ret = syncop_setxattr (subvol, &loc, xattr, flags); + DECODE_SYNCOP_ERR (ret); + +out: + loc_wipe (&loc); + + if (inode) + inode_unref (inode); + + glfs_subvol_done (fs, subvol); + + return ret; +} + +int +glfs_h_removexattrs (struct glfs *fs, struct glfs_object *object, const char *name) +{ + int ret = -1; + xlator_t *subvol = NULL; + inode_t *inode = NULL; + loc_t loc = {0, }; + + /* validate in args */ + if ((fs == NULL) || (object == NULL) || (stat == NULL)) { + errno = EINVAL; + return -1; + } + + __glfs_entry_fs (fs); + + /* get the active volume */ + subvol = glfs_active_subvol (fs); + if (!subvol) { + ret = -1; + errno = EIO; + goto out; + } + + /* get/refresh the in arg objects inode in correlation to the xlator */ + inode = glfs_resolve_inode (fs, subvol, object); + if (!inode) { + errno = ESTALE; + goto out; + } + + /* populate loc */ + GLFS_LOC_FILL_INODE (inode, loc, out); + + /* fop/op */ + ret = syncop_removexattr (subvol, &loc, name, 0); + DECODE_SYNCOP_ERR (ret); + +out: + loc_wipe (&loc); + + if (inode) + inode_unref (inode); + + glfs_subvol_done (fs, subvol); + + return ret; +} + struct glfs_fd * glfs_h_open_with_xdata (struct glfs *fs, struct glfs_object *object, int flags, dict_t * dict) { diff --git a/api/src/glfs-handles.h b/api/src/glfs-handles.h index 548268fd6..277b20a3d 100644 --- a/api/src/glfs-handles.h +++ b/api/src/glfs-handles.h @@ -135,9 +135,17 @@ int glfs_h_stat(struct glfs *fs, struct glfs_object *object, int glfs_h_getattrs (struct glfs *fs, struct glfs_object *object, struct stat *stat) __THROW; +int glfs_h_getxattrs (struct glfs *fs, struct glfs_object *object, + const char *name, void *value, + size_t size) __THROW; + int glfs_h_setattrs (struct glfs *fs, struct glfs_object *object, struct stat *sb, int valid) __THROW; +int glfs_h_setxattrs (struct glfs *fs, struct glfs_object *object, + const char *name, const void *value, + size_t size, int flags) __THROW; + int glfs_h_readlink (struct glfs *fs, struct glfs_object *object, char *buf, size_t bufsiz) __THROW; @@ -154,6 +162,9 @@ int glfs_h_rename_with_xdata (struct glfs *fs, struct glfs_object *olddir, const char *oldname, struct glfs_object *newdir, const char *newname, dict_t *dict) __THROW; +int glfs_h_removexattrs (struct glfs *fs, struct glfs_object *object, + const char *name) __THROW; + /* Operations enabling opaque invariant handle to object transitions */ ssize_t glfs_h_extract_handle (struct glfs_object *object, unsigned char *handle, int len) __THROW; diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index f04557323..d7d675e81 100644 --- a/api/src/glfs-internal.h +++ b/api/src/glfs-internal.h @@ -216,5 +216,8 @@ int glfs_loc_touchup (loc_t *loc); void glfs_iatt_to_stat (struct glfs *fs, struct iatt *iatt, struct stat *stat); int glfs_loc_link (loc_t *loc, struct iatt *iatt); int glfs_loc_unlink (loc_t *loc); +dict_t * dict_for_key_value (const char *name, const char *value, size_t size); +int glfs_getxattr_process (void *value, size_t size, dict_t *xattr, + const char *name); #endif /* !_GLFS_INTERNAL_H */ diff --git a/api/src/glfs-mem-types.h b/api/src/glfs-mem-types.h index 3301b3da5..76f4fc774 100644 --- a/api/src/glfs-mem-types.h +++ b/api/src/glfs-mem-types.h @@ -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 - diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c index 7f62fa259..e2a52c324 100644 --- a/api/src/glfs-mgmt.c +++ b/api/src/glfs-mgmt.c @@ -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; } - diff --git a/api/src/glfs.c b/api/src/glfs.c index 9e9a55ccb..73c46517d 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -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) { + 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); @@ -464,29 +568,9 @@ 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) { - int ret = 0; + int ret = 0; char *tmplog = NULL; if (!logfile) { @@ -498,15 +582,16 @@ glfs_set_logging (struct glfs *fs, const char *logfile, int loglevel) tmplog = (char *)logfile; } + /* finish log set parameters before init */ + if (loglevel >= 0) + gf_log_set_loglevel (loglevel); + ret = gf_log_init (fs->ctx, tmplog, NULL); if (ret) goto out; - if (loglevel >= 0) - gf_log_set_loglevel (loglevel); - out: - return ret; + return ret; } diff --git a/api/src/glfs.h b/api/src/glfs.h index 7fef3a873..1ebb8f507 100644 --- a/api/src/glfs.h +++ b/api/src/glfs.h @@ -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 |