diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/Makefile.am | 2 | ||||
| -rw-r--r-- | tools/setgfid2path/Makefile.am | 5 | ||||
| -rw-r--r-- | tools/setgfid2path/gluster-setgfid2path.8 | 54 | ||||
| -rw-r--r-- | tools/setgfid2path/src/Makefile.am | 14 | ||||
| -rw-r--r-- | tools/setgfid2path/src/main.c | 128 | 
5 files changed, 202 insertions, 1 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am index d689f60fa52..5808a3728cd 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = gfind_missing_files glusterfind +SUBDIRS = gfind_missing_files glusterfind setgfid2path  CLEANFILES = diff --git a/tools/setgfid2path/Makefile.am b/tools/setgfid2path/Makefile.am new file mode 100644 index 00000000000..c14787a80ce --- /dev/null +++ b/tools/setgfid2path/Makefile.am @@ -0,0 +1,5 @@ +SUBDIRS = src + +EXTRA_DIST = gluster-setgfid2path.8 + +man8_MANS = gluster-setgfid2path.8 diff --git a/tools/setgfid2path/gluster-setgfid2path.8 b/tools/setgfid2path/gluster-setgfid2path.8 new file mode 100644 index 00000000000..2e228ca8514 --- /dev/null +++ b/tools/setgfid2path/gluster-setgfid2path.8 @@ -0,0 +1,54 @@ + +.\"  Copyright (c) 2017 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. +.\" +.\" +.TH gluster-setgfid2path 8 "Command line utility to set GFID to Path Xattrs" +.SH NAME +gluster-setgfid2path - Gluster tool to set GFID to Path xattrs +.SH SYNOPSIS +.B gluster-setgfid2path +.IR file +.SH DESCRIPTION +New feature introduced with Gluster release 3.12, to find full path from GFID. +This feature can be enabled using Volume set command \fBgluster volume set +<VOLUME> storage.gfid2path enable\fR +.PP +Once \fBgfid2path\fR feature is enabled, it starts recording the necessary +xattrs required for the feature. But it will not add xattrs for the already +existing files. This tool provides facility to update the gfid2path xattrs for +the given file path. + +.SH EXAMPLES +To add xattrs of a single file, +.PP +.nf +.RS +gluster-setgfid2path /bricks/b1/hello.txt +.RE +.fi +.PP +To set xattr for all the existing files, run the below script on each bricks. +.PP +.nf +.RS +BRICK=/bricks/b1 +find $BRICK -type d \\( -path "${BRICK}/.trashcan" -o -path \\ +    "${BRICK}/.glusterfs" \\) -prune -o -type f \\ +    -exec gluster-setgfid2path {} \\; +.RE +.fi +.PP +.SH SEE ALSO +.nf +\fBgluster\fR(8) +\fR +.fi +.SH COPYRIGHT +.nf +Copyright(c) 2017   Red Hat, Inc.   <http://www.redhat.com> diff --git a/tools/setgfid2path/src/Makefile.am b/tools/setgfid2path/src/Makefile.am new file mode 100644 index 00000000000..45520cadafb --- /dev/null +++ b/tools/setgfid2path/src/Makefile.am @@ -0,0 +1,14 @@ +gluster_setgfid2pathdir = $(sbindir) + +gluster_setgfid2path_PROGRAMS = gluster-setgfid2path + +gluster_setgfid2path_SOURCES = main.c + +gluster_setgfid2path_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la + +gluster_setgfid2path_LDFLAGS = $(GF_LDFLAGS) + +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ +	-I$(top_builddir)/rpc/xdr/src + +AM_CFLAGS = -Wall $(GF_CFLAGS) diff --git a/tools/setgfid2path/src/main.c b/tools/setgfid2path/src/main.c new file mode 100644 index 00000000000..07d7a48b15d --- /dev/null +++ b/tools/setgfid2path/src/main.c @@ -0,0 +1,128 @@ +/* +   Copyright (c) 2017 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 <libgen.h> + +#include "common-utils.h" +#include "syscall.h" + +#define MAX_GFID2PATH_LINK_SUP 500 +#define GFID_SIZE 16 +#define GFID_XATTR_KEY "trusted.gfid" + + +int main(int argc, char **argv) +{ +        int             ret                               = 0; +        struct stat     st; +        char           *dname                             = NULL; +        char           *bname                             = NULL; +        ssize_t         ret_size                          = 0; +        uuid_t          pgfid_raw                         = {0,}; +        char            pgfid[36]                         = ""; +        char            xxh64[GF_XXH64_DIGEST_LENGTH*2+1] = {0,}; +        char            pgfid_bname[1024]                 = {0,}; +        char           *key                               = NULL; +        char           *val                               = NULL; +        size_t          key_size                          = 0; +        size_t          val_size                          = 0; +        const char     *file_path                         = NULL; +        char           *file_path1                        = NULL; +        char           *file_path2                        = NULL; + +        if (argc != 2) { +                fprintf (stderr, "Usage: setgfid2path <file-path>\n"); +                return -1; +        } + +        ret = sys_lstat (argv[1], &st); +        if (ret != 0) { +                fprintf (stderr, "Invalid File Path\n"); +                return -1; +        } + +        if (st.st_nlink >= MAX_GFID2PATH_LINK_SUP) { +                fprintf (stderr, +                         "Number of Hardlink support exceeded. " +                         "max=%d\n", MAX_GFID2PATH_LINK_SUP); +                return -1; +        } + +        file_path = argv[1]; +        file_path1 = strdup (file_path); +        file_path2 = strdup (file_path); + +        dname = dirname (file_path1); +        bname = basename (file_path2); + +        /* Get GFID of Parent directory */ +        ret_size = sys_lgetxattr (dname, GFID_XATTR_KEY, pgfid_raw, GFID_SIZE); +        if (ret_size != GFID_SIZE) { +                fprintf (stderr, +                         "Failed to get GFID of parent directory. dir=%s\n", +                         dname); +                ret = -1; +                goto out; +        } + +        /* Convert to UUID format */ +        if (uuid_utoa_r (pgfid_raw, pgfid) == NULL) { +                fprintf (stderr, +                         "Failed to format GFID of parent directory. " +                         "dir=%s GFID=%s\n", dname, pgfid_raw); +                ret = -1; +                goto out; +        } + +        /* Find xxhash for PGFID/BaseName */ +        snprintf (pgfid_bname, sizeof (pgfid_bname), "%s/%s", pgfid, bname); +        gf_xxh64_wrapper ( +                        (unsigned char *)pgfid_bname, +                        strlen (pgfid_bname), +                        GF_XXHSUM64_DEFAULT_SEED, +                        xxh64 +                        ); + +        key_size = strlen(GFID2PATH_XATTR_KEY_PREFIX) + +                GF_XXH64_DIGEST_LENGTH*2+1; +        key = alloca (key_size); +        snprintf (key, key_size, GFID2PATH_XATTR_KEY_PREFIX"%s", xxh64); + +        val_size = UUID_CANONICAL_FORM_LEN + NAME_MAX + 2; +        val = alloca (val_size); +        snprintf (val, val_size, "%s/%s", pgfid, bname); + +        /* Set the Xattr, ignore if same key xattr already exists */ +        ret = sys_lsetxattr (file_path, key, val, strlen(val), XATTR_CREATE); +        if (ret == -1) { +                if (errno == EEXIST) { +                        printf ("Xattr already exists, ignoring..\n"); +                        ret = 0; +                        goto out; +                } + +                fprintf (stderr, +                         "Failed to set gfid2path xattr. errno=%d\n error=%s", +                         errno, strerror(errno)); +                ret = -1; +                goto out; +        } + +        printf ("Success. file=%s key=%s value=%s\n", file_path, key, val); + +out: +        if (file_path1 != NULL) +                free (file_path1); + +        if (file_path2 != NULL) +                free (file_path2); + +        return ret; +}  | 
