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

[Xen-changelog] add quota to xenstored.



# HG changeset patch
# User vhanquez@xxxxxxxxxxxxxxxxxxxxxxx
# Node ID e7d769001b4b2dc9d21beecdf4c20c69b0242a61
# Parent  14f6d138c61dc4fe2e4fd3310835f694d4fa13db
add quota to xenstored.

Signed-off-by: Vincent Hanquez <vincent@xxxxxxxxxxxxx>

diff -r 14f6d138c61d -r e7d769001b4b tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Thu Apr 13 14:15:56 2006
+++ b/tools/xenstore/xenstored_core.c   Thu Apr 13 16:21:13 2006
@@ -77,6 +77,10 @@
        } while (0)
 
 
+int quota_nb_entry_per_domain = 1000;
+int quota_nb_watch_per_domain = 128;
+int quota_max_entry_size = 2048; /* 2K */
+
 #ifdef TESTING
 static bool failtest = false;
 
@@ -455,6 +459,10 @@
        data.dsize = 3*sizeof(uint32_t)
                + node->num_perms*sizeof(node->perms[0])
                + node->datalen + node->childlen;
+
+       if (data.dsize >= quota_max_entry_size)
+               goto error;
+
        data.dptr = talloc_size(node, data.dsize);
        ((uint32_t *)data.dptr)[0] = node->num_perms;
        ((uint32_t *)data.dptr)[1] = node->datalen;
@@ -470,10 +478,12 @@
        /* TDB should set errno, but doesn't even set ecode AFAICT. */
        if (tdb_store(tdb_context(conn), key, data, TDB_REPLACE) != 0) {
                corrupt(conn, "Write of %s = %s failed", key, data);
-               errno = ENOSPC;
-               return false;
+               goto error;
        }
        return true;
+ error:
+       errno = ENOSPC;
+       return false;
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -765,8 +775,11 @@
        key.dptr = (void *)node->name;
        key.dsize = strlen(node->name);
 
-       if (tdb_delete(tdb_context(conn), key) != 0)
+       if (tdb_delete(tdb_context(conn), key) != 0) {
                corrupt(conn, "Could not delete '%s'", node->name);
+               return;
+       }
+       domain_entry_dec(conn);
 }
 
 /* Must not be / */
@@ -788,7 +801,10 @@
                parent = construct_node(conn, parentname);
        if (!parent)
                return NULL;
-       
+
+       if (domain_entry(conn) >= quota_nb_entry_per_domain)
+               return NULL;
+
        /* Add child to parent. */
        base = basename(name);
        baselen = strlen(base) + 1;
@@ -814,6 +830,7 @@
        node->children = node->data = NULL;
        node->childlen = node->datalen = 0;
        node->parent = parent;
+       domain_entry_inc(conn);
        return node;
 }
 
@@ -848,8 +865,10 @@
        /* We write out the nodes down, setting destructor in case
         * something goes wrong. */
        for (i = node; i; i = i->parent) {
-               if (!write_node(conn, i))
+               if (!write_node(conn, i)) {
+                       domain_entry_dec(conn);
                        return NULL;
+               }
                talloc_set_destructor(i, destroy_node);
        }
 
@@ -1706,6 +1725,9 @@
 "  --no-fork           to request that the daemon does not fork,\n"
 "  --output-pid        to request that the pid of the daemon is output,\n"
 "  --trace-file <file> giving the file for logging, and\n"
+"  --entry-nb <nb>     limit the number of entries per domain,\n"
+"  --entry-size <size> limit the size of entry per domain, and\n"
+"  --entry-watch <nb>  limit the number of watches per domain,\n"
 "  --no-recovery       to request that no recovery should be attempted when\n"
 "                      the store is corrupted (debug only),\n"
 "  --preserve-local    to request that /local is preserved on start-up,\n"
@@ -1715,14 +1737,17 @@
 
 static struct option options[] = {
        { "no-domain-init", 0, NULL, 'D' },
+       { "entry-nb", 1, NULL, 'E' },
        { "pid-file", 1, NULL, 'F' },
        { "help", 0, NULL, 'H' },
        { "no-fork", 0, NULL, 'N' },
        { "output-pid", 0, NULL, 'P' },
+       { "entry-size", 1, NULL, 'S' },
        { "trace-file", 1, NULL, 'T' },
        { "no-recovery", 0, NULL, 'R' },
        { "preserve-local", 0, NULL, 'L' },
        { "verbose", 0, NULL, 'V' },
+       { "watch-nb", 1, NULL, 'W' },
        { NULL, 0, NULL, 0 } };
 
 extern void dump_conn(struct connection *conn); 
@@ -1737,11 +1762,14 @@
        bool no_domain_init = false;
        const char *pidfile = NULL;
 
-       while ((opt = getopt_long(argc, argv, "DF:HNPT:RLV", options,
+       while ((opt = getopt_long(argc, argv, "DE:F:HNPS:T:RLVW:", options,
                                  NULL)) != -1) {
                switch (opt) {
                case 'D':
                        no_domain_init = true;
+                       break;
+               case 'E':
+                       quota_nb_entry_per_domain = strtol(optarg, NULL, 10);
                        break;
                case 'F':
                        pidfile = optarg;
@@ -1761,11 +1789,17 @@
                case 'L':
                        remove_local = false;
                        break;
+               case 'S':
+                       quota_max_entry_size = strtol(optarg, NULL, 10);
+                       break;
                case 'T':
                        tracefile = optarg;
                        break;
                case 'V':
                        verbose = true;
+                       break;
+               case 'W':
+                       quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
                        break;
                }
        }
diff -r 14f6d138c61d -r e7d769001b4b tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Thu Apr 13 14:15:56 2006
+++ b/tools/xenstore/xenstored_domain.c Thu Apr 13 16:21:13 2006
@@ -74,6 +74,12 @@
 
        /* Have we noticed that this domain is shutdown? */
        int shutdown;
+
+       /* number of entry from this domain in the store */
+       int nbentry;
+
+       /* number of watch for this domain */
+       int nbwatch;
 };
 
 static LIST_HEAD(domains);
@@ -285,6 +291,8 @@
        domain->conn->id = domid;
 
        domain->remote_port = port;
+       domain->nbentry = 0;
+       domain->nbwatch = 0;
 
        return domain;
 }
@@ -562,6 +570,50 @@
        return eventchn_fd;
 }
 
+void domain_entry_inc(struct connection *conn)
+{
+       if (!conn || !conn->domain)
+               return;
+       conn->domain->nbentry++;
+}
+
+void domain_entry_dec(struct connection *conn)
+{
+       if (!conn || !conn->domain)
+               return;
+       if (conn->domain->nbentry)
+               conn->domain->nbentry--;
+}
+
+int domain_entry(struct connection *conn)
+{
+       return (conn && conn->domain && conn->domain->domid)
+               ? conn->domain->nbentry
+               : 0;
+}
+
+void domain_watch_inc(struct connection *conn)
+{
+       if (!conn || !conn->domain)
+               return;
+       conn->domain->nbwatch++;
+}
+
+void domain_watch_dec(struct connection *conn)
+{
+       if (!conn || !conn->domain)
+               return;
+       if (conn->domain->nbwatch)
+               conn->domain->nbwatch--;
+}
+
+int domain_watch(struct connection *conn)
+{
+       return (conn && conn->domain && conn->domain->domid)
+               ? conn->domain->nbwatch
+               : 0;
+}
+
 /*
  * Local variables:
  *  c-file-style: "linux"
diff -r 14f6d138c61d -r e7d769001b4b tools/xenstore/xenstored_domain.h
--- a/tools/xenstore/xenstored_domain.h Thu Apr 13 14:15:56 2006
+++ b/tools/xenstore/xenstored_domain.h Thu Apr 13 16:21:13 2006
@@ -47,4 +47,12 @@
 bool domain_can_read(struct connection *conn);
 bool domain_can_write(struct connection *conn);
 
+/* Quota manipulation */
+void domain_entry_inc(struct connection *conn);
+void domain_entry_dec(struct connection *conn);
+int domain_entry(struct connection *conn);
+void domain_watch_inc(struct connection *conn);
+void domain_watch_dec(struct connection *conn);
+int domain_watch(struct connection *conn);
+
 #endif /* _XENSTORED_DOMAIN_H */
diff -r 14f6d138c61d -r e7d769001b4b tools/xenstore/xenstored_watch.c
--- a/tools/xenstore/xenstored_watch.c  Thu Apr 13 14:15:56 2006
+++ b/tools/xenstore/xenstored_watch.c  Thu Apr 13 16:21:13 2006
@@ -32,6 +32,8 @@
 #include "xenstored_test.h"
 #include "xenstored_domain.h"
 
+extern int quota_nb_watch_per_domain;
+
 struct watch
 {
        /* Watches on this connection */
@@ -135,6 +137,11 @@
                }
        }
 
+       if (domain_watch(conn) > quota_nb_watch_per_domain) {
+               send_error(conn, E2BIG);
+               return;
+       }
+
        watch = talloc(conn, struct watch);
        watch->node = talloc_strdup(watch, vec[0]);
        watch->token = talloc_strdup(watch, vec[1]);
@@ -145,6 +152,7 @@
 
        INIT_LIST_HEAD(&watch->events);
 
+       domain_watch_inc(conn);
        list_add_tail(&watch->list, &conn->watches);
        trace_create(watch, "watch");
        talloc_set_destructor(watch, destroy_watch);
@@ -169,6 +177,7 @@
                if (streq(watch->node, node) && streq(watch->token, vec[1])) {
                        list_del(&watch->list);
                        talloc_free(watch);
+                       domain_watch_dec(conn);
                        send_ack(conn, XS_UNWATCH);
                        return;
                }

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.