diff options
| -rw-r--r-- | tests/bugs/posix/bug-1651445.t | 58 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 33 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix-common.c | 34 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 13 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix-inode-fd-ops.c | 10 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.h | 3 | 
6 files changed, 138 insertions, 13 deletions
diff --git a/tests/bugs/posix/bug-1651445.t b/tests/bugs/posix/bug-1651445.t new file mode 100644 index 00000000000..f6f1833f919 --- /dev/null +++ b/tests/bugs/posix/bug-1651445.t @@ -0,0 +1,58 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../snapshot.rc + +cleanup + +TEST verify_lvm_version +TEST glusterd +TEST pidof glusterd +TEST init_n_bricks 3 +TEST setup_lvm 3 + +TEST $CLI volume create $V0 replica 3 $H0:$L{1,2,3} +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 + +TEST $CLI volume set $V0 storage.reserve-size 10MB + +#No effect as priority to reserve-size +TEST $CLI volume set $V0 storage.reserve 20 + +TEST dd if=/dev/zero of=$M0/a bs=100M count=1 +sleep 5 + +#Below dd confirms posix is giving priority to reserve-size +TEST dd if=/dev/zero of=$M0/b bs=40M count=1 + +sleep 5 +TEST ! dd if=/dev/zero of=$M0/c bs=5M count=1 + +rm -rf $M0/* +#Size will reserve from the previously set reserve option = 20% +TEST $CLI volume set $V0 storage.reserve-size 0 + +#Overwrite reserve option +TEST $CLI volume set $V0 storage.reserve-size 40MB + +#wait 5s to reset disk_space_full flag +sleep 5 + +TEST dd if=/dev/zero of=$M0/a bs=100M count=1 +TEST dd if=/dev/zero of=$M0/b bs=10M count=1 + +# Wait 5s to update disk_space_full flag because thread check disk space +# after every 5s + +sleep 5 +# setup_lvm create lvm partition of 150M and 40M are reserve so after +# consuming more than 110M next dd should fail +TEST ! dd if=/dev/zero of=$M0/c bs=5M count=1 + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index 73cea5d5478..abc1573f372 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -750,6 +750,30 @@ out:      return ret;  } +static int +validate_size(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, +              char **op_errstr) +{ +    xlator_t *this = NULL; +    uint64_t size = 0; +    int ret = -1; + +    this = THIS; +    GF_VALIDATE_OR_GOTO("glusterd", this, out); +    ret = gf_string2bytesize_uint64(value, &size); +    if (ret < 0) { +        gf_asprintf(op_errstr, +                    "%s is not a valid size. %s " +                    "expects a valid value in bytes", +                    value, key); +        gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", +               *op_errstr); +    } +out: +    gf_msg_debug("glusterd", 0, "Returning %d", ret); + +    return ret; +}  /* dispatch table for VOLUME SET   * ----------------------------- @@ -2346,6 +2370,15 @@ struct volopt_map_entry glusterd_volopt_map[] = {          .op_version = GD_OP_VERSION_3_13_0,      },      { +        .key = "storage.reserve-size", +        .voltype = "storage/posix", +        .value = "0", +        .validate_fn = validate_size, +        .description = "If set, priority will be given to " +                       "storage.reserve-size over storage.reserve", +        .op_version = GD_OP_VERSION_7_0, +    }, +    {          .option = "health-check-timeout",          .key = "storage.health-check-timeout",          .type = NO_DOC, diff --git a/xlators/storage/posix/src/posix-common.c b/xlators/storage/posix/src/posix-common.c index 06ff6e631bb..31dc9495af1 100644 --- a/xlators/storage/posix/src/posix-common.c +++ b/xlators/storage/posix/src/posix-common.c @@ -344,11 +344,18 @@ posix_reconfigure(xlator_t *this, dict_t *options)                 " fallback to <hostname>:<export>");      } -    GF_OPTION_RECONF("reserve", priv->disk_reserve, options, uint32, out); -    if (priv->disk_reserve) { +    GF_OPTION_RECONF("reserve-size", priv->disk_reserve_size, options, size, +                     out); + +    GF_OPTION_RECONF("reserve", priv->disk_reserve_percent, options, uint32, +                     out); +    if (priv->disk_reserve_size || priv->disk_reserve_percent) {          ret = posix_spawn_disk_space_check_thread(this); -        if (ret) +        if (ret) { +            gf_msg(this->name, GF_LOG_INFO, 0, P_MSG_DISK_SPACE_CHECK_FAILED, +                   "Getting disk space check from thread failed");              goto out; +        }      }      GF_OPTION_RECONF("health-check-interval", priv->health_check_interval, @@ -966,11 +973,17 @@ posix_init(xlator_t *this)      _private->disk_space_check_active = _gf_false;      _private->disk_space_full = 0; -    GF_OPTION_INIT("reserve", _private->disk_reserve, uint32, out); -    if (_private->disk_reserve) { +    GF_OPTION_INIT("reserve-size", _private->disk_reserve_size, size, out); + +    GF_OPTION_INIT("reserve", _private->disk_reserve_percent, uint32, out); + +    if (_private->disk_reserve_size || _private->disk_reserve_percent) {          ret = posix_spawn_disk_space_check_thread(this); -        if (ret) +        if (ret) { +            gf_msg(this->name, GF_LOG_INFO, 0, P_MSG_DISK_SPACE_CHECK_FAILED, +                   "Getting disk space check from thread failed ");              goto out; +        }      }      _private->health_check_active = _gf_false; @@ -1214,6 +1227,15 @@ struct volume_options posix_options[] = {                      " Set to 0 to disable",       .op_version = {GD_OP_VERSION_3_13_0},       .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, +    {.key = {"reserve-size"}, +     .type = GF_OPTION_TYPE_SIZET, +     .min = 0, +     .default_value = "0", +     .validate = GF_OPT_VALIDATE_MIN, +     .description = "size in megabytes to be reserved for disk space." +                    " Set to 0 to disable", +     .op_version = {GD_OP_VERSION_7_0}, +     .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC},      {.key = {"batch-fsync-mode"},       .type = GF_OPTION_TYPE_STR,       .default_value = "reverse-fsync", diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 80f5fb8514c..7296f698db0 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -2265,6 +2265,7 @@ posix_disk_space_check(xlator_t *this)      struct posix_private *priv = NULL;      char *subvol_path = NULL;      int op_ret = 0; +    uint64_t size = 0;      int percent = 0;      struct statvfs buf = {0};      uint64_t totsz = 0; @@ -2275,7 +2276,14 @@ posix_disk_space_check(xlator_t *this)      GF_VALIDATE_OR_GOTO(this->name, priv, out);      subvol_path = priv->base_path; -    percent = priv->disk_reserve; + +    if (priv->disk_reserve_size) { +        size = priv->disk_reserve_size; +    } else { +        percent = priv->disk_reserve_percent; +        totsz = (buf.f_blocks * buf.f_bsize); +        size = ((totsz * percent) / 100); +    }      op_ret = sys_statvfs(subvol_path, &buf); @@ -2284,10 +2292,9 @@ posix_disk_space_check(xlator_t *this)                 "statvfs failed on %s", subvol_path);          goto out;      } -    totsz = (buf.f_blocks * buf.f_bsize);      freesz = (buf.f_bfree * buf.f_bsize); -    if (freesz <= ((totsz * percent) / 100)) { +    if (freesz <= size) {          priv->disk_space_full = 1;      } else {          priv->disk_space_full = 0; diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c index c12856d4764..16f175c21b8 100644 --- a/xlators/storage/posix/src/posix-inode-fd-ops.c +++ b/xlators/storage/posix/src/posix-inode-fd-ops.c @@ -725,7 +725,7 @@ posix_do_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,         thread after every 5 sec sleep to working correctly storage.reserve         option behaviour      */ -    if (priv->disk_reserve) +    if (priv->disk_reserve_size || priv->disk_reserve_percent)          posix_disk_space_check(this);      DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, ret, ret, out); @@ -2345,8 +2345,12 @@ posix_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)          goto out;      } -    percent = priv->disk_reserve; -    reserved_blocks = (buf.f_blocks * percent) / 100; +    if (priv->disk_reserve_size) { +        reserved_blocks = priv->disk_reserve_size / buf.f_bsize; +    } else { +        percent = priv->disk_reserve_percent; +        reserved_blocks = (buf.f_blocks * percent) / 100; +    }      if (buf.f_bfree > reserved_blocks) {          buf.f_bfree = (buf.f_bfree - reserved_blocks); diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index e807d4a972e..02e7003a57b 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -224,7 +224,8 @@ struct posix_private {      pthread_t health_check;      gf_boolean_t health_check_active; -    uint32_t disk_reserve; +    uint32_t disk_reserve_percent; +    uint64_t disk_reserve_size;      uint32_t disk_space_full;      pthread_t disk_space_check;      gf_boolean_t disk_space_check_active;  | 
