tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

dry-run (-n) option for quotacheck



I'm not sure whether this belongs in tech-userlevel since quotacheck(8) is
such a low-level program intefering with kernel data structures so this could
easily belong to tech-kern (or tech-fs, if there was such a list):

I felt like quotacheck(8) needs a dry-run option.
Actually, I'm investigating what supposedly is another error in quotacheck(8)
since if finds disk usage for uids for which find(1) doesn't find an inode.
Is the attached patch OK? Does anybody besides me find it useful?
The patch looks much more invasive than it actually is due to large blocks
of unchanged code being indented in "if (!nflag) { ... }" bodies.
--- quotacheck.c.orig   2007-05-20 16:27:37.000000000 +0200
+++ quotacheck.c        2008-10-21 11:03:10.000000000 +0200
@@ -141,6 +141,7 @@
 static int     uflag;          /* check user quotas */
 static int     vflag;          /* verbose */
 static int     qflag;          /* quick but untidy mode */
+static int     nflag;          /* dry run */
 static int     fi;             /* open disk file descriptor */
 static u_int32_t highid[MAXQUOTAS];/* highest addid()'ed identifier per type */
 static int needswap;   /* FS is in swapped order */
@@ -187,7 +188,7 @@
        int ch;
 
        errs = maxrun = 0;
-       while ((ch = getopt(argc, argv, "aguvqdl:")) != -1) {
+       while ((ch = getopt(argc, argv, "aguvqndl:")) != -1) {
                switch(ch) {
                case 'a':
                        aflag++;
@@ -204,6 +205,9 @@
                case 'q':
                        qflag++;
                        break;
+               case 'n':
+                       nflag++;
+                       break;
                case 'v':
                        vflag++;
                        break;
@@ -276,7 +280,7 @@
 {
 
        (void)fprintf(stderr,
-           "usage:\t%s -a [-gquv] [-l maxparallel]\n\t%s [-gquv] filesys 
...\n", getprogname(),
+           "usage:\t%s -a [-gnquv] [-l maxparallel]\n\t%s [-gnquv] filesys 
...\n", getprogname(),
            getprogname());
        exit(1);
 }
@@ -486,25 +490,29 @@
        static struct dqblk zerodqbuf;
        static struct fileusage zerofileusage;
 
-       if ((qfo = fopen(quotafile, "r+")) == NULL) {
-               if (errno == ENOENT)
-                       qfo = fopen(quotafile, "w+");
-               if (qfo) {
-                       (void) fprintf(stderr,
-                           "quotacheck: creating quota file %s\n", quotafile);
-#define        MODE    (S_IRUSR|S_IWUSR|S_IRGRP)
-                       (void) fchown(fileno(qfo), getuid(), getquotagid());
-                       (void) fchmod(fileno(qfo), MODE);
-               } else {
-                       (void) fprintf(stderr,
-                           "quotacheck: %s: %s\n", quotafile, strerror(errno));
-                       return (1);
+       if (!nflag) {
+               if ((qfo = fopen(quotafile, "r+")) == NULL) {
+                       if (errno == ENOENT)
+                               qfo = fopen(quotafile, "w+");
+                       if (qfo) {
+                               (void) fprintf(stderr,
+                                   "quotacheck: creating quota file %s\n", 
quotafile);
+       #define MODE    (S_IRUSR|S_IWUSR|S_IRGRP)
+                               (void) fchown(fileno(qfo), getuid(), 
getquotagid());
+                               (void) fchmod(fileno(qfo), MODE);
+                       } else {
+                               (void) fprintf(stderr,
+                                   "quotacheck: %s: %s\n", quotafile, 
strerror(errno));
+                               return (1);
+                       }
                }
-       }
+       } else
+               qfo = NULL; /* silence gcc */
        if ((qfi = fopen(quotafile, "r")) == NULL) {
                (void) fprintf(stderr,
                    "quotacheck: %s: %s\n", quotafile, strerror(errno));
-               (void) fclose(qfo);
+               if (!nflag)
+                       (void) fclose(qfo);
                return (1);
        }
        if (quotactl(fsname, QCMD(Q_SYNC, type), 0, (void *) NULL) < 0 &&
@@ -555,31 +563,33 @@
                                        dqbuf.dqb_curblocks, fup->fu_curblocks);
                        (void)printf("\n");
                }
-               /*
-                * Reset time limit if have a soft limit and were
-                * previously under it, but are now over it.
-                */
-               if (dqbuf.dqb_bsoftlimit &&
-                   dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit &&
-                   fup->fu_curblocks >= dqbuf.dqb_bsoftlimit)
-                       dqbuf.dqb_btime = 0;
-               if (dqbuf.dqb_isoftlimit &&
-                   dqbuf.dqb_curblocks < dqbuf.dqb_isoftlimit &&
-                   fup->fu_curblocks >= dqbuf.dqb_isoftlimit)
-                       dqbuf.dqb_itime = 0;
-               dqbuf.dqb_curinodes = fup->fu_curinodes;
-               dqbuf.dqb_curblocks = fup->fu_curblocks;
-
-               if (need_seek) {
-                       (void) fseeko(qfo, (off_t)id * sizeof(struct dqblk),
-                           SEEK_SET);
-                       need_seek = nextid != id + 1;
-               }
-               (void) fwrite((char *)&dqbuf, sizeof(struct dqblk), 1, qfo);
-
-               if (!warned)
-                       (void) quotactl(fsname, QCMD(Q_SETUSE, type), id,
-                           (caddr_t)&dqbuf);
+               if (!nflag) {
+                       /*
+                        * Reset time limit if have a soft limit and were
+                        * previously under it, but are now over it.
+                        */
+                       if (dqbuf.dqb_bsoftlimit &&
+                           dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit &&
+                           fup->fu_curblocks >= dqbuf.dqb_bsoftlimit)
+                               dqbuf.dqb_btime = 0;
+                       if (dqbuf.dqb_isoftlimit &&
+                           dqbuf.dqb_curblocks < dqbuf.dqb_isoftlimit &&
+                           fup->fu_curblocks >= dqbuf.dqb_isoftlimit)
+                               dqbuf.dqb_itime = 0;
+                       dqbuf.dqb_curinodes = fup->fu_curinodes;
+                       dqbuf.dqb_curblocks = fup->fu_curblocks;
+
+                       if (need_seek) {
+                               (void) fseeko(qfo, (off_t)id * sizeof(struct 
dqblk),
+                                   SEEK_SET);
+                               need_seek = nextid != id + 1;
+                       }
+                       (void) fwrite((char *)&dqbuf, sizeof(struct dqblk), 1, 
qfo);
+
+                       if (!warned)
+                               (void) quotactl(fsname, QCMD(Q_SETUSE, type), 
id,
+                                   (caddr_t)&dqbuf);
+               }
 
                fup->fu_curinodes = 0;
                fup->fu_curblocks = 0;
@@ -588,11 +598,13 @@
                }
        }
        (void) fclose(qfi);
-       (void) fflush(qfo);
-       if (highid[type] != UINT32_MAX)
-               (void) ftruncate(fileno(qfo),
-                   (off_t)((highid[type] + 1) * sizeof(struct dqblk)));
-       (void) fclose(qfo);
+       if (!nflag) {
+               (void) fflush(qfo);
+               if (highid[type] != UINT32_MAX)
+                       (void) ftruncate(fileno(qfo),
+                           (off_t)((highid[type] + 1) * sizeof(struct dqblk)));
+               (void) fclose(qfo);
+       }
        return (0);
 }
 
--- quotacheck.8.orig   2004-01-05 19:46:44.000000000 +0100
+++ quotacheck.8        2008-10-20 21:51:01.000000000 +0200
@@ -40,10 +40,10 @@
 .Nd filesystem quota consistency checker
 .Sh SYNOPSIS
 .Nm
-.Op Fl gquv
+.Op Fl gnquv
 .Ar filesystem Ar ...
 .Nm
-.Op Fl gquv
+.Op Fl gnquv
 .Op Fl l Ar maxparallel
 .Fl a
 .Sh DESCRIPTION
@@ -107,6 +107,13 @@
 is more verbose,
 and reports corrected discrepancies between the
 calculated and recorded disk quotas.
+.It Fl n
+.Nm
+updates neither the quota file nor the current system copy
+of any incorrect quotas.
+This is useful mostly with the
+.It Fl v
+option.
 .El
 .Pp
 Specifying both


Home | Main Index | Thread Index | Old Index