Add 'hammer info' command that shows extended information about mounted HAMMER fs.
authorAntonio Huete <tuxillo@quantumachine.net>
Sun, 5 Jul 2009 00:36:48 +0000 (02:36 +0200)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sun, 5 Jul 2009 17:07:26 +0000 (10:07 -0700)
sbin/hammer/Makefile
sbin/hammer/cmd_info.c [new file with mode: 0644]
sbin/hammer/hammer.8
sbin/hammer/hammer.c
sbin/hammer/hammer.h
sys/vfs/hammer/hammer_ioctl.c
sys/vfs/hammer/hammer_ioctl.h

index 3b62cf5..9900c41 100644 (file)
@@ -7,11 +7,11 @@ SRCS= hammer.c ondisk.c blockmap.c cache.c misc.c cycle.c \
        cmd_blockmap.c cmd_reblock.c cmd_rebalance.c \
        cmd_synctid.c cmd_stats.c \
        cmd_pseudofs.c cmd_snapshot.c cmd_mirror.c cmd_status.c \
        cmd_blockmap.c cmd_reblock.c cmd_rebalance.c \
        cmd_synctid.c cmd_stats.c \
        cmd_pseudofs.c cmd_snapshot.c cmd_mirror.c cmd_status.c \
-       cmd_cleanup.c cmd_version.c
+       cmd_cleanup.c cmd_info.c cmd_version.c
 MAN=   hammer.8
 
 CFLAGS+= -I${.CURDIR}/../../sys -DALIST_NO_DEBUG
 MAN=   hammer.8
 
 CFLAGS+= -I${.CURDIR}/../../sys -DALIST_NO_DEBUG
-LDADD= -lm
+LDADD= -lm -lutil
 
 .PATH: ${.CURDIR}/../../sys/libkern
 SRCS+= crc32.c
 
 .PATH: ${.CURDIR}/../../sys/libkern
 SRCS+= crc32.c
diff --git a/sbin/hammer/cmd_info.c b/sbin/hammer/cmd_info.c
new file mode 100644 (file)
index 0000000..aba8dfb
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
+ *
+ * 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 "hammer.h"
+#include <libutil.h>
+
+void   show_info(char *path);
+int    percent(int64_t value, int64_t total);
+
+#define WS      " \t\r\n"
+
+void
+hammer_cmd_info(int ac)
+{
+       FILE *fp;
+       char *fs, *ptr, *path;
+       char buf[256];
+
+       tzset();
+       if (ac == 0) {
+               fp = popen("/sbin/mount -t hammer", "r");
+               if (fp == NULL)
+                       errx(1, "hammer info: 'mount' failed");
+               while (fgets(buf, sizeof(buf), fp) != NULL) {
+                       fs = strtok(buf, WS);
+                       if (fs == NULL)
+                               continue;
+                       ptr = strtok(NULL, WS);
+                       if (ptr == NULL)
+                               continue;
+                       path = strtok(NULL, WS);
+                       if (path == NULL)
+                               continue;
+                       ptr = strtok(NULL, WS);
+                       if (ptr == NULL)
+                               continue;
+                       if ((strncmp(ptr, "(hammer,", 8) == 0))
+                               show_info(path);
+               }
+               fclose(fp);
+       }
+}
+
+void show_info(char *path) {
+
+       int64_t usedbigblocks = 0, bytes = 0;
+       struct  hammer_ioc_info info;
+       char    buf[6];
+       int     fd;
+       char    *fsid, *fstype;
+
+       fsid = fstype = NULL;
+
+       bzero(&info, sizeof(struct hammer_ioc_info));
+
+       /* Try to get a file descriptor based on the path given */
+       fd = open(path, O_RDONLY);
+       if (fd < 0) {
+               perror("show_info");
+               exit(EXIT_FAILURE);
+       }
+
+       if ((ioctl(fd, HAMMERIOC_GET_INFO, &info)) < 0) {
+               perror("show_info");
+               exit(EXIT_FAILURE);
+       }
+
+       /* Find out the UUID strings */
+       uuid_to_string(&info.vol_fsid, &fsid, NULL);
+
+       /* Volume information */
+       fprintf(stdout, "Volume identification\n");
+       fprintf(stdout, "\tLabel          %s\n", info.vol_name);
+       fprintf(stdout, "\tNo. Volumes    %d\n", info.nvolumes);
+       fprintf(stdout, "\tFSID           %s\n", fsid);
+
+       /* Big blocks information */
+       usedbigblocks = info.bigblocks - info.freebigblocks;
+
+       fprintf(stdout, "Big block information\n");
+       fprintf(stdout, "\tTotal\t       %lld\n", info.bigblocks);
+       fprintf(stdout, "\tUsed\t       %lld (%d%%)\n\tReserved       %lld (%d%%)\n\tFree\t       %lld (%d%%)\n",
+                       usedbigblocks, percent(usedbigblocks, info.bigblocks),
+                       info.rsvbigblocks, percent(info.rsvbigblocks, info.bigblocks),
+                       (info.freebigblocks - info.rsvbigblocks),
+                       percent(info.freebigblocks - info.rsvbigblocks, info.bigblocks));
+       fprintf(stdout, "Space information\n");
+
+       /* Space information */
+       bytes = (info.bigblocks << HAMMER_LARGEBLOCK_BITS);
+       humanize_number(buf, sizeof(buf)  - (bytes < 0 ? 0 : 1), bytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
+       fprintf(stdout, "\tTotal size     %6s (%lld bytes)\n", buf, bytes);
+
+       bytes = (usedbigblocks << HAMMER_LARGEBLOCK_BITS);
+       humanize_number(buf, sizeof(buf)  - (bytes < 0 ? 0 : 1), bytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
+       fprintf(stdout, "\tUsed space     %6s\n", buf);
+
+       bytes = (info.rsvbigblocks << HAMMER_LARGEBLOCK_BITS);
+       humanize_number(buf, sizeof(buf)  - (bytes < 0 ? 0 : 1), bytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
+       fprintf(stdout, "\tReserved space %6s\n", buf);
+
+       bytes = ((info.freebigblocks - info.rsvbigblocks) << HAMMER_LARGEBLOCK_BITS);
+       humanize_number(buf, sizeof(buf)  - (bytes < 0 ? 0 : 1), bytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
+       fprintf(stdout, "\tFree space     %6s\n\n", buf);
+}
+
+int percent(int64_t value, int64_t total) {
+
+       /* Avoid divide-by-zero */
+       if (value == 0)
+               value = 1;
+
+       return ((value * 100) / total);
+}
index 6da7e23..6f5a5e4 100644 (file)
@@ -247,6 +247,10 @@ part of the hash key.
 Generate the top 32 bits of a
 .Nm HAMMER
 64 bit directory hash for the specified file name.
 Generate the top 32 bits of a
 .Nm HAMMER
 64 bit directory hash for the specified file name.
+.\" ==== info ====
+.It Ar info
+Shows extended information about all the mounted HAMMER filesystems.
+At the moment volume identification, big blocks information and space details are shown.
 .\" ==== cleanup ====
 .It Ar cleanup Op Ar filesystem ...
 This is a meta-command which executes snapshot, pruning, and reblocking
 .\" ==== cleanup ====
 .It Ar cleanup Op Ar filesystem ...
 This is a meta-command which executes snapshot, pruning, and reblocking
index 8c2e609..18e3333 100644 (file)
@@ -285,6 +285,10 @@ main(int ac, char **av)
                hammer_cmd_cleanup(av + 1, ac - 1);
                exit(0);
        }
                hammer_cmd_cleanup(av + 1, ac - 1);
                exit(0);
        }
+       if (strcmp(av[0], "info") == 0) {
+               hammer_cmd_info(ac - 1);
+               exit(0);
+       }
        if (strcmp(av[0], "prune-everything") == 0) {
                hammer_cmd_softprune(av + 1, ac - 1, 1);
                exit(0);
        if (strcmp(av[0], "prune-everything") == 0) {
                hammer_cmd_softprune(av + 1, ac - 1, 1);
                exit(0);
@@ -435,6 +439,7 @@ usage(int exit_code)
                "hammer namekey1 <path>\n"
                "hammer namekey2 <path>\n"
                "hammer cleanup [<filesystem> ...]\n"
                "hammer namekey1 <path>\n"
                "hammer namekey2 <path>\n"
                "hammer cleanup [<filesystem> ...]\n"
+               "hammer info\n"
                "hammer snapshot [<filesystem>] <snapshot-dir>\n"
                "hammer prune <softlink-dir>\n"
                "hammer prune-everything <filesystem>\n"
                "hammer snapshot [<filesystem>] <snapshot-dir>\n"
                "hammer prune <softlink-dir>\n"
                "hammer prune-everything <filesystem>\n"
index 2b23eb9..4d05a1c 100644 (file)
@@ -97,6 +97,7 @@ void hammer_cmd_pseudofs_downgrade(char **av, int ac);
 void hammer_cmd_status(char **av, int ac);
 void hammer_cmd_snapshot(char **av, int ac);
 void hammer_cmd_cleanup(char **av, int ac);
 void hammer_cmd_status(char **av, int ac);
 void hammer_cmd_snapshot(char **av, int ac);
 void hammer_cmd_cleanup(char **av, int ac);
+void hammer_cmd_info(int ac);
 void hammer_cmd_get_version(char **av, int ac);
 void hammer_cmd_set_version(char **av, int ac);
 
 void hammer_cmd_get_version(char **av, int ac);
 void hammer_cmd_set_version(char **av, int ac);
 
index bf4f540..9e12382 100644 (file)
@@ -46,6 +46,10 @@ static int hammer_ioc_get_version(hammer_transaction_t trans,
 static int hammer_ioc_set_version(hammer_transaction_t trans,
                                hammer_inode_t ip,
                                struct hammer_ioc_version *ver);
 static int hammer_ioc_set_version(hammer_transaction_t trans,
                                hammer_inode_t ip,
                                struct hammer_ioc_version *ver);
+static int hammer_ioc_get_info(hammer_transaction_t trans,
+                               struct hammer_ioc_info *info);
+
+
 
 int
 hammer_ioctl(hammer_inode_t ip, u_long com, caddr_t data, int fflag,
 
 int
 hammer_ioctl(hammer_inode_t ip, u_long com, caddr_t data, int fflag,
@@ -135,6 +139,10 @@ hammer_ioctl(hammer_inode_t ip, u_long com, caddr_t data, int fflag,
                error = hammer_ioc_get_version(&trans, ip, 
                                    (struct hammer_ioc_version *)data);
                break;
                error = hammer_ioc_get_version(&trans, ip, 
                                    (struct hammer_ioc_version *)data);
                break;
+       case HAMMERIOC_GET_INFO:
+               error = hammer_ioc_get_info(&trans,
+                                   (struct hammer_ioc_info *)data);
+               break;
        case HAMMERIOC_SET_VERSION:
                if (error == 0) {
                        error = hammer_ioc_set_version(&trans, ip, 
        case HAMMERIOC_SET_VERSION:
                if (error == 0) {
                        error = hammer_ioc_set_version(&trans, ip, 
@@ -501,5 +509,30 @@ failed:
        return(0);
 }
 
        return(0);
 }
 
+/*
+ * Get information
+ */
+static
+int
+hammer_ioc_get_info(hammer_transaction_t trans, struct hammer_ioc_info *info) {
+
+       struct hammer_volume_ondisk     *od = trans->hmp->rootvol->ondisk;
+       struct hammer_mount             *hm = trans->hmp;
+
+       /* Fill the structure with the necessary information */
+       _hammer_checkspace(hm, HAMMER_CHKSPC_WRITE, &info->rsvbigblocks);
+       info->rsvbigblocks = info->rsvbigblocks >> HAMMER_LARGEBLOCK_BITS;
+       strlcpy(info->vol_name, od->vol_name, sizeof(od->vol_name));
 
 
+       info->vol_fsid = hm->fsid;
+       info->vol_fstype = od->vol_fstype;
+       info->version = hm->version;
+
+       info->inodes = od->vol0_stat_inodes;
+       info->bigblocks = od->vol0_stat_bigblocks;
+       info->freebigblocks = od->vol0_stat_freebigblocks;
+       info->nvolumes = hm->nvolumes;
+
+       return 0;
+}
 
 
index 46eaa8f..1bb8fb3 100644 (file)
@@ -218,6 +218,29 @@ struct hammer_ioc_synctid {
        hammer_tid_t            tid;
 };
 
        hammer_tid_t            tid;
 };
 
+/*
+ * HAMMERIOC_GET_INFO
+ */
+struct hammer_ioc_info {
+       struct hammer_ioc_head          head;
+
+       char            vol_name[64];
+       uuid_t          vol_fsid;
+       uuid_t          vol_fstype;
+
+       int             version;
+       int             nvolumes;
+       int             reserved01;
+       int             reserved02;
+
+       int64_t         bigblocks;
+       int64_t         freebigblocks;
+       int64_t         rsvbigblocks;
+       int64_t         inodes;
+
+       int64_t         reservedext[16];
+};
+
 /*
  * HAMMERIOC_GET_PSEUDOFS
  * HAMMERIOC_SET_PSEUDOFS
 /*
  * HAMMERIOC_GET_PSEUDOFS
  * HAMMERIOC_SET_PSEUDOFS
@@ -376,6 +399,7 @@ typedef union hammer_ioc_mrecord_any *hammer_ioc_mrecord_any_t;
 #define HAMMERIOC_GET_VERSION  _IOWR('h',13,struct hammer_ioc_version)
 #define HAMMERIOC_SET_VERSION  _IOWR('h',14,struct hammer_ioc_version)
 #define HAMMERIOC_REBALANCE    _IOWR('h',15,struct hammer_ioc_rebalance)
 #define HAMMERIOC_GET_VERSION  _IOWR('h',13,struct hammer_ioc_version)
 #define HAMMERIOC_SET_VERSION  _IOWR('h',14,struct hammer_ioc_version)
 #define HAMMERIOC_REBALANCE    _IOWR('h',15,struct hammer_ioc_rebalance)
+#define HAMMERIOC_GET_INFO     _IOR('h',16,struct hammer_ioc_info)
 
 #endif
 
 
 #endif