summaryrefslogtreecommitdiffstats
path: root/xlators/experimental/fdl/src/dump-tmpl.c
diff options
context:
space:
mode:
authorJeff Darcy <jdarcy@redhat.com>2016-02-08 13:30:49 -0500
committerJeff Darcy <jdarcy@redhat.com>2016-02-13 05:13:07 -0800
commitc458433041aafb48ae6d6e5fcf3e1e737dc3fda3 (patch)
tree33a03ca0c1f5faf58419de2c4ff4532752ddfb07 /xlators/experimental/fdl/src/dump-tmpl.c
parentda33097c3d6492e3b468b4347e47c70828fb4320 (diff)
experimental: add fdl (Full Data Logging) translator
NSR needs logging that is different than our existing changelog in several ways: * Full data, not just metadata * Pre-op, not post-op * High performance * Supports the concept of time-bounded "terms" Others (for example EC) might need the same thing. This patch adds such a translator. It also adds code to dump the resulting journals, and to replay them using syncops, plus (very rudimentary) tests for all of the above. Change-Id: I29680a1b4e0a9e7d5a8497fef302c46434b86636 Signed-off-by: Jeff Darcy <jdarcy@redhat.com> Reviewed-on: http://review.gluster.org/12450 Smoke: Gluster Build System <jenkins@build.gluster.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Diffstat (limited to 'xlators/experimental/fdl/src/dump-tmpl.c')
-rw-r--r--xlators/experimental/fdl/src/dump-tmpl.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/xlators/experimental/fdl/src/dump-tmpl.c b/xlators/experimental/fdl/src/dump-tmpl.c
new file mode 100644
index 00000000000..cac1071a9c1
--- /dev/null
+++ b/xlators/experimental/fdl/src/dump-tmpl.c
@@ -0,0 +1,156 @@
+#pragma fragment PROLOG
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glfs.h"
+#include "iatt.h"
+#include "xlator.h"
+#include "jnl-types.h"
+
+#pragma fragment DICT
+ {
+ int key_len, data_len;
+ char *key_ptr;
+ printf ("@ARGNAME@ = dict {\n");
+ for (;;) {
+ key_len = *((int *)new_meta);
+ new_meta += sizeof(int);
+ if (!key_len) {
+ break;
+ }
+ key_ptr = new_meta;
+ new_meta += key_len;
+ data_len = *((int *)new_meta);
+ new_meta += sizeof(int) + data_len;
+ printf (" %s = <%d bytes>\n", key_ptr, data_len);
+ }
+ printf ("}\n");
+ }
+
+#pragma fragment DOUBLE
+ printf ("@ARGNAME@ = @FORMAT@\n", *((uint64_t *)new_meta),
+ *((uint64_t *)new_meta));
+ new_meta += sizeof(uint64_t);
+
+#pragma fragment GFID
+ printf ("@ARGNAME@ = <gfid %s>\n", uuid_utoa(*((uuid_t *)new_meta)));
+ new_meta += 16;
+
+#pragma fragment INTEGER
+ printf ("@ARGNAME@ = @FORMAT@\n", *((uint32_t *)new_meta),
+ *((uint32_t *)new_meta));
+ new_meta += sizeof(uint32_t);
+
+#pragma fragment LOC
+ printf ("@ARGNAME@ = loc {\n");
+ printf (" gfid = %s\n", uuid_utoa(*((uuid_t *)new_meta)));
+ new_meta += 16;
+ printf (" pargfid = %s\n", uuid_utoa(*((uuid_t *)new_meta)));
+ new_meta += 16;
+ if (*(new_meta++)) {
+ printf (" name = %s\n", new_meta);
+ new_meta += (strlen(new_meta) + 1);
+ }
+ printf ("}\n");
+
+#pragma fragment STRING
+ if (*(new_meta++)) {
+ printf ("@ARGNAME@ = %s\n", new_meta);
+ new_meta += (strlen(new_meta) + 1);
+ }
+
+#pragma fragment VECTOR
+ {
+ size_t len = *((size_t *)new_meta);
+ new_meta += sizeof(len);
+ printf ("@ARGNAME@ = <%zu bytes>\n", len);
+ new_data += len;
+ }
+
+#pragma fragment IATT
+ {
+ ia_prot_t *myprot = ((ia_prot_t *)new_meta);
+ printf ("@ARGNAME@ = iatt {\n");
+ printf (" ia_prot = %c%c%c",
+ myprot->suid ? 'S' : '-',
+ myprot->sgid ? 'S' : '-',
+ myprot->sticky ? 'T' : '-');
+ printf ("%c%c%c",
+ myprot->owner.read ? 'r' : '-',
+ myprot->owner.write ? 'w' : '-',
+ myprot->owner.exec ? 'x' : '-');
+ printf ("%c%c%c",
+ myprot->group.read ? 'r' : '-',
+ myprot->group.write ? 'w' : '-',
+ myprot->group.exec ? 'x' : '-');
+ printf ("%c%c%c\n",
+ myprot->other.read ? 'r' : '-',
+ myprot->other.write ? 'w' : '-',
+ myprot->other.exec ? 'x' : '-');
+ new_meta += sizeof(ia_prot_t);
+ uint32_t *myints = (uint32_t *)new_meta;
+ printf (" ia_uid = %u\n", myints[0]);
+ printf (" ia_gid = %u\n", myints[1]);
+ printf (" ia_atime = %u.%09u\n", myints[2], myints[3]);
+ printf (" ia_mtime = %u.%09u\n", myints[4], myints[5]);
+ new_meta += sizeof(*myints) * 6;
+ }
+
+#pragma fragment FOP
+void
+fdl_dump_@NAME@ (char **old_meta, char **old_data)
+{
+ char *new_meta = *old_meta;
+ char *new_data = *old_data;
+
+ /* TBD: word size/endianness */
+@FUNCTION_BODY@
+
+ *old_meta = new_meta;
+ *old_data = new_data;
+}
+
+#pragma fragment CASE
+ case GF_FOP_@UPNAME@:
+ printf ("=== GF_FOP_@UPNAME@\n");
+ fdl_dump_@NAME@ (&new_meta, &new_data);
+ break;
+
+#pragma fragment EPILOG
+int
+fdl_dump (char **old_meta, char **old_data)
+{
+ char *new_meta = *old_meta;
+ char *new_data = *old_data;
+ static glfs_t *fs = NULL;
+ int recognized = 1;
+ event_header_t *eh;
+
+ /*
+ * We don't really call anything else in GFAPI, but this is the most
+ * convenient way to satisfy all of the spurious dependencies on how it
+ * or glusterfsd initialize (e.g. setting up THIS).
+ */
+ if (!fs) {
+ fs = glfs_new ("dummy");
+ }
+
+ eh = (event_header_t *)new_meta;
+ new_meta += sizeof (*eh);
+
+ /* TBD: check event_type instead of assuming NEW_REQUEST */
+
+ switch (eh->fop_type) {
+@SWITCH_BODY@
+
+ default:
+ printf ("unknown fop %u\n", eh->fop_type);
+ recognized = 0;
+ }
+
+ *old_meta = new_meta;
+ *old_data = new_data;
+ return recognized;
+}