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
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
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
39 #include <libhammer.h>
41 void show_info(char *path
);
42 static double percent(int64_t value
, int64_t total
);
45 hammer_cmd_info(char **av
, int ac
)
47 struct statfs
*stfsbuf
;
48 int mntsize
, i
, first
= 1;
62 mntsize
= getmntinfo(&stfsbuf
, MNT_NOWAIT
);
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) {
76 printf("No mounted HAMMER filesystems found\n");
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.
89 __test_if_hammer_or_abort(const char *path
)
91 struct hammer_ioc_info info
;
94 fd
= open(path
, O_RDONLY
);
96 err(1, "Failed to open %s", path
);
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
);
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
;
123 char rootvol
[MAXPATHLEN
];
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
);
136 errx(1, "Failed to get filesystem info");
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");
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");
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)
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
)) {
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)");
233 libhammer_free_fsinfo(fip
);
239 percent(int64_t value
, int64_t total
)
241 /* Avoid divide-by-zero */
245 return ((value
* 100.0) / (double)total
);