diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | glusterfs.spec.in | 7 | ||||
-rw-r--r-- | tests/gfid2path/gfid2path_fuse.t | 23 | ||||
-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 |
9 files changed, 232 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore index cc4399dfef3..ccda5aa8783 100644 --- a/.gitignore +++ b/.gitignore @@ -121,3 +121,4 @@ libglusterfs/src/eventtypes.h extras/init.d/glustereventsd-Debian extras/init.d/glustereventsd-FreeBSD extras/init.d/glustereventsd-Redhat +tools/setgfid2path/src/gluster-setgfid2path diff --git a/configure.ac b/configure.ac index b1593b30a02..413d071c1db 100644 --- a/configure.ac +++ b/configure.ac @@ -282,6 +282,8 @@ AC_CONFIG_FILES([Makefile tools/glusterfind/glusterfind tools/glusterfind/Makefile tools/glusterfind/src/Makefile + tools/setgfid2path/Makefile + tools/setgfid2path/src/Makefile tests/basic/fuse/Makefile tests/basic/gfapi/Makefile]) diff --git a/glusterfs.spec.in b/glusterfs.spec.in index d9730f0821d..f26611bf845 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in @@ -1223,10 +1223,14 @@ exit 0 %{_sbindir}/glusterd %{_sbindir}/glfsheal %{_sbindir}/gf_attach +%{_sbindir}/gluster-setgfid2path # {_sbindir}/glusterfsd is the actual binary, but glusterfs (client) is a # symlink. The binary itself (and symlink) are part of the glusterfs-fuse # package, because glusterfs-server depends on that anyway. +# Manpages +%{_mandir}/man8/gluster-setgfid2path.8* + # xlators %{_libdir}/libposix2common.so %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator @@ -1369,6 +1373,9 @@ exit 0 %endif %changelog +* Thu Jul 20 2017 Aravinda VK <avishwan@redhat.com> +- Added new tool/binary to set the gfid2path xattr on files + * Thu Jul 13 2017 Kaleb S. KEITHLEY <kkeithle@redhat.com> - various directories not owned by any package diff --git a/tests/gfid2path/gfid2path_fuse.t b/tests/gfid2path/gfid2path_fuse.t index 38798cf60d0..a66ab183683 100644 --- a/tests/gfid2path/gfid2path_fuse.t +++ b/tests/gfid2path/gfid2path_fuse.t @@ -3,6 +3,8 @@ . $(dirname $0)/../include.rc . $(dirname $0)/../volume.rc +CLI_SETGFID2PATH="gluster-setgfid2path"; + cleanup; XXHSUM_SOURCE="$(dirname $0)/../../contrib/xxhash/xxhsum.c $(dirname $0)/../../contrib/xxhash/xxhash.c" @@ -25,15 +27,30 @@ EXPECT '1' brick_count $V0 TEST $CLI volume start $V0; EXPECT 'Started' volinfo_field $V0 'Status'; -## enable gfid2path -TEST $CLI volume set $V0 gfid2path enable - ## Mount the volume TEST $GFS --volfile-server=$H0 --volfile-id=$V0 $M0; pgfid="00000000-0000-0000-0000-000000000001" xxh64_file=$B0/${V0}1/xxh64_file +# Create a file before enabling gfid2path +fname=$M0/before_file1 +touch $fname; +backpath=$B0/${V0}1/before_file1 + +# Set gfid2path xattr +TEST $CLI_SETGFID2PATH $backpath + +#Check for the presence of xattr +pgfid_bname=$pgfid/before_file1 +echo -n $pgfid_bname > $xxh64_file +xxh64sum=$($XXHSUM_EXEC $xxh64_file | awk '{print $1}') +key="trusted.gfid2path.$xxh64sum" +EXPECT $pgfid_bname get_text_xattr $key $backpath + +## enable gfid2path +TEST $CLI volume set $V0 gfid2path enable + #CREATE fname=$M0/file1 touch $fname; 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; +} |