summaryrefslogtreecommitdiffstats
path: root/xlators/experimental/fdl
diff options
context:
space:
mode:
authorAvra Sengupta <asengupt@redhat.com>2016-06-23 12:15:22 +0530
committerJeff Darcy <jdarcy@redhat.com>2016-11-08 11:25:25 -0800
commit3e50e09723e024cd451c5f48a153fef0fe4857c7 (patch)
treede1ef8f66ff17eb2791fb406e122486da8cfe463 /xlators/experimental/fdl
parent3e980c5eff495725e7c01793451bc81fd6f94ad5 (diff)
jbr: Sending rollback from failed fop to fdl
In case of a failed fop, the failure is detected by the leader in the jbr-server in two places. First during a quorum check of +ve responses when it receives responses from all the followers. At this point if the fop hasn't been successfully journaled at a quorum of followers (as in there is no merit in trying the fop in the leader as the quorum will never be met), then we fail the fop. Also if this quorum is met, then the fop is tried on the leader, and after the leader completes the fop a quorum check similar to the previous one is done again, this time including the leaders outcome. If quorum is not met, then we fail the fop. In both these cases, when the fop fails we send a -ve ack to the client. With this patch, now we will also send a rollback through a GF_FOP_IPC to all the followers(and also to the leader in the second case of failure). This rollback will contain the index and term number of the fop which failed. This will be recorded in the respective journals of the bricks and will be used to rollback the fop on that brick later. A subsequent write, and it's respective rollback would look something like the following in the journal. The trusted.jbr.term and trusted.jbr.index present in the dict of both the logs, relate them, and the presence of "rollback-fop" in the dict of IPC indicates that it is a rollback fop, and the value 13(stands for GF_FOP_WRITE) indicates what kind of rollback operation it is. === GF_FOP_WRITE fd = <gfid 77f12ea2-ca56-40e3-a46e-ba2308baa035> vector = <158 bytes> offset = 0 (0x0) flags = 32769 (0x8001) xdata = dict { trusted.jbr.term = 0 <2 bytes> trusted.jbr.index = 4 <2 bytes> } === GF_FOP_IPC xdata = dict { trusted.jbr.term = 0 <2 bytes> trusted.jbr.index = 4 <2 bytes> rollback-fop = 13 <3 bytes> } Change-Id: I70b6a143d20697153d58e2f719e34ecd1ed160a5 BUG: 1349385 Signed-off-by: Avra Sengupta <asengupt@redhat.com> Reviewed-on: http://review.gluster.org/14783 NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Jeff Darcy <jdarcy@redhat.com> Smoke: Gluster Build System <jenkins@build.gluster.org>
Diffstat (limited to 'xlators/experimental/fdl')
-rw-r--r--xlators/experimental/fdl/src/Makefile.am2
-rw-r--r--xlators/experimental/fdl/src/dump-tmpl.c35
-rw-r--r--xlators/experimental/fdl/src/fdl-tmpl.c33
-rw-r--r--xlators/experimental/fdl/src/fdl.h30
-rwxr-xr-xxlators/experimental/fdl/src/gen_fdl.py35
-rw-r--r--xlators/experimental/fdl/src/jnl-types.h14
-rw-r--r--xlators/experimental/fdl/src/recon-tmpl.c2
7 files changed, 126 insertions, 25 deletions
diff --git a/xlators/experimental/fdl/src/Makefile.am b/xlators/experimental/fdl/src/Makefile.am
index 9ec9d4f06ff..3f1eccc0ed6 100644
--- a/xlators/experimental/fdl/src/Makefile.am
+++ b/xlators/experimental/fdl/src/Makefile.am
@@ -1,7 +1,7 @@
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/experimental
xlator_LTLIBRARIES = fdl.la
-noinst_HEADERS = jnl-types.h
+noinst_HEADERS = fdl.h
nodist_fdl_la_SOURCES = fdl.c
fdl_la_LDFLAGS = -module -avoid-version
diff --git a/xlators/experimental/fdl/src/dump-tmpl.c b/xlators/experimental/fdl/src/dump-tmpl.c
index cac1071a9c1..32b0fef6af3 100644
--- a/xlators/experimental/fdl/src/dump-tmpl.c
+++ b/xlators/experimental/fdl/src/dump-tmpl.c
@@ -2,17 +2,42 @@
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
+#include <ctype.h>
#endif
#include "glfs.h"
#include "iatt.h"
#include "xlator.h"
-#include "jnl-types.h"
+#include "fdl.h"
+
+/*
+ * Returns 0 if the string is ASCII printable *
+ * and -1 if it's not ASCII printable *
+ */
+int str_isprint (char *s)
+{
+ int ret = -1;
+
+ if (!s)
+ goto out;
+
+ while (s[0] != '\0') {
+ if (!isprint(s[0]))
+ goto out;
+ else
+ s++;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
#pragma fragment DICT
{
int key_len, data_len;
char *key_ptr;
+ char *key_val;
printf ("@ARGNAME@ = dict {\n");
for (;;) {
key_len = *((int *)new_meta);
@@ -23,8 +48,14 @@
key_ptr = new_meta;
new_meta += key_len;
data_len = *((int *)new_meta);
+ key_val = new_meta + sizeof(int);
new_meta += sizeof(int) + data_len;
- printf (" %s = <%d bytes>\n", key_ptr, data_len);
+ if (str_isprint(key_val))
+ printf (" %s = <%d bytes>\n",
+ key_ptr, data_len);
+ else
+ printf (" %s = %s <%d bytes>\n",
+ key_ptr, key_val, data_len);
}
printf ("}\n");
}
diff --git a/xlators/experimental/fdl/src/fdl-tmpl.c b/xlators/experimental/fdl/src/fdl-tmpl.c
index fdcfafbac31..a92f6676ce1 100644
--- a/xlators/experimental/fdl/src/fdl-tmpl.c
+++ b/xlators/experimental/fdl/src/fdl-tmpl.c
@@ -21,7 +21,7 @@
#include "defaults.h"
#include "syscall.h"
#include "xlator.h"
-#include "jnl-types.h"
+#include "fdl.h"
/* TBD: make tunable */
#define META_FILE_SIZE (1 << 20)
@@ -55,6 +55,9 @@ typedef struct {
int first_term;
} fdl_private_t;
+int32_t
+fdl_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata);
+
void
fdl_enqueue (xlator_t *this, call_stub_t *stub)
{
@@ -341,8 +344,21 @@ err_unlocked:
}
int32_t
+fdl_ipc_continue (call_frame_t *frame, xlator_t *this,
+ int32_t op, dict_t *xdata)
+{
+ /*
+ * Nothing to be done here. Just Unwind. *
+ */
+ STACK_UNWIND_STRICT (ipc, frame, 0, 0, xdata);
+
+ return 0;
+}
+
+int32_t
fdl_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata)
{
+ call_stub_t *stub;
fdl_private_t *priv = this->private;
dict_t *tdict;
int32_t gt_err = EIO;
@@ -381,6 +397,20 @@ fdl_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata)
}
break;
+ case FDL_IPC_JBR_SERVER_ROLLBACK:
+ /*
+ * In case of a rollback from jbr-server, dump *
+ * the term and index number in the journal, *
+ * which will later be used to rollback the fop *
+ */
+ stub = fop_ipc_stub (frame, fdl_ipc_continue,
+ op, xdata);
+ fdl_len_ipc (stub);
+ stub->serialize = fdl_serialize_ipc;
+ fdl_enqueue (this, stub);
+
+ break;
+
default:
STACK_WIND_TAIL (frame,
FIRST_CHILD(this),
@@ -423,7 +453,6 @@ fdl_init (xlator_t *this)
* bit cleaner than messing with the generation to add a hand-written
* exception.
*/
- this->fops->ipc = fdl_ipc;
if (pthread_create(&priv->worker,NULL,fdl_worker,this) != 0) {
gf_log (this->name, GF_LOG_ERROR,
diff --git a/xlators/experimental/fdl/src/fdl.h b/xlators/experimental/fdl/src/fdl.h
new file mode 100644
index 00000000000..32e38c93f2d
--- /dev/null
+++ b/xlators/experimental/fdl/src/fdl.h
@@ -0,0 +1,30 @@
+/*
+ Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _FDL_H_
+#define _FDL_H_
+
+#define NEW_REQUEST (uint8_t)'N'
+
+typedef struct {
+ uint8_t event_type; /* e.g. NEW_REQUEST */
+ uint8_t fop_type; /* e.g. GF_FOP_SETATTR */
+ uint16_t request_id;
+ uint32_t ext_length;
+} event_header_t;
+
+enum {
+ FDL_IPC_BASE = 0xfeedbee5, /* ... and they make honey */
+ FDL_IPC_CHANGE_TERM,
+ FDL_IPC_GET_TERMS,
+ FDL_IPC_JBR_SERVER_ROLLBACK
+};
+
+#endif /* _FDL_H_ */
diff --git a/xlators/experimental/fdl/src/gen_fdl.py b/xlators/experimental/fdl/src/gen_fdl.py
index 7f6b1aaaeaa..d59f12a4841 100755
--- a/xlators/experimental/fdl/src/gen_fdl.py
+++ b/xlators/experimental/fdl/src/gen_fdl.py
@@ -300,19 +300,44 @@ def get_special_subs (args):
ser_code += ser_tmpl.replace("@SRC@",src)
return len_code, ser_code
+# Mention those fops in the selective_generate table, for which
+# only a few common functions will be generated, and mention those
+# functions. Rest of the functions can be customized
+selective_generate = {
+ "ipc": "len,serialize",
+ }
+
def gen_fdl ():
entrypoints = []
for name, value in ops.iteritems():
if "journal" not in [ x[0] for x in value ]:
continue
+
+ # generate all functions for all the fops
+ # except for the ones in selective_generate for which
+ # generate only the functions mentioned in the
+ # selective_generate table
+ gen_funcs = "len,serialize,callback,continue,fop"
+ if name in selective_generate:
+ gen_funcs = selective_generate[name].split(",")
+
len_code, ser_code = get_special_subs(value)
fop_subs[name]["@LEN_CODE@"] = len_code[:-1]
fop_subs[name]["@SER_CODE@"] = ser_code[:-1]
- print generate(LEN_TEMPLATE,name,fop_subs)
- print generate(SER_TEMPLATE,name,fop_subs)
- print generate(CBK_TEMPLATE,name,cbk_subs)
- print generate(CONTINUE_TEMPLATE,name,fop_subs)
- print generate(FOP_TEMPLATE,name,fop_subs)
+ if 'len' in gen_funcs:
+ print generate(LEN_TEMPLATE,name,fop_subs)
+ if 'serialize' in gen_funcs:
+ print generate(SER_TEMPLATE,name,fop_subs)
+ if name == 'writev':
+ print "#define DESTAGE_ASYNC"
+ if 'callback' in gen_funcs:
+ print generate(CBK_TEMPLATE,name,cbk_subs)
+ if 'continue' in gen_funcs:
+ print generate(CONTINUE_TEMPLATE,name,fop_subs)
+ if 'fop' in gen_funcs:
+ print generate(FOP_TEMPLATE,name,fop_subs)
+ if name == 'writev':
+ print "#undef DESTAGE_ASYNC"
entrypoints.append(name)
print "struct xlator_fops fops = {"
for ep in entrypoints:
diff --git a/xlators/experimental/fdl/src/jnl-types.h b/xlators/experimental/fdl/src/jnl-types.h
deleted file mode 100644
index 8cb39d01a25..00000000000
--- a/xlators/experimental/fdl/src/jnl-types.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#define NEW_REQUEST (uint8_t)'N'
-
-typedef struct {
- uint8_t event_type; /* e.g. NEW_REQUEST */
- uint8_t fop_type; /* e.g. GF_FOP_SETATTR */
- uint16_t request_id;
- uint32_t ext_length;
-} event_header_t;
-
-enum {
- FDL_IPC_BASE = 0xfeedbee5, /* ... and they make honey */
- FDL_IPC_CHANGE_TERM,
- FDL_IPC_GET_TERMS,
-};
diff --git a/xlators/experimental/fdl/src/recon-tmpl.c b/xlators/experimental/fdl/src/recon-tmpl.c
index 523bda39418..ab5edb1a378 100644
--- a/xlators/experimental/fdl/src/recon-tmpl.c
+++ b/xlators/experimental/fdl/src/recon-tmpl.c
@@ -11,7 +11,7 @@
#include "xlator.h"
#include "glfs-internal.h"
-#include "jnl-types.h"
+#include "fdl.h"
#define GFAPI_SUCCESS 0