hammer2 - Add 'hammer2 freemap' directive
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 4 Jun 2013 21:41:50 +0000 (14:41 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 4 Jun 2013 21:41:50 +0000 (14:41 -0700)
* Beef up 'show' and add the 'hammer2 freemap' directive to dump the
  freemap.

sbin/hammer2/cmd_debug.c
sbin/hammer2/hammer2.h
sbin/hammer2/main.c

index 3a0878a..18b9f1f 100644 (file)
@@ -307,11 +307,12 @@ cmd_debugspan(const char *hostname)
  *                                 SHOW                                *
  ************************************************************************/
 
-static void show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref);
+static void show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref,
+                       int dofreemap);
 static void tabprintf(int tab, const char *ctl, ...);
 
 int
-cmd_show(const char *devpath)
+cmd_show(const char *devpath, int dofreemap)
 {
        hammer2_blockref_t broot;
        hammer2_blockref_t best;
@@ -346,18 +347,18 @@ cmd_show(const char *devpath)
                                best = broot;
                        }
                        if (VerboseOpt >= 3)
-                               show_bref(fd, 0, i, &broot);
+                               show_bref(fd, 0, i, &broot, dofreemap);
                }
        }
        if (VerboseOpt < 3)
-               show_bref(fd, 0, best_i, &best);
+               show_bref(fd, 0, best_i, &best, dofreemap);
        close(fd);
 
        return 0;
 }
 
 static void
-show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref)
+show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref, int dofreemap)
 {
        hammer2_media_data_t media;
        hammer2_blockref_t *bscan;
@@ -386,12 +387,20 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref)
        case HAMMER2_BREF_TYPE_VOLUME:
                type_str = "volume";
                break;
+       case HAMMER2_BREF_TYPE_FREEMAP:
+               type_str = "freemap";
+               break;
+       case HAMMER2_BREF_TYPE_FREEMAP_NODE:
+               type_str = "fmapnode";
+               break;
+       case HAMMER2_BREF_TYPE_FREEMAP_LEAF:
+               type_str = "fbitmap";
+               break;
        default:
                type_str = "unknown";
                break;
        }
 
-
        tabprintf(tab, "%s.%-3d %016jx %016jx/%-2d mir=%016jx mod=%016jx ",
               type_str, bi, (intmax_t)bref->data_off,
               (intmax_t)bref->key, (intmax_t)bref->keybits,
@@ -399,21 +408,40 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref)
        tab += SHOW_TAB;
 
        bytes = (size_t)1 << (bref->data_off & HAMMER2_OFF_MASK_RADIX);
-       if (bytes < HAMMER2_MINIOSIZE || bytes > sizeof(media)) {
-               printf("(bad block size %zd)\n", bytes);
-               return;
-       }
-       if (bref->type != HAMMER2_BREF_TYPE_DATA || VerboseOpt >= 1) {
-               lseek(fd, bref->data_off & ~HAMMER2_OFF_MASK_RADIX, 0);
-               if (read(fd, &media, bytes) != (ssize_t)bytes) {
-                       printf("(media read failed)\n");
+
+       {
+               hammer2_off_t io_off;
+               hammer2_off_t io_base;
+               size_t io_bytes;
+               size_t boff;
+
+               io_off = bref->data_off & ~HAMMER2_OFF_MASK_RADIX;
+               io_base = io_off & ~(hammer2_off_t)(HAMMER2_MINIOSIZE - 1);
+               io_bytes = bytes;
+               boff = io_off - io_base;
+
+               io_bytes = HAMMER2_MINIOSIZE;
+               while (io_bytes + boff < bytes)
+                       io_bytes <<= 1;
+
+               if (io_bytes > sizeof(media)) {
+                       printf("(bad block size %zd)\n", bytes);
                        return;
                }
+               if (bref->type != HAMMER2_BREF_TYPE_DATA || VerboseOpt >= 1) {
+                       lseek(fd, io_base, 0);
+                       if (read(fd, &media, io_bytes) != (ssize_t)io_bytes) {
+                               printf("(media read failed)\n");
+                               return;
+                       }
+                       if (boff)
+                               bcopy((char *)&media + boff, &media, bytes);
+               }
        }
 
        bscan = NULL;
        bcount = 0;
-       didnl = 0;
+       didnl = 1;
 
        switch(bref->type) {
        case HAMMER2_BREF_TYPE_EMPTY:
@@ -520,11 +548,39 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref)
                }
                break;
        case HAMMER2_BREF_TYPE_VOLUME:
-               bscan = &media.voldata.sroot_blockset.blockref[0];
-               bcount = HAMMER2_SET_COUNT;
+               if (dofreemap) {
+                       bscan = &media.voldata.freemap_blockset.blockref[0];
+                       bcount = HAMMER2_SET_COUNT;
+               } else {
+                       bscan = &media.voldata.sroot_blockset.blockref[0];
+                       bcount = HAMMER2_SET_COUNT;
+               }
+               printf("{\n");
+               break;
+       case HAMMER2_BREF_TYPE_FREEMAP_LEAF:
+               printf("radix=%d {\n",
+                       bref->check.freemap.radix);
+               obrace = 1;
+               for (i = 0; i < (int)(bytes / sizeof(uint64_t)); ++i) {
+                       if ((i & 3) == 0)
+                               tabprintf(tab, "");
+                       else
+                               printf(" ");
+                       printf("%016jx", (intmax_t)media.bmdata.array[i]);
+                       if ((i & 3) == 3)
+                               printf("\n");
+               }
+               if (((i - 1) & 3) != 3)
+                       printf("\n");
+               break;
+       case HAMMER2_BREF_TYPE_FREEMAP_NODE:
                printf("{\n");
+               bscan = &media.npdata.blockref[0];
+               bcount = bytes / sizeof(hammer2_blockref_t);
                break;
        default:
+               printf("\n");
+               obrace = 0;
                break;
        }
        if (str)
@@ -535,7 +591,7 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref)
                                printf("\n");
                                didnl = 1;
                        }
-                       show_bref(fd, tab, i, &bscan[i]);
+                       show_bref(fd, tab, i, &bscan[i], dofreemap);
                }
        }
        tab -= SHOW_TAB;
index 53e64fe..caf2349 100644 (file)
@@ -120,7 +120,7 @@ int cmd_stat(int ac, const char **av);
 int cmd_leaf(const char *sel_path);
 int cmd_shell(const char *hostname);
 int cmd_debugspan(const char *hostname);
-int cmd_show(const char *devpath);
+int cmd_show(const char *devpath, int dofreemap);
 int cmd_rsainit(const char *dir_path);
 int cmd_rsaenc(const char **keys, int nkeys);
 int cmd_rsadec(const char **keys, int nkeys);
index 461a8d1..d622250 100644 (file)
@@ -317,7 +317,18 @@ main(int ac, char **av)
                        fprintf(stderr, "show: requires device path\n");
                        usage(1);
                } else {
-                       cmd_show(av[1]);
+                       cmd_show(av[1], 0);
+               }
+       } else if (strcmp(av[0], "freemap") == 0) {
+               /*
+                * Raw dump of freemap.  Use -v to check all crc's, and
+                * -vv to dump bulk file data.
+                */
+               if (ac != 2) {
+                       fprintf(stderr, "freemap: requires device path\n");
+                       usage(1);
+               } else {
+                       cmd_show(av[1], 1);
                }
        } else {
                fprintf(stderr, "Unrecognized command: %s\n", av[0]);
@@ -364,6 +375,7 @@ usage(int code)
                "    debugspan <target> Connect to target, run CONN/SPAN\n"
                "    rsainit            Initialize rsa fields\n"
                "    show devpath       Raw hammer2 media dump\n"
+               "    freemap devpath    Raw hammer2 media dump\n"
        );
        exit(code);
 }