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