From 0ef870741a2f49d47a02725aed13a95335a6e42f Mon Sep 17 00:00:00 2001 From: Anoop C S Date: Fri, 27 Feb 2015 15:14:08 +0530 Subject: Features/trash : Combined patches for trash translator This is the combined patch set for supporting trash feature. http://www.gluster.org/community/documentation/index.php/Features/Trash Current patch includes the following features: * volume set options for enabling trash globally and exclusively for internal operations like self-heal and re-balance * volume set options for setting the eliminate path, trash directory path and maximum trashable file size. * test script for checking the functionality of the feature * brief documentation on different aspects of trash feature. Change-Id: Ic7486982dcd6e295d1eba0f4d5ee6d33bf1b4cb3 BUG: 1132465 Signed-off-by: Anoop C S Signed-off-by: Jiffin Tony Thottan Reviewed-on: http://review.gluster.org/8312 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/mgmt/glusterd/src/glusterd-op-sm.c | 78 +++++++++++++++++++++++++ xlators/mgmt/glusterd/src/glusterd-volgen.c | 34 ++++++++++- xlators/mgmt/glusterd/src/glusterd-volgen.h | 1 + xlators/mgmt/glusterd/src/glusterd-volume-set.c | 22 +++++++ 4 files changed, 134 insertions(+), 1 deletion(-) (limited to 'xlators/mgmt/glusterd/src') diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index a78c80eceb4..2f121e49e9e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -647,11 +647,14 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr) char *key = NULL; char *key_fixed = NULL; char *value = NULL; + char *val_dup = NULL; char str[100] = {0, }; + char *trash_path = NULL; int count = 0; int dict_count = 0; char errstr[2048] = {0, }; glusterd_volinfo_t *volinfo = NULL; + glusterd_brickinfo_t *brickinfo = NULL; dict_t *val_dict = NULL; gf_boolean_t global_opt = _gf_false; glusterd_volinfo_t *voliter = NULL; @@ -663,7 +666,9 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr) uint32_t local_key_op_version = 0; gf_boolean_t origin_glusterd = _gf_true; gf_boolean_t check_op_version = _gf_true; + gf_boolean_t trash_enabled = _gf_false; gf_boolean_t all_vol = _gf_false; + struct stat stbuf = {0, }; GF_ASSERT (dict); this = THIS; @@ -940,6 +945,76 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr) if (glusterd_check_globaloption (key)) global_opt = _gf_true; + if (volinfo) { + ret = glusterd_volinfo_get (volinfo, + VKEY_FEATURES_TRASH, &val_dup); + if (val_dup) { + ret = gf_string2boolean (val_dup, + &trash_enabled); + if (ret) + goto out; + } + } + + if (!strcmp(key, "features.trash-dir") && trash_enabled) { + if (strchr (value, '/')) { + snprintf (errstr, sizeof (errstr), + "Path is not allowed as option"); + gf_log (this->name, GF_LOG_ERROR, + "Unable to set the options in 'volume " + "set': %s", errstr); + ret = -1; + goto out; + } + + list_for_each_entry (brickinfo, &volinfo->bricks, + brick_list) { + /* Check for local brick */ + if (!uuid_compare (brickinfo->uuid, MY_UUID)) { + trash_path = gf_strdup (brickinfo->path); + strcat(trash_path, "/"); + strcat(trash_path, value); + + /* Checks whether a directory with + given option exists or not */ + if (!stat(trash_path, &stbuf)) { + snprintf (errstr, sizeof (errstr), + "Path %s exists", value); + gf_log (this->name, GF_LOG_ERROR, + "Unable to set the options in " + "'volume set': %s", errstr); + ret = -1; + goto out; + } else { + gf_log (this->name, GF_LOG_DEBUG, + "Directory with given name " + "does not exists, continuing"); + } + + if (volinfo->status == GLUSTERD_STATUS_STARTED + && brickinfo->status != GF_BRICK_STARTED) { + /* If volume is in started state , checks + whether bricks are online */ + snprintf (errstr, sizeof (errstr), + "One or more bricks are down"); + gf_log (this->name, GF_LOG_ERROR, + "Unable to set the options in " + "'volume set': %s", errstr); + ret = -1; + goto out; + } + } + } + } else if (!strcmp(key, "features.trash-dir") && !trash_enabled) { + snprintf (errstr, sizeof (errstr), + "Trash translator is not enabled. Use " + "volume set %s trash on", volname); + gf_log (this->name, GF_LOG_ERROR, + "Unable to set the options in 'volume " + "set': %s", errstr); + ret = -1; + goto out; + } ret = dict_set_str (val_dict, key, value); if (ret) { @@ -1015,6 +1090,9 @@ out: if (val_dict) dict_unref (val_dict); + if (trash_path) + GF_FREE (trash_path); + GF_FREE (key_fixed); if (errstr[0] != '\0') *op_errstr = gf_strdup (errstr); diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 1af7a77cff1..779d6be34a4 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -1421,6 +1421,7 @@ brick_graph_add_posix (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, { int ret = -1; gf_boolean_t quota_enabled = _gf_true; + gf_boolean_t trash_enabled = _gf_false; gf_boolean_t pgfid_feat = _gf_false; char *value = NULL; xlator_t *xl = NULL; @@ -1435,6 +1436,13 @@ brick_graph_add_posix (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, goto out; } + ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_TRASH, &value); + if (value) { + ret = gf_string2boolean (value, &trash_enabled); + if (ret) + goto out; + } + ret = glusterd_volinfo_get (volinfo, "update-link-count-parent", &value); @@ -1459,13 +1467,36 @@ brick_graph_add_posix (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, if (ret) goto out; - if (quota_enabled || pgfid_feat) + if (quota_enabled || pgfid_feat || trash_enabled) xlator_set_option (xl, "update-link-count-parent", "on"); out: return ret; } +static int +brick_graph_add_trash (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, + dict_t *set_dict, glusterd_brickinfo_t *brickinfo) +{ + int ret = -1; + xlator_t *xl = NULL; + + xl = volgen_graph_add (graph, "features/trash", volinfo->volname); + if (!xl) + goto out; + ret = xlator_set_option (xl, "trash-dir", ".trashcan"); + if (ret) + goto out; + ret = xlator_set_option (xl, "brick-path", brickinfo->path); + if (ret) + goto out; + ret = xlator_set_option (xl, "trash-internal-op", "off"); + if (ret) + goto out; +out: + return ret; +} + static int brick_graph_add_bd (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, dict_t *set_dict, glusterd_brickinfo_t *brickinfo) @@ -2018,6 +2049,7 @@ static volgen_brick_xlator_t server_graph_table[] = { {brick_graph_add_acl, "acl"}, {brick_graph_add_changelog, "changelog"}, {brick_graph_add_bd, "bd"}, + {brick_graph_add_trash, "trash"}, {brick_graph_add_posix, "posix"}, }; diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h index bc9c2265384..947de76c926 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.h +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h @@ -32,6 +32,7 @@ #define VKEY_MARKER_XTIME_FORCE GEOREP".ignore-pid-check" #define VKEY_CHANGELOG "changelog.changelog" #define VKEY_FEATURES_QUOTA "features.quota" +#define VKEY_FEATURES_TRASH "features.trash" #define AUTH_ALLOW_MAP_KEY "auth.allow" #define AUTH_REJECT_MAP_KEY "auth.reject" diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index b0cf2609210..77f6853dd51 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -1641,6 +1641,28 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "mgmt/glusterd", .op_version = GD_OP_VERSION_3_6_0, }, + + /*Trash translator options */ + { .key = "features.trash", + .voltype = "features/trash", + .op_version = GD_OP_VERSION_3_7_0, + }, + { .key = "features.trash-dir", + .voltype = "features/trash", + .op_version = GD_OP_VERSION_3_7_0, + }, + { .key = "features.trash-eliminate-path", + .voltype = "features/trash", + .op_version = GD_OP_VERSION_3_7_0, + }, + { .key = "features.trash-max-filesize", + .voltype = "features/trash", + .op_version = GD_OP_VERSION_3_7_0, + }, + { .key = "features.trash-internal-op", + .voltype = "features/trash", + .op_version = GD_OP_VERSION_3_7_0, + }, { .key = "locks.trace", .voltype = "features/locks", .type = NO_DOC, -- cgit