hammer2 - Add directives for setting the check mode
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 5 Aug 2014 07:04:24 +0000 (00:04 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 5 Aug 2014 07:04:24 +0000 (00:04 -0700)
* 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.

sbin/hammer2/Makefile
sbin/hammer2/cmd_debug.c
sbin/hammer2/cmd_setcheck.c [new file with mode: 0644]
sbin/hammer2/cmd_setcomp.c
sbin/hammer2/cmd_stat.c
sbin/hammer2/hammer2.h
sbin/hammer2/main.c
sbin/hammer2/print_inode.c

index 755095f..616602d 100644 (file)
@@ -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
index fe4fbbe..30e83dd 100644 (file)
@@ -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 (file)
index 0000000..f5bd9a0
--- /dev/null
@@ -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 <dillon@dragonflybsd.org>
+ *
+ * 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;
+}
index 3d34aad..593f635 100644 (file)
@@ -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 <dillon@dragonflybsd.org>
  *
  * 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);
index ab42f12..961c8a0 100644 (file)
@@ -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);
+}
index 144c692..cfb62a3 100644 (file)
@@ -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
index 96c0cb1..7da4fa4 100644 (file)
@@ -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);
 }
index 7a749c8..c82b9e0 100644 (file)
@@ -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 <dillon@dragonflybsd.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions