From: Paul Durrant <pdurrant@amazon.com>
To: <xen-devel@lists.xenproject.org>
Cc: Anthony PERARD <anthony.perard@citrix.com>,
Paul Durrant <pdurrant@amazon.com>,
Ian Jackson <ian.jackson@eu.citrix.com>, Wei Liu <wl@xen.org>
Subject: [Xen-devel] [PATCH v4 4/7] libxl: add infrastructure to track and query 'recent' domids
Date: Wed, 22 Jan 2020 14:44:43 +0000 [thread overview]
Message-ID: <20200122144446.919-5-pdurrant@amazon.com> (raw)
In-Reply-To: <20200122144446.919-1-pdurrant@amazon.com>
A domid is considered recent if the domain it represents was destroyed
less than a specified number of seconds ago. The number can be set using
the environment variable LIBXL_DOMID_REUSE_TIMEOUT. If the variable does
not exist then a default value of 60s is used.
Whenever a domain is destroyed, a time-stamped record will be written into
a history file (/var/run/xen/domid-history). To avoid the history file
growing too large, any records with time-stamps that indicate that the
age of a domid has exceeded the re-use timeout will also be purged.
A new utility function, libxl__is_recent_domid(), has been added. This
function reads the same history file checking whether a specified domid
has a record that does not exceed the re-use timeout. Since this utility
function does not write to the file, no records are actually purged by it.
NOTE: The history file is purged on boot to it is safe to use
CLOCK_MONOTONIC as a time source.
Signed-off-by: Paul Durrant <pdurrant@amazon.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>
Cc: Anthony PERARD <anthony.perard@citrix.com>
v4:
- Use new generalised libxl__flock
- Don't read and write the same file
- Use 'recent' rather than 'retired'
- Add code into xen-init-dom0 to delete an old history file at boot
v2:
- New in v2
---
tools/helpers/xen-init-dom0.c | 30 ++++++++
tools/libxl/libxl.h | 2 +
tools/libxl/libxl_domain.c | 135 ++++++++++++++++++++++++++++++++++
tools/libxl/libxl_internal.c | 10 +++
tools/libxl/libxl_internal.h | 14 ++++
5 files changed, 191 insertions(+)
diff --git a/tools/helpers/xen-init-dom0.c b/tools/helpers/xen-init-dom0.c
index a1e5729458..56f69ab66f 100644
--- a/tools/helpers/xen-init-dom0.c
+++ b/tools/helpers/xen-init-dom0.c
@@ -12,6 +12,32 @@
#define DOMNAME_PATH "/local/domain/0/name"
#define DOMID_PATH "/local/domain/0/domid"
+int clear_domid_history(void)
+{
+ int rc = 1;
+ xentoollog_logger_stdiostream *logger;
+ libxl_ctx *ctx;
+
+ logger = xtl_createlogger_stdiostream(stderr, XTL_ERROR, 0);
+ if (!logger)
+ return 1;
+
+ if (libxl_ctx_alloc(&ctx, LIBXL_VERSION, 0,
+ (xentoollog_logger *)logger)) {
+ fprintf(stderr, "cannot init libxl context\n");
+ goto outlog;
+ }
+
+ if (!libxl_clear_domid_history(ctx))
+ rc = 0;
+
+ libxl_ctx_free(ctx);
+
+outlog:
+ xtl_logger_destroy((xentoollog_logger *)logger);
+ return rc;
+}
+
int main(int argc, char **argv)
{
int rc;
@@ -70,6 +96,10 @@ int main(int argc, char **argv)
if (rc)
goto out;
+ rc = clear_domid_history();
+ if (rc)
+ goto out;
+
/* Write xenstore entries. */
if (!xs_write(xsh, XBT_NULL, DOMID_PATH, "0", strlen("0"))) {
fprintf(stderr, "cannot set domid for Dom0\n");
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 18c1a2d6bf..1d235ecb1c 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -2657,6 +2657,8 @@ static inline int libxl_qemu_monitor_command_0x041200(libxl_ctx *ctx,
#include <libxl_event.h>
+int libxl_clear_domid_history(libxl_ctx *ctx);
+
#endif /* LIBXL_H */
/*
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 1bdb1615d8..d424a8542f 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1268,6 +1268,140 @@ static void dm_destroy_cb(libxl__egc *egc,
libxl__devices_destroy(egc, &dis->drs);
}
+static unsigned int libxl__get_domid_reuse_timeout(void)
+{
+ const char *env_timeout = getenv("LIBXL_DOMID_REUSE_TIMEOUT");
+
+ return env_timeout ? strtol(env_timeout, NULL, 0) :
+ LIBXL_DOMID_REUSE_TIMEOUT;
+}
+
+char *libxl__domid_history_path(libxl__gc *gc, const char *suffix)
+{
+ return GCSPRINTF("%s/domid-history%s", libxl__run_dir_path(),
+ suffix ?: "");
+}
+
+int libxl_clear_domid_history(libxl_ctx *ctx)
+{
+ GC_INIT(ctx);
+ char *path;
+ int rc = ERROR_FAIL;
+
+ path = libxl__domid_history_path(gc, NULL);
+ if (!path)
+ goto out;
+
+ if (unlink(path) < 0 && errno != ENOENT) {
+ LOGE(ERROR, "failed to remove '%s'\n", path);
+ goto out;
+ }
+
+ rc = 0;
+
+out:
+ GC_FREE;
+ return rc;
+}
+
+static void libxl__mark_domid_recent(libxl__gc *gc, uint32_t domid)
+{
+ long timeout = libxl__get_domid_reuse_timeout();
+ libxl__flock *lock;
+ char *old, *new;
+ FILE *of = NULL, *nf = NULL;
+ struct timespec ts;
+ char line[64];
+
+ lock = libxl__lock_domid_history(gc);
+ if (!lock) {
+ LOGED(ERROR, domid, "failed to acquire lock");
+ goto out;
+ }
+
+ old = libxl__domid_history_path(gc, NULL);
+ of = fopen(old, "r");
+ if (!of && errno != ENOENT)
+ LOGED(WARN, domid, "failed to open '%s'", old);
+
+ new = libxl__domid_history_path(gc, ".new");
+ nf = fopen(new, "a");
+ if (!nf) {
+ LOGED(ERROR, domid, "failed to open '%s'", new);
+ goto out;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ while (of && fgets(line, sizeof(line), of)) {
+ unsigned long sec;
+ unsigned int ignored;
+
+ if (sscanf(line, "%lu %u", &sec, &ignored) != 2) {
+ LOGED(ERROR, domid, "ignoring malformed line: %s", line);
+ continue;
+ }
+
+ if (ts.tv_sec - sec > timeout)
+ continue; /* Ignore expired entries */
+
+ if (fputs(line, nf) == EOF) {
+ LOGED(ERROR, domid, "failed to write");
+ goto out;
+ }
+ }
+
+ if (fprintf(nf, "%lu %u\n", ts.tv_sec, domid) < 0) {
+ LOGED(ERROR, domid, "failed to write");
+ goto out;
+ }
+
+ fflush(nf);
+
+ if (rename(new, old) < 0)
+ LOGED(ERROR, domid, "failed to rename '%s' -> '%s'", old, new);
+
+out:
+ if (nf) fclose(nf);
+ if (of) fclose(of);
+ if (lock) libxl__unlock_file(lock);
+}
+
+bool libxl__is_domid_recent(libxl__gc *gc, uint32_t domid)
+{
+ long timeout = libxl__get_domid_reuse_timeout();
+ bool recent = false;
+ const char *name;
+ FILE *f;
+ struct timespec ts;
+
+ name = GCSPRINTF("%s/domid-history", libxl__run_dir_path());
+ f = fopen(name, "r");
+ if (!f) {
+ if (errno != ENOENT) LOGED(WARN, domid, "failed to open %s", name);
+ return false;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ while (!feof(f)) {
+ unsigned long sec;
+ unsigned int check;
+
+ if (fscanf(f, "%lu %u", &sec, &check) != 2)
+ continue;
+
+ if (check == domid && ts.tv_sec - sec <= timeout) {
+ recent = true;
+ break;
+ }
+ }
+
+ fclose(f);
+
+ return recent;
+}
+
static void devices_destroy_cb(libxl__egc *egc,
libxl__devices_remove_state *drs,
int rc)
@@ -1331,6 +1465,7 @@ static void devices_destroy_cb(libxl__egc *egc,
if (!ctx->xch) goto badchild;
if (!dis->soft_reset) {
+ libxl__mark_domid_recent(gc, domid);
rc = xc_domain_destroy(ctx->xch, domid);
} else {
rc = xc_domain_pause(ctx->xch, domid);
diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
index 211236dc99..bbd4c6cba9 100644
--- a/tools/libxl/libxl_internal.c
+++ b/tools/libxl/libxl_internal.c
@@ -504,6 +504,16 @@ libxl__flock *libxl__lock_domain_userdata(libxl__gc *gc, uint32_t domid)
return lock;
}
+libxl__flock *libxl__lock_domid_history(libxl__gc *gc)
+{
+ const char *lockfile;
+
+ lockfile = libxl__domid_history_path(gc, ".lock");
+ if (!lockfile) return NULL;
+
+ return libxl__lock_file(gc, lockfile);
+}
+
int libxl__get_domain_configuration(libxl__gc *gc, uint32_t domid,
libxl_domain_config *d_config)
{
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 3fb38220e5..a50d5a2939 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -4233,6 +4233,8 @@ _hidden void libxl__remus_teardown(libxl__egc *egc,
_hidden void libxl__remus_restore_setup(libxl__egc *egc,
libxl__domain_create_state *dcs);
+_hidden char *libxl__domid_history_path(libxl__gc *gc,
+ const char *suffix);
/*
* Convenience macros.
@@ -4631,6 +4633,7 @@ libxl__flock *libxl__lock_file(libxl__gc *gc, const char *filename);
void libxl__unlock_file(libxl__flock *lock);
libxl__flock *libxl__lock_domain_userdata(libxl__gc *gc, uint32_t domid);
+libxl__flock *libxl__lock_domid_history(libxl__gc *gc);
/*
* Retrieve / store domain configuration from / to libxl private
@@ -4769,6 +4772,17 @@ _hidden int libxl__domain_pvcontrol(libxl__egc *egc,
libxl__xswait_state *pvcontrol,
domid_t domid, const char *cmd);
+/*
+ * Maximum number of seconds after desctruction then a domid remains
+ * 'recent'. Recent domids are not allowed to be re-used. This can be
+ * overidden, for debugging purposes, by the environment variable of the
+ * same name.
+ */
+#define LIBXL_DOMID_REUSE_TIMEOUT 60
+
+/* Check whether a domid is recent */
+bool libxl__is_domid_recent(libxl__gc *gc, uint32_t domid);
+
#endif
/*
--
2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2020-01-22 14:45 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-22 14:44 [Xen-devel] [PATCH v4 0/7] xl/libxl: domid allocation/preservation changes Paul Durrant
2020-01-22 14:44 ` [Xen-devel] [PATCH v4 1/7] libxl: add definition of INVALID_DOMID to the API Paul Durrant
2020-01-22 14:52 ` Roger Pau Monné
2020-01-31 10:31 ` Durrant, Paul
2020-01-31 11:06 ` Roger Pau Monné
2020-01-31 11:10 ` Durrant, Paul
2020-01-31 12:07 ` Andrew Cooper
2020-01-31 12:11 ` Durrant, Paul
2020-01-30 17:31 ` Ian Jackson
2020-01-30 17:35 ` Durrant, Paul
2020-01-30 17:51 ` Ian Jackson
2020-01-22 14:44 ` [Xen-devel] [PATCH v4 2/7] libxl_create: make 'soft reset' explicit Paul Durrant
2020-01-22 14:44 ` [Xen-devel] [PATCH v4 3/7] libxl: generalise libxl__domain_userdata_lock() Paul Durrant
2020-01-30 17:04 ` Ian Jackson
2020-01-22 14:44 ` Paul Durrant [this message]
2020-01-30 17:23 ` [Xen-devel] [PATCH v4 4/7] libxl: add infrastructure to track and query 'recent' domids Ian Jackson
2020-01-31 10:55 ` Anthony PERARD
2020-01-31 10:57 ` Durrant, Paul
2020-01-22 14:44 ` [Xen-devel] [PATCH v4 5/7] libxl: allow creation of domains with a specified or random domid Paul Durrant
2020-01-30 17:25 ` Ian Jackson
2020-01-30 17:32 ` Durrant, Paul
2020-01-22 14:44 ` [Xen-devel] [PATCH v4 6/7] xl.conf: introduce 'domid_policy' Paul Durrant
2020-01-22 14:44 ` [Xen-devel] [PATCH v4 7/7] xl: allow domid to be preserved on save/restore or migrate Paul Durrant
2020-01-30 17:28 ` Ian Jackson
2020-01-30 17:42 ` Durrant, Paul
2020-01-30 18:20 ` Andrew Cooper
2020-01-31 16:07 ` Wei Liu
2020-02-01 11:56 ` Durrant, Paul
2020-02-21 11:58 ` Wei Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200122144446.919-5-pdurrant@amazon.com \
--to=pdurrant@amazon.com \
--cc=anthony.perard@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.