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