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