summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/transport.c')
0 files changed, 0 insertions, 0 deletions
2:02 -0700 commit7e8eefca2caaaa61e1b31b747384f660c595d9c9 (patch) treea6e862f2caad4097a41dd8b260a2333e90db3b4a /heal/src parent7808d4b7892ccd80bcabb1253ee359a64c51c612 (diff)
heal: glfs-heal implementation
Thanks a lot to Niels for helping me to get build stuff right. Change-Id: I634f24d90cd856ceab3cc0c6e9a91003f443403e BUG: 1147462 Signed-off-by: Pranith Kumar K <pkarampu@redhat.com> Reviewed-on: http://review.gluster.org/6529 Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'heal/src')
-rw-r--r--heal/src/Makefile.am35
-rw-r--r--heal/src/glfs-heal.c610
2 files changed, 645 insertions, 0 deletions
diff --git a/heal/src/Makefile.am b/heal/src/Makefile.am
new file mode 100644
index 00000000000..65093df35cc
--- /dev/null
+++ b/heal/src/Makefile.am
@@ -0,0 +1,35 @@
+sbin_PROGRAMS = glfsheal
+
+glfsheal_SOURCES = glfs-heal.c
+
+glfsheal_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(GF_LDADD)\
+ $(RLLIBS) $(top_builddir)/rpc/xdr/src/libgfxdr.la \
+ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
+ $(top_builddir)/api/src/libgfapi.la \
+ $(top_builddir)/xlators/cluster/afr/src/afr.la \
+ $(GF_GLUSTERFS_LIBS) $(XML_LIBS)
+
+glfsheal_LDFLAGS = $(GF_LDFLAGS)
+
+AM_CPPFLAGS = $(GF_CPPFLAGS) \
+ -I$(top_srcdir)/xlators/lib/src\
+ -I$(top_srcdir)/xlators/cluster/afr/src\
+ -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/rpc-lib/src\
+ -I$(top_srcdir)/rpc/xdr/src\
+ -I$(top_srcdir)/api/src\
+ -I$(top_srcdir)/contrib/argp-standalone\
+ -DDATADIR=\"$(localstatedir)\" \
+ -DCONFDIR=\"$(sysconfdir)/glusterfs\" \
+ -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\
+ -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) -DSBIN_DIR=\"$(sbindir)\"\
+ $(XML_CPPFLAGS)
+
+AM_CFLAGS = -Wall $(GF_GLUSTERFS_CFLAGS)
+
+CLEANFILES =
+
+$(top_builddir)/libglusterfs/src/libglusterfs.la:
+ $(MAKE) -C $(top_builddir)/libglusterfs/src/ all
+
+$(top_builddir)/xlators/cluster/afr/src/afr.la:
+ $(MAKE) -C $(top_builddir)/xlators/cluster/afr/src/ all
diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c
new file mode 100644
index 00000000000..d02858642ab
--- /dev/null
+++ b/heal/src/glfs-heal.c
@@ -0,0 +1,610 @@
+/*
+ Copyright (c) 2014 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "glfs.h"
+#include "glfs-handles.h"
+#include "glfs-internal.h"
+#include "syncop.h"
+#include <string.h>
+#include <time.h>
+#include "afr.h"
+#include "afr-self-heal.h"
+#include "afr-self-heald.h"
+
+#define DEFAULT_HEAL_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
+
+int
+glfsh_link_inode_update_loc (loc_t *loc, struct iatt *iattr)
+{
+ inode_t *link_inode = NULL;
+ int ret = -1;
+
+ link_inode = inode_link (loc->inode, NULL, NULL, iattr);
+ if (link_inode == NULL)
+ goto out;
+
+ inode_unref (loc->inode);
+ loc->inode = link_inode;
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+glfsh_get_index_dir_loc (loc_t *rootloc, xlator_t *xl, loc_t *dirloc,
+ int32_t *op_errno)
+{
+ void *index_gfid = NULL;
+ int ret = 0;
+ dict_t *xattr = NULL;
+ struct iatt iattr = {0};
+ struct iatt parent = {0};
+
+ ret = syncop_getxattr (xl, rootloc, &xattr, GF_XATTROP_INDEX_GFID);
+ if (ret < 0) {
+ *op_errno = -ret;
+ goto out;
+ }
+
+ ret = dict_get_ptr (xattr, GF_XATTROP_INDEX_GFID, &index_gfid);
+ if (ret < 0) {
+ *op_errno = EINVAL;
+ goto out;
+ }
+
+ uuid_copy (dirloc->gfid, index_gfid);
+ dirloc->path = "";
+ dirloc->inode = inode_new (rootloc->inode->table);
+ ret = syncop_lookup (xl, dirloc, NULL,
+ &iattr, NULL, &parent);
+ dirloc->path = NULL;
+ if (ret < 0) {
+ *op_errno = -ret;
+ goto out;
+ }
+ ret = glfsh_link_inode_update_loc (dirloc, &iattr);
+ if (ret)
+ goto out;
+ glfs_loc_touchup (dirloc);
+
+ ret = 0;
+out:
+ if (xattr)
+ dict_unref (xattr);
+ return ret;
+}
+
+int
+afr_selfheal_locked_metadata_inspect (call_frame_t *frame, xlator_t *this,
+ inode_t *inode,
+ gf_boolean_t *metadata_selfheal)
+{
+ int ret = -1;
+ unsigned char *locked_on = NULL;
+ afr_private_t *priv = this->private;
+
+ locked_on = alloca0 (priv->child_count);
+
+ ret = afr_selfheal_inodelk (frame, this, inode, this->name,
+ LLONG_MAX - 1, 0, locked_on);
+ {
+ if (ret == 0) {
+ /* Not a single lock */
+ ret = -afr_final_errno (frame->local, priv);
+ if (ret == 0)
+ ret = -ENOTCONN;/* all invalid responses */
+ goto out;
+ }
+ ret = afr_selfheal_unlocked_inspect (frame, this, inode->gfid,
+ NULL, NULL,
+ metadata_selfheal, NULL);
+ }
+ afr_selfheal_uninodelk (frame, this, inode, this->name,
+ LLONG_MAX - 1, 0, locked_on);
+out:
+ return ret;
+}
+
+int
+afr_selfheal_locked_data_inspect (call_frame_t *frame, xlator_t *this,
+ inode_t *inode, gf_boolean_t *data_selfheal)
+{
+ int ret = -1;
+ afr_private_t *priv = NULL;
+ unsigned char *locked_on = NULL;
+ unsigned char *data_lock = NULL;
+
+ priv = this->private;
+ locked_on = alloca0 (priv->child_count);
+ data_lock = alloca0 (priv->child_count);
+
+ ret = afr_selfheal_tryinodelk (frame, this, inode, priv->sh_domain,
+ 0, 0, locked_on);
+ {
+ if (ret == 0) {
+ ret = -afr_final_errno (frame->local, priv);
+ if (ret == 0)
+ ret = -ENOTCONN;/* all invalid responses */
+ goto out;
+ }
+ ret = afr_selfheal_inodelk (frame, this, inode, this->name,
+ 0, 0, data_lock);
+ {
+ if (ret == 0) {
+ ret = -afr_final_errno (frame->local, priv);
+ if (ret == 0)
+ ret = -ENOTCONN;
+ /* all invalid responses */
+ goto unlock;
+ }
+ ret = afr_selfheal_unlocked_inspect (frame, this,
+ inode->gfid, NULL,
+ data_selfheal,
+ NULL, NULL);
+ }
+ afr_selfheal_uninodelk (frame, this, inode, this->name, 0, 0,
+ data_lock);
+ }
+unlock:
+ afr_selfheal_uninodelk (frame, this, inode, priv->sh_domain, 0, 0,
+ locked_on);
+out:
+ return ret;
+}
+
+int
+afr_selfheal_locked_entry_inspect (call_frame_t *frame, xlator_t *this,
+ inode_t *inode, gf_boolean_t *entry_selfheal)
+{
+ int ret = -1;
+ afr_private_t *priv = NULL;
+ unsigned char *locked_on = NULL;
+ unsigned char *data_lock = NULL;
+
+ priv = this->private;
+ locked_on = alloca0 (priv->child_count);
+ data_lock = alloca0 (priv->child_count);
+
+ ret = afr_selfheal_tryentrylk (frame, this, inode, priv->sh_domain,
+ NULL, locked_on);
+ {
+ if (ret == 0) {
+ ret = -afr_final_errno (frame->local, priv);
+ if (ret == 0)
+ ret = -ENOTCONN;/* all invalid responses */
+ goto out;
+ }
+
+ ret = afr_selfheal_entrylk (frame, this, inode, this->name,
+ NULL, data_lock);
+ {
+ if (ret == 0) {
+ ret = -afr_final_errno (frame->local, priv);
+ if (ret == 0)
+ ret = -ENOTCONN;
+ /* all invalid responses */
+ goto unlock;
+ }
+ ret = afr_selfheal_unlocked_inspect (frame, this,
+ inode->gfid,
+ NULL, NULL, NULL,
+ entry_selfheal);
+ }
+ afr_selfheal_unentrylk (frame, this, inode, this->name, NULL,
+ data_lock);
+ }
+unlock:
+ afr_selfheal_unentrylk (frame, this, inode, priv->sh_domain, NULL,
+ locked_on);
+out:
+ return ret;
+}
+
+int
+afr_selfheal_locked_inspect (call_frame_t *frame, xlator_t *this, uuid_t gfid,
+ inode_t **inode,
+ gf_boolean_t *data_selfheal,
+ gf_boolean_t *metadata_selfheal,
+ gf_boolean_t *entry_selfheal)
+{
+ int ret = -1;
+ gf_boolean_t dsh = _gf_false;
+ gf_boolean_t msh = _gf_false;
+ gf_boolean_t esh = _gf_false;
+
+ ret = afr_selfheal_unlocked_inspect (frame, this, gfid, inode,
+ &dsh, &msh, &esh);
+ if (ret)
+ goto out;
+
+ /* For every heal type hold locks and check if it indeed needs heal */
+
+ if (msh) {
+ msh = _gf_false;
+ ret = afr_selfheal_locked_metadata_inspect (frame, this,
+ *inode, &msh);
+ if (msh || ret < 0)
+ goto out;
+ }
+
+ if (dsh) {
+ dsh = _gf_false;
+ ret = afr_selfheal_locked_data_inspect (frame, this, *inode,
+ &dsh);
+ if (dsh || ret < 0)
+ goto out;
+ }
+
+ if (esh) {
+ esh = _gf_false;
+ ret = afr_selfheal_locked_entry_inspect (frame, this, *inode,
+ &esh);
+ }
+
+out:
+ if (entry_selfheal)
+ *entry_selfheal = esh;
+ if (data_selfheal)
+ *data_selfheal = dsh;
+ if (metadata_selfheal)
+ *metadata_selfheal = msh;
+ return ret;
+}
+
+static xlator_t*
+_get_afr_ancestor (xlator_t *xl)
+{
+ if (!xl || !xl->parents)
+ return NULL;
+
+ while (xl->parents) {
+ xl = xl->parents->xlator;
+ if (!xl)
+ break;
+ if (strcmp (xl->type, "cluster/replicate") == 0)
+ return xl;
+ }
+
+ return NULL;
+}
+
+static int
+glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,
+ off_t *offset, uint64_t *num_entries)
+{
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
+ int ret = 0;
+ char *path = NULL;
+ uuid_t gfid = {0};
+ inode_t *inode = NULL;
+ call_frame_t *frame = NULL;
+ xlator_t *this = NULL;
+ gf_boolean_t data_selfheal = _gf_false;
+ gf_boolean_t metadata_selfheal = _gf_false;
+ gf_boolean_t entry_selfheal = _gf_false;
+
+ this = THIS;
+ frame = afr_frame_create (this);
+ if (!frame) {
+ ret = -1;
+ goto out;