/* Copyright (c) 2017 Red Hat, Inc. 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 #include #include #include #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 \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 = SLEN(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; }