From: Thomas Nikolajsen Date: Sat, 14 Nov 2009 14:08:46 +0000 (+0100) Subject: hammer info: align display, include PFS#0 & show correct snapshot count X-Git-Tag: v2.7.1~379^2~2 X-Git-Url: http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/095ad2eb08ab6db9b8786bb6a3150fd84b017d70 hammer info: align display, include PFS#0 & show correct snapshot count * show snapshot count for HAMMER version 2- & 3+ * fix snapshot count for HAMMER version 3+ * show HAMMER version * show inode count * show PFS #0 (HAMMER FS) * align display --- diff --git a/sbin/hammer/cmd_info.c b/sbin/hammer/cmd_info.c index b13010a..bc93cb4 100644 --- a/sbin/hammer/cmd_info.c +++ b/sbin/hammer/cmd_info.c @@ -38,12 +38,13 @@ void show_info(char *path); char *find_pfs_mount(int pfsid, uuid_t parentuuid, int ismaster); double percent(int64_t value, int64_t total); +u_int32_t count_snapshots(int fd, u_int32_t version, char *pfs_snapshots, char *mountedon); void hammer_cmd_info(void) { struct statfs *stfsbuf; - int mntsize, i; + int mntsize, i, first = 1; char *fstype, *path; tzset(); @@ -52,8 +53,13 @@ hammer_cmd_info(void) for (i=0; i < mntsize; i++) { fstype = stfsbuf[i].f_fstypename; path = stfsbuf[i].f_mntonname; - if ((strcmp(fstype, "hammer")) == 0) + if ((strcmp(fstype, "hammer")) == 0) { + if (first) + first = 0; + else + fprintf(stdout, "\n"); show_info(path); + } } } else { fprintf(stdout, "No mounted filesystems found\n"); @@ -64,25 +70,23 @@ hammer_cmd_info(void) void show_info(char *path) { - struct hammer_ioc_snapshot snapinfo; struct hammer_pseudofs_data pfs_od; struct hammer_ioc_pseudofs_rw pfs; int64_t usedbigblocks, bytes; struct hammer_ioc_info info; int fd, pfs_id, ismaster; - char *fsid, *fstype; + char *fsid; char *mountedon; char buf[6]; u_int32_t sc; - fsid = fstype = mountedon = NULL; + fsid = mountedon = NULL; usedbigblocks = 0; - pfs_id = 1; /* Do not include PFS#0 */ + pfs_id = 0; /* Include PFS#0 */ bytes = 0; sc = 0; bzero(&info, sizeof(struct hammer_ioc_info)); - bzero(&snapinfo, sizeof(struct hammer_ioc_snapshot)); /* Try to get a file descriptor based on the path given */ fd = open(path, O_RDONLY); @@ -101,18 +105,19 @@ show_info(char *path) /* 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); + fprintf(stdout, "\tLabel %s\n", info.vol_name); + fprintf(stdout, "\tNo. Volumes %d\n", info.nvolumes); + fprintf(stdout, "\tFSID %s\n", fsid); + fprintf(stdout, "\tHAMMER Version %d\n", info.version); /* Big blocks information */ usedbigblocks = info.bigblocks - info.freebigblocks; fprintf(stdout, "Big block information\n"); - fprintf(stdout, "\tTotal\t %jd\n", (intmax_t)info.bigblocks); - fprintf(stdout, "\tUsed\t %jd (%.2lf%%)\n\tReserved " - "%jd (%.2lf%%)\n\tFree\t " - "%jd (%.2lf%%)\n", + fprintf(stdout, "\tTotal %10jd\n", (intmax_t)info.bigblocks); + fprintf(stdout, "\tUsed %10jd (%.2lf%%)\n" + "\tReserved %10jd (%.2lf%%)\n" + "\tFree %10jd (%.2lf%%)\n", (intmax_t)usedbigblocks, percent(usedbigblocks, info.bigblocks), (intmax_t)info.rsvbigblocks, @@ -123,6 +128,7 @@ show_info(char *path) fprintf(stdout, "Space information\n"); /* Space information */ + fprintf(stdout, "\tNo. Inodes %10jd\n", (intmax_t)info.inodes); bytes = (info.bigblocks << HAMMER_LARGEBLOCK_BITS); humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), bytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); @@ -146,7 +152,7 @@ show_info(char *path) /* Pseudo-filesystem information */ fprintf(stdout, "PFS information\n"); - fprintf(stdout, "\tPFS-Id\tMode\tSnaps\tMounted-on\n"); + fprintf(stdout, "\tPFS-Id Mode Snaps Mounted-on\n"); while(pfs_id < HAMMER_MAX_PFS) { bzero(&pfs, sizeof(pfs)); @@ -156,13 +162,15 @@ show_info(char *path) pfs.bytes = sizeof(pfs_od); pfs.version = HAMMER_IOC_PSEUDOFS_VERSION; if (ioctl(fd, HAMMERIOC_GET_PSEUDOFS, &pfs) >= 0) { - if (ioctl(fd, HAMMERIOC_GET_SNAPSHOT, &snapinfo) >= 0) - sc = snapinfo.count; - ismaster = (pfs_od.mirror_flags & HAMMER_PFSD_SLAVE) ? 0 : 1; - mountedon = find_pfs_mount(pfs_id, info.vol_fsid, ismaster); + if (pfs_id == 0) + mountedon = path; + else + mountedon = find_pfs_mount(pfs_id, info.vol_fsid, ismaster); + + sc = count_snapshots(fd, info.version, pfs_od.snapshots, mountedon); - fprintf(stdout, "\t%05d\t%6s\t%5u\t", + fprintf(stdout, "\t%6d %-6s %6d ", pfs_id, (ismaster ? "MASTER" : "SLAVE"), sc); if (mountedon) fprintf(stdout, "%s", mountedon); @@ -171,9 +179,7 @@ show_info(char *path) fprintf(stdout, "\n"); } pfs_id++; - } - - fprintf(stdout, "\n\n"); /* In the case multiple volumes, two new-line separation */ + } free(fsid); free(mountedon); @@ -255,8 +261,53 @@ double percent(int64_t value, int64_t total) { /* Avoid divide-by-zero */ - if (value == 0) - value = 1; + if (total == 0) + return 100.0; return ((value * 100.0) / (double)total); } + +u_int32_t +count_snapshots(int fd, u_int32_t version, char *pfs_snapshots, char *mountedon) +{ + struct hammer_ioc_snapshot snapinfo; + char *snapshots_path, *fpath; + struct dirent *den; + struct stat st; + DIR *dir; + u_int32_t snapshot_count = 0; + + bzero(&snapinfo, sizeof(struct hammer_ioc_snapshot)); + if (version < 3) { + /* + * old style: count the number of softlinks in the snapshots dir + */ + if (pfs_snapshots[0]) + snapshots_path = pfs_snapshots; + else + asprintf(&snapshots_path, "%s/snapshots", mountedon); + if ((dir = opendir(snapshots_path)) != NULL) { + while ((den = readdir(dir)) != NULL) { + if (den->d_name[0] == '.') + continue; + asprintf(&fpath, "%s/%s", snapshots_path, den->d_name); + if (lstat(fpath, &st) == 0 && S_ISLNK(st.st_mode)) + snapshot_count++; + free(fpath); + } + closedir(dir); + } + } else { + /* + * new style: file system meta-data + */ + do { + if (ioctl(fd, HAMMERIOC_GET_SNAPSHOT, &snapinfo) < 0) { + perror("count_snapshots"); + exit(EXIT_FAILURE); + } + snapshot_count += snapinfo.count; + } while (snapinfo.head.error == 0 && snapinfo.count); + } + return snapshot_count; +}