Print this page
NEX-7498 Cannot display userquota of 2TB or larger using quota
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
*** 21,30 ****
--- 21,32 ----
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+ /* Copyright 2016 Nexenta Systems, Inc. All rights reserved. */
+
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* University Copyright- Copyright (c) 1982, 1986, 1988
*** 65,74 ****
--- 67,92 ----
#include <libzfs.h>
int vflag;
int nolocalquota;
+ /*
+ * struct dqblk is a 32 bit quantity and is common across NFS and UFS.
+ * UFS has a 2TB limit and an uint32_t can hold this value.
+ * NFS translates this to rquota where all members are unit32_t in size.
+ * A private dqblk, dqblk_zfs is defined here.
+ */
+ struct dqblk_zfs {
+ uint64_t dqbz_bhardlimit; /* absolute limit on disk blks alloc */
+ uint64_t dqbz_bsoftlimit; /* preferred limit on disk blks */
+ uint64_t dqbz_curblocks; /* current block count */
+ uint64_t dqbz_fhardlimit; /* maximum # allocated files + 1 */
+ uint64_t dqbz_fsoftlimit; /* preferred file limit */
+ uint64_t dqbz_curfiles; /* current # allocated files */
+ uint64_t dqbz_btimelimit; /* time limit for excessive disk use */
+ uint64_t dqbz_ftimelimit; /* time limit for excessive files */
+ };
extern int optind;
extern char *optarg;
#define QFNAME "quotas"
*** 81,134 ****
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
#endif
static void zexit(int);
! static int getzfsquota(char *, char *, struct dqblk *);
static int getnfsquota(char *, char *, uid_t, struct dqblk *);
static void showuid(uid_t);
static void showquotas(uid_t, char *);
! static void warn(struct mnttab *, struct dqblk *);
static void heading(uid_t, char *);
! static void prquota(struct mnttab *, struct dqblk *);
static void fmttime(char *, long);
- static libzfs_handle_t *(*_libzfs_init)(void);
- static void (*_libzfs_fini)(libzfs_handle_t *);
- static zfs_handle_t *(*_zfs_open)(libzfs_handle_t *, const char *, int);
- static void (*_zfs_close)(zfs_handle_t *);
- static int (*_zfs_prop_get_userquota_int)(zfs_handle_t *, const char *,
- uint64_t *);
static libzfs_handle_t *g_zfs = NULL;
- /*
- * Dynamically check for libzfs, in case the user hasn't installed the SUNWzfs
- * packages. 'quota' utility supports zfs as an option.
- */
- static void
- load_libzfs(void)
- {
- void *hdl;
-
- if (g_zfs != NULL)
- return;
-
- if ((hdl = dlopen("libzfs.so", RTLD_LAZY)) != NULL) {
- _libzfs_init = (libzfs_handle_t *(*)(void))dlsym(hdl,
- "libzfs_init");
- _libzfs_fini = (void (*)())dlsym(hdl, "libzfs_fini");
- _zfs_open = (zfs_handle_t *(*)())dlsym(hdl, "zfs_open");
- _zfs_close = (void (*)())dlsym(hdl, "zfs_close");
- _zfs_prop_get_userquota_int = (int (*)())
- dlsym(hdl, "zfs_prop_get_userquota_int");
-
- if (_libzfs_init && _libzfs_fini && _zfs_open &&
- _zfs_close && _zfs_prop_get_userquota_int)
- g_zfs = _libzfs_init();
- }
- }
-
int
main(int argc, char *argv[])
{
int opt;
int i;
--- 99,124 ----
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
#endif
static void zexit(int);
! static boolean_t blklimits_is_zero(struct dqblk *, struct dqblk_zfs *);
! static int getzfsquota(char *, char *, struct dqblk_zfs *);
static int getnfsquota(char *, char *, uid_t, struct dqblk *);
static void showuid(uid_t);
static void showquotas(uid_t, char *);
! static void warn(struct mnttab *, struct dqblk *, struct dqblk_zfs *);
! static void warn_dqblk_impl(struct mnttab *, struct dqblk *);
! static void warn_dqblk_zfs_impl(struct mnttab *, struct dqblk_zfs *);
static void heading(uid_t, char *);
! static void prquota(struct mnttab *, struct dqblk *, struct dqblk_zfs *);
! static void prquota_dqblk_impl(struct mnttab *, struct dqblk *);
! static void prquota_dqblk_zfs_impl(struct mnttab *, struct dqblk_zfs *);
static void fmttime(char *, long);
static libzfs_handle_t *g_zfs = NULL;
int
main(int argc, char *argv[])
{
int opt;
int i;
*** 151,161 ****
"file_dac_read privileges\n"));
exit(1);
}
- load_libzfs();
while ((opt = getopt(argc, argv, "vV")) != EOF) {
switch (opt) {
case 'v':
--- 141,150 ----
*** 240,249 ****
--- 229,239 ----
showquotas(uid_t uid, char *name)
{
struct mnttab mnt;
FILE *mtab;
struct dqblk dqblk;
+ struct dqblk_zfs dqblkz;
uid_t myuid;
struct failed_srv {
char *serv_name;
struct failed_srv *next;
};
*** 263,275 ****
if (vflag)
heading(uid, name);
mtab = fopen(MNTTAB, "r");
while (getmntent(mtab, &mnt) == NULL) {
if (strcmp(mnt.mnt_fstype, MNTTYPE_ZFS) == 0) {
! bzero(&dqblk, sizeof (dqblk));
! if (getzfsquota(name, mnt.mnt_special, &dqblk))
continue;
} else if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) == 0) {
if (nolocalquota ||
(quotactl(Q_GETQUOTA,
mnt.mnt_mountp, uid, &dqblk) != 0 &&
--- 253,268 ----
if (vflag)
heading(uid, name);
mtab = fopen(MNTTAB, "r");
while (getmntent(mtab, &mnt) == NULL) {
+ boolean_t is_zfs = B_FALSE;
+
if (strcmp(mnt.mnt_fstype, MNTTYPE_ZFS) == 0) {
! is_zfs = B_TRUE;
! bzero(&dqblkz, sizeof (dqblkz));
! if (getzfsquota(name, mnt.mnt_special, &dqblkz))
continue;
} else if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) == 0) {
if (nolocalquota ||
(quotactl(Q_GETQUOTA,
mnt.mnt_mountp, uid, &dqblk) != 0 &&
*** 409,425 ****
free_replica(rl, count);
} else {
continue;
}
! if (dqblk.dqb_bsoftlimit == 0 && dqblk.dqb_bhardlimit == 0 &&
! dqblk.dqb_fsoftlimit == 0 && dqblk.dqb_fhardlimit == 0)
continue;
if (vflag)
! prquota(&mnt, &dqblk);
else
! warn(&mnt, &dqblk);
}
/*
* Free list of failed servers
*/
--- 402,420 ----
free_replica(rl, count);
} else {
continue;
}
!
! if (blklimits_is_zero(&dqblk, is_zfs ? &dqblkz : NULL))
continue;
+
if (vflag)
! prquota(&mnt, &dqblk, is_zfs ? &dqblkz : NULL);
else
! warn(&mnt, &dqblk, is_zfs ? &dqblkz : NULL);
!
}
/*
* Free list of failed servers
*/
*** 433,502 ****
fclose(mtab);
}
static void
! warn(struct mnttab *mntp, struct dqblk *dqp)
{
! struct timeval tv;
!
! time(&(tv.tv_sec));
! tv.tv_usec = 0;
! if (dqp->dqb_bhardlimit &&
! dqp->dqb_curblocks >= dqp->dqb_bhardlimit) {
! printf("Block limit reached on %s\n", mntp->mnt_mountp);
! } else if (dqp->dqb_bsoftlimit &&
! dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
! if (dqp->dqb_btimelimit == 0) {
! printf("Over disk quota on %s, remove %luK\n",
! mntp->mnt_mountp,
! kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1));
! } else if (dqp->dqb_btimelimit > tv.tv_sec) {
! char btimeleft[80];
!
! fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
! printf("Over disk quota on %s, remove %luK within %s\n",
! mntp->mnt_mountp,
! kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1),
! btimeleft);
! } else {
! printf(
! "Over disk quota on %s, time limit has expired, remove %luK\n",
! mntp->mnt_mountp,
! kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1));
! }
! }
! if (dqp->dqb_fhardlimit &&
! dqp->dqb_curfiles >= dqp->dqb_fhardlimit) {
! printf("File count limit reached on %s\n", mntp->mnt_mountp);
! } else if (dqp->dqb_fsoftlimit &&
! dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
! if (dqp->dqb_ftimelimit == 0) {
! printf("Over file quota on %s, remove %lu file%s\n",
! mntp->mnt_mountp,
! dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
! ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
! "s" : ""));
! } else if (dqp->dqb_ftimelimit > tv.tv_sec) {
! char ftimeleft[80];
!
! fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
! printf(
! "Over file quota on %s, remove %lu file%s within %s\n",
! mntp->mnt_mountp,
! dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
! ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
! "s" : ""), ftimeleft);
! } else {
! printf(
! "Over file quota on %s, time limit has expired, remove %lu file%s\n",
! mntp->mnt_mountp,
! dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
! ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
! "s" : ""));
! }
! }
}
static void
heading(uid_t uid, char *name)
{
--- 428,443 ----
fclose(mtab);
}
static void
! warn(struct mnttab *mntp, struct dqblk *dqp, struct dqblk_zfs *dqzp)
{
! if (dqzp != NULL)
! warn_dqblk_zfs_impl(mntp, dqzp);
! else
! warn_dqblk_impl(mntp, dqp);
}
static void
heading(uid_t uid, char *name)
{
*** 512,582 ****
"limit",
"timeleft");
}
static void
! prquota(struct mnttab *mntp, struct dqblk *dqp)
{
! struct timeval tv;
! char ftimeleft[80], btimeleft[80];
! char *cp;
!
! time(&(tv.tv_sec));
! tv.tv_usec = 0;
! if (dqp->dqb_bsoftlimit && dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
! if (dqp->dqb_btimelimit == 0) {
! strlcpy(btimeleft, "NOT STARTED", sizeof (btimeleft));
! } else if (dqp->dqb_btimelimit > tv.tv_sec) {
! fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
! } else {
! strlcpy(btimeleft, "EXPIRED", sizeof (btimeleft));
! }
! } else {
! btimeleft[0] = '\0';
! }
! if (dqp->dqb_fsoftlimit && dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
! if (dqp->dqb_ftimelimit == 0) {
! strlcpy(ftimeleft, "NOT STARTED", sizeof (ftimeleft));
! } else if (dqp->dqb_ftimelimit > tv.tv_sec) {
! fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
! } else {
! strlcpy(ftimeleft, "EXPIRED", sizeof (ftimeleft));
! }
! } else {
! ftimeleft[0] = '\0';
! }
! if (strlen(mntp->mnt_mountp) > 12) {
! printf("%s\n", mntp->mnt_mountp);
! cp = "";
! } else {
! cp = mntp->mnt_mountp;
! }
!
! if (dqp->dqb_curfiles == 0 &&
! dqp->dqb_fsoftlimit == 0 && dqp->dqb_fhardlimit == 0) {
! printf("%-12.12s %7d %6d %6d %11s %6s %6s %6s %11s\n",
! cp,
! kb(dqp->dqb_curblocks),
! kb(dqp->dqb_bsoftlimit),
! kb(dqp->dqb_bhardlimit),
! "-",
! "-",
! "-",
! "-",
! "-");
! } else {
! printf("%-12.12s %7d %6d %6d %11s %6d %6d %6d %11s\n",
! cp,
! kb(dqp->dqb_curblocks),
! kb(dqp->dqb_bsoftlimit),
! kb(dqp->dqb_bhardlimit),
! btimeleft,
! dqp->dqb_curfiles,
! dqp->dqb_fsoftlimit,
! dqp->dqb_fhardlimit,
! ftimeleft);
! }
}
static void
fmttime(char *buf, long time)
{
--- 453,468 ----
"limit",
"timeleft");
}
static void
! prquota(struct mnttab *mntp, struct dqblk *dqp, struct dqblk_zfs *dqzp)
{
! if (dqzp != NULL)
! prquota_dqblk_zfs_impl(mntp, dqzp);
! else
! prquota_dqblk_impl(mntp, dqp);
}
static void
fmttime(char *buf, long time)
{
*** 866,908 ****
return ((int)clnt_stat);
}
static int
! getzfsquota(char *user, char *dataset, struct dqblk *zq)
{
zfs_handle_t *zhp = NULL;
char propname[ZFS_MAXPROPLEN];
uint64_t userquota, userused;
! if (g_zfs == NULL)
! return (1);
! if ((zhp = _zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
return (1);
(void) snprintf(propname, sizeof (propname), "userquota@%s", user);
! if (_zfs_prop_get_userquota_int(zhp, propname, &userquota) != 0) {
! _zfs_close(zhp);
return (1);
}
(void) snprintf(propname, sizeof (propname), "userused@%s", user);
! if (_zfs_prop_get_userquota_int(zhp, propname, &userused) != 0) {
! _zfs_close(zhp);
return (1);
}
! zq->dqb_bhardlimit = userquota / DEV_BSIZE;
! zq->dqb_bsoftlimit = userquota / DEV_BSIZE;
! zq->dqb_curblocks = userused / DEV_BSIZE;
! _zfs_close(zhp);
return (0);
}
static void
zexit(int n)
{
if (g_zfs != NULL)
! _libzfs_fini(g_zfs);
exit(n);
}
--- 752,1071 ----
return ((int)clnt_stat);
}
static int
! getzfsquota(char *user, char *dataset, struct dqblk_zfs *zq)
{
zfs_handle_t *zhp = NULL;
char propname[ZFS_MAXPROPLEN];
uint64_t userquota, userused;
! if (g_zfs == NULL) {
! g_zfs = libzfs_init();
! }
! if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
return (1);
(void) snprintf(propname, sizeof (propname), "userquota@%s", user);
! if (zfs_prop_get_userquota_int(zhp, propname, &userquota) != 0) {
! zfs_close(zhp);
return (1);
}
(void) snprintf(propname, sizeof (propname), "userused@%s", user);
! if (zfs_prop_get_userquota_int(zhp, propname, &userused) != 0) {
! zfs_close(zhp);
return (1);
}
! zq->dqbz_bhardlimit = userquota / DEV_BSIZE;
! zq->dqbz_bsoftlimit = userquota / DEV_BSIZE;
! zq->dqbz_curblocks = userused / DEV_BSIZE;
! zfs_close(zhp);
return (0);
}
+ static boolean_t
+ blklimits_is_zero(struct dqblk *dqp, struct dqblk_zfs *dqzp)
+ {
+ if (dqzp == NULL) {
+ if (dqp->dqb_bsoftlimit == 0 && dqp->dqb_bhardlimit == 0 &&
+ dqp->dqb_fsoftlimit == 0 && dqp->dqb_fhardlimit == 0) {
+ return (B_TRUE);
+ } else {
+ return (B_FALSE);
+ }
+ } else {
+ if (dqzp->dqbz_bsoftlimit == 0 && dqzp->dqbz_bhardlimit == 0 &&
+ dqzp->dqbz_fsoftlimit == 0 && dqzp->dqbz_fhardlimit == 0) {
+ return (B_TRUE);
+ } else {
+ return (B_FALSE);
+ }
+ }
+ }
+
static void
+ warn_dqblk_impl(struct mnttab *mntp, struct dqblk *dqp)
+ {
+ struct timeval tv;
+
+ time(&(tv.tv_sec));
+ tv.tv_usec = 0;
+ if (dqp->dqb_bhardlimit &&
+ dqp->dqb_curblocks >= dqp->dqb_bhardlimit) {
+ printf("Block limit reached on %s\n", mntp->mnt_mountp);
+ } else if (dqp->dqb_bsoftlimit &&
+ dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
+ if (dqp->dqb_btimelimit == 0) {
+ printf("Over disk quota on %s, remove %luK\n",
+ mntp->mnt_mountp,
+ kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1));
+ } else if (dqp->dqb_btimelimit > tv.tv_sec) {
+ char btimeleft[80];
+
+ fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
+ printf("Over disk quota on %s, remove %luK within %s\n",
+ mntp->mnt_mountp,
+ kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1),
+ btimeleft);
+ } else {
+ printf("Over disk quota on %s, time limit has expired,"
+ " remove %luK\n", mntp->mnt_mountp,
+ kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1));
+ }
+ }
+ if (dqp->dqb_fhardlimit &&
+ dqp->dqb_curfiles >= dqp->dqb_fhardlimit) {
+ printf("File count limit reached on %s\n", mntp->mnt_mountp);
+ } else if (dqp->dqb_fsoftlimit &&
+ dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
+ if (dqp->dqb_ftimelimit == 0) {
+ printf("Over file quota on %s, remove %lu file%s\n",
+ mntp->mnt_mountp,
+ dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
+ ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
+ "s" : ""));
+ } else if (dqp->dqb_ftimelimit > tv.tv_sec) {
+ char ftimeleft[80];
+
+ fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
+ printf("Over file quota on %s, remove %lu file%s"
+ " within %s\n", mntp->mnt_mountp,
+ dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
+ ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
+ "s" : ""), ftimeleft);
+ } else {
+ printf("Over file quota on %s, time limit has expired,"
+ " remove %lu file%s\n", mntp->mnt_mountp,
+ dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
+ ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
+ "s" : ""));
+ }
+ }
+ }
+
+ static void
+ warn_dqblk_zfs_impl(struct mnttab *mntp, struct dqblk_zfs *dqzp)
+ {
+ struct timeval tv;
+
+ time(&(tv.tv_sec));
+ tv.tv_usec = 0;
+ if (dqzp->dqbz_bhardlimit &&
+ dqzp->dqbz_curblocks >= dqzp->dqbz_bhardlimit) {
+ printf("Block limit reached on %s\n", mntp->mnt_mountp);
+ } else if (dqzp->dqbz_bsoftlimit &&
+ dqzp->dqbz_curblocks >= dqzp->dqbz_bsoftlimit) {
+ if (dqzp->dqbz_btimelimit == 0) {
+ printf("Over disk quota on %s, remove %luK\n",
+ mntp->mnt_mountp,
+ kb(dqzp->dqbz_curblocks -
+ dqzp->dqbz_bsoftlimit + 1));
+ } else if (dqzp->dqbz_btimelimit > tv.tv_sec) {
+ char btimeleft[80];
+
+ fmttime(btimeleft, dqzp->dqbz_btimelimit - tv.tv_sec);
+ printf("Over disk quota on %s, remove %luK within %s\n",
+ mntp->mnt_mountp,
+ kb(dqzp->dqbz_curblocks -
+ dqzp->dqbz_bsoftlimit + 1),
+ btimeleft);
+ } else {
+ printf("Over disk quota on %s, time limit has expired,"
+ " remove %luK\n", mntp->mnt_mountp,
+ kb(dqzp->dqbz_curblocks -
+ dqzp->dqbz_bsoftlimit + 1));
+ }
+ }
+ if (dqzp->dqbz_fhardlimit &&
+ dqzp->dqbz_curfiles >= dqzp->dqbz_fhardlimit) {
+ printf("File count limit reached on %s\n", mntp->mnt_mountp);
+ } else if (dqzp->dqbz_fsoftlimit &&
+ dqzp->dqbz_curfiles >= dqzp->dqbz_fsoftlimit) {
+ if (dqzp->dqbz_ftimelimit == 0) {
+ printf("Over file quota on %s, remove %lu file%s\n",
+ mntp->mnt_mountp,
+ dqzp->dqbz_curfiles - dqzp->dqbz_fsoftlimit + 1,
+ ((dqzp->dqbz_curfiles -
+ dqzp->dqbz_fsoftlimit + 1) > 1 ?
+ "s" : ""));
+ } else if (dqzp->dqbz_ftimelimit > tv.tv_sec) {
+ char ftimeleft[80];
+
+ fmttime(ftimeleft, dqzp->dqbz_ftimelimit - tv.tv_sec);
+ printf("Over file quota on %s, remove %lu file%s "
+ " within %s\n", mntp->mnt_mountp,
+ dqzp->dqbz_curfiles - dqzp->dqbz_fsoftlimit + 1,
+ ((dqzp->dqbz_curfiles -
+ dqzp->dqbz_fsoftlimit + 1) > 1 ?
+ "s" : ""), ftimeleft);
+ } else {
+ printf("Over file quota on %s, time limit has expired,"
+ " remove %lu file%s\n", mntp->mnt_mountp,
+ dqzp->dqbz_curfiles - dqzp->dqbz_fsoftlimit + 1,
+ ((dqzp->dqbz_curfiles -
+ dqzp->dqbz_fsoftlimit + 1) > 1 ?
+ "s" : ""));
+ }
+ }
+ }
+
+ static void
+ prquota_dqblk_impl(struct mnttab *mntp, struct dqblk *dqp)
+ {
+ struct timeval tv;
+ char ftimeleft[80], btimeleft[80];
+ char *cp;
+
+ time(&(tv.tv_sec));
+ tv.tv_usec = 0;
+ if (dqp->dqb_bsoftlimit && dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
+ if (dqp->dqb_btimelimit == 0) {
+ strlcpy(btimeleft, "NOT STARTED", sizeof (btimeleft));
+ } else if (dqp->dqb_btimelimit > tv.tv_sec) {
+ fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
+ } else {
+ strlcpy(btimeleft, "EXPIRED", sizeof (btimeleft));
+ }
+ } else {
+ btimeleft[0] = '\0';
+ }
+ if (dqp->dqb_fsoftlimit && dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
+ if (dqp->dqb_ftimelimit == 0) {
+ strlcpy(ftimeleft, "NOT STARTED", sizeof (ftimeleft));
+ } else if (dqp->dqb_ftimelimit > tv.tv_sec) {
+ fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
+ } else {
+ strlcpy(ftimeleft, "EXPIRED", sizeof (ftimeleft));
+ }
+ } else {
+ ftimeleft[0] = '\0';
+ }
+ if (strlen(mntp->mnt_mountp) > 12) {
+ printf("%s\n", mntp->mnt_mountp);
+ cp = "";
+ } else {
+ cp = mntp->mnt_mountp;
+ }
+
+ if (dqp->dqb_curfiles == 0 &&
+ dqp->dqb_fsoftlimit == 0 && dqp->dqb_fhardlimit == 0) {
+ printf("%-12.12s %7d %6d %6d %11s %6s %6s %6s %11s\n",
+ cp,
+ kb(dqp->dqb_curblocks),
+ kb(dqp->dqb_bsoftlimit),
+ kb(dqp->dqb_bhardlimit),
+ "-",
+ "-",
+ "-",
+ "-",
+ "-");
+ } else {
+ printf("%-12.12s %7d %6d %6d %11s %6d %6d %6d %11s\n",
+ cp,
+ kb(dqp->dqb_curblocks),
+ kb(dqp->dqb_bsoftlimit),
+ kb(dqp->dqb_bhardlimit),
+ btimeleft,
+ dqp->dqb_curfiles,
+ dqp->dqb_fsoftlimit,
+ dqp->dqb_fhardlimit,
+ ftimeleft);
+ }
+ }
+
+ static void
+ prquota_dqblk_zfs_impl(struct mnttab *mntp, struct dqblk_zfs *dqzp)
+ {
+ struct timeval tv;
+ char ftimeleft[80], btimeleft[80];
+ char *cp;
+
+ time(&(tv.tv_sec));
+ tv.tv_usec = 0;
+ if (dqzp->dqbz_bsoftlimit &&
+ dqzp->dqbz_curblocks >= dqzp->dqbz_bsoftlimit) {
+ if (dqzp->dqbz_btimelimit == 0) {
+ strlcpy(btimeleft, "NOT STARTED", sizeof (btimeleft));
+ } else if (dqzp->dqbz_btimelimit > tv.tv_sec) {
+ fmttime(btimeleft, dqzp->dqbz_btimelimit - tv.tv_sec);
+ } else {
+ strlcpy(btimeleft, "EXPIRED", sizeof (btimeleft));
+ }
+ } else {
+ btimeleft[0] = '\0';
+ }
+ if (dqzp->dqbz_fsoftlimit &&
+ dqzp->dqbz_curfiles >= dqzp->dqbz_fsoftlimit) {
+ if (dqzp->dqbz_ftimelimit == 0) {
+ strlcpy(ftimeleft, "NOT STARTED", sizeof (ftimeleft));
+ } else if (dqzp->dqbz_ftimelimit > tv.tv_sec) {
+ fmttime(ftimeleft, dqzp->dqbz_ftimelimit - tv.tv_sec);
+ } else {
+ strlcpy(ftimeleft, "EXPIRED", sizeof (ftimeleft));
+ }
+ } else {
+ ftimeleft[0] = '\0';
+ }
+ if (strlen(mntp->mnt_mountp) > 12) {
+ printf("%s\n", mntp->mnt_mountp);
+ cp = "";
+ } else {
+ cp = mntp->mnt_mountp;
+ }
+
+ if (dqzp->dqbz_curfiles == 0 &&
+ dqzp->dqbz_fsoftlimit == 0 && dqzp->dqbz_fhardlimit == 0) {
+ printf("%-12.12s %7llu %6llu %6llu %11s %6s %6s %6s %11s\n",
+ cp,
+ kb(dqzp->dqbz_curblocks),
+ kb(dqzp->dqbz_bsoftlimit),
+ kb(dqzp->dqbz_bhardlimit),
+ "-",
+ "-",
+ "-",
+ "-",
+ "-");
+ } else {
+ printf("%-12.12s %7llu %6llu %6llu %11s %6d %6d %6d %11s\n",
+ cp,
+ kb(dqzp->dqbz_curblocks),
+ kb(dqzp->dqbz_bsoftlimit),
+ kb(dqzp->dqbz_bhardlimit),
+ btimeleft,
+ dqzp->dqbz_curfiles,
+ dqzp->dqbz_fsoftlimit,
+ dqzp->dqbz_fhardlimit,
+ ftimeleft);
+ }
+ }
+
+ static void
zexit(int n)
{
if (g_zfs != NULL)
! libzfs_fini(g_zfs);
exit(n);
}