[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |