Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libquota Add initial versions of quota_open(), quota_clo...
details: https://anonhg.NetBSD.org/src/rev/4f9fdcf3f83b
branches: trunk
changeset: 772598:4f9fdcf3f83b
user: dholland <dholland%NetBSD.org@localhost>
date: Mon Jan 09 15:27:04 2012 +0000
description:
Add initial versions of quota_open(), quota_close(), quota_get(),
calling proplib code mostly taken from getufsquota().
Correct the proplib refcount handling in the code from getufsquota(),
where it was (as far as I can tell) wrong.
Avoid doing illegal and unsafe casts from (struct quotaval *)
to (uint64_t *).
diffstat:
lib/libquota/Makefile | 3 +-
lib/libquota/quota_get.c | 17 +-
lib/libquota/quota_open.c | 30 +++-
lib/libquota/quota_proplib.c | 306 +++++++++++++++++++++++++++++++++++++++++++
lib/libquota/quotapvt.h | 37 +++++
5 files changed, 376 insertions(+), 17 deletions(-)
diffs (truncated from 473 to 300 lines):
diff -r 21079a1c1488 -r 4f9fdcf3f83b lib/libquota/Makefile
--- a/lib/libquota/Makefile Mon Jan 09 15:25:33 2012 +0000
+++ b/lib/libquota/Makefile Mon Jan 09 15:27:04 2012 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.2 2012/01/09 15:22:38 dholland Exp $
+# $NetBSD: Makefile,v 1.3 2012/01/09 15:27:04 dholland Exp $
# @(#)Makefile 8.1 (Berkeley) 6/4/93
.include <bsd.own.mk>
@@ -18,5 +18,6 @@
SRCS+= quota_schema.c
SRCS+= quota_get.c quota_put.c quota_delete.c
SRCS+= quota_cursor.c
+SRCS+= quota_proplib.c
.include <bsd.lib.mk>
diff -r 21079a1c1488 -r 4f9fdcf3f83b lib/libquota/quota_get.c
--- a/lib/libquota/quota_get.c Mon Jan 09 15:25:33 2012 +0000
+++ b/lib/libquota/quota_get.c Mon Jan 09 15:27:04 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_get.c,v 1.1 2012/01/09 15:22:38 dholland Exp $ */
+/* $NetBSD: quota_get.c,v 1.2 2012/01/09 15:27:04 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,22 +29,23 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_get.c,v 1.1 2012/01/09 15:22:38 dholland Exp $");
-
-#include <errno.h>
+__RCSID("$NetBSD: quota_get.c,v 1.2 2012/01/09 15:27:04 dholland Exp $");
#include <quota.h>
+#include "quotapvt.h"
-/* ARGSUSED */
void
quotaval_clear(struct quotaval *qv)
{
+ qv->qv_hardlimit = QUOTA_NOLIMIT;
+ qv->qv_softlimit = QUOTA_NOLIMIT;
+ qv->qv_usage = 0;
+ qv->qv_expiretime = QUOTA_NOTIME;
+ qv->qv_grace = QUOTA_NOTIME;
}
-/* ARGSUSED */
int
quota_get(struct quotahandle *qh, const struct quotakey *qk, struct quotaval *qv)
{
- errno = ENOSYS;
- return -1;
+ return __quota_proplib_get(qh, qk, qv);
}
diff -r 21079a1c1488 -r 4f9fdcf3f83b lib/libquota/quota_open.c
--- a/lib/libquota/quota_open.c Mon Jan 09 15:25:33 2012 +0000
+++ b/lib/libquota/quota_open.c Mon Jan 09 15:27:04 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_open.c,v 1.1 2012/01/09 15:22:38 dholland Exp $ */
+/* $NetBSD: quota_open.c,v 1.2 2012/01/09 15:27:04 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,26 +29,39 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_open.c,v 1.1 2012/01/09 15:22:38 dholland Exp $");
+__RCSID("$NetBSD: quota_open.c,v 1.2 2012/01/09 15:27:04 dholland Exp $");
+#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <quota.h>
+#include "quotapvt.h"
-/* ARGSUSED */
struct quotahandle *
quota_open(const char *path)
{
- errno = ENOSYS;
- return NULL;
+ struct quotahandle *qh;
+ int serrno;
+
+ qh = malloc(sizeof(*qh));
+ if (qh == NULL) {
+ return NULL;
+ }
+ qh->qh_mountpoint = strdup(path);
+ if (qh->qh_mountpoint == NULL) {
+ serrno = errno;
+ free(qh);
+ errno = serrno;
+ return NULL;
+ }
+ return qh;
}
const char *
quota_getmountpoint(struct quotahandle *qh)
{
- errno = ENOSYS;
- return NULL;
+ return qh->qh_mountpoint;
}
const char *
@@ -58,8 +71,9 @@
return NULL;
}
-/* ARGSUSED */
void
quota_close(struct quotahandle *qh)
{
+ free(qh->qh_mountpoint);
+ free(qh);
}
diff -r 21079a1c1488 -r 4f9fdcf3f83b lib/libquota/quota_proplib.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libquota/quota_proplib.c Mon Jan 09 15:27:04 2012 +0000
@@ -0,0 +1,306 @@
+/* $NetBSD: quota_proplib.c,v 1.1 2012/01/09 15:27:04 dholland Exp $ */
+/*-
+ * Copyright (c) 2011 Manuel Bouyer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: quota_proplib.c,v 1.1 2012/01/09 15:27:04 dholland Exp $");
+
+#include <string.h>
+#include <errno.h>
+
+#include <quota.h>
+#include "quotapvt.h"
+
+#include <quota/quotaprop.h>
+#include <quota/quota.h>
+
+int
+__quota_proplib_get(struct quotahandle *qh, const struct quotakey *qk,
+ struct quotaval *qv)
+{
+ prop_dictionary_t dict, data, cmd;
+ prop_array_t cmds, datas;
+ struct plistref pref;
+ int8_t error8;
+ const char *idstr;
+ const char *cmdstr;
+ uint64_t vals[UFS_QUOTA_NENTRIES];
+ uint64_t *valptrs[1];
+ int limitcode;
+ int serrno;
+
+ switch (qk->qk_idtype) {
+ case QUOTA_IDTYPE_USER:
+ idstr = QUOTADICT_CLASS_USER;
+ break;
+ case QUOTA_IDTYPE_GROUP:
+ idstr = QUOTADICT_CLASS_GROUP;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * Cons up the RPC packet.
+ */
+
+ data = prop_dictionary_create();
+ if (data == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ if (!prop_dictionary_set_uint32(data, "id", qk->qk_id)) {
+ prop_object_release(data);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ datas = prop_array_create();
+ if (datas == NULL) {
+ prop_object_release(data);
+ errno = ENOMEM;
+ return -1;
+ }
+ if (!prop_array_add_and_rel(datas, data)) {
+ prop_object_release(datas);
+ /* DATA is consumed if this fails! */
+ errno = ENOMEM;
+ return -1;
+ }
+
+ cmds = prop_array_create();
+ if (cmds == NULL) {
+ prop_object_release(datas);
+ errno = ENOMEM;
+ return -1;
+ }
+ if (!quota_prop_add_command(cmds, "get", idstr, datas)) {
+ prop_object_release(cmds);
+ /* AFAICT, CMDS is consumed if this fails, too. */
+ errno = ENOMEM;
+ return -1;
+ }
+
+ dict = quota_prop_create();
+ if (dict == NULL) {
+ prop_object_release(cmds);
+ errno = ENOMEM;
+ return -1;
+ }
+ if (!prop_dictionary_set(dict, "commands", cmds)) {
+ prop_object_release(dict);
+ /* here CMDS is *not* released on failure. yay consistency! */
+ prop_object_release(cmds);
+ errno = ENOMEM;
+ return -1;
+ }
+ /* as far as I can tell this is required here - dholland */
+ prop_object_release(cmds);
+
+ /*
+ * Convert it to an XML turd for transfer.
+ */
+
+ if (prop_dictionary_send_syscall(dict, &pref) != 0) {
+ serrno = errno;
+ prop_object_release(dict);
+ errno = serrno;
+ return -1;
+ }
+ prop_object_release(dict);
+
+ /*
+ * Send it off.
+ *
+ * Note:
+ *
+ * prop_dictionary_send_syscall allocates memory in PREF,
+ * which we ought to free if quotactl fails, but there's no
+ * way (or no documented way) to do this without breaking the
+ * abstraction.
+ *
+ * Furthermore, quotactl replaces the send buffer in PREF
+ * with a receive buffer. (AFAIK at least...) This overwrites
+ * the send buffer and makes it impossible to free it. The
+ * receive buffer is consumed by prop_dictionary_recv_syscall
+ * with munmap(); however, I'm not sure what happens if the
+ * prop_dictionary_recv_syscall operation fails.
+ *
+ * So it at least looks as if the send bundle is leaked on
+ * every quotactl call.
+ *
+ * XXX.
+ *
+ * - dholland 20111125
+ */
+
+ if (quotactl(qh->qh_mountpoint, &pref) != 0) {
+ /* XXX free PREF buffer here */
+ return -1;
+ }
+ /* XXX free now-overwritten PREF buffer here */
+
+ /*
+ * Convert the XML response turd.
+ */
+
+ if (prop_dictionary_recv_syscall(&pref, &dict) != 0) {
+ /* XXX do we have to free the buffer in PREF here? */
+ return -1;
+ }
Home |
Main Index |
Thread Index |
Old Index