hammer2 - Add 'hammer2 stat'
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 19 May 2012 22:21:01 +0000 (15:21 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 19 May 2012 22:21:01 +0000 (15:21 -0700)
* Add the 'hammer2 stat' directive to access inode information not
  available from a normal stat.

  Currently reports ncopies, data_count, inode_count, data_quota, and
  inode_quota.

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

index 35981b1..f6bd7bf 100644 (file)
@@ -2,7 +2,7 @@ PROG=   hammer2
 SRCS=  main.c subs.c icrc.c msg.c crypto.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
+SRCS+= cmd_rsa.c cmd_stat.c
 #MAN=  hammer2.8
 NOMAN= TRUE
 DEBUG_FLAGS=-g
index f648ab1..af170f3 100644 (file)
@@ -297,6 +297,7 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref)
        int bcount;
        int i;
        int didnl;
+       int namelen;
        int obrace = 1;
        size_t bytes;
        const char *type_str;
@@ -324,21 +325,23 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref)
        }
 
 
-       tabprintf(tab, "%s.%-3d %016jx/%-2d mir=%016jx mod=%016jx ",
-              type_str, bi,
-              bref->key, bref->keybits,
-              bref->mirror_tid, bref->modify_tid);
+       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,
+              (intmax_t)bref->mirror_tid, (intmax_t)bref->modify_tid);
        tab += SHOW_TAB;
 
        bytes = (size_t)1 << (bref->data_off & HAMMER2_OFF_MASK_RADIX);
-       if (bytes > sizeof(media)) {
+       if (bytes < HAMMER2_MINIOSIZE || bytes > sizeof(media)) {
                printf("(bad block size %zd)\n", bytes);
+               sleep(1);
                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");
+                       sleep(1);
                        return;
                }
        }
@@ -359,7 +362,11 @@ show_bref(int fd, int tab, int bi, hammer2_blockref_t *bref)
                        bscan = &media.ipdata.u.blockset.blockref[0];
                        bcount = HAMMER2_SET_COUNT;
                }
-               tabprintf(tab, "filename \"%s\"\n", media.ipdata.filename);
+               namelen = media.ipdata.name_len;
+               if (namelen > HAMMER2_INODE_MAXNAME)
+                       namelen = 0;
+               tabprintf(tab, "filename \"%*.*s\"\n",
+                         namelen, namelen, media.ipdata.filename);
                tabprintf(tab, "version  %d\n", media.ipdata.version);
                tabprintf(tab, "uflags   0x%08x\n",
                          media.ipdata.uflags);
diff --git a/sbin/hammer2/cmd_stat.c b/sbin/hammer2/cmd_stat.c
new file mode 100644 (file)
index 0000000..306418b
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2011-2012 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"
+
+/*
+ * Should be run as root.  Creates /etc/hammer2/rsa.{pub,prv} using
+ * an openssl command.
+ */
+int
+cmd_stat(int ac, const char **av)
+{
+       hammer2_ioc_inode_t ino;
+       const char *cdir = ".";
+       int ec = 0;
+       int w;
+       int i;
+       int fd;
+
+       if (ac == 0) {
+               ac = 1;
+               av = &cdir;
+       }
+       for (i = w = 0; i < ac; ++i) {
+               if (w < (int)strlen(av[i]))
+                       w = (int)strlen(av[i]);
+       }
+       if (w < 16)
+               w = 16;
+       printf("%-*.*s ncp data-use  inode-use\n", w, w, "PATH");
+       for (i = 0; i < ac; ++i) {
+               if ((fd = open(av[i], O_RDONLY)) < 0) {
+                       fprintf(stderr, "%s: %s\n", av[i], strerror(errno));
+                       ec = 1;
+                       continue;
+               }
+               if (ioctl(fd, HAMMER2IOC_INODE_GET, &ino) < 0) {
+                       fprintf(stderr, "%s: %s\n", av[i], strerror(errno));
+                       ec = 1;
+                       continue;
+               }
+               printf("%-*.*s ", w, w, av[i]);
+               printf("%3d ", ino.ip_data.ncopies);
+               printf("%9s ", sizetostr(ino.ip_data.data_count));
+               printf("%9s ", sizetostr(ino.ip_data.inode_count));
+               if (ino.ip_data.data_quota || ino.ip_data.inode_quota) {
+                       printf(" quota ");
+                       printf("%12s", sizetostr(ino.ip_data.data_quota));
+                       printf("/%-12s", sizetostr(ino.ip_data.inode_quota));
+               }
+               printf("\n");
+       }
+       return ec;
+}
index e7642af..6eddcd0 100644 (file)
@@ -97,6 +97,7 @@ int cmd_pfs_create(const char *sel_path, const char *name,
 int cmd_pfs_delete(const char *sel_path, const char *name);
 
 int cmd_service(void);
+int cmd_stat(int ac, const char **av);
 int cmd_leaf(const char *sel_path);
 int cmd_shell(const char *hostname);
 int cmd_show(const char *devpath);
@@ -139,6 +140,7 @@ const char *hammer2_time64_to_str(uint64_t htime64, char **strp);
 const char *hammer2_uuid_to_str(uuid_t *uuid, char **strp);
 const char *hammer2_iptype_to_str(uint8_t type);
 const char *hammer2_pfstype_to_str(uint8_t type);
+const char *sizetostr(hammer2_off_t size);
 
 void hammer2_shell_remote(hammer2_msg_t *msg);
 void msg_printf(hammer2_msg_t *msg, const char *ctl, ...);
index a43f5cd..a6aa429 100644 (file)
@@ -187,6 +187,8 @@ main(int ac, char **av)
                 * protocol.
                 */
                ecode = cmd_service();
+       } else if (strcmp(av[0], "stat") == 0) {
+               ecode = cmd_stat(ac - 1, (const char **)&av[1]);
        } else if (strcmp(av[0], "leaf") == 0) {
                /*
                 * Start the management daemon for a specific PFS.
@@ -309,6 +311,7 @@ usage(int code)
                "    pfs-delete <label> Destroy a PFS\n"
                "    snapshot           Snapshot a PFS\n"
                "    service            Start service daemon\n"
+               "    stat [<path>]      Return inode quota & config\n"
                "    leaf               Start pfs leaf daemon\n"
                "    shell [<host>]     Connect to debug shell\n"
                "    rsainit            Initialize rsa fields\n"
index a1d526e..30deeda 100644 (file)
@@ -242,3 +242,26 @@ hammer2_pfstype_to_str(uint8_t type)
                return("ILLEGAL");
        }
 }
+
+const char *
+sizetostr(hammer2_off_t size)
+{
+       static char buf[32];
+
+       if (size < 1024 / 2) {
+               snprintf(buf, sizeof(buf), "%6.2f", (double)size);
+       } else if (size < 1024 * 1024 / 2) {
+               snprintf(buf, sizeof(buf), "%6.2fKB",
+                       (double)size / 1024);
+       } else if (size < 1024 * 1024 * 1024LL / 2) {
+               snprintf(buf, sizeof(buf), "%6.2fMB",
+                       (double)size / (1024 * 1024));
+       } else if (size < 1024 * 1024 * 1024LL * 1024LL / 2) {
+               snprintf(buf, sizeof(buf), "%6.2fGB",
+                       (double)size / (1024 * 1024 * 1024LL));
+       } else {
+               snprintf(buf, sizeof(buf), "%6.2fTB",
+                       (double)size / (1024 * 1024 * 1024LL * 1024LL));
+       }
+       return(buf);
+}