summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-rpc-ops.c30
-rw-r--r--tests/bitrot/bug-1207627-bitrot-scrub-status.t7
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot-scrub.c137
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot.c45
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot.h25
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c17
6 files changed, 220 insertions, 41 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index b623051cad9..6dcf0f37e3f 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -10736,7 +10736,11 @@ gf_cli_print_bitrot_scrub_status (dict_t *dict)
uint64_t scrub_files = 0;
uint64_t unsigned_files = 0;
uint64_t scrub_time = 0;
- uint64_t last_scrub = 0;
+ uint64_t days = 0;
+ uint64_t hour = 0;
+ uint64_t minut = 0;
+ uint64_t second = 0;
+ char *last_scrub = NULL;
uint64_t error_count = 0;
@@ -10790,8 +10794,12 @@ gf_cli_print_bitrot_scrub_status (dict_t *dict)
for (i = 1; i <= count; i++) {
/* Reset the variables to prevent carryover of values */
node_name = NULL;
- last_scrub = 0;
+ last_scrub = NULL;
scrub_time = 0;
+ days = 0;
+ hour = 0;
+ minut = 0;
+ second = 0;
error_count = 0;
scrub_files = 0;
unsigned_files = 0;
@@ -10825,7 +10833,7 @@ gf_cli_print_bitrot_scrub_status (dict_t *dict)
memset (key, 0, 256);
snprintf (key, 256, "last-scrub-time-%d", i);
- ret = dict_get_uint64 (dict, key, &last_scrub);
+ ret = dict_get_str (dict, key, &last_scrub);
if (ret)
gf_log ("cli", GF_LOG_TRACE, "failed to get last scrub"
" time");
@@ -10848,11 +10856,17 @@ gf_cli_print_bitrot_scrub_status (dict_t *dict)
cli_out ("%s: %"PRIu64 "\n", "Number of Unsigned files",
unsigned_files);
- cli_out ("%s: %"PRIu64 "\n", "Last completed scrub time",
- scrub_time);
-
- cli_out ("%s: %"PRIu64 "\n", "Duration of last scrub",
- last_scrub);
+ cli_out ("%s: %s\n", "Last completed scrub time",
+ (*last_scrub) ? last_scrub : "Scrubber pending to "
+ "complete.");
+
+ /* Printing last scrub duration time in human readable form*/
+ days = scrub_time/86400;
+ hour = (scrub_time%86400)/3600;
+ minut = (scrub_time%86400%3600)/60;
+ second = (scrub_time%86400%3600%60);
+ cli_out ("%s: %"PRIu64 ":%"PRIu64 ":%"PRIu64 ":%"PRIu64 "\n",
+ "Duration of last scrub", days, hour, minut, second);
cli_out ("%s: %"PRIu64 "\n", "Error count", error_count);
diff --git a/tests/bitrot/bug-1207627-bitrot-scrub-status.t b/tests/bitrot/bug-1207627-bitrot-scrub-status.t
index 0bbcb38cde2..bca3919e2ac 100644
--- a/tests/bitrot/bug-1207627-bitrot-scrub-status.t
+++ b/tests/bitrot/bug-1207627-bitrot-scrub-status.t
@@ -33,11 +33,4 @@ EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'hourly' scrub_status $V0 'Scrub frequency'
EXPECT_WITHIN $PROCESS_UP_TIMEOUT '/var/log/glusterfs/bitd.log' scrub_status $V0 'Bitrot error log location'
EXPECT_WITHIN $PROCESS_UP_TIMEOUT '/var/log/glusterfs/scrub.log' scrub_status $V0 'Scrubber error log location'
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT '0' scrub_status $V0 'Number of Scrubbed files'
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT '0' scrub_status $V0 'Number of Unsigned files'
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT '0' scrub_status $V0 'Last completed scrub time'
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT '0' scrub_status $V0 'Duration of last scrub'
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT '0' scrub_status $V0 'Error count'
-
-
cleanup;
diff --git a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c
index 768b3bc98cd..9a9a9a6bb70 100644
--- a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c
+++ b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c
@@ -79,6 +79,20 @@ bitd_fetch_signature (xlator_t *this, br_child_t *child,
}
+static void
+br_inc_unsigned_file_count (xlator_t *this)
+{
+ br_private_t *priv = NULL;
+
+ priv = this->private;
+
+ pthread_mutex_lock (&priv->scrub_stat.lock);
+ {
+ priv->scrub_stat.unsigned_files++;
+ }
+ pthread_mutex_unlock (&priv->scrub_stat.lock);
+}
+
/**
* POST COMPUTE CHECK
*
@@ -112,6 +126,7 @@ bitd_scrub_post_compute_check (xlator_t *this,
* The log entry looks pretty ugly, but helps in debugging..
*/
if (signptr->stale || (signptr->version != version)) {
+ br_inc_unsigned_file_count (this);
gf_msg_debug (this->name, 0, "<STAGE: POST> Object [GFID: %s] "
"either has a stale signature OR underwent "
"signing during checksumming {Stale: %d | "
@@ -186,6 +201,7 @@ bitd_scrub_pre_compute_check (xlator_t *this, br_child_t *child,
ret = bitd_signature_staleness (this, child, fd, &stale, version);
if (!ret && stale) {
+ br_inc_unsigned_file_count (this);
gf_msg_debug (this->name, 0, "<STAGE: PRE> Object [GFID: %s] "
"has stale signature",
uuid_utoa (fd->inode->gfid));
@@ -258,6 +274,16 @@ bitd_compare_ckum (xlator_t *this,
return ret;
}
+static void
+br_inc_scrubbed_file (br_private_t *priv)
+{
+ pthread_mutex_lock (&priv->scrub_stat.lock);
+ {
+ priv->scrub_stat.scrubbed_files++;
+ }
+ pthread_mutex_unlock (&priv->scrub_stat.lock);
+}
+
/**
* "The Scrubber"
*
@@ -268,19 +294,20 @@ bitd_compare_ckum (xlator_t *this,
int
br_scrubber_scrub_begin (xlator_t *this, struct br_fsscan_entry *fsentry)
{
- int32_t ret = -1;
- fd_t *fd = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- struct iatt parent_buf = {0, };
- pid_t pid = 0;
- br_child_t *child = NULL;
- unsigned char *md = NULL;
- inode_t *linked_inode = NULL;
- br_isignature_out_t *sign = NULL;
- unsigned long signedversion = 0;
- gf_dirent_t *entry = NULL;
- loc_t *parent = NULL;
+ int32_t ret = -1;
+ fd_t *fd = NULL;
+ loc_t loc = {0, };
+ struct iatt iatt = {0, };
+ struct iatt parent_buf = {0, };
+ pid_t pid = 0;
+ br_child_t *child = NULL;
+ unsigned char *md = NULL;
+ inode_t *linked_inode = NULL;
+ br_isignature_out_t *sign = NULL;
+ unsigned long signedversion = 0;
+ gf_dirent_t *entry = NULL;
+ br_private_t *priv = NULL;
+ loc_t *parent = NULL;
GF_VALIDATE_OR_GOTO ("bit-rot", fsentry, out);
@@ -288,9 +315,12 @@ br_scrubber_scrub_begin (xlator_t *this, struct br_fsscan_entry *fsentry)
parent = &fsentry->parent;
child = fsentry->data;
+ priv = this->private;
+
GF_VALIDATE_OR_GOTO ("bit-rot", entry, out);
GF_VALIDATE_OR_GOTO ("bit-rot", parent, out);
GF_VALIDATE_OR_GOTO ("bit-rot", child, out);
+ GF_VALIDATE_OR_GOTO ("bit-rot", priv, out);
pid = GF_CLIENT_PID_SCRUB;
@@ -377,6 +407,9 @@ br_scrubber_scrub_begin (xlator_t *this, struct br_fsscan_entry *fsentry)
ret = bitd_compare_ckum (this, sign, md,
linked_inode, entry, fd, child, &loc);
+ /* Increment of total number of scrubbed file counter */
+ br_inc_scrubbed_file (priv);
+
GF_FREE (sign); /* alloced on post-compute */
/** fd_unref() takes care of closing fd.. like syncop_close() */
@@ -555,21 +588,72 @@ br_fsscan_deactivate (xlator_t *this, br_child_t *child)
return 0;
}
+static void
+br_update_scrub_start_time (xlator_t *this, struct timeval *tv)
+{
+ br_private_t *priv = NULL;
+ static int child;
+
+ priv = this->private;
+
+
+ /* Setting scrubber starting time for first child only */
+ if (child == 0) {
+ pthread_mutex_lock (&priv->scrub_stat.lock);
+ {
+ priv->scrub_stat.scrub_start_tv.tv_sec = tv->tv_sec;
+ }
+ pthread_mutex_unlock (&priv->scrub_stat.lock);
+ }
+
+ if (++child == priv->up_children) {
+ child = 0;
+ }
+}
+
+static void
+br_update_scrub_finish_time (xlator_t *this, char *timestr, struct timeval *tv)
+{
+ br_private_t *priv = NULL;
+ static int child;
+
+ priv = this->private;
+
+ /*Setting scrubber finishing time at time time of last child operation*/
+ if (++child == priv->up_children) {
+ pthread_mutex_lock (&priv->scrub_stat.lock);
+ {
+ priv->scrub_stat.scrub_end_tv.tv_sec = tv->tv_sec;
+
+ priv->scrub_stat.scrub_duration =
+ priv->scrub_stat.scrub_end_tv.tv_sec -
+ priv->scrub_stat.scrub_start_tv.tv_sec;
+
+ strncpy (priv->scrub_stat.last_scrub_time, timestr,
+ sizeof (priv->scrub_stat.last_scrub_time));
+
+ child = 0;
+ }
+ pthread_mutex_unlock (&priv->scrub_stat.lock);
+ }
+}
static inline void
br_fsscanner_log_time (xlator_t *this, br_child_t *child, const char *sfx)
{
- struct timeval tv = {0,};
- char timestr[1024] = {0,};
+ char timestr[1024] = {0,};
+ struct timeval tv = {0,};
gettimeofday (&tv, NULL);
gf_time_fmt (timestr, sizeof (timestr), tv.tv_sec, gf_timefmt_FT);
if (strcasecmp (sfx, "started") == 0) {
+ br_update_scrub_start_time (this, &tv);
gf_msg (this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_START,
"Scrubbing \"%s\" %s at %s", child->brick_path, sfx,
timestr);
} else {
+ br_update_scrub_finish_time (this, timestr, &tv);
gf_msg (this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_FINISH,
"Scrubbing \"%s\" %s at %s", child->brick_path, sfx,
timestr);
@@ -577,14 +661,33 @@ br_fsscanner_log_time (xlator_t *this, br_child_t *child, const char *sfx)
}
static void
-br_fsscanner_wait_until_kicked (struct br_scanfs *fsscan)
+br_fsscanner_wait_until_kicked (xlator_t *this, struct br_scanfs *fsscan)
{
+ static int i;
+ br_private_t *priv = NULL;
+
+ priv = this->private;
+
pthread_cleanup_push (_br_lock_cleaner, &fsscan->wakelock);
pthread_mutex_lock (&fsscan->wakelock);
{
while (!fsscan->kick)
pthread_cond_wait (&fsscan->wakecond,
&fsscan->wakelock);
+
+ /* resetting total number of scrubbed file when scrubbing
+ * done for all of its children */
+ if (i == priv->up_children) {
+ pthread_mutex_lock (&priv->scrub_stat.lock);
+ {
+ priv->scrub_stat.scrubbed_files = 0;
+ priv->scrub_stat.unsigned_files = 0;
+ i = 0;
+ }
+ pthread_mutex_unlock (&priv->scrub_stat.lock);
+ }
+ ++i;
+
fsscan->kick = _gf_false;
}
pthread_mutex_unlock (&fsscan->wakelock);
@@ -642,7 +745,7 @@ br_fsscanner (void *arg)
loc.inode = child->table->root;
while (1) {
- br_fsscanner_wait_until_kicked (fsscan);
+ br_fsscanner_wait_until_kicked (this, fsscan);
{
/* precursor for scrub */
br_fsscanner_entry_control (this, child);
diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.c b/xlators/features/bit-rot/src/bitd/bit-rot.c
index a88fa57662e..9ec2e42bbf6 100644
--- a/xlators/features/bit-rot/src/bitd/bit-rot.c
+++ b/xlators/features/bit-rot/src/bitd/bit-rot.c
@@ -1565,7 +1565,16 @@ int
br_scrubber_status_get (xlator_t *this, dict_t **dict)
{
- int ret = -1;
+ int ret = -1;
+ char key[256] = {0,};
+ br_private_t *priv = NULL;
+ struct br_scrub_stats *scrub_stats = NULL;
+
+ priv = this->private;
+
+ GF_VALIDATE_OR_GOTO ("bit-rot", priv, out);
+
+ scrub_stats = &priv->scrub_stat;
ret = br_get_bad_objects_list (this, dict);
if (ret) {
@@ -1573,6 +1582,40 @@ br_scrubber_status_get (xlator_t *this, dict_t **dict)
"files");
}
+ memset (key, 0, 256);
+ snprintf (key, 256, "scrubbed-files");
+ ret = dict_set_uint32 (*dict, key, scrub_stats->scrubbed_files);
+ if (ret) {
+ gf_msg_debug (this->name, 0, "Failed to setting scrubbed file "
+ "entry to the dictionary");
+ }
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "unsigned-files");
+ ret = dict_set_uint32 (*dict, key, scrub_stats->unsigned_files);
+ if (ret) {
+ gf_msg_debug (this->name, 0, "Failed to set unsigned file count"
+ " entry to the dictionary");
+ }
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "scrub-duration");
+ ret = dict_set_uint32 (*dict, key, scrub_stats->scrub_duration);
+ if (ret) {
+ gf_msg_debug (this->name, 0, "Failed to set scrub duration"
+ " entry to the dictionary");
+ }
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "last-scrub-time");
+ ret = dict_set_dynstr_with_alloc (*dict, key,
+ scrub_stats->last_scrub_time);
+ if (ret) {
+ gf_msg_debug (this->name, 0, "Failed to set "
+ "last scrub time value");
+ }
+
+out:
return ret;
}
diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.h b/xlators/features/bit-rot/src/bitd/bit-rot.h
index 647ea5a3fae..39ce790b4e6 100644
--- a/xlators/features/bit-rot/src/bitd/bit-rot.h
+++ b/xlators/features/bit-rot/src/bitd/bit-rot.h
@@ -159,6 +159,26 @@ struct br_scrubber {
typedef struct br_obj_n_workers br_obj_n_workers_t;
+typedef struct br_private br_private_t;
+
+typedef void (*br_scrubbed_file_update) (br_private_t *priv);
+
+struct br_scrub_stats {
+ uint32_t scrubbed_files; /* Total number of scrubbed file */
+
+ uint32_t unsigned_files; /* Total number of unsigned file */
+
+ uint32_t scrub_duration; /* Duration of last scrub */
+
+ char last_scrub_time[1024]; /*last scrub completion time */
+
+ struct timeval scrub_start_tv; /* Scrubbing starting time*/
+
+ struct timeval scrub_end_tv; /* Scrubbing finishing time */
+
+ pthread_mutex_t lock;
+};
+
struct br_private {
pthread_mutex_t lock;
@@ -184,17 +204,18 @@ struct br_private {
and ready to be picked up for
signing and the workers which sign
the objects */
+
uint32_t expiry_time; /* objects "wait" time */
br_tbf_t *tbf; /* token bucket filter */
gf_boolean_t iamscrubber; /* function as a fs scrubber */
+ struct br_scrub_stats scrub_stat; /* statistics of scrub*/
+
struct br_scrubber fsscrub; /* scrubbers for this subvolume */
};
-typedef struct br_private br_private_t;
-
struct br_object {
xlator_t *this;
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index c373229788b..c9457e89b45 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -8304,7 +8304,8 @@ glusterd_volume_bitrot_scrub_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)
uint64_t scrubbed_files = 0;
uint64_t unsigned_files = 0;
uint64_t scrub_duration = 0;
- uint64_t last_scrub_time = 0;
+ char *last_scrub_time = NULL;
+ char *scrub_time = NULL;
char *volname = NULL;
char *node_uuid = NULL;
char *node_uuid_str = NULL;
@@ -8396,11 +8397,12 @@ glusterd_volume_bitrot_scrub_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)
memset (key, 0, 256);
snprintf (key, 256, "last-scrub-time-%d", src_count);
- ret = dict_get_uint64 (rsp_dict, key, &value);
+ ret = dict_get_str (rsp_dict, key, &last_scrub_time);
if (!ret) {
+ scrub_time = gf_strdup (last_scrub_time);
memset (key, 0, 256);
snprintf (key, 256, "last-scrub-time-%d", src_count+dst_count);
- ret = dict_set_uint64 (aggr, key, value);
+ ret = dict_set_dynstr (aggr, key, scrub_time);
if (ret) {
gf_msg_debug (this->name, 0, "Failed to set "
"last scrub time value");
@@ -8522,7 +8524,8 @@ glusterd_bitrot_volume_node_rsp (dict_t *aggr, dict_t *rsp_dict)
uint64_t scrubbed_files = 0;
uint64_t unsigned_files = 0;
uint64_t scrub_duration = 0;
- uint64_t last_scrub_time = 0;
+ char *last_scrub_time = NULL;
+ char *scrub_time = NULL;
char *volname = NULL;
char *node_str = NULL;
char *scrub_freq = NULL;
@@ -8663,11 +8666,13 @@ glusterd_bitrot_volume_node_rsp (dict_t *aggr, dict_t *rsp_dict)
}
}
- ret = dict_get_uint64 (rsp_dict, "last-scrub-time", &value);
+ ret = dict_get_str (rsp_dict, "last-scrub-time", &last_scrub_time);
if (!ret) {
memset (key, 0, 256);
snprintf (key, 256, "last-scrub-time-%d", i);
- ret = dict_set_uint64 (aggr, key, value);
+
+ scrub_time = gf_strdup (last_scrub_time);
+ ret = dict_set_dynstr (aggr, key, scrub_time);
if (ret) {
gf_msg_debug (this->name, 0, "Failed to set "
"last scrub time value");