From: Matthew Dillon Date: Tue, 5 Aug 2014 07:04:24 +0000 (-0700) Subject: hammer2 - Add directives for setting the check mode X-Git-Tag: v4.1.0~334 X-Git-Url: https://gitweb.dragonflybsd.org/~tuxillo/dragonfly.git/commitdiff_plain/8adee7de1428f5412bc3cb872362dd5a84e72d4e hammer2 - Add directives for setting the check mode * Add setcheck, setcrc32, and a few other directives for setting the crc check mode on a directory or file. The inode and any new chains or modifications will inherit the mode. * Make adjustments to stat and show to display more information. --- diff --git a/sbin/hammer2/Makefile b/sbin/hammer2/Makefile index 755095fcf4..616602dae8 100644 --- a/sbin/hammer2/Makefile +++ b/sbin/hammer2/Makefile @@ -2,7 +2,8 @@ PROG= hammer2 SRCS= main.c subs.c icrc.c SRCS+= cmd_remote.c cmd_snapshot.c cmd_pfs.c SRCS+= cmd_service.c cmd_leaf.c cmd_debug.c -SRCS+= cmd_rsa.c cmd_stat.c cmd_setcomp.c print_inode.c +SRCS+= cmd_rsa.c cmd_stat.c cmd_setcomp.c cmd_setcheck.c +SRCS+= print_inode.c #MAN= hammer2.8 NOMAN= TRUE DEBUG_FLAGS=-g diff --git a/sbin/hammer2/cmd_debug.c b/sbin/hammer2/cmd_debug.c index fe4fbbe70b..30e83dd093 100644 --- a/sbin/hammer2/cmd_debug.c +++ b/sbin/hammer2/cmd_debug.c @@ -501,6 +501,10 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref, int dofreemap) if (bref->type != HAMMER2_BREF_TYPE_DATA || VerboseOpt >= 1) { switch(HAMMER2_DEC_CHECK(bref->methods)) { case HAMMER2_CHECK_NONE: + printf("(meth %02x) ", bref->methods); + break; + case HAMMER2_CHECK_DISABLED: + printf("(meth %02x) ", bref->methods); break; case HAMMER2_CHECK_ISCSI32: cv = hammer2_icrc32(&media, bytes); @@ -509,11 +513,15 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref, int dofreemap) bref->methods, bref->check.iscsi32.value, cv); + } else { + printf("(meth %02x) ", bref->methods); } break; case HAMMER2_CHECK_CRC64: + printf("(meth %02x) ", bref->methods); break; case HAMMER2_CHECK_SHA192: + printf("(meth %02x) ", bref->methods); break; case HAMMER2_CHECK_FREEMAP: cv = hammer2_icrc32(&media, bytes); @@ -522,6 +530,8 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref, int dofreemap) bref->methods, bref->check.freemap.icrc32, cv); + } else { + printf("(meth %02x) ", bref->methods); } break; } @@ -594,6 +604,8 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref, int dofreemap) media.ipdata.ncopies); tabprintf(tab, "compalg %u\n", media.ipdata.comp_algo); + tabprintf(tab, "checkalg %u\n", + media.ipdata.check_algo); if (media.ipdata.op_flags & HAMMER2_OPFLAG_PFSROOT) { tabprintf(tab, "pfs_type %u (%s)\n", media.ipdata.pfs_type, diff --git a/sbin/hammer2/cmd_setcheck.c b/sbin/hammer2/cmd_setcheck.c new file mode 100644 index 0000000000..f5bd9a0ce7 --- /dev/null +++ b/sbin/hammer2/cmd_setcheck.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "hammer2.h" + +static int cmd_setcheck_core(uint8_t check_algo, const char *path_str, + struct stat *st); + +int +cmd_setcheck(const char *check_str, char **paths) +{ + static const char *checks[] = HAMMER2_CHECK_STRINGS; + struct stat st; + int check_algo; + int ecode; + int res; + + ecode = 0; + + if (isdigit(check_str[0])) { + check_algo = strtol(check_str, NULL, 0); + } else { + check_algo = HAMMER2_CHECK_STRINGS_COUNT; + while (--check_algo >= 0) { + if (strcasecmp(check_str, checks[check_algo]) == 0) + break; + } + if (check_algo < 0 && strcasecmp(check_str, "default") == 0) { + check_algo = HAMMER2_CHECK_ISCSI32; + check_str = "crc32"; + } + if (check_algo < 0 && strcasecmp(check_str, "disabled") == 0) { + check_algo = HAMMER2_CHECK_DISABLED; + check_str = "disabled"; + } + if (check_algo < 0) { + fprintf(stderr, + "Unknown check code type: %s\n", + check_str); + ecode = 3; + } + } + + if (ecode == 0) { + while (*paths) { + if (lstat(*paths, &st) == 0) { + res = cmd_setcheck_core( + HAMMER2_ENC_ALGO(check_algo), + *paths, + &st); + if (res) + ecode = res; + } else { + printf("%s: %s\n", *paths, strerror(errno)); + ecode = 3; + } + ++paths; + } + } + + return ecode; +} + +static int +cmd_setcheck_core(uint8_t check_algo, const char *path_str, struct stat *st) +{ + hammer2_ioc_inode_t inode; + int fd; + int res; + + fd = hammer2_ioctl_handle(path_str); + if (fd < 0) { + res = 3; + goto failed; + } + res = ioctl(fd, HAMMER2IOC_INODE_GET, &inode); + if (res < 0) { + fprintf(stderr, + "%s: HAMMER2IOC_INODE_GET: error %s\n", + path_str, strerror(errno)); + res = 3; + goto failed; + } + printf("%s\tcheck_algo=0x%02x\n", path_str, check_algo); + inode.ip_data.check_algo = check_algo; + res = ioctl(fd, HAMMER2IOC_INODE_SET, &inode); + if (res < 0) { + fprintf(stderr, + "%s: HAMMER2IOC_INODE_SET: error %s\n", + path_str, strerror(errno)); + res = 3; + goto failed; + } + res = 0; + + if (RecurseOpt && S_ISDIR(st->st_mode)) { + DIR *dir; + char *path; + struct dirent *den; + + if ((dir = fdopendir(fd)) != NULL) { + while ((den = readdir(dir)) != NULL) { + if (strcmp(den->d_name, ".") == 0 || + strcmp(den->d_name, "..") == 0) { + continue; + } + asprintf(&path, "%s/%s", path_str, den->d_name); + if (lstat(path, st) == 0) + cmd_setcheck_core(check_algo, path, st); + free(path); + } + closedir(dir); + } + } +failed: + close(fd); + return res; +} diff --git a/sbin/hammer2/cmd_setcomp.c b/sbin/hammer2/cmd_setcomp.c index 3d34aade02..593f635ab7 100644 --- a/sbin/hammer2/cmd_setcomp.c +++ b/sbin/hammer2/cmd_setcomp.c @@ -1,6 +1,8 @@ /* * Copyright (c) 2013 The DragonFly Project. All rights reserved. * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -108,7 +110,7 @@ cmd_setcomp(const char *comp_str, char **paths) while (*paths) { if (lstat(*paths, &st) == 0) { res = cmd_setcomp_core( - HAMMER2_ENC_COMP(comp_algo) | + HAMMER2_ENC_ALGO(comp_algo) | HAMMER2_ENC_LEVEL(comp_level), *paths, &st); diff --git a/sbin/hammer2/cmd_stat.c b/sbin/hammer2/cmd_stat.c index ab42f12f35..961c8a0283 100644 --- a/sbin/hammer2/cmd_stat.c +++ b/sbin/hammer2/cmd_stat.c @@ -35,6 +35,7 @@ #include "hammer2.h" static const char *compmodestr(uint8_t comp_algo); +static const char *checkmodestr(uint8_t comp_algo); /* * Should be run as root. Creates /etc/hammer2/rsa.{pub,prv} using @@ -78,6 +79,7 @@ cmd_stat(int ac, const char **av) printf("%9s ", counttostr(ino.ip_data.inode_count)); printf("%p ", ino.kdata); printf("comp=%s ", compmodestr(ino.ip_data.comp_algo)); + printf("check=%s ", checkmodestr(ino.ip_data.check_algo)); if (ino.ip_data.data_quota || ino.ip_data.inode_quota) { printf(" quota "); printf("%12s", sizetostr(ino.ip_data.data_quota)); @@ -94,7 +96,7 @@ compmodestr(uint8_t comp_algo) { static char buf[64]; static const char *comps[] = HAMMER2_COMP_STRINGS; - int comp = HAMMER2_DEC_COMP(comp_algo); + int comp = HAMMER2_DEC_ALGO(comp_algo); int level = HAMMER2_DEC_LEVEL(comp_algo); if (level) { @@ -114,3 +116,31 @@ compmodestr(uint8_t comp_algo) } return (buf); } + +static +const char * +checkmodestr(uint8_t check_algo) +{ + static char buf[64]; + static const char *checks[] = HAMMER2_CHECK_STRINGS; + int check = HAMMER2_DEC_ALGO(check_algo); + int level = HAMMER2_DEC_LEVEL(check_algo); + + /* + * NOTE: Check algorithms normally do not encode any level. + */ + if (level) { + if (check >= 0 && check < HAMMER2_CHECK_STRINGS_COUNT) + snprintf(buf, sizeof(buf), "%s:%d", + checks[check], level); + else + snprintf(buf, sizeof(buf), "unknown(%d):%d", + check, level); + } else { + if (check >= 0 && check < HAMMER2_CHECK_STRINGS_COUNT) + snprintf(buf, sizeof(buf), "%s", checks[check]); + else + snprintf(buf, sizeof(buf), "unknown(%d)", check); + } + return (buf); +} diff --git a/sbin/hammer2/hammer2.h b/sbin/hammer2/hammer2.h index 144c69217c..cfb62a3c47 100644 --- a/sbin/hammer2/hammer2.h +++ b/sbin/hammer2/hammer2.h @@ -141,6 +141,7 @@ int cmd_rsainit(const char *dir_path); int cmd_rsaenc(const char **keys, int nkeys); int cmd_rsadec(const char **keys, int nkeys); int cmd_setcomp(const char *comp_str, char **paths); +int cmd_setcheck(const char *comp_str, char **paths); /* * Misc functions diff --git a/sbin/hammer2/main.c b/sbin/hammer2/main.c index 96c0cb185c..7da4fa4505 100644 --- a/sbin/hammer2/main.c +++ b/sbin/hammer2/main.c @@ -368,6 +368,30 @@ main(int ac, char **av) */ ecode = cmd_setcomp(av[1], &av[2]); } + } else if (strcmp(av[0], "setcheck") == 0) { + if (ac < 3) { + /* + * Missing compression method and at least one + * path. + */ + fprintf(stderr, + "setcheck: requires check code method and" + "directory/file path\n"); + usage(1); + } else { + /* + * Multiple paths may be specified + */ + ecode = cmd_setcheck(av[1], &av[2]); + } + } else if (strcmp(av[0], "clrcheck") == 0) { + ecode = cmd_setcheck("none", &av[1]); + } else if (strcmp(av[0], "setcrc32") == 0) { + ecode = cmd_setcheck("crc32", &av[1]); + } else if (strcmp(av[0], "setcrc64") == 0) { + ecode = cmd_setcheck("crc64", &av[1]); + } else if (strcmp(av[0], "setsha192") == 0) { + ecode = cmd_setcheck("sha192", &av[1]); } else if (strcmp(av[0], "printinode") == 0) { if (ac != 2) { fprintf(stderr, @@ -440,8 +464,16 @@ usage(int code) "Raw hammer2 media dump\n" " freemap devpath " "Raw hammer2 media dump\n" - " setcomp comp[:level] path " - "Set compression {none, autozero, lz4, zlib} & level\n" + " setcomp comp[:level] path... " + "Set comp algo {none, autozero, lz4, zlib} & level\n" + " setcheck check path... " + "Set check algo {none, crc32, crc64, sha192}\n" + " setcrc32 path... " + "Set check algo to crc32\n" + " setcrc64 path... " + "Set check algo to crc64\n" + " setsha192 path... " + "Set check algo to sha192\n" ); exit(code); } diff --git a/sbin/hammer2/print_inode.c b/sbin/hammer2/print_inode.c index 7a749c899e..c82b9e0838 100644 --- a/sbin/hammer2/print_inode.c +++ b/sbin/hammer2/print_inode.c @@ -1,6 +1,8 @@ /* * Copyright (c) 2013 The DragonFly Project. All rights reserved. * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions