Source-Changes-HG archive

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

[src/bouyer-quota2]: src/usr.sbin/repquota Add an option -x to export a files...



details:   https://anonhg.NetBSD.org/src/rev/56dfbc7e7db1
branches:  bouyer-quota2
changeset: 761155:56dfbc7e7db1
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Thu Feb 10 17:11:35 2011 +0000

description:
Add an option -x to export a filesystem quotas in a plist format, which
can be feed to quotactl(8). This is the way to migrate limits from quota1
to quota2.

diffstat:

 usr.sbin/repquota/repquota.8 |   17 +++++-
 usr.sbin/repquota/repquota.c |  105 ++++++++++++++++++++++++++++++++++++------
 2 files changed, 101 insertions(+), 21 deletions(-)

diffs (266 lines):

diff -r 4542c5da6c21 -r 56dfbc7e7db1 usr.sbin/repquota/repquota.8
--- a/usr.sbin/repquota/repquota.8      Thu Feb 10 16:16:05 2011 +0000
+++ b/usr.sbin/repquota/repquota.8      Thu Feb 10 17:11:35 2011 +0000
@@ -29,9 +29,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     from: @(#)repquota.8   8.1 (Berkeley) 6/6/93
-.\"    $NetBSD: repquota.8,v 1.9.50.1 2011/01/21 16:58:07 bouyer Exp $
+.\"    $NetBSD: repquota.8,v 1.9.50.2 2011/02/10 17:11:35 bouyer Exp $
 .\"
-.Dd January 21, 2011
+.Dd February 10, 2011
 .Dt REPQUOTA 8
 .Os
 .Sh NAME
@@ -52,6 +52,12 @@
 .Op Fl u
 .Op Fl v
 .Fl a
+.Nm
+.Fl x
+.Op Fl D
+.Op Fl g
+.Op Fl u
+.Ar filesystem
 .Sh DESCRIPTION
 .Nm
 prints a summary of the disk usage and quotas for the
@@ -73,6 +79,10 @@
 Debug: print plist sent to and received from kernel.
 .It Fl h
 Numbers are displayed in a human readable format.
+.It Fl x
+export filesystem quota in a plist format suitable for
+.Xr quotactl 8 .
+A single filesystem should be specified.
 .El
 .Pp
 For each user or group, the current
@@ -83,14 +93,13 @@
 .Xr edquota 8 .
 .Pp
 Only the super-user may use this command.
-.Sh DIAGNOSTICS
-Various messages about inaccessible files; self-explanatory.
 .Sh SEE ALSO
 .Xr quota 1 ,
 .Xr quotactl 2 ,
 .Xr fstab 5 ,
 .Xr edquota 8 ,
 .Xr quotacheck 8 ,
+.Xr quotactl 8 ,
 .Xr quotaon 8
 .Sh HISTORY
 The
diff -r 4542c5da6c21 -r 56dfbc7e7db1 usr.sbin/repquota/repquota.c
--- a/usr.sbin/repquota/repquota.c      Thu Feb 10 16:16:05 2011 +0000
+++ b/usr.sbin/repquota/repquota.c      Thu Feb 10 17:11:35 2011 +0000
@@ -40,7 +40,7 @@
 #if 0
 static char sccsid[] = "@(#)repquota.c 8.2 (Berkeley) 11/22/94";
 #else
-__RCSID("$NetBSD: repquota.c,v 1.25.2.6 2011/02/03 15:56:16 bouyer Exp $");
+__RCSID("$NetBSD: repquota.c,v 1.25.2.7 2011/02/10 17:11:35 bouyer Exp $");
 #endif
 #endif /* not lint */
 
@@ -82,12 +82,15 @@
 #define FUHASH 1024    /* must be power of two */
 struct fileusage *fuhead[MAXQUOTAS][FUHASH];
 u_long highid[MAXQUOTAS];      /* highest addid()'ed identifier per type */
+int valid[MAXQUOTAS];
 struct quota2_entry defaultq2e[MAXQUOTAS];
 
 int    vflag = 0;              /* verbose */
 int    aflag = 0;              /* all file systems */
 int    Dflag = 0;              /* debug */
-int    hflag = 0;              /* debug */
+int    hflag = 0;              /* humanize */
+int    xflag = 0;              /* export */
+
 
 struct fileusage *addid(u_long, int, const char *);
 int    hasquota(struct fstab *, int, char **);
@@ -99,6 +102,7 @@
 int    repquota1(const struct statvfs *, int);
 void   usage(void);
 void   printquotas(int, const struct statvfs *, int);
+void   exportquotas(void);
 void   dqblk2q2e(const struct dqblk *, struct quota2_entry *);
 
 int
@@ -114,7 +118,7 @@
        struct statvfs *fst;
        int nfst;
 
-       while ((ch = getopt(argc, argv, "Daguhv")) != -1) {
+       while ((ch = getopt(argc, argv, "Daguhvx")) != -1) {
                switch(ch) {
                case 'a':
                        aflag++;
@@ -134,12 +138,17 @@
                case 'D':
                        Dflag++;
                        break;
+               case 'x':
+                       xflag++;
+                       break;
                default:
                        usage();
                }
        }
        argc -= optind;
        argv += optind;
+       if (xflag && argc != 1)
+               usage();
        if (argc == 0 && !aflag)
                usage();
        if (!gflag && !uflag) {
@@ -184,6 +193,8 @@
                                errs += repquota(&fst[i], USRQUOTA);
                }
        }
+       if (xflag)
+               exportquotas();
        for (i = 0; i < argc; i++)
                if ((done & (1 << i)) == 0)
                        fprintf(stderr, "%s not mounted\n", argv[i]);
@@ -193,9 +204,10 @@
 void
 usage()
 {
-       fprintf(stderr, "usage:\n\t%s\n\t%s\n",
-               "repquota [-D] [-v] [-g] [-u] -a",
-               "repquota [-D] [-v] [-g] [-u] filesys ...");
+       fprintf(stderr, "usage:\n"
+               "\trepquota [-D] [-v] [-g] [-u] -a\n"
+               "\trepquota [-D] [-v] [-g] [-u] filesys ...\n"
+               "\trepquota -x [-D] [-g] [-u] filesys\n");
        exit(1);
 }
 
@@ -293,6 +305,7 @@
                if (dataiter == NULL)
                        err(1, "prop_array_iterator");
 
+               valid[type] = 1;
                while ((data = prop_object_iterator_next(dataiter)) != NULL) {
                        strid = NULL;
                        if (!prop_dictionary_get_uint32(data, "id", &id)) {
@@ -322,7 +335,8 @@
        }
        prop_object_iterator_release(cmditer);
        prop_object_release(dict);
-       printquotas(type, vfs, version);
+       if (xflag == 0)
+               printquotas(type, vfs, version);
        return (0);
 }
 
@@ -334,16 +348,8 @@
        FILE *qf;
        u_long id;
        struct dqblk dqbuf;
+       time_t bgrace = MAX_DQ_TIME, igrace = MAX_DQ_TIME;
 
-#if 0
-       static int warned = 0;
-       if (quotactl(fs->fs_file, QCMD(Q_SYNC, type), 0, 0) < 0 &&
-           errno == EOPNOTSUPP && !warned && vflag) {
-               warned++;
-               fprintf(stdout,
-                   "*** Warning: Quotas are not compiled into this kernel\n");
-       }
-#endif
        setfsent();
        while ((fs = getfsent()) != NULL) {
                if (strcmp(fs->fs_vfstype, "ffs") == 0 &&
@@ -366,14 +372,26 @@
                fread(&dqbuf, sizeof(struct dqblk), 1, qf);
                if (feof(qf))
                        break;
+               if (id == 0) {
+                       if (dqbuf.dqb_btime > 0)
+                               bgrace = dqbuf.dqb_btime;
+                       if (dqbuf.dqb_itime > 0)
+                               igrace = dqbuf.dqb_itime;
+               }
                if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0)
                        continue;
                if ((fup = lookup(id, type)) == 0)
                        fup = addid(id, type, (char *)0);
                dqblk2q2e(&dqbuf, &fup->fu_q2e);
+               fup->fu_q2e.q2e_val[QL_BLOCK].q2v_grace = bgrace;
+               fup->fu_q2e.q2e_val[QL_FILE].q2v_grace = igrace;
        }
+       defaultq2e[type].q2e_val[QL_BLOCK].q2v_grace = bgrace;
+       defaultq2e[type].q2e_val[QL_FILE].q2v_grace = igrace;
        fclose(qf);
-       printquotas(type, vfs, 1);
+       valid[type] = 1;
+       if (xflag == 0)
+               printquotas(type, vfs, 1);
        return (0);
 }
 
@@ -453,6 +471,59 @@
        }
 }
 
+void
+exportquotas()
+{
+       u_long id;
+       struct fileusage *fup;
+       prop_dictionary_t dict, data;
+       prop_array_t cmds, datas;
+       int type;
+
+       dict = quota2_prop_create();
+       cmds = prop_array_create();
+
+       if (dict == NULL || cmds == NULL) {
+               errx(1, "can't allocate proplist");
+       }
+
+
+       for (type = 0; type < MAXQUOTAS; type++) {
+               if (valid[type] == 0)
+                       continue;
+               datas = prop_array_create();
+               if (datas == NULL)
+                       errx(1, "can't allocate proplist");
+               data = q2etoprop(&defaultq2e[type], 1);
+               if (data == NULL)
+                       err(1, "q2etoprop(default)");
+               if (!prop_array_add_and_rel(datas, data))
+                       err(1, "prop_array_add(data)");
+
+               for (id = 0; id <= highid[type]; id++) {
+                       fup = lookup(id, type);
+                       if (fup == 0)
+                               continue;
+                       fup->fu_q2e.q2e_uid = id;
+                       data = q2etoprop(&fup->fu_q2e, 0);
+                       if (data == NULL)
+                               err(1, "q2etoprop(default)");
+                       if (!prop_array_add_and_rel(datas, data))
+                               err(1, "prop_array_add(data)");
+               }
+
+               if (!quota2_prop_add_command(cmds, "set",
+                   qfextension[type], datas))
+                       err(1, "prop_add_command");
+       }
+
+       if (!prop_dictionary_set(dict, "commands", cmds))
+               err(1, "prop_dictionary_set(command)");
+
+       printf("%s\n", prop_dictionary_externalize(dict));
+       return;
+}
+
 /*
  * Check to see if target appears in list of size cnt.
  */



Home | Main Index | Thread Index | Old Index