# 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
|