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>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/fs.d/ufs/quota/quota.c
          +++ new/usr/src/cmd/fs.d/ufs/quota/quota.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  
       26 +/* Copyright 2016 Nexenta Systems, Inc.  All rights reserved. */
       27 +
  26   28  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  27   29  /*        All Rights Reserved   */
  28   30  
  29   31  /*
  30   32   * University Copyright- Copyright (c) 1982, 1986, 1988
  31   33   * The Regents of the University of California
  32   34   * All Rights Reserved
  33   35   *
  34   36   * University Acknowledgment- Portions of this document are derived from
  35   37   * software developed by the University of California, Berkeley, and its
↓ open down ↓ 24 lines elided ↑ open up ↑
  60   62  #include <netdb.h>
  61   63  #include <rpcsvc/rquota.h>
  62   64  #include <zone.h>
  63   65  #include "../../nfs/lib/replica.h"
  64   66  #include <dlfcn.h>
  65   67  #include <libzfs.h>
  66   68  
  67   69  int     vflag;
  68   70  int     nolocalquota;
  69   71  
       72 +/*
       73 + * struct dqblk is a 32 bit quantity and is common across NFS and UFS.
       74 + * UFS has a 2TB limit and an uint32_t can hold this value.
       75 + * NFS translates this to rquota where all members are unit32_t in size.
       76 + * A private dqblk, dqblk_zfs is defined here.
       77 + */
       78 +struct dqblk_zfs {
       79 +        uint64_t  dqbz_bhardlimit; /* absolute limit on disk blks alloc */
       80 +        uint64_t  dqbz_bsoftlimit; /* preferred limit on disk blks */
       81 +        uint64_t  dqbz_curblocks;  /* current block count */
       82 +        uint64_t  dqbz_fhardlimit; /* maximum # allocated files + 1 */
       83 +        uint64_t  dqbz_fsoftlimit; /* preferred file limit */
       84 +        uint64_t  dqbz_curfiles;   /* current # allocated files */
       85 +        uint64_t  dqbz_btimelimit; /* time limit for excessive disk use */
       86 +        uint64_t  dqbz_ftimelimit; /* time limit for excessive files */
       87 +};
  70   88  extern int      optind;
  71   89  extern char     *optarg;
  72   90  
  73   91  #define QFNAME  "quotas"
  74   92  
  75   93  #if DEV_BSIZE < 1024
  76   94  #define kb(x)   ((x) / (1024 / DEV_BSIZE))
  77   95  #else
  78   96  #define kb(x)   ((x) * (DEV_BSIZE / 1024))
  79   97  #endif
  80   98  
  81   99  #if     !defined(TEXT_DOMAIN)   /* Should be defined by cc -D */
  82  100  #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
  83  101  #endif
  84  102  
  85  103  static void zexit(int);
  86      -static int getzfsquota(char *, char *, struct dqblk *);
      104 +static boolean_t blklimits_is_zero(struct dqblk *, struct dqblk_zfs *);
      105 +static int getzfsquota(char *, char *, struct dqblk_zfs *);
  87  106  static int getnfsquota(char *, char *, uid_t, struct dqblk *);
  88  107  static void showuid(uid_t);
  89  108  static void showquotas(uid_t, char *);
  90      -static void warn(struct mnttab *, struct dqblk *);
      109 +static void warn(struct mnttab *, struct dqblk *, struct dqblk_zfs *);
      110 +static void warn_dqblk_impl(struct mnttab *, struct dqblk *);
      111 +static void warn_dqblk_zfs_impl(struct mnttab *, struct dqblk_zfs *);
  91  112  static void heading(uid_t, char *);
  92      -static void prquota(struct mnttab *, struct dqblk *);
      113 +static void prquota(struct mnttab *, struct dqblk *, struct dqblk_zfs *);
      114 +static void prquota_dqblk_impl(struct mnttab *, struct dqblk *);
      115 +static void prquota_dqblk_zfs_impl(struct mnttab *, struct dqblk_zfs *);
  93  116  static void fmttime(char *, long);
  94  117  
  95      -static libzfs_handle_t *(*_libzfs_init)(void);
  96      -static void (*_libzfs_fini)(libzfs_handle_t *);
  97      -static zfs_handle_t *(*_zfs_open)(libzfs_handle_t *, const char *, int);
  98      -static void (*_zfs_close)(zfs_handle_t *);
  99      -static int (*_zfs_prop_get_userquota_int)(zfs_handle_t *, const char *,
 100      -    uint64_t *);
 101  118  static libzfs_handle_t *g_zfs = NULL;
 102  119  
 103      -/*
 104      - * Dynamically check for libzfs, in case the user hasn't installed the SUNWzfs
 105      - * packages.  'quota' utility supports zfs as an option.
 106      - */
 107      -static void
 108      -load_libzfs(void)
 109      -{
 110      -        void *hdl;
 111      -
 112      -        if (g_zfs != NULL)
 113      -                return;
 114      -
 115      -        if ((hdl = dlopen("libzfs.so", RTLD_LAZY)) != NULL) {
 116      -                _libzfs_init = (libzfs_handle_t *(*)(void))dlsym(hdl,
 117      -                    "libzfs_init");
 118      -                _libzfs_fini = (void (*)())dlsym(hdl, "libzfs_fini");
 119      -                _zfs_open = (zfs_handle_t *(*)())dlsym(hdl, "zfs_open");
 120      -                _zfs_close = (void (*)())dlsym(hdl, "zfs_close");
 121      -                _zfs_prop_get_userquota_int = (int (*)())
 122      -                    dlsym(hdl, "zfs_prop_get_userquota_int");
 123      -
 124      -                if (_libzfs_init && _libzfs_fini && _zfs_open &&
 125      -                    _zfs_close && _zfs_prop_get_userquota_int)
 126      -                        g_zfs = _libzfs_init();
 127      -        }
 128      -}
 129      -
 130  120  int
 131  121  main(int argc, char *argv[])
 132  122  {
 133  123          int     opt;
 134  124          int     i;
 135  125          int     status = 0;
 136  126  
 137  127          (void) setlocale(LC_ALL, "");
 138  128          (void) textdomain(TEXT_DOMAIN);
 139  129  
↓ open down ↓ 6 lines elided ↑ open up ↑
 146  136          if (__init_suid_priv(PU_CLEARLIMITSET, PRIV_FILE_DAC_READ,
 147  137              NULL) == -1) {
 148  138                  (void) fprintf(stderr,
 149  139                      gettext("Insufficient privileges, "
 150  140                      "quota must be set-uid root or have "
 151  141                      "file_dac_read privileges\n"));
 152  142  
 153  143                  exit(1);
 154  144          }
 155  145  
 156      -        load_libzfs();
 157  146  
 158  147          while ((opt = getopt(argc, argv, "vV")) != EOF) {
 159  148                  switch (opt) {
 160  149  
 161  150                  case 'v':
 162  151                          vflag++;
 163  152                          break;
 164  153  
 165  154                  case 'V':               /* Print command line */
 166  155                          {
↓ open down ↓ 68 lines elided ↑ open up ↑
 235  224          showquotas(pwd->pw_uid, name);
 236  225          return (0);
 237  226  }
 238  227  
 239  228  static void
 240  229  showquotas(uid_t uid, char *name)
 241  230  {
 242  231          struct mnttab mnt;
 243  232          FILE *mtab;
 244  233          struct dqblk dqblk;
      234 +        struct dqblk_zfs dqblkz;
 245  235          uid_t myuid;
 246  236          struct failed_srv {
 247  237                  char *serv_name;
 248  238                  struct failed_srv *next;
 249  239          };
 250  240          struct failed_srv *failed_srv_list = NULL;
 251  241          int     rc;
 252  242          char    my_zonename[ZONENAME_MAX];
 253  243          zoneid_t my_zoneid = getzoneid();
 254  244  
↓ open down ↓ 3 lines elided ↑ open up ↑
 258  248                  zexit(32);
 259  249          }
 260  250  
 261  251          memset(my_zonename, '\0', ZONENAME_MAX);
 262  252          getzonenamebyid(my_zoneid, my_zonename, ZONENAME_MAX);
 263  253  
 264  254          if (vflag)
 265  255                  heading(uid, name);
 266  256          mtab = fopen(MNTTAB, "r");
 267  257          while (getmntent(mtab, &mnt) == NULL) {
      258 +                boolean_t is_zfs = B_FALSE;
      259 +
 268  260                  if (strcmp(mnt.mnt_fstype, MNTTYPE_ZFS) == 0) {
 269      -                        bzero(&dqblk, sizeof (dqblk));
 270      -                        if (getzfsquota(name, mnt.mnt_special, &dqblk))
      261 +                        is_zfs = B_TRUE;
      262 +                        bzero(&dqblkz, sizeof (dqblkz));
      263 +                        if (getzfsquota(name, mnt.mnt_special, &dqblkz))
 271  264                                  continue;
 272  265                  } else if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) == 0) {
 273  266                          if (nolocalquota ||
 274  267                              (quotactl(Q_GETQUOTA,
 275  268                              mnt.mnt_mountp, uid, &dqblk) != 0 &&
 276  269                              !(vflag && getdiskquota(&mnt, uid, &dqblk))))
 277  270                                  continue;
 278  271                  } else if (strcmp(mnt.mnt_fstype, MNTTYPE_NFS) == 0) {
 279  272  
 280  273                          struct replica *rl;
↓ open down ↓ 123 lines elided ↑ open up ↑
 404  397                                  }
 405  398  
 406  399                                  free_replica(rl, count);
 407  400                                  continue;
 408  401                          }
 409  402  
 410  403                          free_replica(rl, count);
 411  404                  } else {
 412  405                          continue;
 413  406                  }
 414      -                if (dqblk.dqb_bsoftlimit == 0 && dqblk.dqb_bhardlimit == 0 &&
 415      -                    dqblk.dqb_fsoftlimit == 0 && dqblk.dqb_fhardlimit == 0)
      407 +
      408 +                if (blklimits_is_zero(&dqblk, is_zfs ? &dqblkz : NULL))
 416  409                          continue;
      410 +
 417  411                  if (vflag)
 418      -                        prquota(&mnt, &dqblk);
      412 +                        prquota(&mnt, &dqblk, is_zfs ? &dqblkz : NULL);
 419  413                  else
 420      -                        warn(&mnt, &dqblk);
      414 +                        warn(&mnt, &dqblk, is_zfs ? &dqblkz : NULL);
      415 +
 421  416          }
 422  417  
 423  418          /*
 424  419           * Free list of failed servers
 425  420           */
 426  421          while (failed_srv_list != NULL) {
 427  422                  struct failed_srv *tmp_srv = failed_srv_list;
 428  423  
 429  424                  failed_srv_list = failed_srv_list->next;
 430  425                  free(tmp_srv->serv_name);
 431  426                  free(tmp_srv);
 432  427          }
 433  428  
 434  429          fclose(mtab);
 435  430  }
 436  431  
 437  432  static void
 438      -warn(struct mnttab *mntp, struct dqblk *dqp)
      433 +warn(struct mnttab *mntp, struct dqblk *dqp, struct dqblk_zfs *dqzp)
 439  434  {
 440      -        struct timeval tv;
 441      -
 442      -        time(&(tv.tv_sec));
 443      -        tv.tv_usec = 0;
 444      -        if (dqp->dqb_bhardlimit &&
 445      -            dqp->dqb_curblocks >= dqp->dqb_bhardlimit) {
 446      -                printf("Block limit reached on %s\n", mntp->mnt_mountp);
 447      -        } else if (dqp->dqb_bsoftlimit &&
 448      -            dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
 449      -                if (dqp->dqb_btimelimit == 0) {
 450      -                        printf("Over disk quota on %s, remove %luK\n",
 451      -                            mntp->mnt_mountp,
 452      -                            kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1));
 453      -                } else if (dqp->dqb_btimelimit > tv.tv_sec) {
 454      -                        char btimeleft[80];
 455      -
 456      -                        fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
 457      -                        printf("Over disk quota on %s, remove %luK within %s\n",
 458      -                            mntp->mnt_mountp,
 459      -                            kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1),
 460      -                            btimeleft);
 461      -                } else {
 462      -                        printf(
 463      -                "Over disk quota on %s, time limit has expired, remove %luK\n",
 464      -                            mntp->mnt_mountp,
 465      -                            kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1));
 466      -                }
 467      -        }
 468      -        if (dqp->dqb_fhardlimit &&
 469      -            dqp->dqb_curfiles >= dqp->dqb_fhardlimit) {
 470      -                printf("File count limit reached on %s\n", mntp->mnt_mountp);
 471      -        } else if (dqp->dqb_fsoftlimit &&
 472      -            dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
 473      -                if (dqp->dqb_ftimelimit == 0) {
 474      -                        printf("Over file quota on %s, remove %lu file%s\n",
 475      -                            mntp->mnt_mountp,
 476      -                            dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
 477      -                            ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
 478      -                            "s" : ""));
 479      -                } else if (dqp->dqb_ftimelimit > tv.tv_sec) {
 480      -                        char ftimeleft[80];
 481      -
 482      -                        fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
 483      -                        printf(
 484      -"Over file quota on %s, remove %lu file%s within %s\n",
 485      -                            mntp->mnt_mountp,
 486      -                            dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
 487      -                            ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
 488      -                            "s" : ""), ftimeleft);
 489      -                } else {
 490      -                        printf(
 491      -"Over file quota on %s, time limit has expired, remove %lu file%s\n",
 492      -                            mntp->mnt_mountp,
 493      -                            dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
 494      -                            ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
 495      -                            "s" : ""));
 496      -                }
 497      -        }
      435 +        if (dqzp != NULL)
      436 +                warn_dqblk_zfs_impl(mntp, dqzp);
      437 +        else
      438 +                warn_dqblk_impl(mntp, dqp);
 498  439  }
 499  440  
 500  441  static void
 501  442  heading(uid_t uid, char *name)
 502  443  {
 503  444          printf("Disk quotas for %s (uid %ld):\n", name, (long)uid);
 504  445          printf("%-12s %7s%7s%7s%12s%7s%7s%7s%12s\n",
 505  446              "Filesystem",
 506  447              "usage",
 507  448              "quota",
 508  449              "limit",
 509  450              "timeleft",
 510  451              "files",
 511  452              "quota",
 512  453              "limit",
 513  454              "timeleft");
 514  455  }
 515  456  
 516  457  static void
 517      -prquota(struct mnttab *mntp, struct dqblk *dqp)
      458 +prquota(struct mnttab *mntp, struct dqblk *dqp, struct dqblk_zfs *dqzp)
 518  459  {
 519      -        struct timeval tv;
 520      -        char ftimeleft[80], btimeleft[80];
 521      -        char *cp;
 522      -
 523      -        time(&(tv.tv_sec));
 524      -        tv.tv_usec = 0;
 525      -        if (dqp->dqb_bsoftlimit && dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
 526      -                if (dqp->dqb_btimelimit == 0) {
 527      -                        strlcpy(btimeleft, "NOT STARTED", sizeof (btimeleft));
 528      -                } else if (dqp->dqb_btimelimit > tv.tv_sec) {
 529      -                        fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
 530      -                } else {
 531      -                        strlcpy(btimeleft, "EXPIRED", sizeof (btimeleft));
 532      -                }
 533      -        } else {
 534      -                btimeleft[0] = '\0';
 535      -        }
 536      -        if (dqp->dqb_fsoftlimit && dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
 537      -                if (dqp->dqb_ftimelimit == 0) {
 538      -                        strlcpy(ftimeleft, "NOT STARTED", sizeof (ftimeleft));
 539      -                } else if (dqp->dqb_ftimelimit > tv.tv_sec) {
 540      -                        fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
 541      -                } else {
 542      -                        strlcpy(ftimeleft, "EXPIRED", sizeof (ftimeleft));
 543      -                }
 544      -        } else {
 545      -                ftimeleft[0] = '\0';
 546      -        }
 547      -        if (strlen(mntp->mnt_mountp) > 12) {
 548      -                printf("%s\n", mntp->mnt_mountp);
 549      -                cp = "";
 550      -        } else {
 551      -                cp = mntp->mnt_mountp;
 552      -        }
 553      -
 554      -        if (dqp->dqb_curfiles == 0 &&
 555      -            dqp->dqb_fsoftlimit == 0 && dqp->dqb_fhardlimit == 0) {
 556      -                printf("%-12.12s %7d %6d %6d %11s %6s %6s %6s %11s\n",
 557      -                    cp,
 558      -                    kb(dqp->dqb_curblocks),
 559      -                    kb(dqp->dqb_bsoftlimit),
 560      -                    kb(dqp->dqb_bhardlimit),
 561      -                    "-",
 562      -                    "-",
 563      -                    "-",
 564      -                    "-",
 565      -                    "-");
 566      -        } else {
 567      -                printf("%-12.12s %7d %6d %6d %11s %6d %6d %6d %11s\n",
 568      -                    cp,
 569      -                    kb(dqp->dqb_curblocks),
 570      -                    kb(dqp->dqb_bsoftlimit),
 571      -                    kb(dqp->dqb_bhardlimit),
 572      -                    btimeleft,
 573      -                    dqp->dqb_curfiles,
 574      -                    dqp->dqb_fsoftlimit,
 575      -                    dqp->dqb_fhardlimit,
 576      -                    ftimeleft);
 577      -        }
      460 +        if (dqzp != NULL)
      461 +                prquota_dqblk_zfs_impl(mntp, dqzp);
      462 +        else
      463 +                prquota_dqblk_impl(mntp, dqp);
 578  464  }
 579  465  
 580  466  static void
 581  467  fmttime(char *buf, long time)
 582  468  {
 583  469          int i;
 584  470          static struct {
 585  471                  int c_secs;             /* conversion units in secs */
 586  472                  char *c_str;            /* unit string */
 587  473          } cunits [] = {
↓ open down ↓ 228 lines elided ↑ open up ↑
 816  702          default:
 817  703                  fprintf(stderr, "bad rpc result, host: %s\n",  hostp);
 818  704                  return (RPC_CANTDECODEARGS);
 819  705          }
 820  706  
 821  707          /* NOTREACHED */
 822  708  }
 823  709  
 824  710  int
 825  711  callaurpc(char *host, int prognum, int versnum, int procnum,
 826      -                xdrproc_t inproc, char *in, xdrproc_t outproc, char *out)
      712 +    xdrproc_t inproc, char *in, xdrproc_t outproc, char *out)
 827  713  {
 828  714          static enum clnt_stat clnt_stat;
 829  715          struct timeval tottimeout = {20, 0};
 830  716  
 831  717          static CLIENT *cl = NULL;
 832  718          static int oldprognum, oldversnum;
 833  719          static char oldhost[MAXHOSTNAMELEN+1];
 834  720  
 835  721          /*
 836  722           * Cache the client handle in case there are lots
↓ open down ↓ 24 lines elided ↑ open up ↑
 861  747          if (clnt_stat != RPC_SUCCESS)
 862  748                  return ((int)clnt_stat);        /* don't bother retrying */
 863  749  
 864  750          clnt_stat = clnt_call(cl, procnum, inproc, in,
 865  751              outproc, out, tottimeout);
 866  752  
 867  753          return ((int)clnt_stat);
 868  754  }
 869  755  
 870  756  static int
 871      -getzfsquota(char *user, char *dataset, struct dqblk *zq)
      757 +getzfsquota(char *user, char *dataset, struct dqblk_zfs *zq)
 872  758  {
 873  759          zfs_handle_t *zhp = NULL;
 874  760          char propname[ZFS_MAXPROPLEN];
 875  761          uint64_t userquota, userused;
 876  762  
 877      -        if (g_zfs == NULL)
 878      -                return (1);
      763 +        if (g_zfs == NULL) {
      764 +                g_zfs = libzfs_init();
      765 +        }
 879  766  
 880      -        if ((zhp = _zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
      767 +        if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
 881  768                  return (1);
 882  769  
 883  770          (void) snprintf(propname, sizeof (propname), "userquota@%s", user);
 884      -        if (_zfs_prop_get_userquota_int(zhp, propname, &userquota) != 0) {
 885      -                _zfs_close(zhp);
      771 +        if (zfs_prop_get_userquota_int(zhp, propname, &userquota) != 0) {
      772 +                zfs_close(zhp);
 886  773                  return (1);
 887  774          }
 888  775  
 889  776          (void) snprintf(propname, sizeof (propname), "userused@%s", user);
 890      -        if (_zfs_prop_get_userquota_int(zhp, propname, &userused) != 0) {
 891      -                _zfs_close(zhp);
      777 +        if (zfs_prop_get_userquota_int(zhp, propname, &userused) != 0) {
      778 +                zfs_close(zhp);
 892  779                  return (1);
 893  780          }
 894  781  
 895      -        zq->dqb_bhardlimit = userquota / DEV_BSIZE;
 896      -        zq->dqb_bsoftlimit = userquota / DEV_BSIZE;
 897      -        zq->dqb_curblocks = userused / DEV_BSIZE;
 898      -        _zfs_close(zhp);
      782 +        zq->dqbz_bhardlimit = userquota / DEV_BSIZE;
      783 +        zq->dqbz_bsoftlimit = userquota / DEV_BSIZE;
      784 +        zq->dqbz_curblocks = userused / DEV_BSIZE;
      785 +        zfs_close(zhp);
 899  786          return (0);
 900  787  }
 901  788  
      789 +static boolean_t
      790 +blklimits_is_zero(struct dqblk *dqp, struct dqblk_zfs *dqzp)
      791 +{
      792 +        if (dqzp == NULL) {
      793 +                if (dqp->dqb_bsoftlimit == 0 && dqp->dqb_bhardlimit == 0 &&
      794 +                    dqp->dqb_fsoftlimit == 0 && dqp->dqb_fhardlimit == 0) {
      795 +                        return (B_TRUE);
      796 +                } else {
      797 +                        return (B_FALSE);
      798 +                }
      799 +        } else {
      800 +                if (dqzp->dqbz_bsoftlimit == 0 && dqzp->dqbz_bhardlimit == 0 &&
      801 +                    dqzp->dqbz_fsoftlimit == 0 && dqzp->dqbz_fhardlimit == 0) {
      802 +                        return (B_TRUE);
      803 +                } else {
      804 +                        return (B_FALSE);
      805 +                }
      806 +        }
      807 +}
      808 +
 902  809  static void
      810 +warn_dqblk_impl(struct mnttab *mntp, struct dqblk *dqp)
      811 +{
      812 +        struct timeval tv;
      813 +
      814 +        time(&(tv.tv_sec));
      815 +        tv.tv_usec = 0;
      816 +        if (dqp->dqb_bhardlimit &&
      817 +            dqp->dqb_curblocks >= dqp->dqb_bhardlimit) {
      818 +                printf("Block limit reached on %s\n", mntp->mnt_mountp);
      819 +        } else if (dqp->dqb_bsoftlimit &&
      820 +            dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
      821 +                if (dqp->dqb_btimelimit == 0) {
      822 +                        printf("Over disk quota on %s, remove %luK\n",
      823 +                            mntp->mnt_mountp,
      824 +                            kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1));
      825 +                } else if (dqp->dqb_btimelimit > tv.tv_sec) {
      826 +                        char btimeleft[80];
      827 +
      828 +                        fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
      829 +                        printf("Over disk quota on %s, remove %luK within %s\n",
      830 +                            mntp->mnt_mountp,
      831 +                            kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1),
      832 +                            btimeleft);
      833 +                } else {
      834 +                        printf("Over disk quota on %s, time limit has expired,"
      835 +                            " remove %luK\n", mntp->mnt_mountp,
      836 +                            kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1));
      837 +                }
      838 +        }
      839 +        if (dqp->dqb_fhardlimit &&
      840 +            dqp->dqb_curfiles >= dqp->dqb_fhardlimit) {
      841 +                printf("File count limit reached on %s\n", mntp->mnt_mountp);
      842 +        } else if (dqp->dqb_fsoftlimit &&
      843 +            dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
      844 +                if (dqp->dqb_ftimelimit == 0) {
      845 +                        printf("Over file quota on %s, remove %lu file%s\n",
      846 +                            mntp->mnt_mountp,
      847 +                            dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
      848 +                            ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
      849 +                            "s" : ""));
      850 +                } else if (dqp->dqb_ftimelimit > tv.tv_sec) {
      851 +                        char ftimeleft[80];
      852 +
      853 +                        fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
      854 +                        printf("Over file quota on %s, remove %lu file%s"
      855 +                            " within %s\n", mntp->mnt_mountp,
      856 +                            dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
      857 +                            ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
      858 +                            "s" : ""), ftimeleft);
      859 +                } else {
      860 +                        printf("Over file quota on %s, time limit has expired,"
      861 +                            " remove %lu file%s\n", mntp->mnt_mountp,
      862 +                            dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
      863 +                            ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
      864 +                            "s" : ""));
      865 +                }
      866 +        }
      867 +}
      868 +
      869 +static void
      870 +warn_dqblk_zfs_impl(struct mnttab *mntp, struct dqblk_zfs *dqzp)
      871 +{
      872 +        struct timeval tv;
      873 +
      874 +        time(&(tv.tv_sec));
      875 +        tv.tv_usec = 0;
      876 +        if (dqzp->dqbz_bhardlimit &&
      877 +            dqzp->dqbz_curblocks >= dqzp->dqbz_bhardlimit) {
      878 +                printf("Block limit reached on %s\n", mntp->mnt_mountp);
      879 +        } else if (dqzp->dqbz_bsoftlimit &&
      880 +            dqzp->dqbz_curblocks >= dqzp->dqbz_bsoftlimit) {
      881 +                if (dqzp->dqbz_btimelimit == 0) {
      882 +                        printf("Over disk quota on %s, remove %luK\n",
      883 +                            mntp->mnt_mountp,
      884 +                            kb(dqzp->dqbz_curblocks -
      885 +                            dqzp->dqbz_bsoftlimit + 1));
      886 +                } else if (dqzp->dqbz_btimelimit > tv.tv_sec) {
      887 +                        char btimeleft[80];
      888 +
      889 +                        fmttime(btimeleft, dqzp->dqbz_btimelimit - tv.tv_sec);
      890 +                        printf("Over disk quota on %s, remove %luK within %s\n",
      891 +                            mntp->mnt_mountp,
      892 +                            kb(dqzp->dqbz_curblocks -
      893 +                            dqzp->dqbz_bsoftlimit + 1),
      894 +                            btimeleft);
      895 +                } else {
      896 +                        printf("Over disk quota on %s, time limit has expired,"
      897 +                            " remove %luK\n", mntp->mnt_mountp,
      898 +                            kb(dqzp->dqbz_curblocks -
      899 +                            dqzp->dqbz_bsoftlimit + 1));
      900 +                }
      901 +        }
      902 +        if (dqzp->dqbz_fhardlimit &&
      903 +            dqzp->dqbz_curfiles >= dqzp->dqbz_fhardlimit) {
      904 +                printf("File count limit reached on %s\n", mntp->mnt_mountp);
      905 +        } else if (dqzp->dqbz_fsoftlimit &&
      906 +            dqzp->dqbz_curfiles >= dqzp->dqbz_fsoftlimit) {
      907 +                if (dqzp->dqbz_ftimelimit == 0) {
      908 +                        printf("Over file quota on %s, remove %lu file%s\n",
      909 +                            mntp->mnt_mountp,
      910 +                            dqzp->dqbz_curfiles - dqzp->dqbz_fsoftlimit + 1,
      911 +                            ((dqzp->dqbz_curfiles -
      912 +                            dqzp->dqbz_fsoftlimit + 1) > 1 ?
      913 +                            "s" : ""));
      914 +                } else if (dqzp->dqbz_ftimelimit > tv.tv_sec) {
      915 +                        char ftimeleft[80];
      916 +
      917 +                        fmttime(ftimeleft, dqzp->dqbz_ftimelimit - tv.tv_sec);
      918 +                        printf("Over file quota on %s, remove %lu file%s "
      919 +                            " within %s\n", mntp->mnt_mountp,
      920 +                            dqzp->dqbz_curfiles - dqzp->dqbz_fsoftlimit + 1,
      921 +                            ((dqzp->dqbz_curfiles -
      922 +                            dqzp->dqbz_fsoftlimit + 1) > 1 ?
      923 +                            "s" : ""), ftimeleft);
      924 +                } else {
      925 +                        printf("Over file quota on %s, time limit has expired,"
      926 +                            " remove %lu file%s\n", mntp->mnt_mountp,
      927 +                            dqzp->dqbz_curfiles - dqzp->dqbz_fsoftlimit + 1,
      928 +                            ((dqzp->dqbz_curfiles -
      929 +                            dqzp->dqbz_fsoftlimit + 1) > 1 ?
      930 +                            "s" : ""));
      931 +                }
      932 +        }
      933 +}
      934 +
      935 +static void
      936 +prquota_dqblk_impl(struct mnttab *mntp, struct dqblk *dqp)
      937 +{
      938 +        struct timeval tv;
      939 +        char ftimeleft[80], btimeleft[80];
      940 +        char *cp;
      941 +
      942 +        time(&(tv.tv_sec));
      943 +        tv.tv_usec = 0;
      944 +        if (dqp->dqb_bsoftlimit && dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
      945 +                if (dqp->dqb_btimelimit == 0) {
      946 +                        strlcpy(btimeleft, "NOT STARTED", sizeof (btimeleft));
      947 +                } else if (dqp->dqb_btimelimit > tv.tv_sec) {
      948 +                        fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
      949 +                } else {
      950 +                        strlcpy(btimeleft, "EXPIRED", sizeof (btimeleft));
      951 +                }
      952 +        } else {
      953 +                btimeleft[0] = '\0';
      954 +        }
      955 +        if (dqp->dqb_fsoftlimit && dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
      956 +                if (dqp->dqb_ftimelimit == 0) {
      957 +                        strlcpy(ftimeleft, "NOT STARTED", sizeof (ftimeleft));
      958 +                } else if (dqp->dqb_ftimelimit > tv.tv_sec) {
      959 +                        fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
      960 +                } else {
      961 +                        strlcpy(ftimeleft, "EXPIRED", sizeof (ftimeleft));
      962 +                }
      963 +        } else {
      964 +                ftimeleft[0] = '\0';
      965 +        }
      966 +        if (strlen(mntp->mnt_mountp) > 12) {
      967 +                printf("%s\n", mntp->mnt_mountp);
      968 +                cp = "";
      969 +        } else {
      970 +                cp = mntp->mnt_mountp;
      971 +        }
      972 +
      973 +        if (dqp->dqb_curfiles == 0 &&
      974 +            dqp->dqb_fsoftlimit == 0 && dqp->dqb_fhardlimit == 0) {
      975 +                printf("%-12.12s %7d %6d %6d %11s %6s %6s %6s %11s\n",
      976 +                    cp,
      977 +                    kb(dqp->dqb_curblocks),
      978 +                    kb(dqp->dqb_bsoftlimit),
      979 +                    kb(dqp->dqb_bhardlimit),
      980 +                    "-",
      981 +                    "-",
      982 +                    "-",
      983 +                    "-",
      984 +                    "-");
      985 +        } else {
      986 +                printf("%-12.12s %7d %6d %6d %11s %6d %6d %6d %11s\n",
      987 +                    cp,
      988 +                    kb(dqp->dqb_curblocks),
      989 +                    kb(dqp->dqb_bsoftlimit),
      990 +                    kb(dqp->dqb_bhardlimit),
      991 +                    btimeleft,
      992 +                    dqp->dqb_curfiles,
      993 +                    dqp->dqb_fsoftlimit,
      994 +                    dqp->dqb_fhardlimit,
      995 +                    ftimeleft);
      996 +        }
      997 +}
      998 +
      999 +static void
     1000 +prquota_dqblk_zfs_impl(struct mnttab *mntp, struct dqblk_zfs *dqzp)
     1001 +{
     1002 +        struct timeval tv;
     1003 +        char ftimeleft[80], btimeleft[80];
     1004 +        char *cp;
     1005 +
     1006 +        time(&(tv.tv_sec));
     1007 +        tv.tv_usec = 0;
     1008 +        if (dqzp->dqbz_bsoftlimit &&
     1009 +            dqzp->dqbz_curblocks >= dqzp->dqbz_bsoftlimit) {
     1010 +                if (dqzp->dqbz_btimelimit == 0) {
     1011 +                        strlcpy(btimeleft, "NOT STARTED", sizeof (btimeleft));
     1012 +                } else if (dqzp->dqbz_btimelimit > tv.tv_sec) {
     1013 +                        fmttime(btimeleft, dqzp->dqbz_btimelimit - tv.tv_sec);
     1014 +                } else {
     1015 +                        strlcpy(btimeleft, "EXPIRED", sizeof (btimeleft));
     1016 +                }
     1017 +        } else {
     1018 +                btimeleft[0] = '\0';
     1019 +        }
     1020 +        if (dqzp->dqbz_fsoftlimit &&
     1021 +            dqzp->dqbz_curfiles >= dqzp->dqbz_fsoftlimit) {
     1022 +                if (dqzp->dqbz_ftimelimit == 0) {
     1023 +                        strlcpy(ftimeleft, "NOT STARTED", sizeof (ftimeleft));
     1024 +                } else if (dqzp->dqbz_ftimelimit > tv.tv_sec) {
     1025 +                        fmttime(ftimeleft, dqzp->dqbz_ftimelimit - tv.tv_sec);
     1026 +                } else {
     1027 +                        strlcpy(ftimeleft, "EXPIRED", sizeof (ftimeleft));
     1028 +                }
     1029 +        } else {
     1030 +                ftimeleft[0] = '\0';
     1031 +        }
     1032 +        if (strlen(mntp->mnt_mountp) > 12) {
     1033 +                printf("%s\n", mntp->mnt_mountp);
     1034 +                cp = "";
     1035 +        } else {
     1036 +                cp = mntp->mnt_mountp;
     1037 +        }
     1038 +
     1039 +        if (dqzp->dqbz_curfiles == 0 &&
     1040 +            dqzp->dqbz_fsoftlimit == 0 && dqzp->dqbz_fhardlimit == 0) {
     1041 +                printf("%-12.12s %7llu %6llu %6llu %11s %6s %6s %6s %11s\n",
     1042 +                    cp,
     1043 +                    kb(dqzp->dqbz_curblocks),
     1044 +                    kb(dqzp->dqbz_bsoftlimit),
     1045 +                    kb(dqzp->dqbz_bhardlimit),
     1046 +                    "-",
     1047 +                    "-",
     1048 +                    "-",
     1049 +                    "-",
     1050 +                    "-");
     1051 +        } else {
     1052 +                printf("%-12.12s %7llu %6llu %6llu %11s %6d %6d %6d %11s\n",
     1053 +                    cp,
     1054 +                    kb(dqzp->dqbz_curblocks),
     1055 +                    kb(dqzp->dqbz_bsoftlimit),
     1056 +                    kb(dqzp->dqbz_bhardlimit),
     1057 +                    btimeleft,
     1058 +                    dqzp->dqbz_curfiles,
     1059 +                    dqzp->dqbz_fsoftlimit,
     1060 +                    dqzp->dqbz_fhardlimit,
     1061 +                    ftimeleft);
     1062 +        }
     1063 +}
     1064 +
     1065 +static void
 903 1066  zexit(int n)
 904 1067  {
 905 1068          if (g_zfs != NULL)
 906      -                _libzfs_fini(g_zfs);
     1069 +                libzfs_fini(g_zfs);
 907 1070          exit(n);
 908 1071  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX