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