kernel/nata: Extract ad_get_geometry().
[dragonfly.git] / sbin / hammer / cmd_info.c
blob6082ce875c7fc0f5a3ce234b59d4aeb5213e2ab6
1 /*
2 * Copyright (c) 2009 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Antonio Huete <tuxillo@quantumachine.net>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
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.
36 #include "hammer.h"
38 #include <libutil.h>
39 #include <libhammer.h>
41 void show_info(char *path);
42 static double percent(int64_t value, int64_t total);
44 void
45 hammer_cmd_info(char **av, int ac)
47 struct statfs *stfsbuf;
48 int mntsize, i, first = 1;
49 char *fstype, *path;
51 tzset();
53 if (ac > 0) {
54 while (ac) {
55 show_info(*av);
56 --ac;
57 ++av;
58 if (ac)
59 printf("\n");
61 } else {
62 mntsize = getmntinfo(&stfsbuf, MNT_NOWAIT);
63 if (mntsize > 0) {
64 for (i = 0; i < mntsize; i++) {
65 fstype = stfsbuf[i].f_fstypename;
66 path = stfsbuf[i].f_mntonname;
67 if ((strcmp(fstype, "hammer")) == 0) {
68 if (first)
69 first = 0;
70 else
71 printf("\n");
72 show_info(path);
75 if (first)
76 printf("No mounted HAMMER filesystems found\n");
77 } else {
78 printf("No mounted filesystems found\n");
84 * This is an adhoc function which exists only because libhammer can't
85 * properly handle variety of errors.
87 static
88 void
89 __test_if_hammer_or_abort(const char *path)
91 struct hammer_ioc_info info;
92 int fd;
94 fd = open(path, O_RDONLY);
95 if (fd < 0) {
96 err(1, "Failed to open %s", path);
97 /* not reached */
101 * This ioctl never fails as long as fd is for HAMMER filesystem,
102 * thus we can assume path isn't in HAMMER if this fails.
104 if (ioctl(fd, HAMMERIOC_GET_INFO, &info) < 0) {
105 err(1, "%s is probably not a HAMMER filesystem", path);
106 /* not reached */
109 close(fd);
112 void
113 show_info(char *path)
115 libhammer_fsinfo_t fip;
116 libhammer_pfsinfo_t pi, pi_first;
117 struct hammer_ioc_volume_list ioc;
118 int64_t usedbigblocks;
119 int64_t usedbytes, rsvbytes;
120 int64_t totalbytes, freebytes;
121 char *fsid;
122 char buf[6];
123 char rootvol[MAXPATHLEN];
124 int i;
126 fsid = NULL;
127 usedbigblocks = 0;
129 usedbytes = totalbytes = rsvbytes = freebytes = 0;
131 /* Need to do this before libhammer gets involved */
132 __test_if_hammer_or_abort(path);
134 fip = libhammer_get_fsinfo(path);
135 if (fip == NULL) {
136 errx(1, "Failed to get filesystem info");
137 /* not reached */
140 /* Find out the UUID strings */
141 hammer_uuid_to_string(&fip->vol_fsid, &fsid);
143 /* Get the volume paths */
144 if (hammer_fs_to_vol(path, &ioc) == -1) {
145 errx(1, "Failed to get volume paths");
146 /* not reached */
149 /* Get the root volume path */
150 if (hammer_fs_to_rootvol(path, rootvol, sizeof(rootvol)) == -1) {
151 errx(1, "Failed to get root volume path");
152 /* not reached */
155 /* Volume information */
156 printf("Volume identification\n");
157 printf("\tLabel %s\n", fip->vol_name);
158 printf("\tNo. Volumes %d\n", fip->nvolumes);
159 printf("\tHAMMER Volumes ");
160 for (i = 0; i < ioc.nvols; i++) {
161 printf("%s", ioc.vols[i].device_name);
162 if (i != ioc.nvols - 1)
163 printf(":");
165 printf("\n");
166 printf("\tRoot Volume %s\n", rootvol);
167 printf("\tFSID %s\n", fsid);
168 printf("\tHAMMER Version %d\n", fip->version);
170 /* Big-blocks information */
171 usedbigblocks = fip->bigblocks - fip->freebigblocks;
173 printf("Big-block information\n");
174 printf("\tTotal %10jd\n", (intmax_t)fip->bigblocks);
175 printf("\tUsed %10jd (%.2lf%%)\n"
176 "\tReserved %10jd (%.2lf%%)\n"
177 "\tFree %10jd (%.2lf%%)\n",
178 (intmax_t)usedbigblocks,
179 percent(usedbigblocks, fip->bigblocks),
180 (intmax_t)fip->rsvbigblocks,
181 percent(fip->rsvbigblocks, fip->bigblocks),
182 (intmax_t)(fip->freebigblocks - fip->rsvbigblocks),
183 percent(fip->freebigblocks - fip->rsvbigblocks, fip->bigblocks));
184 printf("Space information\n");
186 /* Space information */
187 totalbytes = (fip->bigblocks << HAMMER_BIGBLOCK_BITS);
188 usedbytes = (usedbigblocks << HAMMER_BIGBLOCK_BITS);
189 rsvbytes = (fip->rsvbigblocks << HAMMER_BIGBLOCK_BITS);
190 freebytes = ((fip->freebigblocks - fip->rsvbigblocks)
191 << HAMMER_BIGBLOCK_BITS);
193 printf("\tNo. Inodes %10jd\n", (intmax_t)fip->inodes);
194 humanize_number(buf, sizeof(buf) - (totalbytes < 0 ? 0 : 1),
195 totalbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
196 printf("\tTotal size %6s (%jd bytes)\n",
197 buf, (intmax_t)totalbytes);
199 humanize_number(buf, sizeof(buf) - (usedbytes < 0 ? 0 : 1),
200 usedbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
201 printf("\tUsed %6s (%.2lf%%)\n", buf,
202 percent(usedbytes, totalbytes));
204 humanize_number(buf, sizeof(buf) - (rsvbytes < 0 ? 0 : 1),
205 rsvbytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
206 printf("\tReserved %6s (%.2lf%%)\n", buf,
207 percent(rsvbytes, totalbytes));
209 humanize_number(buf, sizeof(buf) - (freebytes < 0 ? 0 : 1),
210 freebytes, "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
211 printf("\tFree %6s (%.2lf%%)\n", buf,
212 percent(freebytes, totalbytes));
214 /* Pseudo-filesystem information */
215 printf("PFS information\n");
216 printf("\t PFS# Mode Snaps\n");
218 /* Iterate all the PFSs found */
219 pi_first = libhammer_get_first_pfs(fip);
220 for (pi = pi_first; pi != NULL; pi = libhammer_get_next_pfs(pi)) {
221 printf("\t%6d %-6s",
222 pi->pfs_id, (pi->ismaster ? "MASTER" : "SLAVE"));
224 snprintf(buf, 6, "%d", pi->snapcount);
225 printf(" %6s", (pi->head.error && pi->snapcount == 0) ? "-" : buf);
226 if (pi->pfs_id == HAMMER_ROOT_PFSID)
227 printf(" (root PFS)");
228 printf("\n");
231 free(fsid);
233 libhammer_free_fsinfo(fip);
237 static
238 double
239 percent(int64_t value, int64_t total)
241 /* Avoid divide-by-zero */
242 if (total == 0)
243 return 100.0;
245 return ((value * 100.0) / (double)total);