|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 02/11] tools/xenstored: add central quota check functions
Add central functions for checking a value (either an absolute one or
the current domain value plus an offset) against a specific quota.
This is in preparation of introducing per-domain quota.
The required changes allow to drop the "update" parameter from
domain_nbentry_fix().
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
tools/xenstored/core.c | 4 +-
tools/xenstored/domain.c | 74 +++++++++++++++++------------------
tools/xenstored/domain.h | 7 ++--
tools/xenstored/transaction.c | 2 +-
tools/xenstored/watch.c | 4 +-
5 files changed, 43 insertions(+), 48 deletions(-)
diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index d509736c32..5a4bf3e302 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -1538,7 +1538,7 @@ static struct node *create_node(struct connection *conn,
const void *ctx,
for (i = node; i; i = i->parent) {
/* i->parent is set for each new node, so check quota. */
if (i->parent &&
- domain_nbentry(conn) >= hard_quotas[ACC_NODES].val) {
+ domain_check_quota_add(conn->domain, ACC_NODES, 1)) {
ret = ENOSPC;
goto err;
}
@@ -2320,7 +2320,7 @@ void setup_structure(bool live_update)
manual_node("/tool/xenstored", NULL);
manual_node("@releaseDomain", NULL);
manual_node("@introduceDomain", NULL);
- domain_nbentry_fix(priv_domid, 5, true);
+ domain_nbentry_fix(priv_domid, 5);
}
}
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index e453b3061f..1df9265ad5 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -389,6 +389,25 @@ void wrl_apply_debit_trans_commit(struct connection *conn)
wrl_apply_debit_actual(conn->domain);
}
+static bool domain_check_quota_val(struct domain *d, enum accitem what,
+ unsigned int val)
+{
+ unsigned int quota = hard_quotas[what].val;
+
+ if (!quota || !domid_is_unprivileged(d->domid))
+ return false;
+
+ return val >= quota;
+}
+
+bool domain_check_quota_add(struct domain *d, enum accitem what, int add)
+{
+ if (add < 0 || !d)
+ return false;
+
+ return domain_check_quota_val(d, what, d->acc[what].val + add);
+}
+
static bool check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
{
return ((prod - cons) <= XENSTORE_RING_SIZE);
@@ -490,10 +509,9 @@ static bool domain_can_read(struct connection *conn)
if (domain_is_unprivileged(conn)) {
if (domain->wrl_credit < 0)
return false;
- if (domain->acc[ACC_OUTST].val >= hard_quotas[ACC_OUTST].val)
+ if (domain_check_quota_add(domain, ACC_OUTST, 0))
return false;
- if (domain->acc[ACC_MEM].val >= hard_quotas[ACC_MEM].val &&
- hard_quotas[ACC_MEM].val)
+ if (domain_check_quota_add(domain, ACC_MEM, 0))
return false;
}
@@ -904,16 +922,20 @@ do { \
int acc_fix_domains(struct list_head *head, bool chk_quota, bool update)
{
+ struct domain *d;
struct changed_domain *cd;
- int cnt;
list_for_each_entry(cd, head, list) {
- cnt = domain_nbentry_fix(cd->domid, cd->acc[ACC_NODES], update);
- if (!update) {
- if (chk_quota && cnt >= hard_quotas[ACC_NODES].val)
- return ENOSPC;
- if (cnt < 0)
+ if (update) {
+ domain_nbentry_fix(cd->domid, cd->acc[ACC_NODES]);
+ } else if (chk_quota) {
+ d = find_or_alloc_existing_domain(cd->domid);
+
+ if (!d)
return ENOMEM;
+ if (domain_check_quota_add(d, ACC_NODES,
+ cd->acc[ACC_NODES]))
+ return ENOSPC;
}
}
@@ -1732,7 +1754,7 @@ bool domain_max_chk(const struct connection *conn, enum
accitem what,
if (!conn || !conn->domain)
return false;
- if (domain_is_unprivileged(conn) && val > hard_quotas[what].val)
+ if (domain_check_quota_val(conn->domain, what, val))
return true;
domain_acc_valid_max(conn->domain, what, val);
@@ -1752,21 +1774,9 @@ int domain_nbentry_dec(struct connection *conn, unsigned
int domid)
? errno : 0;
}
-int domain_nbentry_fix(unsigned int domid, int num, bool update)
-{
- int ret;
-
- ret = domain_acc_add(NULL, domid, ACC_NODES, update ? num : 0, update);
- if (ret < 0 || update)
- return ret;
-
- return domid_is_unprivileged(domid) ? ret + num : 0;
-}
-
-unsigned int domain_nbentry(struct connection *conn)
+int domain_nbentry_fix(unsigned int domid, int num)
{
- return domain_is_unprivileged(conn)
- ? domain_acc_add(conn, conn->id, ACC_NODES, 0, true) : 0;
+ return domain_acc_add(NULL, domid, ACC_NODES, num, true);
}
static bool domain_chk_quota(struct connection *conn, unsigned int mem)
@@ -1781,7 +1791,7 @@ static bool domain_chk_quota(struct connection *conn,
unsigned int mem)
domain = conn->domain;
now = time(NULL);
- if (mem >= hard_quotas[ACC_MEM].val && hard_quotas[ACC_MEM].val) {
+ if (domain_check_quota_val(domain, ACC_MEM, mem)) {
if (domain->hard_quota_reported)
return true;
syslog(LOG_ERR, "Domain %u exceeds hard memory quota, Xenstore
interface to domain stalled\n",
@@ -1857,13 +1867,6 @@ void domain_watch_dec(struct connection *conn)
domain_acc_add(conn, conn->id, ACC_WATCH, -1, true);
}
-int domain_watch(struct connection *conn)
-{
- return (domain_is_unprivileged(conn))
- ? domain_acc_add(conn, conn->id, ACC_WATCH, 0, true)
- : 0;
-}
-
void domain_outstanding_inc(struct connection *conn)
{
domain_acc_add(conn, conn->id, ACC_OUTST, 1, true);
@@ -1884,13 +1887,6 @@ void domain_transaction_dec(struct connection *conn)
domain_acc_add(conn, conn->id, ACC_TRANS, -1, true);
}
-unsigned int domain_transaction_get(struct connection *conn)
-{
- return (domain_is_unprivileged(conn))
- ? domain_acc_add(conn, conn->id, ACC_TRANS, 0, true)
- : 0;
-}
-
const char *dump_state_connections(FILE *fp)
{
const char *ret = NULL;
diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h
index 28186ccac0..b229f6f4e0 100644
--- a/tools/xenstored/domain.h
+++ b/tools/xenstored/domain.h
@@ -113,8 +113,7 @@ int domain_alloc_permrefs(struct node_perms *perms);
/* Quota manipulation */
int domain_nbentry_inc(struct connection *conn, unsigned int domid);
int domain_nbentry_dec(struct connection *conn, unsigned int domid);
-int domain_nbentry_fix(unsigned int domid, int num, bool update);
-unsigned int domain_nbentry(struct connection *conn);
+int domain_nbentry_fix(unsigned int domid, int num);
int domain_memory_add(struct connection *conn, unsigned int domid, int mem,
bool no_quota_check);
@@ -141,12 +140,10 @@ static inline void domain_memory_add_nochk(struct
connection *conn,
}
void domain_watch_inc(struct connection *conn);
void domain_watch_dec(struct connection *conn);
-int domain_watch(struct connection *conn);
void domain_outstanding_inc(struct connection *conn);
void domain_outstanding_dec(struct connection *conn, unsigned int domid);
void domain_transaction_inc(struct connection *conn);
void domain_transaction_dec(struct connection *conn);
-unsigned int domain_transaction_get(struct connection *conn);
int domain_get_quota(const void *ctx, struct connection *conn,
unsigned int domid);
@@ -161,6 +158,8 @@ int domain_max_global_acc(const void *ctx, struct
connection *conn);
void domain_reset_global_acc(void);
bool domain_max_chk(const struct connection *conn, enum accitem what,
unsigned int val);
+bool domain_check_quota_add(struct domain *d, enum accitem what,
+ int add);
extern long wrl_ntransactions;
diff --git a/tools/xenstored/transaction.c b/tools/xenstored/transaction.c
index 167cd597fd..ccf93a1132 100644
--- a/tools/xenstored/transaction.c
+++ b/tools/xenstored/transaction.c
@@ -470,7 +470,7 @@ int do_transaction_start(const void *ctx, struct connection
*conn,
if (conn->transaction)
return EBUSY;
- if (domain_transaction_get(conn) > hard_quotas[ACC_TRANS].val)
+ if (domain_check_quota_add(conn->domain, ACC_TRANS, 1))
return ENOSPC;
/* Attach transaction to ctx for autofree until it's complete */
diff --git a/tools/xenstored/watch.c b/tools/xenstored/watch.c
index b66a9f1a39..36e4d33f22 100644
--- a/tools/xenstored/watch.c
+++ b/tools/xenstored/watch.c
@@ -220,8 +220,8 @@ int do_watch(const void *ctx, struct connection *conn,
struct buffered_data *in)
return EEXIST;
}
- if (domain_watch(conn) > hard_quotas[ACC_WATCH].val)
- return E2BIG;
+ if (domain_check_quota_add(conn->domain, ACC_WATCH, 1))
+ return ENOSPC;
watch = add_watch(conn, vec[0], vec[1], relative, false);
if (!watch)
--
2.53.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |