diff options
-rw-r--r-- | include/fstree.h | 2 | ||||
-rw-r--r-- | lib/fstree/fstree_from_dir.c | 79 | ||||
-rw-r--r-- | mkfs/mkfs.c | 3 | ||||
-rw-r--r-- | mkfs/mkfs.h | 1 | ||||
-rw-r--r-- | mkfs/options.c | 20 |
5 files changed, 102 insertions, 3 deletions
diff --git a/include/fstree.h b/include/fstree.h index 9f47f76..cbd3c9c 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -39,6 +39,8 @@ enum { DIR_SCAN_KEEP_TIME = 0x01, DIR_SCAN_ONE_FILESYSTEM = 0x02, + + DIR_SCAN_READ_XATTR = 0x04, }; /* Encapsulates a set of key-value pairs attached to a tree_node_t */ diff --git a/lib/fstree/fstree_from_dir.c b/lib/fstree/fstree_from_dir.c index 7301d91..4b89272 100644 --- a/lib/fstree/fstree_from_dir.c +++ b/lib/fstree/fstree_from_dir.c @@ -10,6 +10,9 @@ #include "util.h" #include <sys/types.h> +#ifdef HAVE_SYS_XATTR_H +#include <sys/xattr.h> +#endif #include <dirent.h> #include <unistd.h> #include <string.h> @@ -52,6 +55,75 @@ fail: return NULL; } +#ifdef HAVE_SYS_XATTR_H +static int populate_xattr(fstree_t *fs, tree_node_t *node) +{ + char *key, *value = NULL, *buffer = NULL; + ssize_t buflen, vallen, keylen; + + buflen = listxattr(node->name, NULL, 0); + + if (buflen < 0) { + perror("listxattr"); + return -1; + } + + if (buflen == 0) + return 0; + + buffer = malloc(buflen); + if (buffer == NULL) { + perror("xattr name buffer"); + return -1; + } + + buflen = listxattr(node->name, buffer, buflen); + if (buflen == -1) { + perror("listxattr"); + goto fail; + } + + key = buffer; + while (buflen > 0) { + vallen = getxattr(node->name, key, NULL, 0); + if (vallen == -1) + goto fail; + + if (vallen > 0) { + value = calloc(1, vallen + 1); + if (value == NULL) { + perror("xattr value buffer"); + goto fail; + } + + vallen = getxattr(node->name, key, value, vallen); + if (vallen == -1) { + perror("getxattr"); + goto fail; + } + + value[vallen] = 0; + if (fstree_add_xattr(fs, node, key, value)) + goto fail; + + free(value); + value = NULL; + } + + keylen = strlen(key) + 1; + buflen -= keylen; + key += keylen; + } + + free(buffer); + return 0; +fail: + free(value); + free(buffer); + return -1; +} +#endif + static int populate_dir(fstree_t *fs, tree_node_t *root, dev_t devstart, unsigned int flags) { @@ -115,6 +187,13 @@ static int populate_dir(fstree_t *fs, tree_node_t *root, dev_t devstart, goto fail; } +#ifdef HAVE_SYS_XATTR_H + if (flags & DIR_SCAN_READ_XATTR) { + if (populate_xattr(fs, n)) + return -1; + } +#endif + free(extra); extra = NULL; } diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index f0d1e73..b11dce0 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -81,6 +81,9 @@ static int read_fstree(fstree_t *fs, options_t *opt) if (opt->one_filesystem) flags |= DIR_SCAN_ONE_FILESYSTEM; + if (opt->keep_xattr) + flags |= DIR_SCAN_READ_XATTR; + return fstree_from_dir(fs, opt->packdir, flags); } diff --git a/mkfs/mkfs.h b/mkfs/mkfs.h index c7c327c..e02c248 100644 --- a/mkfs/mkfs.h +++ b/mkfs/mkfs.h @@ -36,6 +36,7 @@ typedef struct { int blksz; int devblksz; bool keep_time; + bool keep_xattr; bool one_filesystem; bool exportable; bool quiet; diff --git a/mkfs/options.c b/mkfs/options.c index 340cb81..2778a9e 100644 --- a/mkfs/options.c +++ b/mkfs/options.c @@ -15,6 +15,9 @@ static struct option long_opts[] = { { "pack-file", required_argument, NULL, 'F' }, { "pack-dir", required_argument, NULL, 'D' }, { "keep-time", no_argument, NULL, 'k' }, +#ifdef HAVE_SYS_XATTR_H + { "keep-xattr", no_argument, NULL, 'x' }, +#endif { "one-file-system", no_argument, NULL, 'o' }, { "exportable", no_argument, NULL, 'e' }, { "force", no_argument, NULL, 'f' }, @@ -26,11 +29,14 @@ static struct option long_opts[] = { { "help", no_argument, NULL, 'h' }, }; +static const char *short_opts = "F:D:X:c:b:B:d:kxoefqhV" #ifdef WITH_SELINUX -static const char *short_opts = "s:F:D:X:c:b:B:d:koefqhV"; -#else -static const char *short_opts = "F:D:X:c:b:B:d:koefqhV"; +"s:" +#endif +#ifdef HAVE_SYS_XATTR_H +"x" #endif +; extern char *__progname; @@ -77,6 +83,8 @@ static const char *help_string = " --keep-time, -k When using --pack-dir only, use the timestamps\n" " from the input files instead of setting\n" " defaults on all input paths.\n" +" --keep-xattr, -x When using --pack-dir only, read and pack the\n" +" extended attributes from the input files.\n" " --one-file-system, -o When using --pack-dir only, stay in local file\n" " system and do not cross mount points.\n" " --exportable, -e Generate an export table for NFS support.\n" @@ -139,6 +147,7 @@ void process_command_line(options_t *opt, int argc, char **argv) opt->compressor = compressor_get_default(); opt->blksz = SQFS_DEFAULT_BLOCK_SIZE; opt->devblksz = SQFS_DEVBLK_SIZE; + opt->keep_xattr = false; opt->keep_time = false; opt->one_filesystem = false; opt->exportable = false; @@ -188,6 +197,11 @@ void process_command_line(options_t *opt, int argc, char **argv) case 'k': opt->keep_time = true; break; +#ifdef HAVE_SYS_XATTR_H + case 'x': + opt->keep_xattr = true; + break; +#endif case 'o': opt->one_filesystem = true; break; |