summaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/examples/Makefile.am6
-rw-r--r--api/examples/__init__.py.in1
-rwxr-xr-xapi/examples/getvolfile.py4
-rw-r--r--api/examples/setup.py.in5
-rw-r--r--api/src/glfs-handleops.c160
-rw-r--r--api/src/glfs-handles.h11
-rw-r--r--api/src/glfs-internal.h3
-rw-r--r--api/src/glfs-mem-types.h2
-rw-r--r--api/src/glfs-mgmt.c82
-rw-r--r--api/src/glfs.c135
-rw-r--r--api/src/glfs.h33
11 files changed, 376 insertions, 66 deletions
diff --git a/api/examples/Makefile.am b/api/examples/Makefile.am
index 05f40ff53..f1a8d12b2 100644
--- a/api/examples/Makefile.am
+++ b/api/examples/Makefile.am
@@ -1,6 +1,10 @@
+# The bits needed for glfsxmp
EXTRA_PROGRAMS = glfsxmp
glfsxmp_SOURCES = glfsxmp.c
glfsxmp_CFLAGS = $(GLFS_CFLAGS) -Wall
glfsxmp_LDADD = $(GLFS_LIBS) -lrt
-EXTRA_DIST = gfapi.py
+# Install __init__.py (a generated file), and gfapi.py into
+# the Python site-packages area
+pygfapidir = $(pythondir)/gluster
+pygfapi_PYTHON = __init__.py gfapi.py
diff --git a/api/examples/__init__.py.in b/api/examples/__init__.py.in
new file mode 100644
index 000000000..280beb2dc
--- /dev/null
+++ b/api/examples/__init__.py.in
@@ -0,0 +1 @@
+__version__ = "@PACKAGE_VERSION@"
diff --git a/api/examples/getvolfile.py b/api/examples/getvolfile.py
index 82d9db055..184586c63 100755
--- a/api/examples/getvolfile.py
+++ b/api/examples/getvolfile.py
@@ -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):
diff --git a/api/examples/setup.py.in b/api/examples/setup.py.in
index 44b738094..f22fa1f30 100644
--- a/api/examples/setup.py.in
+++ b/api/examples/setup.py.in
@@ -1,10 +1,5 @@
from distutils.core import setup
-# generate a __init__.py for the package namespace
-fo = open('__init__.py', 'w')
-fo.write('__version__ = "@PACKAGE_VERSION@"\n')
-fo.close()
-
DESC = """GlusterFS is a clustered file-system capable of scaling to
several petabytes. It aggregates various storage bricks over Infiniband
RDMA or TCP/IP interconnect into one large parallel network file system.
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