1 /* 2 * Copyright (c) 2009 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Antonio Huete <tuxillo@quantumachine.net> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 */ 35 #include <libhammer.h> 36 #include <libutil.h> 37 38 #include "hammer.h" 39 40 void show_info(char *path); 41 static double percent(int64_t value, int64_t total); 42 43 void 44 hammer_cmd_info(char **av, int ac) 45 { 46 struct statfs *stfsbuf; 47 int mntsize, i, first = 1; 48 char *fstype, *path; 49 50 tzset(); 51 52 if (ac > 0) { 53 while (ac) { 54 show_info(*av); 55 --ac; 56 ++av; 57 } 58 } else { 59 mntsize = getmntinfo(&stfsbuf, MNT_NOWAIT); 60 if (mntsize > 0) { 61 for (i = 0; i < mntsize; i++) { 62 fstype = stfsbuf[i].f_fstypename; 63 path = stfsbuf[i].f_mntonname; 64 if ((strcmp(fstype, "hammer")) == 0) { 65 if (first) 66 first = 0; 67 else 68 fprintf(stdout, "\n"); 69 show_info(path); 70 } 71 } 72 } else { 73 fprintf(stdout, "No mounted filesystems found\n"); 74 } 75 } 76 } 77 78 void 79 show_info(char *path) 80 { 81 libhammer_volinfo_t hvi; 82 libhammer_pfsinfo_t pi, pi_first; 83 int64_t usedbigblocks; 84 int64_t usedbytes, rsvbytes; 85 int64_t totalbytes, freebytes; 86 char *fsid; 87 char buf[6]; 88 89 fsid = NULL; 90 usedbigblocks = 0; 91 92 usedbytes = totalbytes = rsvbytes = freebytes = 0; 93 94 hvi = libhammer_get_volinfo(path); 95 if (hvi == NULL) { 96 perror("libhammer_get_volinfo"); 97 exit(EXIT_FAILURE); 98 } 99 100 /* Find out the UUID strings */ 101 uuid_to_string(&hvi->vol_fsid, &fsid, NULL); 102 103 /* Volume information */ 104 fprintf(stdout, "Volume identification\n"); 105 fprintf(stdout, "\tLabel %s\n", hvi->vol_name); 106 fprintf(stdout, "\tNo. Volumes %d\n", hvi->nvolumes); 107 fprintf(stdout, "\tFSID %s\n", fsid); 108 fprintf(stdout, "\tHAMMER Version %d\n", hvi->version); 109 110 /* Big blocks information */ 111 usedbigblocks = hvi->bigblocks - hvi->freebigblocks; 112 113 fprintf(stdout, "Big block information\n"); 114 fprintf(stdout, "\tTotal %10jd\n", (intmax_t)hvi->bigblocks); 115 fprintf(stdout, "\tUsed %10jd (%.2lf%%)\n" 116 "\tReserved %10jd (%.2lf%%)\n" 117 "\tFree %10jd (%.2lf%%)\n", 118 (intmax_t)usedbigblocks, 119 percent(usedbigblocks, hvi->bigblocks), 120 (intmax_t)hvi->rsvbigblocks, 121 percent(hvi->rsvbigblocks, hvi->bigblocks), 122 (intmax_t)(hvi->freebigblocks - hvi->rsvbigblocks), 123 percent(hvi->freebigblocks - hvi->rsvbigblocks, 124 hvi->bigblocks)); 125 fprintf(stdout, "Space information\n"); 126 127 /* Space information */ 128 totalbytes = (hvi->bigblocks << HAMMER_LARGEBLOCK_BITS); 129 usedbytes = (usedbigblocks << HAMMER_LARGEBLOCK_BITS); 130 rsvbytes = (hvi->rsvbigblocks << HAMMER_LARGEBLOCK_BITS); 131 freebytes = ((hvi->freebigblocks - hvi->rsvbigblocks) 132 << HAMMER_LARGEBLOCK_BITS); 133 134 fprintf(stdout, "\tNo. Inodes %10jd\n", (intmax_t)hvi->inodes); 135 humanize_number(buf, sizeof(buf) - (totalbytes < 0 ? 0 : 1), 136 totalbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); 137 fprintf(stdout, "\tTotal size %6s (%jd bytes)\n", 138 buf, (intmax_t)totalbytes); 139 140 humanize_number(buf, sizeof(buf) - (usedbytes < 0 ? 0 : 1), 141 usedbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); 142 fprintf(stdout, "\tUsed %6s (%.2lf%%)\n", buf, 143 percent(usedbytes, totalbytes)); 144 145 humanize_number(buf, sizeof(buf) - (rsvbytes < 0 ? 0 : 1), 146 rsvbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); 147 fprintf(stdout, "\tReserved %6s (%.2lf%%)\n", buf, 148 percent(rsvbytes, totalbytes)); 149 150 humanize_number(buf, sizeof(buf) - (freebytes < 0 ? 0 : 1), 151 freebytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); 152 fprintf(stdout, "\tFree %6s (%.2lf%%)\n", buf, 153 percent(freebytes, totalbytes)); 154 155 /* Pseudo-filesystem information */ 156 fprintf(stdout, "PFS information\n"); 157 fprintf(stdout, "\tPFS ID Mode Snaps Mounted on\n"); 158 159 /* Iterate all the PFSs found */ 160 pi_first = libhammer_get_first_pfs(hvi); 161 for (pi = pi_first; pi != NULL; pi = libhammer_get_next_pfs(pi)) { 162 fprintf(stdout, "\t%6d %-6s", 163 pi->pfs_id, (pi->ismaster ? "MASTER" : "SLAVE")); 164 165 snprintf(buf, 6, "%d", pi->snapcount); 166 fprintf(stdout, " %6s ", (pi->head.error && pi->snapcount == 0) ? "-" : buf); 167 168 if (pi->mountedon) 169 fprintf(stdout, "%s", pi->mountedon); 170 else 171 fprintf(stdout, "not mounted"); 172 173 fprintf(stdout, "\n"); 174 } 175 176 free(fsid); 177 178 libhammer_free_volinfo(hvi); 179 180 } 181 182 static double 183 percent(int64_t value, int64_t total) 184 { 185 /* Avoid divide-by-zero */ 186 if (total == 0) 187 return 100.0; 188 189 return ((value * 100.0) / (double)total); 190 } 191