[Xen-devel] [PATCH] x86/xen/time: fix section mismatch for xen_init_time_ops()

2017-12-23 Thread Nick Desaulniers
The header declares this function as __init but is defined in __ref
section.

Signed-off-by: Nick Desaulniers 
---
 arch/x86/xen/xen-ops.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 75011b8..3b34745 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -72,7 +72,7 @@ u64 xen_clocksource_read(void);
 void xen_setup_cpu_clockevents(void);
 void xen_save_time_memory_area(void);
 void xen_restore_time_memory_area(void);
-void __init xen_init_time_ops(void);
+void __ref xen_init_time_ops(void);
 void __init xen_hvm_init_time_ops(void);
 
 irqreturn_t xen_debug_interrupt(int irq, void *dev_id);
-- 
2.7.4


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

Re: [Xen-devel] 92a0f81d89 ("x86/cpu_entry_area: Move it out of the fixmap"): BUG: kernel hang in boot stage

2017-12-23 Thread Thomas Gleixner
On Sun, 24 Dec 2017, kernel test robot wrote:

> Greetings,
> 
> 0day kernel testing robot got the below dmesg and the first bad commit is
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git WIP.x86/pti
> 
> commit 92a0f81d89571e3e8759366e050ee05cc545ef99
> Author: Thomas Gleixner 
> AuthorDate: Wed Dec 20 18:51:31 2017 +0100
> Commit: Ingo Molnar 
> CommitDate: Fri Dec 22 20:13:05 2017 +0100
> 
> x86/cpu_entry_area: Move it out of the fixmap

Yes, I'm an idiot.

 for (; start < end; start += PMD_SIZE)

which works fine when start + PMD_SIZE does not wrap around to 0 

Fix is on the way to git.

Thanks,

tglx

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

[Xen-devel] 92a0f81d89 ("x86/cpu_entry_area: Move it out of the fixmap"): BUG: kernel hang in boot stage

2017-12-23 Thread kernel test robot
Greetings,

0day kernel testing robot got the below dmesg and the first bad commit is

https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git WIP.x86/pti

commit 92a0f81d89571e3e8759366e050ee05cc545ef99
Author: Thomas Gleixner 
AuthorDate: Wed Dec 20 18:51:31 2017 +0100
Commit: Ingo Molnar 
CommitDate: Fri Dec 22 20:13:05 2017 +0100

x86/cpu_entry_area: Move it out of the fixmap

Put the cpu_entry_area into a separate P4D entry. The fixmap gets too big
and 0-day already hit a case where the fixmap PTEs were cleared by
cleanup_highmap().

Aside of that the fixmap API is a pain as it's all backwards.

Signed-off-by: Thomas Gleixner 
Cc: Andy Lutomirski 
Cc: Borislav Petkov 
Cc: Dave Hansen 
Cc: H. Peter Anvin 
Cc: Josh Poimboeuf 
Cc: Juergen Gross 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Ingo Molnar 

ed1bbc40a0  x86/cpu_entry_area: Move it to a separate unit
92a0f81d89  x86/cpu_entry_area: Move it out of the fixmap
679d0580c1  x86/ldt: Make the LDT mapping RO
3056af3db3  Merge branch 'WIP.x86/pti.base'
+---+++++
|   | ed1bbc40a0 | 92a0f81d89 | 679d0580c1 | 
3056af3db3 |
+---+++++
| boot_successes| 77 | 0  | 0  | 0  
|
| boot_failures | 0  | 26 | 43 | 19 
|
| BUG:kernel_hang_in_boot_stage | 0  | 26 | 43 | 19 
|
+---+++++

[0.00] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
[0.00] BRK [0x07cb7000, 0x07cb7fff] PGTABLE
[0.00] BRK [0x07cb8000, 0x07cb8fff] PGTABLE
[0.00] BRK [0x07cb9000, 0x07cb9fff] PGTABLE
[0.00] BRK [0x07cba000, 0x07cbafff] PGTABLE
BUG: kernel hang in boot stage


  # HH:MM RESULT GOOD 
BAD GOOD_BUT_DIRTY DIRTY_NOT_BAD
git bisect start 858ee49740dd2f7e85f1b45c2af708b6c08f0771 v4.14 --
git bisect good 7fbbd5cbebf118a9e09f5453f686656a167c3d1c  # 23:18  G 11 
00   0  x86/entry/64: Remove the SYSENTER stack canary
git bisect good 4fe2d8b11a370af286287a2661de9d4e6c9a145a  # 23:27  G 11 
00   0  x86/entry: Rename SYSENTER_stack to CPU_ENTRY_AREA_entry_stack
git bisect good dd95f1a4b5ca904c78e6a097091eb21436478abb  # 23:39  G 11 
00   0  x86/mm: Put MMU to hardware ASID translation in one place
git bisect  bad 613e396bc0d4c7604fba23256644e78454c68cf6  # 23:47  B  0 
2   16   0  init: Invoke init_espfix_bsp() from mm_init()
git bisect good ed1bbc40a0d10e0c5c74fe7bdc6298295cf40255  # 23:58  G 11 
00   0  x86/cpu_entry_area: Move it to a separate unit
git bisect  bad 92a0f81d89571e3e8759366e050ee05cc545ef99  # 00:07  B  0
11   36  11  x86/cpu_entry_area: Move it out of the fixmap
# first bad commit: [92a0f81d89571e3e8759366e050ee05cc545ef99] 
x86/cpu_entry_area: Move it out of the fixmap
git bisect good ed1bbc40a0d10e0c5c74fe7bdc6298295cf40255  # 00:19  G 31 
00   0  x86/cpu_entry_area: Move it to a separate unit
# extra tests on HEAD of tip/master
git bisect  bad 3056af3db33464f58e51ddcc9fd5552413e3a6f2  # 00:55  B  0 
5   27   8  Merge branch 'WIP.x86/pti.base'
# extra tests on tree/branch tip/WIP.x86/pti
git bisect  bad 679d0580c1655be350392a66a45cedc9f4c5e139  # 01:14  B  0 
2   42  26  x86/ldt: Make the LDT mapping RO
# extra tests on tree/branch tip/master
git bisect  bad 3056af3db33464f58e51ddcc9fd5552413e3a6f2  # 01:14  B  0
19   33   0  Merge branch 'WIP.x86/pti.base'

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/lkp  Intel Corporation


dmesg-quantal-lkp-hsw01-11:20171224000613:i386-randconfig-a1-201751:4.14.0-00142-g92a0f81:2.gz
Description: application/gzip
#!/bin/bash

kernel=$1

kvm=(
qemu-system-x86_64
-enable-kvm
-cpu kvm64
-kernel $kernel
-m 512
-smp 2
-device e1000,netdev=net0
-netdev user,id=net0
-boot order=nc
-no-reboot
-watchdog i6300esb
-watchdog-action debug
-rtc base=localtime
-serial stdio
-display none
-monitor null
)

append=(
root=/dev/ram0
hung_task_panic=1
debug
apic=debug
sysrq_always_enabled
rcupdate.rcu_cpu_stall_timeout=100
net.ifnames=0

Re: [Xen-devel] Question about PV normalise_pagetable

2017-12-23 Thread Andrew Cooper
On 23/12/17 13:35, Bruno Alvisio wrote:
> Hi all,
> 
> I was understanding the code in tools/libxc/xc_sr_save_x86_pv.c and
> found this comment to the normalise_pagetable:
> 
> /*
> * Normalise a pagetable for the migration stream. Performs pfn->mfn
> * conversions on the ptes.
> */
> static int normalise_pagetable(struct xc_sr_context *ctx, const uint64_t
> *src,
> uint64_t *dst, unsigned long type)
> 
> 
> Looks like the function (as it should) is doing the reverse conversion
> mfn->pfn.
> 
> Wanted to confirm this typo or if I am missing something?

Yup.  This is a typo - well spotted!  (Probably too much copy
during the 3 or 4 times I reworked the callbacks interface.)

I'll see about fixing this in due course.

~Andrew

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

[Xen-devel] [PATCH RFC v3 RESEND 09/12] Migration with Local Disks Mirroring: New stream phase type for libxc streams

2017-12-23 Thread Bruno Alvisio
Adapted libxc restore stream. Defined libxc stream phase types:

0. XC_STREAM_PHASE_DEFAULT: This is the stream phase when no local disks are
being mirrored as part of the domain save or restore (=0)

1. XC_STREAM_PHASE_POST_MIRROR_DISKS: This stream phase transfers the virtual
RAM from source to destination. It happens after disks mirroring is completed.

2. XC_STREAM_PHASE_PRE_MIRROR_DISKS: This stream transfers pfns and parameters
necessary to start the QEMU process in the destination. It happens before the
disks mirroring.

The PRE_MIRROR_DISKS phase stream type skips the stream_complete ops to restore
the domain. The restore is performed by the POST_MIRROR_DISKS phase stream that
is executed later in the restore flow. If no local disks are mirrored the
restore is executed by the DEFAULT phase stream type.

Signed-off-by: Bruno Alvisio 
---
 tools/libxc/xc_sr_common.h|  1 +
 tools/libxc/xc_sr_restore.c   | 51 ++-
 tools/libxc/xc_sr_stream_format.h |  5 
 3 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index a145a15..8cf393f 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -177,6 +177,7 @@ struct xc_sr_context
 xc_interface *xch;
 uint32_t domid;
 int fd;
+int stream_phase;
 
 xc_dominfo_t dominfo;
 
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index 7f74d28..924386c 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -736,7 +736,10 @@ static int restore(struct xc_sr_context *ctx)
 struct xc_sr_record rec;
 int rc, saved_rc = 0, saved_errno = 0;
 
-IPRINTF("Restoring domain");
+if ( ctx->stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+IPRINTF("Restoring domain");
+else
+IPRINTF("Mirroring disks restoring phase");
 
 rc = setup(ctx);
 if ( rc )
@@ -799,11 +802,16 @@ static int restore(struct xc_sr_context *ctx)
  * With Remus, if we reach here, there must be some error on primary,
  * failover from the last checkpoint state.
  */
-rc = ctx->restore.ops.stream_complete(ctx);
-if ( rc )
-goto err;
+if ( ctx->stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+{
+rc = ctx->restore.ops.stream_complete(ctx);
+if ( rc )
+goto err;
 
-IPRINTF("Restore successful");
+IPRINTF("Restore successful");
+} else {
+IPRINTF("Mirroring disks restore phase successful");
+}
 goto done;
 
  err:
@@ -837,6 +845,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 {
 .xch = xch,
 .fd = io_fd,
+.stream_phase = stream_phase
 };
 
 /* GCC 4.4 (of CentOS 6.x vintage) can' t initialise anonymous unions. */
@@ -890,29 +899,27 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 ctx.restore.p2m_size = nr_pfns;
 
 if ( ctx.dominfo.hvm )
-{
 ctx.restore.ops = restore_ops_x86_hvm;
-if ( restore() )
-return -1;
-}
 else
-{
 ctx.restore.ops = restore_ops_x86_pv;
-if ( restore() )
-return -1;
-}
 
-IPRINTF("XenStore: mfn %#"PRIpfn", dom %d, evt %u",
-ctx.restore.xenstore_gfn,
-ctx.restore.xenstore_domid,
-ctx.restore.xenstore_evtchn);
+if ( restore() )
+return -1;
+
+if ( stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+{
+IPRINTF("XenStore: mfn %#"PRIpfn", dom %d, evt %u",
+ctx.restore.xenstore_gfn,
+ctx.restore.xenstore_domid,
+ctx.restore.xenstore_evtchn);
 
-IPRINTF("Console: mfn %#"PRIpfn", dom %d, evt %u",
-ctx.restore.console_gfn,
-ctx.restore.console_domid,
-ctx.restore.console_evtchn);
+IPRINTF("Console: mfn %#"PRIpfn", dom %d, evt %u",
+ctx.restore.console_gfn,
+ctx.restore.console_domid,
+ctx.restore.console_evtchn);
 
-*console_gfn = ctx.restore.console_gfn;
+*console_gfn = ctx.restore.console_gfn;
+}
 *store_mfn = ctx.restore.xenstore_gfn;
 
 return 0;
diff --git a/tools/libxc/xc_sr_stream_format.h 
b/tools/libxc/xc_sr_stream_format.h
index 15ff1c7..c705da4 100644
--- a/tools/libxc/xc_sr_stream_format.h
+++ b/tools/libxc/xc_sr_stream_format.h
@@ -138,6 +138,11 @@ struct xc_sr_rec_hvm_params
 struct xc_sr_rec_hvm_params_entry param[0];
 };
 
+/* LIBXC stream phase types */
+#define XC_STREAM_PHASE_DEFAULT 0
+#define XC_STREAM_PHASE_POST_MIRROR_DISKS 1
+#define XC_STREAM_PHASE_PRE_MIRROR_DISKS 2
+
 #endif
 /*
  * Local variables:
-- 
2.3.2 (Apple Git-55)


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

[Xen-devel] [PATCH RFC v3 RESEND 06/12] Migration with Local Disks Mirroring: Added 'mirror_disks' field to domain_create_state

2017-12-23 Thread Bruno Alvisio
A new field 'mirror_disks' is added to the libxl struct
libxl__domain_create_state to record if QEMU drives should be mirrored during
migration. This variable is used to setup the sequence of calls and streams in
libxl and libxc.

Signed-off-by: Bruno Alvisio 
---
 tools/libxl/libxl.h  | 4 ++--
 tools/libxl/libxl_create.c   | 8 +---
 tools/libxl/libxl_internal.h | 1 +
 tools/ocaml/libs/xl/xenlight_stubs.c | 2 +-
 tools/xl/xl_vmcontrol.c  | 5 +++--
 5 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 7828ba8..25245cc 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1371,7 +1371,7 @@ int libxl_domain_create_new(libxl_ctx *ctx, 
libxl_domain_config *d_config,
 LIBXL_EXTERNAL_CALLERS_ONLY;
 int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config,
 uint32_t *domid, int restore_fd,
-int send_back_fd,
+int send_back_fd, int mirror_disks,
 const libxl_domain_restore_params *params,
 const libxl_asyncop_how *ao_how,
 const libxl_asyncprogress_how *aop_console_how)
@@ -1412,7 +1412,7 @@ static inline int libxl_domain_create_restore_0x040400(
 LIBXL_EXTERNAL_CALLERS_ONLY
 {
 return libxl_domain_create_restore(ctx, d_config, domid, restore_fd,
-   -1, params, ao_how, aop_console_how);
+   -1, 0, params, ao_how, aop_console_how);
 }
 
 #define libxl_domain_create_restore libxl_domain_create_restore_0x040400
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index f15fb21..95978a8 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1639,6 +1639,7 @@ static void domain_create_cb(libxl__egc *egc,
 
 static int do_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config,
 uint32_t *domid, int restore_fd, int send_back_fd,
+int mirror_disks,
 const libxl_domain_restore_params *params,
 const libxl_asyncop_how *ao_how,
 const libxl_asyncprogress_how *aop_console_how)
@@ -1654,6 +1655,7 @@ static int do_domain_create(libxl_ctx *ctx, 
libxl_domain_config *d_config,
 libxl_domain_config_copy(ctx, >dcs.guest_config_saved, d_config);
 cdcs->dcs.restore_fd = cdcs->dcs.libxc_fd = restore_fd;
 cdcs->dcs.send_back_fd = send_back_fd;
+cdcs->dcs.mirror_disks = mirror_disks;
 if (restore_fd > -1) {
 cdcs->dcs.restore_params = *params;
 rc = libxl__fd_flags_modify_save(gc, cdcs->dcs.restore_fd,
@@ -1881,13 +1883,13 @@ int libxl_domain_create_new(libxl_ctx *ctx, 
libxl_domain_config *d_config,
 const libxl_asyncprogress_how *aop_console_how)
 {
 unset_disk_colo_restore(d_config);
-return do_domain_create(ctx, d_config, domid, -1, -1, NULL,
+return do_domain_create(ctx, d_config, domid, -1, -1, 0, NULL,
 ao_how, aop_console_how);
 }
 
 int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config,
 uint32_t *domid, int restore_fd,
-int send_back_fd,
+int send_back_fd, int mirror_disks,
 const libxl_domain_restore_params *params,
 const libxl_asyncop_how *ao_how,
 const libxl_asyncprogress_how *aop_console_how)
@@ -1899,7 +1901,7 @@ int libxl_domain_create_restore(libxl_ctx *ctx, 
libxl_domain_config *d_config,
 }
 
 return do_domain_create(ctx, d_config, domid, restore_fd, send_back_fd,
-params, ao_how, aop_console_how);
+mirror_disks, params, ao_how, aop_console_how);
 }
 
 int libxl_domain_soft_reset(libxl_ctx *ctx,
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index e8a4dc2..ee62bfb 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3757,6 +3757,7 @@ struct libxl__domain_create_state {
 int restore_fd, libxc_fd;
 int restore_fdfl; /* original flags of restore_fd */
 int send_back_fd;
+int mirror_disks;
 libxl_domain_restore_params restore_params;
 uint32_t domid_soft_reset;
 libxl__domain_create_cb *callback;
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c 
b/tools/ocaml/libs/xl/xenlight_stubs.c
index a757782..900d7f1 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -538,7 +538,7 @@ value stub_libxl_domain_create_restore(value ctx, value 
domain_config, value par
 

[Xen-devel] [PATCH RFC v3 RESEND 02/12] Migration with Local Disks Mirroring: Added QMP commands used for mirroring disks

2017-12-23 Thread Bruno Alvisio
Migration with local disks mirroring uses the embedded NBD server in QEMU. A NBD
server is added in libxl during instance creation time in the destination (QMP
command: nbd_server_add). The drive mirror command (QMP: driver_mirror) is
executed on the source during 'instance save' to replicate the disk in the
destination. When the local disk migration option is used, the QEMU process in
the destination will be started with the "-incoming defer" option instead of
"-incoming fd". Once the disk and memory have been transferred to the
destination the QEMU process will be resumed using the migrate incoming command
(QMP command: migrate_incoming).

Signed-off-by: Bruno Alvisio 
---
 tools/libxl/libxl_internal.h |  11 
 tools/libxl/libxl_qmp.c  | 139 +++
 2 files changed, 150 insertions(+)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index bfa95d8..4d7679e 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1830,6 +1830,17 @@ _hidden int libxl__qmp_nbd_server_add(libxl__gc *gc, int 
domid,
 /* Start replication */
 _hidden int libxl__qmp_start_replication(libxl__gc *gc, int domid,
  bool primary);
+/* Mirror drive */
+_hidden int libxl__qmp_drive_mirror(libxl__gc *gc, int domid,
+const char* device, const char* target,
+const char* format);
+/* Query block devices */
+_hidden int libxl__qmp_query_block(libxl__gc *gc, int domid,
+   char *device_names);
+/* Resume QEMU process started with -incoming defer option */
+_hidden int libxl__qmp_migrate_incoming(libxl__gc *gc, int domid,
+const char* uri);
+
 /* Get replication error that occurs when the vm is running */
 _hidden int libxl__qmp_query_xen_replication_status(libxl__gc *gc, int domid);
 /* Do checkpoint */
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 0e993af..1a1a318 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -1159,6 +1159,145 @@ int libxl__qmp_stop_replication(libxl__gc *gc, int 
domid, bool primary)
 return qmp_run_command(gc, domid, "xen-set-replication", args, NULL, NULL);
 }
 
+static int block_job_ready_handler(libxl__qmp_handler *qmp,
+   const libxl__json_object *data,
+   void *opaque)
+{
+GC_INIT(qmp->ctx);
+int rc = -1;
+
+const char *type;
+const char *device;
+unsigned int len;
+unsigned int offset;
+unsigned int speed;
+
+const libxl__json_object *obj = NULL;
+
+obj = libxl__json_map_get("type", data, JSON_STRING);
+if (!obj) {
+LOGD(ERROR, qmp->domid, "Failed to retrieve job type.");
+rc = ERROR_FAIL;
+goto out;
+}
+type = libxl__json_object_get_string(obj);
+
+obj = libxl__json_map_get("device", data, JSON_STRING);
+if (!obj) {
+LOGD(ERROR, qmp->domid, "Failed to retrieve device.");
+rc = ERROR_FAIL;
+goto out;
+}
+device = libxl__json_object_get_string(obj);
+
+obj = libxl__json_map_get("len", data, JSON_INTEGER);
+if (!obj) {
+LOGD(ERROR, qmp->domid, "Failed to retrieve length.");
+rc = ERROR_FAIL;
+goto out;
+}
+len = libxl__json_object_get_integer(obj);
+
+obj = libxl__json_map_get("offset", data, JSON_INTEGER);
+if (!obj) {
+LOGD(ERROR, qmp->domid, "Failed to retrieve offset.");
+rc = ERROR_FAIL;
+goto out;
+}
+offset = libxl__json_object_get_integer(obj);
+
+obj = libxl__json_map_get("speed", data, JSON_INTEGER);
+if (!obj) {
+LOGD(ERROR, qmp->domid, "Failed to retrieve speed.");
+rc = ERROR_FAIL;
+goto out;
+}
+speed = libxl__json_object_get_integer(obj);
+
+LOGD(INFO, qmp->domid, "Block Job Ready: Details: Device: %s, Type: %s, "
+   "Len: %u, Offset: %u, Speed %u.", device, type,
+   len, offset, speed);
+
+rc = 0;
+out:
+GC_FREE;
+return rc;
+}
+
+int libxl__qmp_drive_mirror(libxl__gc *gc, int domid, const char* device,
+const char* target, const char* format)
+{
+libxl__qmp_handler *qmp = NULL;
+libxl__json_object *args = NULL;
+int block_job_timeout = 3600;
+int rc = 0;
+
+qmp = libxl__qmp_initialize(gc, domid);
+if (!qmp)
+return -1;
+
+qmp_parameters_add_string(gc, , "device", device);
+qmp_parameters_add_string(gc, , "target", target);
+qmp_parameters_add_string(gc, , "sync", "full");
+qmp_parameters_add_string(gc, , "format", format);
+qmp_parameters_add_string(gc, , "mode", "existing");
+qmp_parameters_add_integer(gc, , "granularity", 0);
+qmp_parameters_add_integer(gc, , "buf-size", 0);
+
+rc = 

[Xen-devel] [PATCH RFC v3 RESEND 10/12] Migration with Local Disks Mirroring: libxl save flow support

2017-12-23 Thread Bruno Alvisio
The domain save state contains a new 'mirror_disks' field. It determines the
flow of the domain save. If false, the save flow will invoke the DEFAULT phase
libxl/libxc stream type. If true, the save flow invokes the PRE_MIRROR_DISKS
phase stream type first. Upon reception of the signal from the source that the
NBD server has been started it triggers the disks mirroring job. Once it
receives an event from QEMU that the mirroring job is complete, the
POST_MIRROR_DISKS phase stream type is invoked.

Signed-off-by: Bruno Alvisio 
---
 tools/libxl/libxl_dom_save.c | 53 ++--
 tools/libxl/libxl_domain.c   |  2 ++
 tools/libxl/libxl_internal.h |  4 
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/tools/libxl/libxl_dom_save.c b/tools/libxl/libxl_dom_save.c
index 6487672..78c4e86 100644
--- a/tools/libxl/libxl_dom_save.c
+++ b/tools/libxl/libxl_dom_save.c
@@ -25,6 +25,9 @@ static void stream_done(libxl__egc *egc,
 libxl__stream_write_state *sws, int rc);
 static void domain_save_done(libxl__egc *egc,
  libxl__domain_save_state *dss, int rc);
+static void domain_pre_mirror_disks_done(libxl__egc *egc,
+ libxl__stream_write_state *sws,
+ int rc);
 
 /*- complicated callback, called by xc_domain_save -*/
 
@@ -411,14 +414,60 @@ void libxl__domain_save(libxl__egc *egc, 
libxl__domain_save_state *dss)
 dss->sws.fd  = dss->fd;
 dss->sws.back_channel = false;
 dss->sws.completion_callback = stream_done;
-
-libxl__stream_write_start(egc, >sws);
+dss->sws.mirror_disks = 0;
+
+if (!dss->mirror_disks) {
+libxl__stream_write_start(egc, >sws);
+} else {
+dss->sws_mirror_disks.ao  = dss->ao;
+dss->sws_mirror_disks.dss = dss;
+dss->sws_mirror_disks.fd  = dss->fd;
+dss->sws_mirror_disks.back_channel = false;
+dss->sws_mirror_disks.mirror_disks = 1;
+dss->sws_mirror_disks.completion_callback = 
domain_pre_mirror_disks_done;
+
+libxl__stream_write_start(egc, >sws_mirror_disks);
+}
 return;
 
  out:
 domain_save_done(egc, dss, rc);
 }
 
+static void domain_pre_mirror_disks_done(libxl__egc *egc,
+ libxl__stream_write_state *sws,
+ int rc)
+{
+libxl__domain_save_state *dss = sws->dss;
+STATE_AO_GC(dss->ao);
+const uint32_t domid = dss->domid;
+char* target;
+
+if (rc)
+goto err;
+
+rc = libxl_read_fixedmessage(CTX, dss->recv_fd, nbd_server_started_banner,
+ sizeof(nbd_server_started_banner)-1,
+ "migration stream", 0);
+if (rc)
+goto err;
+
+target = GCSPRINTF("nbd:%s:%s:exportname=%s", dss->hostname,
+   DRIVE_MIRROR_PORT, DRIVE_MIRROR_DEVICE);
+rc = libxl__qmp_drive_mirror(gc, dss->domid, DRIVE_MIRROR_DEVICE, target,
+ "raw");
+if (rc) {
+LOGD(ERROR, domid, "Sending QMP drive mirror command failed");
+goto err;
+}
+
+libxl__stream_write_start(egc, >dss->sws);
+return;
+
+ err:
+   dss->callback(egc, dss, rc);
+}
+
 static void stream_done(libxl__egc *egc,
 libxl__stream_write_state *sws, int rc)
 {
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index d1209cd..341ed52 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -511,6 +511,8 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, 
int fd, int recv_fd,
 dss->type = type;
 dss->live = flags & LIBXL_SUSPEND_LIVE;
 dss->debug = flags & LIBXL_SUSPEND_DEBUG;
+dss->mirror_disks = (flags & LIBXL_SUSPEND_MIRROR_DISKS) ? 1 : 0;
+dss->hostname = hostname;
 dss->checkpointed_stream = LIBXL_CHECKPOINTED_STREAM_NONE;
 
 rc = libxl__fd_flags_modify_save(gc, dss->fd,
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 76bbe48..0a3215f 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3197,6 +3197,7 @@ struct libxl__stream_write_state {
 libxl__domain_save_state *dss;
 int fd;
 bool back_channel;
+int mirror_disks;
 void (*completion_callback)(libxl__egc *egc,
 libxl__stream_write_state *sws,
 int rc);
@@ -3296,6 +3297,8 @@ struct libxl__domain_save_state {
 libxl_domain_type type;
 int live;
 int debug;
+int mirror_disks;
+const char* hostname;
 int checkpointed_stream;
 const libxl_domain_remus_info *remus;
 /* private */
@@ -3311,6 +3314,7 @@ struct libxl__domain_save_state {
 };
 libxl__checkpoint_devices_state cds;
 libxl__stream_write_state sws;
+libxl__stream_write_state sws_mirror_disks;
 

[Xen-devel] [PATCH RFC v3 RESEND 03/12] Migration with Local Disks Mirroring: Refactored migrate_read_fixedmessage

2017-12-23 Thread Bruno Alvisio
The function migrate_fixed_message is going to be used in the libxl create and
save flow for event synchronization during migration. It needs to be accessible
from libxl_create and libxl_dom_save and thus it is moved to libxl_utils.

Signed-off-by: Bruno Alvisio 
---
 tools/libxl/libxl_utils.c | 21 +++
 tools/libxl/libxl_utils.h |  3 +++
 tools/xl/xl_migrate.c | 52 +++
 3 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 507ee56..5139320 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -510,6 +510,27 @@ int libxl__read_sysfs_file_contents(libxl__gc *gc, const 
char *filename,
 READ_WRITE_EXACTLY(read, 1, /* */)
 READ_WRITE_EXACTLY(write, 0, const)
 
+int libxl_read_fixedmessage(libxl_ctx *ctx, int fd, const void *msg, int msgsz,
+const char *what, const char *rune)
+{
+char buf[msgsz];
+const char *stream;
+int rc;
+
+stream = rune ? "migration receiver stream" : "migration stream";
+rc = libxl_read_exactly(ctx, fd, buf, msgsz, stream, what);
+if (rc) return 1;
+
+if (memcmp(buf, msg, msgsz)) {
+fprintf(stderr, "%s contained unexpected data instead of %s\n",
+stream, what);
+if (rune)
+fprintf(stderr, "(command run was: %s )\n", rune);
+return 1;
+}
+return 0;
+}
+
 int libxl__remove_file(libxl__gc *gc, const char *path)
 {
 for (;;) {
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 9e743dc..d1e80ef 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -56,6 +56,9 @@ int libxl_write_exactly(libxl_ctx *ctx, int fd, const void 
*data,
* logged using filename (which is only used for logging) and what
* (which may be 0). */
 
+int libxl_read_fixedmessage(libxl_ctx *ctx, int fd, const void *msg, int msgsz,
+const char *what, const char *rune);
+
 int libxl_pipe(libxl_ctx *ctx, int pipes[2]);
   /* Just like pipe(2), but log errors. */
 
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 1f0e87d..33d39e8 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -68,26 +68,6 @@ static pid_t create_migration_child(const char *rune, int 
*send_fd,
 return child;
 }
 
-static int migrate_read_fixedmessage(int fd, const void *msg, int msgsz,
- const char *what, const char *rune) {
-char buf[msgsz];
-const char *stream;
-int rc;
-
-stream = rune ? "migration receiver stream" : "migration stream";
-rc = libxl_read_exactly(ctx, fd, buf, msgsz, stream, what);
-if (rc) return 1;
-
-if (memcmp(buf, msg, msgsz)) {
-fprintf(stderr, "%s contained unexpected data instead of %s\n",
-stream, what);
-if (rune)
-fprintf(stderr, "(command run was: %s )\n", rune);
-return 1;
-}
-return 0;
-}
-
 static void migration_child_report(int recv_fd) {
 pid_t child;
 int status, sr;
@@ -162,9 +142,9 @@ static void migrate_do_preamble(int send_fd, int recv_fd, 
pid_t child,
 exit(EXIT_FAILURE);
 }
 
-rc = migrate_read_fixedmessage(recv_fd, migrate_receiver_banner,
-   sizeof(migrate_receiver_banner)-1,
-   "banner", rune);
+rc = libxl_read_fixedmessage(ctx, recv_fd, migrate_receiver_banner,
+ sizeof(migrate_receiver_banner)-1,
+ "banner", rune);
 if (rc) {
 close(send_fd);
 migration_child_report(recv_fd);
@@ -219,9 +199,9 @@ static void migrate_domain(uint32_t domid, const char 
*rune, int debug,
 // Should only be printed when debugging as it's a bit messy with
 // progress indication.
 
-rc = migrate_read_fixedmessage(recv_fd, migrate_receiver_ready,
-   sizeof(migrate_receiver_ready),
-   "ready message", rune);
+rc = libxl_read_fixedmessage(ctx, recv_fd, migrate_receiver_ready,
+ sizeof(migrate_receiver_ready),
+ "ready message", rune);
 if (rc) goto failed_resume;
 
 xtl_stdiostream_adjust_flags(logger, 0, XTL_STDIOSTREAM_HIDE_PROGRESS);
@@ -251,9 +231,9 @@ static void migrate_domain(uint32_t domid, const char 
*rune, int debug,
  "migration stream", "GO message");
 if (rc) goto failed_badly;
 
-rc = migrate_read_fixedmessage(recv_fd, migrate_report,
-   sizeof(migrate_report),
-   "success/failure report message", rune);
+rc = libxl_read_fixedmessage(ctx, recv_fd, migrate_report,
+ sizeof(migrate_report),
+ 

[Xen-devel] [PATCH RFC v3 RESEND 05/12] Migration with Local Disks Mirroring: QEMU process is started with '-incoming defer' option

2017-12-23 Thread Bruno Alvisio
For the migration with local disks mirroring scenario, the QEMU process is
started before the virtual RAM is transferred to the destination node so that
the QEMU embedded NBD server and disks mirroring jobs can be started. After the
virtual RAM and QEMU state are transferred, the QEMU process will be resumed
using the QMP 'migrate-incoming' command.

When qemu-xen is started with '-incoming defer' option the initial state of the
instance will be 'inmigrate'. Thus, when either 'running' or 'inmigrate' are
read from xenstore the spawn detach is carried out.

Signed-off-by: Bruno Alvisio 
---
 tools/libxl/libxl_dm.c   | 20 ++--
 tools/libxl/libxl_internal.h |  1 +
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index a2ea95a..e12e015 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -940,7 +940,7 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
 const libxl_domain_config 
*guest_config,
 char ***args, char ***envs,
 const libxl__domain_build_state *state,
-int *dm_state_fd)
+int *dm_state_fd, int mirror_disks)
 {
 const libxl_domain_create_info *c_info = _config->c_info;
 const libxl_domain_build_info *b_info = _config->b_info;
@@ -1431,6 +1431,12 @@ static int libxl__build_device_model_args_new(libxl__gc 
*gc,
 flexarray_append(dm_args, "-incoming");
 flexarray_append(dm_args, GCSPRINTF("fd:%d",*dm_state_fd));
 }
+
+if (mirror_disks) {
+flexarray_append(dm_args, "-incoming");
+flexarray_append(dm_args, "defer");
+}
+
 for (i = 0; b_info->extra && b_info->extra[i] != NULL; i++)
 flexarray_append(dm_args, b_info->extra[i]);
 
@@ -1728,7 +1734,7 @@ static int libxl__build_device_model_args(libxl__gc *gc,
 const libxl_domain_config 
*guest_config,
 char ***args, char ***envs,
 const libxl__domain_build_state *state,
-int *dm_state_fd)
+int *dm_state_fd, int mirror_disks)
 /* dm_state_fd may be NULL iff caller knows we are using old stubdom
  * and therefore will be passing a filename rather than a fd. */
 {
@@ -1744,7 +1750,8 @@ static int libxl__build_device_model_args(libxl__gc *gc,
 return libxl__build_device_model_args_new(gc, dm,
   guest_domid, guest_config,
   args, envs,
-  state, dm_state_fd);
+  state, dm_state_fd,
+  mirror_disks);
 default:
 LOGED(ERROR, guest_domid, "unknown device model version %d",
   guest_config->b_info.device_model_version);
@@ -1964,7 +1971,7 @@ void libxl__spawn_stub_dm(libxl__egc *egc, 
libxl__stub_dm_spawn_state *sdss)
 
 ret = libxl__build_device_model_args(gc, "stubdom-dm", guest_domid,
  guest_config, , NULL,
- d_state, NULL);
+ d_state, NULL, 0);
 if (ret) {
 ret = ERROR_FAIL;
 goto out;
@@ -2267,7 +2274,8 @@ void libxl__spawn_local_dm(libxl__egc *egc, 
libxl__dm_spawn_state *dmss)
 }
 rc = libxl__build_device_model_args(gc, dm, domid, guest_config,
   , , state,
-  _state_fd);
+  _state_fd,
+  dmss->mirror_disks);
 if (rc)
 goto out;
 
@@ -2397,7 +2405,7 @@ static void device_model_confirm(libxl__egc *egc, 
libxl__spawn_state *spawn,
 if (!xsdata)
 return;
 
-if (strcmp(xsdata, "running"))
+if (strcmp(xsdata, "running") && strcmp(xsdata, "inmigrate"))
 return;
 
 libxl__spawn_initiate_detach(gc, spawn);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 4d7679e..e8a4dc2 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3711,6 +3711,7 @@ struct libxl__dm_spawn_state {
 libxl__spawn_state spawn;
 /* filled in by user, must remain valid: */
 uint32_t guest_domid; /* domain being served */
+int mirror_disks;
 libxl_domain_config *guest_config;
 libxl__domain_build_state *build_state; /* relates to guest_domid */
 libxl__dm_spawn_cb *callback;
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org

[Xen-devel] [PATCH RFC v3 RESEND 04/12] Migration with Local Disks Mirroring: Added a new '-q' flag to xl migrate for disk mirorring

2017-12-23 Thread Bruno Alvisio
When the '-q' flag is provided to the 'xl migrate' command all the block devices
that are local should be mirrored to the destination node. If the flag is not
present migration flow will be equivalent to current migration flow. A new
'mirror_disks' field is added to the xl domain_create struct to indicate that
disks will be mirrored during instance startup. A new LIBXL_SUSPEND_MIRROR_DISK
flag is added to indicate that the block mirror jobs should be performed during
the suspension of the instance. libxl_domain_suspend takes a new 'hostname'
param with the name of the host where the QEMU drives will be mirrored to.
libxl_domain_suspend takes a 'recv_fd' param that is used for receving messages
from destination during migration.

Signed-off-by: Bruno Alvisio 
---
 tools/libxl/libxl.h  |  4 +-
 tools/libxl/libxl_domain.c   |  4 +-
 tools/ocaml/libs/xl/xenlight_stubs.c |  2 +-
 tools/xl/xl.h|  1 +
 tools/xl/xl_cmdtable.c   |  3 +-
 tools/xl/xl_migrate.c| 74 +++-
 tools/xl/xl_saverestore.c|  2 +-
 7 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 5e9aed7..7828ba8 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1444,12 +1444,14 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, 
uint32_t domid,
 libxl_domain_config *d_config)
 LIBXL_EXTERNAL_CALLERS_ONLY;
 
-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int recv_fd,
  int flags, /* LIBXL_SUSPEND_* */
+ const char* hostname,
  const libxl_asyncop_how *ao_how)
  LIBXL_EXTERNAL_CALLERS_ONLY;
 #define LIBXL_SUSPEND_DEBUG 1
 #define LIBXL_SUSPEND_LIVE 2
+#define LIBXL_SUSPEND_MIRROR_DISKS 4
 
 /* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )]
  *   If this parameter is true, use co-operative resume. The guest
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 814f812..d1209cd 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -486,7 +486,8 @@ static void domain_suspend_cb(libxl__egc *egc,
 
 }
 
-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int recv_fd,
+ int flags, const char* hostname,
  const libxl_asyncop_how *ao_how)
 {
 AO_CREATE(ctx, domid, ao_how);
@@ -506,6 +507,7 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, 
int fd, int flags,
 
 dss->domid = domid;
 dss->fd = fd;
+dss->recv_fd = recv_fd;
 dss->type = type;
 dss->live = flags & LIBXL_SUSPEND_LIVE;
 dss->debug = flags & LIBXL_SUSPEND_DEBUG;
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c 
b/tools/ocaml/libs/xl/xenlight_stubs.c
index 0140780..a757782 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -611,7 +611,7 @@ value stub_libxl_domain_suspend(value ctx, value domid, 
value fd, value async, v
libxl_asyncop_how *ao_how = aohow_val(async);
 
caml_enter_blocking_section();
-   ret = libxl_domain_suspend(CTX, c_domid, c_fd, 0, ao_how);
+   ret = libxl_domain_suspend(CTX, c_domid, c_fd, 0, 0, NULL, ao_how);
caml_leave_blocking_section();
 
free(ao_how);
diff --git a/tools/xl/xl.h b/tools/xl/xl.h
index 6b60d1d..fd8e8e6 100644
--- a/tools/xl/xl.h
+++ b/tools/xl/xl.h
@@ -35,6 +35,7 @@ struct domain_create {
 int daemonize;
 int monitor; /* handle guest reboots etc */
 int paused;
+int mirror_disks;
 int dryrun;
 int quiet;
 int vnc;
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 5546cf6..45a0b1a 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -165,7 +165,8 @@ struct cmd_spec cmd_table[] = {
   "-e  Do not wait in the background (on ) 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"
+  "-q  Mirror local disks to destination - Copy all local 
storage devices."
 },
 { "restore",
   _restore, 0, 1,
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 33d39e8..48b0179 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -157,7 +157,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,
-   const char 

[Xen-devel] [PATCH RFC v3 RESEND 11/12] Migration with Local Disks Mirroring: libxl write stream support for stream phase type

2017-12-23 Thread Bruno Alvisio
The libxl stream write receives stream phase type (DEFAULT, PRE_MIRROR_DISKS or
POST_MIRROR_DISKS) and registers the appropiate callback to the
libxl_save_helper. If the stream phase == PRE_MIRROR_DISKS the stream skips
writing the context record since it is written at a later time by the
POST_MIRROR_DISKS libxl stream.

Signed-off-by: Bruno Alvisio 
---
 tools/libxc/include/xenguest.h   |  3 +-
 tools/libxc/xc_nomigrate.c   |  3 +-
 tools/libxc/xc_sr_save.c |  3 +-
 tools/libxl/libxl_internal.h | 12 +--
 tools/libxl/libxl_save_callout.c | 10 --
 tools/libxl/libxl_save_helper.c  |  3 +-
 tools/libxl/libxl_stream_write.c | 67 +---
 7 files changed, 73 insertions(+), 28 deletions(-)

diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index 014dee0..743294b 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -134,7 +134,8 @@ typedef enum {
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom,
uint32_t flags /* XCFLAGS_xxx */,
struct save_callbacks* callbacks, int hvm,
-   xc_migration_stream_t stream_type, int recv_fd);
+   xc_migration_stream_t stream_type, int recv_fd,
+   int stream_phase);
 
 /* callbacks provided by xc_domain_restore */
 struct restore_callbacks {
diff --git a/tools/libxc/xc_nomigrate.c b/tools/libxc/xc_nomigrate.c
index 75fe560..ab2d744 100644
--- a/tools/libxc/xc_nomigrate.c
+++ b/tools/libxc/xc_nomigrate.c
@@ -22,7 +22,8 @@
 
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t flags,
struct save_callbacks* callbacks, int hvm,
-   xc_migration_stream_t stream_type, int recv_fd)
+   xc_migration_stream_t stream_type, int recv_fd,
+   int stream_phase)
 {
 errno = ENOSYS;
 return -1;
diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
index 5a40e58..b7498e3 100644
--- a/tools/libxc/xc_sr_save.c
+++ b/tools/libxc/xc_sr_save.c
@@ -967,7 +967,8 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom,
uint32_t flags, struct save_callbacks* callbacks,
-   int hvm, xc_migration_stream_t stream_type, int recv_fd)
+   int hvm, xc_migration_stream_t stream_type, int recv_fd,
+   int stream_phase)
 {
 struct xc_sr_context ctx =
 {
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 0a3215f..320c97d 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3799,12 +3799,18 @@ _hidden void libxl__domain_save(libxl__egc *egc,
 /* calls libxl__xc_domain_suspend_done when done */
 _hidden void libxl__xc_domain_save(libxl__egc *egc,
libxl__domain_save_state *dss,
-   libxl__save_helper_state *shs);
+   libxl__save_helper_state *shs,
+   int stream_phase);
 /* If rc==0 then retval is the return value from xc_domain_save
  * and errnoval is the errno value it provided.
  * If rc!=0, retval and errnoval are undefined. */
-_hidden void libxl__xc_domain_save_done(libxl__egc*, void *dss_void,
-int rc, int retval, int errnoval);
+_hidden void libxl__xc_domain_save_returned(libxl__egc*, void *dss_void,
+int rc, int retval, int errnoval);
+
+_hidden void libxl__xc_mirror_disks_save_returned(libxl__egc *egc,
+  void *dss_void,
+  int rc, int retval,
+  int errnoval);
 
 /* Used by asynchronous callbacks: ie ones which xc regards as
  * returning a value, but which we want to handle asynchronously.
diff --git a/tools/libxl/libxl_save_callout.c b/tools/libxl/libxl_save_callout.c
index 0ff9a01..090d50b 100644
--- a/tools/libxl/libxl_save_callout.c
+++ b/tools/libxl/libxl_save_callout.c
@@ -86,7 +86,7 @@ void libxl__xc_domain_restore(libxl__egc *egc, 
libxl__domain_create_state *dcs,
 }
 
 void libxl__xc_domain_save(libxl__egc *egc, libxl__domain_save_state *dss,
-   libxl__save_helper_state *shs)
+   libxl__save_helper_state *shs, int stream_phase)
 {
 STATE_AO_GC(dss->ao);
 
@@ -95,13 +95,17 @@ void libxl__xc_domain_save(libxl__egc *egc, 
libxl__domain_save_state *dss,
 
 const unsigned long argnums[] = {
 dss->domid, dss->xcflags, dss->hvm, cbflags,
-dss->checkpointed_stream,
+dss->checkpointed_stream, stream_phase,
 };
 
 shs->ao = ao;
 shs->domid = dss->domid;
 shs->recv_callback = libxl__srm_callout_received_save;
- 

[Xen-devel] [PATCH RFC v3 RESEND 00/12] Migration with Local Disks Mirroring

2017-12-23 Thread Bruno Alvisio
I have worked on a solution to be able to migrate domains that use QEMU as the
backend disk driver. I have adapted the migration flow and piggybacked on the
"drive-mirroring" capability already provided by QEMU.

Overview

1. The "xl migrate" command has an additional "-q" flag. When provided the local
storage of the domain is mirrored to the destination during the migration
process.

2. Internally, the modification consists on adding a new
libxl__stream_read_state struct to the libxl__domain_create_state structure and
libxl__stream_write_state struct to the libxl__domain_save_state struct.

3. Migration flow can now be divided into three phases:
   a. Phase One: Copies the necessary PFNs/params to start a QEMU process on the
  destination. QEMU is started with the "-incoming defer" option.
   b. Phase Two: Disk is mirrored using the QEMU embedded NBD server.
   c. Phase Three: Once the disk is completely mirrored, virtual RAM of the
  domain is live migrated to the destination. This phase most closely 
  resembles to the current migration flow.

4. If the “-q” option is not provided the migration is equivalent to the current
migration flow.

The new migration flow has follows the following major sequence of steps:
1. 1st stream copies the necessary PFNs and params from source to destination
to start the QEMU process in destination.
2. QEMU process is started on the destination with the option "-incoming defer".
(This creates the QEMU process but it doesn’t start running the main loop until
"migrate incoming" command is executed)
3. "drive mirror" QMP command is executed so that the disk is mirrored to the
destination node.
4. An event listener waits for the QMP BLOCK_JOB_READY event sent by QEMU which
signals that the "disk mirror job" is complete.
5. 2nd stream copies the virtual RAM from source to destination. At this point, 
the domain is suspended on source.
6. "migrate incoming" QMP command is executed in the destination node.
7. Domain is restored in destination.

Notes

1. Note that as of now "xen_platform_pci=0" for this feature to work. 
This is necessary so that the block devices are seen by QEMU. Further 
modification should be made for the case "xen_platform_pci=1" if we still 
want to use NBD mirroring capability provided by QEMU.
2. The current branch has still some hardcoded values but they can be easily
removed (I wanted initial feedback first):
a. Port used for disks mirroring ("11000"): Changed by opening a socket and
   sending the port number to the source node.
b. Name of the block devices ("ide0-hd0"): Currently the branch only 
   supports domains with one IDE drive. This constraint can easily be 
   removed by querying QEMU for the block-devices and checking their 
   backends on Xenstore. The name of the block devices to be mirrored 
   would be then sent to the destination node for starting the NBD server.
3.This feature needs a small patch to QEMU-XEN.

Here is a link to the Xen branch in Github:
https://github.com/balvisio/xen/tree/feature/migration_with_local_disks_mirroring

Here is a link to the QEMU-Xen branch in Github:
https://github.com/balvisio/qemu-xen/tree/feature/migration_with_local_disks_mirroring

Any feedback/suggestion is appreciated.

Cheers,

Bruno

Signed-off-by: Bruno Alvisio 


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

[Xen-devel] [PATCH RFC v3 RESEND 07/12] Migration with Local Disks Mirroring: Added new libxl_read_stream and callbacks in restore flow

2017-12-23 Thread Bruno Alvisio
For migration with local disks mirroring a QEMU NBD server is started while
restoring the domain. This server will be responsible for receiving the disks
sent from the source node: The disks transfer will be triggered during the
domain save on the source using the QMP drive-mirror command.

A second libxl_read_stream is created (srs_mirror_disks): During domain restore
the first libxc stream transfers the necessary PFNs and params only so that the
QEMU process and NBD server can be started. After the disk mirroring jobs are
completed the second libxl_read_stream is started and the virtual RAM is
transferred.

In the migration with disks mirroring case:
1. domcreate_devmodel_deferred_started is the callback function for launch_dm

2. domcreate_stream_done is the callback function for the end of 1st
libxl_read_stream

3. domcreate_post_mirror_disks_stream_done is the callback function for the 2nd
libxl_read_stream

The original libxl_create calling sequence:
1. domcreate_bootloader_done
2. libxl/libxc stream
3. domcreate_stream_done
4. domcreate_pre_build
5. domcreate_rebuild_done
6. domcreate_multidev_begin
7. domcreate_launch_dm
8. domcreate_devmodel_started

In the case of migration with local disk mirroring the sequence becomes:

1. domcreate_bootloader_done
2. pre mirror disk libxl/libxc stream: Transfers PFNs/params necessary for
QEMU initilization
3. domcreate_stream_done
4. domcreate_pre_build
5. domcreate_rebuild_done
6. domcreate_multidev_begin
7. domcreate_launch_dm: Starts QEMU with "-incoming defer option"
8. domcreate_devmodel_deferred_started: Starts NBD server for disks mirroring
9. post mirror disks libxl/libxc stream: Transfers all virtual RAM: Similar to
original stream
10. domcreate_post_mirror_disks_steam_done: Resumes QEMU process by
executing QMP "migrate-incoming" command
11. domcreate_devmodel_started

Signed-off-by: Bruno Alvisio 
---
 tools/libxl/libxl.h  |   6 +++
 tools/libxl/libxl_create.c   | 117 +--
 tools/libxl/libxl_internal.h |   2 +
 3 files changed, 120 insertions(+), 5 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 25245cc..af2aa9a 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1453,6 +1453,12 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, 
int fd, int recv_fd,
 #define LIBXL_SUSPEND_LIVE 2
 #define LIBXL_SUSPEND_MIRROR_DISKS 4
 
+#define DRIVE_MIRROR_PORT "11000"
+#define DRIVE_MIRROR_DEVICE "ide0-hd0"
+
+static const char nbd_server_started_banner[]=
+"nbd server started on source, start mirror job.\n";
+
 /* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )]
  *   If this parameter is true, use co-operative resume. The guest
  *   must support this.
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 95978a8..f834282 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -761,6 +761,9 @@ static int store_libxl_entry(libxl__gc *gc, uint32_t domid,
 static void domcreate_devmodel_started(libxl__egc *egc,
libxl__dm_spawn_state *dmss,
int rc);
+static void domcreate_devmodel_deferred_started(libxl__egc *egc,
+libxl__dm_spawn_state *dmss,
+int ret);
 static void domcreate_bootloader_console_available(libxl__egc *egc,
libxl__bootloader_state 
*bl);
 static void domcreate_bootloader_done(libxl__egc *egc,
@@ -777,6 +780,10 @@ static void domcreate_stream_done(libxl__egc *egc,
   libxl__stream_read_state *srs,
   int ret);
 
+static void domcreate_post_mirror_disks_stream_done(libxl__egc *egc,
+libxl__stream_read_state 
*srs,
+int ret);
+
 static void domcreate_rebuild_done(libxl__egc *egc,
libxl__domain_create_state *dcs,
int ret);
@@ -1036,6 +1043,48 @@ static void libxl__colo_restore_setup_done(libxl__egc 
*egc,
 libxl__stream_read_start(egc, >srs);
 }
 
+static void domcreate_devmodel_deferred_started(libxl__egc *egc,
+libxl__dm_spawn_state *dmss,
+int ret)
+{
+libxl__domain_create_state *dcs = CONTAINER_OF(dmss, *dcs, sdss.dm);
+STATE_AO_GC(dmss->spawn.ao);
+const uint32_t domid = dcs->guest_domid;
+dcs->sdss.dm.guest_domid = domid;
+
+if (ret) {
+LOGD(ERROR, domid, "device model did not start: %d", ret);
+goto error_out;
+}
+
+ret = libxl__qmp_nbd_server_start(gc, domid, "::", DRIVE_MIRROR_PORT);
+if (ret) {
+LOGD(ERROR, domid, "Failed to start NBD Server");
+ 

[Xen-devel] [PATCH RFC v3 RESEND 08/12] Migration with Local Disks Mirroring: New stream phase type for libxl streams

2017-12-23 Thread Bruno Alvisio
The libxl streams are classified by a stream phase parameter (stream_phase):

0. DEFAULT: This is the stream phase when no local disks are being mirrored as
part of the domain save or restore flow. (=0)

1. POST_MIRROR_DISKS: This stream phase happens during the migration flow after
the disks have been completely mirrored. In time order, this is the second libxl
stream of the migration flow. (=1)

2. PRE_MIRROR_DISKS: This stream happens before the disks start to be mirrored
to the destination. In time order, this is the first libxl stream of the
migration flow. (=2)

libxl__xc_mirror_disks_restore_returned is the callback function in the
libxl_read_stream that is registered for the return of libxc_mirror_disks
stream.

Signed-off-by: Bruno Alvisio 
---
 tools/libxc/include/xenguest.h   |  3 ++-
 tools/libxc/xc_nomigrate.c   |  3 ++-
 tools/libxc/xc_sr_restore.c  |  3 ++-
 tools/libxl/libxl_colo_restore.c |  4 ++--
 tools/libxl/libxl_internal.h | 12 +++-
 tools/libxl/libxl_save_callout.c | 13 +
 tools/libxl/libxl_save_helper.c  |  5 -
 tools/libxl/libxl_stream_read.c  | 24 ++--
 tools/libxl/libxl_types.idl  |  6 ++
 9 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index b4b2e19..014dee0 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -199,7 +199,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
   unsigned long *console_mfn, uint32_t console_domid,
   unsigned int hvm, unsigned int pae,
   xc_migration_stream_t stream_type,
-  struct restore_callbacks *callbacks, int send_back_fd);
+  struct restore_callbacks *callbacks, int send_back_fd,
+  int stream_phase);
 
 /**
  * This function will create a domain for a paravirtualized Linux
diff --git a/tools/libxc/xc_nomigrate.c b/tools/libxc/xc_nomigrate.c
index 6d6169d..75fe560 100644
--- a/tools/libxc/xc_nomigrate.c
+++ b/tools/libxc/xc_nomigrate.c
@@ -34,7 +34,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t 
dom,
   unsigned long *console_mfn, uint32_t console_domid,
   unsigned int hvm, unsigned int pae,
   xc_migration_stream_t stream_type,
-  struct restore_callbacks *callbacks, int send_back_fd)
+  struct restore_callbacks *callbacks, int send_back_fd,
+  int stream_phase)
 {
 errno = ENOSYS;
 return -1;
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index ea7b033..7f74d28 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -829,7 +829,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
   unsigned long *console_gfn, uint32_t console_domid,
   unsigned int hvm, unsigned int pae,
   xc_migration_stream_t stream_type,
-  struct restore_callbacks *callbacks, int send_back_fd)
+  struct restore_callbacks *callbacks, int send_back_fd,
+  int stream_phase)
 {
 xen_pfn_t nr_pfns;
 struct xc_sr_context ctx =
diff --git a/tools/libxl/libxl_colo_restore.c b/tools/libxl/libxl_colo_restore.c
index 0c535bd..a45bf51 100644
--- a/tools/libxl/libxl_colo_restore.c
+++ b/tools/libxl/libxl_colo_restore.c
@@ -132,7 +132,7 @@ static void colo_resume_vm(libxl__egc *egc,
 return;
 }
 
-libxl__xc_domain_restore_done(egc, dcs, 0, 0, 0);
+libxl__xc_domain_restore_done(egc, dcs, dcs->srs, 0, 0, 0);
 
 return;
 }
@@ -325,7 +325,7 @@ void libxl__colo_restore_teardown(libxl__egc *egc, void 
*dcs_void,
 /* crcs->status is LIBXL_COLO_SETUPED */
 dcs->srs.completion_callback = NULL;
 }
-libxl__xc_domain_restore_done(egc, dcs, ret, retval, errnoval);
+libxl__xc_domain_restore_done(egc, dcs, dcs->srs, ret, retval, errnoval);
 
 if (crs->qdisk_setuped) {
 libxl__qmp_stop_replication(gc, crs->domid, false);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index feb9370..76bbe48 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3825,13 +3825,23 @@ _hidden int libxl__restore_emulator_xenstore_data
 _hidden void libxl__xc_domain_restore(libxl__egc *egc,
   libxl__domain_create_state *dcs,
   libxl__save_helper_state *shs,
-  int hvm, int pae);
+  int hvm, int pae, int stream_phase);
 /* If rc==0 then retval is the return value from xc_domain_save
  * and errnoval is the errno value it provided.
  * If rc!=0, retval and errnoval are undefined. */
 _hidden 

[Xen-devel] [PATCH RFC v3 RESEND 12/12] Migration with Local Disks Mirroring: Introduce pre_mirror_disks_stream_phase op to xc_sr_save_ops

2017-12-23 Thread Bruno Alvisio
A new op pre_mirror_stream_phase is introduced as part of the xc_sr_save_ops.
This op sends all pfns and params that need to be transferred before the disks
mirroring jobs can be started. Note that no new libxc record type is created.

The save flow is modified such that: if the stream_phase ==
XC_PRE_MIRROR_DISKS_STREAM_PHASE only the pre_mirror_disks op is executed as
part of the save(). In all other libxc phase types, the original flow is
executed.

Signed-off-by: Bruno Alvisio 
---
 tools/libxc/xc_sr_common.h   |  11 
 tools/libxc/xc_sr_save.c |  24 +++--
 tools/libxc/xc_sr_save_x86_hvm.c | 109 +++
 3 files changed, 105 insertions(+), 39 deletions(-)

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index 8cf393f..44f4103 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -96,6 +96,13 @@ struct xc_sr_save_ops
  * after a successful save, or upon encountering an error.
  */
 int (*cleanup)(struct xc_sr_context *ctx);
+
+/**
+ * Send the necessary records/params to allow the start of the local
+ * disks mirroring job in the destination node. It will be called exactly
+ * once only if the stream phase type == XC_STREAM_PHASE_PRE_MIRROR_DISKS
+ */
+int (*pre_mirror_disks_stream_phase)(struct xc_sr_context *ctx);
 };
 
 
@@ -398,6 +405,10 @@ int read_record(struct xc_sr_context *ctx, int fd, struct 
xc_sr_record *rec);
 int populate_pfns(struct xc_sr_context *ctx, unsigned count,
   const xen_pfn_t *original_pfns, const uint32_t *types);
 
+int add_to_batch(struct xc_sr_context *ctx, xen_pfn_t pfn);
+
+int flush_batch(struct xc_sr_context *ctx);
+
 #endif
 /*
  * Local variables:
diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
index b7498e3..557dafe 100644
--- a/tools/libxc/xc_sr_save.c
+++ b/tools/libxc/xc_sr_save.c
@@ -279,7 +279,7 @@ static int write_batch(struct xc_sr_context *ctx)
 /*
  * Flush a batch of pfns into the stream.
  */
-static int flush_batch(struct xc_sr_context *ctx)
+int flush_batch(struct xc_sr_context *ctx)
 {
 int rc = 0;
 
@@ -301,7 +301,7 @@ static int flush_batch(struct xc_sr_context *ctx)
 /*
  * Add a single pfn to the batch, flushing the batch if full.
  */
-static int add_to_batch(struct xc_sr_context *ctx, xen_pfn_t pfn)
+int add_to_batch(struct xc_sr_context *ctx, xen_pfn_t pfn)
 {
 int rc = 0;
 
@@ -842,8 +842,12 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 xc_interface *xch = ctx->xch;
 int rc, saved_rc = 0, saved_errno = 0;
 
-IPRINTF("Saving domain %d, type %s",
-ctx->domid, dhdr_type_to_str(guest_type));
+if ( ctx->stream_phase == XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+IPRINTF("Pre-mirroring disks save phase for domain %d, type %s",
+ctx->domid, dhdr_type_to_str(guest_type));
+else
+IPRINTF("Saving domain %d, type %s",
+ctx->domid, dhdr_type_to_str(guest_type));
 
 rc = setup(ctx);
 if ( rc )
@@ -855,6 +859,13 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 if ( rc )
 goto err;
 
+if ( ctx->stream_phase == XC_STREAM_PHASE_PRE_MIRROR_DISKS ) {
+rc = ctx->save.ops.pre_mirror_disks_stream_phase(ctx);
+if ( rc )
+goto err;
+goto end;
+}
+
 rc = ctx->save.ops.start_of_stream(ctx);
 if ( rc )
 goto err;
@@ -939,6 +950,7 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 }
 } while ( ctx->save.checkpointed != XC_MIG_STREAM_NONE );
 
+ end:
 xc_report_progress_single(xch, "End of stream");
 
 rc = write_end_record(ctx);
@@ -974,6 +986,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom,
 {
 .xch = xch,
 .fd = io_fd,
+.stream_phase = stream_phase
 };
 
 /* GCC 4.4 (of CentOS 6.x vintage) can' t initialise anonymous unions. */
@@ -989,7 +1002,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom,
stream_type == XC_MIG_STREAM_COLO);
 
 /* Sanity checks for callbacks. */
-if ( hvm )
+/* The pre mirror disks phase stream doesn't enable/disable qemu log */
+if ( hvm && ctx.stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
 assert(callbacks->switch_qemu_logdirty);
 if ( ctx.save.checkpointed )
 assert(callbacks->checkpoint && callbacks->postcopy);
diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c
index 97a8c49..423edd7 100644
--- a/tools/libxc/xc_sr_save_x86_hvm.c
+++ b/tools/libxc/xc_sr_save_x86_hvm.c
@@ -4,6 +4,32 @@
 
 #include 
 
+static const unsigned int params[] = {
+HVM_PARAM_STORE_PFN,
+HVM_PARAM_IOREQ_PFN,
+HVM_PARAM_BUFIOREQ_PFN,
+HVM_PARAM_PAGING_RING_PFN,
+HVM_PARAM_MONITOR_RING_PFN,
+HVM_PARAM_SHARING_RING_PFN,
+HVM_PARAM_VM86_TSS_SIZED,
+

[Xen-devel] [PATCH RFC v3 RESEND 01/12] Migration with Local Disks Mirroring: Added support in libxl to handle QMP events

2017-12-23 Thread Bruno Alvisio
Migration with Local Disk Mirroring uses the QEMU embedded NBD server. To
migrate the disk, a 'disk mirror job' is started from the source so that the
block devices emulated by QEMU are mirrored to the destination node. Once the
mirroring job is ready, QEMU sends an asynchronous QMP event. This code adds
support to register handlers when QMP events are received.

Signed-off-by: Bruno Alvisio 
---
 tools/libxl/libxl_qmp.c | 58 +
 1 file changed, 58 insertions(+)

diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index eab993a..0e993af 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -59,6 +59,13 @@ typedef struct callback_id_pair {
 LIBXL_STAILQ_ENTRY(struct callback_id_pair) next;
 } callback_id_pair;
 
+typedef struct event_handler_pair {
+const char* event_type;
+void *opaque;
+qmp_request_context *context;
+qmp_callback_t event_handler;
+} event_handler_pair;
+
 struct libxl__qmp_handler {
 struct sockaddr_un addr;
 int qmp_fd;
@@ -66,6 +73,9 @@ struct libxl__qmp_handler {
 time_t timeout;
 /* wait_for_id will be used by the synchronous send function */
 int wait_for_id;
+/* wait_for_event_type is used to wait on QMP events */
+const char* wait_for_event_type;
+event_handler_pair *ehp;
 
 char buffer[QMP_RECEIVE_BUFFER_SIZE + 1];
 libxl__yajl_ctx *yajl_ctx;
@@ -287,6 +297,27 @@ static void qmp_handle_error_response(libxl__gc *gc, 
libxl__qmp_handler *qmp,
  libxl__json_object_get_string(resp));
 }
 
+static void qmp_handle_event(libxl__gc *gc, libxl__qmp_handler *qmp,
+ const libxl__json_object *event)
+{
+const char* event_type = NULL;
+const libxl__json_object *event_o = NULL;
+event_o = libxl__json_map_get("event", event, JSON_ANY);
+event_type = libxl__json_object_get_string(event_o);
+int rc;
+
+if(qmp->wait_for_event_type &&
+!strcmp(event_type, qmp->wait_for_event_type)) {
+if(qmp->ehp->event_handler) {
+rc = qmp->ehp->event_handler(qmp,
+   libxl__json_map_get("data", event, JSON_ANY),
+   qmp->ehp->opaque);
+}
+qmp->ehp->context->rc = rc;
+qmp->wait_for_event_type = NULL;
+}
+}
+
 static int qmp_handle_response(libxl__gc *gc, libxl__qmp_handler *qmp,
const libxl__json_object *resp)
 {
@@ -325,6 +356,7 @@ static int qmp_handle_response(libxl__gc *gc, 
libxl__qmp_handler *qmp,
 qmp_handle_error_response(gc, qmp, resp);
 return -1;
 case LIBXL__QMP_MESSAGE_TYPE_EVENT:
+qmp_handle_event(gc, qmp, resp);
 return 0;
 case LIBXL__QMP_MESSAGE_TYPE_INVALID:
 return -1;
@@ -624,6 +656,32 @@ static void qmp_free_handler(libxl__qmp_handler *qmp)
 free(qmp);
 }
 
+static int __attribute__((unused)) wait_for_event(libxl__qmp_handler *qmp,
+  event_handler_pair *ehp,
+  int timeout)
+{
+int ret = 0;
+GC_INIT(qmp->ctx);
+qmp->timeout = timeout;
+qmp_request_context context = { .rc = 0 };
+qmp->ehp = ehp;
+qmp->wait_for_event_type = ehp->event_type;
+ehp->context = 
+
+while (qmp->wait_for_event_type) {
+if ((ret = qmp_next(gc, qmp)) < 0) {
+break;
+}
+}
+
+if (!qmp->wait_for_event_type && ret == 0)
+ret = context.rc;
+
+GC_FREE;
+
+return ret;
+}
+
 /*
  * QMP Parameters Helpers
  */
-- 
2.3.2 (Apple Git-55)


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

[Xen-devel] Question about PV normalise_pagetable

2017-12-23 Thread Bruno Alvisio
Hi all,

I was understanding the code in tools/libxc/xc_sr_save_x86_pv.c and found
this comment to the normalise_pagetable:

/*
 * Normalise a pagetable for the migration stream.  Performs pfn->mfn
 * conversions on the ptes.
 */
static int normalise_pagetable(struct xc_sr_context *ctx, const uint64_t *src,
   uint64_t *dst, unsigned long type)


Looks like the function (as it should) is doing the reverse conversion mfn->pfn.

Wanted to confirm this typo or if I am missing something?

Thanks,

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

[Xen-devel] [distros-debian-stretch test] 73257: trouble: blocked/broken

2017-12-23 Thread Platform Team regression test user
flight 73257 distros-debian-stretch real [real]
http://osstest.xs.citrite.net/~osstest/testlogs/logs/73257/

Failures and problems with tests :-(

Tests which did not succeed and are blocking,
including tests which could not be run:
 build-armhf-pvopsbroken
 build-i386   broken
 build-amd64-pvopsbroken
 build-armhf  broken
 build-amd64  broken
 build-i386-pvops broken

Tests which did not succeed, but are not blocking:
 test-amd64-i386-amd64-stretch-netboot-pygrub  1 build-check(1) blocked n/a
 test-amd64-amd64-amd64-stretch-netboot-pvgrub  1 build-check(1)blocked n/a
 test-amd64-i386-i386-stretch-netboot-pvgrub  1 build-check(1)  blocked n/a
 test-amd64-amd64-i386-stretch-netboot-pygrub  1 build-check(1) blocked n/a
 test-armhf-armhf-armhf-stretch-netboot-pygrub  1 build-check(1)blocked n/a
 build-armhf-pvops 4 host-install(4)  broken like 72887
 build-armhf   4 host-install(4)  broken like 72887
 build-amd64-pvops 4 host-install(4)  broken like 72887
 build-amd64   4 host-install(4)  broken like 72887
 build-i386-pvops  4 host-install(4)  broken like 72887
 build-i3864 host-install(4)  broken like 72887

baseline version:
 flight   72887

jobs:
 build-amd64  broken  
 build-armhf  broken  
 build-i386   broken  
 build-amd64-pvopsbroken  
 build-armhf-pvopsbroken  
 build-i386-pvops broken  
 test-amd64-amd64-amd64-stretch-netboot-pvgrubblocked 
 test-amd64-i386-i386-stretch-netboot-pvgrub  blocked 
 test-amd64-i386-amd64-stretch-netboot-pygrub blocked 
 test-armhf-armhf-armhf-stretch-netboot-pygrubblocked 
 test-amd64-amd64-i386-stretch-netboot-pygrub blocked 



sg-report-flight on osstest.xs.citrite.net
logs: /home/osstest/logs
images: /home/osstest/images

Logs, config files, etc. are available at
http://osstest.xs.citrite.net/~osstest/testlogs/logs

Test harness code can be found at
http://xenbits.xensource.com/gitweb?p=osstest.git;a=summary


Push not applicable.


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