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