HAMMER Utility - Fix typo in var declaration.
[dragonfly.git] / sbin / hammer / cmd_info.c
CommitLineData
b66b9421
AH
1/*
2 * Copyright (c) 2009 The DragonFly Project. All rights reserved.
3 *
eac446c5
MD
4 * This code is derived from software contributed to The DragonFly Project
5 * by Antonio Huete <tuxillo@quantumachine.net>
6 *
b66b9421
AH
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 "hammer.h"
36#include <libutil.h>
37
38void show_info(char *path);
7bb56fa9 39char *find_pfs_mount(int pfsid, uuid_t parentuuid, int ismaster);
eac446c5 40double percent(int64_t value, int64_t total);
b66b9421
AH
41
42void
eac446c5 43hammer_cmd_info(void)
b66b9421 44{
eac446c5
MD
45 struct statfs *stfsbuf;
46 int mntsize, i;
47 char *fstype, *path;
b66b9421
AH
48
49 tzset();
eac446c5
MD
50 mntsize = getmntinfo(&stfsbuf, MNT_NOWAIT);
51 if (mntsize > 0) {
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)
b66b9421
AH
56 show_info(path);
57 }
7bb56fa9 58 } else {
eac446c5 59 fprintf(stdout, "No mounted filesystems found\n");
7bb56fa9 60 }
eac446c5 61
b66b9421
AH
62}
63
7bb56fa9
MD
64void
65show_info(char *path)
66{
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;
73 char *fsid, *fstype;
74 char *mountedon;
75 char buf[6];
76 u_int32_t sc;
b66b9421 77
7bb56fa9 78 fsid = fstype = mountedon = NULL;
eac446c5 79 usedbigblocks = 0;
7bb56fa9 80 pfs_id = 1; /* Do not include PFS#0 */
eac446c5 81 bytes = 0;
7bb56fa9 82 sc = 0;
b66b9421
AH
83
84 bzero(&info, sizeof(struct hammer_ioc_info));
7bb56fa9 85 bzero(&snapinfo, sizeof(struct hammer_ioc_snapshot));
b66b9421
AH
86
87 /* Try to get a file descriptor based on the path given */
88 fd = open(path, O_RDONLY);
89 if (fd < 0) {
90 perror("show_info");
91 exit(EXIT_FAILURE);
92 }
93
94 if ((ioctl(fd, HAMMERIOC_GET_INFO, &info)) < 0) {
95 perror("show_info");
96 exit(EXIT_FAILURE);
97 }
98
99 /* Find out the UUID strings */
100 uuid_to_string(&info.vol_fsid, &fsid, NULL);
101
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);
107
108 /* Big blocks information */
109 usedbigblocks = info.bigblocks - info.freebigblocks;
110
111 fprintf(stdout, "Big block information\n");
a276dc6b
MD
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 "
115 "%jd (%.2lf%%)\n",
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,
122 info.bigblocks));
b66b9421
AH
123 fprintf(stdout, "Space information\n");
124
125 /* Space information */
126 bytes = (info.bigblocks << HAMMER_LARGEBLOCK_BITS);
7bb56fa9
MD
127 humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), bytes, "",
128 HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
a276dc6b
MD
129 fprintf(stdout, "\tTotal size %6s (%jd bytes)\n",
130 buf, (intmax_t)bytes);
b66b9421
AH
131
132 bytes = (usedbigblocks << HAMMER_LARGEBLOCK_BITS);
7bb56fa9
MD
133 humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), bytes, "",
134 HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
b66b9421
AH
135 fprintf(stdout, "\tUsed space %6s\n", buf);
136
137 bytes = (info.rsvbigblocks << HAMMER_LARGEBLOCK_BITS);
7bb56fa9
MD
138 humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), bytes, "",
139 HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE | HN_B);
b66b9421
AH
140 fprintf(stdout, "\tReserved space %6s\n", buf);
141
142 bytes = ((info.freebigblocks - info.rsvbigblocks) << HAMMER_LARGEBLOCK_BITS);
7bb56fa9
MD
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);
146
147 /* Pseudo-filesystem information */
148 fprintf(stdout, "PFS information\n");
149 fprintf(stdout, "\tPFS-Id\tMode\tSnaps\tMounted-on\n");
150
151 while(pfs_id < HAMMER_MAX_PFS) {
152 bzero(&pfs, sizeof(pfs));
153 bzero(&pfs_od, sizeof(pfs_od));
154 pfs.pfs_id = pfs_id;
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)
160 sc = snapinfo.count;
161
162 ismaster = (pfs_od.mirror_flags & HAMMER_PFSD_SLAVE) ? 0 : 1;
163 mountedon = find_pfs_mount(pfs_id, info.vol_fsid, ismaster);
164
165 fprintf(stdout, "\t%05d\t%6s\t%5u\t",
166 pfs_id, (ismaster ? "MASTER" : "SLAVE"), sc);
167 if (mountedon)
168 fprintf(stdout, "%s", mountedon);
169 else
170 fprintf(stdout, "not-mounted");
171 fprintf(stdout, "\n");
172 }
173 pfs_id++;
174 }
175
176 fprintf(stdout, "\n\n"); /* In the case multiple volumes, two new-line separation */
177
178 free(fsid);
179 free(mountedon);
b66b9421
AH
180}
181
7bb56fa9
MD
182char *
183find_pfs_mount(int pfsid, uuid_t parentuuid, int ismaster)
184{
185 struct hammer_ioc_info hi;
186 struct statfs *mntbuf;
187 int mntsize;
188 int curmount;
189 int fd;
190 size_t mntbufsize;
d14ecbb6 191 char *trailstr;
7bb56fa9
MD
192 char *retval;
193
194 retval = NULL;
195
196 /* Do not continue if there are no mounted filesystems */
197 mntsize = getfsstat(NULL, 0, MNT_NOWAIT);
198 if (mntsize <= 0)
199 return retval;
b66b9421 200
7bb56fa9
MD
201 mntbufsize = (mntsize) * sizeof(struct statfs);
202 mntbuf = malloc(mntbufsize);
203 if (mntbuf == NULL) {
204 perror("show_info");
205 exit(EXIT_FAILURE);
206 }
207
208 mntsize = getfsstat(mntbuf, (long)mntbufsize, MNT_NOWAIT);
209 curmount = mntsize - 1;
210
211 asprintf(&trailstr, ":%05d", pfsid);
212
213 /*
214 * Iterate all the mounted points looking for the PFS passed to
215 * this function.
216 */
217 while(curmount >= 0) {
218 /*
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.
222 */
223 bzero(&hi, sizeof(hi));
224 if ((fd = open(mntbuf[curmount].f_mntfromname, O_RDONLY)) < 0) {
225 curmount--;
226 continue;
227 }
228
229 if ((ioctl(fd, HAMMERIOC_GET_INFO, &hi)) < 0) {
230 curmount--;
231 continue;
232 }
233
234 if (strstr(mntbuf[curmount].f_mntfromname, trailstr) != NULL &&
235 (uuid_compare(&hi.vol_fsid, &parentuuid, NULL)) == 0) {
236 if (ismaster) {
237 if (strstr(mntbuf[curmount].f_mntfromname, "@@-1") != NULL) {
238 retval = strdup(mntbuf[curmount].f_mntonname);
239 break;
240 }
241 } else {
242 if (strstr(mntbuf[curmount].f_mntfromname, "@@0x") != NULL ) {
243 retval = strdup(mntbuf[curmount].f_mntonname);
244 break;
245 }
246 }
247 }
248 curmount--;
249 }
250 free(trailstr);
251 return retval;
252}
253
254double
255percent(int64_t value, int64_t total)
256{
b66b9421
AH
257 /* Avoid divide-by-zero */
258 if (value == 0)
259 value = 1;
260
eac446c5 261 return ((value * 100.0) / (double)total);
b66b9421 262}