19ddb49cbSWarner Losh /*- 24b88c807SRodney W. Grimes * Copyright (c) 1980, 1990, 1993, 1994 34b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 44b88c807SRodney W. Grimes * (c) UNIX System Laboratories, Inc. 54b88c807SRodney W. Grimes * All or some portions of this file are derived from material licensed 64b88c807SRodney W. Grimes * to the University of California by American Telephone and Telegraph 74b88c807SRodney W. Grimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with 84b88c807SRodney W. Grimes * the permission of UNIX System Laboratories, Inc. 94b88c807SRodney W. Grimes * 104b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 114b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 124b88c807SRodney W. Grimes * are met: 134b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 144b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 154b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 164b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 174b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 18*fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 194b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 204b88c807SRodney W. Grimes * without specific prior written permission. 214b88c807SRodney W. Grimes * 224b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 234b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 244b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 254b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 264b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 274b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 284b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 294b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 304b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 314b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 324b88c807SRodney W. Grimes * SUCH DAMAGE. 334b88c807SRodney W. Grimes */ 344b88c807SRodney W. Grimes 3509a80d48SDavid E. O'Brien #if 0 364b88c807SRodney W. Grimes #ifndef lint 3716cc192aSSteve Price static const char copyright[] = 384b88c807SRodney W. Grimes "@(#) Copyright (c) 1980, 1990, 1993, 1994\n\ 394b88c807SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 404b88c807SRodney W. Grimes #endif /* not lint */ 414b88c807SRodney W. Grimes 424b88c807SRodney W. Grimes #ifndef lint 4316cc192aSSteve Price static char sccsid[] = "@(#)df.c 8.9 (Berkeley) 5/8/95"; 444b88c807SRodney W. Grimes #endif /* not lint */ 4509a80d48SDavid E. O'Brien #endif 465eb43ac2SDavid E. O'Brien #include <sys/cdefs.h> 475eb43ac2SDavid E. O'Brien __FBSDID("$FreeBSD$"); 484b88c807SRodney W. Grimes 494b88c807SRodney W. Grimes #include <sys/param.h> 504b88c807SRodney W. Grimes #include <sys/stat.h> 514b88c807SRodney W. Grimes #include <sys/mount.h> 52a25695c3SJim Pirzyk #include <sys/sysctl.h> 53176d3efdSBrooks Davis #ifdef MOUNT_CHAR_DEVS 54a78192e3SBruce Evans #include <ufs/ufs/ufsmount.h> 55176d3efdSBrooks Davis #endif 564b88c807SRodney W. Grimes #include <err.h> 577d3940bbSPawel Jakub Dawidek #include <libutil.h> 58019e4a53SGreg Lehey #include <locale.h> 59facc3cb0SBrooks Davis #ifdef MOUNT_CHAR_DEVS 60facc3cb0SBrooks Davis #include <mntopts.h> 61facc3cb0SBrooks Davis #endif 620bd9f151SIan Dowse #include <stdint.h> 634b88c807SRodney W. Grimes #include <stdio.h> 644b88c807SRodney W. Grimes #include <stdlib.h> 654b88c807SRodney W. Grimes #include <string.h> 66dd6d33e8SMichael Haro #include <sysexits.h> 674b88c807SRodney W. Grimes #include <unistd.h> 68b6ff8745SMarcel Moolenaar #include <libxo/xo.h> 694b88c807SRodney W. Grimes 70532aff98SPoul-Henning Kamp #include "extern.h" 71532aff98SPoul-Henning Kamp 72dd6d33e8SMichael Haro #define UNITS_SI 1 73dd6d33e8SMichael Haro #define UNITS_2 2 74dd6d33e8SMichael Haro 7562edbd31SIan Dowse /* Maximum widths of various fields. */ 7662edbd31SIan Dowse struct maxwidths { 770bd9f151SIan Dowse int mntfrom; 78b56ca465SPawel Jakub Dawidek int fstype; 790bd9f151SIan Dowse int total; 800bd9f151SIan Dowse int used; 810bd9f151SIan Dowse int avail; 820bd9f151SIan Dowse int iused; 830bd9f151SIan Dowse int ifree; 8462edbd31SIan Dowse }; 8562edbd31SIan Dowse 86c6f13844SDavid E. O'Brien static void addstat(struct statfs *, struct statfs *); 87b7dbd3e9SMark Murray static char *getmntpt(const char *); 880bd9f151SIan Dowse static int int64width(int64_t); 89532aff98SPoul-Henning Kamp static char *makenetvfslist(void); 90fde81c7dSKirk McKusick static void prthuman(const struct statfs *, int64_t); 91b6ff8745SMarcel Moolenaar static void prthumanval(const char *, int64_t); 92841fe8e8SDavid Schultz static intmax_t fsbtoblk(int64_t, uint64_t, u_long); 93532aff98SPoul-Henning Kamp static void prtstat(struct statfs *, struct maxwidths *); 94be2c4e54SDavid E. O'Brien static size_t regetmntinfo(struct statfs **, long, const char **); 95b7dbd3e9SMark Murray static void update_maxwidths(struct maxwidths *, const struct statfs *); 96532aff98SPoul-Henning Kamp static void usage(void); 974b88c807SRodney W. Grimes 980bd9f151SIan Dowse static __inline int 990bd9f151SIan Dowse imax(int a, int b) 10062edbd31SIan Dowse { 101b7dbd3e9SMark Murray return (a > b ? a : b); 10262edbd31SIan Dowse } 10362edbd31SIan Dowse 104b56ca465SPawel Jakub Dawidek static int aflag = 0, cflag, hflag, iflag, kflag, lflag = 0, nflag, Tflag; 105019e4a53SGreg Lehey static int thousands; 106176d3efdSBrooks Davis #ifdef MOUNT_CHAR_DEVS 107532aff98SPoul-Henning Kamp static struct ufs_args mdev; 108176d3efdSBrooks Davis #endif 109532aff98SPoul-Henning Kamp 1104b88c807SRodney W. Grimes int 111f9bcb0beSWarner Losh main(int argc, char *argv[]) 1124b88c807SRodney W. Grimes { 1134b88c807SRodney W. Grimes struct stat stbuf; 114c6f13844SDavid E. O'Brien struct statfs statfsbuf, totalbuf; 11562edbd31SIan Dowse struct maxwidths maxwidths; 116c6f13844SDavid E. O'Brien struct statfs *mntbuf; 117facc3cb0SBrooks Davis #ifdef MOUNT_CHAR_DEVS 118facc3cb0SBrooks Davis struct iovec *iov = NULL; 119facc3cb0SBrooks Davis #endif 120a95a13bbSKris Kennaway const char *fstype; 121176d3efdSBrooks Davis #ifdef MOUNT_CHAR_DEVS 122176d3efdSBrooks Davis char *mntpath; 123facc3cb0SBrooks Davis char errmsg[255] = {0}; 124176d3efdSBrooks Davis #endif 125176d3efdSBrooks Davis char *mntpt; 126532aff98SPoul-Henning Kamp const char **vfslist; 1277b0514faSDag-Erling Smørgrav int i, mntsize; 128be2c4e54SDavid E. O'Brien int ch, rv; 129facc3cb0SBrooks Davis #ifdef MOUNT_CHAR_DEVS 130facc3cb0SBrooks Davis int iovlen = 0; 131facc3cb0SBrooks Davis #endif 132f3895a82SKris Kennaway 133f3895a82SKris Kennaway fstype = "ufs"; 134019e4a53SGreg Lehey (void)setlocale(LC_ALL, ""); 13511ed25f2SUlrich Spörlein memset(&maxwidths, 0, sizeof(maxwidths)); 136076419d2SDavid E. O'Brien memset(&totalbuf, 0, sizeof(totalbuf)); 137076419d2SDavid E. O'Brien totalbuf.f_bsize = DEV_BSIZE; 138d7c881e8SWarner Losh strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN); 139a78192e3SBruce Evans vfslist = NULL; 140b6ff8745SMarcel Moolenaar 141b6ff8745SMarcel Moolenaar argc = xo_parse_args(argc, argv); 142b6ff8745SMarcel Moolenaar if (argc < 0) 143b6ff8745SMarcel Moolenaar exit(1); 144b6ff8745SMarcel Moolenaar 145019e4a53SGreg Lehey while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T,")) != -1) 1464b88c807SRodney W. Grimes switch (ch) { 1475b42dac8SJulian Elischer case 'a': 1485b42dac8SJulian Elischer aflag = 1; 1495b42dac8SJulian Elischer break; 150dd6d33e8SMichael Haro case 'b': 151dd6d33e8SMichael Haro /* FALLTHROUGH */ 152dd6d33e8SMichael Haro case 'P': 153df464e43SChristian S.J. Peron /* 1546bccea7cSRebecca Cran * POSIX specifically discusses the behavior of 155df464e43SChristian S.J. Peron * both -k and -P. It states that the blocksize should 156df464e43SChristian S.J. Peron * be set to 1024. Thus, if this occurs, simply break 157df464e43SChristian S.J. Peron * rather than clobbering the old blocksize. 158df464e43SChristian S.J. Peron */ 159df464e43SChristian S.J. Peron if (kflag) 160df464e43SChristian S.J. Peron break; 1612966d28cSSean Farley setenv("BLOCKSIZE", "512", 1); 162dd6d33e8SMichael Haro hflag = 0; 163dd6d33e8SMichael Haro break; 164c6f13844SDavid E. O'Brien case 'c': 165c6f13844SDavid E. O'Brien cflag = 1; 166c6f13844SDavid E. O'Brien break; 16793a3fa19SJohn W. De Boskey case 'g': 1682966d28cSSean Farley setenv("BLOCKSIZE", "1g", 1); 16993a3fa19SJohn W. De Boskey hflag = 0; 17093a3fa19SJohn W. De Boskey break; 171dd6d33e8SMichael Haro case 'H': 172dd6d33e8SMichael Haro hflag = UNITS_SI; 173dd6d33e8SMichael Haro break; 174dd6d33e8SMichael Haro case 'h': 175dd6d33e8SMichael Haro hflag = UNITS_2; 176dd6d33e8SMichael Haro break; 1774b88c807SRodney W. Grimes case 'i': 1784b88c807SRodney W. Grimes iflag = 1; 1794b88c807SRodney W. Grimes break; 1807f0eabfdSGarrett Wollman case 'k': 181df464e43SChristian S.J. Peron kflag++; 1822966d28cSSean Farley setenv("BLOCKSIZE", "1024", 1); 183dd6d33e8SMichael Haro hflag = 0; 184dd6d33e8SMichael Haro break; 185a25695c3SJim Pirzyk case 'l': 186246ef54fSConrad Meyer /* Ignore duplicate -l */ 187246ef54fSConrad Meyer if (lflag) 188246ef54fSConrad Meyer break; 189a25695c3SJim Pirzyk if (vfslist != NULL) 190b6ff8745SMarcel Moolenaar xo_errx(1, "-l and -t are mutually exclusive."); 191a25695c3SJim Pirzyk vfslist = makevfslist(makenetvfslist()); 19227f82335SWill Andrews lflag = 1; 193a25695c3SJim Pirzyk break; 194dd6d33e8SMichael Haro case 'm': 1952966d28cSSean Farley setenv("BLOCKSIZE", "1m", 1); 196dd6d33e8SMichael Haro hflag = 0; 1977f0eabfdSGarrett Wollman break; 1984b88c807SRodney W. Grimes case 'n': 1994b88c807SRodney W. Grimes nflag = 1; 2004b88c807SRodney W. Grimes break; 2014b88c807SRodney W. Grimes case 't': 20227f82335SWill Andrews if (lflag) 203b6ff8745SMarcel Moolenaar xo_errx(1, "-l and -t are mutually exclusive."); 204a78192e3SBruce Evans if (vfslist != NULL) 205b6ff8745SMarcel Moolenaar xo_errx(1, "only one -t option may be specified"); 206f3895a82SKris Kennaway fstype = optarg; 207a78192e3SBruce Evans vfslist = makevfslist(optarg); 2084b88c807SRodney W. Grimes break; 209b56ca465SPawel Jakub Dawidek case 'T': 210b56ca465SPawel Jakub Dawidek Tflag = 1; 211b56ca465SPawel Jakub Dawidek break; 212019e4a53SGreg Lehey case ',': 213019e4a53SGreg Lehey thousands = 1; 214019e4a53SGreg Lehey break; 2154b88c807SRodney W. Grimes case '?': 2164b88c807SRodney W. Grimes default: 2174b88c807SRodney W. Grimes usage(); 2184b88c807SRodney W. Grimes } 2194b88c807SRodney W. Grimes argc -= optind; 2204b88c807SRodney W. Grimes argv += optind; 2214b88c807SRodney W. Grimes 222b8904f2aSJoerg Wunsch rv = 0; 2234b88c807SRodney W. Grimes if (!*argv) { 2247b0514faSDag-Erling Smørgrav /* everything (modulo -t) */ 2257b0514faSDag-Erling Smørgrav mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 226a78192e3SBruce Evans mntsize = regetmntinfo(&mntbuf, mntsize, vfslist); 2277b0514faSDag-Erling Smørgrav } else { 2287b0514faSDag-Erling Smørgrav /* just the filesystems specified on the command line */ 2297b0514faSDag-Erling Smørgrav mntbuf = malloc(argc * sizeof(*mntbuf)); 23011ed25f2SUlrich Spörlein if (mntbuf == NULL) 231b6ff8745SMarcel Moolenaar xo_err(1, "malloc()"); 2327b0514faSDag-Erling Smørgrav mntsize = 0; 2337b0514faSDag-Erling Smørgrav /* continued in for loop below */ 2344b88c807SRodney W. Grimes } 2354b88c807SRodney W. Grimes 236b6ff8745SMarcel Moolenaar xo_open_container("storage-system-information"); 237b6ff8745SMarcel Moolenaar xo_open_list("filesystem"); 238b6ff8745SMarcel Moolenaar 2397b0514faSDag-Erling Smørgrav /* iterate through specified filesystems */ 2404b88c807SRodney W. Grimes for (; *argv; argv++) { 2414b88c807SRodney W. Grimes if (stat(*argv, &stbuf) < 0) { 24211ed25f2SUlrich Spörlein if ((mntpt = getmntpt(*argv)) == NULL) { 243b6ff8745SMarcel Moolenaar xo_warn("%s", *argv); 244b8904f2aSJoerg Wunsch rv = 1; 2454b88c807SRodney W. Grimes continue; 2464b88c807SRodney W. Grimes } 247176d3efdSBrooks Davis #ifdef MOUNT_CHAR_DEVS 248f3895a82SKris Kennaway } else if (S_ISCHR(stbuf.st_mode)) { 24911ed25f2SUlrich Spörlein if ((mntpt = getmntpt(*argv)) == NULL) { 250f3895a82SKris Kennaway mdev.fspec = *argv; 251f3895a82SKris Kennaway mntpath = strdup("/tmp/df.XXXXXX"); 252f3895a82SKris Kennaway if (mntpath == NULL) { 253b6ff8745SMarcel Moolenaar xo_warn("strdup failed"); 254f3895a82SKris Kennaway rv = 1; 2554b88c807SRodney W. Grimes continue; 256f3895a82SKris Kennaway } 257f3895a82SKris Kennaway mntpt = mkdtemp(mntpath); 258f3895a82SKris Kennaway if (mntpt == NULL) { 259b6ff8745SMarcel Moolenaar xo_warn("mkdtemp(\"%s\") failed", mntpath); 260f3895a82SKris Kennaway rv = 1; 261f3895a82SKris Kennaway free(mntpath); 262f3895a82SKris Kennaway continue; 263f3895a82SKris Kennaway } 264facc3cb0SBrooks Davis if (iov != NULL) 265facc3cb0SBrooks Davis free_iovec(&iov, &iovlen); 266facc3cb0SBrooks Davis build_iovec_argf(&iov, &iovlen, "fstype", "%s", 267facc3cb0SBrooks Davis fstype); 268facc3cb0SBrooks Davis build_iovec_argf(&iov, &iovlen, "fspath", "%s", 269facc3cb0SBrooks Davis mntpath); 270facc3cb0SBrooks Davis build_iovec_argf(&iov, &iovlen, "from", "%s", 271facc3cb0SBrooks Davis *argv); 272facc3cb0SBrooks Davis build_iovec(&iov, &iovlen, "errmsg", errmsg, 273facc3cb0SBrooks Davis sizeof(errmsg)); 274facc3cb0SBrooks Davis if (nmount(iov, iovlen, 275facc3cb0SBrooks Davis MNT_RDONLY|MNT_NOEXEC) < 0) { 276facc3cb0SBrooks Davis if (errmsg[0]) 277facc3cb0SBrooks Davis xo_warn("%s: %s", *argv, 278facc3cb0SBrooks Davis errmsg); 279facc3cb0SBrooks Davis else 280b6ff8745SMarcel Moolenaar xo_warn("%s", *argv); 281532aff98SPoul-Henning Kamp rv = 1; 282f3895a82SKris Kennaway (void)rmdir(mntpt); 283f3895a82SKris Kennaway free(mntpath); 284f3895a82SKris Kennaway continue; 285f3895a82SKris Kennaway } else if (statfs(mntpt, &statfsbuf) == 0) { 286f3895a82SKris Kennaway statfsbuf.f_mntonname[0] = '\0'; 28762edbd31SIan Dowse prtstat(&statfsbuf, &maxwidths); 288076419d2SDavid E. O'Brien if (cflag) 289076419d2SDavid E. O'Brien addstat(&totalbuf, &statfsbuf); 290f3895a82SKris Kennaway } else { 291b6ff8745SMarcel Moolenaar xo_warn("%s", *argv); 292f3895a82SKris Kennaway rv = 1; 293f3895a82SKris Kennaway } 294f3895a82SKris Kennaway (void)unmount(mntpt, 0); 295f3895a82SKris Kennaway (void)rmdir(mntpt); 296f3895a82SKris Kennaway free(mntpath); 297f3895a82SKris Kennaway continue; 298f3895a82SKris Kennaway } 299176d3efdSBrooks Davis #endif 3004b88c807SRodney W. Grimes } else 3014b88c807SRodney W. Grimes mntpt = *argv; 3020e7d023fSBruce Evans 3034b88c807SRodney W. Grimes /* 3044b88c807SRodney W. Grimes * Statfs does not take a `wait' flag, so we cannot 3054b88c807SRodney W. Grimes * implement nflag here. 3064b88c807SRodney W. Grimes */ 3074b88c807SRodney W. Grimes if (statfs(mntpt, &statfsbuf) < 0) { 308b6ff8745SMarcel Moolenaar xo_warn("%s", mntpt); 309b8904f2aSJoerg Wunsch rv = 1; 3104b88c807SRodney W. Grimes continue; 3114b88c807SRodney W. Grimes } 3120e7d023fSBruce Evans 3130e7d023fSBruce Evans /* 3140e7d023fSBruce Evans * Check to make sure the arguments we've been given are 3150e7d023fSBruce Evans * satisfied. Return an error if we have been asked to 3160e7d023fSBruce Evans * list a mount point that does not match the other args 3170e7d023fSBruce Evans * we've been given (-l, -t, etc.). 318c22acefbSJordan K. Hubbard */ 319c22acefbSJordan K. Hubbard if (checkvfsname(statfsbuf.f_fstypename, vfslist)) { 3200e7d023fSBruce Evans rv = 1; 321c22acefbSJordan K. Hubbard continue; 322c22acefbSJordan K. Hubbard } 3230e7d023fSBruce Evans 3247b0514faSDag-Erling Smørgrav /* the user asked for it, so ignore the ignore flag */ 3257b0514faSDag-Erling Smørgrav statfsbuf.f_flags &= ~MNT_IGNORE; 3267b0514faSDag-Erling Smørgrav 3277b0514faSDag-Erling Smørgrav /* add to list */ 3287b0514faSDag-Erling Smørgrav mntbuf[mntsize++] = statfsbuf; 3297b0514faSDag-Erling Smørgrav } 3307b0514faSDag-Erling Smørgrav 33111ed25f2SUlrich Spörlein memset(&maxwidths, 0, sizeof(maxwidths)); 3327b0514faSDag-Erling Smørgrav for (i = 0; i < mntsize; i++) { 3337b0514faSDag-Erling Smørgrav if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) { 3347b0514faSDag-Erling Smørgrav update_maxwidths(&maxwidths, &mntbuf[i]); 335076419d2SDavid E. O'Brien if (cflag) 3367b0514faSDag-Erling Smørgrav addstat(&totalbuf, &mntbuf[i]); 3374b88c807SRodney W. Grimes } 3387b0514faSDag-Erling Smørgrav } 3397b0514faSDag-Erling Smørgrav for (i = 0; i < mntsize; i++) 3407b0514faSDag-Erling Smørgrav if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) 3417b0514faSDag-Erling Smørgrav prtstat(&mntbuf[i], &maxwidths); 342b6ff8745SMarcel Moolenaar 343b6ff8745SMarcel Moolenaar xo_close_list("filesystem"); 344b6ff8745SMarcel Moolenaar 345076419d2SDavid E. O'Brien if (cflag) 346076419d2SDavid E. O'Brien prtstat(&totalbuf, &maxwidths); 347b6ff8745SMarcel Moolenaar 348b6ff8745SMarcel Moolenaar xo_close_container("storage-system-information"); 349b6ff8745SMarcel Moolenaar xo_finish(); 350d5183594SXin LI exit(rv); 3514b88c807SRodney W. Grimes } 3524b88c807SRodney W. Grimes 353532aff98SPoul-Henning Kamp static char * 354b7dbd3e9SMark Murray getmntpt(const char *name) 3554b88c807SRodney W. Grimes { 356be2c4e54SDavid E. O'Brien size_t mntsize, i; 3574b88c807SRodney W. Grimes struct statfs *mntbuf; 3584b88c807SRodney W. Grimes 3594b88c807SRodney W. Grimes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 3604b88c807SRodney W. Grimes for (i = 0; i < mntsize; i++) { 3614b88c807SRodney W. Grimes if (!strcmp(mntbuf[i].f_mntfromname, name)) 3624b88c807SRodney W. Grimes return (mntbuf[i].f_mntonname); 3634b88c807SRodney W. Grimes } 36411ed25f2SUlrich Spörlein return (NULL); 3654b88c807SRodney W. Grimes } 3664b88c807SRodney W. Grimes 3674b88c807SRodney W. Grimes /* 3684b88c807SRodney W. Grimes * Make a pass over the file system info in ``mntbuf'' filtering out 369a78192e3SBruce Evans * file system types not in vfslist and possibly re-stating to get 3704b88c807SRodney W. Grimes * current (not cached) info. Returns the new count of valid statfs bufs. 3714b88c807SRodney W. Grimes */ 372be2c4e54SDavid E. O'Brien static size_t 373532aff98SPoul-Henning Kamp regetmntinfo(struct statfs **mntbufp, long mntsize, const char **vfslist) 3744b88c807SRodney W. Grimes { 375239c9e60SChristian S.J. Peron int error, i, j; 3764b88c807SRodney W. Grimes struct statfs *mntbuf; 3774b88c807SRodney W. Grimes 378a78192e3SBruce Evans if (vfslist == NULL) 3794b88c807SRodney W. Grimes return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT)); 3804b88c807SRodney W. Grimes 3814b88c807SRodney W. Grimes mntbuf = *mntbufp; 382a78192e3SBruce Evans for (j = 0, i = 0; i < mntsize; i++) { 383a78192e3SBruce Evans if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) 384a78192e3SBruce Evans continue; 385239c9e60SChristian S.J. Peron /* 386239c9e60SChristian S.J. Peron * XXX statfs(2) can fail for various reasons. It may be 387239c9e60SChristian S.J. Peron * possible that the user does not have access to the 388239c9e60SChristian S.J. Peron * pathname, if this happens, we will fall back on 389239c9e60SChristian S.J. Peron * "stale" filesystem statistics. 390239c9e60SChristian S.J. Peron */ 391239c9e60SChristian S.J. Peron error = statfs(mntbuf[i].f_mntonname, &mntbuf[j]); 392239c9e60SChristian S.J. Peron if (nflag || error < 0) 393239c9e60SChristian S.J. Peron if (i != j) { 394239c9e60SChristian S.J. Peron if (error < 0) 395b6ff8745SMarcel Moolenaar xo_warnx("%s stats possibly stale", 396239c9e60SChristian S.J. Peron mntbuf[i].f_mntonname); 3974b88c807SRodney W. Grimes mntbuf[j] = mntbuf[i]; 398239c9e60SChristian S.J. Peron } 3994b88c807SRodney W. Grimes j++; 4004b88c807SRodney W. Grimes } 4014b88c807SRodney W. Grimes return (j); 4024b88c807SRodney W. Grimes } 4034b88c807SRodney W. Grimes 404532aff98SPoul-Henning Kamp static void 405fde81c7dSKirk McKusick prthuman(const struct statfs *sfsp, int64_t used) 406dd6d33e8SMichael Haro { 407dd6d33e8SMichael Haro 408b6ff8745SMarcel Moolenaar prthumanval(" {:blocks/%6s}", sfsp->f_blocks * sfsp->f_bsize); 409b6ff8745SMarcel Moolenaar prthumanval(" {:used/%6s}", used * sfsp->f_bsize); 410b6ff8745SMarcel Moolenaar prthumanval(" {:available/%6s}", sfsp->f_bavail * sfsp->f_bsize); 411dd6d33e8SMichael Haro } 412dd6d33e8SMichael Haro 413532aff98SPoul-Henning Kamp static void 414b6ff8745SMarcel Moolenaar prthumanval(const char *fmt, int64_t bytes) 415dd6d33e8SMichael Haro { 4167d3940bbSPawel Jakub Dawidek char buf[6]; 4177d3940bbSPawel Jakub Dawidek int flags; 418dd6d33e8SMichael Haro 4197d3940bbSPawel Jakub Dawidek flags = HN_B | HN_NOSPACE | HN_DECIMAL; 4207d3940bbSPawel Jakub Dawidek if (hflag == UNITS_SI) 4217d3940bbSPawel Jakub Dawidek flags |= HN_DIVISOR_1000; 422dd6d33e8SMichael Haro 4237d3940bbSPawel Jakub Dawidek humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), 4247d3940bbSPawel Jakub Dawidek bytes, "", HN_AUTOSCALE, flags); 4257d3940bbSPawel Jakub Dawidek 426b6ff8745SMarcel Moolenaar xo_attr("value", "%lld", (long long) bytes); 427b6ff8745SMarcel Moolenaar xo_emit(fmt, buf); 428dd6d33e8SMichael Haro } 429dd6d33e8SMichael Haro 430dd6d33e8SMichael Haro /* 431b93ce3b7SSimon L. B. Nielsen * Print an inode count in "human-readable" format. 432b93ce3b7SSimon L. B. Nielsen */ 433b93ce3b7SSimon L. B. Nielsen static void 434b6ff8745SMarcel Moolenaar prthumanvalinode(const char *fmt, int64_t bytes) 435b93ce3b7SSimon L. B. Nielsen { 436b93ce3b7SSimon L. B. Nielsen char buf[6]; 437b93ce3b7SSimon L. B. Nielsen int flags; 438b93ce3b7SSimon L. B. Nielsen 439b93ce3b7SSimon L. B. Nielsen flags = HN_NOSPACE | HN_DECIMAL | HN_DIVISOR_1000; 440b93ce3b7SSimon L. B. Nielsen 441b93ce3b7SSimon L. B. Nielsen humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), 442b93ce3b7SSimon L. B. Nielsen bytes, "", HN_AUTOSCALE, flags); 443b93ce3b7SSimon L. B. Nielsen 444b6ff8745SMarcel Moolenaar xo_attr("value", "%lld", (long long) bytes); 445b6ff8745SMarcel Moolenaar xo_emit(fmt, buf); 446b93ce3b7SSimon L. B. Nielsen } 447b93ce3b7SSimon L. B. Nielsen 448b93ce3b7SSimon L. B. Nielsen /* 4494b88c807SRodney W. Grimes * Convert statfs returned file system size into BLOCKSIZE units. 4504b88c807SRodney W. Grimes */ 451841fe8e8SDavid Schultz static intmax_t 452841fe8e8SDavid Schultz fsbtoblk(int64_t num, uint64_t fsbs, u_long bs) 453841fe8e8SDavid Schultz { 4546b7aceb8SGreg Lehey return (num * (intmax_t) fsbs / (int64_t) bs); 455841fe8e8SDavid Schultz } 4564b88c807SRodney W. Grimes 4574b88c807SRodney W. Grimes /* 4584b88c807SRodney W. Grimes * Print out status about a file system. 4594b88c807SRodney W. Grimes */ 460532aff98SPoul-Henning Kamp static void 46162edbd31SIan Dowse prtstat(struct statfs *sfsp, struct maxwidths *mwp) 4624b88c807SRodney W. Grimes { 4632897dce8SAlexander Kabaev static long blocksize; 464b7dbd3e9SMark Murray static int headerlen, timesthrough = 0; 465a95a13bbSKris Kennaway static const char *header; 466fde81c7dSKirk McKusick int64_t used, availblks, inodes; 467019e4a53SGreg Lehey const char *format; 4684b88c807SRodney W. Grimes 4694b88c807SRodney W. Grimes if (++timesthrough == 1) { 4700bd9f151SIan Dowse mwp->mntfrom = imax(mwp->mntfrom, (int)strlen("Filesystem")); 471b56ca465SPawel Jakub Dawidek mwp->fstype = imax(mwp->fstype, (int)strlen("Type")); 472019e4a53SGreg Lehey if (thousands) { /* make space for commas */ 473019e4a53SGreg Lehey mwp->total += (mwp->total - 1) / 3; 474019e4a53SGreg Lehey mwp->used += (mwp->used - 1) / 3; 475019e4a53SGreg Lehey mwp->avail += (mwp->avail - 1) / 3; 476019e4a53SGreg Lehey mwp->iused += (mwp->iused - 1) / 3; 477019e4a53SGreg Lehey mwp->ifree += (mwp->ifree - 1) / 3; 478019e4a53SGreg Lehey } 479dd6d33e8SMichael Haro if (hflag) { 480dd6d33e8SMichael Haro header = " Size"; 4810bd9f151SIan Dowse mwp->total = mwp->used = mwp->avail = 4820bd9f151SIan Dowse (int)strlen(header); 483dd6d33e8SMichael Haro } else { 484dd6d33e8SMichael Haro header = getbsize(&headerlen, &blocksize); 4850bd9f151SIan Dowse mwp->total = imax(mwp->total, headerlen); 486dd6d33e8SMichael Haro } 4870bd9f151SIan Dowse mwp->used = imax(mwp->used, (int)strlen("Used")); 4880bd9f151SIan Dowse mwp->avail = imax(mwp->avail, (int)strlen("Avail")); 48962edbd31SIan Dowse 490b6ff8745SMarcel Moolenaar xo_emit("{T:/%-*s}", mwp->mntfrom, "Filesystem"); 491b56ca465SPawel Jakub Dawidek if (Tflag) 492b6ff8745SMarcel Moolenaar xo_emit(" {T:/%-*s}", mwp->fstype, "Type"); 493b6ff8745SMarcel Moolenaar xo_emit(" {T:/%*s} {T:/%*s} {T:/%*s} Capacity", 494b6ff8745SMarcel Moolenaar mwp->total, header, 4950bd9f151SIan Dowse mwp->used, "Used", mwp->avail, "Avail"); 49662edbd31SIan Dowse if (iflag) { 497b93ce3b7SSimon L. B. Nielsen mwp->iused = imax(hflag ? 0 : mwp->iused, 498b93ce3b7SSimon L. B. Nielsen (int)strlen(" iused")); 499b93ce3b7SSimon L. B. Nielsen mwp->ifree = imax(hflag ? 0 : mwp->ifree, 500b93ce3b7SSimon L. B. Nielsen (int)strlen("ifree")); 501b6ff8745SMarcel Moolenaar xo_emit(" {T:/%*s} {T:/%*s} {T:\%iused}", 5020bd9f151SIan Dowse mwp->iused - 2, "iused", mwp->ifree, "ifree"); 50362edbd31SIan Dowse } 504b6ff8745SMarcel Moolenaar xo_emit(" {T:Mounted on}\n"); 5054b88c807SRodney W. Grimes } 506b6ff8745SMarcel Moolenaar 507b6ff8745SMarcel Moolenaar xo_open_instance("filesystem"); 50871cfc678SGreg Lehey /* Check for 0 block size. Can this happen? */ 50971cfc678SGreg Lehey if (sfsp->f_bsize == 0) { 510b6ff8745SMarcel Moolenaar xo_warnx ("File system %s does not have a block size, assuming 512.", 51171cfc678SGreg Lehey sfsp->f_mntonname); 51271cfc678SGreg Lehey sfsp->f_bsize = 512; 51371cfc678SGreg Lehey } 514b6ff8745SMarcel Moolenaar xo_emit("{tk:name/%-*s}", mwp->mntfrom, sfsp->f_mntfromname); 515b56ca465SPawel Jakub Dawidek if (Tflag) 516b6ff8745SMarcel Moolenaar xo_emit(" {:type/%-*s}", mwp->fstype, sfsp->f_fstypename); 5174b88c807SRodney W. Grimes used = sfsp->f_blocks - sfsp->f_bfree; 5184b88c807SRodney W. Grimes availblks = sfsp->f_bavail + used; 519dd6d33e8SMichael Haro if (hflag) { 520dd6d33e8SMichael Haro prthuman(sfsp, used); 521dd6d33e8SMichael Haro } else { 522019e4a53SGreg Lehey if (thousands) 523b6ff8745SMarcel Moolenaar format = " {t:total-blocks/%*j'd} {t:used-blocks/%*j'd} " 524b6ff8745SMarcel Moolenaar "{t:available-blocks/%*j'd}"; 525019e4a53SGreg Lehey else 526b6ff8745SMarcel Moolenaar format = " {t:total-blocks/%*jd} {t:used-blocks/%*jd} " 527b6ff8745SMarcel Moolenaar "{t:available-blocks/%*jd}"; 528b6ff8745SMarcel Moolenaar xo_emit(format, 529841fe8e8SDavid Schultz mwp->total, fsbtoblk(sfsp->f_blocks, 5300bd9f151SIan Dowse sfsp->f_bsize, blocksize), 531841fe8e8SDavid Schultz mwp->used, fsbtoblk(used, sfsp->f_bsize, blocksize), 532841fe8e8SDavid Schultz mwp->avail, fsbtoblk(sfsp->f_bavail, 5330bd9f151SIan Dowse sfsp->f_bsize, blocksize)); 534dd6d33e8SMichael Haro } 535b6ff8745SMarcel Moolenaar xo_emit(" {:used-percent/%5.0f}{U:%%}", 5364b88c807SRodney W. Grimes availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0); 5374b88c807SRodney W. Grimes if (iflag) { 5384b88c807SRodney W. Grimes inodes = sfsp->f_files; 5394b88c807SRodney W. Grimes used = inodes - sfsp->f_ffree; 540b93ce3b7SSimon L. B. Nielsen if (hflag) { 541b6ff8745SMarcel Moolenaar xo_emit(" "); 542b6ff8745SMarcel Moolenaar prthumanvalinode(" {:inodes-used/%5s}", used); 543b6ff8745SMarcel Moolenaar prthumanvalinode(" {:inodes-free/%5s}", sfsp->f_ffree); 544b93ce3b7SSimon L. B. Nielsen } else { 545019e4a53SGreg Lehey if (thousands) 546b6ff8745SMarcel Moolenaar format = " {:inodes-used/%*j'd} {:inodes-free/%*j'd}"; 547019e4a53SGreg Lehey else 548b6ff8745SMarcel Moolenaar format = " {:inodes-used/%*jd} {:inodes-free/%*jd}"; 549b6ff8745SMarcel Moolenaar xo_emit(format, mwp->iused, (intmax_t)used, 550b93ce3b7SSimon L. B. Nielsen mwp->ifree, (intmax_t)sfsp->f_ffree); 551b93ce3b7SSimon L. B. Nielsen } 552b6ff8745SMarcel Moolenaar xo_emit(" {:inodes-used-percent/%4.0f}{U:%%} ", 553b6ff8745SMarcel Moolenaar inodes == 0 ? 100.0 : 5540bd9f151SIan Dowse (double)used / (double)inodes * 100.0); 555cca108e6SDavid E. O'Brien } else 556b6ff8745SMarcel Moolenaar xo_emit(" "); 557c6f13844SDavid E. O'Brien if (strncmp(sfsp->f_mntfromname, "total", MNAMELEN) != 0) 558b6ff8745SMarcel Moolenaar xo_emit(" {:mounted-on}", sfsp->f_mntonname); 559b6ff8745SMarcel Moolenaar xo_emit("\n"); 560b6ff8745SMarcel Moolenaar xo_close_instance("filesystem"); 561076419d2SDavid E. O'Brien } 562076419d2SDavid E. O'Brien 563431586a8SXin LI static void 564076419d2SDavid E. O'Brien addstat(struct statfs *totalfsp, struct statfs *statfsp) 565076419d2SDavid E. O'Brien { 566c6f13844SDavid E. O'Brien uint64_t bsize; 567076419d2SDavid E. O'Brien 568c6f13844SDavid E. O'Brien bsize = statfsp->f_bsize / totalfsp->f_bsize; 569076419d2SDavid E. O'Brien totalfsp->f_blocks += statfsp->f_blocks * bsize; 570076419d2SDavid E. O'Brien totalfsp->f_bfree += statfsp->f_bfree * bsize; 571076419d2SDavid E. O'Brien totalfsp->f_bavail += statfsp->f_bavail * bsize; 572076419d2SDavid E. O'Brien totalfsp->f_files += statfsp->f_files; 573076419d2SDavid E. O'Brien totalfsp->f_ffree += statfsp->f_ffree; 5744b88c807SRodney W. Grimes } 5754b88c807SRodney W. Grimes 5764b88c807SRodney W. Grimes /* 57762edbd31SIan Dowse * Update the maximum field-width information in `mwp' based on 57862edbd31SIan Dowse * the file system specified by `sfsp'. 57962edbd31SIan Dowse */ 580532aff98SPoul-Henning Kamp static void 581b7dbd3e9SMark Murray update_maxwidths(struct maxwidths *mwp, const struct statfs *sfsp) 58262edbd31SIan Dowse { 5832897dce8SAlexander Kabaev static long blocksize = 0; 584dc474219SMike Barcroft int dummy; 58562edbd31SIan Dowse 58662edbd31SIan Dowse if (blocksize == 0) 58762edbd31SIan Dowse getbsize(&dummy, &blocksize); 58862edbd31SIan Dowse 5890bd9f151SIan Dowse mwp->mntfrom = imax(mwp->mntfrom, (int)strlen(sfsp->f_mntfromname)); 590b56ca465SPawel Jakub Dawidek mwp->fstype = imax(mwp->fstype, (int)strlen(sfsp->f_fstypename)); 5910bd9f151SIan Dowse mwp->total = imax(mwp->total, int64width( 592fde81c7dSKirk McKusick fsbtoblk((int64_t)sfsp->f_blocks, sfsp->f_bsize, blocksize))); 5930bd9f151SIan Dowse mwp->used = imax(mwp->used, 5940bd9f151SIan Dowse int64width(fsbtoblk((int64_t)sfsp->f_blocks - 595fde81c7dSKirk McKusick (int64_t)sfsp->f_bfree, sfsp->f_bsize, blocksize))); 5960bd9f151SIan Dowse mwp->avail = imax(mwp->avail, int64width(fsbtoblk(sfsp->f_bavail, 59762edbd31SIan Dowse sfsp->f_bsize, blocksize))); 5980bd9f151SIan Dowse mwp->iused = imax(mwp->iused, int64width((int64_t)sfsp->f_files - 59962edbd31SIan Dowse sfsp->f_ffree)); 6000bd9f151SIan Dowse mwp->ifree = imax(mwp->ifree, int64width(sfsp->f_ffree)); 60162edbd31SIan Dowse } 60262edbd31SIan Dowse 6030bd9f151SIan Dowse /* Return the width in characters of the specified value. */ 6040bd9f151SIan Dowse static int 605fde81c7dSKirk McKusick int64width(int64_t val) 60662edbd31SIan Dowse { 6070bd9f151SIan Dowse int len; 60862edbd31SIan Dowse 60962edbd31SIan Dowse len = 0; 61062edbd31SIan Dowse /* Negative or zero values require one extra digit. */ 61162edbd31SIan Dowse if (val <= 0) { 61262edbd31SIan Dowse val = -val; 61362edbd31SIan Dowse len++; 61462edbd31SIan Dowse } 61562edbd31SIan Dowse while (val > 0) { 61662edbd31SIan Dowse len++; 61762edbd31SIan Dowse val /= 10; 61862edbd31SIan Dowse } 61962edbd31SIan Dowse 62062edbd31SIan Dowse return (len); 62162edbd31SIan Dowse } 62262edbd31SIan Dowse 623532aff98SPoul-Henning Kamp static void 624f9bcb0beSWarner Losh usage(void) 6254b88c807SRodney W. Grimes { 626dd6d33e8SMichael Haro 627b6ff8745SMarcel Moolenaar xo_error( 6287eb55d4dSXin LI "usage: df [-b | -g | -H | -h | -k | -m | -P] [-acilnT] [-t type] [-,]\n" 6297eb55d4dSXin LI " [file | filesystem ...]\n"); 630dd6d33e8SMichael Haro exit(EX_USAGE); 6314b88c807SRodney W. Grimes } 632a25695c3SJim Pirzyk 633532aff98SPoul-Henning Kamp static char * 634f9bcb0beSWarner Losh makenetvfslist(void) 635a25695c3SJim Pirzyk { 636a25695c3SJim Pirzyk char *str, *strptr, **listptr; 637b7dbd3e9SMark Murray struct xvfsconf *xvfsp, *keep_xvfsp; 6385965373eSMaxime Henrion size_t buflen; 6395965373eSMaxime Henrion int cnt, i, maxvfsconf; 640a25695c3SJim Pirzyk 6415965373eSMaxime Henrion if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) { 642b6ff8745SMarcel Moolenaar xo_warn("sysctl(vfs.conflist)"); 643a25695c3SJim Pirzyk return (NULL); 644a25695c3SJim Pirzyk } 6455965373eSMaxime Henrion xvfsp = malloc(buflen); 6465965373eSMaxime Henrion if (xvfsp == NULL) { 647b6ff8745SMarcel Moolenaar xo_warnx("malloc failed"); 6485965373eSMaxime Henrion return (NULL); 6495965373eSMaxime Henrion } 650b7dbd3e9SMark Murray keep_xvfsp = xvfsp; 6515965373eSMaxime Henrion if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) { 652b6ff8745SMarcel Moolenaar xo_warn("sysctl(vfs.conflist)"); 653b7dbd3e9SMark Murray free(keep_xvfsp); 6545965373eSMaxime Henrion return (NULL); 6555965373eSMaxime Henrion } 6565965373eSMaxime Henrion maxvfsconf = buflen / sizeof(struct xvfsconf); 657a25695c3SJim Pirzyk 658a25695c3SJim Pirzyk if ((listptr = malloc(sizeof(char*) * maxvfsconf)) == NULL) { 659b6ff8745SMarcel Moolenaar xo_warnx("malloc failed"); 660b7dbd3e9SMark Murray free(keep_xvfsp); 661a25695c3SJim Pirzyk return (NULL); 662a25695c3SJim Pirzyk } 663a25695c3SJim Pirzyk 6645965373eSMaxime Henrion for (cnt = 0, i = 0; i < maxvfsconf; i++) { 6655965373eSMaxime Henrion if (xvfsp->vfc_flags & VFCF_NETWORK) { 6665965373eSMaxime Henrion listptr[cnt++] = strdup(xvfsp->vfc_name); 667a067aeceSGarrett Wollman if (listptr[cnt-1] == NULL) { 668b6ff8745SMarcel Moolenaar xo_warnx("malloc failed"); 669b7dbd3e9SMark Murray free(listptr); 670b7dbd3e9SMark Murray free(keep_xvfsp); 671a25695c3SJim Pirzyk return (NULL); 672a25695c3SJim Pirzyk } 673a25695c3SJim Pirzyk } 6745965373eSMaxime Henrion xvfsp++; 6755965373eSMaxime Henrion } 676a25695c3SJim Pirzyk 677cf5b29e1SRuslan Ermilov if (cnt == 0 || 678cf5b29e1SRuslan Ermilov (str = malloc(sizeof(char) * (32 * cnt + cnt + 2))) == NULL) { 679cf5b29e1SRuslan Ermilov if (cnt > 0) 680b6ff8745SMarcel Moolenaar xo_warnx("malloc failed"); 681a25695c3SJim Pirzyk free(listptr); 682b7dbd3e9SMark Murray free(keep_xvfsp); 683a25695c3SJim Pirzyk return (NULL); 684a25695c3SJim Pirzyk } 685a25695c3SJim Pirzyk 686a25695c3SJim Pirzyk *str = 'n'; *(str + 1) = 'o'; 687a25695c3SJim Pirzyk for (i = 0, strptr = str + 2; i < cnt; i++, strptr++) { 688d7c881e8SWarner Losh strlcpy(strptr, listptr[i], 32); 689a25695c3SJim Pirzyk strptr += strlen(listptr[i]); 690a25695c3SJim Pirzyk *strptr = ','; 691a25695c3SJim Pirzyk free(listptr[i]); 692a25695c3SJim Pirzyk } 69316fc3635SMark Murray *(--strptr) = '\0'; 694a25695c3SJim Pirzyk 695b7dbd3e9SMark Murray free(keep_xvfsp); 696a25695c3SJim Pirzyk free(listptr); 697a25695c3SJim Pirzyk return (str); 698a25695c3SJim Pirzyk } 699