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 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 if (ac) 58 printf("\n"); 59 } 60 } else { 61 mntsize = getmntinfo(&stfsbuf, MNT_NOWAIT); 62 if (mntsize > 0) { 63 for (i = 0; i < mntsize; i++) { 64 fstype = stfsbuf[i].f_fstypename; 65 path = stfsbuf[i].f_mntonname; 66 if ((strcmp(fstype, "hammer")) == 0) { 67 if (first) 68 first = 0; 69 else 70 printf("\n"); 71 show_info(path); 72 } 73 } 74 if (first) 75 printf("No mounted HAMMER filesystems found\n"); 76 } else { 77 printf("No mounted filesystems found\n"); 78 } 79 } 80 } 81 82 void 83 show_info(char *path) 84 { 85 libhammer_fsinfo_t fip; 86 libhammer_pfsinfo_t pi, pi_first; 87 struct hammer_ioc_volume_list ioc; 88 int64_t usedbigblocks; 89 int64_t usedbytes, rsvbytes; 90 int64_t totalbytes, freebytes; 91 char *fsid; 92 char buf[6]; 93 char rootvol[MAXPATHLEN]; 94 int i; 95 96 fsid = NULL; 97 usedbigblocks = 0; 98 99 usedbytes = totalbytes = rsvbytes = freebytes = 0; 100 101 fip = libhammer_get_fsinfo(path); 102 if (fip == NULL) { 103 perror("libhammer_get_fsinfo"); 104 exit(EXIT_FAILURE); 105 } 106 107 /* Find out the UUID strings */ 108 uuid_to_string(&fip->vol_fsid, &fsid, NULL); 109 110 /* Get the volume paths */ 111 if (hammer_fs_to_vol(path, &ioc) == -1) { 112 fprintf(stderr, "Failed to get volume paths\n"); 113 exit(1); 114 } 115 116 /* Get the root volume path */ 117 if (hammer_fs_to_rootvol(path, rootvol, sizeof(rootvol)) == -1) { 118 fprintf(stderr, "Failed to get root volume path\n"); 119 exit(1); 120 } 121 122 /* Volume information */ 123 printf("Volume identification\n"); 124 printf("\tLabel %s\n", fip->vol_name); 125 printf("\tNo. Volumes %d\n", fip->nvolumes); 126 printf("\tHAMMER Volumes "); 127 for (i = 0; i < ioc.nvols; i++) { 128 printf("%s", ioc.vols[i].device_name); 129 if (i != ioc.nvols - 1) 130 printf(":"); 131 } 132 printf("\n"); 133 printf("\tRoot Volume %s\n", rootvol); 134 printf("\tFSID %s\n", fsid); 135 printf("\tHAMMER Version %d\n", fip->version); 136 137 /* Big-blocks information */ 138 usedbigblocks = fip->bigblocks - fip->freebigblocks; 139 140 printf("Big-block information\n"); 141 printf("\tTotal %10jd\n", (intmax_t)fip->bigblocks); 142 printf("\tUsed %10jd (%.2lf%%)\n" 143 "\tReserved %10jd (%.2lf%%)\n" 144 "\tFree %10jd (%.2lf%%)\n", 145 (intmax_t)usedbigblocks, 146 percent(usedbigblocks, fip->bigblocks), 147 (intmax_t)fip->rsvbigblocks, 148 percent(fip->rsvbigblocks, fip->bigblocks), 149 (intmax_t)(fip->freebigblocks - fip->rsvbigblocks), 150 percent(fip->freebigblocks - fip->rsvbigblocks, fip->bigblocks)); 151 printf("Space information\n"); 152 153 /* Space information */ 154 totalbytes = (fip->bigblocks << HAMMER_BIGBLOCK_BITS); 155 usedbytes = (usedbigblocks << HAMMER_BIGBLOCK_BITS); 156 rsvbytes = (fip->rsvbigblocks << HAMMER_BIGBLOCK_BITS); 157 freebytes = ((fip->freebigblocks - fip->rsvbigblocks) 158 << HAMMER_BIGBLOCK_BITS); 159 160 printf("\tNo. Inodes %10jd\n", (intmax_t)fip->inodes); 161 humanize_number(buf, sizeof(buf) - (totalbytes < 0 ? 0 : 1), 162 totalbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); 163 printf("\tTotal size %6s (%jd bytes)\n", 164 buf, (intmax_t)totalbytes); 165 166 humanize_number(buf, sizeof(buf) - (usedbytes < 0 ? 0 : 1), 167 usedbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); 168 printf("\tUsed %6s (%.2lf%%)\n", buf, 169 percent(usedbytes, totalbytes)); 170 171 humanize_number(buf, sizeof(buf) - (rsvbytes < 0 ? 0 : 1), 172 rsvbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); 173 printf("\tReserved %6s (%.2lf%%)\n", buf, 174 percent(rsvbytes, totalbytes)); 175 176 humanize_number(buf, sizeof(buf) - (freebytes < 0 ? 0 : 1), 177 freebytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B); 178 printf("\tFree %6s (%.2lf%%)\n", buf, 179 percent(freebytes, totalbytes)); 180 181 /* Pseudo-filesystem information */ 182 printf("PFS information\n"); 183 printf("\tPFS ID Mode Snaps Mounted on\n"); 184 185 /* Iterate all the PFSs found */ 186 pi_first = libhammer_get_first_pfs(fip); 187 for (pi = pi_first; pi != NULL; pi = libhammer_get_next_pfs(pi)) { 188 printf("\t%6d %-6s", 189 pi->pfs_id, (pi->ismaster ? "MASTER" : "SLAVE")); 190 191 snprintf(buf, 6, "%d", pi->snapcount); 192 printf(" %6s ", (pi->head.error && pi->snapcount == 0) ? "-" : buf); 193 194 if (pi->mountedon) 195 printf("%s", pi->mountedon); 196 else 197 printf("not mounted"); 198 199 printf("\n"); 200 } 201 202 free(fsid); 203 204 libhammer_free_fsinfo(fip); 205 206 } 207 208 static double 209 percent(int64_t value, int64_t total) 210 { 211 /* Avoid divide-by-zero */ 212 if (total == 0) 213 return 100.0; 214 215 return ((value * 100.0) / (double)total); 216 } 217