Module Name: src
Committed By: dholland
Date: Mon Jan 30 16:45:13 UTC 2012
Modified Files:
src/include: quota.h
src/lib/libquota: quota_oldfiles.c quota_open.c quota_proplib.c
quotapvt.h
src/usr.sbin/quotaon: Makefile quotaon.c
Log Message:
Add quota_quotaon() and quota_quotaoff(). Use them in quotaon(8).
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/include/quota.h
cvs rdiff -u -r1.4 -r1.5 src/lib/libquota/quota_oldfiles.c
cvs rdiff -u -r1.5 -r1.6 src/lib/libquota/quota_open.c
cvs rdiff -u -r1.9 -r1.10 src/lib/libquota/quota_proplib.c
cvs rdiff -u -r1.11 -r1.12 src/lib/libquota/quotapvt.h
cvs rdiff -u -r1.8 -r1.9 src/usr.sbin/quotaon/Makefile
cvs rdiff -u -r1.28 -r1.29 src/usr.sbin/quotaon/quotaon.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/include/quota.h
diff -u src/include/quota.h:1.4 src/include/quota.h:1.5
--- src/include/quota.h:1.4 Mon Jan 30 16:44:08 2012
+++ src/include/quota.h Mon Jan 30 16:45:13 2012
@@ -55,6 +55,9 @@ unsigned quota_getnumobjtypes(struct quo
const char *quota_objtype_getname(struct quotahandle *, int /*objtype*/);
int quota_objtype_isbytes(struct quotahandle *, int /*objtype*/);
+int quota_quotaon(struct quotahandle *, int /*idtype*/);
+int quota_quotaoff(struct quotahandle *, int /*idtype*/);
+
int quota_get(struct quotahandle *, const struct quotakey *,
struct quotaval *);
Index: src/lib/libquota/quota_oldfiles.c
diff -u src/lib/libquota/quota_oldfiles.c:1.4 src/lib/libquota/quota_oldfiles.c:1.5
--- src/lib/libquota/quota_oldfiles.c:1.4 Mon Jan 30 06:15:22 2012
+++ src/lib/libquota/quota_oldfiles.c Mon Jan 30 16:45:13 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_oldfiles.c,v 1.4 2012/01/30 06:15:22 dholland Exp $ */
+/* $NetBSD: quota_oldfiles.c,v 1.5 2012/01/30 16:45:13 dholland Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@@ -237,6 +237,57 @@ __quota_oldfiles_infstab(const char *mou
return __quota_oldfiles_find_fstabentry(mountpoint) != NULL;
}
+static void
+__quota_oldfiles_defquotafile(struct quotahandle *qh, int idtype,
+ char *buf, size_t maxlen)
+{
+ static const char *const names[] = INITQFNAMES;
+
+ (void)snprintf(buf, maxlen, "%s/%s.%s",
+ qh->qh_mountpoint,
+ QUOTAFILENAME, names[USRQUOTA]);
+}
+
+const char *
+__quota_oldfiles_getquotafile(struct quotahandle *qh, int idtype,
+ char *buf, size_t maxlen)
+{
+ const struct oldfiles_fstabentry *ofe;
+ const char *file;
+
+ ofe = __quota_oldfiles_find_fstabentry(qh->qh_mountpoint);
+ if (ofe == NULL) {
+ errno = ENXIO;
+ return NULL;
+ }
+
+ switch (idtype) {
+ case USRQUOTA:
+ if (!ofe->ofe_hasuserquota) {
+ errno = ENXIO;
+ return NULL;
+ }
+ file = ofe->ofe_userquotafile;
+ break;
+ case GRPQUOTA:
+ if (!ofe->ofe_hasgroupquota) {
+ errno = ENXIO;
+ return NULL;
+ }
+ file = ofe->ofe_groupquotafile;
+ break;
+ default:
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (file == NULL) {
+ __quota_oldfiles_defquotafile(qh, idtype, buf, maxlen);
+ file = buf;
+ }
+ return file;
+}
+
static uint64_t
dqblk_getlimit(uint32_t val)
{
@@ -316,8 +367,6 @@ __quota_oldfiles_open(struct quotahandle
int
__quota_oldfiles_initialize(struct quotahandle *qh)
{
- static const char *const names[] = INITQFNAMES;
-
const struct oldfiles_fstabentry *ofe;
char path[PATH_MAX];
const char *userquotafile, *groupquotafile;
@@ -345,9 +394,8 @@ __quota_oldfiles_initialize(struct quota
if (ofe->ofe_hasuserquota) {
userquotafile = ofe->ofe_userquotafile;
if (userquotafile == NULL) {
- (void)snprintf(path, sizeof(path), "%s/%s.%s",
- qh->qh_mountpoint,
- QUOTAFILENAME, names[USRQUOTA]);
+ __quota_oldfiles_defquotafile(qh, USRQUOTA,
+ path, sizeof(path));
userquotafile = path;
}
if (__quota_oldfiles_open(qh, userquotafile,
@@ -358,9 +406,8 @@ __quota_oldfiles_initialize(struct quota
if (ofe->ofe_hasgroupquota) {
groupquotafile = ofe->ofe_groupquotafile;
if (groupquotafile == NULL) {
- (void)snprintf(path, sizeof(path), "%s/%s.%s",
- qh->qh_mountpoint,
- QUOTAFILENAME, names[GRPQUOTA]);
+ __quota_oldfiles_defquotafile(qh, GRPQUOTA,
+ path, sizeof(path));
groupquotafile = path;
}
if (__quota_oldfiles_open(qh, groupquotafile,
@@ -380,6 +427,45 @@ __quota_oldfiles_getimplname(struct quot
return "ufs/ffs quota v1 file access";
}
+int
+__quota_oldfiles_quotaon(struct quotahandle *qh, int idtype)
+{
+ int result;
+
+ /*
+ * If we have the quota files open, close them.
+ */
+
+ if (qh->qh_oldfilesopen) {
+ if (qh->qh_userfile >= 0) {
+ close(qh->qh_userfile);
+ qh->qh_userfile = -1;
+ }
+ if (qh->qh_groupfile >= 0) {
+ close(qh->qh_groupfile);
+ qh->qh_groupfile = -1;
+ }
+ qh->qh_oldfilesopen = 0;
+ }
+
+ /*
+ * Go over to the syscall interface.
+ */
+
+ result = __quota_proplib_quotaon(qh, idtype);
+ if (result < 0) {
+ return -1;
+ }
+
+ /*
+ * We succeeded, so all further access should be via the
+ * kernel.
+ */
+
+ qh->qh_mode = QUOTA_MODE_PROPLIB;
+ return 0;
+}
+
static int
__quota_oldfiles_doget(struct quotahandle *qh, const struct quotakey *qk,
struct quotaval *qv, int *isallzero)
Index: src/lib/libquota/quota_open.c
diff -u src/lib/libquota/quota_open.c:1.5 src/lib/libquota/quota_open.c:1.6
--- src/lib/libquota/quota_open.c:1.5 Wed Jan 25 17:43:37 2012
+++ src/lib/libquota/quota_open.c Mon Jan 30 16:45:13 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_open.c,v 1.5 2012/01/25 17:43:37 dholland Exp $ */
+/* $NetBSD: quota_open.c,v 1.6 2012/01/30 16:45:13 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_open.c,v 1.5 2012/01/25 17:43:37 dholland Exp $");
+__RCSID("$NetBSD: quota_open.c,v 1.6 2012/01/30 16:45:13 dholland Exp $");
#include <sys/types.h>
#include <sys/statvfs.h>
@@ -64,6 +64,15 @@ quota_open(const char *path)
* 3. Check if the volume is listed in fstab as one of
* the filesystem types supported by quota_oldfiles.c,
* and with the proper mount options to enable quotas.
+ *
+ * Note that (as of this writing) the mount options for
+ * enabling quotas are accepted by mount for *all* filesystem
+ * types and then ignored -- the kernel mount flag (ST_QUOTA /
+ * MNT_QUOTA) gets set either by the filesystem based on its
+ * own criteria, or for old-style quotas, during quotaon. The
+ * quota filenames specified in fstab are not passed to or
+ * known by the kernel except via quota_oldfiles.c! This is
+ * generally gross but not easily fixed.
*/
if (statvfs(path, &stv) < 0) {
@@ -144,3 +153,41 @@ quota_close(struct quotahandle *qh)
free(qh->qh_mountpoint);
free(qh);
}
+
+int
+quota_quotaon(struct quotahandle *qh, int idtype)
+{
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_NFS:
+ errno = EOPNOTSUPP;
+ break;
+ case QUOTA_MODE_PROPLIB:
+ return __quota_proplib_quotaon(qh, idtype);
+ case QUOTA_MODE_OLDFILES:
+ return __quota_oldfiles_quotaon(qh, idtype);
+ default:
+ errno = EINVAL;
+ break;
+ }
+ return -1;
+}
+
+int
+quota_quotaoff(struct quotahandle *qh, int idtype)
+{
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_NFS:
+ errno = EOPNOTSUPP;
+ break;
+ case QUOTA_MODE_PROPLIB:
+ return __quota_proplib_quotaoff(qh, idtype);
+ case QUOTA_MODE_OLDFILES:
+ /* can't quotaoff if we haven't quotaon'd */
+ errno = ENOTCONN;
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+ return -1;
+}
Index: src/lib/libquota/quota_proplib.c
diff -u src/lib/libquota/quota_proplib.c:1.9 src/lib/libquota/quota_proplib.c:1.10
--- src/lib/libquota/quota_proplib.c:1.9 Mon Jan 30 16:44:08 2012
+++ src/lib/libquota/quota_proplib.c Mon Jan 30 16:45:13 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_proplib.c,v 1.9 2012/01/30 16:44:08 dholland Exp $ */
+/* $NetBSD: quota_proplib.c,v 1.10 2012/01/30 16:45:13 dholland Exp $ */
/*-
* Copyright (c) 2011 Manuel Bouyer
* All rights reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_proplib.c,v 1.9 2012/01/30 16:44:08 dholland Exp $");
+__RCSID("$NetBSD: quota_proplib.c,v 1.10 2012/01/30 16:45:13 dholland Exp $");
#include <stdlib.h>
#include <string.h>
@@ -35,6 +35,7 @@ __RCSID("$NetBSD: quota_proplib.c,v 1.9
#include <err.h>
#include <quota.h>
+#include <ufs/ufs/quota1.h>
#include "quotapvt.h"
#include <quota/quotaprop.h>
@@ -55,6 +56,8 @@ struct proplib_quotacursor {
unsigned didblocks;
};
+static const char *const __quota1_qfnames[] = INITQFNAMES;
+
int
__quota_proplib_getversion(struct quotahandle *qh, int8_t *version_ret)
{
@@ -240,6 +243,112 @@ __quota_proplib_objtype_isbytes(int objt
}
static int
+__quota_proplib_quotaonoff(struct quotahandle *qh, int idtype, int offmode)
+{
+ prop_dictionary_t dict, data, cmd;
+ prop_array_t cmds, datas;
+ struct plistref pref;
+ int8_t error8;
+ const char *file;
+ char path[PATH_MAX];
+
+ /*
+ * Note that while it is an error to call quotaon on something
+ * that isn't a volume with old-style quotas that expects
+ * quotaon to be called, it's not our responsibility to check
+ * for that; the filesystem will. Also note that it is not an
+ * error to call quotaon repeatedly -- apparently this is to
+ * permit changing the quota file in use on the fly or
+ * something. So all we need to do here is ask the oldfiles
+ * code if the mount option was set in fstab and fetch back
+ * the filename.
+ */
+
+ if (offmode) {
+ file = NULL;
+ } else {
+ file = __quota_oldfiles_getquotafile(qh, idtype,
+ path, sizeof(path));
+ if (file == NULL) {
+ /*
+ * This idtype (or maybe any idtype) was
+ * not enabled in fstab.
+ */
+ errno = ENXIO;
+ return -1;
+ }
+ }
+
+ dict = quota_prop_create();
+ cmds = prop_array_create();
+ datas = prop_array_create();
+
+ if (dict == NULL || cmds == NULL || datas == NULL)
+ errx(1, "can't allocate proplist");
+
+ if (offmode) {
+ if (!quota_prop_add_command(cmds, "quotaoff",
+ __quota1_qfnames[idtype], datas))
+ err(1, "prop_add_command");
+ } else {
+ data = prop_dictionary_create();
+ if (data == NULL)
+ errx(1, "can't allocate proplist");
+ if (!prop_dictionary_set_cstring(data, "quotafile", file))
+ err(1, "prop_dictionary_set(quotafile)");
+ if (!prop_array_add_and_rel(datas, data))
+ err(1, "prop_array_add(data)");
+ if (!quota_prop_add_command(cmds, "quotaon",
+ __quota1_qfnames[idtype], datas))
+ err(1, "prop_add_command");
+ }
+ if (!prop_dictionary_set(dict, "commands", cmds))
+ err(1, "prop_dictionary_set(command)");
+
+ if (prop_dictionary_send_syscall(dict, &pref) != 0)
+ err(1, "prop_dictionary_send_syscall");
+ prop_object_release(dict);
+
+ if (quotactl(qh->qh_mountpoint, &pref) != 0) {
+ warn("quotactl(%s)", qh->qh_mountpoint);
+ return -1;
+ }
+
+ if (prop_dictionary_recv_syscall(&pref, &dict) != 0)
+ err(1, "prop_dictionary_recv_syscall");
+
+ if ((errno = quota_get_cmds(dict, &cmds)) != 0)
+ err(1, "quota_get_cmds");
+
+ /* only one command, no need to iter */
+ cmd = prop_array_get(cmds, 0);
+ if (cmd == NULL)
+ err(1, "prop_array_get(cmd)");
+
+ if (!prop_dictionary_get_int8(cmd, "return", &error8))
+ err(1, "prop_get(return)");
+
+ if (error8) {
+ errno = error8;
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+__quota_proplib_quotaon(struct quotahandle *qh, int idtype)
+{
+ return __quota_proplib_quotaonoff(qh, idtype, 0);
+}
+
+int
+__quota_proplib_quotaoff(struct quotahandle *qh, int idtype)
+{
+ return __quota_proplib_quotaonoff(qh, idtype, 1);
+}
+
+static int
__quota_proplib_extractval(int objtype, prop_dictionary_t data,
struct quotaval *qv)
{
Index: src/lib/libquota/quotapvt.h
diff -u src/lib/libquota/quotapvt.h:1.11 src/lib/libquota/quotapvt.h:1.12
--- src/lib/libquota/quotapvt.h:1.11 Mon Jan 30 16:44:09 2012
+++ src/lib/libquota/quotapvt.h Mon Jan 30 16:45:13 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quotapvt.h,v 1.11 2012/01/30 16:44:09 dholland Exp $ */
+/* $NetBSD: quotapvt.h,v 1.12 2012/01/30 16:45:13 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -64,6 +64,8 @@ const char *__quota_proplib_idtype_getna
unsigned __quota_proplib_getnumobjtypes(void);
const char *__quota_proplib_objtype_getname(int objtype);
int __quota_proplib_objtype_isbytes(int objtype);
+int __quota_proplib_quotaon(struct quotahandle *, int idtype);
+int __quota_proplib_quotaoff(struct quotahandle *, int idtype);
int __quota_proplib_get(struct quotahandle *qh, const struct quotakey *qk,
struct quotaval *qv);
int __quota_proplib_put(struct quotahandle *qh, const struct quotakey *qk,
@@ -95,6 +97,9 @@ void __quota_oldfiles_load_fstab(void);
int __quota_oldfiles_infstab(const char *);
int __quota_oldfiles_initialize(struct quotahandle *qh);
const char *__quota_oldfiles_getimplname(struct quotahandle *);
+const char *__quota_oldfiles_getquotafile(struct quotahandle *, int idtype,
+ char *buf, size_t maxlen);
+int __quota_oldfiles_quotaon(struct quotahandle *, int idtype);
int __quota_oldfiles_get(struct quotahandle *qh, const struct quotakey *qk,
struct quotaval *qv);
int __quota_oldfiles_put(struct quotahandle *qh, const struct quotakey *qk,
Index: src/usr.sbin/quotaon/Makefile
diff -u src/usr.sbin/quotaon/Makefile:1.8 src/usr.sbin/quotaon/Makefile:1.9
--- src/usr.sbin/quotaon/Makefile:1.8 Thu Mar 24 17:05:47 2011
+++ src/usr.sbin/quotaon/Makefile Mon Jan 30 16:45:13 2012
@@ -1,5 +1,5 @@
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
-# $NetBSD: Makefile,v 1.8 2011/03/24 17:05:47 bouyer Exp $
+# $NetBSD: Makefile,v 1.9 2012/01/30 16:45:13 dholland Exp $
.include <bsd.own.mk>
WARNS ?= 4
@@ -10,11 +10,6 @@ MAN= quotaon.8
MLINKS= quotaon.8 quotaoff.8
LINKS= ${BINDIR}/quotaon ${BINDIR}/quotaoff
-.PATH: ${NETBSDSRCDIR}/usr.bin/quota
-SRCS+= quotautil.c
-CPPFLAGS+=-I${NETBSDSRCDIR}/usr.bin/quota
-CPPFLAGS+=-I${NETBSDSRCDIR}/sys
-
DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC}
LDADD= -lquota -lprop -lrpcsvc
Index: src/usr.sbin/quotaon/quotaon.c
diff -u src/usr.sbin/quotaon/quotaon.c:1.28 src/usr.sbin/quotaon/quotaon.c:1.29
--- src/usr.sbin/quotaon/quotaon.c:1.28 Wed Jan 25 01:28:40 2012
+++ src/usr.sbin/quotaon/quotaon.c Mon Jan 30 16:45:13 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quotaon.c,v 1.28 2012/01/25 01:28:40 dholland Exp $ */
+/* $NetBSD: quotaon.c,v 1.29 2012/01/30 16:45:13 dholland Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19
#if 0
static char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: quotaon.c,v 1.28 2012/01/25 01:28:40 dholland Exp $");
+__RCSID("$NetBSD: quotaon.c,v 1.29 2012/01/30 16:45:13 dholland Exp $");
#endif
#endif /* not lint */
@@ -53,10 +53,8 @@ __RCSID("$NetBSD: quotaon.c,v 1.28 2012/
#include <sys/file.h>
#include <sys/mount.h>
-#include <quota/quotaprop.h>
+#include <quota.h>
#include <ufs/ufs/quota1.h>
-#include <sys/quota.h>
-
#include <err.h>
#include <fstab.h>
@@ -66,26 +64,29 @@ __RCSID("$NetBSD: quotaon.c,v 1.28 2012/
#include <string.h>
#include <unistd.h>
-#include "quotautil.h"
-static int aflag; /* all file systems */
-static int gflag; /* operate on group quotas */
-static int uflag; /* operate on user quotas */
static int vflag; /* verbose */
static void usage(void) __dead;
-static int quotaonoff(struct fstab *, int, int, const char *);
+static int quotaonoff(struct fstab *, struct quotahandle *, int, int, int);
static int readonly(struct fstab *);
+static int oneof(const char *target, char *list[], int cnt);
int
main(int argc, char *argv[])
{
struct fstab *fs;
- char qfnp[MAXPATHLEN];
+ struct quotahandle *qh;
long argnum, done = 0;
int i, offmode = 0, errs = 0;
+ unsigned restrictions;
int ch;
+ int aflag = 0; /* all file systems */
+ int gflag = 0; /* operate on group quotas */
+ int uflag = 0; /* operate on user quotas */
+ int noguflag = 0; /* operate on both (by default) */
+
if (strcmp(getprogname(), "quotaoff") == 0)
offmode++;
else if (strcmp(getprogname(), "quotaon") != 0)
@@ -117,30 +118,74 @@ main(int argc, char *argv[])
usage();
if (!gflag && !uflag) {
- gflag++;
- uflag++;
+ noguflag = 1;
+ }
+
+ /*
+ * XXX at the moment quota_open also uses getfsent(), but it
+ * uses it only up front. To avoid conflicting with it, let it
+ * initialize first.
+ */
+ qh = quota_open("/");
+ if (qh != NULL) {
+ quota_close(qh);
}
+
setfsent();
while ((fs = getfsent()) != NULL) {
if ((strcmp(fs->fs_vfstype, "ffs") &&
strcmp(fs->fs_vfstype, "lfs")) ||
strcmp(fs->fs_type, FSTAB_RW))
continue;
- if (aflag) {
- if (gflag && hasquota(qfnp, sizeof(qfnp), fs, GRPQUOTA))
- errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
- if (uflag && hasquota(qfnp, sizeof(qfnp), fs, USRQUOTA))
- errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
+
+ if (!aflag) {
+ if ((argnum = oneof(fs->fs_file, argv, argc)) < 0 &&
+ (argnum = oneof(fs->fs_spec, argv, argc)) < 0) {
+ continue;
+ }
+ done |= 1U << argnum;
+ }
+
+ qh = quota_open(fs->fs_file);
+ if (qh == NULL) {
+ if (!aflag) {
+ warn("quota_open");
+ errs++;
+ }
+ continue;
+ }
+
+ restrictions = quota_getrestrictions(qh);
+ if ((restrictions & QUOTA_RESTRICT_NEEDSQUOTACHECK) == 0) {
+ /* Not a quota v1 volume, skip it */
+ if (!aflag) {
+ errno = EBUSY;
+ warn("%s", fs->fs_file);
+ errs++;
+ }
+ quota_close(qh);
continue;
}
- if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
- (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
- done |= 1U << argnum;
- if (gflag && hasquota(qfnp, sizeof(qfnp), fs, GRPQUOTA))
- errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
- if (uflag && hasquota(qfnp, sizeof(qfnp), fs, USRQUOTA))
- errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
+
+ /*
+ * The idea here is to warn if someone explicitly
+ * tries to turn on group quotas and there are no
+ * group quotas, and likewise for user quotas, but not
+ * to warn if just doing the default thing and one of
+ * the quota types isn't configured.
+ */
+
+ if (noguflag) {
+ errs += quotaonoff(fs, qh, offmode, GRPQUOTA, 0);
+ errs += quotaonoff(fs, qh, offmode, USRQUOTA, 0);
}
+ if (gflag) {
+ errs += quotaonoff(fs, qh, offmode, GRPQUOTA, 1);
+ }
+ if (uflag) {
+ errs += quotaonoff(fs, qh, offmode, USRQUOTA, 1);
+ }
+ quota_close(qh);
}
endfsent();
for (i = 0; i < argc; i++)
@@ -159,76 +204,34 @@ usage(void)
}
static int
-quotaonoff( struct fstab *fs, int offmode, int type, const char *qfpathname)
+quotaonoff(struct fstab *fs, struct quotahandle *qh, int offmode, int idtype,
+ int warn_on_enxio)
{
const char *mode = (offmode == 1) ? "off" : "on";
- prop_dictionary_t dict, data, cmd;
- prop_array_t cmds, datas;
- struct plistref pref;
- int8_t error8;
-
- dict = quota_prop_create();
- cmds = prop_array_create();
- datas = prop_array_create();
- if (strcmp(fs->fs_file, "/") && readonly(fs))
+ if (strcmp(fs->fs_file, "/") && readonly(fs)) {
return 1;
-
- if (dict == NULL || cmds == NULL || datas == NULL)
- errx(1, "can't allocate proplist");
+ }
if (offmode) {
- if (!quota_prop_add_command(cmds, "quotaoff",
- qfextension[type], datas))
- err(1, "prop_add_command");
+ if (quota_quotaoff(qh, idtype)) {
+ if (warn_on_enxio || errno != ENXIO) {
+ warn("quota%s for %s", mode, fs->fs_file);
+ }
+ return 1;
+ }
} else {
- data = prop_dictionary_create();
- if (data == NULL)
- errx(1, "can't allocate proplist");
- if (!prop_dictionary_set_cstring(data, "quotafile",
- qfpathname))
- err(1, "prop_dictionary_set(quotafile)");
- if (!prop_array_add_and_rel(datas, data))
- err(1, "prop_array_add(data)");
- if (!quota_prop_add_command(cmds, "quotaon",
- qfextension[type], datas))
- err(1, "prop_add_command");
- }
- if (!prop_dictionary_set(dict, "commands", cmds))
- err(1, "prop_dictionary_set(command)");
-
- if (prop_dictionary_send_syscall(dict, &pref) != 0)
- err(1, "prop_dictionary_send_syscall");
- prop_object_release(dict);
-
- if (quotactl(fs->fs_file, &pref) != 0) {
- warn("quotactl(%s)", fs->fs_file);
- return(1);
- }
-
- if (prop_dictionary_recv_syscall(&pref, &dict) != 0)
- err(1, "prop_dictionary_recv_syscall");
-
- if ((errno = quota_get_cmds(dict, &cmds)) != 0)
- err(1, "quota_get_cmds");
-
- /* only one command, no need to iter */
- cmd = prop_array_get(cmds, 0);
- if (cmd == NULL)
- err(1, "prop_array_get(cmd)");
-
- if (!prop_dictionary_get_int8(cmd, "return", &error8))
- err(1, "prop_get(return)");
-
- if (error8) {
- errno = error8;
- warn("quota%s for %s", mode, fs->fs_file);
- return 1;
+ if (quota_quotaon(qh, idtype)) {
+ if (warn_on_enxio || errno != ENXIO) {
+ warn("quota%s for %s", mode, fs->fs_file);
+ }
+ return 1;
+ }
}
if (vflag) {
printf("%s: %s quotas turned %s\n",
- fs->fs_file, qfextension[type], mode);
+ fs->fs_file, quota_idtype_getname(qh, idtype), mode);
}
return 0;
}
@@ -253,3 +256,17 @@ readonly(struct fstab *fs)
}
return 0;
}
+
+/*
+ * Check to see if target appears in list of size cnt.
+ */
+static int
+oneof(const char *target, char *list[], int cnt)
+{
+ int i;
+
+ for (i = 0; i < cnt; i++)
+ if (strcmp(target, list[i]) == 0)
+ return i;
+ return -1;
+}