diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index eeb0d893e8..2e02b577c9 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -260,6 +260,8 @@ static void free_buffered_data(struct buffered_data *out, } } + domain_memory_add_nochk(conn->id, -out->hdr.msg.len - sizeof(out->hdr)); + if (out->hdr.msg.type == XS_WATCH_EVENT) { req = out->pend.req; if (req) { @@ -904,11 +906,14 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type, bdata->timeout_msec = 0; bdata->watch_event = false; - if (len <= DEFAULT_BUFFER_SIZE) + if (len <= DEFAULT_BUFFER_SIZE) { bdata->buffer = bdata->default_buffer; - else { + /* Don't check quota, path might be used for returning error. */ + domain_memory_add_nochk(conn->id, len + sizeof(bdata->hdr)); + } else { bdata->buffer = talloc_array(bdata, char, len); - if (!bdata->buffer) { + if (!bdata->buffer || + domain_memory_add_chk(conn->id, len + sizeof(bdata->hdr))) { send_error(conn, ENOMEM); return; } @@ -973,6 +978,11 @@ void send_event(struct buffered_data *req, struct connection *conn, } } + if (domain_memory_add_chk(conn->id, len + sizeof(bdata->hdr))) { + talloc_free(bdata); + return; + } + if (timeout_watch_event_msec && domain_is_unprivileged(conn)) { bdata->timeout_msec = get_now_msec() + timeout_watch_event_msec; if (!conn->timeout_msec) @@ -2940,6 +2950,12 @@ static void add_buffered_data(struct buffered_data *bdata, */ if (bdata->hdr.msg.type != XS_WATCH_EVENT) domain_outstanding_inc(conn); + /* + * We are restoring the state after Live-Update and the new quota may + * be smaller. So ignore it. The limit will be applied for any resource + * after the state has been fully restored. + */ + domain_memory_add_nochk(conn->id, len + sizeof(bdata->hdr)); } void read_state_buffered_data(const void *ctx, struct connection *conn,