tools/xenstore: allow live update only with no transaction active

In order to simplify live update state dumping only allow live update
to happen when no transaction is active.

A timeout is used to detect guests which have a transaction active for
longer periods of time. In case such a guest is detected when trying
to do a live update it will be reported and the update will fail.

The admin can then either use a longer timeout, or use the force flag
to just ignore the transactions of such a guest, or kill the guest
before retrying.

Signed-off-by: Juergen Gross <jgross@suse.com>
Acked-by: Wei Liu <wl@xen.org>
This commit is contained in:
Juergen Gross committed 2021-01-21 17:31:02 +01:00
1 parent af216a99fb
commit e04e53a5be
3 files changed
+33 -2

No files matched your search

+27 -2
View File
@@ -312,12 +312,37 @@ static const char *lu_arch(const void *ctx, struct connection *conn,
static bool lu_check_lu_allowed(void)
{
return true;
struct connection *conn;
time_t now = time(NULL);
unsigned int ta_total = 0, ta_long = 0;
list_for_each_entry(conn, &connections, list) {
if (conn->ta_start_time) {
ta_total++;
if (conn->ta_start_time - now >= lu_status->timeout)
ta_long++;
}
}
return ta_total ? (lu_status->force && ta_long == ta_total) : true;
}
static const char *lu_reject_reason(const void *ctx)
{
return "BUSY";
char *ret = NULL;
struct connection *conn;
time_t now = time(NULL);
list_for_each_entry(conn, &connections, list) {
if (conn->ta_start_time - now >= lu_status->timeout) {
ret = talloc_asprintf(ctx, "%s\nDomain %u: %ld s",
ret ? : "Domains with long running transactions:",
conn->id,
conn->ta_start_time - now);
}
}
return ret ? (const char *)ret : "Overlapping transactions";
}
static const char *lu_dump_state(const void *ctx, struct connection *conn)
+1
View File
@@ -107,6 +107,7 @@ struct connection
struct list_head transaction_list;
uint32_t next_transaction_id;
unsigned int transaction_started;
time_t ta_start_time;
/* List of delayed requests. */
struct list_head delayed;
+5
View File
@@ -473,6 +473,8 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
list_add_tail(&trans->list, &conn->transaction_list);
talloc_steal(conn, trans);
talloc_set_destructor(trans, destroy_transaction);
if (!conn->transaction_started)
conn->ta_start_time = time(NULL);
conn->transaction_started++;
wrl_ntransactions++;
@@ -511,6 +513,8 @@ int do_transaction_end(struct connection *conn, struct buffered_data *in)
conn->transaction = NULL;
list_del(&trans->list);
conn->transaction_started--;
if (!conn->transaction_started)
conn->ta_start_time = 0;
/* Attach transaction to in for auto-cleanup */
talloc_steal(in, trans);
@@ -589,6 +593,7 @@ void conn_delete_all_transactions(struct connection *conn)
assert(conn->transaction == NULL);
conn->transaction_started = 0;
conn->ta_start_time = 0;
}
int check_transactions(struct hashtable *hash)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.