HAMMER Util - Refactor mount list scan and other fixes
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 19 Aug 2009 15:30:38 +0000 (08:30 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 19 Aug 2009 15:30:38 +0000 (08:30 -0700)
    * MOUNTCTL - Fix a problem with user mount flags parsing in HAMMER.

    * User mount flags for HAMMER FS was not properly handled. Now
      function vfs_flagstostr() is able to append to the passed buf.

    * Refactor the mountlist scan for info / cleanup commands.

Submitted-by: Antonio Huete Jimenez <tuxillo@quantumachine.net>
sbin/hammer/cmd_cleanup.c
sbin/hammer/cmd_info.c
sbin/hammer/hammer.c
sbin/hammer/hammer.h
sys/kern/vfs_subr.c
sys/vfs/hammer/hammer_vnops.c

index e40fc41..db46e2d 100644 (file)
@@ -91,36 +91,33 @@ struct didpfs *FirstPFS;
 void
 hammer_cmd_cleanup(char **av, int ac)
 {
-       FILE *fp;
-       char *fs, *ptr, *path;
-       char buf[256];
+       char *fstype, *fs, *path;
+       struct statfs *stfsbuf;
+       int mntsize, i;
 
        tzset();
        if (ac == 0) {
-               fp = popen("/sbin/mount -t hammer,null", "r");
-               if (fp == NULL)
-                       errx(1, "hammer cleanup: '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) ||
-                           ((strncmp(ptr, "(null,", 6) == 0) &&
-                            (strstr(fs, "/@@0x") != NULL ||
-                             strstr(fs, "/@@-1") != NULL))) {
-                               do_cleanup(path);
+               mntsize = getmntinfo(&stfsbuf, MNT_NOWAIT);
+               if (mntsize > 0) {
+                       for (i=0; i < mntsize; i++) {
+                               /*
+                                * We will cleanup in the case fstype is hammer.
+                                * If we have null-mounted PFS, we check the
+                                * mount source. If it looks like a PFS, we
+                                * proceed to cleanup also.
+                                */
+                               fstype = stfsbuf[i].f_fstypename;
+                               fs = stfsbuf[i].f_mntfromname;
+                               if ((strcmp(fstype, "hammer") == 0) ||
+                                   ((strcmp(fstype, "null") == 0) &&
+                                    (strstr(fs, "/@@0x") != NULL ||
+                                     strstr(fs, "/@@-1") != NULL))) {
+                                       path = stfsbuf[i].f_mntonname;
+                                       do_cleanup(path);
+                               }
                        }
                }
-               fclose(fp);
+
        } else {
                while (ac) {
                        do_cleanup(*av);
@@ -791,5 +788,3 @@ runcmd(int *resp, const char *ctl, ...)
        if (resp)
                *resp = res;
 }
-
-
index aba8dfb..bf55bdc 100644 (file)
@@ -1,6 +1,9 @@
 /*
  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
  *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Antonio Huete <tuxillo@quantumachine.net>
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
 #include <libutil.h>
 
 void   show_info(char *path);
-int    percent(int64_t value, int64_t total);
-
-#define WS      " \t\r\n"
+double percent(int64_t value, int64_t total);
 
 void
-hammer_cmd_info(int ac)
+hammer_cmd_info(void)
 {
-       FILE *fp;
-       char *fs, *ptr, *path;
-       char buf[256];
+       struct statfs *stfsbuf;
+       int mntsize, i;
+       char *fstype, *path;
 
        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))
+       mntsize = getmntinfo(&stfsbuf, MNT_NOWAIT);
+       if (mntsize > 0) {
+               for (i=0; i < mntsize; i++) {
+                       fstype = stfsbuf[i].f_fstypename;
+                       path = stfsbuf[i].f_mntonname;
+                       if ((strcmp(fstype, "hammer")) == 0)
                                show_info(path);
                }
-               fclose(fp);
        }
+       else
+               fprintf(stdout, "No mounted filesystems found\n");
+
 }
 
 void show_info(char *path) {
 
-       int64_t usedbigblocks = 0, bytes = 0;
+       int64_t usedbigblocks, bytes;
        struct  hammer_ioc_info info;
        char    buf[6];
        int     fd;
        char    *fsid, *fstype;
 
        fsid = fstype = NULL;
+       usedbigblocks = 0;
+       bytes = 0;
 
        bzero(&info, sizeof(struct hammer_ioc_info));
 
@@ -107,7 +100,7 @@ void show_info(char *path) {
 
        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",
+       fprintf(stdout, "\tUsed\t       %lld (%.2lf%%)\n\tReserved       %lld (%.2lf%%)\n\tFree\t       %lld (%.2lf%%)\n",
                        usedbigblocks, percent(usedbigblocks, info.bigblocks),
                        info.rsvbigblocks, percent(info.rsvbigblocks, info.bigblocks),
                        (info.freebigblocks - info.rsvbigblocks),
@@ -132,11 +125,11 @@ void show_info(char *path) {
        fprintf(stdout, "\tFree space     %6s\n\n", buf);
 }
 
-int percent(int64_t value, int64_t total) {
+double percent(int64_t value, int64_t total) {
 
        /* Avoid divide-by-zero */
        if (value == 0)
                value = 1;
 
-       return ((value * 100) / total);
+       return ((value * 100.0) / (double)total);
 }
index dec15f5..b3ddbb6 100644 (file)
@@ -295,7 +295,7 @@ main(int ac, char **av)
                exit(0);
        }
        if (strcmp(av[0], "info") == 0) {
-               hammer_cmd_info(ac - 1);
+               hammer_cmd_info();
                exit(0);
        }
        if (strcmp(av[0], "prune-everything") == 0) {
index d4f7204..b0c6bdd 100644 (file)
@@ -100,7 +100,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_info(int ac);
+void hammer_cmd_info(void);
 void hammer_cmd_get_version(char **av, int ac);
 void hammer_cmd_set_version(char **av, int ac);
 void hammer_cmd_expand(char **av, int ac);
index 6a2f12f..b82ee44 100644 (file)
@@ -1654,13 +1654,25 @@ vfs_flagstostr(int flags, const struct mountctl_opt *optp,
        int bwritten;
        int bleft;
        int optlen;
-
-       if (optp == NULL)
-               optp = optnames;
+       int actsize;
 
        *errorp = 0;
        bwritten = 0;
        bleft = len - 1;        /* leave room for trailing \0 */
+
+       /*
+        * Checks the size of the string. If it contains
+        * any data, then we will append the new flags to
+        * it.
+        */
+       actsize = strlen(buf);
+       if (actsize > 0)
+               buf += actsize;
+
+       /* Default flags if no flags passed */
+       if (optp == NULL)
+               optp = optnames;
+
        if (bleft < 0) {        /* degenerate case, 0-length buffer */
                *errorp = EINVAL;
                return(0);
@@ -1670,7 +1682,7 @@ vfs_flagstostr(int flags, const struct mountctl_opt *optp,
                if ((flags & optp->o_opt) == 0)
                        continue;
                optlen = strlen(optp->o_name);
-               if (bwritten) {
+               if (bwritten || actsize > 0) {
                        if (bleft < 2) {
                                *errorp = ENOSPC;
                                break;
index 2c12590..a92e9c4 100644 (file)
@@ -2222,7 +2222,6 @@ hammer_vop_mountctl(struct vop_mountctl_args *ap)
        struct mount *mp;
        int usedbytes;
        int error;
-       char *pos;
 
        error = 0;
        usedbytes = 0;
@@ -2251,21 +2250,10 @@ hammer_vop_mountctl(struct vop_mountctl_args *ap)
 
                usedbytes = *ap->a_res;
 
-               if (usedbytes && usedbytes < ap->a_buflen) {
-                       pos = (char *)ap->a_buf + usedbytes;
-                       *pos++ = ','; /* Overwrite trailing \0 */
-                       usedbytes++;
-
+               if (usedbytes > 0 && usedbytes < ap->a_buflen) {
                        usedbytes += vfs_flagstostr(hmp->hflags, extraopt, ap->a_buf,
                                                    ap->a_buflen - usedbytes,
                                                    &error);
-
-                       /* Remove trailing comma if  no HAMMER flags returned */
-                       if (usedbytes == *ap->a_res) {
-                               *pos-- = 0;
-                               usedbytes--;
-                       }
-
                }
 
                *ap->a_res += usedbytes;