From eac446c50abe1405a40b6ff5eb347bcae6464101 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 19 Aug 2009 08:30:38 -0700 Subject: [PATCH] HAMMER Util - Refactor mount list scan and other fixes * 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 --- sbin/hammer/cmd_cleanup.c | 49 +++++++++++++++----------------- sbin/hammer/cmd_info.c | 53 +++++++++++++++-------------------- sbin/hammer/hammer.c | 2 +- sbin/hammer/hammer.h | 2 +- sys/kern/vfs_subr.c | 20 ++++++++++--- sys/vfs/hammer/hammer_vnops.c | 14 +-------- 6 files changed, 64 insertions(+), 76 deletions(-) diff --git a/sbin/hammer/cmd_cleanup.c b/sbin/hammer/cmd_cleanup.c index e40fc41c5c..db46e2d2fd 100644 --- a/sbin/hammer/cmd_cleanup.c +++ b/sbin/hammer/cmd_cleanup.c @@ -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; } - - diff --git a/sbin/hammer/cmd_info.c b/sbin/hammer/cmd_info.c index aba8dfb0c0..bf55bdc085 100644 --- a/sbin/hammer/cmd_info.c +++ b/sbin/hammer/cmd_info.c @@ -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 + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -33,51 +36,41 @@ #include 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); } diff --git a/sbin/hammer/hammer.c b/sbin/hammer/hammer.c index dec15f5297..b3ddbb64ab 100644 --- a/sbin/hammer/hammer.c +++ b/sbin/hammer/hammer.c @@ -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) { diff --git a/sbin/hammer/hammer.h b/sbin/hammer/hammer.h index d4f72049d9..b0c6bdd870 100644 --- a/sbin/hammer/hammer.h +++ b/sbin/hammer/hammer.h @@ -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); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 6a2f12f5ec..b82ee44cf1 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -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; diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c index 2c125905fb..a92e9c4276 100644 --- a/sys/vfs/hammer/hammer_vnops.c +++ b/sys/vfs/hammer/hammer_vnops.c @@ -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; -- 2.41.0