All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xen-devel] [PATCH v6 0/6] xl/libxl: domid allocation/preservation changes
@ 2020-02-19  9:37 Paul Durrant
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids Paul Durrant
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Paul Durrant @ 2020-02-19  9:37 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Jason Andryuk,
	George Dunlap, Andrew Cooper, Paul Durrant,
	Konrad Rzeszutek Wilk, Ian Jackson, Jan Beulich, Anthony PERARD

Paul Durrant (6):
  libxl: add infrastructure to track and query 'recent' domids
  libxl: modify libxl__logv() to only log valid domid values
  public/xen.h: add a definition for a 'valid domid' mask
  libxl: allow creation of domains with a specified or random domid
  xl.conf: introduce 'domid_policy'
  xl: allow domid to be preserved on save/restore or migrate

 docs/man/xl.1.pod.in          |  14 +++
 docs/man/xl.conf.5.pod        |  10 ++
 tools/examples/xl.conf        |   4 +
 tools/helpers/xen-init-dom0.c |  30 +++++
 tools/libxl/libxl.h           |  16 +++
 tools/libxl/libxl_create.c    |  76 +++++++++++-
 tools/libxl/libxl_domain.c    | 222 ++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.c  |  12 +-
 tools/libxl/libxl_internal.h  |  14 +++
 tools/libxl/libxl_types.idl   |   1 +
 tools/xl/xl.c                 |  10 ++
 tools/xl/xl.h                 |   2 +
 tools/xl/xl_cmdtable.c        |   6 +-
 tools/xl/xl_migrate.c         |  15 ++-
 tools/xl/xl_saverestore.c     |  19 ++-
 tools/xl/xl_vmcontrol.c       |   3 +
 xen/include/public/xen.h      |   3 +
 17 files changed, 439 insertions(+), 18 deletions(-)
---
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Anthony PERARD <anthony.perard@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Jason Andryuk <jandryuk@gmail.com>
Cc: Julien Grall <julien@xen.org>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Wei Liu <wl@xen.org>
-- 
2.20.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids
  2020-02-19  9:37 [Xen-devel] [PATCH v6 0/6] xl/libxl: domid allocation/preservation changes Paul Durrant
@ 2020-02-19  9:37 ` Paul Durrant
  2020-02-20 16:19   ` Ian Jackson
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 2/6] libxl: modify libxl__logv() to only log valid domid values Paul Durrant
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Paul Durrant @ 2020-02-19  9:37 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Paul Durrant, Ian Jackson, Wei Liu

A domid is considered recent if the domain it represents was destroyed
less than a specified number of seconds ago. For debugging and/or testing
purposes 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>

v6:
 _ Addressed further comments from Ian

v5:
 - Re-work file manipulation some more
 - Add more error checks

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           |   7 ++
 tools/libxl/libxl_domain.c    | 222 ++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.c  |  10 ++
 tools/libxl/libxl_internal.h  |  14 +++
 5 files changed, 283 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 fde8548847..80ae110a52 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -2679,6 +2679,13 @@ static inline int libxl_qemu_monitor_command_0x041200(libxl_ctx *ctx,
 
 #include <libxl_event.h>
 
+/*
+ * This function is for use only during host initialisation. If it is
+ * invoked on a host with running domains, or concurrent libxl
+ * processes then the system may malfuntion.
+ */
+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 973fc1434d..53f90cb555 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1268,6 +1268,226 @@ 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 int libxl__read_recent(libxl__gc *gc, FILE *f, unsigned long *sec,
+                              unsigned int *domid)
+{
+    if (!f) {
+        *domid = INVALID_DOMID;
+        return 0;
+    }
+
+    for (;;) {
+        int n = fscanf(f, "%lu %u", sec, domid);
+
+        if (n == EOF) {
+            if (ferror(f)) {
+                LOGE(ERROR, "failed");
+                return ERROR_FAIL;
+            }
+
+            *domid = INVALID_DOMID;
+            break;
+        } else if (n == 2 && libxl_domid_valid_guest(*domid)) {
+            break;
+        }
+    }
+
+    return 0;
+}
+
+static int libxl__write_recent(libxl__gc *gc, FILE *f, unsigned long sec,
+                               unsigned int domid)
+{
+    int n = fprintf(f, "%lu %u\n", sec, domid);
+
+    if (n >= 0) return 0;
+
+    LOGE(ERROR, "failed");
+    return ERROR_FAIL;
+}
+
+static int libxl__open_domid_history(libxl__gc *gc, FILE **f)
+{
+    char *path = libxl__domid_history_path(gc, NULL);
+
+    *f = fopen(path, "r");
+    if (*f || errno == ENOENT) return 0;
+
+    LOGE(ERROR, "failed to open '%s'", path);
+    return ERROR_FAIL;
+}
+
+static int libxl__close_domid_history(libxl__gc *gc, FILE **f)
+{
+    int ret;
+
+    if (!*f) return 0;
+
+    ret = fclose(*f);
+    *f = NULL;
+    if (!ret) return 0;
+
+    LOGE(ERROR, "failed");
+    return ERROR_FAIL;
+}
+
+static int libxl__replace_domid_history(libxl__gc *gc, char *new)
+{
+    char *path = libxl__domid_history_path(gc, NULL);
+    int ret = rename(new, path);
+
+    if (!ret) return 0;
+
+    LOGE(ERROR, "failed to rename '%s' -> '%s'", new, path);
+    return ERROR_FAIL;
+}
+
+static int libxl__mark_domid_recent(libxl__gc *gc, uint32_t domid)
+{
+    long timeout = libxl__get_domid_reuse_timeout();
+    libxl__flock *lock;
+    char *new;
+    FILE *of = NULL, *nf = NULL;
+    struct timespec ts;
+    int ret, rc;
+
+    lock = libxl__lock_domid_history(gc);
+    if (!lock) {
+        LOGED(ERROR, domid, "failed to acquire lock");
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    rc = libxl__open_domid_history(gc, &of);
+    if (rc) goto out;
+
+    new = libxl__domid_history_path(gc, ".new");
+    nf = fopen(new, "a");
+    if (!nf) {
+        LOGED(ERROR, domid, "failed to open '%s'", new);
+        goto out;
+    }
+
+    if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
+        LOGED(ERROR, domid, "failed to get time");
+        goto out;
+    }
+
+    for (;;) {
+        unsigned long sec;
+        unsigned int val;
+
+        rc = libxl__read_recent(gc, of, &sec, &val);
+        if (rc) goto out;
+
+        if (val == INVALID_DOMID) /* EOF */
+            break;
+
+        if (ts.tv_sec - sec > timeout)
+            continue; /* Ignore expired entries */
+
+        rc = libxl__write_recent(gc, nf, sec, val);
+        if (rc) goto out;
+    }
+
+    rc = libxl__write_recent(gc, nf, ts.tv_sec, domid);
+    if (rc) goto out;
+
+    ret = fclose(nf);
+    nf = NULL;
+    if (ret == EOF) {
+        LOGED(ERROR, domid, "failed to close '%s'", new);
+        goto out;
+    }
+
+    rc = libxl__close_domid_history(gc, &of);
+    if (rc) goto out;
+
+    rc = libxl__replace_domid_history(gc, new);
+
+out:
+    if (nf) fclose(nf);
+    if (of) fclose(of);
+    if (lock) libxl__unlock_file(lock);
+
+    return rc;
+}
+
+int libxl__is_domid_recent(libxl__gc *gc, uint32_t domid, bool *recent)
+{
+    long timeout = libxl__get_domid_reuse_timeout();
+    FILE *f;
+    struct timespec ts;
+    int rc;
+
+    rc = libxl__open_domid_history(gc, &f);
+    if (rc) goto out;
+
+    if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
+        LOGED(ERROR, domid, "failed to get time");
+        goto out;
+    }
+
+    *recent = false;
+    for (;;) {
+        unsigned long sec;
+        unsigned int val;
+
+        rc = libxl__read_recent(gc, f, &sec, &val);
+        if (rc) goto out;
+
+        if (val == INVALID_DOMID) /* EOF */
+            break;
+
+        if (val == domid && ts.tv_sec - sec <= timeout) {
+            *recent = true;
+            break;
+        }
+    }
+
+    rc = libxl__close_domid_history(gc, &f);
+
+out:
+    if (f) fclose(f);
+    return rc;
+}
+
 static void devices_destroy_cb(libxl__egc *egc,
                                libxl__devices_remove_state *drs,
                                int rc)
@@ -1331,6 +1551,8 @@ static void devices_destroy_cb(libxl__egc *egc,
         if (!ctx->xch) goto badchild;
 
         if (!dis->soft_reset) {
+            rc = libxl__mark_domid_recent(gc, domid);
+            if (rc) goto badchild;
             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 4936446069..43e5885d1e 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -4263,6 +4263,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.
@@ -4661,6 +4663,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
@@ -4799,6 +4802,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 */
+int libxl__is_domid_recent(libxl__gc *gc, uint32_t domid, bool *recent);
+
 #endif
 
 /*
-- 
2.20.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Xen-devel] [PATCH v6 2/6] libxl: modify libxl__logv() to only log valid domid values
  2020-02-19  9:37 [Xen-devel] [PATCH v6 0/6] xl/libxl: domid allocation/preservation changes Paul Durrant
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids Paul Durrant
@ 2020-02-19  9:37 ` Paul Durrant
  2020-02-20 16:20   ` Ian Jackson
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 3/6] public/xen.h: add a definition for a 'valid domid' mask Paul Durrant
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Paul Durrant @ 2020-02-19  9:37 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Paul Durrant, Ian Jackson, Wei Liu

Some code-paths use values other than INVALID_DOMID to indicate an invalid
domain id. Specifically, xl will pass a value of 0 when creating/restoring
a domain. Therefore modify libxl__logv() to use libxl_domid_valid_guest()
as a validity test.

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>

v6:
 - New in v6 (split out from another patch)
---
 tools/libxl/libxl_internal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
index bbd4c6cba9..d93a75533f 100644
--- a/tools/libxl/libxl_internal.c
+++ b/tools/libxl/libxl_internal.c
@@ -234,7 +234,7 @@ void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
     fileline[sizeof(fileline)-1] = 0;
 
     domain[0] = 0;
-    if (domid != INVALID_DOMID)
+    if (libxl_domid_valid_guest(domid))
         snprintf(domain, sizeof(domain), "Domain %"PRIu32":", domid);
  x:
     xtl_log(ctx->lg, msglevel, errnoval, "libxl",
-- 
2.20.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Xen-devel] [PATCH v6 3/6] public/xen.h: add a definition for a 'valid domid' mask
  2020-02-19  9:37 [Xen-devel] [PATCH v6 0/6] xl/libxl: domid allocation/preservation changes Paul Durrant
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids Paul Durrant
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 2/6] libxl: modify libxl__logv() to only log valid domid values Paul Durrant
@ 2020-02-19  9:37 ` Paul Durrant
  2020-02-20 16:22   ` Ian Jackson
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 4/6] libxl: allow creation of domains with a specified or random domid Paul Durrant
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Paul Durrant @ 2020-02-19  9:37 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Paul Durrant, Ian Jackson,
	Jan Beulich

A subsequent patch will modify libxl to allow selection of a random domid
value when creating domains. Valid values are limited to a width of 15 bits,
so add an appropriate mask definition to the public header.

Signed-off-by: Paul Durrant <pdurrant@amazon.com>
---
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Julien Grall <julien@xen.org>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Wei Liu <wl@xen.org>

v6:
 - New in v6 (split out from another patch)
---
 xen/include/public/xen.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index d2198dffad..75b1619d0d 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -614,6 +614,9 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
 /* Idle domain. */
 #define DOMID_IDLE           xen_mk_uint(0x7FFF)
 
+/* Mask for valid domain id values */
+#define DOMID_MASK           xen_mk_uint(0x7FFF)
+
 #ifndef __ASSEMBLY__
 
 typedef uint16_t domid_t;
-- 
2.20.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Xen-devel] [PATCH v6 4/6] libxl: allow creation of domains with a specified or random domid
  2020-02-19  9:37 [Xen-devel] [PATCH v6 0/6] xl/libxl: domid allocation/preservation changes Paul Durrant
                   ` (2 preceding siblings ...)
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 3/6] public/xen.h: add a definition for a 'valid domid' mask Paul Durrant
@ 2020-02-19  9:37 ` Paul Durrant
  2020-02-20 16:25   ` Ian Jackson
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 5/6] xl.conf: introduce 'domid_policy' Paul Durrant
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 6/6] xl: allow domid to be preserved on save/restore or migrate Paul Durrant
  5 siblings, 1 reply; 15+ messages in thread
From: Paul Durrant @ 2020-02-19  9:37 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Paul Durrant, Jason Andryuk,
	Ian Jackson, Jan Beulich, Anthony PERARD

This patch adds a 'domid' field to libxl_domain_create_info and then
modifies libxl__domain_make() to have Xen use that value if it is valid.
If the domid value is invalid then Xen will choose the domid, as before,
unless the value is the new special RANDOM_DOMID value added to the API.
This value instructs libxl__domain_make() to choose a random domid value
for Xen to use.

If Xen determines that a domid specified to or chosen by
libxl__domain_make() co-incides with an existing domain then the create
operation will fail. In this case, if RANDOM_DOMID was specified to
libxl__domain_make() then a new random value will be chosen and the create
operation will be re-tried, otherwise libxl__domain_make() will fail.

After Xen has successfully created a new domain, libxl__domain_make() will
check whether its domid matches any recently used domid values. If it does
then the domain will be destroyed. If the domid used in creation was
specified to libxl__domain_make() then it will fail at this point,
otherwise the create operation will be re-tried with either a new random
or Xen-selected domid value.

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>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Julien Grall <julien@xen.org>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Jason Andryuk <jandryuk@gmail.com>

v6:
 - Addressed further comments from Ian

v5:
 - Flattened nested loops

v4:
 - Not added Jason's R-b because of substantial change
 - Check for recent domid *after* creation
 - Re-worked commit comment

v3:
 - Added DOMID_MASK definition used to mask randomized values
 - Use stack variable to avoid assuming endianness

v2:
 - Re-worked to use a value from libxl_domain_create_info
---
 tools/libxl/libxl.h         |  9 +++++
 tools/libxl/libxl_create.c  | 76 ++++++++++++++++++++++++++++++++++---
 tools/libxl/libxl_types.idl |  1 +
 3 files changed, 81 insertions(+), 5 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 80ae110a52..35e13428b2 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1268,6 +1268,14 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, const libxl_mac *src);
  */
 #define LIBXL_HAVE_DOMAIN_NEED_MEMORY_CONFIG
 
+/*
+ * LIBXL_HAVE_CREATEINFO_DOMID
+ *
+ * libxl_domain_create_new() and libxl_domain_create_restore() will use
+ * a domid specified in libxl_domain_create_info().
+ */
+#define LIBXL_HAVE_CREATEINFO_DOMID
+
 typedef char **libxl_string_list;
 void libxl_string_list_dispose(libxl_string_list *sl);
 int libxl_string_list_length(const libxl_string_list *sl);
@@ -1528,6 +1536,7 @@ int libxl_ctx_free(libxl_ctx *ctx /* 0 is OK */);
 /* domain related functions */
 
 #define INVALID_DOMID ~0
+#define RANDOM_DOMID (INVALID_DOMID - 1)
 
 /* If the result is ERROR_ABORTED, the domain may or may not exist
  * (in a half-created state).  *domid will be valid and will be the
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 3a7364e2ac..ccc9e70990 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -600,11 +600,77 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config,
             goto out;
         }
 
-        ret = xc_domain_create(ctx->xch, domid, &create);
-        if (ret < 0) {
-            LOGED(ERROR, *domid, "domain creation fail");
-            rc = ERROR_FAIL;
-            goto out;
+        for (;;) {
+            uint32_t local_domid;
+            bool recent;
+
+            if (info->domid == RANDOM_DOMID) {
+                uint16_t v;
+
+                ret = libxl__random_bytes(gc, (void *)&v, sizeof(v));
+                if (ret < 0)
+                    break;
+
+                v &= DOMID_MASK;
+                if (!libxl_domid_valid_guest(v))
+                    continue;
+
+                local_domid = v;
+            } else {
+                local_domid = info->domid; /* May not be valid */
+            }
+
+            ret = xc_domain_create(ctx->xch, &local_domid, &create);
+            if (ret < 0) {
+                /*
+                 * If we generated a random domid and creation failed
+                 * because that domid already exists then simply try
+                 * again.
+                 */
+                if (errno == EEXIST && info->domid == RANDOM_DOMID)
+                    continue;
+
+                LOGED(ERROR, local_domid, "domain creation fail");
+                rc = ERROR_FAIL;
+                goto out;
+            }
+
+            /* A new domain now exists */
+            *domid = local_domid;
+
+            rc = libxl__is_domid_recent(gc, local_domid, &recent);
+            if (rc)
+                goto out;
+
+            /* The domid is not recent, so we're done */
+            if (!recent)
+                break;
+
+            /*
+             * If the domid was specified then there's no point in
+             * trying again.
+             */
+            if (libxl_domid_valid_guest(info->domid)) {
+                LOGED(ERROR, local_domid, "domain id recently used");
+                rc = ERROR_FAIL;
+                goto out;
+            }
+
+            /*
+             * The domain is recent and so cannot be used. Clear domid
+             * here since, if xc_domain_destroy() fails below there is
+             * little point calling it again in the error path.
+             */
+            *domid = INVALID_DOMID;
+
+            ret = xc_domain_destroy(ctx->xch, local_domid);
+            if (ret < 0) {
+                LOGED(ERROR, local_domid, "domain destroy fail");
+                rc = ERROR_FAIL;
+                goto out;
+            }
+
+            /* The domain was successfully destroyed, so we can try again */
         }
 
         rc = libxl__arch_domain_save_config(gc, d_config, state, &create);
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 7921950f6a..d0d431614f 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -409,6 +409,7 @@ libxl_domain_create_info = Struct("domain_create_info",[
     ("ssidref",      uint32),
     ("ssid_label",   string),
     ("name",         string),
+    ("domid",        libxl_domid),
     ("uuid",         libxl_uuid),
     ("xsdata",       libxl_key_value_list),
     ("platformdata", libxl_key_value_list),
-- 
2.20.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Xen-devel] [PATCH v6 5/6] xl.conf: introduce 'domid_policy'
  2020-02-19  9:37 [Xen-devel] [PATCH v6 0/6] xl/libxl: domid allocation/preservation changes Paul Durrant
                   ` (3 preceding siblings ...)
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 4/6] libxl: allow creation of domains with a specified or random domid Paul Durrant
@ 2020-02-19  9:37 ` Paul Durrant
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 6/6] xl: allow domid to be preserved on save/restore or migrate Paul Durrant
  5 siblings, 0 replies; 15+ messages in thread
From: Paul Durrant @ 2020-02-19  9:37 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Paul Durrant, Ian Jackson, Wei Liu

This patch adds a new global 'domid_policy' configuration option to decide
how domain id values are allocated for new domains. It may be set to one of
two values:

"xen", the default value, will cause an invalid domid value to be passed
to do_domain_create() preserving the existing behaviour of having Xen
choose the domid value during domain_create().

"random" will cause the special RANDOM_DOMID value to be passed to
do_domain_create() such that libxl__domain_make() will select a random
domid value.

Signed-off-by: Paul Durrant <pdurrant@amazon.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
Cc: Wei Liu <wl@xen.org>
Cc: Anthony PERARD <anthony.perard@citrix.com>

v2:
 - New in v2
---
 docs/man/xl.conf.5.pod  | 10 ++++++++++
 tools/examples/xl.conf  |  4 ++++
 tools/xl/xl.c           | 10 ++++++++++
 tools/xl/xl.h           |  1 +
 tools/xl/xl_vmcontrol.c |  2 ++
 5 files changed, 27 insertions(+)

diff --git a/docs/man/xl.conf.5.pod b/docs/man/xl.conf.5.pod
index 207ab3e77a..41ee428744 100644
--- a/docs/man/xl.conf.5.pod
+++ b/docs/man/xl.conf.5.pod
@@ -45,6 +45,16 @@ The semantics of each C<KEY> defines which form of C<VALUE> is required.
 
 =over 4
 
+=item B<domid_policy="xen"|"random">
+
+Determines how domain-id is set when creating a new domain.
+
+If set to "xen" then the hypervisor will allocate new domain-id values on a sequential basis.
+
+If set to "random" then a random domain-id value will be chosen.
+
+Default: "xen"
+
 =item B<autoballoon="off"|"on"|"auto">
 
 If set to "on" then C<xl> will automatically reduce the amount of
diff --git a/tools/examples/xl.conf b/tools/examples/xl.conf
index 0446deb304..95f2f442d3 100644
--- a/tools/examples/xl.conf
+++ b/tools/examples/xl.conf
@@ -1,5 +1,9 @@
 ## Global XL config file ##
 
+# Set domain-id policy. "xen" means that the hypervisor will choose the
+# id of a new domain. "random" means that a random value will be chosen.
+#domid_policy="xen"
+
 # Control whether dom0 is ballooned down when xen doesn't have enough
 # free memory to create a domain.  "auto" means only balloon if dom0
 # starts with all the host's memory.
diff --git a/tools/xl/xl.c b/tools/xl/xl.c
index 3d4390a46d..2a5ddd4390 100644
--- a/tools/xl/xl.c
+++ b/tools/xl/xl.c
@@ -54,6 +54,7 @@ int claim_mode = 1;
 bool progress_use_cr = 0;
 int max_grant_frames = -1;
 int max_maptrack_frames = -1;
+libxl_domid domid_policy = INVALID_DOMID;
 
 xentoollog_level minmsglevel = minmsglevel_default;
 
@@ -228,6 +229,15 @@ static void parse_global_config(const char *configfile,
     else
         libxl_bitmap_set_any(&global_pv_affinity_mask);
 
+    if (!xlu_cfg_get_string (config, "domid_policy", &buf, 0)) {
+        if (!strcmp(buf, "xen"))
+            domid_policy = INVALID_DOMID;
+        else if (!strcmp(buf, "random"))
+            domid_policy = RANDOM_DOMID;
+        else
+            fprintf(stderr, "invalid domid_policy option");
+    }
+
     xlu_cfg_destroy(config);
 }
 
diff --git a/tools/xl/xl.h b/tools/xl/xl.h
index 60bdad8ffb..2b4709efb2 100644
--- a/tools/xl/xl.h
+++ b/tools/xl/xl.h
@@ -283,6 +283,7 @@ extern int max_maptrack_frames;
 extern libxl_bitmap global_vm_affinity_mask;
 extern libxl_bitmap global_hvm_affinity_mask;
 extern libxl_bitmap global_pv_affinity_mask;
+extern libxl_domid domid_policy;
 
 enum output_format {
     OUTPUT_FORMAT_JSON,
diff --git a/tools/xl/xl_vmcontrol.c b/tools/xl/xl_vmcontrol.c
index e520b1da79..39292acfe6 100644
--- a/tools/xl/xl_vmcontrol.c
+++ b/tools/xl/xl_vmcontrol.c
@@ -899,6 +899,8 @@ start:
         autoconnect_console_how = 0;
     }
 
+    d_config.c_info.domid = domid_policy;
+
     if ( restoring ) {
         libxl_domain_restore_params params;
 
-- 
2.20.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Xen-devel] [PATCH v6 6/6] xl: allow domid to be preserved on save/restore or migrate
  2020-02-19  9:37 [Xen-devel] [PATCH v6 0/6] xl/libxl: domid allocation/preservation changes Paul Durrant
                   ` (4 preceding siblings ...)
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 5/6] xl.conf: introduce 'domid_policy' Paul Durrant
@ 2020-02-19  9:37 ` Paul Durrant
  5 siblings, 0 replies; 15+ messages in thread
From: Paul Durrant @ 2020-02-19  9:37 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Paul Durrant, Ian Jackson, Wei Liu

This patch adds a '-D' command line option to save and migrate to allow
the domain id to be incorporated into the saved domain configuration and
hence be preserved.

NOTE: Logically it may seem as though preservation of domid should be
      dealt with by libxl, but the libxl migration stream has no record
      in which to transfer domid and remote domain creation occurs before
      the migration stream is parsed. Hence this patch modifies xl rather
      then libxl.

Signed-off-by: Paul Durrant <pdurrant@amazon.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
Cc: Wei Liu <wl@xen.org>
Cc: Anthony PERARD <anthony.perard@citrix.com>

v5:
 - Expand the commit comment to say why it is xl being patched rather
   than libxl

v2:
 - Heavily re-worked based on new libxl_domain_create_info
---
 docs/man/xl.1.pod.in      | 14 ++++++++++++++
 tools/xl/xl.h             |  1 +
 tools/xl/xl_cmdtable.c    |  6 ++++--
 tools/xl/xl_migrate.c     | 15 ++++++++++-----
 tools/xl/xl_saverestore.c | 19 ++++++++++++++-----
 tools/xl/xl_vmcontrol.c   |  3 ++-
 6 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index 33ad2ebd71..09339282e6 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -490,6 +490,13 @@ Display huge (!) amount of debug information during the migration process.
 
 Leave the domain on the receive side paused after migration.
 
+=item B<-D>
+
+Preserve the B<domain-id> in the domain coniguration that is transferred
+such that it will be identical on the destination host, unless that
+configuration is overridden using the B<-C> option. Note that it is not
+possible to use this option for a 'localhost' migration.
+
 =back
 
 =item B<remus> [I<OPTIONS>] I<domain-id> I<host>
@@ -692,6 +699,13 @@ Leave the domain running after creating the snapshot.
 
 Leave the domain paused after creating the snapshot.
 
+=item B<-D>
+
+Preserve the B<domain-id> in the domain coniguration that is embedded in
+the state file such that it will be identical when the domain is restored,
+unless that configuration is overridden. (See the B<restore> operation
+above).
+
 =back
 
 =item B<sharing> [I<domain-id>]
diff --git a/tools/xl/xl.h b/tools/xl/xl.h
index 2b4709efb2..06569c6c4a 100644
--- a/tools/xl/xl.h
+++ b/tools/xl/xl.h
@@ -99,6 +99,7 @@ struct save_file_header {
 #define SAVEFILE_BYTEORDER_VALUE ((uint32_t)0x01020304UL)
 
 void save_domain_core_begin(uint32_t domid,
+                            int preserve_domid,
                             const char *override_config_file,
                             uint8_t **config_data_r,
                             int *config_len_r);
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 3b302b2f20..08335394e5 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -153,7 +153,8 @@ struct cmd_spec cmd_table[] = {
       "[options] <Domain> <CheckpointFile> [<ConfigFile>]",
       "-h  Print this help.\n"
       "-c  Leave domain running after creating the snapshot.\n"
-      "-p  Leave domain paused after creating the snapshot."
+      "-p  Leave domain paused after creating the snapshot.\n"
+      "-D  Store the domain id in the configration."
     },
     { "migrate",
       &main_migrate, 0, 1,
@@ -167,7 +168,8 @@ struct cmd_spec cmd_table[] = {
       "-e              Do not wait in the background (on <host>) for the death\n"
       "                of the domain.\n"
       "--debug         Print huge (!) amount of debug during the migration process.\n"
-      "-p              Do not unpause domain after migrating it."
+      "-p              Do not unpause domain after migrating it.\n"
+      "-D              Preserve the domain id"
     },
     { "restore",
       &main_restore, 0, 1,
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 22f0429b84..0813beb801 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -176,7 +176,8 @@ static void migrate_do_preamble(int send_fd, int recv_fd, pid_t child,
 
 }
 
-static void migrate_domain(uint32_t domid, const char *rune, int debug,
+static void migrate_domain(uint32_t domid, int preserve_domid,
+                           const char *rune, int debug,
                            const char *override_config_file)
 {
     pid_t child = -1;
@@ -187,7 +188,7 @@ static void migrate_domain(uint32_t domid, const char *rune, int debug,
     uint8_t *config_data;
     int config_len, flags = LIBXL_SUSPEND_LIVE;
 
-    save_domain_core_begin(domid, override_config_file,
+    save_domain_core_begin(domid, preserve_domid, override_config_file,
                            &config_data, &config_len);
 
     if (!config_len) {
@@ -537,13 +538,14 @@ int main_migrate(int argc, char **argv)
     char *rune = NULL;
     char *host;
     int opt, daemonize = 1, monitor = 1, debug = 0, pause_after_migration = 0;
+    int preserve_domid = 0;
     static struct option opts[] = {
         {"debug", 0, 0, 0x100},
         {"live", 0, 0, 0x200},
         COMMON_LONG_OPTS
     };
 
-    SWITCH_FOREACH_OPT(opt, "FC:s:ep", opts, "migrate", 2) {
+    SWITCH_FOREACH_OPT(opt, "FC:s:epD", opts, "migrate", 2) {
     case 'C':
         config_filename = optarg;
         break;
@@ -560,6 +562,9 @@ int main_migrate(int argc, char **argv)
     case 'p':
         pause_after_migration = 1;
         break;
+    case 'D':
+        preserve_domid = 1;
+        break;
     case 0x100: /* --debug */
         debug = 1;
         break;
@@ -596,7 +601,7 @@ int main_migrate(int argc, char **argv)
                   pause_after_migration ? " -p" : "");
     }
 
-    migrate_domain(domid, rune, debug, config_filename);
+    migrate_domain(domid, preserve_domid, rune, debug, config_filename);
     return EXIT_SUCCESS;
 }
 
@@ -716,7 +721,7 @@ int main_remus(int argc, char **argv)
             }
         }
 
-        save_domain_core_begin(domid, NULL, &config_data, &config_len);
+        save_domain_core_begin(domid, 0, NULL, &config_data, &config_len);
 
         if (!config_len) {
             fprintf(stderr, "No config file stored for running domain and "
diff --git a/tools/xl/xl_saverestore.c b/tools/xl/xl_saverestore.c
index 9be033fe65..953d791d1a 100644
--- a/tools/xl/xl_saverestore.c
+++ b/tools/xl/xl_saverestore.c
@@ -32,6 +32,7 @@
 #ifndef LIBXL_HAVE_NO_SUSPEND_RESUME
 
 void save_domain_core_begin(uint32_t domid,
+                            int preserve_domid,
                             const char *override_config_file,
                             uint8_t **config_data_r,
                             int *config_len_r)
@@ -62,6 +63,8 @@ void save_domain_core_begin(uint32_t domid,
             fprintf(stderr, "unable to retrieve domain configuration\n");
             exit(EXIT_FAILURE);
         }
+
+        d_config.c_info.domid = preserve_domid ? domid : 0;
     }
 
     config_c = libxl_domain_config_to_json(ctx, &d_config);
@@ -120,14 +123,15 @@ void save_domain_core_writeconfig(int fd, const char *source,
             hdr.optional_data_len);
 }
 
-static int save_domain(uint32_t domid, const char *filename, int checkpoint,
-                            int leavepaused, const char *override_config_file)
+static int save_domain(uint32_t domid, int preserve_domid,
+                       const char *filename, int checkpoint,
+                       int leavepaused, const char *override_config_file)
 {
     int fd;
     uint8_t *config_data;
     int config_len;
 
-    save_domain_core_begin(domid, override_config_file,
+    save_domain_core_begin(domid, preserve_domid, override_config_file,
                            &config_data, &config_len);
 
     if (!config_len) {
@@ -236,15 +240,19 @@ int main_save(int argc, char **argv)
     const char *config_filename = NULL;
     int checkpoint = 0;
     int leavepaused = 0;
+    int preserve_domid = 0;
     int opt;
 
-    SWITCH_FOREACH_OPT(opt, "cp", NULL, "save", 2) {
+    SWITCH_FOREACH_OPT(opt, "cpD", NULL, "save", 2) {
     case 'c':
         checkpoint = 1;
         break;
     case 'p':
         leavepaused = 1;
         break;
+    case 'D':
+        preserve_domid = 1;
+        break;
     }
 
     if (argc-optind > 3) {
@@ -257,7 +265,8 @@ int main_save(int argc, char **argv)
     if ( argc - optind >= 3 )
         config_filename = argv[optind + 2];
 
-    save_domain(domid, filename, checkpoint, leavepaused, config_filename);
+    save_domain(domid, preserve_domid, filename, checkpoint, leavepaused,
+                config_filename);
     return EXIT_SUCCESS;
 }
 
diff --git a/tools/xl/xl_vmcontrol.c b/tools/xl/xl_vmcontrol.c
index 39292acfe6..2e2d427492 100644
--- a/tools/xl/xl_vmcontrol.c
+++ b/tools/xl/xl_vmcontrol.c
@@ -899,7 +899,8 @@ start:
         autoconnect_console_how = 0;
     }
 
-    d_config.c_info.domid = domid_policy;
+    if (!libxl_domid_valid_guest(d_config.c_info.domid))
+        d_config.c_info.domid = domid_policy;
 
     if ( restoring ) {
         libxl_domain_restore_params params;
-- 
2.20.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids Paul Durrant
@ 2020-02-20 16:19   ` Ian Jackson
  2020-02-20 16:36     ` Durrant, Paul
  0 siblings, 1 reply; 15+ messages in thread
From: Ian Jackson @ 2020-02-20 16:19 UTC (permalink / raw)
  To: Paul Durrant; +Cc: Anthony Perard, xen-devel, Wei Liu

Paul Durrant writes ("[PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids"):
> A domid is considered recent if the domain it represents was destroyed
> less than a specified number of seconds ago. For debugging and/or testing
> purposes 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.
...

Quoting only the parts which are neither specific to the particular
function, nor calls to the functions into which common code has
currently been moved:

> +static int libxl__mark_domid_recent(libxl__gc *gc, uint32_t domid)
> +{
+    long timeout = libxl__get_domid_reuse_timeout();
...
> +    if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
> +        LOGED(ERROR, domid, "failed to get time");
> +        goto out;
> +    }
...
> +        if (ts.tv_sec - sec > timeout)
> +            continue; /* Ignore expired entries */

> +int libxl__is_domid_recent(libxl__gc *gc, uint32_t domid, bool *recent)
> +{
> +    long timeout = libxl__get_domid_reuse_timeout();
...
> +    if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
> +        LOGED(ERROR, domid, "failed to get time");
> +        goto out;
> +    }
...
> +        if (val == domid && ts.tv_sec - sec <= timeout) {

I'm afraid I am still making style comments:

IMO the reuse timeout call and the clock_gettime call should be put in
libxl__open_domid_history; and the time filtering check should be
folded into libxl__read_recent.

In my review of v4 I wrote:

  Do you think this can be combined somehow ?  Possibilities seem to
  include: explicit read_recent_{init,entry,finish} functions; a single
  function with a "per-entry" callback; same but with a macro.  If you
  do that you can also have it have handle the "file does not exist"
  special case.

You've provided the read_recent_entry function but the "init" function
libxl__open_domid_history does too little.  This series seems to be
moving towards what I called read_recent_{init,entry,finish} (which
should probably have the timestamp and FILE* in a struct together) but
it seems to be doing so quite slowly.

In your factored out functions you generally do this:

   int some_function(){
      r = do_the_thing();
      if (r == 0) return 0;

      LOGE(....)
      return ERROR_FAIL;
    }

This structure is not ideal because:

 - It makes it hard to extend this function to do more, later.
   For example, refactoring the clock_gettime call into
   what is now libxl__open_domid_history would involve reorganising
   the function.

 - It encourages vacuous log messages whose content is mainly in the
   function and line number framing:
       +    LOGE(ERROR, "failed");
       +    return ERROR_FAIL;
       +}
   rather than
       if (!*f) {
           LOGE(ERROR, "failed to open recent domid file `%s'", path);
           rc = ERROR_FAIL;
           goto out;
       }
   (and the latter is to be preferred).

 - It is nonstandard.  See ERROR_HANDLING in CODING_STYLE.

> +    ret = fclose(nf);

This should be called `r', not `ret'.  See CODING_STYLE.

Sorry that some of the other code which you are having to edit here
sets a bad example.  (See the apology at the top of CODING_STYLE.)
(Existing uses of `ret' in libxl are sometimes a syscall return value
and sometimes a libxl error code, which is one reason that name is now
deprecated.)

> +static int libxl__replace_domid_history(libxl__gc *gc, char *new)
> +{

For the record: it was not necessary to break this out into its own
function, because there is only one call site, so open-coding it would
not duplicate anything.  On the other hand if you think it is clearer,
I have no objection.

I think the actual behaviour is correct now but I would like to read
it again when it is in the conventional style.

Thanks
Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Xen-devel] [PATCH v6 2/6] libxl: modify libxl__logv() to only log valid domid values
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 2/6] libxl: modify libxl__logv() to only log valid domid values Paul Durrant
@ 2020-02-20 16:20   ` Ian Jackson
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Jackson @ 2020-02-20 16:20 UTC (permalink / raw)
  To: Paul Durrant; +Cc: Anthony Perard, xen-devel, Wei Liu

Paul Durrant writes ("[PATCH v6 2/6] libxl: modify libxl__logv() to only log valid domid values"):
> Some code-paths use values other than INVALID_DOMID to indicate an invalid
> domain id. Specifically, xl will pass a value of 0 when creating/restoring
> a domain. Therefore modify libxl__logv() to use libxl_domid_valid_guest()
> as a validity test.

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Xen-devel] [PATCH v6 3/6] public/xen.h: add a definition for a 'valid domid' mask
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 3/6] public/xen.h: add a definition for a 'valid domid' mask Paul Durrant
@ 2020-02-20 16:22   ` Ian Jackson
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Jackson @ 2020-02-20 16:22 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	Andrew Cooper, George Dunlap, Jan Beulich, xen-devel

Paul Durrant writes ("[PATCH v6 3/6] public/xen.h: add a definition for a 'valid domid' mask"):
> A subsequent patch will modify libxl to allow selection of a random domid
> value when creating domains. Valid values are limited to a width of 15 bits,
> so add an appropriate mask definition to the public header.

This is fine by me but I wonder if hypervisor maintainers would like
more rationale.

In the conversation where I asked you to split this out I wrote:

> >   This is useful for programs which need to [explanation],
> >   including for example, libxl, which is going to want to
> >   randomly generate domids.
> > 
> > Maybe it needs some explanation of why this belongs in the Xen
> > public headers rather than in some header available to libxc,
> > libxl and other tools stuff ?

Your commit message seems to me to explain the former but not the
latter.  I don't know if hypervisor maintainers want the latter.

Anyway,

Reviewed-by: Ian Jackson <ian.jackson@eu.citrix.com>

Thanks,
Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Xen-devel] [PATCH v6 4/6] libxl: allow creation of domains with a specified or random domid
  2020-02-19  9:37 ` [Xen-devel] [PATCH v6 4/6] libxl: allow creation of domains with a specified or random domid Paul Durrant
@ 2020-02-20 16:25   ` Ian Jackson
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Jackson @ 2020-02-20 16:25 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	Andrew Cooper, Jason Andryuk, George Dunlap, Jan Beulich,
	Anthony Perard, xen-devel

Paul Durrant writes ("[PATCH v6 4/6] libxl: allow creation of domains with a specified or random domid"):
> This patch adds a 'domid' field to libxl_domain_create_info and then
> modifies libxl__domain_make() to have Xen use that value if it is valid.
> If the domid value is invalid then Xen will choose the domid, as before,
> unless the value is the new special RANDOM_DOMID value added to the API.
> This value instructs libxl__domain_make() to choose a random domid value
> for Xen to use.
> 
> If Xen determines that a domid specified to or chosen by
> libxl__domain_make() co-incides with an existing domain then the create
> operation will fail. In this case, if RANDOM_DOMID was specified to
> libxl__domain_make() then a new random value will be chosen and the create
> operation will be re-tried, otherwise libxl__domain_make() will fail.
> 
> After Xen has successfully created a new domain, libxl__domain_make() will
> check whether its domid matches any recently used domid values. If it does
> then the domain will be destroyed. If the domid used in creation was
> specified to libxl__domain_make() then it will fail at this point,
> otherwise the create operation will be re-tried with either a new random
> or Xen-selected domid value.

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

Thanks.  The logic seems a lot clearer now.

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids
  2020-02-20 16:19   ` Ian Jackson
@ 2020-02-20 16:36     ` Durrant, Paul
  2020-02-20 16:45       ` Ian Jackson
  0 siblings, 1 reply; 15+ messages in thread
From: Durrant, Paul @ 2020-02-20 16:36 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Anthony Perard, xen-devel, Wei Liu

> -----Original Message-----
> From: Ian Jackson <ian.jackson@citrix.com>
> Sent: 20 February 2020 16:20
> To: Durrant, Paul <pdurrant@amazon.co.uk>
> Cc: xen-devel@lists.xenproject.org; Wei Liu <wl@xen.org>; Anthony Perard
> <anthony.perard@citrix.com>
> Subject: Re: [PATCH v6 1/6] libxl: add infrastructure to track and query
> 'recent' domids
> 
> Paul Durrant writes ("[PATCH v6 1/6] libxl: add infrastructure to track
> and query 'recent' domids"):
> > A domid is considered recent if the domain it represents was destroyed
> > less than a specified number of seconds ago. For debugging and/or
> testing
> > purposes 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.
> ...
> 
> Quoting only the parts which are neither specific to the particular
> function, nor calls to the functions into which common code has
> currently been moved:
> 
> > +static int libxl__mark_domid_recent(libxl__gc *gc, uint32_t domid)
> > +{
> +    long timeout = libxl__get_domid_reuse_timeout();
> ...
> > +    if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
> > +        LOGED(ERROR, domid, "failed to get time");
> > +        goto out;
> > +    }
> ...
> > +        if (ts.tv_sec - sec > timeout)
> > +            continue; /* Ignore expired entries */
> 
> > +int libxl__is_domid_recent(libxl__gc *gc, uint32_t domid, bool *recent)
> > +{
> > +    long timeout = libxl__get_domid_reuse_timeout();
> ...
> > +    if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
> > +        LOGED(ERROR, domid, "failed to get time");
> > +        goto out;
> > +    }
> ...
> > +        if (val == domid && ts.tv_sec - sec <= timeout) {
> 
> I'm afraid I am still making style comments:
> 
> IMO the reuse timeout call and the clock_gettime call should be put in
> libxl__open_domid_history; and the time filtering check should be
> folded into libxl__read_recent.

Ok. I was having a hard time guessing just exactly what you're looking for. I think that makes it a little clearer.

> 
> In my review of v4 I wrote:
> 
>   Do you think this can be combined somehow ?  Possibilities seem to
>   include: explicit read_recent_{init,entry,finish} functions; a single
>   function with a "per-entry" callback; same but with a macro.  If you
>   do that you can also have it have handle the "file does not exist"
>   special case.
> 
> You've provided the read_recent_entry function but the "init" function
> libxl__open_domid_history does too little.  This series seems to be
> moving towards what I called read_recent_{init,entry,finish} (which
> should probably have the timestamp and FILE* in a struct together) but
> it seems to be doing so quite slowly.

Now again I'm not sure *exactly* what you want me to do, but I'll have another guess.

> 
> In your factored out functions you generally do this:
> 
>    int some_function(){
>       r = do_the_thing();
>       if (r == 0) return 0;
> 
>       LOGE(....)
>       return ERROR_FAIL;
>     }
> 
> This structure is not ideal because:
> 
>  - It makes it hard to extend this function to do more, later.
>    For example, refactoring the clock_gettime call into
>    what is now libxl__open_domid_history would involve reorganising
>    the function.

Ok, but it makes the code shorter done the way I have it and I don't really see why any necessary future re-organisation would be such a problem.

> 
>  - It encourages vacuous log messages whose content is mainly in the
>    function and line number framing:
>        +    LOGE(ERROR, "failed");
>        +    return ERROR_FAIL;
>        +}
>    rather than
>        if (!*f) {
>            LOGE(ERROR, "failed to open recent domid file `%s'", path);
>            rc = ERROR_FAIL;
>            goto out;
>        }
>    (and the latter is to be preferred).

But by asking me to put the error handling inside the sub-functions I lost context such as 'path' which was present in the previous structure. I could pass in an argument purely for the benefit of a log function but that seems excessive. I guess I will pull the error logging out again, but that seemed to be against your requirement to de-duplicate code.

> 
>  - It is nonstandard.  See ERROR_HANDLING in CODING_STYLE.
> 
> > +    ret = fclose(nf);
> 
> This should be called `r', not `ret'.  See CODING_STYLE.

Ok, I clearly didn't pick up all the subtleties.

> 
> Sorry that some of the other code which you are having to edit here
> sets a bad example.  (See the apology at the top of CODING_STYLE.)
> (Existing uses of `ret' in libxl are sometimes a syscall return value
> and sometimes a libxl error code, which is one reason that name is now
> deprecated.)
> 
> > +static int libxl__replace_domid_history(libxl__gc *gc, char *new)
> > +{
> 
> For the record: it was not necessary to break this out into its own
> function, because there is only one call site, so open-coding it would
> not duplicate anything.  On the other hand if you think it is clearer,
> I have no objection.
> 
> I think the actual behaviour is correct now but I would like to read
> it again when it is in the conventional style.
> 

I will spin it again shortly.

  Paul

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids
  2020-02-20 16:36     ` Durrant, Paul
@ 2020-02-20 16:45       ` Ian Jackson
  2020-02-20 16:54         ` Durrant, Paul
  0 siblings, 1 reply; 15+ messages in thread
From: Ian Jackson @ 2020-02-20 16:45 UTC (permalink / raw)
  To: Durrant, Paul; +Cc: Anthony Perard, xen-devel, Wei Liu

Durrant, Paul writes ("RE: [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids"):
> [Ian:]
> > IMO the reuse timeout call and the clock_gettime call should be put in
> > libxl__open_domid_history; and the time filtering check should be
> > folded into libxl__read_recent.
> 
> Ok. I was having a hard time guessing just exactly what you're looking for. I think that makes it a little clearer.
...
> > In my review of v4 I wrote:
> > 
> >   Do you think this can be combined somehow ?  Possibilities seem to
> >   include: explicit read_recent_{init,entry,finish} functions; a single
> >   function with a "per-entry" callback; same but with a macro.  If you
> >   do that you can also have it have handle the "file does not exist"
> >   special case.
> > 
> > You've provided the read_recent_entry function but the "init" function
> > libxl__open_domid_history does too little.  This series seems to be
> > moving towards what I called read_recent_{init,entry,finish} (which
> > should probably have the timestamp and FILE* in a struct together) but
> > it seems to be doing so quite slowly.
> 
> Now again I'm not sure *exactly* what you want me to do, but I'll have another guess.

Maybe it would be better for us to try to come to a shared
understanding before you do another respin...

> >  - It encourages vacuous log messages whose content is mainly in the
> >    function and line number framing:
> >        +    LOGE(ERROR, "failed");
> >        +    return ERROR_FAIL;
> >        +}
> >    rather than
> >        if (!*f) {
> >            LOGE(ERROR, "failed to open recent domid file `%s'", path);
> >            rc = ERROR_FAIL;
> >            goto out;
> >        }
> >    (and the latter is to be preferred).
> 
> But by asking me to put the error handling inside the sub-functions I lost context such as 'path' which was present in the previous structure. I could pass in an argument purely for the benefit of a log function but that seems excessive. I guess I will pull the error logging out again, but that seemed to be against your requirement to de-duplicate code.

I think the path needs to be passed into these functions.  This is why
I think the functions need to take a struct* as an argument, for their
shared state (including the path and the other stuff).

Thanks,
Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids
  2020-02-20 16:45       ` Ian Jackson
@ 2020-02-20 16:54         ` Durrant, Paul
  2020-02-20 17:19           ` Ian Jackson
  0 siblings, 1 reply; 15+ messages in thread
From: Durrant, Paul @ 2020-02-20 16:54 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Anthony Perard, xen-devel, Wei Liu

> -----Original Message-----
> From: Ian Jackson <ian.jackson@citrix.com>
> Sent: 20 February 2020 16:46
> To: Durrant, Paul <pdurrant@amazon.co.uk>
> Cc: xen-devel@lists.xenproject.org; Wei Liu <wl@xen.org>; Anthony Perard
> <anthony.perard@citrix.com>
> Subject: RE: [PATCH v6 1/6] libxl: add infrastructure to track and query
> 'recent' domids
> 
> Durrant, Paul writes ("RE: [PATCH v6 1/6] libxl: add infrastructure to
> track and query 'recent' domids"):
> > [Ian:]
> > > IMO the reuse timeout call and the clock_gettime call should be put in
> > > libxl__open_domid_history; and the time filtering check should be
> > > folded into libxl__read_recent.
> >
> > Ok. I was having a hard time guessing just exactly what you're looking
> for. I think that makes it a little clearer.
> ...
> > > In my review of v4 I wrote:
> > >
> > >   Do you think this can be combined somehow ?  Possibilities seem to
> > >   include: explicit read_recent_{init,entry,finish} functions; a
> single
> > >   function with a "per-entry" callback; same but with a macro.  If you
> > >   do that you can also have it have handle the "file does not exist"
> > >   special case.
> > >
> > > You've provided the read_recent_entry function but the "init" function
> > > libxl__open_domid_history does too little.  This series seems to be
> > > moving towards what I called read_recent_{init,entry,finish} (which
> > > should probably have the timestamp and FILE* in a struct together) but
> > > it seems to be doing so quite slowly.
> >
> > Now again I'm not sure *exactly* what you want me to do, but I'll have
> another guess.
> 
> Maybe it would be better for us to try to come to a shared
> understanding before you do another respin...
> 

Not being co-located makes this somewhat tricky; I think it will basically still come down to me writing some code and then you saying whether that's what you meant... unless you can write some (pseudo-)code to illustrate? I think, from what you say below, I might now have a better idea of what you want so let's have one more go-around of me writing the code first :-)

> > >  - It encourages vacuous log messages whose content is mainly in the
> > >    function and line number framing:
> > >        +    LOGE(ERROR, "failed");
> > >        +    return ERROR_FAIL;
> > >        +}
> > >    rather than
> > >        if (!*f) {
> > >            LOGE(ERROR, "failed to open recent domid file `%s'", path);
> > >            rc = ERROR_FAIL;
> > >            goto out;
> > >        }
> > >    (and the latter is to be preferred).
> >
> > But by asking me to put the error handling inside the sub-functions I
> lost context such as 'path' which was present in the previous structure. I
> could pass in an argument purely for the benefit of a log function but
> that seems excessive. I guess I will pull the error logging out again, but
> that seemed to be against your requirement to de-duplicate code.
> 
> I think the path needs to be passed into these functions.  This is why
> I think the functions need to take a struct* as an argument, for their
> shared state (including the path and the other stuff).
> 

Ok, if that's the style you prefer I'll re-structure it that way.

  Paul

> Thanks,
> Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids
  2020-02-20 16:54         ` Durrant, Paul
@ 2020-02-20 17:19           ` Ian Jackson
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Jackson @ 2020-02-20 17:19 UTC (permalink / raw)
  To: Durrant, Paul; +Cc: Anthony Perard, xen-devel, Wei Liu

Durrant, Paul writes ("RE: [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids"):
> Not being co-located makes this somewhat tricky; I think it will basically still come down to me writing some code and then you saying whether that's what you meant... unless you can write some (pseudo-)code to illustrate? I think, from what you say below, I might now have a better idea of what you want so let's have one more go-around of me writing the code first :-)

OK.

> [Ian:]
> > I think the path needs to be passed into these functions.  This is why
> > I think the functions need to take a struct* as an argument, for their
> > shared state (including the path and the other stuff).
> 
> Ok, if that's the style you prefer I'll re-structure it that way.

My bottom line on this aspect of code structure is that I want each
thing to be written only once.

Thanks,
Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2020-02-20 17:20 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-19  9:37 [Xen-devel] [PATCH v6 0/6] xl/libxl: domid allocation/preservation changes Paul Durrant
2020-02-19  9:37 ` [Xen-devel] [PATCH v6 1/6] libxl: add infrastructure to track and query 'recent' domids Paul Durrant
2020-02-20 16:19   ` Ian Jackson
2020-02-20 16:36     ` Durrant, Paul
2020-02-20 16:45       ` Ian Jackson
2020-02-20 16:54         ` Durrant, Paul
2020-02-20 17:19           ` Ian Jackson
2020-02-19  9:37 ` [Xen-devel] [PATCH v6 2/6] libxl: modify libxl__logv() to only log valid domid values Paul Durrant
2020-02-20 16:20   ` Ian Jackson
2020-02-19  9:37 ` [Xen-devel] [PATCH v6 3/6] public/xen.h: add a definition for a 'valid domid' mask Paul Durrant
2020-02-20 16:22   ` Ian Jackson
2020-02-19  9:37 ` [Xen-devel] [PATCH v6 4/6] libxl: allow creation of domains with a specified or random domid Paul Durrant
2020-02-20 16:25   ` Ian Jackson
2020-02-19  9:37 ` [Xen-devel] [PATCH v6 5/6] xl.conf: introduce 'domid_policy' Paul Durrant
2020-02-19  9:37 ` [Xen-devel] [PATCH v6 6/6] xl: allow domid to be preserved on save/restore or migrate Paul Durrant

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.