summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/dht
diff options
context:
space:
mode:
authorAmar Tumballi <amar@gluster.com>2010-07-14 13:58:20 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-07-14 14:44:26 -0700
commit654a720eed0bc5faaeeaa4eb34f1cfc10df76230 (patch)
treeb84419d192c46e39a40b7a3133666ddde453aba2 /xlators/cluster/dht
parente73a856e926465068f6f6cf5a0cace501589957c (diff)
proper way to do defrag of a mountpoint
Usage: "glusterfs-defrag <MOUNTPOINT>" there are new features added to distribute with this patch: * bash# getfattr -n trusted.distribute.linkinfo <file> Gives output in the format "<hostname>:<directory>", if there is a linkfile present, where hostname is server, directory is backend directory where the actual linkfile is present. * bash# getfattr -n trusted.glusterfs.pathinfo <path> Gives layout information if directory, and info about actual location of file in backend servers, in the form of 'hostname:directory'. (TODO: should extend it to all xlators) * bash# getfattr -n trusted.distribute.fix.layout <path> scales out the directory layout in distribute, so when new servers are added, layouts are fixed to include them. * removed 'scale-n-defrag.sh' as its no more required. * changed 'defrag.sh' to have a feature to specify target bricks, so defrag happens to only those nodes. moved the file to 'glusterfs-defrag', which now gets installed to '${prefix}/bin' * storage/posix: takes new option 'hostname' so it can resolve to same hostname given during 'gluster volume create'. with 'trusted.glusterfs.pathinfo' posix returns the value in 'hostname:real_path' format. Signed-off-by: Amar Tumballi <amar@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 1073 ('gluster defrag <VOLNAME>' fails in mainline) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1073
Diffstat (limited to 'xlators/cluster/dht')
-rw-r--r--xlators/cluster/dht/src/dht-common.c217
-rw-r--r--xlators/cluster/dht/src/dht-common.h5
2 files changed, 219 insertions, 3 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 1cfeae690f9..dd2a3f3f1e1 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -1410,6 +1410,127 @@ err:
int
+dht_fix_layout_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+{
+ DHT_STACK_UNWIND (getxattr, frame, -1, ENODATA, NULL);
+
+ return 0;
+}
+
+static void
+fill_layout_info (dht_layout_t *layout, char *buf)
+{
+ int i = 0;
+ char tmp_buf[128] = {0,};
+
+ for (i = 0; i < layout->cnt; i++) {
+ snprintf (tmp_buf, 128, "(%s %u %u)",
+ layout->list[i].xlator->name,
+ layout->list[i].start,
+ layout->list[i].stop);
+ if (i)
+ strcat (buf, " ");
+ strcat (buf, tmp_buf);
+ }
+}
+
+int
+dht_pathinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xattr)
+{
+ dht_local_t *local = NULL;
+ int ret = 0;
+ int flag = 0;
+ int this_call_cnt = 0;
+ char *value_got = NULL;
+ char layout_buf[8192] = {0,};
+ char xattr_buf[8192 + 1024] = {0,};
+ dict_t *dict = NULL;
+
+ local = frame->local;
+
+ if (op_ret != -1) {
+ ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &value_got);
+ if (!ret) {
+ if (!local->pathinfo)
+ local->pathinfo = GF_CALLOC (8192, sizeof (char),
+ gf_common_mt_char);
+ if (local->pathinfo)
+ strcat (local->pathinfo, value_got);
+ }
+ }
+
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt)) {
+ if (local->layout->cnt > 1) {
+ /* Set it for directory */
+ fill_layout_info (local->layout, layout_buf);
+ flag = 1;
+ }
+
+ dict = dict_new ();
+
+ if (flag && local->pathinfo)
+ snprintf (xattr_buf, 9216, "((%s %s) (%s-layout %s))",
+ this->name, local->pathinfo, this->name,
+ layout_buf);
+ else if (local->pathinfo)
+ snprintf (xattr_buf, 9216, "(%s %s)",
+ this->name, local->pathinfo);
+ else if (flag)
+ snprintf (xattr_buf, 9216, "(%s-layout %s)",
+ this->name, layout_buf);
+
+ ret = dict_set_str (dict, GF_XATTR_PATHINFO_KEY,
+ xattr_buf);
+
+ if (local->pathinfo)
+ GF_FREE (local->pathinfo);
+ GF_FREE (local->key);
+
+ DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
+
+ if (dict)
+ dict_unref (dict);
+
+ return 0;
+ }
+
+ if (local->pathinfo)
+ strcat (local->pathinfo, " Link: ");
+
+ /* This will happen if there pending */
+ STACK_WIND (frame, dht_pathinfo_getxattr_cbk, local->hashed_subvol,
+ local->hashed_subvol->fops->getxattr,
+ &local->loc, local->key);
+
+ return 0;
+}
+
+int
+dht_linkinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xattr)
+{
+ int ret = 0;
+ char *value = NULL;
+
+ if (op_ret != -1) {
+ ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &value);
+ if (!ret) {
+ ret = dict_set_str (xattr, GF_XATTR_LINKINFO_KEY, value);
+ if (!ret)
+ gf_log (this->name, GF_LOG_TRACE,
+ "failed to set linkinfo");
+ }
+ }
+
+ DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr);
+
+ return 0;
+}
+
+int
dht_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, dict_t *xattr)
{
@@ -1429,9 +1550,14 @@ int
dht_getxattr (call_frame_t *frame, xlator_t *this,
loc_t *loc, const char *key)
{
- xlator_t *subvol = NULL;
- int op_errno = -1;
-
+ xlator_t *subvol = NULL;
+ xlator_t *hashed_subvol = NULL;
+ xlator_t *cached_subvol = NULL;
+ dht_conf_t *conf = NULL;
+ dht_local_t *local = NULL;
+ dht_layout_t *layout = NULL;
+ int op_errno = -1;
+ int ret = 0;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -1439,6 +1565,91 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc->inode, err);
VALIDATE_OR_GOTO (loc->path, err);
+ conf = this->private;
+ layout = dht_layout_get (this, loc->inode);
+ if (key && (strcmp (key, GF_XATTR_PATHINFO_KEY) == 0)) {
+ hashed_subvol = dht_subvol_get_hashed (this, loc);
+ cached_subvol = dht_subvol_get_cached (this, loc->inode);
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+ local->key = gf_strdup (key);
+ if (!local->key) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+ local->layout = layout;
+
+ local->call_cnt = 1;
+ if (hashed_subvol != cached_subvol) {
+ local->call_cnt = 2;
+ local->hashed_subvol = hashed_subvol;
+ }
+
+ STACK_WIND (frame, dht_pathinfo_getxattr_cbk, cached_subvol,
+ cached_subvol->fops->getxattr, loc, key);
+
+ return 0;
+ }
+ if (key && (strcmp (key, GF_XATTR_LINKINFO_KEY) == 0)) {
+ hashed_subvol = dht_subvol_get_hashed (this, loc);
+ cached_subvol = dht_subvol_get_cached (this, loc->inode);
+ if (hashed_subvol == cached_subvol) {
+ op_errno = ENODATA;
+ goto err;
+ }
+ if (hashed_subvol) {
+ STACK_WIND (frame, dht_linkinfo_getxattr_cbk, hashed_subvol,
+ hashed_subvol->fops->getxattr, loc,
+ GF_XATTR_PATHINFO_KEY);
+ return 0;
+ }
+ op_errno = ENODATA;
+ goto err;
+ }
+ if (key && (strcmp (key, GF_XATTR_FIX_LAYOUT_KEY) == 0)) {
+ if (layout->cnt < conf->subvolume_cnt) {
+ gf_log (this->name, GF_LOG_INFO,
+ "expanding layout of %s from %d to %d",
+ loc->path, layout->cnt, conf->subvolume_cnt);
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+ local->layout = layout;
+ dht_selfheal_new_directory (frame, dht_fix_layout_cbk,
+ layout);
+ return 0;
+ }
+ op_errno = ENODATA;
+ goto err;
+ }
subvol = dht_subvol_get_cached (this, loc->inode);
if (!subvol) {
gf_log (this->name, GF_LOG_DEBUG,
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index b361f14426e..d5a5c7b2c59 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -27,6 +27,7 @@
#ifndef _DHT_H
#define _DHT_H
+#define GF_XATTR_FIX_LAYOUT_KEY "trusted.distribute.fix.layout"
#define GF_DHT_LOOKUP_UNHASHED_ON 1
#define GF_DHT_LOOKUP_UNHASHED_AUTO 2
@@ -116,6 +117,10 @@ struct dht_local {
int32_t flags;
mode_t mode;
dev_t rdev;
+
+ /* need for file-info */
+ char *pathinfo;
+ char *key;
};
typedef struct dht_local dht_local_t;