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