diff options
| author | Subha sree Mohankumar <smohanku@redhat.com> | 2017-11-02 15:09:37 +0530 | 
|---|---|---|
| committer | Amar Tumballi <amarts@redhat.com> | 2017-12-02 12:03:28 +0000 | 
| commit | 09cb795587772b60ba102f4369ab3f4501cdc01a (patch) | |
| tree | 09c3c7bbd4ca9772f890780d13320d41d5e68bdd | |
| parent | 59d1cc720f52357f7a6f20bb630febc6a622c99c (diff) | |
storage/posix : options to override umask
Options "create-mask" and "create-directory-mask" are added to
remove the mode bits set on a file or directory when its created.
Default value of these options is 0777.
Options "force-create-mode" and "force-create-directory" sets
the default permission for a file or directory irrespective of
the clients umask.
Default value of these options is 0000.
Command to set option:
volume set <volume name> storage.<option-name> <value>
The valid value range from 0000 to 0777.
Updates #301
Change-Id: Ia33d13f2117202ca55a056c747ccc3674eb8bae1
Signed-off-by: Subha sree Mohankumar <smohanku@redhat.com>
| -rw-r--r-- | tests/bugs/glusterfs/bug-1482528.t | 100 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 22 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 142 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.h | 7 | 
4 files changed, 258 insertions, 13 deletions
diff --git a/tests/bugs/glusterfs/bug-1482528.t b/tests/bugs/glusterfs/bug-1482528.t new file mode 100644 index 00000000000..3adf260bdcd --- /dev/null +++ b/tests/bugs/glusterfs/bug-1482528.t @@ -0,0 +1,100 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup +#Basic checks +TEST glusterd +TEST pidof glusterd + +#Create a distributed volume +TEST $CLI volume create $V0 $H0:$B0/${V0}{1..2} +TEST $CLI volume start $V0 + +# Mount FUSE without selinux: +TEST glusterfs -s $H0 --volfile-id $V0 $@ $M0 + +TEST touch $M0/default.txt +EXPECT "644" stat -c %a $M0/default.txt + +TEST chmod 0444 $M0/default.txt +EXPECT "444" stat -c %a $M0/default.txt + +TEST mkdir $M0/default +EXPECT "755" stat -c %a $M0/default + +TEST chmod 0444 $M0/default +EXPECT "444" stat -c %a $M0/default + +TEST mkfifo $M0/mkfifo +EXPECT "644" stat -c %a $M0/mkfifo + +TEST mknod $M0/dmknod b 4 5 +EXPECT "644" stat -c %a $M0/dmknod + +#Set the create-directory-mask and create-mask options +TEST $CLI volume set $V0 storage.create-directory-mask 0444 +TEST $CLI volume set $V0 storage.create-mask 0444 + +TEST mkdir $M0/create-directory +EXPECT "444" stat -c %a $M0/create-directory + +TEST touch $M0/create-mask.txt +EXPECT "444" stat -c %a $M0/create-mask.txt + +TEST chmod 0777 $M0/create-mask.txt +EXPECT "444" stat -c %a $M0/create-mask.txt + +TEST chmod 0400 $M0/create-mask.txt +EXPECT "400" stat -c %a $M0/create-mask.txt + +TEST chmod 0777 $M0/create-directory +EXPECT "444" stat -c %a $M0/create-directory + +TEST chmod 0400 $M0/create-directory +EXPECT "400" stat -c %a $M0/create-directory + +TEST mkfifo $M0/cfifo +EXPECT "444" stat -c %a $M0/cfifo + +TEST chmod 0777 $M0/cfifo +EXPECT "444" stat -c %a $M0/cfifo + +TEST mknod $M0/cmknod b 4 5 +EXPECT "444" stat -c %a $M0/cmknod + +#set force-create-mode and force-directory-mode options +TEST $CLI volume set $V0 storage.force-create-mode 0777 +TEST $CLI volume set $V0 storage.force-directory-mode 0333 + +TEST touch $M0/force-create-mode.txt +EXPECT "777" stat -c %a $M0/force-create-mode.txt + +TEST mkdir $M0/force-directory +EXPECT "777" stat -c %a $M0/force-directory + +TEST chmod 0222 $M0/force-create-mode.txt +EXPECT "777" stat -c %a $M0/force-create-mode.txt + +TEST chmod 0222 $M0/force-directory +EXPECT "333" stat -c %a $M0/force-directory + +TEST mkdir $M0/link +TEST ln -s $M0/force-create-mode.txt $M0/link +EXPECT "777" stat -c %a $M0/link/force-create-mode.txt + +TEST ln $M0/force-create-mode.txt $M0/link/fc.txt +EXPECT "777" stat -c %a $M0/link/fc.txt + +TEST setfacl -m o:r $M0/force-create-mode.txt +EXPECT "777" stat -c %a $M0/force-create-mode.txt + +TEST ln -s $M0/force-directory $M0/link +EXPECT "777" stat -c %a $M0/link/force-directory + +TEST mkfifo $M0/ffifo +EXPECT "777" stat -c %a $M0/ffifo + +TEST mknod $M0/mknod b 4 5 +EXPECT "777" stat -c %a $M0/mknod diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index 8ec8a3125ee..7750914705e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -1,4 +1,4 @@ -/* +	/*     Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>     This file is part of GlusterFS. @@ -2823,6 +2823,26 @@ struct volopt_map_entry glusterd_volopt_map[] = {            .voltype     = "storage/posix",            .op_version  = GD_OP_VERSION_4_0_0,          }, +        { .option      = "force-create-mode", +          .key         = "storage.force-create-mode", +          .voltype     = "storage/posix", +          .op_version  = GD_OP_VERSION_4_0_0, +        }, +        { .option      = "force-directory-mode", +          .key         = "storage.force-directory-mode", +          .voltype     = "storage/posix", +          .op_version  = GD_OP_VERSION_4_0_0, +        }, +        { .option      = "create-mask", +          .key         = "storage.create-mask", +          .voltype     = "storage/posix", +          .op_version  = GD_OP_VERSION_4_0_0, +        }, +        { .option      = "create-directory-mask", +          .key         = "storage.create-directory-mask", +          .voltype     = "storage/posix", +          .op_version  = GD_OP_VERSION_4_0_0, +        },          { .key         = "storage.bd-aio",            .voltype     = "storage/bd",            .op_version  = 3 diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 0435d7a677f..3b03779f305 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -394,14 +394,27 @@ out:          return 0;  } +static inline mode_t override_umask (mode_t mode, mode_t mode_bit) +{ +        gf_msg_debug ("posix", 0, "The value of mode is %u", mode); +        mode = mode >> 9; /* 3x3 (bits for each octal digit)*/ +        mode = (mode << 9) | mode_bit; +        gf_msg_debug ("posix", 0, "The value of mode is %u", mode); +        return mode; +} +  static int  posix_do_chmod (xlator_t *this, const char *path, struct iatt *stbuf)  {          int32_t     ret = -1;          mode_t      mode = 0; +        mode_t      mode_bit = 0; +        struct posix_private *priv = NULL;          struct stat stat;          int         is_symlink = 0; +        priv = this->private; +        VALIDATE_OR_GOTO (priv, out);          ret = sys_lstat (path, &stat);          if (ret != 0) {                  gf_msg (this->name, GF_LOG_WARNING, 0, P_MSG_LSTAT_FAILED, @@ -412,7 +425,17 @@ posix_do_chmod (xlator_t *this, const char *path, struct iatt *stbuf)          if (S_ISLNK (stat.st_mode))                  is_symlink = 1; -        mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type); +        if (S_ISDIR (stat.st_mode)) { +                mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type); +                mode_bit = (mode & priv->create_directory_mask) +                            | priv->force_directory_mode; +                mode = override_umask(mode, mode_bit); +        } else { +                mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type); +                mode_bit = (mode & priv->create_mask) +                            | priv->force_create_mode; +                mode = override_umask(mode, mode_bit); +        }          ret = lchmod (path, mode);          if ((ret == -1) && (errno == ENOSYS)) {                  /* in Linux symlinks are always in mode 0777 and no @@ -633,10 +656,20 @@ int32_t  posix_do_fchmod (xlator_t *this,                   int fd, struct iatt *stbuf)  { -        mode_t  mode = 0; +        int32_t     ret = -1; +        mode_t      mode = 0; +        mode_t      mode_bit = 0; +        struct posix_private *priv = NULL; +        priv = this->private; +        VALIDATE_OR_GOTO (priv, out);          mode = st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type); -        return sys_fchmod (fd, mode); +        mode_bit = (mode & priv->create_mask) +                    | priv->force_create_mode; +        mode = override_umask (mode, mode_bit); +        ret = sys_fchmod (fd, mode); +out: +        return ret;  }  static int @@ -1392,6 +1425,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this,          gf_boolean_t          entry_created   = _gf_false, gfid_set = _gf_false;          gf_boolean_t          linked          = _gf_false;          gf_loglevel_t         level           = GF_LOG_NONE; +        mode_t                mode_bit        = 0;          DECLARE_OLD_FS_ID_VAR; @@ -1405,11 +1439,13 @@ posix_mknod (call_frame_t *frame, xlator_t *this,                                    out);          MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL); +        mode_bit = (priv->create_mask & mode) | priv->force_create_mode; +        mode = override_umask (mode, mode_bit); +          gid = frame->root->gid;          SET_FS_ID (frame->root->uid, gid);          DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out); -          if (!real_path || !par_path) {                  op_ret = -1;                  op_errno = ESTALE; @@ -1452,9 +1488,9 @@ posix_mknod (call_frame_t *frame, xlator_t *this,  real_op:  #ifdef __NetBSD__ -	if (S_ISFIFO(mode)) -		op_ret = mkfifo (real_path, mode); -	else +        if (S_ISFIFO(mode)) +                op_ret = mkfifo (real_path, mode); +        else  #endif /* __NetBSD__ */          op_ret = sys_mknod (real_path, mode, dev); @@ -1600,6 +1636,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,          char          pgfid[GF_UUID_BUF_SIZE] = {0};          char                 value_buf[4096]  = {0,};          gf_boolean_t         have_val         = _gf_false; +        mode_t               mode_bit         = 0;          DECLARE_OLD_FS_ID_VAR; @@ -1643,6 +1680,10 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,          SET_FS_ID (frame->root->uid, gid); +        mode_bit = (priv->create_directory_mask & mode) +                   | priv->force_directory_mode; +        mode = override_umask (mode, mode_bit); +          if (xdata) {                  op_ret = dict_get_ptr (xdata, "gfid-req", &uuid_req);                  if (!op_ret && !gf_uuid_compare (stbuf.ia_gfid, uuid_req)) { @@ -3089,6 +3130,7 @@ posix_create (call_frame_t *frame, xlator_t *this,          int                    nlink_samepgfid = 0;          char *                 pgfid_xattr_key = NULL;          gf_boolean_t           entry_created   = _gf_false, gfid_set = _gf_false; +        mode_t                 mode_bit        = 0;          DECLARE_OLD_FS_ID_VAR; @@ -3143,6 +3185,9 @@ posix_create (call_frame_t *frame, xlator_t *this,          if (priv->o_direct)                  _flags |= O_DIRECT; + +        mode_bit = (priv->create_mask & mode) | priv->force_create_mode; +        mode = override_umask (mode, mode_bit);          _fd = sys_open (real_path, _flags, mode);          if (_fd == -1) { @@ -3312,7 +3357,7 @@ posix_open (call_frame_t *frame, xlator_t *this,          if (priv->o_direct)                  flags |= O_DIRECT; -        _fd = sys_open (real_path, flags, 0); +        _fd = sys_open (real_path, flags, priv->force_create_mode);          if (_fd == -1) {                  op_ret   = -1;                  op_errno = errno; @@ -7176,10 +7221,13 @@ reconfigure (xlator_t *this, dict_t *options)          int32_t               uid = -1;          int32_t               gid = -1;  	char                 *batch_fsync_mode_str = NULL; -    char                 *gfid2path_sep = NULL; - -	priv = this->private; +        char                 *gfid2path_sep = NULL; +        int32_t              force_create_mode = -1; +        int32_t              force_directory_mode = -1; +        int32_t              create_mask = -1; +        int32_t              create_directory_mask = -1; +        priv = this->private;          GF_OPTION_RECONF ("brick-uid", uid, options, int32, out);          GF_OPTION_RECONF ("brick-gid", gid, options, int32, out);  	if (uid != -1 || gid != -1) @@ -7258,8 +7306,23 @@ reconfigure (xlator_t *this, dict_t *options)          GF_OPTION_RECONF ("shared-brick-count", priv->shared_brick_count,                            options, int32, out); +        GF_OPTION_RECONF ("force-create-mode", force_create_mode, +                          options, int32, out); +        priv->force_create_mode = force_create_mode; + +        GF_OPTION_RECONF ("force-directory-mode", force_directory_mode, +                          options, int32, out); +        priv->force_directory_mode = force_directory_mode; + +        GF_OPTION_RECONF ("create-mask", create_mask, +                          options, int32, out); +        priv->create_mask = create_mask; -	ret = 0; +        GF_OPTION_RECONF ("create-directory-mask", create_directory_mask, +                          options, int32, out); +        priv->create_directory_mask = create_directory_mask; + +        ret = 0;  out:  	return ret;  } @@ -7401,6 +7464,10 @@ init (xlator_t *this)          int32_t               gid           = -1;  	char                 *batch_fsync_mode_str;          char                 *gfid2path_sep = NULL; +        int                  force_create  = -1; +        int                  force_directory = -1; +        int                  create_mask  = -1; +        int                  create_directory_mask = -1;          dir_data = dict_get (this->options, "directory"); @@ -7919,6 +7986,19 @@ init (xlator_t *this)          GF_OPTION_INIT ("batch-fsync-delay-usec", _private->batch_fsync_delay_usec,                          uint32, out); +        GF_OPTION_INIT ("force-create-mode", force_create, int32, out); +        _private->force_create_mode = force_create; + +        GF_OPTION_INIT ("force-directory-mode", force_directory, int32, out); +        _private->force_directory_mode = force_directory; + +        GF_OPTION_INIT ("create-mask", +                        create_mask, int32, out); +        _private->create_mask = create_mask; + +        GF_OPTION_INIT ("create-directory-mask", +                        create_directory_mask, int32, out); +        _private->create_directory_mask = create_directory_mask;  out:          if (ret) {                  if (_private) { @@ -8190,5 +8270,43 @@ struct volume_options options[] = {            " Useful for displaying the proper usable size through statvfs() "            "call (df command)",          }, +        { .key  = {"force-create-mode"}, +          .type = GF_OPTION_TYPE_INT, +          .min = 0000, +          .max = 0777, +          .default_value = "0000", +          .validate = GF_OPT_VALIDATE_MIN, +          .validate = GF_OPT_VALIDATE_MAX, +          .description = "Mode bit permission that will always be set on a file." +        }, +        { .key  = {"force-directory-mode"}, +          .type = GF_OPTION_TYPE_INT, +          .min = 0000, +          .max = 0777, +          .default_value = "0000", +          .validate = GF_OPT_VALIDATE_MIN, +          .validate = GF_OPT_VALIDATE_MAX, +          .description = "Mode bit permission that will be always set on directory" +        }, +        { .key  = {"create-mask"}, +          .type = GF_OPTION_TYPE_INT, +          .min = 0000, +          .max = 0777, +          .default_value = "0777", +          .validate = GF_OPT_VALIDATE_MIN, +          .validate = GF_OPT_VALIDATE_MAX, +          .description = "Any bit not set here will be removed from the" +          "modes set on a file when it is created" +        }, +        { .key  = {"create-directory-mask"}, +          .type = GF_OPTION_TYPE_INT, +          .min = 0000, +          .max = 0777, +          .default_value = "0777", +          .validate = GF_OPT_VALIDATE_MIN, +          .validate = GF_OPT_VALIDATE_MAX, +          .description = "Any bit not set here will be removed from the" +          "modes set on a directory when it is created" +        },          { .key  = {NULL} }  }; diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 8db87f1de9f..e2f1dfa2dd1 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -232,6 +232,13 @@ struct posix_private {          /* Option to handle the cases of multiple bricks exported from             same backend. Very much usable in brick-splitting feature. */          int32_t shared_brick_count; + +        /*Option to set mode bit permission that will always be set on +          file/directory. */ +        mode_t          force_create_mode; +        mode_t          force_directory_mode; +        mode_t          create_mask; +        mode_t          create_directory_mask;  };  typedef struct {  | 
