1994-05-26 06:18:55 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 1980, 1990, 1993, 1994
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
* (c) UNIX System Laboratories, Inc.
|
|
|
|
* All or some portions of this file are derived from material licensed
|
|
|
|
* to the University of California by American Telephone and Telegraph
|
|
|
|
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
|
|
|
* the permission of UNIX System Laboratories, Inc.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2003-05-01 16:58:57 +00:00
|
|
|
#if 0
|
1994-05-26 06:18:55 +00:00
|
|
|
#ifndef lint
|
1997-08-07 21:31:00 +00:00
|
|
|
static const char copyright[] =
|
1994-05-26 06:18:55 +00:00
|
|
|
"@(#) Copyright (c) 1980, 1990, 1993, 1994\n\
|
|
|
|
The Regents of the University of California. All rights reserved.\n";
|
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
#ifndef lint
|
1997-08-07 21:31:00 +00:00
|
|
|
static char sccsid[] = "@(#)df.c 8.9 (Berkeley) 5/8/95";
|
1994-05-26 06:18:55 +00:00
|
|
|
#endif /* not lint */
|
2003-05-01 16:58:57 +00:00
|
|
|
#endif
|
2002-06-30 05:13:54 +00:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
1994-05-26 06:18:55 +00:00
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/mount.h>
|
2001-06-04 23:07:15 +00:00
|
|
|
#include <sys/sysctl.h>
|
1997-03-13 17:41:37 +00:00
|
|
|
#include <ufs/ufs/ufsmount.h>
|
1994-05-26 06:18:55 +00:00
|
|
|
#include <err.h>
|
1999-12-15 03:44:09 +00:00
|
|
|
#include <math.h>
|
2004-02-08 23:42:09 +00:00
|
|
|
#include <stdint.h>
|
1994-05-26 06:18:55 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
1999-12-15 03:44:09 +00:00
|
|
|
#include <sysexits.h>
|
1994-05-26 06:18:55 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
|
2002-05-12 19:24:09 +00:00
|
|
|
#include "extern.h"
|
|
|
|
|
1999-12-15 03:44:09 +00:00
|
|
|
#define UNITS_SI 1
|
|
|
|
#define UNITS_2 2
|
|
|
|
|
|
|
|
#define KILO_SZ(n) (n)
|
|
|
|
#define MEGA_SZ(n) ((n) * (n))
|
|
|
|
#define GIGA_SZ(n) ((n) * (n) * (n))
|
|
|
|
#define TERA_SZ(n) ((n) * (n) * (n) * (n))
|
|
|
|
#define PETA_SZ(n) ((n) * (n) * (n) * (n) * (n))
|
|
|
|
|
|
|
|
#define KILO_2_SZ (KILO_SZ(1024ULL))
|
|
|
|
#define MEGA_2_SZ (MEGA_SZ(1024ULL))
|
|
|
|
#define GIGA_2_SZ (GIGA_SZ(1024ULL))
|
|
|
|
#define TERA_2_SZ (TERA_SZ(1024ULL))
|
|
|
|
#define PETA_2_SZ (PETA_SZ(1024ULL))
|
|
|
|
|
|
|
|
#define KILO_SI_SZ (KILO_SZ(1000ULL))
|
|
|
|
#define MEGA_SI_SZ (MEGA_SZ(1000ULL))
|
|
|
|
#define GIGA_SI_SZ (GIGA_SZ(1000ULL))
|
|
|
|
#define TERA_SI_SZ (TERA_SZ(1000ULL))
|
|
|
|
#define PETA_SI_SZ (PETA_SZ(1000ULL))
|
|
|
|
|
2002-03-26 20:32:37 +00:00
|
|
|
/* Maximum widths of various fields. */
|
|
|
|
struct maxwidths {
|
2004-02-08 23:42:09 +00:00
|
|
|
int mntfrom;
|
|
|
|
int total;
|
|
|
|
int used;
|
|
|
|
int avail;
|
|
|
|
int iused;
|
|
|
|
int ifree;
|
2002-03-26 20:32:37 +00:00
|
|
|
};
|
|
|
|
|
2003-05-03 10:21:26 +00:00
|
|
|
static uintmax_t vals_si [] = {
|
|
|
|
1,
|
|
|
|
KILO_SI_SZ,
|
|
|
|
MEGA_SI_SZ,
|
|
|
|
GIGA_SI_SZ,
|
|
|
|
TERA_SI_SZ,
|
|
|
|
PETA_SI_SZ
|
|
|
|
};
|
|
|
|
static uintmax_t vals_base2[] = {
|
|
|
|
1,
|
|
|
|
KILO_2_SZ,
|
|
|
|
MEGA_2_SZ,
|
|
|
|
GIGA_2_SZ,
|
|
|
|
TERA_2_SZ,
|
|
|
|
PETA_2_SZ
|
|
|
|
};
|
|
|
|
static uintmax_t *valp;
|
1999-12-15 03:44:09 +00:00
|
|
|
|
|
|
|
typedef enum { NONE, KILO, MEGA, GIGA, TERA, PETA, UNIT_MAX } unit_t;
|
|
|
|
|
2003-05-03 10:21:26 +00:00
|
|
|
static unit_t unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA };
|
1999-12-15 03:44:09 +00:00
|
|
|
|
2003-05-03 10:21:26 +00:00
|
|
|
static char *getmntpt(const char *);
|
2004-02-08 23:42:09 +00:00
|
|
|
static int int64width(int64_t);
|
2002-05-12 19:24:09 +00:00
|
|
|
static char *makenetvfslist(void);
|
2003-11-12 08:01:40 +00:00
|
|
|
static void prthuman(const struct statfs *, int64_t);
|
2002-05-12 19:24:09 +00:00
|
|
|
static void prthumanval(double);
|
|
|
|
static void prtstat(struct statfs *, struct maxwidths *);
|
2004-04-18 20:56:31 +00:00
|
|
|
static void addstat(struct statfs *, struct statfs *);
|
2003-09-13 20:46:58 +00:00
|
|
|
static size_t regetmntinfo(struct statfs **, long, const char **);
|
2002-05-12 19:24:09 +00:00
|
|
|
static unit_t unit_adjust(double *);
|
2003-05-03 10:21:26 +00:00
|
|
|
static void update_maxwidths(struct maxwidths *, const struct statfs *);
|
2002-05-12 19:24:09 +00:00
|
|
|
static void usage(void);
|
|
|
|
|
2004-02-08 23:42:09 +00:00
|
|
|
static __inline int
|
|
|
|
imax(int a, int b)
|
2002-03-26 20:32:37 +00:00
|
|
|
{
|
2003-05-03 10:21:26 +00:00
|
|
|
return (a > b ? a : b);
|
2002-03-26 20:32:37 +00:00
|
|
|
}
|
|
|
|
|
2004-04-18 20:56:31 +00:00
|
|
|
static int aflag = 0, cflag, hflag, iflag, nflag;
|
2002-05-12 19:24:09 +00:00
|
|
|
static struct ufs_args mdev;
|
|
|
|
|
1994-05-26 06:18:55 +00:00
|
|
|
int
|
2002-02-02 06:24:13 +00:00
|
|
|
main(int argc, char *argv[])
|
1994-05-26 06:18:55 +00:00
|
|
|
{
|
|
|
|
struct stat stbuf;
|
2004-04-18 20:56:31 +00:00
|
|
|
struct statfs statfsbuf, totalbuf, *mntbuf;
|
2002-03-26 20:32:37 +00:00
|
|
|
struct maxwidths maxwidths;
|
2001-05-20 04:12:30 +00:00
|
|
|
const char *fstype;
|
2002-05-12 19:24:09 +00:00
|
|
|
char *mntpath, *mntpt;
|
|
|
|
const char **vfslist;
|
2003-09-13 20:46:58 +00:00
|
|
|
size_t i, mntsize;
|
|
|
|
int ch, rv;
|
2001-05-09 08:44:15 +00:00
|
|
|
|
|
|
|
fstype = "ufs";
|
1994-08-12 07:26:52 +00:00
|
|
|
|
2004-04-18 20:56:31 +00:00
|
|
|
memset (&totalbuf, 0, sizeof (totalbuf));
|
|
|
|
totalbuf.f_bsize = DEV_BSIZE;
|
|
|
|
strncpy (totalbuf.f_mntfromname, "total", MNAMELEN);
|
1997-03-13 17:41:37 +00:00
|
|
|
vfslist = NULL;
|
2004-04-18 20:56:31 +00:00
|
|
|
while ((ch = getopt(argc, argv, "abcgHhiklmnPt:")) != -1)
|
1994-05-26 06:18:55 +00:00
|
|
|
switch (ch) {
|
1999-11-01 04:57:43 +00:00
|
|
|
case 'a':
|
|
|
|
aflag = 1;
|
|
|
|
break;
|
2004-04-18 20:56:31 +00:00
|
|
|
case 'c':
|
|
|
|
cflag = 1;
|
|
|
|
break;
|
1999-12-15 03:44:09 +00:00
|
|
|
case 'b':
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
case 'P':
|
|
|
|
putenv("BLOCKSIZE=512");
|
|
|
|
hflag = 0;
|
|
|
|
break;
|
2000-06-03 20:17:39 +00:00
|
|
|
case 'g':
|
|
|
|
putenv("BLOCKSIZE=1g");
|
|
|
|
hflag = 0;
|
|
|
|
break;
|
1999-12-15 03:44:09 +00:00
|
|
|
case 'H':
|
|
|
|
hflag = UNITS_SI;
|
|
|
|
valp = vals_si;
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
hflag = UNITS_2;
|
|
|
|
valp = vals_base2;
|
|
|
|
break;
|
1994-05-26 06:18:55 +00:00
|
|
|
case 'i':
|
|
|
|
iflag = 1;
|
|
|
|
break;
|
1994-08-10 19:21:07 +00:00
|
|
|
case 'k':
|
1994-08-12 10:23:49 +00:00
|
|
|
putenv("BLOCKSIZE=1k");
|
1999-12-15 03:44:09 +00:00
|
|
|
hflag = 0;
|
|
|
|
break;
|
2001-06-04 23:07:15 +00:00
|
|
|
case 'l':
|
|
|
|
if (vfslist != NULL)
|
|
|
|
errx(1, "-l and -t are mutually exclusive.");
|
|
|
|
vfslist = makevfslist(makenetvfslist());
|
|
|
|
break;
|
1999-12-15 03:44:09 +00:00
|
|
|
case 'm':
|
|
|
|
putenv("BLOCKSIZE=1m");
|
|
|
|
hflag = 0;
|
1994-08-10 19:21:07 +00:00
|
|
|
break;
|
1994-05-26 06:18:55 +00:00
|
|
|
case 'n':
|
|
|
|
nflag = 1;
|
|
|
|
break;
|
|
|
|
case 't':
|
1997-03-13 17:41:37 +00:00
|
|
|
if (vfslist != NULL)
|
2001-12-11 18:22:01 +00:00
|
|
|
errx(1, "only one -t option may be specified");
|
2001-08-01 02:09:09 +00:00
|
|
|
fstype = optarg;
|
1997-03-13 17:41:37 +00:00
|
|
|
vfslist = makevfslist(optarg);
|
1994-05-26 06:18:55 +00:00
|
|
|
break;
|
|
|
|
case '?':
|
|
|
|
default:
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
argc -= optind;
|
|
|
|
argv += optind;
|
|
|
|
|
|
|
|
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
2002-03-26 20:32:37 +00:00
|
|
|
bzero(&maxwidths, sizeof(maxwidths));
|
|
|
|
for (i = 0; i < mntsize; i++)
|
|
|
|
update_maxwidths(&maxwidths, &mntbuf[i]);
|
1994-05-26 06:18:55 +00:00
|
|
|
|
1997-10-12 13:55:43 +00:00
|
|
|
rv = 0;
|
1994-05-26 06:18:55 +00:00
|
|
|
if (!*argv) {
|
1997-03-13 17:41:37 +00:00
|
|
|
mntsize = regetmntinfo(&mntbuf, mntsize, vfslist);
|
2002-05-18 21:10:40 +00:00
|
|
|
bzero(&maxwidths, sizeof(maxwidths));
|
1999-11-01 04:57:43 +00:00
|
|
|
for (i = 0; i < mntsize; i++) {
|
2004-04-18 20:56:31 +00:00
|
|
|
if (cflag)
|
|
|
|
addstat(&totalbuf, &mntbuf[i]);
|
|
|
|
update_maxwidths(&maxwidths, &mntbuf[i]);
|
|
|
|
}
|
|
|
|
if (cflag)
|
|
|
|
update_maxwidths(&maxwidths, &totalbuf);
|
|
|
|
for (i = 0; i < mntsize; i++)
|
1999-11-01 04:57:43 +00:00
|
|
|
if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0)
|
2002-03-26 20:32:37 +00:00
|
|
|
prtstat(&mntbuf[i], &maxwidths);
|
2004-04-18 20:56:31 +00:00
|
|
|
if (cflag)
|
|
|
|
prtstat(&totalbuf, &maxwidths);
|
1997-10-12 13:55:43 +00:00
|
|
|
exit(rv);
|
1994-05-26 06:18:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (; *argv; argv++) {
|
|
|
|
if (stat(*argv, &stbuf) < 0) {
|
|
|
|
if ((mntpt = getmntpt(*argv)) == 0) {
|
|
|
|
warn("%s", *argv);
|
1997-10-12 13:55:43 +00:00
|
|
|
rv = 1;
|
1994-05-26 06:18:55 +00:00
|
|
|
continue;
|
|
|
|
}
|
2001-05-09 08:44:15 +00:00
|
|
|
} else if (S_ISCHR(stbuf.st_mode)) {
|
|
|
|
if ((mntpt = getmntpt(*argv)) == 0) {
|
|
|
|
mdev.fspec = *argv;
|
|
|
|
mntpath = strdup("/tmp/df.XXXXXX");
|
|
|
|
if (mntpath == NULL) {
|
|
|
|
warn("strdup failed");
|
|
|
|
rv = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
mntpt = mkdtemp(mntpath);
|
|
|
|
if (mntpt == NULL) {
|
|
|
|
warn("mkdtemp(\"%s\") failed", mntpath);
|
|
|
|
rv = 1;
|
|
|
|
free(mntpath);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (mount(fstype, mntpt, MNT_RDONLY,
|
|
|
|
&mdev) != 0) {
|
2002-05-12 19:24:09 +00:00
|
|
|
warn("%s", *argv);
|
|
|
|
rv = 1;
|
2001-05-09 08:44:15 +00:00
|
|
|
(void)rmdir(mntpt);
|
|
|
|
free(mntpath);
|
|
|
|
continue;
|
|
|
|
} else if (statfs(mntpt, &statfsbuf) == 0) {
|
|
|
|
statfsbuf.f_mntonname[0] = '\0';
|
2002-03-26 20:32:37 +00:00
|
|
|
prtstat(&statfsbuf, &maxwidths);
|
2004-04-18 20:56:31 +00:00
|
|
|
if (cflag)
|
|
|
|
addstat(&totalbuf, &statfsbuf);
|
2001-05-09 08:44:15 +00:00
|
|
|
} else {
|
|
|
|
warn("%s", *argv);
|
|
|
|
rv = 1;
|
|
|
|
}
|
|
|
|
(void)unmount(mntpt, 0);
|
|
|
|
(void)rmdir(mntpt);
|
|
|
|
free(mntpath);
|
|
|
|
continue;
|
|
|
|
}
|
1994-05-26 06:18:55 +00:00
|
|
|
} else
|
|
|
|
mntpt = *argv;
|
2003-06-03 11:54:42 +00:00
|
|
|
|
1994-05-26 06:18:55 +00:00
|
|
|
/*
|
|
|
|
* Statfs does not take a `wait' flag, so we cannot
|
|
|
|
* implement nflag here.
|
|
|
|
*/
|
|
|
|
if (statfs(mntpt, &statfsbuf) < 0) {
|
|
|
|
warn("%s", mntpt);
|
1997-10-12 13:55:43 +00:00
|
|
|
rv = 1;
|
1994-05-26 06:18:55 +00:00
|
|
|
continue;
|
|
|
|
}
|
2003-06-03 11:54:42 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check to make sure the arguments we've been given are
|
|
|
|
* satisfied. Return an error if we have been asked to
|
|
|
|
* list a mount point that does not match the other args
|
|
|
|
* we've been given (-l, -t, etc.).
|
2003-06-02 22:33:12 +00:00
|
|
|
*/
|
|
|
|
if (checkvfsname(statfsbuf.f_fstypename, vfslist)) {
|
2003-06-03 11:54:42 +00:00
|
|
|
rv = 1;
|
2003-06-02 22:33:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
2003-06-03 11:54:42 +00:00
|
|
|
|
2002-03-26 20:32:37 +00:00
|
|
|
if (argc == 1) {
|
|
|
|
bzero(&maxwidths, sizeof(maxwidths));
|
|
|
|
update_maxwidths(&maxwidths, &statfsbuf);
|
|
|
|
}
|
|
|
|
prtstat(&statfsbuf, &maxwidths);
|
2004-04-18 20:56:31 +00:00
|
|
|
if (cflag)
|
|
|
|
addstat(&totalbuf, &statfsbuf);
|
1994-05-26 06:18:55 +00:00
|
|
|
}
|
2004-04-18 20:56:31 +00:00
|
|
|
if (cflag)
|
|
|
|
prtstat(&totalbuf, &maxwidths);
|
1997-10-12 13:55:43 +00:00
|
|
|
return (rv);
|
1994-05-26 06:18:55 +00:00
|
|
|
}
|
|
|
|
|
2002-05-12 19:24:09 +00:00
|
|
|
static char *
|
2003-05-03 10:21:26 +00:00
|
|
|
getmntpt(const char *name)
|
1994-05-26 06:18:55 +00:00
|
|
|
{
|
2003-09-13 20:46:58 +00:00
|
|
|
size_t mntsize, i;
|
1994-05-26 06:18:55 +00:00
|
|
|
struct statfs *mntbuf;
|
|
|
|
|
|
|
|
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
|
|
|
for (i = 0; i < mntsize; i++) {
|
|
|
|
if (!strcmp(mntbuf[i].f_mntfromname, name))
|
|
|
|
return (mntbuf[i].f_mntonname);
|
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2002-08-21 17:32:44 +00:00
|
|
|
* Make a pass over the file system info in ``mntbuf'' filtering out
|
|
|
|
* file system types not in vfslist and possibly re-stating to get
|
1994-05-26 06:18:55 +00:00
|
|
|
* current (not cached) info. Returns the new count of valid statfs bufs.
|
|
|
|
*/
|
2003-09-13 20:46:58 +00:00
|
|
|
static size_t
|
2002-05-12 19:24:09 +00:00
|
|
|
regetmntinfo(struct statfs **mntbufp, long mntsize, const char **vfslist)
|
1994-05-26 06:18:55 +00:00
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
struct statfs *mntbuf;
|
|
|
|
|
1997-03-13 17:41:37 +00:00
|
|
|
if (vfslist == NULL)
|
1994-05-26 06:18:55 +00:00
|
|
|
return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT));
|
|
|
|
|
|
|
|
mntbuf = *mntbufp;
|
1997-03-13 17:41:37 +00:00
|
|
|
for (j = 0, i = 0; i < mntsize; i++) {
|
|
|
|
if (checkvfsname(mntbuf[i].f_fstypename, vfslist))
|
|
|
|
continue;
|
|
|
|
if (!nflag)
|
|
|
|
(void)statfs(mntbuf[i].f_mntonname,&mntbuf[j]);
|
|
|
|
else if (i != j)
|
|
|
|
mntbuf[j] = mntbuf[i];
|
|
|
|
j++;
|
1994-05-26 06:18:55 +00:00
|
|
|
}
|
|
|
|
return (j);
|
|
|
|
}
|
|
|
|
|
1999-12-15 03:44:09 +00:00
|
|
|
/*
|
|
|
|
* Output in "human-readable" format. Uses 3 digits max and puts
|
|
|
|
* unit suffixes at the end. Makes output compact and easy to read,
|
|
|
|
* especially on huge disks.
|
|
|
|
*
|
|
|
|
*/
|
2002-05-12 19:24:09 +00:00
|
|
|
static unit_t
|
2002-02-02 06:24:13 +00:00
|
|
|
unit_adjust(double *val)
|
1999-12-15 03:44:09 +00:00
|
|
|
{
|
|
|
|
double abval;
|
|
|
|
unit_t unit;
|
2003-05-03 10:21:26 +00:00
|
|
|
int unit_sz;
|
1999-12-15 03:44:09 +00:00
|
|
|
|
|
|
|
abval = fabs(*val);
|
|
|
|
|
|
|
|
unit_sz = abval ? ilogb(abval) / 10 : 0;
|
|
|
|
|
2003-05-03 10:21:26 +00:00
|
|
|
if (unit_sz >= (int)UNIT_MAX) {
|
1999-12-15 03:44:09 +00:00
|
|
|
unit = NONE;
|
|
|
|
} else {
|
|
|
|
unit = unitp[unit_sz];
|
|
|
|
*val /= (double)valp[unit_sz];
|
|
|
|
}
|
|
|
|
|
|
|
|
return (unit);
|
|
|
|
}
|
|
|
|
|
2002-05-12 19:24:09 +00:00
|
|
|
static void
|
2003-11-12 08:01:40 +00:00
|
|
|
prthuman(const struct statfs *sfsp, int64_t used)
|
1999-12-15 03:44:09 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
prthumanval((double)sfsp->f_blocks * (double)sfsp->f_bsize);
|
|
|
|
prthumanval((double)used * (double)sfsp->f_bsize);
|
|
|
|
prthumanval((double)sfsp->f_bavail * (double)sfsp->f_bsize);
|
|
|
|
}
|
|
|
|
|
2002-05-12 19:24:09 +00:00
|
|
|
static void
|
2002-02-02 06:24:13 +00:00
|
|
|
prthumanval(double bytes)
|
1999-12-15 03:44:09 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
unit_t unit;
|
|
|
|
unit = unit_adjust(&bytes);
|
|
|
|
|
|
|
|
if (bytes == 0)
|
2004-04-18 20:56:31 +00:00
|
|
|
(void)printf(" 0B");
|
1999-12-15 03:44:09 +00:00
|
|
|
else if (bytes > 10)
|
2004-04-18 20:56:31 +00:00
|
|
|
(void)printf(" % 6.0f%c", bytes, "BKMGTPE"[unit]);
|
1999-12-15 03:44:09 +00:00
|
|
|
else
|
2004-04-18 20:56:31 +00:00
|
|
|
(void)printf(" % 6.1f%c", bytes, "BKMGTPE"[unit]);
|
1999-12-15 03:44:09 +00:00
|
|
|
}
|
|
|
|
|
1994-05-26 06:18:55 +00:00
|
|
|
/*
|
2002-08-21 17:32:44 +00:00
|
|
|
* Convert statfs returned file system size into BLOCKSIZE units.
|
|
|
|
* Attempts to avoid overflow for large file systems.
|
1994-05-26 06:18:55 +00:00
|
|
|
*/
|
|
|
|
#define fsbtoblk(num, fsbs, bs) \
|
|
|
|
(((fsbs) != 0 && (fsbs) < (bs)) ? \
|
2004-03-09 10:02:44 +00:00
|
|
|
(num) / (intmax_t)((bs) / (fsbs)) : \
|
|
|
|
(num) * (intmax_t)((fsbs) / (bs)))
|
1994-05-26 06:18:55 +00:00
|
|
|
|
|
|
|
/*
|
2002-08-21 17:32:44 +00:00
|
|
|
* Print out status about a file system.
|
1994-05-26 06:18:55 +00:00
|
|
|
*/
|
2002-05-12 19:24:09 +00:00
|
|
|
static void
|
2002-03-26 20:32:37 +00:00
|
|
|
prtstat(struct statfs *sfsp, struct maxwidths *mwp)
|
1994-05-26 06:18:55 +00:00
|
|
|
{
|
2003-11-12 08:01:40 +00:00
|
|
|
static u_long blocksize;
|
2003-05-03 10:21:26 +00:00
|
|
|
static int headerlen, timesthrough = 0;
|
2001-05-20 04:12:30 +00:00
|
|
|
static const char *header;
|
2003-11-12 08:01:40 +00:00
|
|
|
int64_t used, availblks, inodes;
|
2004-04-18 20:56:31 +00:00
|
|
|
int total;
|
1994-05-26 06:18:55 +00:00
|
|
|
|
|
|
|
if (++timesthrough == 1) {
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->mntfrom = imax(mwp->mntfrom, (int)strlen("Filesystem"));
|
1999-12-15 03:44:09 +00:00
|
|
|
if (hflag) {
|
2004-04-22 16:26:05 +00:00
|
|
|
header = " Size";
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->total = mwp->used = mwp->avail =
|
|
|
|
(int)strlen(header);
|
1999-12-15 03:44:09 +00:00
|
|
|
} else {
|
|
|
|
header = getbsize(&headerlen, &blocksize);
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->total = imax(mwp->total, headerlen);
|
2002-03-26 20:32:37 +00:00
|
|
|
}
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->used = imax(mwp->used, (int)strlen("Used"));
|
|
|
|
mwp->avail = imax(mwp->avail, (int)strlen("Avail"));
|
2002-03-26 20:32:37 +00:00
|
|
|
|
2003-05-03 16:02:52 +00:00
|
|
|
(void)printf("%-*s %-*s %*s %*s Capacity",
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->mntfrom, "Filesystem", mwp->total, header,
|
|
|
|
mwp->used, "Used", mwp->avail, "Avail");
|
2002-03-26 20:32:37 +00:00
|
|
|
if (iflag) {
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->iused = imax(mwp->iused, (int)strlen(" iused"));
|
|
|
|
mwp->ifree = imax(mwp->ifree, (int)strlen("ifree"));
|
2003-05-03 16:02:52 +00:00
|
|
|
(void)printf(" %*s %*s %%iused",
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->iused - 2, "iused", mwp->ifree, "ifree");
|
1999-12-15 03:44:09 +00:00
|
|
|
}
|
1994-05-26 06:18:55 +00:00
|
|
|
(void)printf(" Mounted on\n");
|
|
|
|
}
|
2004-02-08 23:42:09 +00:00
|
|
|
(void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname);
|
1994-05-26 06:18:55 +00:00
|
|
|
used = sfsp->f_blocks - sfsp->f_bfree;
|
|
|
|
availblks = sfsp->f_bavail + used;
|
1999-12-15 03:44:09 +00:00
|
|
|
if (hflag) {
|
|
|
|
prthuman(sfsp, used);
|
|
|
|
} else {
|
2003-11-12 21:47:42 +00:00
|
|
|
(void)printf(" %*jd %*jd %*jd",
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->total, (intmax_t)fsbtoblk(sfsp->f_blocks,
|
|
|
|
sfsp->f_bsize, blocksize),
|
|
|
|
mwp->used, (intmax_t)fsbtoblk(used, sfsp->f_bsize,
|
|
|
|
blocksize),
|
|
|
|
mwp->avail, (intmax_t)fsbtoblk(sfsp->f_bavail,
|
|
|
|
sfsp->f_bsize, blocksize));
|
1999-12-15 03:44:09 +00:00
|
|
|
}
|
1994-05-26 06:18:55 +00:00
|
|
|
(void)printf(" %5.0f%%",
|
|
|
|
availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
|
2004-04-18 20:56:31 +00:00
|
|
|
total = !*sfsp->f_mntonname &&
|
|
|
|
strncmp(sfsp->f_mntfromname, "total", MNAMELEN) == 0;
|
1994-05-26 06:18:55 +00:00
|
|
|
if (iflag) {
|
|
|
|
inodes = sfsp->f_files;
|
|
|
|
used = inodes - sfsp->f_ffree;
|
2004-02-08 23:42:09 +00:00
|
|
|
(void)printf(" %*jd %*jd %4.0f%% ", mwp->iused, (intmax_t)used,
|
|
|
|
mwp->ifree, (intmax_t)sfsp->f_ffree, inodes == 0 ? 100.0 :
|
|
|
|
(double)used / (double)inodes * 100.0);
|
2004-04-22 16:26:05 +00:00
|
|
|
} else
|
|
|
|
(void)printf(" ");
|
|
|
|
if (!total)
|
2004-04-18 20:56:31 +00:00
|
|
|
(void)printf(" %s", sfsp->f_mntonname);
|
|
|
|
(void)printf("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
addstat(struct statfs *totalfsp, struct statfs *statfsp)
|
|
|
|
{
|
|
|
|
double bsize = statfsp->f_bsize / totalfsp->f_bsize;
|
|
|
|
|
|
|
|
totalfsp->f_blocks += statfsp->f_blocks * bsize;
|
|
|
|
totalfsp->f_bfree += statfsp->f_bfree * bsize;
|
|
|
|
totalfsp->f_bavail += statfsp->f_bavail * bsize;
|
|
|
|
totalfsp->f_files += statfsp->f_files;
|
|
|
|
totalfsp->f_ffree += statfsp->f_ffree;
|
1994-05-26 06:18:55 +00:00
|
|
|
}
|
|
|
|
|
2002-03-26 20:32:37 +00:00
|
|
|
/*
|
|
|
|
* Update the maximum field-width information in `mwp' based on
|
2002-08-21 17:32:44 +00:00
|
|
|
* the file system specified by `sfsp'.
|
2002-03-26 20:32:37 +00:00
|
|
|
*/
|
2002-05-12 19:24:09 +00:00
|
|
|
static void
|
2003-05-03 10:21:26 +00:00
|
|
|
update_maxwidths(struct maxwidths *mwp, const struct statfs *sfsp)
|
2002-03-26 20:32:37 +00:00
|
|
|
{
|
2003-11-12 08:01:40 +00:00
|
|
|
static u_long blocksize = 0;
|
2002-12-30 18:10:37 +00:00
|
|
|
int dummy;
|
2002-03-26 20:32:37 +00:00
|
|
|
|
|
|
|
if (blocksize == 0)
|
|
|
|
getbsize(&dummy, &blocksize);
|
|
|
|
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->mntfrom = imax(mwp->mntfrom, (int)strlen(sfsp->f_mntfromname));
|
|
|
|
mwp->total = imax(mwp->total, int64width(
|
2003-11-12 08:01:40 +00:00
|
|
|
fsbtoblk((int64_t)sfsp->f_blocks, sfsp->f_bsize, blocksize)));
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->used = imax(mwp->used,
|
|
|
|
int64width(fsbtoblk((int64_t)sfsp->f_blocks -
|
2003-11-12 08:01:40 +00:00
|
|
|
(int64_t)sfsp->f_bfree, sfsp->f_bsize, blocksize)));
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->avail = imax(mwp->avail, int64width(fsbtoblk(sfsp->f_bavail,
|
2002-03-26 20:32:37 +00:00
|
|
|
sfsp->f_bsize, blocksize)));
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->iused = imax(mwp->iused, int64width((int64_t)sfsp->f_files -
|
2002-03-26 20:32:37 +00:00
|
|
|
sfsp->f_ffree));
|
2004-02-08 23:42:09 +00:00
|
|
|
mwp->ifree = imax(mwp->ifree, int64width(sfsp->f_ffree));
|
2002-03-26 20:32:37 +00:00
|
|
|
}
|
|
|
|
|
2004-02-08 23:42:09 +00:00
|
|
|
/* Return the width in characters of the specified value. */
|
|
|
|
static int
|
2003-11-12 08:01:40 +00:00
|
|
|
int64width(int64_t val)
|
2002-03-26 20:32:37 +00:00
|
|
|
{
|
2004-02-08 23:42:09 +00:00
|
|
|
int len;
|
2002-03-26 20:32:37 +00:00
|
|
|
|
|
|
|
len = 0;
|
|
|
|
/* Negative or zero values require one extra digit. */
|
|
|
|
if (val <= 0) {
|
|
|
|
val = -val;
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
while (val > 0) {
|
|
|
|
len++;
|
|
|
|
val /= 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (len);
|
|
|
|
}
|
|
|
|
|
2002-05-12 19:24:09 +00:00
|
|
|
static void
|
2002-02-02 06:24:13 +00:00
|
|
|
usage(void)
|
1994-05-26 06:18:55 +00:00
|
|
|
{
|
1999-12-15 03:44:09 +00:00
|
|
|
|
1997-03-13 17:41:37 +00:00
|
|
|
(void)fprintf(stderr,
|
2004-04-18 20:56:31 +00:00
|
|
|
"usage: df [-b | -H | -h | -k | -m | -P] [-aciln] [-t type] [file | filesystem ...]\n");
|
1999-12-15 03:44:09 +00:00
|
|
|
exit(EX_USAGE);
|
1994-05-26 06:18:55 +00:00
|
|
|
}
|
2001-06-04 23:07:15 +00:00
|
|
|
|
2002-05-12 19:24:09 +00:00
|
|
|
static char *
|
2002-02-02 06:24:13 +00:00
|
|
|
makenetvfslist(void)
|
2001-06-04 23:07:15 +00:00
|
|
|
{
|
|
|
|
char *str, *strptr, **listptr;
|
2003-05-03 10:21:26 +00:00
|
|
|
struct xvfsconf *xvfsp, *keep_xvfsp;
|
- Introduce a new struct xvfsconf, the userland version of struct vfsconf.
- Make getvfsbyname() take a struct xvfsconf *.
- Convert several consumers of getvfsbyname() to use struct xvfsconf.
- Correct the getvfsbyname.3 manpage.
- Create a new vfs.conflist sysctl to dump all the struct xvfsconf in the
kernel, and rewrite getvfsbyname() to use this instead of the weird
existing API.
- Convert some {set,get,end}vfsent() consumers to use the new vfs.conflist
sysctl.
- Convert a vfsload() call in nfsiod.c to kldload() and remove the useless
vfsisloadable() and endvfsent() calls.
- Add a warning printf() in vfs_sysctl() to tell people they are using
an old userland.
After these changes, it's possible to modify struct vfsconf without
breaking the binary compatibility. Please note that these changes don't
break this compatibility either.
When bp will have updated mount_smbfs(8) with the patch I sent him, there
will be no more consumers of the {set,get,end}vfsent(), vfsisloadable()
and vfsload() API, and I will promptly delete it.
2002-08-10 20:19:04 +00:00
|
|
|
size_t buflen;
|
|
|
|
int cnt, i, maxvfsconf;
|
|
|
|
|
|
|
|
if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) {
|
|
|
|
warn("sysctl(vfs.conflist)");
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
xvfsp = malloc(buflen);
|
|
|
|
if (xvfsp == NULL) {
|
|
|
|
warnx("malloc failed");
|
2001-06-04 23:07:15 +00:00
|
|
|
return (NULL);
|
|
|
|
}
|
2003-05-03 10:21:26 +00:00
|
|
|
keep_xvfsp = xvfsp;
|
- Introduce a new struct xvfsconf, the userland version of struct vfsconf.
- Make getvfsbyname() take a struct xvfsconf *.
- Convert several consumers of getvfsbyname() to use struct xvfsconf.
- Correct the getvfsbyname.3 manpage.
- Create a new vfs.conflist sysctl to dump all the struct xvfsconf in the
kernel, and rewrite getvfsbyname() to use this instead of the weird
existing API.
- Convert some {set,get,end}vfsent() consumers to use the new vfs.conflist
sysctl.
- Convert a vfsload() call in nfsiod.c to kldload() and remove the useless
vfsisloadable() and endvfsent() calls.
- Add a warning printf() in vfs_sysctl() to tell people they are using
an old userland.
After these changes, it's possible to modify struct vfsconf without
breaking the binary compatibility. Please note that these changes don't
break this compatibility either.
When bp will have updated mount_smbfs(8) with the patch I sent him, there
will be no more consumers of the {set,get,end}vfsent(), vfsisloadable()
and vfsload() API, and I will promptly delete it.
2002-08-10 20:19:04 +00:00
|
|
|
if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) {
|
|
|
|
warn("sysctl(vfs.conflist)");
|
2003-05-03 10:21:26 +00:00
|
|
|
free(keep_xvfsp);
|
- Introduce a new struct xvfsconf, the userland version of struct vfsconf.
- Make getvfsbyname() take a struct xvfsconf *.
- Convert several consumers of getvfsbyname() to use struct xvfsconf.
- Correct the getvfsbyname.3 manpage.
- Create a new vfs.conflist sysctl to dump all the struct xvfsconf in the
kernel, and rewrite getvfsbyname() to use this instead of the weird
existing API.
- Convert some {set,get,end}vfsent() consumers to use the new vfs.conflist
sysctl.
- Convert a vfsload() call in nfsiod.c to kldload() and remove the useless
vfsisloadable() and endvfsent() calls.
- Add a warning printf() in vfs_sysctl() to tell people they are using
an old userland.
After these changes, it's possible to modify struct vfsconf without
breaking the binary compatibility. Please note that these changes don't
break this compatibility either.
When bp will have updated mount_smbfs(8) with the patch I sent him, there
will be no more consumers of the {set,get,end}vfsent(), vfsisloadable()
and vfsload() API, and I will promptly delete it.
2002-08-10 20:19:04 +00:00
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
maxvfsconf = buflen / sizeof(struct xvfsconf);
|
2001-06-04 23:07:15 +00:00
|
|
|
|
2001-07-16 15:49:58 +00:00
|
|
|
if ((listptr = malloc(sizeof(char*) * maxvfsconf)) == NULL) {
|
2001-06-04 23:07:15 +00:00
|
|
|
warnx("malloc failed");
|
2003-05-03 10:21:26 +00:00
|
|
|
free(keep_xvfsp);
|
2001-06-04 23:07:15 +00:00
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
- Introduce a new struct xvfsconf, the userland version of struct vfsconf.
- Make getvfsbyname() take a struct xvfsconf *.
- Convert several consumers of getvfsbyname() to use struct xvfsconf.
- Correct the getvfsbyname.3 manpage.
- Create a new vfs.conflist sysctl to dump all the struct xvfsconf in the
kernel, and rewrite getvfsbyname() to use this instead of the weird
existing API.
- Convert some {set,get,end}vfsent() consumers to use the new vfs.conflist
sysctl.
- Convert a vfsload() call in nfsiod.c to kldload() and remove the useless
vfsisloadable() and endvfsent() calls.
- Add a warning printf() in vfs_sysctl() to tell people they are using
an old userland.
After these changes, it's possible to modify struct vfsconf without
breaking the binary compatibility. Please note that these changes don't
break this compatibility either.
When bp will have updated mount_smbfs(8) with the patch I sent him, there
will be no more consumers of the {set,get,end}vfsent(), vfsisloadable()
and vfsload() API, and I will promptly delete it.
2002-08-10 20:19:04 +00:00
|
|
|
for (cnt = 0, i = 0; i < maxvfsconf; i++) {
|
|
|
|
if (xvfsp->vfc_flags & VFCF_NETWORK) {
|
|
|
|
listptr[cnt++] = strdup(xvfsp->vfc_name);
|
2001-07-16 15:49:58 +00:00
|
|
|
if (listptr[cnt-1] == NULL) {
|
2001-06-04 23:07:15 +00:00
|
|
|
warnx("malloc failed");
|
2003-05-03 10:21:26 +00:00
|
|
|
free(listptr);
|
|
|
|
free(keep_xvfsp);
|
2001-06-04 23:07:15 +00:00
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
}
|
- Introduce a new struct xvfsconf, the userland version of struct vfsconf.
- Make getvfsbyname() take a struct xvfsconf *.
- Convert several consumers of getvfsbyname() to use struct xvfsconf.
- Correct the getvfsbyname.3 manpage.
- Create a new vfs.conflist sysctl to dump all the struct xvfsconf in the
kernel, and rewrite getvfsbyname() to use this instead of the weird
existing API.
- Convert some {set,get,end}vfsent() consumers to use the new vfs.conflist
sysctl.
- Convert a vfsload() call in nfsiod.c to kldload() and remove the useless
vfsisloadable() and endvfsent() calls.
- Add a warning printf() in vfs_sysctl() to tell people they are using
an old userland.
After these changes, it's possible to modify struct vfsconf without
breaking the binary compatibility. Please note that these changes don't
break this compatibility either.
When bp will have updated mount_smbfs(8) with the patch I sent him, there
will be no more consumers of the {set,get,end}vfsent(), vfsisloadable()
and vfsload() API, and I will promptly delete it.
2002-08-10 20:19:04 +00:00
|
|
|
xvfsp++;
|
|
|
|
}
|
2001-06-04 23:07:15 +00:00
|
|
|
|
2001-12-19 08:38:02 +00:00
|
|
|
if (cnt == 0 ||
|
|
|
|
(str = malloc(sizeof(char) * (32 * cnt + cnt + 2))) == NULL) {
|
|
|
|
if (cnt > 0)
|
|
|
|
warnx("malloc failed");
|
2001-06-04 23:07:15 +00:00
|
|
|
free(listptr);
|
2003-05-03 10:21:26 +00:00
|
|
|
free(keep_xvfsp);
|
2001-06-04 23:07:15 +00:00
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
2001-07-16 15:49:58 +00:00
|
|
|
*str = 'n'; *(str + 1) = 'o';
|
|
|
|
for (i = 0, strptr = str + 2; i < cnt; i++, strptr++) {
|
|
|
|
strncpy(strptr, listptr[i], 32);
|
|
|
|
strptr += strlen(listptr[i]);
|
|
|
|
*strptr = ',';
|
2001-06-04 23:07:15 +00:00
|
|
|
free(listptr[i]);
|
|
|
|
}
|
2004-03-05 08:10:19 +00:00
|
|
|
*(--strptr) = '\0';
|
2001-06-04 23:07:15 +00:00
|
|
|
|
2003-05-03 10:21:26 +00:00
|
|
|
free(keep_xvfsp);
|
2001-06-04 23:07:15 +00:00
|
|
|
free(listptr);
|
|
|
|
return (str);
|
|
|
|
}
|