|
|
cb8e9e |
From 069d8f649618fc1230ce6382ddd12c6b082262c3 Mon Sep 17 00:00:00 2001
|
|
|
cb8e9e |
From: Venky Shankar <vshankar@redhat.com>
|
|
|
cb8e9e |
Date: Tue, 2 Jun 2015 21:23:48 +0530
|
|
|
cb8e9e |
Subject: [PATCH 158/190] features/bitrot: cleanup, v1
|
|
|
cb8e9e |
|
|
|
cb8e9e |
Backport of http://review.gluster.org/11147
|
|
|
cb8e9e |
|
|
|
cb8e9e |
This is a short series of patches (with other cleanups) aimed at
|
|
|
cb8e9e |
cleaning up some of the incorrect assumptions taken in reconfigure()
|
|
|
cb8e9e |
leading to crashes when subvolumes are not fully initialized (as
|
|
|
cb8e9e |
reported here[1] on gluster-devel@). Furthermore, there is some
|
|
|
cb8e9e |
amount of code cleanup to handle disconnection and cleanup up data
|
|
|
cb8e9e |
structure (as part of subsequent patch).
|
|
|
cb8e9e |
|
|
|
cb8e9e |
[1] http://www.gluster.org/pipermail/gluster-devel/2015-June/045410.html
|
|
|
cb8e9e |
|
|
|
cb8e9e |
Change-Id: I68ac4bccfbac4bf02fcc31615bd7d2d191021132
|
|
|
cb8e9e |
BUG: 1232307
|
|
|
cb8e9e |
Signed-off-by: Venky Shankar <vshankar@redhat.com>
|
|
|
cb8e9e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/51743
|
|
|
cb8e9e |
Tested-by: Raghavendra Bhat <raghavendra@redhat.com>
|
|
|
cb8e9e |
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
|
|
|
cb8e9e |
---
|
|
|
cb8e9e |
xlators/features/bit-rot/src/bitd/bit-rot.c | 364 +++++++++++++-------
|
|
|
cb8e9e |
xlators/features/bit-rot/src/bitd/bit-rot.h | 32 ++-
|
|
|
cb8e9e |
.../bit-rot/src/stub/bit-rot-stub-mem-types.h | 1 +
|
|
|
cb8e9e |
3 files changed, 271 insertions(+), 126 deletions(-)
|
|
|
cb8e9e |
|
|
|
cb8e9e |
diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.c b/xlators/features/bit-rot/src/bitd/bit-rot.c
|
|
|
cb8e9e |
index c06a5c1..b855cd7 100644
|
|
|
cb8e9e |
--- a/xlators/features/bit-rot/src/bitd/bit-rot.c
|
|
|
cb8e9e |
+++ b/xlators/features/bit-rot/src/bitd/bit-rot.c
|
|
|
cb8e9e |
@@ -30,6 +30,18 @@
|
|
|
cb8e9e |
|
|
|
cb8e9e |
#define BR_HASH_CALC_READ_SIZE (128 * 1024)
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+typedef int32_t (br_child_handler)(xlator_t *, br_child_t *);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+struct br_child_event {
|
|
|
cb8e9e |
+ xlator_t *this;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ br_child_t *child;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ br_child_handler *call;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ struct list_head list;
|
|
|
cb8e9e |
+};
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
static int
|
|
|
cb8e9e |
br_find_child_index (xlator_t *this, xlator_t *child)
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
@@ -54,26 +66,6 @@ out:
|
|
|
cb8e9e |
return index;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
-static void
|
|
|
cb8e9e |
-br_free_children (xlator_t *this)
|
|
|
cb8e9e |
-{
|
|
|
cb8e9e |
- br_private_t *priv = NULL;
|
|
|
cb8e9e |
- int32_t i = 0;
|
|
|
cb8e9e |
- br_child_t *child = NULL;
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- priv = this->private;
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- for (i = 0; i < priv->child_count; i++) {
|
|
|
cb8e9e |
- child = &priv->children[i];
|
|
|
cb8e9e |
- mem_pool_destroy (child->timer_pool);
|
|
|
cb8e9e |
- list_del_init (&priv->children[i].list);
|
|
|
cb8e9e |
- }
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- GF_FREE (priv->children);
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- priv->children = NULL;
|
|
|
cb8e9e |
-}
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
br_child_t *
|
|
|
cb8e9e |
br_get_child_from_brick_path (xlator_t *this, char *brick_path)
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
@@ -1090,6 +1082,16 @@ br_oneshot_signer (void *arg)
|
|
|
cb8e9e |
return NULL;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+static void
|
|
|
cb8e9e |
+br_set_child_state (br_child_t *child, br_child_state_t state)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ LOCK (&child->lock);
|
|
|
cb8e9e |
+ {
|
|
|
cb8e9e |
+ _br_set_child_state (child, state);
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+ UNLOCK (&child->lock);
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
/**
|
|
|
cb8e9e |
* At this point a thread is spawned to crawl the filesystem (in
|
|
|
cb8e9e |
* tortoise pace) to sign objects that were not signed in previous run(s).
|
|
|
cb8e9e |
@@ -1177,7 +1179,12 @@ br_enact_scrubber (xlator_t *this, br_child_t *child)
|
|
|
cb8e9e |
goto error_return;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- ret = br_fsscan_schedule (this, child, fsscan, fsscrub);
|
|
|
cb8e9e |
+ /* this needs to be serialized with reconfigure() */
|
|
|
cb8e9e |
+ pthread_mutex_lock (&priv->lock);
|
|
|
cb8e9e |
+ {
|
|
|
cb8e9e |
+ ret = br_fsscan_schedule (this, child, fsscan, fsscrub);
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+ pthread_mutex_unlock (&priv->lock);
|
|
|
cb8e9e |
if (ret)
|
|
|
cb8e9e |
goto error_return;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
@@ -1202,6 +1209,30 @@ br_enact_scrubber (xlator_t *this, br_child_t *child)
|
|
|
cb8e9e |
return -1;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+static int32_t
|
|
|
cb8e9e |
+br_child_enaction (xlator_t *this, br_child_t *child, br_stub_init_t *stub)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ int32_t ret = -1;
|
|
|
cb8e9e |
+ br_private_t *priv = this->private;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ LOCK (&child->lock);
|
|
|
cb8e9e |
+ {
|
|
|
cb8e9e |
+ if (priv->iamscrubber)
|
|
|
cb8e9e |
+ ret = br_enact_scrubber (this, child);
|
|
|
cb8e9e |
+ else
|
|
|
cb8e9e |
+ ret = br_enact_signer (this, child, stub);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ if (!ret) {
|
|
|
cb8e9e |
+ _br_set_child_state (child, BR_CHILD_STATE_CONNECTED);
|
|
|
cb8e9e |
+ gf_log (this->name, GF_LOG_INFO,
|
|
|
cb8e9e |
+ "Connected to brick %s..", child->brick_path);
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+ UNLOCK (&child->lock);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ return ret;
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
/**
|
|
|
cb8e9e |
* This routine fetches various attributes associated with a child which
|
|
|
cb8e9e |
* is basically a subvolume. Attributes include brick path and the stub
|
|
|
cb8e9e |
@@ -1209,7 +1240,7 @@ br_enact_scrubber (xlator_t *this, br_child_t *child)
|
|
|
cb8e9e |
* by getxattr() on a virtual key. Depending on the configuration, the
|
|
|
cb8e9e |
* process either acts as a signer or a scrubber.
|
|
|
cb8e9e |
*/
|
|
|
cb8e9e |
-static inline int32_t
|
|
|
cb8e9e |
+int32_t
|
|
|
cb8e9e |
br_brick_connect (xlator_t *this, br_child_t *child)
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
int32_t ret = -1;
|
|
|
cb8e9e |
@@ -1218,14 +1249,13 @@ br_brick_connect (xlator_t *this, br_child_t *child)
|
|
|
cb8e9e |
struct iatt parent = {0, };
|
|
|
cb8e9e |
br_stub_init_t *stub = NULL;
|
|
|
cb8e9e |
dict_t *xattr = NULL;
|
|
|
cb8e9e |
- br_private_t *priv = NULL;
|
|
|
cb8e9e |
int op_errno = 0;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
GF_VALIDATE_OR_GOTO ("bit-rot", this, out);
|
|
|
cb8e9e |
GF_VALIDATE_OR_GOTO (this->name, child, out);
|
|
|
cb8e9e |
GF_VALIDATE_OR_GOTO (this->name, this->private, out);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- priv = this->private;
|
|
|
cb8e9e |
+ br_set_child_state (child, BR_CHILD_STATE_INITIALIZING);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
loc.inode = inode_ref (child->table->root);
|
|
|
cb8e9e |
gf_uuid_copy (loc.gfid, loc.inode->gfid);
|
|
|
cb8e9e |
@@ -1262,20 +1292,15 @@ br_brick_connect (xlator_t *this, br_child_t *child)
|
|
|
cb8e9e |
child->tv.tv_sec = ntohl (stub->timebuf[0]);
|
|
|
cb8e9e |
child->tv.tv_usec = ntohl (stub->timebuf[1]);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- if (priv->iamscrubber)
|
|
|
cb8e9e |
- ret = br_enact_scrubber (this, child);
|
|
|
cb8e9e |
- else
|
|
|
cb8e9e |
- ret = br_enact_signer (this, child, stub);
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- if (!ret)
|
|
|
cb8e9e |
- gf_msg (this->name, GF_LOG_INFO, 0, BRB_MSG_CONNECTED_TO_BRICK,
|
|
|
cb8e9e |
- "Connected to brick %s..", child->brick_path);
|
|
|
cb8e9e |
+ ret = br_child_enaction (this, child, stub);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
free_dict:
|
|
|
cb8e9e |
dict_unref (xattr);
|
|
|
cb8e9e |
wipeloc:
|
|
|
cb8e9e |
loc_wipe (&loc;;
|
|
|
cb8e9e |
out:
|
|
|
cb8e9e |
+ if (ret)
|
|
|
cb8e9e |
+ br_set_child_state (child, BR_CHILD_STATE_CONNFAILED);
|
|
|
cb8e9e |
return ret;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
@@ -1290,7 +1315,8 @@ br_handle_events (void *arg)
|
|
|
cb8e9e |
int32_t ret = 0;
|
|
|
cb8e9e |
xlator_t *this = NULL;
|
|
|
cb8e9e |
br_private_t *priv = NULL;
|
|
|
cb8e9e |
- br_child_t *child = NULL;
|
|
|
cb8e9e |
+ br_child_t *child = NULL;
|
|
|
cb8e9e |
+ struct br_child_event *childev = NULL;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
this = arg;
|
|
|
cb8e9e |
priv = this->private;
|
|
|
cb8e9e |
@@ -1309,17 +1335,20 @@ br_handle_events (void *arg)
|
|
|
cb8e9e |
while (list_empty (&priv->bricks))
|
|
|
cb8e9e |
pthread_cond_wait (&priv->cond, &priv->lock);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- child = list_first_entry
|
|
|
cb8e9e |
- (&priv->bricks, br_child_t, list);
|
|
|
cb8e9e |
- list_del_init (&child->list);
|
|
|
cb8e9e |
+ childev = list_first_entry
|
|
|
cb8e9e |
+ (&priv->bricks, struct br_child_event, list);
|
|
|
cb8e9e |
+ list_del_init (&childev->list);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
pthread_mutex_unlock (&priv->lock);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- ret = br_brick_connect (this, child);
|
|
|
cb8e9e |
+ child = childev->child;
|
|
|
cb8e9e |
+ ret = childev->call (this, child);
|
|
|
cb8e9e |
if (ret)
|
|
|
cb8e9e |
gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
cb8e9e |
- BRB_MSG_SUBVOL_CONNECT_FAILED, "failed to "
|
|
|
cb8e9e |
- "connect to subvolume %s", child->xl->name);
|
|
|
cb8e9e |
+ BRB_MSG_SUBVOL_CONNECT_FAILED,
|
|
|
cb8e9e |
+ "callback handler for subvolume [%s] failed",
|
|
|
cb8e9e |
+ child->xl->name);
|
|
|
cb8e9e |
+ GF_FREE (childev);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
return NULL;
|
|
|
cb8e9e |
@@ -1344,6 +1373,29 @@ mem_acct_init (xlator_t *this)
|
|
|
cb8e9e |
return ret;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+static void
|
|
|
cb8e9e |
+_br_qchild_event (xlator_t *this, br_child_t *child, br_child_handler *call)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ br_private_t *priv = NULL;
|
|
|
cb8e9e |
+ struct br_child_event *childev = NULL;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ priv = this->private;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ childev = GF_CALLOC (1, sizeof (*childev), gf_br_mt_br_child_event_t);
|
|
|
cb8e9e |
+ if (!childev) {
|
|
|
cb8e9e |
+ gf_log (this->name, GF_LOG_ERROR, "Event unhandled for "
|
|
|
cb8e9e |
+ "child.. [Brick: %s]", child->xl->name);
|
|
|
cb8e9e |
+ return;
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ INIT_LIST_HEAD (&childev->list);
|
|
|
cb8e9e |
+ childev->this = this;
|
|
|
cb8e9e |
+ childev->child = child;
|
|
|
cb8e9e |
+ childev->call = call;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ list_add_tail (&childev->list, &priv->bricks);
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
int
|
|
|
cb8e9e |
notify (xlator_t *this, int32_t event, void *data, ...)
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
@@ -1373,14 +1425,14 @@ notify (xlator_t *this, int32_t event, void *data, ...)
|
|
|
cb8e9e |
child = &priv->children[idx];
|
|
|
cb8e9e |
if (child->child_up == 1)
|
|
|
cb8e9e |
goto unblock;
|
|
|
cb8e9e |
+ priv->up_children++;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
child->child_up = 1;
|
|
|
cb8e9e |
child->xl = subvol;
|
|
|
cb8e9e |
- child->table = inode_table_new (4096, subvol);
|
|
|
cb8e9e |
+ if (!child->table)
|
|
|
cb8e9e |
+ child->table = inode_table_new (4096, subvol);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- priv->up_children++;
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- list_add_tail (&child->list, &priv->bricks);
|
|
|
cb8e9e |
+ _br_qchild_event (this, child, br_brick_connect);
|
|
|
cb8e9e |
pthread_cond_signal (&priv->cond);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
unblock:
|
|
|
cb8e9e |
@@ -1410,6 +1462,7 @@ notify (xlator_t *this, int32_t event, void *data, ...)
|
|
|
cb8e9e |
if (priv->up_children == 0)
|
|
|
cb8e9e |
default_notify (this, event, data);
|
|
|
cb8e9e |
break;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
default:
|
|
|
cb8e9e |
default_notify (this, event, data);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
@@ -1563,59 +1616,94 @@ br_signer_init (xlator_t *this, br_private_t *priv)
|
|
|
cb8e9e |
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
-int32_t
|
|
|
cb8e9e |
-init (xlator_t *this)
|
|
|
cb8e9e |
+static void
|
|
|
cb8e9e |
+br_free_children (xlator_t *this, br_private_t *priv, int count)
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
- int i = 0;
|
|
|
cb8e9e |
- int32_t ret = -1;
|
|
|
cb8e9e |
- br_private_t *priv = NULL;
|
|
|
cb8e9e |
- xlator_list_t *trav = NULL;
|
|
|
cb8e9e |
+ br_child_t *child = NULL;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- if (!this->children) {
|
|
|
cb8e9e |
- gf_msg (this->name, GF_LOG_ERROR, 0, BRB_MSG_NO_CHILD,
|
|
|
cb8e9e |
- "FATAL: no children");
|
|
|
cb8e9e |
- goto out;
|
|
|
cb8e9e |
+ for (--count; count >= 0; count--) {
|
|
|
cb8e9e |
+ child = &priv->children[count];
|
|
|
cb8e9e |
+ mem_pool_destroy (child->timer_pool);
|
|
|
cb8e9e |
+ LOCK_DESTROY (&child->lock);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- priv = GF_CALLOC (1, sizeof (*priv), gf_br_mt_br_private_t);
|
|
|
cb8e9e |
- if (!priv) {
|
|
|
cb8e9e |
- gf_msg (this->name, GF_LOG_ERROR, ENOMEM, BRB_MSG_NO_MEMORY,
|
|
|
cb8e9e |
- "failed to allocate memory (->priv)");
|
|
|
cb8e9e |
- goto out;
|
|
|
cb8e9e |
- }
|
|
|
cb8e9e |
+ GF_FREE (priv->children);
|
|
|
cb8e9e |
+ priv->children = NULL;
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- GF_OPTION_INIT ("scrubber", priv->iamscrubber, bool, out);
|
|
|
cb8e9e |
+static int
|
|
|
cb8e9e |
+br_init_children (xlator_t *this, br_private_t *priv)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ int i = 0;
|
|
|
cb8e9e |
+ br_child_t *child = NULL;
|
|
|
cb8e9e |
+ xlator_list_t *trav = NULL;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
priv->child_count = xlator_subvolume_count (this);
|
|
|
cb8e9e |
priv->children = GF_CALLOC (priv->child_count, sizeof (*priv->children),
|
|
|
cb8e9e |
gf_br_mt_br_child_t);
|
|
|
cb8e9e |
if (!priv->children)
|
|
|
cb8e9e |
- goto free_priv;
|
|
|
cb8e9e |
+ goto err;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
trav = this->children;
|
|
|
cb8e9e |
while (trav) {
|
|
|
cb8e9e |
- priv->children[i].this = this;
|
|
|
cb8e9e |
- priv->children[i].xl = trav->xlator;
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- priv->children[i].timer_pool =
|
|
|
cb8e9e |
- mem_pool_new (struct gf_tw_timer_list, 4096);
|
|
|
cb8e9e |
- if (!priv->children[i].timer_pool) {
|
|
|
cb8e9e |
- gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
|
|
|
cb8e9e |
- BRB_MSG_NO_MEMORY, "failed to allocate mem-pool"
|
|
|
cb8e9e |
- " for timer");
|
|
|
cb8e9e |
+ child = &priv->children[i];
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ LOCK_INIT (&child->lock);
|
|
|
cb8e9e |
+ br_set_child_state (child, BR_CHILD_STATE_DISCONNECTED);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ child->this = this;
|
|
|
cb8e9e |
+ child->xl = trav->xlator;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ child->timer_pool = mem_pool_new
|
|
|
cb8e9e |
+ (struct gf_tw_timer_list, 4096);
|
|
|
cb8e9e |
+ if (!child->timer_pool) {
|
|
|
cb8e9e |
+ gf_log (this->name, GF_LOG_ERROR,
|
|
|
cb8e9e |
+ "failed to allocate mem-pool for timer");
|
|
|
cb8e9e |
errno = ENOMEM;
|
|
|
cb8e9e |
- goto free_children;
|
|
|
cb8e9e |
+ goto freechild;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+ INIT_LIST_HEAD (&child->list);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
i++;
|
|
|
cb8e9e |
trav = trav->next;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+ return 0;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ freechild:
|
|
|
cb8e9e |
+ br_free_children (this, priv, i);
|
|
|
cb8e9e |
+ err:
|
|
|
cb8e9e |
+ return -1;
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+int32_t
|
|
|
cb8e9e |
+init (xlator_t *this)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ int32_t ret = -1;
|
|
|
cb8e9e |
+ br_private_t *priv = NULL;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ if (!this->children) {
|
|
|
cb8e9e |
+ gf_log (this->name, GF_LOG_ERROR, "FATAL: no children");
|
|
|
cb8e9e |
+ goto out;
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ priv = GF_CALLOC (1, sizeof (*priv), gf_br_mt_br_private_t);
|
|
|
cb8e9e |
+ if (!priv) {
|
|
|
cb8e9e |
+ gf_log (this->name, GF_LOG_ERROR,
|
|
|
cb8e9e |
+ "failed to allocate memory (->priv)");
|
|
|
cb8e9e |
+ goto out;
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ GF_OPTION_INIT ("scrubber", priv->iamscrubber, bool, out);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ ret = br_init_children (this, priv);
|
|
|
cb8e9e |
+ if (ret)
|
|
|
cb8e9e |
+ goto free_priv;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
pthread_mutex_init (&priv->lock, NULL);
|
|
|
cb8e9e |
pthread_cond_init (&priv->cond, NULL);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- for (i = 0; i < priv->child_count; i++)
|
|
|
cb8e9e |
- INIT_LIST_HEAD (&priv->children[i].list);
|
|
|
cb8e9e |
INIT_LIST_HEAD (&priv->bricks);
|
|
|
cb8e9e |
INIT_LIST_HEAD (&priv->signing);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
@@ -1624,7 +1712,7 @@ init (xlator_t *this)
|
|
|
cb8e9e |
gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
cb8e9e |
BRB_MSG_TIMER_WHEEL_UNAVAILABLE,
|
|
|
cb8e9e |
"global timer wheel unavailable");
|
|
|
cb8e9e |
- goto cleanup_mutex;
|
|
|
cb8e9e |
+ goto cleanup;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
this->private = priv;
|
|
|
cb8e9e |
@@ -1640,7 +1728,7 @@ init (xlator_t *this)
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
if (ret)
|
|
|
cb8e9e |
- goto cleanup_mutex;
|
|
|
cb8e9e |
+ goto cleanup;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
ret = gf_thread_create (&priv->thread, NULL, br_handle_events, this);
|
|
|
cb8e9e |
if (ret != 0) {
|
|
|
cb8e9e |
@@ -1656,16 +1744,12 @@ init (xlator_t *this)
|
|
|
cb8e9e |
return 0;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- cleanup_mutex:
|
|
|
cb8e9e |
+ cleanup:
|
|
|
cb8e9e |
(void) pthread_cond_destroy (&priv->cond);
|
|
|
cb8e9e |
(void) pthread_mutex_destroy (&priv->lock);
|
|
|
cb8e9e |
- free_children:
|
|
|
cb8e9e |
- for (i = 0; i < priv->child_count; i++) {
|
|
|
cb8e9e |
- if (priv->children[i].timer_pool)
|
|
|
cb8e9e |
- mem_pool_destroy (priv->children[i].timer_pool);
|
|
|
cb8e9e |
- }
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- GF_FREE (priv->children);
|
|
|
cb8e9e |
+ br_free_children (this, priv, priv->child_count);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
free_priv:
|
|
|
cb8e9e |
GF_FREE (priv);
|
|
|
cb8e9e |
out:
|
|
|
cb8e9e |
@@ -1683,7 +1767,7 @@ fini (xlator_t *this)
|
|
|
cb8e9e |
|
|
|
cb8e9e |
if (!priv->iamscrubber)
|
|
|
cb8e9e |
br_fini_signer (this, priv);
|
|
|
cb8e9e |
- br_free_children (this);
|
|
|
cb8e9e |
+ br_free_children (this, priv, priv->child_count);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
this->private = NULL;
|
|
|
cb8e9e |
GF_FREE (priv);
|
|
|
cb8e9e |
@@ -1691,64 +1775,96 @@ fini (xlator_t *this)
|
|
|
cb8e9e |
return;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
-int
|
|
|
cb8e9e |
-reconfigure (xlator_t *this, dict_t *options)
|
|
|
cb8e9e |
+static void
|
|
|
cb8e9e |
+br_reconfigure_child (xlator_t *this,
|
|
|
cb8e9e |
+ br_child_t *child, struct br_scrubber *fsscrub)
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
- int i = 0;
|
|
|
cb8e9e |
- int32_t ret = -1;
|
|
|
cb8e9e |
- br_child_t *child = NULL;
|
|
|
cb8e9e |
- br_private_t *priv = NULL;
|
|
|
cb8e9e |
- struct br_scanfs *fsscan = NULL;
|
|
|
cb8e9e |
+ int32_t ret = 0;
|
|
|
cb8e9e |
+ struct br_scanfs *fsscan = &child->fsscan;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ ret = br_fsscan_reschedule (this, child, fsscan, fsscrub, _gf_true);
|
|
|
cb8e9e |
+ if (ret) {
|
|
|
cb8e9e |
+ gf_log (this->name, GF_LOG_ERROR,
|
|
|
cb8e9e |
+ "Could not reschedule scrubber for brick: %s. "
|
|
|
cb8e9e |
+ "Scubbing will continue according to old frequency.",
|
|
|
cb8e9e |
+ child->brick_path);
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+static int
|
|
|
cb8e9e |
+br_reconfigure_scrubber (xlator_t *this, dict_t *options)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ int i = 0;
|
|
|
cb8e9e |
+ int32_t ret = -1;
|
|
|
cb8e9e |
+ br_child_t *child = NULL;
|
|
|
cb8e9e |
+ br_private_t *priv = NULL;
|
|
|
cb8e9e |
struct br_scrubber *fsscrub = NULL;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
priv = this->private;
|
|
|
cb8e9e |
+ fsscrub = &priv->fsscrub;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- if (!priv->iamscrubber) {
|
|
|
cb8e9e |
- ret = br_signer_handle_options (this, priv, options);
|
|
|
cb8e9e |
- if (ret)
|
|
|
cb8e9e |
- goto err;
|
|
|
cb8e9e |
- return 0;
|
|
|
cb8e9e |
+ pthread_mutex_lock (&priv->lock);
|
|
|
cb8e9e |
+ {
|
|
|
cb8e9e |
+ ret = br_scrubber_handle_options (this, priv, options);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
+ pthread_mutex_unlock (&priv->lock);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- ret = br_scrubber_handle_options (this, priv, options);
|
|
|
cb8e9e |
if (ret)
|
|
|
cb8e9e |
goto err;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- fsscrub = &priv->fsscrub;
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
/* reschedule all _up_ subvolume(s) */
|
|
|
cb8e9e |
- pthread_mutex_lock (&priv->lock);
|
|
|
cb8e9e |
- {
|
|
|
cb8e9e |
- for (; i < priv->child_count; i++) {
|
|
|
cb8e9e |
- child = &priv->children[i];
|
|
|
cb8e9e |
- if (!child->child_up) {
|
|
|
cb8e9e |
- gf_msg (this->name, GF_LOG_INFO, 0,
|
|
|
cb8e9e |
- BRB_MSG_BRICK_INFO, "Brick %s is "
|
|
|
cb8e9e |
- "offline, skipping rescheduling (scrub"
|
|
|
cb8e9e |
- " would auto- schedule when brick is "
|
|
|
cb8e9e |
- "back online).", child->brick_path);
|
|
|
cb8e9e |
- continue;
|
|
|
cb8e9e |
- }
|
|
|
cb8e9e |
+ for (; i < priv->child_count; i++) {
|
|
|
cb8e9e |
+ child = &priv->children[i];
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- fsscan = &child->fsscan;
|
|
|
cb8e9e |
- ret = br_fsscan_reschedule (this, child,
|
|
|
cb8e9e |
- fsscan, fsscrub, _gf_true);
|
|
|
cb8e9e |
- if (ret) {
|
|
|
cb8e9e |
- gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
cb8e9e |
- BRB_MSG_RESCHEDULE_SCRUBBER_FAILED,
|
|
|
cb8e9e |
- "Could not reschedule scrubber for "
|
|
|
cb8e9e |
- "brick: %s. Scubbing will continue "
|
|
|
cb8e9e |
- "according to old frequency.",
|
|
|
cb8e9e |
- child->brick_path);
|
|
|
cb8e9e |
+ LOCK (&child->lock);
|
|
|
cb8e9e |
+ {
|
|
|
cb8e9e |
+ if (_br_child_failed_conn (child)) {
|
|
|
cb8e9e |
+ gf_log (this->name, GF_LOG_INFO,
|
|
|
cb8e9e |
+ "Scrubber for brick [%s] failed "
|
|
|
cb8e9e |
+ "initialization, rescheduling is "
|
|
|
cb8e9e |
+ "skipped", child->brick_path);
|
|
|
cb8e9e |
+ goto unblock;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ if (_br_is_child_connected (child))
|
|
|
cb8e9e |
+ br_reconfigure_child (this, child, fsscrub);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ /**
|
|
|
cb8e9e |
+ * for the rest.. either the child is in initialization
|
|
|
cb8e9e |
+ * phase or is disconnected. either way, updated values
|
|
|
cb8e9e |
+ * would be reflected on successful connection.
|
|
|
cb8e9e |
+ */
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
+ unblock:
|
|
|
cb8e9e |
+ UNLOCK (&child->lock);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
- pthread_mutex_unlock (&priv->lock);
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
- return 0;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
err:
|
|
|
cb8e9e |
- return -1;
|
|
|
cb8e9e |
+ return ret;
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+static int
|
|
|
cb8e9e |
+br_reconfigure_signer (xlator_t *this, dict_t *options)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ br_private_t *priv = this->private;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ return br_signer_handle_options (this, priv, options);
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+int
|
|
|
cb8e9e |
+reconfigure (xlator_t *this, dict_t *options)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ int ret = 0;
|
|
|
cb8e9e |
+ br_private_t *priv = NULL;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ priv = this->private;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ if (priv->iamscrubber)
|
|
|
cb8e9e |
+ ret = br_reconfigure_scrubber (this, options);
|
|
|
cb8e9e |
+ else
|
|
|
cb8e9e |
+ ret = br_reconfigure_signer (this, options);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ return ret;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
struct xlator_fops fops;
|
|
|
cb8e9e |
diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.h b/xlators/features/bit-rot/src/bitd/bit-rot.h
|
|
|
cb8e9e |
index 562f17e..b8d9e3b 100644
|
|
|
cb8e9e |
--- a/xlators/features/bit-rot/src/bitd/bit-rot.h
|
|
|
cb8e9e |
+++ b/xlators/features/bit-rot/src/bitd/bit-rot.h
|
|
|
cb8e9e |
@@ -76,7 +76,18 @@ struct br_scanfs {
|
|
|
cb8e9e |
struct gf_tw_timer_list *timer;
|
|
|
cb8e9e |
};
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+/* just need three states to track child status */
|
|
|
cb8e9e |
+typedef enum br_child_state {
|
|
|
cb8e9e |
+ BR_CHILD_STATE_CONNECTED = 1,
|
|
|
cb8e9e |
+ BR_CHILD_STATE_INITIALIZING,
|
|
|
cb8e9e |
+ BR_CHILD_STATE_CONNFAILED,
|
|
|
cb8e9e |
+ BR_CHILD_STATE_DISCONNECTED,
|
|
|
cb8e9e |
+} br_child_state_t;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
struct br_child {
|
|
|
cb8e9e |
+ gf_lock_t lock;
|
|
|
cb8e9e |
+ br_child_state_t c_state;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
char child_up; /* Indicates whether this child is
|
|
|
cb8e9e |
up or not */
|
|
|
cb8e9e |
xlator_t *xl; /* client xlator corresponding to
|
|
|
cb8e9e |
@@ -140,8 +151,8 @@ typedef struct br_obj_n_workers br_obj_n_workers_t;
|
|
|
cb8e9e |
struct br_private {
|
|
|
cb8e9e |
pthread_mutex_t lock;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- struct list_head bricks; /* list of bricks from which CHILD_UP
|
|
|
cb8e9e |
- has been received */
|
|
|
cb8e9e |
+ struct list_head bricks; /* list of bricks from which enents
|
|
|
cb8e9e |
+ have been received */
|
|
|
cb8e9e |
|
|
|
cb8e9e |
struct list_head signing;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
@@ -207,5 +218,22 @@ br_prepare_loc (xlator_t *, br_child_t *, loc_t *, gf_dirent_t *, loc_t *);
|
|
|
cb8e9e |
gf_boolean_t
|
|
|
cb8e9e |
bitd_is_bad_file (xlator_t *, br_child_t *, loc_t *, fd_t *);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+static inline void
|
|
|
cb8e9e |
+_br_set_child_state (br_child_t *child, br_child_state_t state)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ child->c_state = state;
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+static inline int
|
|
|
cb8e9e |
+_br_is_child_connected (br_child_t *child)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ return (child->c_state == BR_CHILD_STATE_CONNECTED);
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+static inline int
|
|
|
cb8e9e |
+_br_child_failed_conn (br_child_t *child)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ return (child->c_state == BR_CHILD_STATE_CONNFAILED);
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
#endif /* __BIT_ROT_H__ */
|
|
|
cb8e9e |
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h b/xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h
|
|
|
cb8e9e |
index fbb69ce..f70fafb 100644
|
|
|
cb8e9e |
--- a/xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h
|
|
|
cb8e9e |
+++ b/xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h
|
|
|
cb8e9e |
@@ -31,6 +31,7 @@ enum br_mem_types {
|
|
|
cb8e9e |
gf_br_stub_mt_br_stub_fd_t,
|
|
|
cb8e9e |
gf_br_stub_mt_br_scanner_freq_t,
|
|
|
cb8e9e |
gf_br_stub_mt_sigstub_t,
|
|
|
cb8e9e |
+ gf_br_mt_br_child_event_t,
|
|
|
cb8e9e |
gf_br_stub_mt_end,
|
|
|
cb8e9e |
};
|
|
|
cb8e9e |
|
|
|
cb8e9e |
--
|
|
|
cb8e9e |
1.7.1
|
|
|
cb8e9e |
|