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
38 void show_info(char *path
);
39 char *find_pfs_mount(int pfsid
, uuid_t parentuuid
, int ismaster
);
40 double percent(int64_t value
, int64_t total
);
45 struct statfs
*stfsbuf
;
50 mntsize
= getmntinfo(&stfsbuf
, MNT_NOWAIT
);
52 for (i
=0; i
< mntsize
; i
++) {
53 fstype
= stfsbuf
[i
].f_fstypename
;
54 path
= stfsbuf
[i
].f_mntonname
;
55 if ((strcmp(fstype
, "hammer")) == 0)
59 fprintf(stdout
, "No mounted filesystems found\n");
67 struct hammer_ioc_snapshot snapinfo
;
68 struct hammer_pseudofs_data pfs_od
;
69 struct hammer_ioc_pseudofs_rw pfs
;
70 int64_t usedbigblocks
, bytes
;
71 struct hammer_ioc_info info
;
72 int fd
, pfs_id
, ismaster
;
78 fsid
= fstype
= mountedon
= NULL
;
80 pfs_id
= 1; /* Do not include PFS#0 */
84 bzero(&info
, sizeof(struct hammer_ioc_info
));
85 bzero(&snapinfo
, sizeof(struct hammer_ioc_snapshot
));
87 /* Try to get a file descriptor based on the path given */
88 fd
= open(path
, O_RDONLY
);
94 if ((ioctl(fd
, HAMMERIOC_GET_INFO
, &info
)) < 0) {
99 /* Find out the UUID strings */
100 uuid_to_string(&info
.vol_fsid
, &fsid
, NULL
);
102 /* Volume information */
103 fprintf(stdout
, "Volume identification\n");
104 fprintf(stdout
, "\tLabel %s\n", info
.vol_name
);
105 fprintf(stdout
, "\tNo. Volumes %d\n", info
.nvolumes
);
106 fprintf(stdout
, "\tFSID %s\n", fsid
);
108 /* Big blocks information */
109 usedbigblocks
= info
.bigblocks
- info
.freebigblocks
;
111 fprintf(stdout
, "Big block information\n");
112 fprintf(stdout
, "\tTotal\t %jd\n", (intmax_t)info
.bigblocks
);
113 fprintf(stdout
, "\tUsed\t %jd (%.2lf%%)\n\tReserved "
114 "%jd (%.2lf%%)\n\tFree\t "
116 (intmax_t)usedbigblocks
,
117 percent(usedbigblocks
, info
.bigblocks
),
118 (intmax_t)info
.rsvbigblocks
,
119 percent(info
.rsvbigblocks
, info
.bigblocks
),
120 (intmax_t)(info
.freebigblocks
- info
.rsvbigblocks
),
121 percent(info
.freebigblocks
- info
.rsvbigblocks
,
123 fprintf(stdout
, "Space information\n");
125 /* Space information */
126 bytes
= (info
.bigblocks
<< HAMMER_LARGEBLOCK_BITS
);
127 humanize_number(buf
, sizeof(buf
) - (bytes
< 0 ? 0 : 1), bytes
, "",
128 HN_AUTOSCALE
, HN_DECIMAL
| HN_NOSPACE
| HN_B
);
129 fprintf(stdout
, "\tTotal size %6s (%jd bytes)\n",
130 buf
, (intmax_t)bytes
);
132 bytes
= (usedbigblocks
<< HAMMER_LARGEBLOCK_BITS
);
133 humanize_number(buf
, sizeof(buf
) - (bytes
< 0 ? 0 : 1), bytes
, "",
134 HN_AUTOSCALE
, HN_DECIMAL
| HN_NOSPACE
| HN_B
);
135 fprintf(stdout
, "\tUsed space %6s\n", buf
);
137 bytes
= (info
.rsvbigblocks
<< HAMMER_LARGEBLOCK_BITS
);
138 humanize_number(buf
, sizeof(buf
) - (bytes
< 0 ? 0 : 1), bytes
, "",
139 HN_AUTOSCALE
, HN_DECIMAL
| HN_NOSPACE
| HN_B
);
140 fprintf(stdout
, "\tReserved space %6s\n", buf
);
142 bytes
= ((info
.freebigblocks
- info
.rsvbigblocks
) << HAMMER_LARGEBLOCK_BITS
);
143 humanize_number(buf
, sizeof(buf
) - (bytes
< 0 ? 0 : 1), bytes
, "",
144 HN_AUTOSCALE
, HN_DECIMAL
| HN_NOSPACE
| HN_B
);
145 fprintf(stdout
, "\tFree space %6s\n", buf
);
147 /* Pseudo-filesystem information */
148 fprintf(stdout
, "PFS information\n");
149 fprintf(stdout
, "\tPFS-Id\tMode\tSnaps\tMounted-on\n");
151 while(pfs_id
< HAMMER_MAX_PFS
) {
152 bzero(&pfs
, sizeof(pfs
));
153 bzero(&pfs_od
, sizeof(pfs_od
));
155 pfs
.ondisk
= &pfs_od
;
156 pfs
.bytes
= sizeof(pfs_od
);
157 pfs
.version
= HAMMER_IOC_PSEUDOFS_VERSION
;
158 if (ioctl(fd
, HAMMERIOC_GET_PSEUDOFS
, &pfs
) >= 0) {
159 if (ioctl(fd
, HAMMERIOC_GET_SNAPSHOT
, &snapinfo
) >= 0)
162 ismaster
= (pfs_od
.mirror_flags
& HAMMER_PFSD_SLAVE
) ? 0 : 1;
163 mountedon
= find_pfs_mount(pfs_id
, info
.vol_fsid
, ismaster
);
165 fprintf(stdout
, "\t%05d\t%6s\t%5u\t",
166 pfs_id
, (ismaster
? "MASTER" : "SLAVE"), sc
);
168 fprintf(stdout
, "%s", mountedon
);
170 fprintf(stdout
, "not-mounted");
171 fprintf(stdout
, "\n");
176 fprintf(stdout
, "\n\n"); /* In the case multiple volumes, two new-line separation */
183 find_pfs_mount(int pfsid
, uuid_t parentuuid
, int ismaster
)
185 struct hammer_ioc_info hi
;
186 struct statfs
*mntbuf
;
196 /* Do not continue if there are no mounted filesystems */
197 mntsize
= getfsstat(NULL
, 0, MNT_NOWAIT
);
201 mntbufsize
= (mntsize
) * sizeof(struct statfs
);
202 mntbuf
= malloc(mntbufsize
);
203 if (mntbuf
== NULL
) {
208 mntsize
= getfsstat(mntbuf
, (long)mntbufsize
, MNT_NOWAIT
);
209 curmount
= mntsize
- 1;
211 asprintf(&trailstr
, ":%05d", pfsid
);
214 * Iterate all the mounted points looking for the PFS passed to
217 while(curmount
>= 0) {
219 * We need to avoid that PFS belonging to other HAMMER
220 * filesystems are showed as mounted, so we compare
221 * against the FSID, which is presumable to be unique.
223 bzero(&hi
, sizeof(hi
));
224 if ((fd
= open(mntbuf
[curmount
].f_mntfromname
, O_RDONLY
)) < 0) {
229 if ((ioctl(fd
, HAMMERIOC_GET_INFO
, &hi
)) < 0) {
234 if (strstr(mntbuf
[curmount
].f_mntfromname
, trailstr
) != NULL
&&
235 (uuid_compare(&hi
.vol_fsid
, &parentuuid
, NULL
)) == 0) {
237 if (strstr(mntbuf
[curmount
].f_mntfromname
, "@@-1") != NULL
) {
238 retval
= strdup(mntbuf
[curmount
].f_mntonname
);
242 if (strstr(mntbuf
[curmount
].f_mntfromname
, "@@0x") != NULL
) {
243 retval
= strdup(mntbuf
[curmount
].f_mntonname
);
255 percent(int64_t value
, int64_t total
)
257 /* Avoid divide-by-zero */
261 return ((value
* 100.0) / (double)total
);