diff options
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/globals.c | 57 | ||||
| -rw-r--r-- | libglusterfs/src/globals.h | 4 | ||||
| -rw-r--r-- | libglusterfs/src/mem-types.h | 3 | ||||
| -rw-r--r-- | libglusterfs/src/syncop.c | 154 | ||||
| -rw-r--r-- | libglusterfs/src/syncop.h | 78 | 
5 files changed, 277 insertions, 19 deletions
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c index 05ff52c2c52..8009fb00c0c 100644 --- a/libglusterfs/src/globals.c +++ b/libglusterfs/src/globals.c @@ -19,6 +19,7 @@  #include "globals.h"  #include "xlator.h"  #include "mem-pool.h" +#include "syncop.h"  const char *gf_fop_list[GF_FOP_MAXVALUE] = {          [GF_FOP_NULL]        = "NULL", @@ -164,6 +165,54 @@ glusterfs_this_set (xlator_t *this)          return 0;  } +/* SYNCOPCTX */ +static pthread_key_t syncopctx_key; + +static void +syncopctx_key_destroy (void *ptr) +{ +	struct syncopctx *opctx = ptr; + +	if (opctx) { +		if (opctx->groups) +			GF_FREE (opctx->groups); + +		GF_FREE (opctx); +	} + +	return; +} + +void * +syncopctx_getctx () +{ +	void *opctx = NULL; + +	opctx = pthread_getspecific (syncopctx_key); + +	return opctx; +} + +int +syncopctx_setctx (void *ctx) +{ +	int ret = 0; + +	ret = pthread_setspecific (syncopctx_key, ctx); + +	return ret; +} + +static int +syncopctx_init (void) +{ +	int ret; + +	ret = pthread_key_create (&syncopctx_key, syncopctx_key_destroy); + +	return ret; +} +  /* SYNCTASK */  int @@ -176,7 +225,6 @@ synctask_init ()          return ret;  } -  void *  synctask_get ()  { @@ -300,6 +348,13 @@ glusterfs_globals_init (glusterfs_ctx_t *ctx)                          "ERROR: glusterfs synctask init failed");                  goto out;          } + +        ret = syncopctx_init (); +        if (ret) { +                gf_log ("", GF_LOG_CRITICAL, +                        "ERROR: glusterfs syncopctx init failed"); +                goto out; +        }  out:          return ret;  } diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h index 709121b51ea..cf52e8e591e 100644 --- a/libglusterfs/src/globals.h +++ b/libglusterfs/src/globals.h @@ -40,6 +40,10 @@ xlator_t **__glusterfs_this_location ();  xlator_t *glusterfs_this_get ();  int glusterfs_this_set (xlator_t *); +/* syncopctx */ +void *syncopctx_getctx (); +int syncopctx_setctx (void *ctx); +  /* task */  void *synctask_get ();  int synctask_set (void *); diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h index 7d9186a419e..c1164f96a06 100644 --- a/libglusterfs/src/mem-types.h +++ b/libglusterfs/src/mem-types.h @@ -110,6 +110,7 @@ enum gf_common_mem_types_ {          gf_common_mt_iov_base_t           = 94,          gf_common_mt_groups_t             = 95,  	gf_common_mt_auxgids              = 96, -        gf_common_mt_end                  = 97 +        gf_common_mt_syncopctx            = 97, +        gf_common_mt_end                  = 98  };  #endif diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c index ba8c84f26c8..6c2e8e48e05 100644 --- a/libglusterfs/src/syncop.c +++ b/libglusterfs/src/syncop.c @@ -15,6 +15,160 @@  #include "syncop.h" +int +syncopctx_setfsuid (void *uid) +{ +	struct syncopctx *opctx = NULL; +	int               ret = 0; + +	/* In args check */ +	if (!uid) { +		ret = -1; +		errno = EINVAL; +		goto out; +	} + +	opctx = syncopctx_getctx (); + +	/* alloc for this thread the first time */ +	if (!opctx) { +		opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx); +		if (!opctx) { +			ret = -1; +			goto out; +		} + +		ret = syncopctx_setctx (opctx); +		if (ret != 0) { +			GF_FREE (opctx); +			opctx = NULL; +			goto out; +		} +	} + +out: +	if (opctx && uid) { +		opctx->uid = *(uid_t *)uid; +		opctx->valid |= SYNCOPCTX_UID; +	} + +	return ret; +} + +int +syncopctx_setfsgid (void *gid) +{ +	struct syncopctx *opctx = NULL; +	int               ret = 0; + +	/* In args check */ +	if (!gid) { +		ret = -1; +		errno = EINVAL; +		goto out; +	} + +	opctx = syncopctx_getctx (); + +	/* alloc for this thread the first time */ +	if (!opctx) { +		opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx); +		if (!opctx) { +			ret = -1; +			goto out; +		} + +		ret = syncopctx_setctx (opctx); +		if (ret != 0) { +			GF_FREE (opctx); +			opctx = NULL; +			goto out; +		} +	} + +out: +	if (opctx && gid) { +		opctx->gid = *(gid_t *)gid; +		opctx->valid |= SYNCOPCTX_GID; +	} + +	return ret; +} + +int +syncopctx_setfsgroups (int count, const void *groups) +{ +	struct syncopctx *opctx = NULL; +	gid_t            *tmpgroups = NULL; +	int               ret = 0; + +	/* In args check */ +	if (count != 0 && !groups) { +		ret = -1; +		errno = EINVAL; +		goto out; +	} + +	opctx = syncopctx_getctx (); + +	/* alloc for this thread the first time */ +	if (!opctx) { +		opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx); +		if (!opctx) { +			ret = -1; +			goto out; +		} + +		ret = syncopctx_setctx (opctx); +		if (ret != 0) { +			GF_FREE (opctx); +			opctx = NULL; +			goto out; +		} +	} + +	/* resize internal groups as required */ +	if (count && opctx->grpsize < count) { +		if (opctx->groups) { +			tmpgroups = GF_REALLOC (opctx->groups, +						(sizeof (gid_t) * count)); +			/* NOTE: Not really required to zero the reallocation, +			 * as ngrps controls the validity of data, +			 * making a note irrespective */ +			if (tmpgroups == NULL) { +				opctx->grpsize = 0; +				GF_FREE (opctx->groups); +				opctx->groups = NULL; +				ret = -1; +				goto out; +			} +		} +		else { +			tmpgroups = GF_CALLOC (count, sizeof (gid_t), +					       gf_common_mt_syncopctx); +			if (tmpgroups == NULL) { +				opctx->grpsize = 0; +				ret = -1; +				goto out; +			} +		} + +		opctx->groups = tmpgroups; +		opctx->grpsize = count; +	} + +	/* copy out the groups passed */ +	if (count) +		memcpy (opctx->groups, groups, (sizeof (gid_t) * count)); + +	/* set/reset the ngrps, this is where reset of groups is handled */ +	opctx->ngrps = count; +	opctx->valid |= SYNCOPCTX_GROUPS; + +out: +	return ret; +} +  static void  __run (struct synctask *task)  { diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h index d0417b26026..4e14dc35335 100644 --- a/libglusterfs/src/syncop.h +++ b/libglusterfs/src/syncop.h @@ -25,6 +25,13 @@  #define SYNCENV_PROC_MIN 2  #define SYNCPROC_IDLE_TIME 600 +/* + * Flags for syncopctx valid elements + */ +#define SYNCOPCTX_UID    0x00000001 +#define SYNCOPCTX_GID    0x00000002 +#define SYNCOPCTX_GROUPS 0x00000004 +  struct synctask;  struct syncproc;  struct syncenv; @@ -146,6 +153,14 @@ struct syncargs {  	int                 done;  }; +struct syncopctx { +        unsigned int valid;  /* valid flags for elements that are set */ +        uid_t        uid; +        gid_t        gid; +        int          grpsize; +        int          ngrps; +        gid_t       *groups; +};  #define __yawn(args) do {                                       \          args->task = synctask_get ();                           \ @@ -234,34 +249,63 @@ void synctask_waitfor (struct synctask *task, int count);  int synctask_setid (struct synctask *task, uid_t uid, gid_t gid);  #define SYNCTASK_SETID(uid, gid) synctask_setid (synctask_get(), uid, gid); +int syncopctx_setfsuid (void *uid); +int syncopctx_setfsgid (void *gid); +int syncopctx_setfsgroups (int count, const void *groups);  static inline call_frame_t *  syncop_create_frame (xlator_t *this)  { -	call_frame_t  *frame = NULL; -	int            ngrps = -1; +	call_frame_t     *frame = NULL; +	int               ngrps = -1; +	struct syncopctx *opctx = NULL;  	frame = create_frame (this, this->ctx->pool);  	if (!frame)  		return NULL; -	frame->root->pid = getpid(); -	frame->root->uid = geteuid (); -	frame->root->gid = getegid (); -        ngrps = getgroups (0, 0); -	if (ngrps < 0) { -		STACK_DESTROY (frame->root); -		return NULL; -	} +	frame->root->pid = getpid (); -	if (call_stack_alloc_groups (frame->root, ngrps) != 0) { -		STACK_DESTROY (frame->root); -		return NULL; -	} +	opctx = syncopctx_getctx (); +	if (opctx && (opctx->valid & SYNCOPCTX_UID)) +		frame->root->uid = opctx->uid; +	else +		frame->root->uid = geteuid (); -	if (getgroups (ngrps, frame->root->groups) < 0) { -		STACK_DESTROY (frame->root); -		return NULL; +	if (opctx && (opctx->valid & SYNCOPCTX_GID)) +		frame->root->gid = opctx->gid; +	else +		frame->root->gid = getegid (); + +	if (opctx && (opctx->valid & SYNCOPCTX_GROUPS)) { +		ngrps = opctx->ngrps; + +		if (ngrps != 0 && opctx->groups != NULL) { +			if (call_stack_alloc_groups (frame->root, ngrps) != 0) { +				STACK_DESTROY (frame->root); +				return NULL; +			} + +			memcpy (frame->root->groups, opctx->groups, +				(sizeof (gid_t) * ngrps)); +		} +	} +	else { +		ngrps = getgroups (0, 0); +		if (ngrps < 0) { +			STACK_DESTROY (frame->root); +			return NULL; +		} + +		if (call_stack_alloc_groups (frame->root, ngrps) != 0) { +			STACK_DESTROY (frame->root); +			return NULL; +		} + +		if (getgroups (ngrps, frame->root->groups) < 0) { +			STACK_DESTROY (frame->root); +			return NULL; +		}  	}  	return frame;  | 
