Source-Changes-HG archive

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

[src/netbsd-6]: src/usr.sbin/edquota Pull up following revision(s) (requested...



details:   https://anonhg.NetBSD.org/src/rev/2e367fd2d350
branches:  netbsd-6
changeset: 774447:2e367fd2d350
user:      riz <riz%NetBSD.org@localhost>
date:      Wed Aug 15 00:35:04 2012 +0000

description:
Pull up following revision(s) (requested by dholland in ticket #498):
        usr.sbin/edquota/edquota.c: revision 1.48
        usr.sbin/edquota/edquota.c: revision 1.49
        usr.sbin/edquota/edquota.c: revision 1.50
        usr.sbin/edquota/edquota.c: revision 1.51
        usr.sbin/edquota/edquota.c: revision 1.52
Minor cleanup: use bitfields instead of a flags word for private state
flags, remove now-unused qfname field.
Bail out early if none of the mounted volumes support quotas. Avoids a
null print in interactive use.
Make editor-based edquota work again.
The format is somewhat different; I'm operating under the assumption
that nobody has automated editing scripts for the old format because
it's much easier just to use the command-line interface of
edquota. The new format is more scalable and more parseable.
Also, do a better job of diagnosing editing errors, and don't blindly
erase all quota information for the user being edited when a parse
error occurs after editing.
three more minor fixes.
Grr. The ATF quota tests demand failing silently in certain circumstances.
For netbsd-6 we will just have to go with the flow, as I'm not touching
anything outside edquota tonight.

diffstat:

 usr.sbin/edquota/edquota.c |  690 ++++++++++++++++++++++++++------------------
 1 files changed, 400 insertions(+), 290 deletions(-)

diffs (truncated from 934 to 300 lines):

diff -r 52913b037523 -r 2e367fd2d350 usr.sbin/edquota/edquota.c
--- a/usr.sbin/edquota/edquota.c        Tue Aug 14 07:59:47 2012 +0000
+++ b/usr.sbin/edquota/edquota.c        Wed Aug 15 00:35:04 2012 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: edquota.c,v 1.46 2012/01/30 19:19:20 dholland Exp $ */
+/*      $NetBSD: edquota.c,v 1.46.2.1 2012/08/15 00:35:04 riz Exp $ */
 /*
  * Copyright (c) 1980, 1990, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -41,7 +41,7 @@
 #if 0
 static char sccsid[] = "from: @(#)edquota.c    8.3 (Berkeley) 4/27/95";
 #else
-__RCSID("$NetBSD: edquota.c,v 1.46 2012/01/30 19:19:20 dholland Exp $");
+__RCSID("$NetBSD: edquota.c,v 1.46.2.1 2012/08/15 00:35:04 riz Exp $");
 #endif
 #endif /* not lint */
 
@@ -88,18 +88,23 @@
 
 #define MAX_TMPSTR     (100+MAXPATHLEN)
 
-/* flags for quotause */
-#define        FOUND   0x01
-#define        XGRACE  0x02    /* extended grace periods (per-id) */
-#define        DEFAULT 0x04
+enum sources {
+       SRC_EDITED,     /* values came from user */
+       SRC_QUOTA,      /* values came from a specific quota entry */
+       SRC_DEFAULT,    /* values were copied from the default quota entry */
+       SRC_CLEAR,      /* values arose by zeroing out a quota entry */
+};
 
 struct quotause {
        struct  quotause *next;
-       long    flags;
+       unsigned found:1,       /* found after running editor */
+               xgrace:1,       /* grace periods are per-id */
+               isdefault:1;
+
        struct  quotaval qv[EDQUOTA_NUMOBJTYPES];
+       enum sources source[EDQUOTA_NUMOBJTYPES];
        char    fsname[MAXPATHLEN + 1];
        char    implementation[32];
-       char    *qfname;
 };
 
 struct quotalist {
@@ -151,6 +156,46 @@
        return -1;
 }
 
+/*
+ * check if a source is "real" (reflects actual data) or not
+ */
+static bool
+source_is_real(enum sources source)
+{
+       switch (source) {
+           case SRC_EDITED:
+           case SRC_QUOTA:
+               return true;
+           case SRC_DEFAULT:
+           case SRC_CLEAR:
+               return false;
+       }
+       assert(!"encountered invalid source");
+       return false;
+}
+
+/*
+ * some simple string tools
+ */
+
+static /*const*/ char *
+skipws(/*const*/ char *s)
+{
+       while (*s == ' ' || *s == '\t') {
+               s++;
+       }
+       return s;
+}
+
+static /*const*/ char *
+skipword(/*const*/ char *s)
+{
+       while (*s != '\0' && *s != '\n' && *s != ' ' && *s != '\t') {
+               s++;
+       }
+       return s;
+}
+
 ////////////////////////////////////////////////////////////
 // quotause operations
 
@@ -161,6 +206,7 @@
 quotause_create(void)
 {
        struct quotause *qup;
+       unsigned i;
 
        qup = malloc(sizeof(*qup));
        if (qup == NULL) {
@@ -168,10 +214,14 @@
        }
 
        qup->next = NULL;
-       qup->flags = 0;
-       memset(qup->qv, 0, sizeof(qup->qv));
+       qup->found = 0;
+       qup->xgrace = 0;
+       qup->isdefault = 0;
+       for (i=0; i<EDQUOTA_NUMOBJTYPES; i++) {
+               quotaval_clear(&qup->qv[i]);
+               qup->source[i] = SRC_CLEAR;
+       }
        qup->fsname[0] = '\0';
-       qup->qfname = NULL;
 
        return qup;
 }
@@ -182,7 +232,6 @@
 static void
 quotause_destroy(struct quotause *qup)
 {
-       free(qup->qfname);
        free(qup);
 }
 
@@ -345,7 +394,7 @@
 #endif
 
 ////////////////////////////////////////////////////////////
-// ffs quota v2
+// generic quota interface
 
 static int
 dogetprivs2(struct quotahandle *qh, int idtype, id_t id, int defaultq,
@@ -356,13 +405,30 @@
        qk.qk_idtype = idtype;
        qk.qk_id = defaultq ? QUOTA_DEFAULTID : id;
        qk.qk_objtype = objtype;
-       if (quota_get(qh, &qk, &qup->qv[objtype])) {
-               /* no entry, get default entry */
-               qk.qk_id = QUOTA_DEFAULTID;
-               if (quota_get(qh, &qk, &qup->qv[objtype])) {
-                       return -1;
-               }
+       if (quota_get(qh, &qk, &qup->qv[objtype]) == 0) {
+               /* succeeded */
+               qup->source[objtype] = SRC_QUOTA;
+               return 0;
+       }
+       if (errno != ENOENT) {
+               /* serious failure */
+               return -1;
        }
+
+       /* no entry, get default entry */
+       qk.qk_id = QUOTA_DEFAULTID;
+       if (quota_get(qh, &qk, &qup->qv[objtype]) == 0) {
+               /* succeeded */
+               qup->source[objtype] = SRC_DEFAULT;
+               return 0;
+       }
+       if (errno != ENOENT) {
+               return -1;
+       }
+
+       /* use a zeroed-out entry */
+       quotaval_clear(&qup->qv[objtype]);
+       qup->source[objtype] = SRC_CLEAR;
        return 0;
 }
 
@@ -375,15 +441,18 @@
        const char *impl;
        unsigned restrictions;
        const char *idtypename;
+       int serrno;
 
        qup = quotause_create();
        strcpy(qup->fsname, filesys);
        if (defaultq)
-               qup->flags |= DEFAULT;
+               qup->isdefault = 1;
 
        qh = quota_open(filesys);
        if (qh == NULL) {
+               serrno = errno;
                quotause_destroy(qup);
+               errno = serrno;
                return NULL;
        }
 
@@ -395,7 +464,7 @@
 
        restrictions = quota_getrestrictions(qh);
        if ((restrictions & QUOTA_RESTRICT_UNIFORMGRACE) == 0) {
-               qup->flags |= XGRACE;           
+               qup->xgrace = 1;
        }
 
        if (*idtypename_p == NULL) {
@@ -407,14 +476,18 @@
        }
 
        if (dogetprivs2(qh, idtype, id, defaultq, QUOTA_OBJTYPE_BLOCKS, qup)) {
+               serrno = errno;
                quota_close(qh);
                quotause_destroy(qup);
+               errno = serrno;
                return NULL;
        }
 
        if (dogetprivs2(qh, idtype, id, defaultq, QUOTA_OBJTYPE_FILES, qup)) {
+               serrno = errno;
                quota_close(qh);
                quotause_destroy(qup);
+               errno = serrno;
                return NULL;
        }
 
@@ -430,7 +503,7 @@
        struct quotakey qk;
        char idname[32];
 
-       if (qup->flags & DEFAULT) {
+       if (qup->isdefault) {
                snprintf(idname, sizeof(idname), "%s default",
                         idtype == QUOTA_IDTYPE_USER ? "user" : "group");
                id = QUOTA_DEFAULTID;
@@ -444,18 +517,24 @@
                err(1, "%s: quota_open", qup->fsname);
        }
 
-       qk.qk_idtype = idtype;
-       qk.qk_id = id;
-       qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
-       if (quota_put(qh, &qk, &qup->qv[QO_BLK])) {
-               err(1, "%s: quota_put (%s blocks)", qup->fsname, idname);
+       if (source_is_real(qup->source[QUOTA_OBJTYPE_BLOCKS])) {
+               qk.qk_idtype = idtype;
+               qk.qk_id = id;
+               qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
+               if (quota_put(qh, &qk, &qup->qv[QO_BLK])) {
+                       err(1, "%s: quota_put (%s blocks)", qup->fsname,
+                           idname);
+               }
        }
 
-       qk.qk_idtype = idtype;
-       qk.qk_id = id;
-       qk.qk_objtype = QUOTA_OBJTYPE_FILES;
-       if (quota_put(qh, &qk, &qup->qv[QO_FL])) {
-               err(1, "%s: quota_put (%s files)", qup->fsname, idname);
+       if (source_is_real(qup->source[QUOTA_OBJTYPE_FILES])) {
+               qk.qk_idtype = idtype;
+               qk.qk_id = id;
+               qk.qk_objtype = QUOTA_OBJTYPE_FILES;
+               if (quota_put(qh, &qk, &qup->qv[QO_FL])) {
+                       err(1, "%s: quota_put (%s files)", qup->fsname,
+                           idname);
+               }
        }
 
        quota_close(qh);
@@ -474,6 +553,7 @@
        int nfst, i;
        struct quotalist *qlist;
        struct quotause *qup;
+       int seenany = 0;
 
        qlist = quotalist_create();
 
@@ -484,6 +564,7 @@
        for (i = 0; i < nfst; i++) {
                if ((fst[i].f_flag & ST_QUOTA) == 0)
                        continue;
+               seenany = 1;
                if (filesys &&
                    strcmp(fst[i].f_mntonname, filesys) != 0 &&
                    strcmp(fst[i].f_mntfromname, filesys) != 0)
@@ -491,24 +572,18 @@
                qup = getprivs2(id, idtype, fst[i].f_mntonname, defaultq,
                                &qlist->idtypename);
                if (qup == NULL) {
-                       /*
-                        * XXX: returning NULL is totally wrong. On
-                        * serious error, abort; on minor error, warn
-                        * and continue.
-                        *
-                        * Note: we cannot warn unconditionally here
-                        * because this case apparently includes "no
-                        * quota entry on this volume" and that causes
-                        * the atf tests to fail. Bletch.
-                        */
-                       /*return NULL;*/
-                       /*warnx("getprivs2 failed");*/
+                       /* XXX the atf tests demand failing silently */



Home | Main Index | Thread Index | Old Index