[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




 


Rackspace

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