diff options
-rw-r--r-- | tests/bugs/distribute/bug-1368012.t | 50 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 32 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-selfheal.c | 16 |
3 files changed, 93 insertions, 5 deletions
diff --git a/tests/bugs/distribute/bug-1368012.t b/tests/bugs/distribute/bug-1368012.t new file mode 100644 index 00000000000..f89314b1f2e --- /dev/null +++ b/tests/bugs/distribute/bug-1368012.t @@ -0,0 +1,50 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +function get_permission { + stat -c "%A" $1 +} + +## Start glusterd +TEST glusterd; +TEST pidof glusterd; +TEST $CLI volume info; + +## Lets create volume +TEST $CLI volume create $V0 $H0:/${V0}{1,2}; + +## Verify volume is created +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +## Start volume and verify +TEST $CLI volume start $V0; +TEST $CLI volume set $V0 performance.stat-prefetch off +EXPECT 'Started' volinfo_field $V0 'Status'; +TEST glusterfs -s $H0 --volfile-id=$V0 $M0 + +##Test case: Add-brick +#------------------------------------------------------------ +#change permission of both root +TEST chmod 444 $M0 + +#store permission for comparision +TEST permission_root=`stat -c "%A" $M0` +TEST echo $permission_root +#Add-brick +TEST $CLI volume add-brick $V0 $H0:/${V0}3 + +#Allow one lookup to happen +TEST pushd $M0 +TEST ls +#Generate another lookup +echo 3 > /proc/sys/vm/drop_caches +TEST ls +#check root permission +EXPECT_WITHIN "5" $permission_root get_permission $M0 +#check permission on the new-brick +EXPECT $permission_root get_permission /${V0}3 +cleanup diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 0131bb519c9..c4326fd075f 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -736,6 +736,27 @@ out: return ret; } +int static +is_permission_different (ia_prot_t *prot1, ia_prot_t *prot2) +{ + if ((prot1->owner.read != prot2->owner.read) || + (prot1->owner.write != prot2->owner.write) || + (prot1->owner.exec != prot2->owner.exec) || + (prot1->group.read != prot2->group.read) || + (prot1->group.write != prot2->group.write) || + (prot1->group.exec != prot2->group.exec) || + (prot1->other.read != prot2->other.read) || + (prot1->other.write != prot2->other.write) || + (prot1->other.exec != prot2->other.exec) || + (prot1->suid != prot2->suid) || + (prot1->sgid != prot2->sgid) || + (prot1->sticky != prot2->sticky)) { + return 1; + } else { + return 0; + } +} + int dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, @@ -857,14 +878,21 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->stbuf.ia_ctime_nsec, stbuf->ia_ctime, stbuf->ia_ctime_nsec)) { + /* Choose source */ local->prebuf.ia_gid = stbuf->ia_gid; local->prebuf.ia_uid = stbuf->ia_uid; + + if (__is_root_gfid (stbuf->ia_gfid)) + local->prebuf.ia_prot = stbuf->ia_prot; } } if (local->stbuf.ia_type != IA_INVAL) { if ((local->stbuf.ia_gid != stbuf->ia_gid) || - (local->stbuf.ia_uid != stbuf->ia_uid)) { + (local->stbuf.ia_uid != stbuf->ia_uid) || + (__is_root_gfid (stbuf->ia_gfid) && + is_permission_different (&local->stbuf.ia_prot, + &stbuf->ia_prot))) { local->need_selfheal = 1; } } @@ -942,6 +970,8 @@ out: gf_uuid_copy (local->gfid, local->stbuf.ia_gfid); local->stbuf.ia_gid = local->prebuf.ia_gid; local->stbuf.ia_uid = local->prebuf.ia_uid; + if (__is_root_gfid(local->stbuf.ia_gfid)) + local->stbuf.ia_prot = local->prebuf.ia_prot; copy = create_frame (this, this->ctx->pool); if (copy) { copy_local = dht_local_init (copy, &local->loc, diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c index bd4c236ffcd..331878b3608 100644 --- a/xlators/cluster/dht/src/dht-selfheal.c +++ b/xlators/cluster/dht/src/dht-selfheal.c @@ -2253,11 +2253,19 @@ dht_dir_attr_heal (void *data) for (i = 0; i < call_cnt; i++) { subvol = conf->subvolumes[i]; - if (!subvol || (subvol == dht_first_up_subvol (this))) + if (!subvol) continue; - ret = syncop_setattr (subvol, &local->loc, &local->stbuf, - (GF_SET_ATTR_UID | GF_SET_ATTR_GID), - NULL, NULL, NULL, NULL); + + if (__is_root_gfid (local->stbuf.ia_gfid)) { + ret = syncop_setattr (subvol, &local->loc, &local->stbuf, + (GF_SET_ATTR_UID | GF_SET_ATTR_GID | GF_SET_ATTR_MODE), + NULL, NULL, NULL, NULL); + } else { + ret = syncop_setattr (subvol, &local->loc, &local->stbuf, + (GF_SET_ATTR_UID | GF_SET_ATTR_GID), + NULL, NULL, NULL, NULL); + } + if (ret) { gf_uuid_unparse(local->loc.gfid, gfid); |