diff options
| -rw-r--r-- | api/src/gfapi.aliases | 2 | ||||
| -rw-r--r-- | api/src/gfapi.map | 7 | ||||
| -rw-r--r-- | api/src/glfs.c | 24 | ||||
| -rw-r--r-- | api/src/glfs.h | 8 | ||||
| -rw-r--r-- | libglusterfs/src/Makefile.am | 2 | ||||
| -rw-r--r-- | libglusterfs/src/call-stub.c | 55 | ||||
| -rw-r--r-- | libglusterfs/src/call-stub.h | 10 | ||||
| -rw-r--r-- | libglusterfs/src/defaults.c | 31 | ||||
| -rw-r--r-- | libglusterfs/src/defaults.h | 9 | ||||
| -rw-r--r-- | libglusterfs/src/globals.c | 3 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 3 | ||||
| -rw-r--r-- | libglusterfs/src/syncop.c | 46 | ||||
| -rw-r--r-- | libglusterfs/src/syncop.h | 4 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.c | 1 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.h | 10 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 1 | ||||
| -rw-r--r-- | rpc/xdr/src/glusterfs3-xdr.x | 12 | ||||
| -rwxr-xr-x | tests/features/ipc.t | 21 | ||||
| -rwxr-xr-x | tests/features/ipctest.py | 28 | ||||
| -rw-r--r-- | xlators/performance/io-threads/src/io-threads.c | 1 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-rpc-fops.c | 184 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client.c | 33 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-rpc-fops.c | 94 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 15 | 
24 files changed, 552 insertions, 52 deletions
diff --git a/api/src/gfapi.aliases b/api/src/gfapi.aliases index 6c0a6413098..2ab7d443eb5 100644 --- a/api/src/gfapi.aliases +++ b/api/src/gfapi.aliases @@ -125,6 +125,8 @@ _pub_glfs_h_removexattrs _glfs_h_removexattrs$GFAPI_3.5.1  _pub_glfs_get_volfile _glfs_get_volfile$GFAPI_3.6.0  _pub_glfs_h_access _glfs_h_access$GFAPI_3.6.0 +_pub_glfs_ipc _glfs_ipc$GFAPI_3.7.0 +  _priv_glfs_free_from_ctx _glfs_free_from_ctx$GFAPI_PRIVATE_3.7.0  _priv_glfs_new_from_ctx _glfs_new_from_ctx$GFAPI_PRIVATE_3.7.0  _priv_glfs_resolve _glfs_resolve$GFAPI_PRIVATE_3.7.0 diff --git a/api/src/gfapi.map b/api/src/gfapi.map index a29f392dc53..39202e1883f 100644 --- a/api/src/gfapi.map +++ b/api/src/gfapi.map @@ -145,10 +145,15 @@ GFAPI_3.6.0 {  		glfs_h_access;  } GFAPI_3.5.1; +GFAPI_3.7.0 { +	global: +		glfs_ipc; +} GFAPI_3.6.0; +  GFAPI_PRIVATE_3.7.0 {  	global:  		glfs_free_from_ctx;  		glfs_new_from_ctx;                  glfs_resolve; -} GFAPI_3.6.0; +} GFAPI_3.7.0; diff --git a/api/src/glfs.c b/api/src/glfs.c index 421374d9731..f23481bbb4c 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -1067,3 +1067,27 @@ pub_glfs_get_volfile (struct glfs *fs, void *buf, size_t len)  GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volfile, 3.6.0); +int +pub_glfs_ipc (struct glfs *fs, int opcode) +{ +	xlator_t        *subvol = NULL; +        int             ret; + +	__glfs_entry_fs (fs); + +	subvol = glfs_active_subvol (fs); +	if (!subvol) { +		ret = -1; +		errno = EIO; +		goto out; +	} + +	ret = syncop_ipc (subvol, opcode, NULL, NULL); +        DECODE_SYNCOP_ERR (ret); + +out: +        glfs_subvol_done (fs, subvol); +        return ret; +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ipc, 3.7.0); diff --git a/api/src/glfs.h b/api/src/glfs.h index 3ef822ed3f1..9ee772741e6 100644 --- a/api/src/glfs.h +++ b/api/src/glfs.h @@ -760,6 +760,14 @@ int glfs_posix_lock (glfs_fd_t *fd, int cmd, struct flock *flock) __THROW  glfs_fd_t *glfs_dup (glfs_fd_t *fd) __THROW          GFAPI_PUBLIC(glfs_dup, 3.4.0); +/* + * No xdata support for now.  Nobody needs this call at all yet except for the + * test script, and that doesn't need xdata.  Adding dict_t support and a new + * header-file requirement doesn't seem worth it until the need is greater. + */ +int glfs_ipc (glfs_fd_t *fd, int cmd) __THROW +        GFAPI_PUBLIC(glfs_ipc, 3.7.0); +  __END_DECLS  #endif /* !_GLFS_H */ diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index 3d1de02e894..02f4462e6b0 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -5,7 +5,7 @@ libglusterfs_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 \  	-DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" \  	-I$(top_srcdir)/rpc/rpc-lib/src/ -I$(CONTRIBDIR)/rbtree \  	-I$(CONTRIBDIR)/libexecinfo ${ARGP_STANDALONE_CPPFLAGS} \ -	-DSBIN_DIR=\"$(sbindir)\" +	-DSBIN_DIR=\"$(sbindir)\" -lm  libglusterfs_la_LIBADD = @LEXLIB@ $(ZLIB_LIBS)  libglusterfs_la_LDFLAGS = -version-info $(LIBGLUSTERFS_LT_VERSION) diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c index 7e94ee3c001..ee2e7c93337 100644 --- a/libglusterfs/src/call-stub.c +++ b/libglusterfs/src/call-stub.c @@ -2297,7 +2297,53 @@ out:  } -static void +call_stub_t * +fop_ipc_cbk_stub (call_frame_t *frame, fop_ipc_cbk_t fn, +                  int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +        call_stub_t *stub = NULL; + +        GF_VALIDATE_OR_GOTO ("call-stub", frame, out); + +        stub = stub_new (frame, 0, GF_FOP_IPC); +        GF_VALIDATE_OR_GOTO ("call-stub", stub, out); + +        stub->fn_cbk.ipc = fn; + +        stub->args_cbk.op_ret = op_ret; +        stub->args_cbk.op_errno = op_errno; + +        if (xdata) +                stub->args_cbk.xdata = dict_ref (xdata); +out: +        return stub; +} + +call_stub_t * +fop_ipc_stub (call_frame_t *frame, fop_ipc_t fn, +              int32_t op, dict_t *xdata) +{ +        call_stub_t *stub = NULL; + +        GF_VALIDATE_OR_GOTO ("call-stub", frame, out); +        GF_VALIDATE_OR_GOTO ("call-stub", fn, out); + +        stub = stub_new (frame, 1, GF_FOP_IPC); +        GF_VALIDATE_OR_GOTO ("call-stub", stub, out); + +        stub->fn.ipc = fn; + +        stub->args.cmd = op; + +        if (xdata) +                stub->args.xdata = dict_ref (xdata); +out: +        return stub; + +} + + +void  call_resume_wind (call_stub_t *stub)  {          GF_VALIDATE_OR_GOTO ("call-stub", stub, out); @@ -2529,6 +2575,10 @@ call_resume_wind (call_stub_t *stub)                                   stub->args.fd, stub->args.offset,                                   stub->args.size, stub->args.xdata);                  break; +        case GF_FOP_IPC: +                stub->fn.ipc (stub->frame, stub->frame->this, +                              stub->args.cmd, stub->args.xdata); +                break;          default:                  gf_log_callingfn ("call-stub", GF_LOG_ERROR, @@ -2736,6 +2786,9 @@ call_resume_unwind (call_stub_t *stub)                  STUB_UNWIND(stub, zerofill, &stub->args_cbk.prestat,                              &stub->args_cbk.poststat, stub->args_cbk.xdata);                  break; +        case GF_FOP_IPC: +                STUB_UNWIND (stub, ipc, stub->args_cbk.xdata); +                break;          default:                  gf_log_callingfn ("call-stub", GF_LOG_ERROR, diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h index eba1413a1e6..fe110775fc6 100644 --- a/libglusterfs/src/call-stub.h +++ b/libglusterfs/src/call-stub.h @@ -72,6 +72,7 @@ typedef struct {  		fop_fallocate_t fallocate;  		fop_discard_t discard;                  fop_zerofill_t zerofill; +                fop_ipc_t ipc;  	} fn;  	union { @@ -119,6 +120,7 @@ typedef struct {  		fop_fallocate_cbk_t fallocate;  		fop_discard_cbk_t discard;                  fop_zerofill_cbk_t zerofill; +                fop_ipc_cbk_t ipc;  	} fn_cbk;  	struct { @@ -761,6 +763,14 @@ fop_zerofill_cbk_stub(call_frame_t *frame,                       struct iatt *statpre, struct iatt *statpost,                       dict_t *xdata); +call_stub_t * +fop_ipc_stub (call_frame_t *frame, fop_ipc_t fn, int32_t op, dict_t *xdata); + +call_stub_t * +fop_ipc_cbk_stub (call_frame_t *frame, fop_ipc_cbk_t fn, +                  int32_t op_ret, int32_t op_errno, dict_t *xdata); + +  void call_resume (call_stub_t *stub);  void call_stub_destroy (call_stub_t *stub);  void call_unwind_error (call_stub_t *stub, int op_ret, int op_errno); diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c index a4f8f924b17..ac08a70cf32 100644 --- a/libglusterfs/src/defaults.c +++ b/libglusterfs/src/defaults.c @@ -1295,6 +1295,16 @@ default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          return 0;  } + +int32_t +default_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                 int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +        STACK_UNWIND_STRICT (ipc, frame, op_ret, op_errno, xdata); +        return 0; +} + +  /* RESUME */  int32_t @@ -1726,6 +1736,17 @@ default_zerofill_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,  } +int32_t +default_ipc_resume (call_frame_t *frame, xlator_t *this, int32_t op, +                    dict_t *xdata) +{ +        STACK_WIND (frame, default_ipc_cbk, +                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->ipc, +                    op, xdata); +        return 0; +} + +  /* FOPS */  int32_t @@ -2162,6 +2183,16 @@ default_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd,  int32_t +default_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) +{ +        STACK_WIND_TAIL (frame, +                         FIRST_CHILD(this), FIRST_CHILD(this)->fops->ipc, +                         op, xdata); +        return 0; +} + + +int32_t  default_forget (xlator_t *this, inode_t *inode)  {          gf_log_callingfn (this->name, GF_LOG_WARNING, "xlator does not " diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h index 9bd5eb842ad..e29d62edfe1 100644 --- a/libglusterfs/src/defaults.h +++ b/libglusterfs/src/defaults.h @@ -263,6 +263,9 @@ int32_t default_zerofill(call_frame_t *frame,                          off_t offset,                          off_t len, dict_t *xdata); +int32_t default_ipc (call_frame_t *frame, xlator_t *this, int32_t op, +                     dict_t *xdata); +  /* Resume */  int32_t default_getspec_resume (call_frame_t *frame, @@ -492,6 +495,9 @@ int32_t default_zerofill_resume(call_frame_t *frame,                                 off_t offset,                                 off_t len, dict_t *xdata); +int32_t default_ipc_resume (call_frame_t *frame, xlator_t *this, +                            int32_t op, dict_t *xdata); +  /* _cbk_resume */ @@ -985,6 +991,9 @@ int32_t default_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,                              int32_t op_ret, int32_t op_errno, struct iatt *pre,                              struct iatt *post, dict_t *xdata); +int32_t default_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                         int32_t op_ret, int32_t op_errno, dict_t *xdata); +  int32_t  default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                       int32_t op_ret, int32_t op_errno, char *spec_data); diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c index 57467ecde1d..bd1165ec50c 100644 --- a/libglusterfs/src/globals.c +++ b/libglusterfs/src/globals.c @@ -70,7 +70,8 @@ const char *gf_fop_list[GF_FOP_MAXVALUE] = {          [GF_FOP_FREMOVEXATTR]= "FREMOVEXATTR",  	[GF_FOP_FALLOCATE]   = "FALLOCATE",  	[GF_FOP_DISCARD]     = "DISCARD", -        [GF_FOP_ZEROFILL]     = "ZEROFILL", +        [GF_FOP_ZEROFILL]    = "ZEROFILL", +        [GF_FOP_IPC]         = "IPC",  };  /* THIS */ diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index d5a604d0341..8d7659b5015 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -238,7 +238,7 @@ typedef enum {          GF_FOP_WRITE,          GF_FOP_STATFS,          GF_FOP_FLUSH, -        GF_FOP_FSYNC,      /* 15 */ +        GF_FOP_FSYNC,      /* 16 */          GF_FOP_SETXATTR,          GF_FOP_GETXATTR,          GF_FOP_REMOVEXATTR, @@ -271,6 +271,7 @@ typedef enum {  	GF_FOP_FALLOCATE,  	GF_FOP_DISCARD,          GF_FOP_ZEROFILL, +        GF_FOP_IPC,          GF_FOP_MAXVALUE,  } glusterfs_fop_t; diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c index 9df462321aa..e3321cf6ddb 100644 --- a/libglusterfs/src/syncop.c +++ b/libglusterfs/src/syncop.c @@ -2417,6 +2417,52 @@ syncop_zerofill(xlator_t *subvol, fd_t *fd, off_t offset, off_t len)  int +syncop_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                int op_ret, int op_errno, dict_t *xdata) +{ +        struct syncargs *args = NULL; + +        args = cookie; + +        if (xdata) { +                args->xdata = dict_ref(xdata); +        } + +        args->op_ret   = op_ret; +        args->op_errno = op_errno; + +        __wake (args); + +        return 0; +} + +int +syncop_ipc (xlator_t *subvol, int32_t op, dict_t *xdata_in, dict_t **xdata_out) +{ +        struct syncargs args = {0, }; + +        SYNCOP (subvol, (&args), syncop_ipc_cbk, subvol->fops->ipc, +                op, xdata_in); + +        if (args.xdata) { +                if (xdata_out) { +                        /* +                         * We're passing this reference to the caller, along +                         * with the pointer itself.  That means they're +                         * responsible for calling dict_unref at some point. +                         */ +                        *xdata_out = args.xdata; +                } else { +                        dict_unref(args.xdata); +                } +        } + +        if (args.op_ret < 0) +                return -args.op_errno; +        return args.op_ret; +} + +int  syncop_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,  	       int op_ret, int op_errno, struct gf_flock *flock,  	       dict_t *xdata) diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h index ec0d8a917e8..7f8ec7345b0 100644 --- a/libglusterfs/src/syncop.h +++ b/libglusterfs/src/syncop.h @@ -435,4 +435,8 @@ int syncop_lk (xlator_t *subvol, fd_t *fd, int cmd, struct gf_flock *flock);  int  syncop_inodelk (xlator_t *subvol, const char *volume, loc_t *loc, int32_t cmd,                  struct gf_flock *lock, dict_t *xdata_req, dict_t **xdata_rsp); + +int +syncop_ipc (xlator_t *subvol, int op, dict_t *xdata_in, dict_t **xdata_out); +  #endif /* _SYNCOP_H */ diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index b58247e52bc..49af7d2e0e6 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -82,6 +82,7 @@ fill_defaults (xlator_t *xl)  	SET_DEFAULT_FOP (fallocate);  	SET_DEFAULT_FOP (discard);          SET_DEFAULT_FOP (zerofill); +        SET_DEFAULT_FOP (ipc);          SET_DEFAULT_FOP (getspec); diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 8e52bbb3010..e953ec04372 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -443,6 +443,10 @@ typedef int32_t (*fop_zerofill_cbk_t) (call_frame_t *frame,                                        struct iatt *preop_stbuf,                                        struct iatt *postop_stbuf, dict_t *xdata); +typedef int32_t (*fop_ipc_cbk_t) (call_frame_t *frame, void *cookie, +                                 xlator_t *this, int32_t op_ret, +                                 int32_t op_errno, dict_t *xdata); +  typedef int32_t (*fop_lookup_t) (call_frame_t *frame,                                   xlator_t *this,                                   loc_t *loc, @@ -674,6 +678,7 @@ typedef int32_t (*fop_discard_t) (call_frame_t *frame,  				  off_t offset,  				  size_t len,                                    dict_t *xdata); +  typedef int32_t (*fop_zerofill_t) (call_frame_t *frame,                                    xlator_t *this,                                    fd_t *fd, @@ -681,6 +686,9 @@ typedef int32_t (*fop_zerofill_t) (call_frame_t *frame,                                    off_t len,                                    dict_t *xdata); +typedef int32_t (*fop_ipc_t) (call_frame_t *frame, xlator_t *this, int32_t op, +                              dict_t *xdata); +  struct xlator_fops {          fop_lookup_t         lookup;          fop_stat_t           stat; @@ -727,6 +735,7 @@ struct xlator_fops {  	fop_fallocate_t	     fallocate;  	fop_discard_t	     discard;          fop_zerofill_t       zerofill; +        fop_ipc_t            ipc;          /* these entries are used for a typechecking hack in STACK_WIND _only_ */          fop_lookup_cbk_t         lookup_cbk; @@ -774,6 +783,7 @@ struct xlator_fops {  	fop_fallocate_cbk_t	 fallocate_cbk;  	fop_discard_cbk_t	 discard_cbk;          fop_zerofill_cbk_t       zerofill_cbk; +        fop_ipc_cbk_t            ipc_cbk;  };  typedef int32_t (*cbk_forget_t) (xlator_t *this, diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index 3d8cf11fa5f..ee59078de42 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -59,6 +59,7 @@ enum gf_fop_procnum {  	GFS3_OP_FALLOCATE,  	GFS3_OP_DISCARD,          GFS3_OP_ZEROFILL, +        GFS3_OP_IPC,          GFS3_OP_MAXVALUE,  } ; diff --git a/rpc/xdr/src/glusterfs3-xdr.x b/rpc/xdr/src/glusterfs3-xdr.x index 81b0f201f89..0136aec2b08 100644 --- a/rpc/xdr/src/glusterfs3-xdr.x +++ b/rpc/xdr/src/glusterfs3-xdr.x @@ -640,6 +640,18 @@ struct gfs3_fstat_req {  }  ; +struct gfs3_ipc_req { +	int     op; +	opaque  xdata<>; +}; + +struct gfs3_ipc_rsp { +	int     op_ret; +	int     op_errno; +	opaque  xdata<>; +}; + +   struct gf_setvolume_req {          opaque dict<>;  }  ; diff --git a/tests/features/ipc.t b/tests/features/ipc.t new file mode 100755 index 00000000000..2aaca6620bf --- /dev/null +++ b/tests/features/ipc.t @@ -0,0 +1,21 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc + +cleanup; +mkdir -p $B0/1 +mkdir -p $M0 + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 $H0:$B0/1 +TEST $CLI volume start $V0 + +# This is a pretty lame test.  Basically we just want to make sure that we +# get all the way through the translator stacks on client and server to get a +# simple error (95 = EOPNOTUPP) instead of a crash, RPC error, etc. +EXPECT 95 $PYTHON $(dirname $0)/ipctest.py $H0 $V0 + +cleanup; diff --git a/tests/features/ipctest.py b/tests/features/ipctest.py new file mode 100755 index 00000000000..0592bae3bbc --- /dev/null +++ b/tests/features/ipctest.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +import ctypes +import ctypes.util + +api = ctypes.CDLL(ctypes.util.find_library("gfapi")) +api.glfs_ipc.argtypes = [ ctypes.c_void_p, ctypes.c_int ] +api.glfs_ipc.restype = ctypes.c_int + +def do_ipc (host, volume): +	fs = api.glfs_new(volume) +	#api.glfs_set_logging(fs,"/dev/stderr",7) +	api.glfs_set_volfile_server(fs,"tcp",host,24007) + +	api.glfs_init(fs) +	ret  = api.glfs_ipc(fs,1470369258) +	api.glfs_fini(fs) + +	return ret + +if __name__ == "__main__": +	import sys + +	try: +		res = apply(do_ipc,sys.argv[1:3]) +		print res +	except: +		print "IPC failed (volume not started?)" diff --git a/xlators/performance/io-threads/src/io-threads.c b/xlators/performance/io-threads/src/io-threads.c index 9c6ae5af12e..148e55ab297 100644 --- a/xlators/performance/io-threads/src/io-threads.c +++ b/xlators/performance/io-threads/src/io-threads.c @@ -341,6 +341,7 @@ iot_schedule (call_frame_t *frame, xlator_t *this, call_stub_t *stub)          case GF_FOP_RELEASEDIR:          case GF_FOP_GETSPEC:                  break; +        case GF_FOP_IPC:          default:                  return -EINVAL;          } diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c index 4305fb39627..7ca91e9880c 100644 --- a/xlators/protocol/client/src/client-rpc-fops.c +++ b/xlators/protocol/client/src/client-rpc-fops.c @@ -2103,6 +2103,55 @@ out:  }  int +client3_3_ipc_cbk (struct rpc_req *req, struct iovec *iov, int count, +                      void *myframe) +{ +        call_frame_t    *frame         = NULL; +        gfs3_ipc_rsp     rsp          = {0,}; +        int              ret           = 0; +        xlator_t *this                 = NULL; +        dict_t  *xdata                 = NULL; + +        this = THIS; + +        frame = myframe; + +        if (-1 == req->rpc_status) { +                rsp.op_ret   = -1; +                rsp.op_errno = ENOTCONN; +                goto out; +        } +        ret = xdr_to_generic(*iov, &rsp, (xdrproc_t) xdr_gfs3_ipc_rsp); +        if (ret < 0) { +                gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed"); +                rsp.op_ret   = -1; +                rsp.op_errno = EINVAL; +                goto out; +        } + +        GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val), +                                      (rsp.xdata.xdata_len), ret, +                                      rsp.op_errno, out); + +out: +        if (rsp.op_ret == -1) { +                gf_log (this->name, GF_LOG_WARNING, +                        "remote operation failed: %s", +                        strerror (gf_error_to_errno (rsp.op_errno))); +        } +        CLIENT_STACK_UNWIND (ipc, frame, +                             rsp.op_ret, gf_error_to_errno (rsp.op_errno), +                             xdata); + +        free (rsp.xdata.xdata_val); + +        if (xdata) +                dict_unref (xdata); + +        return 0; +} + +int  client3_3_setattr_cbk (struct rpc_req *req, struct iovec *iov, int count,                         void *myframe)  { @@ -6098,58 +6147,98 @@ unwind:          return 0;  } +int32_t +client3_3_ipc (call_frame_t *frame, xlator_t *this, void *data) +{ +        clnt_args_t       *args        = NULL; +        clnt_conf_t       *conf        = NULL; +        gfs3_ipc_req       req        = {0,}; +        int                op_errno    = ESTALE; +        int                ret         = 0; + +        GF_ASSERT (frame); + +        if (!this || !data) +                goto unwind; + +        args = data; +        conf = this->private; + +        req.op = args->cmd; + +        GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val), +                                    req.xdata.xdata_len, op_errno, unwind); + +        ret = client_submit_request(this, &req, frame, conf->fops, +                                    GFS3_OP_IPC, client3_3_ipc_cbk, +                                    NULL, NULL, 0, NULL, 0, NULL, +                                    (xdrproc_t) xdr_gfs3_ipc_req); +        if (ret) +                gf_log (this->name, GF_LOG_WARNING, "failed to send the fop"); + +        GF_FREE (req.xdata.xdata_val); + +        return 0; +unwind: +        CLIENT_STACK_UNWIND(ipc, frame, -1, op_errno, NULL); +        GF_FREE (req.xdata.xdata_val); + +        return 0; +} +  /* Table Specific to FOPS */  rpc_clnt_procedure_t clnt3_3_fop_actors[GF_FOP_MAXVALUE] = { -        [GF_FOP_NULL]        = { "NULL",        NULL}, -        [GF_FOP_STAT]        = { "STAT",        client3_3_stat }, -        [GF_FOP_READLINK]    = { "READLINK",    client3_3_readlink }, -        [GF_FOP_MKNOD]       = { "MKNOD",       client3_3_mknod }, -        [GF_FOP_MKDIR]       = { "MKDIR",       client3_3_mkdir }, -        [GF_FOP_UNLINK]      = { "UNLINK",      client3_3_unlink }, -        [GF_FOP_RMDIR]       = { "RMDIR",       client3_3_rmdir }, -        [GF_FOP_SYMLINK]     = { "SYMLINK",     client3_3_symlink }, -        [GF_FOP_RENAME]      = { "RENAME",      client3_3_rename }, -        [GF_FOP_LINK]        = { "LINK",        client3_3_link }, -        [GF_FOP_TRUNCATE]    = { "TRUNCATE",    client3_3_truncate }, -        [GF_FOP_OPEN]        = { "OPEN",        client3_3_open }, -        [GF_FOP_READ]        = { "READ",        client3_3_readv }, -        [GF_FOP_WRITE]       = { "WRITE",       client3_3_writev }, -        [GF_FOP_STATFS]      = { "STATFS",      client3_3_statfs }, -        [GF_FOP_FLUSH]       = { "FLUSH",       client3_3_flush }, -        [GF_FOP_FSYNC]       = { "FSYNC",       client3_3_fsync }, -        [GF_FOP_SETXATTR]    = { "SETXATTR",    client3_3_setxattr }, -        [GF_FOP_GETXATTR]    = { "GETXATTR",    client3_3_getxattr }, -        [GF_FOP_REMOVEXATTR] = { "REMOVEXATTR", client3_3_removexattr }, -        [GF_FOP_OPENDIR]     = { "OPENDIR",     client3_3_opendir }, -        [GF_FOP_FSYNCDIR]    = { "FSYNCDIR",    client3_3_fsyncdir }, -        [GF_FOP_ACCESS]      = { "ACCESS",      client3_3_access }, -        [GF_FOP_CREATE]      = { "CREATE",      client3_3_create }, -        [GF_FOP_FTRUNCATE]   = { "FTRUNCATE",   client3_3_ftruncate }, -        [GF_FOP_FSTAT]       = { "FSTAT",       client3_3_fstat }, -        [GF_FOP_LK]          = { "LK",          client3_3_lk }, -        [GF_FOP_LOOKUP]      = { "LOOKUP",      client3_3_lookup }, -        [GF_FOP_READDIR]     = { "READDIR",     client3_3_readdir }, -        [GF_FOP_INODELK]     = { "INODELK",     client3_3_inodelk }, -        [GF_FOP_FINODELK]    = { "FINODELK",    client3_3_finodelk }, -        [GF_FOP_ENTRYLK]     = { "ENTRYLK",     client3_3_entrylk }, -        [GF_FOP_FENTRYLK]    = { "FENTRYLK",    client3_3_fentrylk }, -        [GF_FOP_XATTROP]     = { "XATTROP",     client3_3_xattrop }, -        [GF_FOP_FXATTROP]    = { "FXATTROP",    client3_3_fxattrop }, -        [GF_FOP_FGETXATTR]   = { "FGETXATTR",   client3_3_fgetxattr }, -        [GF_FOP_FSETXATTR]   = { "FSETXATTR",   client3_3_fsetxattr }, -        [GF_FOP_RCHECKSUM]   = { "RCHECKSUM",   client3_3_rchecksum }, -        [GF_FOP_SETATTR]     = { "SETATTR",     client3_3_setattr }, -        [GF_FOP_FSETATTR]    = { "FSETATTR",    client3_3_fsetattr }, -        [GF_FOP_READDIRP]    = { "READDIRP",    client3_3_readdirp }, -	[GF_FOP_FALLOCATE]   = { "FALLOCATE",	client3_3_fallocate }, -	[GF_FOP_DISCARD]     = { "DISCARD",	client3_3_discard }, -        [GF_FOP_ZEROFILL]    = { "ZEROFILL",    client3_3_zerofill}, -        [GF_FOP_RELEASE]     = { "RELEASE",     client3_3_release }, -        [GF_FOP_RELEASEDIR]  = { "RELEASEDIR",  client3_3_releasedir }, -        [GF_FOP_GETSPEC]     = { "GETSPEC",     client3_getspec }, +        [GF_FOP_NULL]         = { "NULL",         NULL}, +        [GF_FOP_STAT]         = { "STAT",         client3_3_stat }, +        [GF_FOP_READLINK]     = { "READLINK",     client3_3_readlink }, +        [GF_FOP_MKNOD]        = { "MKNOD",        client3_3_mknod }, +        [GF_FOP_MKDIR]        = { "MKDIR",        client3_3_mkdir }, +        [GF_FOP_UNLINK]       = { "UNLINK",       client3_3_unlink }, +        [GF_FOP_RMDIR]        = { "RMDIR",        client3_3_rmdir }, +        [GF_FOP_SYMLINK]      = { "SYMLINK",      client3_3_symlink }, +        [GF_FOP_RENAME]       = { "RENAME",       client3_3_rename }, +        [GF_FOP_LINK]         = { "LINK",         client3_3_link }, +        [GF_FOP_TRUNCATE]     = { "TRUNCATE",     client3_3_truncate }, +        [GF_FOP_OPEN]         = { "OPEN",         client3_3_open }, +        [GF_FOP_READ]         = { "READ",         client3_3_readv }, +        [GF_FOP_WRITE]        = { "WRITE",        client3_3_writev }, +        [GF_FOP_STATFS]       = { "STATFS",       client3_3_statfs }, +        [GF_FOP_FLUSH]        = { "FLUSH",        client3_3_flush }, +        [GF_FOP_FSYNC]        = { "FSYNC",        client3_3_fsync }, +        [GF_FOP_SETXATTR]     = { "SETXATTR",     client3_3_setxattr }, +        [GF_FOP_GETXATTR]     = { "GETXATTR",     client3_3_getxattr }, +        [GF_FOP_REMOVEXATTR]  = { "REMOVEXATTR",  client3_3_removexattr }, +        [GF_FOP_OPENDIR]      = { "OPENDIR",      client3_3_opendir }, +        [GF_FOP_FSYNCDIR]     = { "FSYNCDIR",     client3_3_fsyncdir }, +        [GF_FOP_ACCESS]       = { "ACCESS",       client3_3_access }, +        [GF_FOP_CREATE]       = { "CREATE",       client3_3_create }, +        [GF_FOP_FTRUNCATE]    = { "FTRUNCATE",    client3_3_ftruncate }, +        [GF_FOP_FSTAT]        = { "FSTAT",        client3_3_fstat }, +        [GF_FOP_LK]           = { "LK",           client3_3_lk }, +        [GF_FOP_LOOKUP]       = { "LOOKUP",       client3_3_lookup }, +        [GF_FOP_READDIR]      = { "READDIR",      client3_3_readdir }, +        [GF_FOP_INODELK]      = { "INODELK",      client3_3_inodelk }, +        [GF_FOP_FINODELK]     = { "FINODELK",     client3_3_finodelk }, +        [GF_FOP_ENTRYLK]      = { "ENTRYLK",      client3_3_entrylk }, +        [GF_FOP_FENTRYLK]     = { "FENTRYLK",     client3_3_fentrylk }, +        [GF_FOP_XATTROP]      = { "XATTROP",      client3_3_xattrop }, +        [GF_FOP_FXATTROP]     = { "FXATTROP",     client3_3_fxattrop }, +        [GF_FOP_FGETXATTR]    = { "FGETXATTR",    client3_3_fgetxattr }, +        [GF_FOP_FSETXATTR]    = { "FSETXATTR",    client3_3_fsetxattr }, +        [GF_FOP_RCHECKSUM]    = { "RCHECKSUM",    client3_3_rchecksum }, +        [GF_FOP_SETATTR]      = { "SETATTR",      client3_3_setattr }, +        [GF_FOP_FSETATTR]     = { "FSETATTR",     client3_3_fsetattr }, +        [GF_FOP_READDIRP]     = { "READDIRP",     client3_3_readdirp }, +	[GF_FOP_FALLOCATE]    = { "FALLOCATE",	  client3_3_fallocate }, +	[GF_FOP_DISCARD]      = { "DISCARD",	  client3_3_discard }, +        [GF_FOP_ZEROFILL]     = { "ZEROFILL",     client3_3_zerofill}, +        [GF_FOP_RELEASE]      = { "RELEASE",      client3_3_release }, +        [GF_FOP_RELEASEDIR]   = { "RELEASEDIR",   client3_3_releasedir }, +        [GF_FOP_GETSPEC]      = { "GETSPEC",      client3_getspec },          [GF_FOP_FREMOVEXATTR] = { "FREMOVEXATTR", client3_3_fremovexattr }, +        [GF_FOP_IPC]          = { "IPC",          client3_3_ipc },  };  /* Used From RPC-CLNT library to log proper name of procedure based on number */ @@ -6201,6 +6290,7 @@ char *clnt3_3_fop_names[GFS3_OP_MAXVALUE] = {  	[GFS3_OP_FALLOCATE]   = "FALLOCATE",  	[GFS3_OP_DISCARD]     = "DISCARD",          [GFS3_OP_ZEROFILL]    = "ZEROFILL", +        [GFS3_OP_IPC]         = "IPC",  }; diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index ccb584569ea..d9e7ccd0c4f 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -2144,6 +2144,38 @@ out:  int32_t +client_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) +{ +        int          ret              = -1; +        clnt_conf_t *conf             = NULL; +        rpc_clnt_procedure_t *proc    = NULL; +        clnt_args_t  args             = {0,}; + +        conf = this->private; +        if (!conf || !conf->fops) +                goto out; + +        args.cmd = op; +        args.xdata = xdata; + +        proc = &conf->fops->proctable[GF_FOP_IPC]; +        if (!proc) { +                gf_log (this->name, GF_LOG_ERROR, +                        "rpc procedure not found for %s", +                        gf_fop_list[GF_FOP_IPC]); +                goto out; +        } +        if (proc->fn) +                ret = proc->fn (frame, this, &args); +out: +        if (ret) +                STACK_UNWIND_STRICT(ipc, frame, -1, ENOTCONN, NULL); + +        return 0; +} + + +int32_t  client_getspec (call_frame_t *frame, xlator_t *this, const char *key,                  int32_t flags)  { @@ -2943,6 +2975,7 @@ struct xlator_fops fops = {  	.discard     = client_discard,          .zerofill    = client_zerofill,          .getspec     = client_getspec, +        .ipc         = client_ipc,  }; diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c index 902a8e5f6b8..051b9771432 100644 --- a/xlators/protocol/server/src/server-rpc-fops.c +++ b/xlators/protocol/server/src/server-rpc-fops.c @@ -2026,6 +2026,42 @@ out:  } +int +server_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +        gf_common_rsp      rsp   = {0,}; +        server_state_t    *state = NULL; +        rpcsvc_request_t  *req   = NULL; + +        req = frame->local; +        state  = CALL_STATE (frame); + +        GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), +                                    rsp.xdata.xdata_len, op_errno, out); + +        if (op_ret) { +                gf_log (this->name, GF_LOG_INFO, +                        "%"PRId64": IPC%"PRId64" (%s) ==> (%s)", +                        frame->root->unique, state->resolve.fd_no, +                        uuid_utoa (state->resolve.gfid), +                        strerror (op_errno)); +                goto out; +        } + +out: +        rsp.op_ret    = op_ret; +        rsp.op_errno  = gf_errno_to_error (op_errno); + +        server_submit_reply(frame, req, &rsp, NULL, 0, NULL, +                            (xdrproc_t) xdr_gf_common_rsp); + +        GF_FREE (rsp.xdata.xdata_val); + +        return 0; +} + +  /* Resume function section */  int @@ -3436,6 +3472,63 @@ out:  }  int +server3_3_ipc (rpcsvc_request_t *req) +{ +        call_frame_t    *frame          = NULL; +        gfs3_ipc_req     args           = {0,}; +        int              ret            = -1; +        int              op_errno       = 0; +        dict_t          *xdata          = NULL; +        xlator_t        *bound_xl       = NULL; + +        if (!req) +                return ret; + +        ret = xdr_to_generic (req->msg[0], &args, +                              (xdrproc_t)xdr_gfs3_ipc_req); +        if (ret < 0) { +                /*failed to decode msg*/; +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } + +        frame = get_frame_from_request (req); +        if (!frame) { +                /* something wrong, mostly insufficient memory*/ +                req->rpc_err = GARBAGE_ARGS; /* TODO */ +                goto out; +        } +        frame->root->op = GF_FOP_IPC; + +        bound_xl = frame->root->client->bound_xl; +        if (!bound_xl) { +                /* auth failure, request on subvolume without setvolume */ +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } + +        GF_PROTOCOL_DICT_UNSERIALIZE (bound_xl, xdata, +                                      args.xdata.xdata_val, +                                      args.xdata.xdata_len, +                                      ret, op_errno, out); + +        ret = 0; +        STACK_WIND (frame, server_ipc_cbk, bound_xl, bound_xl->fops->ipc, +                    args.op, xdata); +        if (xdata) { +                dict_unref(xdata); +        } + +out: +        free (args.xdata.xdata_val); + +        if (op_errno) +                req->rpc_err = GARBAGE_ARGS; + +        return ret; +} + +int  server3_3_readlink (rpcsvc_request_t *req)  {          server_state_t    *state                 = NULL; @@ -6165,6 +6258,7 @@ rpcsvc_actor_t glusterfs3_3_fop_actors[GLUSTER_FOP_PROCCNT] = {          [GFS3_OP_FALLOCATE]    = {"FALLOCATE",    GFS3_OP_FALLOCATE,    server3_3_fallocate,    NULL, 0, DRC_NA},          [GFS3_OP_DISCARD]      = {"DISCARD",      GFS3_OP_DISCARD,      server3_3_discard,      NULL, 0, DRC_NA},          [GFS3_OP_ZEROFILL]    =  {"ZEROFILL",     GFS3_OP_ZEROFILL,     server3_3_zerofill,     NULL, 0, DRC_NA}, +        [GFS3_OP_IPC]         =  {"IPC",          GFS3_OP_IPC,          server3_3_ipc,          NULL, 0, DRC_NA},  }; diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 47afed7fdad..fc6ec991c44 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -885,6 +885,20 @@ err:  } +static int32_t +posix_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) +{ +        /* +         * IPC is for inter-translator communication.  If one gets here, it +         * means somebody sent one that nobody else recognized, which is an +         * error much like an uncaught exception. +         */ +        gf_log (this->name, GF_LOG_ERROR, "GF_LOG_IPC(%d) not handled", op); +        STACK_UNWIND_STRICT (ipc, frame, -1, -EOPNOTSUPP, NULL); +        return 0; + +} +  int32_t  posix_opendir (call_frame_t *frame, xlator_t *this,                 loc_t *loc, fd_t *fd, dict_t *xdata) @@ -6193,6 +6207,7 @@ struct xlator_fops fops = {  	.fallocate   = _posix_fallocate,  	.discard     = posix_discard,          .zerofill    = posix_zerofill, +        .ipc         = posix_ipc,  };  struct xlator_cbks cbks = {  | 
