int quota_nb_entry_per_domain = 1000;
int quota_nb_watch_per_domain = 128;
int quota_max_entry_size = 2048; /* 2K */
+int quota_max_transaction = 10;
#ifdef TESTING
static bool failtest = false;
new->write = write;
new->read = read;
new->can_write = true;
+ new->transaction_started = 0;
INIT_LIST_HEAD(&new->out_list);
INIT_LIST_HEAD(&new->watches);
INIT_LIST_HEAD(&new->transaction_list);
" --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"
+" --transaction <nb> limit the number of transaction allowed 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"
{ "output-pid", 0, NULL, 'P' },
{ "entry-size", 1, NULL, 'S' },
{ "trace-file", 1, NULL, 'T' },
+ { "transaction", 1, NULL, 't' },
{ "no-recovery", 0, NULL, 'R' },
{ "preserve-local", 0, NULL, 'L' },
{ "verbose", 0, NULL, 'V' },
const char *pidfile = NULL;
int evtchn_fd = -1;
- while ((opt = getopt_long(argc, argv, "DE:F:HNPS:T:RLVW:", options,
+ while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RLVW:", options,
NULL)) != -1) {
switch (opt) {
case 'D':
case 'S':
quota_max_entry_size = strtol(optarg, NULL, 10);
break;
+ case 't':
+ quota_max_transaction = strtol(optarg, NULL, 10);
+ break;
case 'T':
tracefile = optarg;
break;
struct list_head changes;
};
+extern int quota_max_transaction;
static unsigned int generation;
/* Return tdb context to use for this connection. */
{
struct transaction *trans, *exists;
char id_str[20];
- int started;
/* We don't support nested transactions. */
if (conn->transaction) {
return;
}
- started = 0;
- list_for_each_entry(trans, &conn->transaction_list, list)
- started++;
-
- if (started > 5) {
+ if (conn->transaction_started > quota_max_transaction) {
send_error(conn, ENOSPC);
return;
}
list_add_tail(&trans->list, &conn->transaction_list);
talloc_steal(conn, trans);
talloc_set_destructor(trans, destroy_transaction);
+ conn->transaction_started++;
sprintf(id_str, "%u", trans->id);
send_reply(conn, XS_TRANSACTION_START, id_str, strlen(id_str)+1);
conn->transaction = NULL;
list_del(&trans->list);
+ conn->transaction_started--;
/* Attach transaction to arg for auto-cleanup */
talloc_steal(arg, trans);