Re: [libvirt] [PATCH] libxl: fix domxml-to-native wrong output for qcow2 format

2014-06-13 Thread Bamvor Jian Zhang

 Jim Fehlig wrote: 
 Bamvor Jian Zhangbjzh...@suse.com wrote: 
 e.g. for these following disk configuration in libvirt. 
   disk type='file' device='disk' 
  
 For Xen, using driver name='qemu' .../ (which means qdisk) is only 
 supported by the libxl driver. The old xm/xend stack does not support qdisk. 
  
   driver name='qemu' type='qcow2'/ 
   source file='/var/lib/xen/images/001/disk0.qcow2'/ 
   target dev='hdc'/ 
  
 without this patch, it will be 
 qemu:/var/lib/xen/images/001/disk0.qcow2,hdc,w 
  
 Yeah, that won't work with xend or libxl  :) . 
  
 but it should be(if with this patch) 
 qcow2:/var/lib/xen/images/001/disk0.qcow2,hdc,w 
  
 Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com 
 --- 
  src/xenxs/xen_xm.c | 5 - 
  1 file changed, 4 insertions(+), 1 deletion(-) 
  
 diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c 
 index b2db97d..29835b4 100644 
 --- a/src/xenxs/xen_xm.c 
 +++ b/src/xenxs/xen_xm.c 
 @@ -1209,7 +1209,10 @@ xenFormatXMDisk(virConfValuePtr list, 
  type = aio; 
  else 
  type = virStorageFileFormatTypeToString(format); 
 -virBufferAsprintf(buf, %s:, driver); 
 +if (!STREQ(type, qcow2)) 
 +virBufferAsprintf(buf, %s:, driver); 
 +else 
 +virBufferAsprintf(buf, %s:, type); 
  
 But this only handles the specific case of driver name='qemu'  
 type='qcow2'/. 
 With driver name='qemu' type='raw'/, I get 
  
 qemu:/path/to/disk,hdc,w 
  
 Unfortunately, this is a case where we are trying to use the xm config 
 parser to parse something that is xl-specific.  With driver  
 name='qemu'.../, 
 the corresponding xl disk config would look something like 
  
 disk = ['backendtype=qdisk,/var/lib/xen/images/001/disk0.qcow2,hdc,w'] 
  
 With the type also specified, e.g. driver name='qemu' type='qcow2'/, the  
 xl 
 disk config would be 
  
 disk =  
 ['backendtype=qdisk,format=qcow2,/var/lib/xen/images/001/disk0.qcow2,hdc,w'] 
  
 As I see it, the options are 
  
 1. start working on a xen-xl parser 
 2. map 'qemu' to 'tap' 
  
 We'll eventually need 1 anyhow.  I haven't looked to see how much work that 
 would be.  Certainly a lot of the xm parsing code could be used since xm 
 config is a subset of xl config. 
understand. the main difference between xl and xm format is disk and network.
and it worth to do it.
  
 Option 2 is really a no-op in the libxl stack, where qdisk is used in place 
 of tap anyhow.  One could argue that mapping qemu to tap isn't too insane in 
 the xm/xend stack either, since much of the blktap userspace code was 
 originally based on qemu. 
  
 The below patch works for me.  Can you give it a try?  I'd like to hear wha 
 others think about taking the easy way out with option 2. 
the following patch works for me.

regards

bamvor

  
 Regards, 
 Jim 
  
  
 From 92c476cbe47009c43ebb4a3076a17347c8eea238 Mon Sep 17 00:00:00 2001 
 From: Jim Fehlig jfeh...@suse.com 
 Date: Thu, 12 Jun 2014 15:28:48 -0600 
 Subject: [PATCH] libxl: fix domxml-to-native with qemu disk driver 
  
 Disk config containing driver name='qemu'.../ is converted to 
 the native config containg qemu:/path/to/disk, which is not 
 understood by xm or xl. 
  
 This patch maps 'qemu' to 'tap'.  In xl, tap is mapped to the qemu 
 backend (aka qdisk), making this change essentially a no-op.  In 
 the xm stack, one could argue that mapping qemu to tap isn't too 
 insane, since much of the blktap userspace code was originally 
 based on qemu. 
  
 While at it, noticed that 'driver' wasn't being honored in 
 xenFormatXMDisk, so change the logic a bit to honor a 
 user-specified driver. 
  
 Signed-off-by: Jim Fehlig jfeh...@suse.com 
 --- 
  src/xenxs/xen_xm.c | 29 - 
  1 file changed, 20 insertions(+), 9 deletions(-) 
  
 diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c 
 index b2db97d..ebd525b 100644 
 --- a/src/xenxs/xen_xm.c 
 +++ b/src/xenxs/xen_xm.c 
 @@ -1201,17 +1201,28 @@ xenFormatXMDisk(virConfValuePtr list, 
  int format = virDomainDiskGetFormat(disk); 
  const char *driver = virDomainDiskGetDriver(disk); 
   
 -if (src) { 
 -if (format) { 
 -const char *type; 
 +/* 
 + * In pre-libxl Xen, 'tap' provided the qemu driver functionality. 
 + * In libxl Xen, qemu (aka qdisk) is in fact used.  For backwards 
 + * compatibility, tap == qdisk in libxl Xen, so it is safe to use 
 + * 'tap' in libxl tool. 
 + */ 
 +if (STREQ(driver, qemu)) 
 +driver = tap; 
   
 -if (format == VIR_STORAGE_FILE_RAW) 
 -type = aio; 
 -else 
 -type = virStorageFileFormatTypeToString(format); 
 +if (src) { 
 +if (driver) { 
  virBufferAsprintf(buf, %s:, driver); 
 -if (STREQ(driver, tap)) 
 -virBufferAsprintf(buf, %s:, type); 
 +if (format

[libvirt] [PATCH] libxl: fix domxml-to-native wrong output for qcow2 format

2014-06-12 Thread Bamvor Jian Zhang
e.g. for these following disk configuration in libvirt.
  disk type='file' device='disk'
  driver name='qemu' type='qcow2'/
  source file='/var/lib/xen/images/001/disk0.qcow2'/
  target dev='hdc'/

without this patch, it will be
qemu:/var/lib/xen/images/001/disk0.qcow2,hdc,w
but it should be(if with this patch)
qcow2:/var/lib/xen/images/001/disk0.qcow2,hdc,w

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
 src/xenxs/xen_xm.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c
index b2db97d..29835b4 100644
--- a/src/xenxs/xen_xm.c
+++ b/src/xenxs/xen_xm.c
@@ -1209,7 +1209,10 @@ xenFormatXMDisk(virConfValuePtr list,
 type = aio;
 else
 type = virStorageFileFormatTypeToString(format);
-virBufferAsprintf(buf, %s:, driver);
+if (!STREQ(type, qcow2))
+virBufferAsprintf(buf, %s:, driver);
+else
+virBufferAsprintf(buf, %s:, type);
 if (STREQ(driver, tap))
 virBufferAsprintf(buf, %s:, type);
 } else {
-- 
1.8.1.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] libxl: fix segfault when domain create fail

2013-12-19 Thread Bamvor Jian Zhang
there is a segfault in libxl logging in libxl_ctx_free when domain
create fail. because the log output handler vmessage is freed by
xtl_logger_destroy before libxl_ctx_free in virDomainObjListRemove.
move xtl_logger_destroy after libxl_ctx_free could fix this bug.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
 src/libxl/libxl_domain.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 68009db..e72c483 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -354,12 +354,11 @@ libxlDomainObjPrivateDispose(void *obj)
 libxl_evdisable_domain_death(priv-ctx, priv-deathW);
 
 virChrdevFree(priv-devs);
-
-xtl_logger_destroy(priv-logger);
+libxl_ctx_free(priv-ctx);
 if (priv-logger_file)
 VIR_FORCE_FCLOSE(priv-logger_file);
 
-libxl_ctx_free(priv-ctx);
+xtl_logger_destroy(priv-logger);
 }
 
 static void
-- 
1.8.1.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] fix api changes in xen restore

2013-11-01 Thread Bamvor Jian Zhang
in recently xen commit: 7051d5c8, there is a api changes in
libxl_domain_create_restore.
Author: Andrew Cooper andrew.coop...@citrix.com
Date:   Thu Oct 10 12:23:10 2013 +0100

tools/migrate: Fix regression when migrating from older version of Xen

use the macro LIBXL_HAVE_DOMAIN_CREATE_RESTORE_PARAMS in libxl.h
in order to make libvirt could compile with old and new xen.

the params checkpointed_stream is useful if libvirt libxl driver
support migration. for new, set it as zero.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
 src/libxl/libxl_driver.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 4928695..104ad31 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -555,6 +555,9 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr 
vm,
 int managed_save_fd = -1;
 libxlDomainObjPrivatePtr priv = vm-privateData;
 libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
+#ifdef LIBXL_HAVE_DOMAIN_CREATE_RESTORE_PARAMS
+libxl_domain_restore_params params;
+#endif
 
 if (libxlDomainObjPrivateInitCtx(vm)  0)
 goto error;
@@ -619,8 +622,14 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr 
vm,
 ret = libxl_domain_create_new(priv-ctx, d_config,
   domid, NULL, NULL);
 else
+#ifdef LIBXL_HAVE_DOMAIN_CREATE_RESTORE_PARAMS
+params.checkpointed_stream = 0;
+ret = libxl_domain_create_restore(priv-ctx, d_config, domid,
+  restore_fd, params, NULL, NULL);
+#else
 ret = libxl_domain_create_restore(priv-ctx, d_config, domid,
   restore_fd, NULL, NULL);
+#endif
 
 if (ret) {
 if (restore_fd  0)
-- 
1.8.1.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] add migration APIs to libxl driver

2013-09-30 Thread Bamvor Jian Zhang
 --- 
  src/libxl/libxl_conf.h   |4 + 
  src/libxl/libxl_driver.c |  641 
 ++ 
  src/libxl/libxl_driver.h |5 + 
  3 files changed, 650 insertions(+), 0 deletions(-) 
  
 diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h 
 index 8ba0ee4..2041cc2 100644 
 --- a/src/libxl/libxl_conf.h 
 +++ b/src/libxl/libxl_conf.h 
 @@ -41,6 +41,9 @@ 
  # define LIBXL_VNC_PORT_MIN  5900 
  # define LIBXL_VNC_PORT_MAX  65535 
  
 +# define LIBXL_MIGRATION_PORT_MIN  49152 
 +# define LIBXL_MIGRATION_PORT_MAX  49216 
 + 
there is a overlap between vnc and migration port. althrought, it will try
next port in virPortAllocatorAcquire after bind fail.

  # define LIBXL_CONFIG_DIR SYSCONFDIR /libvirt/libxl 
  # define LIBXL_AUTOSTART_DIR LIBXL_CONFIG_DIR /autostart 
  # define LIBXL_STATE_DIR LOCALSTATEDIR /run/libvirt/libxl 
 @@ -109,6 +112,7 @@ struct _libxlDriverPrivate { 
  
  /* Immutable pointer, self-locking APIs */ 
  virPortAllocatorPtr reservedVNCPorts; 
 +virPortAllocatorPtr reservedMigPorts; 
  
  /* Immutable pointer, lockless APIs*/ 
  virSysinfoDefPtr hostsysinfo; 
 diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c 
 index e2a6d44..93b7153 100644 
 --- a/src/libxl/libxl_driver.c 
 +++ b/src/libxl/libxl_driver.c 
 @@ -32,6 +32,12 @@ 
  #include libxl_utils.h 
  #include fcntl.h 
  #include regex.h 
 +#include stdlib.h 
 +#include string.h 
 +#include sys/types.h 
 +#include sys/socket.h 
 +#include arpa/inet.h 
 +#include netdb.h 
  
  #include internal.h 
  #include virlog.h 
 @@ -52,6 +58,7 @@ 
  #include virsysinfo.h 
  #include viraccessapicheck.h 
  #include viratomic.h 
 +#include rpc/virnetsocket.h 
  
  #define VIR_FROM_THIS VIR_FROM_LIBXL 
  
 @@ -69,6 +76,20 @@ 
  
  static libxlDriverPrivatePtr libxl_driver = NULL; 
  
 +typedef struct _libxlMigrateReceiveArgs { 
 +virConnectPtr conn; 
 +virDomainObjPtr vm; 
 + 
 +/* for freeing listen sockets */ 
 +virNetSocketPtr *socks; 
 +size_t nsocks; 
 +} libxlMigrateReceiveArgs; 
 + 
 +static const char libxlMigrateReceiverReady[]= 
 +libvirt libxl migration receiver ready, send binary domain data; 
 +static const char libxlMigrateReceiverFinish[]= 
 +domain received, ready to unpause; 
 + 
  /* Function declarations */ 
  static int 
  libxlDomainManagedSaveLoad(virDomainObjPtr vm, 
 @@ -836,6 +857,12 @@ libxlStateInitialize(bool privileged, 
LIBXL_VNC_PORT_MAX))) 
  goto error; 
  
 +/* Allocate bitmap for migration port reservation */ 
 +if (!(libxl_driver-reservedMigPorts = 
 +  virPortAllocatorNew(LIBXL_MIGRATION_PORT_MIN, 
 +  LIBXL_MIGRATION_PORT_MAX))) 
 +goto error; 
 + 
  if (!(libxl_driver-domains = virDomainObjListNew())) 
  goto error; 
  
 @@ -4175,11 +4202,620 @@ libxlConnectSupportsFeature(virConnectPtr conn, 
 int feature) 
  switch (feature) { 
  case VIR_DRV_FEATURE_TYPED_PARAM_STRING: 
  return 1; 
 +case VIR_DRV_FEATURE_MIGRATION_V3: 
 +return 1; 
  default: 
  return 0; 
  } 
  } 
  
 +static int 
 +libxlCheckMessageBanner(int fd, const char *banner, int banner_sz) 
 +{ 
 +char buf[banner_sz]; 
 +int ret = 0; 
 + 
 +do { 
 +ret = saferead(fd, buf, banner_sz); 
 +} while (ret == -1  errno == EAGAIN); 
 + 
 +if (ret != banner_sz || memcmp(buf, banner, banner_sz)) { 
 +return -1; 
 +} 
 + 
 +return 0; 
 +} 
 + 
 +static char * 
 +libxlDomainMigrateBegin3(virDomainPtr domain, 
 + const char *xmlin, 
 + char **cookieout ATTRIBUTE_UNUSED, 
 + int *cookieoutlen ATTRIBUTE_UNUSED, 
 + unsigned long flags, 
 + const char *dname ATTRIBUTE_UNUSED, 
 + unsigned long resource ATTRIBUTE_UNUSED) 
 +{ 
 +libxlDriverPrivatePtr driver = domain-conn-privateData; 
 +libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver); 
 +virDomainObjPtr vm; 
 +virDomainDefPtr def = NULL; 
 +char *xml = NULL; 
 + 
 +virCheckFlags(LIBXL_MIGRATION_FLAGS, NULL); 
 + 
 +vm = virDomainObjListFindByUUID(driver-domains, domain-uuid); 
 +if (!vm) { 
 +char uuidstr[VIR_UUID_STRING_BUFLEN]; 
 +virUUIDFormat(domain-uuid, uuidstr); 
 +virReportError(VIR_ERR_OPERATION_INVALID, 
 +   _(no domain with matching uuid '%s'), uuidstr); 
 +goto cleanup; 
 +} 
libxlDomObjFromDomain is introduced in commit 0d87fd0aa by Jim.

 + 
 +if (!virDomainObjIsActive(vm)) { 
 +virReportError(VIR_ERR_OPERATION_INVALID, %s, 
 +   _(domain is not running)); 
 +goto cleanup; 
 +} 
 + 
 +if (virDomainMigrateBegin3EnsureACL(domain-conn, vm-def)  0) 
 +goto cleanup; 
 + 
 +if (xmlin) { 
 +if (!(def = 

[libvirt] [PATCH V5] add console support in libxl

2013-07-25 Thread Bamvor Jian Zhang
this patch introduce the console api in libxl driver for both pv and
hvm guest.  and import and update the libxlMakeChrdevStr function
which was deleted in commit dfa1e1dd.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
Changes since V4:
1), using proper error instead of VIR_ERR_INTERNAL_ERROR.
2), treat safe as unsupported flags in libxl openConsole api.
3), some format and minor logic changes.

Changes since V3:
implicity forbit dev_name pass to libxl driver due to only one
console supported by libxl.

Changes since V2:
1), forbid parallel configure because libxl do not support it
2), only support one serial on libxl driver.
3), also remove console code in libxl driver, AFAICS serial is enough for
connecting to libxl console.

Changes since V1:
1), add virDomainOpenConsoleEnsureACL
3), remove virReportOOMErrorFull when virAsprintf fail.
4), change size_t for non-nagetive number in libxlDomainOpenConsole
size_t i;
size_t num = 0;
5), fix for make check
(1), replace virAsprintf with VIR_STRDUP in two places
(2), delete space.

 src/libxl/libxl_conf.c   | 104 +++
 src/libxl/libxl_conf.h   |   3 ++
 src/libxl/libxl_driver.c |  93 ++
 3 files changed, 200 insertions(+)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 5273a26..827dfdd 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -331,6 +331,92 @@ error:
 }
 
 static int
+libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
+{
+virDomainChrSourceDef srcdef = def-source;
+const char *type = virDomainChrTypeToString(srcdef.type);
+
+if (!type) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   %s, _(unknown chrdev type));
+return -1;
+}
+
+switch (srcdef.type) {
+case VIR_DOMAIN_CHR_TYPE_NULL:
+case VIR_DOMAIN_CHR_TYPE_STDIO:
+case VIR_DOMAIN_CHR_TYPE_VC:
+case VIR_DOMAIN_CHR_TYPE_PTY:
+if (VIR_STRDUP(*buf, type)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_FILE:
+case VIR_DOMAIN_CHR_TYPE_PIPE:
+if (virAsprintf(buf, %s:%s, type, srcdef.data.file.path)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_DEV:
+if (VIR_STRDUP(*buf, srcdef.data.file.path)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_UDP: {
+const char *connectHost = srcdef.data.udp.connectHost;
+const char *bindHost = srcdef.data.udp.bindHost;
+const char *bindService  = srcdef.data.udp.bindService;
+
+if (connectHost == NULL)
+connectHost = ;
+if (bindHost == NULL)
+bindHost = ;
+if (bindService == NULL)
+bindService = 0;
+
+if (virAsprintf(buf, udp:%s:%s@%s:%s,
+connectHost,
+srcdef.data.udp.connectService,
+bindHost,
+bindService)  0)
+return -1;
+break;
+}
+
+case VIR_DOMAIN_CHR_TYPE_TCP: {
+const char *prefix;
+
+if (srcdef.data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET)
+prefix = telnet;
+else
+prefix = tcp;
+
+if (virAsprintf(buf, %s:%s:%s%s,
+prefix,
+srcdef.data.tcp.host,
+srcdef.data.tcp.service,
+srcdef.data.tcp.listen ? ,server,nowait : )  0)
+return -1;
+break;
+}
+
+case VIR_DOMAIN_CHR_TYPE_UNIX:
+if (virAsprintf(buf, unix:%s%s,
+srcdef.data.nix.path,
+srcdef.data.nix.listen ? ,server,nowait : )  0)
+return -1;
+break;
+
+default:
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _(unsupported chardev '%s'), type);
+return -1;
+}
+
+return 0;
+}
+
+static int
 libxlMakeDomBuildInfo(virDomainObjPtr vm, libxl_domain_config *d_config)
 {
 virDomainDefPtr def = vm-def;
@@ -411,6 +497,24 @@ libxlMakeDomBuildInfo(virDomainObjPtr vm, 
libxl_domain_config *d_config)
 if (VIR_STRDUP(b_info-u.hvm.boot, bootorder)  0)
 goto error;
 
+if (def-nserials) {
+if (def-nserials  1) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   %s,
+   _(Only one serial device is supported by 
libxl));
+goto error;
+}
+if (libxlMakeChrdevStr(def-serials[0], b_info-u.hvm.serial)  0)
+goto error;
+}
+
+if (def-nparallels) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   %s,
+   _(Parallel devices are not supported by libxl));
+goto error;
+}
+
 /*
  * The following comment and calculation were taken

[libvirt] [PATCH V4] add console support in libxl

2013-07-24 Thread Bamvor Jian Zhang
this patch introduce the console api in libxl driver for both pv and
hvm guest.  and import and update the libxlMakeChrdevStr function
which was deleted in commit dfa1e1dd.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
Changes since V3:
implicity forbit dev_name pass to libxl driver.

Changes since V2:
1), forbid parallel configure because libxl do not support it
2), only support one serial on libxl driver.
3), also remove console code in libxl driver, AFAICS serial is enough for
connecting to libxl console.

changes since V1:
1), add virDomainOpenConsoleEnsureACL
3), remove virReportOOMErrorFull when virAsprintf fail.
4), change size_t for non-nagetive number in libxlDomainOpenConsole
size_t i;
size_t num = 0;
5), fix for make check
(1), replace virAsprintf with VIR_STRDUP in two places
(2), delete space.

 src/libxl/libxl_conf.c   | 100 +++
 src/libxl/libxl_conf.h   |   3 ++
 src/libxl/libxl_driver.c |  94 
 3 files changed, 197 insertions(+)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 4a0fba9..539d537 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -331,6 +331,90 @@ error:
 }
 
 static int
+libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
+{
+const char *type = virDomainChrTypeToString(def-source.type);
+int ret;
+
+if (!type) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(unexpected chr device type));
+return -1;
+}
+
+switch (def-source.type) {
+case VIR_DOMAIN_CHR_TYPE_NULL:
+case VIR_DOMAIN_CHR_TYPE_STDIO:
+case VIR_DOMAIN_CHR_TYPE_VC:
+case VIR_DOMAIN_CHR_TYPE_PTY:
+if (VIR_STRDUP(*buf, type)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_FILE:
+case VIR_DOMAIN_CHR_TYPE_PIPE:
+if (virAsprintf(buf, %s:%s, type,
+def-source.data.file.path)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_DEV:
+if (VIR_STRDUP(*buf, def-source.data.file.path)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_UDP: {
+const char *connectHost = def-source.data.udp.connectHost;
+const char *bindHost = def-source.data.udp.bindHost;
+const char *bindService  = def-source.data.udp.bindService;
+
+if (connectHost == NULL)
+connectHost = ;
+if (bindHost == NULL)
+bindHost = ;
+if (bindService == NULL)
+bindService = 0;
+
+ret = virAsprintf(buf, udp:%s:%s@%s:%s,
+  connectHost,
+  def-source.data.udp.connectService,
+  bindHost,
+  bindService);
+if (ret  0)
+return -1;
+break;
+
+}
+case VIR_DOMAIN_CHR_TYPE_TCP:
+if (def-source.data.tcp.protocol == 
VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET)
+ret = virAsprintf(buf, telnet:%s:%s%s,
+  def-source.data.tcp.host,
+  def-source.data.tcp.service,
+  def-source.data.tcp.listen ? 
,server,nowait : );
+else
+ret = virAsprintf(buf, tcp:%s:%s%s,
+  def-source.data.tcp.host,
+  def-source.data.tcp.service,
+  def-source.data.tcp.listen ? 
,server,nowait : );
+
+if (ret  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_UNIX:
+ret = virAsprintf(buf, unix:%s%s,
+  def-source.data.nix.path,
+  def-source.data.nix.listen ? ,server,nowait : 
);
+if (ret  0)
+return -1;
+break;
+
+}
+
+return 0;
+}
+
+static int
 libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
 {
 libxl_domain_build_info *b_info = d_config-b_info;
@@ -403,6 +487,22 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, 
libxl_domain_config *d_config)
 if (VIR_STRDUP(b_info-u.hvm.boot, bootorder)  0)
 goto error;
 
+if (def-nserials) {
+if (def-nserials  1) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(Only one serial is supported by 
libxl));
+goto error;
+}
+if (libxlMakeChrdevStr(def-serials[0], b_info-u.hvm.serial)  0)
+goto error;
+}
+
+if (def-nparallels) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(Parallel is not supported));
+goto error

[libvirt] [PATCH V4] add console support in libxl

2013-07-24 Thread Bamvor Jian Zhang
this patch introduce the console api in libxl driver for both pv and
hvm guest.  and import and update the libxlMakeChrdevStr function
which was deleted in commit dfa1e1dd.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
Changes since V3:
implicity forbit dev_name pass to libxl driver due to only one
console supported by libxl.

Changes since V2:
1), forbid parallel configure because libxl do not support it
2), only support one serial on libxl driver.
3), also remove console code in libxl driver, AFAICS serial is enough for
connecting to libxl console.

Changes since V1:
1), add virDomainOpenConsoleEnsureACL
3), remove virReportOOMErrorFull when virAsprintf fail.
4), change size_t for non-nagetive number in libxlDomainOpenConsole
size_t i;
size_t num = 0;
5), fix for make check
(1), replace virAsprintf with VIR_STRDUP in two places
(2), delete space.

 src/libxl/libxl_conf.c   | 100 +++
 src/libxl/libxl_conf.h   |   3 ++
 src/libxl/libxl_driver.c |  94 
 3 files changed, 197 insertions(+)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 4a0fba9..539d537 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -331,6 +331,90 @@ error:
 }
 
 static int
+libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
+{
+const char *type = virDomainChrTypeToString(def-source.type);
+int ret;
+
+if (!type) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(unexpected chr device type));
+return -1;
+}
+
+switch (def-source.type) {
+case VIR_DOMAIN_CHR_TYPE_NULL:
+case VIR_DOMAIN_CHR_TYPE_STDIO:
+case VIR_DOMAIN_CHR_TYPE_VC:
+case VIR_DOMAIN_CHR_TYPE_PTY:
+if (VIR_STRDUP(*buf, type)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_FILE:
+case VIR_DOMAIN_CHR_TYPE_PIPE:
+if (virAsprintf(buf, %s:%s, type,
+def-source.data.file.path)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_DEV:
+if (VIR_STRDUP(*buf, def-source.data.file.path)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_UDP: {
+const char *connectHost = def-source.data.udp.connectHost;
+const char *bindHost = def-source.data.udp.bindHost;
+const char *bindService  = def-source.data.udp.bindService;
+
+if (connectHost == NULL)
+connectHost = ;
+if (bindHost == NULL)
+bindHost = ;
+if (bindService == NULL)
+bindService = 0;
+
+ret = virAsprintf(buf, udp:%s:%s@%s:%s,
+  connectHost,
+  def-source.data.udp.connectService,
+  bindHost,
+  bindService);
+if (ret  0)
+return -1;
+break;
+
+}
+case VIR_DOMAIN_CHR_TYPE_TCP:
+if (def-source.data.tcp.protocol == 
VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET)
+ret = virAsprintf(buf, telnet:%s:%s%s,
+  def-source.data.tcp.host,
+  def-source.data.tcp.service,
+  def-source.data.tcp.listen ? 
,server,nowait : );
+else
+ret = virAsprintf(buf, tcp:%s:%s%s,
+  def-source.data.tcp.host,
+  def-source.data.tcp.service,
+  def-source.data.tcp.listen ? 
,server,nowait : );
+
+if (ret  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_UNIX:
+ret = virAsprintf(buf, unix:%s%s,
+  def-source.data.nix.path,
+  def-source.data.nix.listen ? ,server,nowait : 
);
+if (ret  0)
+return -1;
+break;
+
+}
+
+return 0;
+}
+
+static int
 libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
 {
 libxl_domain_build_info *b_info = d_config-b_info;
@@ -403,6 +487,22 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, 
libxl_domain_config *d_config)
 if (VIR_STRDUP(b_info-u.hvm.boot, bootorder)  0)
 goto error;
 
+if (def-nserials) {
+if (def-nserials  1) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(Only one serial is supported by 
libxl));
+goto error;
+}
+if (libxlMakeChrdevStr(def-serials[0], b_info-u.hvm.serial)  0)
+goto error;
+}
+
+if (def-nparallels) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(Parallel is not supported

Re: [libvirt] [PATCH V3] add console support in libxl

2013-07-19 Thread Bamvor Jian Zhang
Hi, Denial


thanks your reply. 


 Daniel P. Berrange 2013-7-19 下午 23:53 
 On Fri, Jul 19, 2013 at 11:48:56PM +0800, Bamvor Jian Zhang wrote:
  this patch introduce the console api in libxl driver for both pv and
  hvm guest. and import and update the libxlMakeChrdevStr function
  which was deleted in commit dfa1e1dd.
  
  Signed-off-by: Bamvor Jian Zhang 
  ---
  Changes since V2:
  1), forbid parallel configure because libxl do not support it
  2), only support one serial on libxl driver.
  3), also remove console code in libxl driver, AFAICS serial is enough for 
  connecting to libxl console.
  changes since V1:
  1), add virDomainOpenConsoleEnsureACL
  3), remove virReportOOMErrorFull when virAsprintf fail.
  4), change size_t for non-nagetive number in libxlDomainOpenConsole
  size_t i;
  size_t num = 0;
  5), fix for make check
  (1), replace virAsprintf with VIR_STRDUP in two places
  (2), delete space.
  
  src/libxl/libxl_conf.c | 100 +++
  src/libxl/libxl_conf.h | 3 ++
  src/libxl/libxl_driver.c | 87 +
  3 files changed, 190 insertions(+)
  
  diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
  index 4a0fba9..539d537 100644
  --- a/src/libxl/libxl_conf.c
  +++ b/src/libxl/libxl_conf.c
  @@ -331,6 +331,90 @@ error:
  }
  
  static int
  +libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
  +{
  + const char *type = virDomainChrTypeToString(def-source.type);
  + int ret;
  +
  + if (!type) {
  + virReportError(VIR_ERR_INTERNAL_ERROR,
  + %s, _(unexpected chr device type));
  + return -1;
  + }
  +
  + switch (def-source.type) {
  + case VIR_DOMAIN_CHR_TYPE_NULL:
  + case VIR_DOMAIN_CHR_TYPE_STDIO:
  + case VIR_DOMAIN_CHR_TYPE_VC:
  + case VIR_DOMAIN_CHR_TYPE_PTY:
  + if (VIR_STRDUP(*buf, type)  0)
  + return -1;
  + break;
  +
  + case VIR_DOMAIN_CHR_TYPE_FILE:
  + case VIR_DOMAIN_CHR_TYPE_PIPE:
  + if (virAsprintf(buf, %s:%s, type,
  + def-source.data.file.path)  0)
  + return -1;
  + break;
  +
  + case VIR_DOMAIN_CHR_TYPE_DEV:
  + if (VIR_STRDUP(*buf, def-source.data.file.path)  0)
  + return -1;
  + break;
  +
  + case VIR_DOMAIN_CHR_TYPE_UDP: {
  + const char *connectHost = def-source.data.udp.connectHost;
  + const char *bindHost = def-source.data.udp.bindHost;
  + const char *bindService = def-source.data.udp.bindService;
  +
  + if (connectHost == NULL)
  + connectHost = ;
  + if (bindHost == NULL)
  + bindHost = ;
  + if (bindService == NULL)
  + bindService = 0;
  +
  + ret = virAsprintf(buf, udp:%s:%s@%s:%s,
  + connectHost,
  + def-source.data.udp.connectService,
  + bindHost,
  + bindService);
  + if (ret  0)
  + return -1;
  + break;
  +
  + }
  + case VIR_DOMAIN_CHR_TYPE_TCP:
  + if (def-source.data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET)
  + ret = virAsprintf(buf, telnet:%s:%s%s,
  + def-source.data.tcp.host,
  + def-source.data.tcp.service,
  + def-source.data.tcp.listen ? ,server,nowait : );
  + else
  + ret = virAsprintf(buf, tcp:%s:%s%s,
  + def-source.data.tcp.host,
  + def-source.data.tcp.service,
  + def-source.data.tcp.listen ? ,server,nowait : );
  +
  + if (ret  0)
  + return -1;
  + break;
  +
  + case VIR_DOMAIN_CHR_TYPE_UNIX:
  + ret = virAsprintf(buf, unix:%s%s,
  + def-source.data.nix.path,
  + def-source.data.nix.listen ? ,server,nowait : );
  + if (ret  0)
  + return -1;
  + break;
  +
  + }
  +
  + return 0;
  +}
  +
  +static int
  libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
  {
  libxl_domain_build_info *b_info = d_config-b_info;
  @@ -403,6 +487,22 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, 
  libxl_domain  + if (def-nserials  1) {
  + virReportError(VIR_ERR_INTERNAL_ERROR,
  + %s, _(Only one serial is supported by libxl));
  + goto error;
  + }
  + if (libxlMakeChrdevStr(def-serials[0], b_info-u.hvm.serial)  0)
  + goto error;
  + }
  +
  + if (def-nparallels) {
  + virReportError(VIR_ERR_INTERNAL_ERROR,
  + %s, _(Parallel is not supported));
  + goto error;
  + }
  +
  /*
  * The following comment and calculation were taken directly from
  * libxenlight's internal function libxl_get_required_shadow_memory():
  diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
  index 2b4a281..861d689 100644
  --- a/src/libxl/libxl_conf.h
  +++ b/src/libxl/libxl_conf.h
  @@ -34,6 +34,7 @@
  # include configmake.h
  # include virportallocator.h
  # include virobject.h
  +# include virchrdev.h
  
  
  # define LIBXL_VNC_PORT_MIN 5900
  @@ -94,6 +95,8 @@ struct _libxlDomainObjPrivate {
  
  /* per domain libxl ctx */
  libxl_ctx *ctx;
  + /* console */
  + virChrdevsPtr devs;
  libxl_evgen_domain_death *deathW;
  
  /* list of libxl timeout registrations */
  diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
  index 358d387..b3a8d50 100644
  --- a/src/libxl/libxl_driver.c
  +++ b/src/libxl/libxl_driver.c
  @@ -417,6 +417,9 @@ libxlDomainObjPrivateAlloc(void)
  
  libxl_osevent_register_hooks(priv-ctx

[libvirt] [PATCH V3] add console support in libxl

2013-07-19 Thread Bamvor Jian Zhang
this patch introduce the console api in libxl driver for both pv and
hvm guest.  and import and update the libxlMakeChrdevStr function
which was deleted in commit dfa1e1dd.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
Changes since V2:
1), forbid parallel configure because libxl do not support it
2), only support one serial on libxl driver.
3), also remove console code in libxl driver, AFAICS serial is enough for 
connecting to libxl console.
changes since V1:
1), add virDomainOpenConsoleEnsureACL
3), remove virReportOOMErrorFull when virAsprintf fail.
4), change size_t for non-nagetive number in libxlDomainOpenConsole
size_t i;
size_t num = 0;
5), fix for make check
(1), replace virAsprintf with VIR_STRDUP in two places
(2), delete space.

 src/libxl/libxl_conf.c   | 100 +++
 src/libxl/libxl_conf.h   |   3 ++
 src/libxl/libxl_driver.c |  87 +
 3 files changed, 190 insertions(+)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 4a0fba9..539d537 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -331,6 +331,90 @@ error:
 }
 
 static int
+libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
+{
+const char *type = virDomainChrTypeToString(def-source.type);
+int ret;
+
+if (!type) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(unexpected chr device type));
+return -1;
+}
+
+switch (def-source.type) {
+case VIR_DOMAIN_CHR_TYPE_NULL:
+case VIR_DOMAIN_CHR_TYPE_STDIO:
+case VIR_DOMAIN_CHR_TYPE_VC:
+case VIR_DOMAIN_CHR_TYPE_PTY:
+if (VIR_STRDUP(*buf, type)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_FILE:
+case VIR_DOMAIN_CHR_TYPE_PIPE:
+if (virAsprintf(buf, %s:%s, type,
+def-source.data.file.path)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_DEV:
+if (VIR_STRDUP(*buf, def-source.data.file.path)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_UDP: {
+const char *connectHost = def-source.data.udp.connectHost;
+const char *bindHost = def-source.data.udp.bindHost;
+const char *bindService  = def-source.data.udp.bindService;
+
+if (connectHost == NULL)
+connectHost = ;
+if (bindHost == NULL)
+bindHost = ;
+if (bindService == NULL)
+bindService = 0;
+
+ret = virAsprintf(buf, udp:%s:%s@%s:%s,
+  connectHost,
+  def-source.data.udp.connectService,
+  bindHost,
+  bindService);
+if (ret  0)
+return -1;
+break;
+
+}
+case VIR_DOMAIN_CHR_TYPE_TCP:
+if (def-source.data.tcp.protocol == 
VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET)
+ret = virAsprintf(buf, telnet:%s:%s%s,
+  def-source.data.tcp.host,
+  def-source.data.tcp.service,
+  def-source.data.tcp.listen ? 
,server,nowait : );
+else
+ret = virAsprintf(buf, tcp:%s:%s%s,
+  def-source.data.tcp.host,
+  def-source.data.tcp.service,
+  def-source.data.tcp.listen ? 
,server,nowait : );
+
+if (ret  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_UNIX:
+ret = virAsprintf(buf, unix:%s%s,
+  def-source.data.nix.path,
+  def-source.data.nix.listen ? ,server,nowait : 
);
+if (ret  0)
+return -1;
+break;
+
+}
+
+return 0;
+}
+
+static int
 libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
 {
 libxl_domain_build_info *b_info = d_config-b_info;
@@ -403,6 +487,22 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, 
libxl_domain_config *d_config)
 if (VIR_STRDUP(b_info-u.hvm.boot, bootorder)  0)
 goto error;
 
+if (def-nserials) {
+if (def-nserials  1) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(Only one serial is supported by 
libxl));
+goto error;
+}
+if (libxlMakeChrdevStr(def-serials[0], b_info-u.hvm.serial)  0)
+goto error;
+}
+
+if (def-nparallels) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(Parallel is not supported));
+goto error;
+}
+
 /*
  * The following comment and calculation were taken directly

[libvirt] [PATCH V2] add console support in libxl

2013-07-18 Thread Bamvor Jian Zhang
this patch introduce the console api in libxl driver for both pv and
hvm guest.  and import and update the libxlMakeChrdevStr function
which was deleted in commit dfa1e1dd.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
changes since V1:
1), add virDomainOpenConsoleEnsureACL
3), remove virReportOOMErrorFull when virAsprintf fail.
4), change size_t for non-nagetive number in libxlDomainOpenConsole
size_t i;
size_t num = 0;
5), fix for make check
(1), replace virAsprintf with VIR_STRDUP in two places
(2), delete space.

 src/libxl/libxl_conf.c   |  88 ++
 src/libxl/libxl_conf.h   |   3 ++
 src/libxl/libxl_driver.c | 122 +++
 3 files changed, 213 insertions(+)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 4a0fba9..5b3a535 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -331,6 +331,90 @@ error:
 }
 
 static int
+libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
+{
+const char *type = virDomainChrTypeToString(def-source.type);
+int ret;
+
+if (!type) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(unexpected chr device type));
+return -1;
+}
+
+switch (def-source.type) {
+case VIR_DOMAIN_CHR_TYPE_NULL:
+case VIR_DOMAIN_CHR_TYPE_STDIO:
+case VIR_DOMAIN_CHR_TYPE_VC:
+case VIR_DOMAIN_CHR_TYPE_PTY:
+if (VIR_STRDUP(*buf, type)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_FILE:
+case VIR_DOMAIN_CHR_TYPE_PIPE:
+if (virAsprintf(buf, %s:%s, type,
+def-source.data.file.path)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_DEV:
+if (VIR_STRDUP(*buf, def-source.data.file.path)  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_UDP: {
+const char *connectHost = def-source.data.udp.connectHost;
+const char *bindHost = def-source.data.udp.bindHost;
+const char *bindService  = def-source.data.udp.bindService;
+
+if (connectHost == NULL)
+connectHost = ;
+if (bindHost == NULL)
+bindHost = ;
+if (bindService == NULL)
+bindService = 0;
+
+ret = virAsprintf(buf, udp:%s:%s@%s:%s,
+  connectHost,
+  def-source.data.udp.connectService,
+  bindHost,
+  bindService);
+if (ret  0)
+return -1;
+break;
+
+}
+case VIR_DOMAIN_CHR_TYPE_TCP:
+if (def-source.data.tcp.protocol == 
VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET)
+ret = virAsprintf(buf, telnet:%s:%s%s,
+  def-source.data.tcp.host,
+  def-source.data.tcp.service,
+  def-source.data.tcp.listen ? 
,server,nowait : );
+else
+ret = virAsprintf(buf, tcp:%s:%s%s,
+  def-source.data.tcp.host,
+  def-source.data.tcp.service,
+  def-source.data.tcp.listen ? 
,server,nowait : );
+
+if (ret  0)
+return -1;
+break;
+
+case VIR_DOMAIN_CHR_TYPE_UNIX:
+ret = virAsprintf(buf, unix:%s%s,
+  def-source.data.nix.path,
+  def-source.data.nix.listen ? ,server,nowait : 
);
+if (ret  0)
+return -1;
+break;
+
+}
+
+return 0;
+}
+
+static int
 libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
 {
 libxl_domain_build_info *b_info = d_config-b_info;
@@ -403,6 +487,10 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, 
libxl_domain_config *d_config)
 if (VIR_STRDUP(b_info-u.hvm.boot, bootorder)  0)
 goto error;
 
+if (def-nserials 
+(libxlMakeChrdevStr(def-serials[0], b_info-u.hvm.serial)  0))
+goto error;
+
 /*
  * The following comment and calculation were taken directly from
  * libxenlight's internal function libxl_get_required_shadow_memory():
diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index 2b4a281..861d689 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -34,6 +34,7 @@
 # include configmake.h
 # include virportallocator.h
 # include virobject.h
+# include virchrdev.h
 
 
 # define LIBXL_VNC_PORT_MIN  5900
@@ -94,6 +95,8 @@ struct _libxlDomainObjPrivate {
 
 /* per domain libxl ctx */
 libxl_ctx *ctx;
+/* console */
+virChrdevsPtr devs;
 libxl_evgen_domain_death *deathW;
 
 /* list of libxl timeout registrations */
diff --git a/src/libxl

Re: [libvirt] [PATCH] add console support in libxl

2013-07-16 Thread Bamvor Jian Zhang
Hi, Jim

thanks your reply. one comment below.

 已写入 Jim Fehlig jfeh...@suse.com On 07/04/2013 05:58 AM, Bamvor Jian 
 Zhang wrote:
  this patch introduce the console api in libxl driver for both pv and 
  hvm guest.  and import and update the libxlMakeChrdevStr function 
  which was deleted in commit dfa1e1dd. 
  
  Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com 
  --- 
src/libxl/libxl_conf.c   |  97 ++ 
src/libxl/libxl_conf.h   |   3 ++ 
src/libxl/libxl_driver.c | 119  
 +++ 
3 files changed, 219 insertions(+) 
  
  diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c 
  index e170357..08095bc 100644 
  --- a/src/libxl/libxl_conf.c 
  +++ b/src/libxl/libxl_conf.c 
  @@ -332,6 +332,99 @@ error: 
} 
 
static int 
  +libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf) 
  +{ 
  +const char *type = virDomainChrTypeToString(def-source.type); 
  +int ret; 
  + 
  +if (!type) { 
  +virReportError(VIR_ERR_INTERNAL_ERROR, 
  +   %s, _(unexpected chr device type)); 
  +return -1; 
  +} 
  + 
  +switch (def-source.type) { 
  +case VIR_DOMAIN_CHR_TYPE_NULL: 
  +case VIR_DOMAIN_CHR_TYPE_STDIO: 
  +case VIR_DOMAIN_CHR_TYPE_VC: 
  +case VIR_DOMAIN_CHR_TYPE_PTY: 
  +if (virAsprintf(buf, %s, type)  0) { 
  +virReportOOMError(); 
  
 This will need rebased now that Michal's Introduce OOM reporting to  
 virAsprintf patchset is committed. 
  
 https://www.redhat.com/archives/libvir-list/2013-July/msg00506.html 
  
  +return -1; 
  +} 
  +break; 
  + 
  +case VIR_DOMAIN_CHR_TYPE_FILE: 
  +case VIR_DOMAIN_CHR_TYPE_PIPE: 
  +if (virAsprintf(buf, %s:%s, type, 
  +def-source.data.file.path)  0) { 
  +virReportOOMError(); 
  +return -1; 
  +} 
  +break; 
  + 
  +case VIR_DOMAIN_CHR_TYPE_DEV: 
  +if (virAsprintf(buf, %s, def-source.data.file.path)  0) { 
  +virReportOOMError(); 
  +return -1; 
  +} 
  +break; 
  +case VIR_DOMAIN_CHR_TYPE_UDP: { 
  +const char *connectHost = def-source.data.udp.connectHost; 
  +const char *bindHost = def-source.data.udp.bindHost; 
  +const char *bindService  = def-source.data.udp.bindService; 
  + 
  +if (connectHost == NULL) 
  +connectHost = ; 
  +if (bindHost == NULL) 
  +bindHost = ; 
  +if (bindService == NULL) 
  +bindService = 0; 
  + 
  +ret = virAsprintf(buf, udp:%s:%s@%s:%s, 
  +  connectHost, 
  +  def-source.data.udp.connectService, 
  +  bindHost, 
  +  bindService); 
  +if ( ret  0) { 
  
 Extra space between '(' and 'ret', caught by 'make syntax-check'. 
  
  +virReportOOMError(); 
  +return -1; 
  +} 
  +break; 
  +} 
  +case VIR_DOMAIN_CHR_TYPE_TCP: 
  +if (def-source.data.tcp.protocol ==  
 VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET) { 
  +ret = virAsprintf(buf, telnet:%s:%s%s, 
  +  def-source.data.tcp.host, 
  +  def-source.data.tcp.service, 
  +  def-source.data.tcp.listen ?  
 ,server,nowait : ); 
  +} else { 
  +ret = virAsprintf(buf, tcp:%s:%s%s, 
  +  def-source.data.tcp.host, 
  +  def-source.data.tcp.service, 
  +  def-source.data.tcp.listen ?  
 ,server,nowait : ); 
  +} 
  +if ( ret  0) { 
  
 Extra space here too. 
  
  +virReportOOMError(); 
  +return -1; 
  +} 
  +break; 
  + 
  +case VIR_DOMAIN_CHR_TYPE_UNIX: 
  +ret = virAsprintf(buf, unix:%s%s, 
  +  def-source.data.nix.path, 
  +  def-source.data.nix.listen ? 
  ,server,nowait  
 : ); 
  +if ( ret  0) { 
  
 And here. 

 BTW, do all of these types work with Xen?  I've only tested with type 'pty',  
  
 which works fine with both pv and hvm guests. 
i only test the pty type too. lots of type is introduced in 2b84e445(Add 
libxenlight driver), i add the missing type compare with qemu driver. maybe it 
will be used in future. for now, only pty is needed for my console patch.

thanks

Bamvor
  +virReportOOMError(); 
  +return -1; 
  +} 
  +break

[libvirt] [PATCH] add console support in libxl

2013-07-04 Thread Bamvor Jian Zhang
this patch introduce the console api in libxl driver for both pv and
hvm guest.  and import and update the libxlMakeChrdevStr function
which was deleted in commit dfa1e1dd.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
 src/libxl/libxl_conf.c   |  97 ++
 src/libxl/libxl_conf.h   |   3 ++
 src/libxl/libxl_driver.c | 119 +++
 3 files changed, 219 insertions(+)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index e170357..08095bc 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -332,6 +332,99 @@ error:
 }
 
 static int
+libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
+{
+const char *type = virDomainChrTypeToString(def-source.type);
+int ret;
+
+if (!type) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   %s, _(unexpected chr device type));
+return -1;
+}
+
+switch (def-source.type) {
+case VIR_DOMAIN_CHR_TYPE_NULL:
+case VIR_DOMAIN_CHR_TYPE_STDIO:
+case VIR_DOMAIN_CHR_TYPE_VC:
+case VIR_DOMAIN_CHR_TYPE_PTY:
+if (virAsprintf(buf, %s, type)  0) {
+virReportOOMError();
+return -1;
+}
+break;
+
+case VIR_DOMAIN_CHR_TYPE_FILE:
+case VIR_DOMAIN_CHR_TYPE_PIPE:
+if (virAsprintf(buf, %s:%s, type,
+def-source.data.file.path)  0) {
+virReportOOMError();
+return -1;
+}
+break;
+
+case VIR_DOMAIN_CHR_TYPE_DEV:
+if (virAsprintf(buf, %s, def-source.data.file.path)  0) {
+virReportOOMError();
+return -1;
+}
+break;
+case VIR_DOMAIN_CHR_TYPE_UDP: {
+const char *connectHost = def-source.data.udp.connectHost;
+const char *bindHost = def-source.data.udp.bindHost;
+const char *bindService  = def-source.data.udp.bindService;
+
+if (connectHost == NULL)
+connectHost = ;
+if (bindHost == NULL)
+bindHost = ;
+if (bindService == NULL)
+bindService = 0;
+
+ret = virAsprintf(buf, udp:%s:%s@%s:%s,
+  connectHost,
+  def-source.data.udp.connectService,
+  bindHost,
+  bindService);
+if ( ret  0) {
+virReportOOMError();
+return -1;
+}
+break;
+}
+case VIR_DOMAIN_CHR_TYPE_TCP:
+if (def-source.data.tcp.protocol == 
VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET) {
+ret = virAsprintf(buf, telnet:%s:%s%s,
+  def-source.data.tcp.host,
+  def-source.data.tcp.service,
+  def-source.data.tcp.listen ? 
,server,nowait : );
+} else {
+ret = virAsprintf(buf, tcp:%s:%s%s,
+  def-source.data.tcp.host,
+  def-source.data.tcp.service,
+  def-source.data.tcp.listen ? 
,server,nowait : );
+}
+if ( ret  0) {
+virReportOOMError();
+return -1;
+}
+break;
+
+case VIR_DOMAIN_CHR_TYPE_UNIX:
+ret = virAsprintf(buf, unix:%s%s,
+  def-source.data.nix.path,
+  def-source.data.nix.listen ? ,server,nowait : 
);
+if ( ret  0) {
+virReportOOMError();
+return -1;
+}
+break;
+}
+
+return 0;
+}
+
+static int
 libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
 {
 libxl_domain_build_info *b_info = d_config-b_info;
@@ -404,6 +497,10 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, 
libxl_domain_config *d_config)
 if (VIR_STRDUP(b_info-u.hvm.boot, bootorder)  0)
 goto error;
 
+if (def-nserials 
+(libxlMakeChrdevStr(def-serials[0], b_info-u.hvm.serial)  0))
+goto error;
+
 /*
  * The following comment and calculation were taken directly from
  * libxenlight's internal function libxl_get_required_shadow_memory():
diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index 2b4a281..861d689 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -34,6 +34,7 @@
 # include configmake.h
 # include virportallocator.h
 # include virobject.h
+# include virchrdev.h
 
 
 # define LIBXL_VNC_PORT_MIN  5900
@@ -94,6 +95,8 @@ struct _libxlDomainObjPrivate {
 
 /* per domain libxl ctx */
 libxl_ctx *ctx;
+/* console */
+virChrdevsPtr devs;
 libxl_evgen_domain_death *deathW;
 
 /* list of libxl timeout

[libvirt] [PATCH] fix segfault during virsh save in pv guest

2013-04-26 Thread Bamvor Jian Zhang
this patch fix the wrong sequence for fd and timeout register. the sequence
was right in dfa1e1dd for fd register, but it changed in e0622ca2.
in this patch, set priv, xl_priv in info and increase info-priv ref count
before virEventAddHandle. if do this after virEventAddHandle, the fd
callback or fd deregister maybe got the empty priv, xl_priv or wrong ref
count.

after apply this patch, test more than 100 rounds passed compare to fail
within 3 rounds without this patch. each round includes define - start -
destroy - create - suspend - resume - reboot - shutdown - save -
resotre - dump - destroy - create - setmem - setvcpus - destroy.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
 src/libxl/libxl_driver.c |   39 +--
 1 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index b4f1889..212d0fc 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -181,26 +181,28 @@ libxlFDRegisterEventHook(void *priv, int fd, void **hndp,
 return -1;
 }
 
+info-priv = priv;
+/*
+ * Take a reference on the domain object.  Reference is dropped in
+ * libxlEventHookInfoFree, ensuring the domain object outlives the fd
+ * event objects.
+ */
+virObjectRef(info-priv);
+info-xl_priv = xl_priv;
+
 if (events  POLLIN)
 vir_events |= VIR_EVENT_HANDLE_READABLE;
 if (events  POLLOUT)
 vir_events |= VIR_EVENT_HANDLE_WRITABLE;
+
 info-id = virEventAddHandle(fd, vir_events, libxlFDEventCallback,
  info, libxlEventHookInfoFree);
 if (info-id  0) {
+virObjectUnref(info-priv);
 VIR_FREE(info);
 return -1;
 }
 
-info-priv = priv;
-/*
- * Take a reference on the domain object.  Reference is dropped in
- * libxlEventHookInfoFree, ensuring the domain object outlives the fd
- * event objects.
- */
-virObjectRef(info-priv);
-
-info-xl_priv = xl_priv;
 *hndp = info;
 
 return 0;
@@ -283,6 +285,15 @@ libxlTimeoutRegisterEventHook(void *priv,
 return -1;
 }
 
+info-priv = priv;
+/*
+ * Also take a reference on the domain object.  Reference is dropped in
+ * libxlEventHookInfoFree, ensuring the domain object outlives the timeout
+ * event objects.
+ */
+virObjectRef(info-priv);
+info-xl_priv = xl_priv;
+
 gettimeofday(now, NULL);
 timersub(abs_t, now, res);
 /* Ensure timeout is not overflowed */
@@ -296,22 +307,14 @@ libxlTimeoutRegisterEventHook(void *priv,
 info-id = virEventAddTimeout(timeout, libxlTimerCallback,
   info, libxlEventHookInfoFree);
 if (info-id  0) {
+virObjectUnref(info-priv);
 VIR_FREE(info);
 return -1;
 }
 
-info-priv = priv;
-/*
- * Also take a reference on the domain object.  Reference is dropped in
- * libxlEventHookInfoFree, ensuring the domain object outlives the timeout
- * event objects.
- */
-virObjectRef(info-priv);
-
 virObjectLock(info-priv);
 LIBXL_EV_REG_APPEND(info-priv-timerRegistrations, info);
 virObjectUnlock(info-priv);
-info-xl_priv = xl_priv;
 *hndp = info;
 
 return 0;
-- 
1.6.0.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] fix typo introduced by 90430791

2013-04-25 Thread Bamvor Jian Zhang
From: Bamvor Jian Zhang bamv2...@gmail.com


Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
 src/node_device/node_device_hal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/node_device/node_device_hal.c 
b/src/node_device/node_device_hal.c
index 4a430dc..63245a9 100644
--- a/src/node_device/node_device_hal.c
+++ b/src/node_device/node_device_hal.c
@@ -764,7 +764,7 @@ static int nodeDeviceClose(virConnectPtr conn 
ATTRIBUTE_UNUSED)
 static virNodeDeviceDriver halNodeDeviceDriver = {
 .name = halNodeDeviceDriver,
 .nodeDeviceOpen = nodeDeviceOpen, /* 0.5.0 */
-.nodDeviceClose = nodDeviceClose, /* 0.5.0 */
+.nodeDeviceClose = nodeDeviceClose, /* 0.5.0 */
 .nodeNumOfDevices = nodeNumOfDevices, /* 0.5.0 */
 .nodeListDevices = nodeListDevices, /* 0.5.0 */
 .connectListAllNodeDevices = nodeListAllNodeDevices, /* 0.10.2 */
-- 
1.8.1.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH V2] implement managedsave in libvirt xen legacy driver

2012-12-04 Thread Bamvor Jian Zhang
Implement the domainManagedSave, domainHasManagedSaveImage, and
domainManagedSaveRemove functions in the libvirt legacy xen driver.

domainHasManagedSaveImage check the managedsave image from filesystem
everytime. This is different from qemu and libxl driver. In qemu or
libxl driver, there is a hasManagesSave flags in virDomainObjPtr which
is not used in xen legacy driver. This flag could not add into xen
driver ptr either, because the driver ptr will be release at the end of
every libvirt api calls. Meanwhile, AFAIK, xen store all the flags in
xen not in libvirt xen driver. There is no need to add this flags in xen.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
Changes since v1:
(1), add save dir in libvirt.spec.in and src/Makefile.am
(2), misc changes for return value and memory leak.

i have test the following case for this patch:
1), virsh managedsave save domain to /var/lib/xen/save/domain_name.save.
call xenUnifiedDomainManagedSave.
2), virsh start: if managedsave image is exist, it should be boot from
managed save image.
call xenUnifiedDomainHasManagedSaveImage.
3), virsh start --force-boot: fresh boot, delete the managed save image
if exists.
call xenUnifiedDomainHasManagedSaveImage,
xenUnifiedDomainManagedSaveRemove.
4), virsh managedsave-remove: remove managed save image.
call xenUnifiedDomainManagedSaveRemove
5), virsh undefine: undefine the domain, it will fail if mananed save
image exist.
call xenUnifiedDomainHasManagedSaveImage.
6), virsh undefine --managed-save: undefine the domain, and remove
mananed save image.
call xenUnifiedDomainHasManagedSaveImage and
xenUnifiedDomainManagedSaveRemove.
7), virsh list --all --with-managed-save. list domain if managed save
image exist. got nothing if non-exists.
call xenUnifiedDomainHasManagedSaveImage.
8), virsh list --all --without-managed-save. do not list the domain if
managed save image exist.
call xenUnifiedDomainHasManagedSaveImage.

 libvirt.spec.in  |   3 ++
 src/Makefile.am  |   6 +++
 src/xen/xen_driver.c | 108 ++-
 src/xen/xen_driver.h |   2 +
 4 files changed, 118 insertions(+), 1 deletion(-)

diff --git a/libvirt.spec.in b/libvirt.spec.in
index 47cb087..ae18adb 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1719,6 +1719,9 @@ rm -f $RPM_BUILD_ROOT%{_sysconfdir}/sysctl.d/libvirtd
 %ghost %dir %{_localstatedir}/run/libvirt/libxl/
 %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/libxl/
 %endif
+%if %{with_xen}
+%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/xen/
+%endif
 %if %{with_network}
 %ghost %dir %{_localstatedir}/run/libvirt/network/
 %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/network/
diff --git a/src/Makefile.am b/src/Makefile.am
index 01cb995..fc0d78a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1769,6 +1769,9 @@ if WITH_UML
$(MKDIR_P) $(DESTDIR)$(localstatedir)/lib/libvirt/uml
$(MKDIR_P) $(DESTDIR)$(localstatedir)/run/libvirt/uml
 endif
+if WITH_XEN
+   $(MKDIR_P) $(DESTDIR)$(localstatedir)/lib/libvirt/xen
+endif
 if WITH_NETWORK
$(MKDIR_P) $(DESTDIR)$(localstatedir)/lib/libvirt/network
$(MKDIR_P) $(DESTDIR)$(localstatedir)/lib/libvirt/dnsmasq
@@ -1815,6 +1818,9 @@ if WITH_UML
rmdir $(DESTDIR)$(localstatedir)/lib/libvirt/uml ||:
rmdir $(DESTDIR)$(localstatedir)/run/libvirt/uml ||:
 endif
+if WITH_XEN
+   rmdir $(DESTDIR)$(localstatedir)/lib/libvirt/xen ||:
+endif
 if WITH_NETWORK
rm -f 
$(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml
rm -f $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/default.xml
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 5a40757..71ff5bd 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -65,8 +65,10 @@
 #include command.h
 #include virnodesuspend.h
 #include nodeinfo.h
+#include configmake.h
 
 #define VIR_FROM_THIS VIR_FROM_XEN
+#define XEN_SAVE_DIR LOCALSTATEDIR /lib/libvirt/xen/save
 
 static int
 xenUnifiedNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
@@ -267,6 +269,7 @@ xenUnifiedOpen(virConnectPtr conn, virConnectAuthPtr auth, 
unsigned int flags)
 {
 int i, ret = VIR_DRV_OPEN_DECLINED;
 xenUnifiedPrivatePtr priv;
+char ebuf[1024];
 
 #ifdef __sun
 /*
@@ -406,6 +409,17 @@ xenUnifiedOpen(virConnectPtr conn, virConnectAuthPtr auth, 
unsigned int flags)
 }
 #endif
 
+if (virAsprintf(priv-saveDir, %s, XEN_SAVE_DIR) == -1) {
+virReportOOMError();
+goto fail;
+}
+
+if (virFileMakePath(priv-saveDir)  0) {
+VIR_ERROR(_(Failed to create save dir '%s': %s), priv-saveDir,
+  virStrerror(errno, ebuf, sizeof(ebuf)));
+goto fail;
+}
+
 return VIR_DRV_OPEN_SUCCESS;
 
 fail:
@@ -437,6 +451,7 @@ xenUnifiedClose(virConnectPtr conn)
 if (priv-opened[i])
 drivers[i]-xenClose(conn);
 
+VIR_FREE(priv-saveDir);
 virMutexDestroy(priv-lock);
 VIR_FREE(conn

[libvirt] [PATCH] implement managedsave in libvirt xen legacy driver

2012-11-30 Thread Bamvor Jian Zhang
Implement the domainManagedSave, domainHasManagedSaveImage, and
domainManagedSaveRemove functions in the libvirt legacy xen driver.

domainHasManagedSaveImage check the managedsave image from filesystem
everytime. This is different from qemu and libxl driver. In qemu or
libxl driver, there is a hasManagesSave flags in virDomainObjPtr which
is not used in xen legacy driver. This flag could not add into xen
driver ptr either, because the driver ptr will be release at the end of
every libvirt api calls. Meanwhile, AFAIK, xen store all the flags in
xen not in libvirt xen driver. There is no need to add this flags in xen.

---
i have test the following case for this patch:
1), virsh managedsave save domain to /var/lib/xen/save/domain_name.save.
call xenUnifiedDomainManagedSave.
2), virsh start: if managedsave image is exist, it should be boot from
managed save image.
call xenUnifiedDomainHasManagedSaveImage.
3), virsh start --force-boot: fresh boot, delete the managed save image
if exists.
call xenUnifiedDomainHasManagedSaveImage,
xenUnifiedDomainManagedSaveRemove.
4), virsh managedsave-remove: remove managed save image.
call xenUnifiedDomainManagedSaveRemove
5), virsh undefine: undefine the domain, it will fail if mananed save
image exist.
call xenUnifiedDomainHasManagedSaveImage.
6), virsh undefine --managed-save: undefine the domain, and remove
mananed save image.
call xenUnifiedDomainHasManagedSaveImage and
xenUnifiedDomainManagedSaveRemove.
7), virsh list --all --with-managed-save. list domain if managed save
image exist. got nothing if non-exists.
call xenUnifiedDomainHasManagedSaveImage.
8), virsh list --all --without-managed-save. do not list the domain if
managed save image exist.
call xenUnifiedDomainHasManagedSaveImage.

 src/xen/xen_driver.c | 109 ++-
 src/xen/xen_driver.h |   2 +
 2 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 5a40757..0b2418d 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -67,6 +67,7 @@
 #include nodeinfo.h
 
 #define VIR_FROM_THIS VIR_FROM_XEN
+#define XEN_SAVE_DIR LOCALSTATEDIR /lib/libvirt/xen/save
 
 static int
 xenUnifiedNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
@@ -267,6 +268,7 @@ xenUnifiedOpen(virConnectPtr conn, virConnectAuthPtr auth, 
unsigned int flags)
 {
 int i, ret = VIR_DRV_OPEN_DECLINED;
 xenUnifiedPrivatePtr priv;
+char ebuf[1024];
 
 #ifdef __sun
 /*
@@ -406,6 +408,17 @@ xenUnifiedOpen(virConnectPtr conn, virConnectAuthPtr auth, 
unsigned int flags)
 }
 #endif
 
+if (virAsprintf(priv-saveDir, %s, XEN_SAVE_DIR) == -1) {
+virReportOOMError();
+goto fail;
+}
+
+if (virFileMakePath(priv-saveDir)  0) {
+VIR_ERROR(_(Failed to create save dir '%s': %s), priv-saveDir,
+  virStrerror(errno, ebuf, sizeof(ebuf)));
+goto fail;
+}
+
 return VIR_DRV_OPEN_SUCCESS;
 
 fail:
@@ -437,6 +450,7 @@ xenUnifiedClose(virConnectPtr conn)
 if (priv-opened[i])
 drivers[i]-xenClose(conn);
 
+VIR_FREE(priv-saveDir);
 virMutexDestroy(priv-lock);
 VIR_FREE(conn-privateData);
 
@@ -1080,6 +1094,79 @@ xenUnifiedDomainSave(virDomainPtr dom, const char *to)
 return xenUnifiedDomainSaveFlags(dom, to, NULL, 0);
 }
 
+static char *
+xenUnifiedDomainManagedSavePath(xenUnifiedPrivatePtr priv, virDomainPtr dom)
+{
+char *ret;
+
+if (virAsprintf(ret, %s/%s.save, priv-saveDir, dom-name)  0) {
+virReportOOMError();
+return NULL;
+}
+
+VIR_DEBUG(managed save image: %s, ret);
+return ret;
+}
+
+static int
+xenUnifiedDomainManagedSave(virDomainPtr dom, unsigned int flags)
+{
+GET_PRIVATE(dom-conn);
+char *name;
+int ret = -1;
+
+virCheckFlags(0, -1);
+
+name = xenUnifiedDomainManagedSavePath(priv, dom);
+if (!name)
+goto cleanup;
+
+if (priv-opened[XEN_UNIFIED_XEND_OFFSET])
+ret = xenDaemonDomainSave(dom, name);
+
+cleanup:
+VIR_FREE(name);
+return ret;
+}
+
+static int
+xenUnifiedDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
+{
+GET_PRIVATE(dom-conn);
+char *name;
+int ret = -1;
+
+virCheckFlags(0, -1);
+
+name = xenUnifiedDomainManagedSavePath(priv, dom);
+if (!name)
+return ret;
+
+ret = virFileExists(name);
+VIR_FREE(name);
+return ret;
+}
+
+static int
+xenUnifiedDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
+{
+GET_PRIVATE(dom-conn);
+char *name;
+int ret = -1;
+
+virCheckFlags(0, -1);
+
+name = xenUnifiedDomainManagedSavePath(priv, dom);
+if (!name)
+goto cleanup;
+
+ret = unlink(name);
+VIR_FREE(name);
+
+cleanup:
+return ret;
+}
+
 static int
 xenUnifiedDomainRestoreFlags(virConnectPtr conn, const char *from,
  const char *dxml, unsigned int flags)
@@ -1504,16 +1591,33 @@ static int
 

Re: [libvirt] [PATCH 2/2] Add lock in libxl api

2012-11-02 Thread Bamvor Jian Zhang


 Jim Fehlig jfeh...@suse.com wrote: 
 Bamvor Jian Zhang wrote: 
  Add long-running jobs for save, dump. Add normal job for the 
  api maybe modify the domain. 
  
  Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com 
  --- 
   src/libxl/libxl_driver.c | 219 
  ++- 
   1 file changed, 158 insertions(+), 61 deletions(-) 
  
  diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c 
  index d01d915..28e50b0 100644 
  --- a/src/libxl/libxl_driver.c 
  +++ b/src/libxl/libxl_driver.c 
  @@ -1534,9 +1534,13 @@ libxlDomainCreateXML(virConnectPtr conn, const char  
 *xml, 
   goto cleanup; 
   def = NULL; 

  +if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY)  
  0) 
  +goto cleanup; 
  + 
   if (libxlVmStart(driver, vm, (flags  VIR_DOMAIN_START_PAUSED) != 0, 
-1)  0) { 
  -virDomainRemoveInactive(driver-domains, vm); 
  +if (libxlDomainObjEndJob(driver, vm)) 
  +virDomainRemoveInactive(driver-domains, vm); 
   vm = NULL; 
   goto cleanup; 
   } 
  @@ -1545,6 +1549,8 @@ libxlDomainCreateXML(virConnectPtr conn, const char  
 *xml, 
   if (dom) 
   dom-id = vm-def-id; 

  +if (!libxlDomainObjEndJob(driver, vm)) 
  +vm = NULL; 
   cleanup: 
   virDomainDefFree(def); 
   if (vm) 
  @@ -1651,9 +1657,13 @@ libxlDomainSuspend(virDomainPtr dom) 
  _(No domain with matching uuid '%s'), uuidstr); 
   goto cleanup; 
   } 
  + 
  +if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY)  0) 
  +goto cleanup; 
  + 
   if (!virDomainObjIsActive(vm)) { 
   virReportError(VIR_ERR_OPERATION_INVALID, %s, _(Domain is not  
 running)); 
  -goto cleanup; 
  +goto endjob; 
   } 
 
  
 IMO, we should check if the domain is active before calling 
 libxlDomainObjBeginJob(). 
  

   priv = vm-privateData; 
  @@ -1663,7 +1673,7 @@ libxlDomainSuspend(virDomainPtr dom) 
   virReportError(VIR_ERR_INTERNAL_ERROR, 
  _(Failed to suspend domain '%d' with  
 libxenlight), 
  dom-id); 
  -goto cleanup; 
  +goto endjob; 
   } 

   virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,  
 VIR_DOMAIN_PAUSED_USER); 
  @@ -1673,10 +1683,14 @@ libxlDomainSuspend(virDomainPtr dom) 
   } 

   if (virDomainSaveStatus(driver-caps, driver-stateDir, vm)  0) 
  -goto cleanup; 
  +goto endjob; 

   ret = 0; 

  +endjob: 
  +if (!libxlDomainObjEndJob(driver, vm)) 
  +vm = NULL; 
  + 
   cleanup: 
   if (vm) 
   virDomainObjUnlock(vm); 
  @@ -1710,9 +1724,12 @@ libxlDomainResume(virDomainPtr dom) 
   goto cleanup; 
   } 

  +if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY)  0) 
  +goto cleanup; 
  + 
   if (!virDomainObjIsActive(vm)) { 
   virReportError(VIR_ERR_OPERATION_INVALID, %s, _(Domain is not  
 running)); 
  -goto cleanup; 
  +goto endjob; 
   } 
 
  
 Same here. 
  

   priv = vm-privateData; 
  @@ -1722,7 +1739,7 @@ libxlDomainResume(virDomainPtr dom) 
   virReportError(VIR_ERR_INTERNAL_ERROR, 
  _(Failed to resume domain '%d' with  
 libxenlight), 
  dom-id); 
  -goto cleanup; 
  +goto endjob; 
   } 

   virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, 
  @@ -1733,10 +1750,14 @@ libxlDomainResume(virDomainPtr dom) 
   } 

   if (virDomainSaveStatus(driver-caps, driver-stateDir, vm)  0) 
  -goto cleanup; 
  +goto endjob; 

   ret = 0; 

  +endjob: 
  +if (!libxlDomainObjEndJob(driver, vm)) 
  +vm = NULL; 
  + 
   cleanup: 
   if (vm) 
   virDomainObjUnlock(vm); 
  @@ -1768,10 +1789,13 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned 
   
 int flags) 
   goto cleanup; 
   } 

  +if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY)  
  0) 
  +goto cleanup; 
  + 
   if (!virDomainObjIsActive(vm)) { 
   virReportError(VIR_ERR_OPERATION_INVALID, 
  %s, _(Domain is not running)); 
  -goto cleanup; 
  +goto endjob; 
   } 
 
  
 And here. 
  

   priv = vm-privateData; 
  @@ -1779,7 +1803,7 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned  
 int flags) 
   virReportError(VIR_ERR_INTERNAL_ERROR, 
  _(Failed to shutdown domain '%d' with  
 libxenlight), 
  dom-id); 
  -goto cleanup; 
  +goto endjob; 
   } 

   /* vm is marked shutoff (or removed from domains list if not  
 persistent) 
  @@ -1787,6 +1811,10 @@ libxlDomainShutdownFlags(virDomainPtr dom

Re: [libvirt] [PATCH 1/2] Introduce a lock for libxl long-running api

2012-11-02 Thread Bamvor Jian Zhang
Hi, Jim

thanks your reply. 
i have update my patch and resend to the list.
besides, there are two comments from you not modify in my v2 patch. 
see my comments below. 

 Jim Fehlig jfeh...@suse.com wrote: 
 Bamvor Jian Zhang wrote: 
  This patch introduce a lock for protecting the long-running 
  api (save, dump, migration and so on) from the other api 
  which may update the status of the virtual machine. 
 
  
 Hi Bamvor, 
  
 Thanks for the patches and sorry for the delayed response.  I've been 
 traveling quite a bit lately and just got around to reviewing and 
 testing your work. 
  
 Testing so far looks good.  I can save and dump vm's while at the same 
 time list and retrieve info. 
  
 See my comments inline, but did want to raise a more general comment 
 first.  There is a quite a bit of code here borrowed from the qemu 
 driver, which in general is fine since the libxl driver does not need 
 the same locking features as the qemu one.  I'd like to hear the opinion 
 of other libvirt maintainers wrt the duplicated code. 
  
  Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com 
  --- 
   src/libxl/libxl_conf.h   |  58 ++ 
   src/libxl/libxl_driver.c | 446  
 +++ 
   2 files changed, 504 insertions(+) 
  
  diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h 
  index 56bf85c..dab1466 100644 
  --- a/src/libxl/libxl_conf.h 
  +++ b/src/libxl/libxl_conf.h 
  @@ -73,6 +73,62 @@ struct _libxlDriverPrivate { 
   char *saveDir; 
   }; 

  +# define JOB_MASK(job)  (1  (job - 1)) 
  +# define DEFAULT_JOB_MASK   \ 
  +(JOB_MASK(LIBXL_JOB_DESTROY) |  \ 
  + JOB_MASK(LIBXL_JOB_ABORT)) 
  + 
  +/* Jobs which have to be tracked in domain state XML. */ 
  +# define LIBXL_DOMAIN_TRACK_JOBS\ 
  +(JOB_MASK(LIBXL_JOB_DESTROY) |  \ 
  + JOB_MASK(LIBXL_JOB_ASYNC)) 
  + 
  +/* Only 1 job is allowed at any time 
  + * A job includes *all* libxl.so api, even those just querying 
  + * information, not merely actions */ 
  +enum libxlDomainJob { 
  +LIBXL_JOB_NONE = 0,  /* Always set to 0 for easy if (jobActive)  
 conditions */ 
  +LIBXL_JOB_DESTROY,   /* Destroys the domain (cannot be masked out) 
   
 */ 
  +LIBXL_JOB_MODIFY,/* May change state */ 
  +LIBXL_JOB_ABORT, /* Abort current async job */ 
  +LIBXL_JOB_MIGRATION_OP,  /* Operation influencing outgoing migration  
 */ 
  + 
  +/* The following two items must always be the last items before  
 JOB_LAST */ 
  +LIBXL_JOB_ASYNC, /* Asynchronous job */ 
 
  
 There is only one item, so the comment needs updated. 
  
  + 
  +LIBXL_JOB_LAST 
  +}; 
  +VIR_ENUM_DECL(libxlDomainJob) 
  + 
  +/* Async job consists of a series of jobs that may change state.  
 Independent 
  + * jobs that do not change state (and possibly others if explicitly  
 allowed by 
  + * current async job) are allowed to be run even if async job is active. 
  + */ 
  +enum libxlDomainAsyncJob { 
  +LIBXL_ASYNC_JOB_NONE = 0, 
  +LIBXL_ASYNC_JOB_MIGRATION_OUT, 
  +LIBXL_ASYNC_JOB_MIGRATION_IN, 
 
  
 The libxl driver doesn't currently support migration.  These could be 
 added in a patch set implementing migration. 

  +LIBXL_ASYNC_JOB_SAVE, 
  +LIBXL_ASYNC_JOB_DUMP, 
 
  
 IMO, LIBXL_ASYNC_JOB_RESTORE should be added to this list.  I see It is 
 omitted in the qemu driver as well, so perhaps there is a good reason 
 for it? 
i do not know why it is omitted by qemu driver. but for libxl driver, it is
hard to let other operation execution even if it is a async job. because
virDomainObjPtr is used by libxlVmStart, especially by
libxl_domain_create_restore.  
  + 
  +LIBXL_ASYNC_JOB_LAST 
  +}; 
  +VIR_ENUM_DECL(libxlDomainAsyncJob) 
  + 
  +struct libxlDomainJobObj { 
  +virCond cond;   /* Use to coordinate jobs */ 
  +enum libxlDomainJob active; /* Currently running job */ 
  +int owner;  /* Thread which set current job */ 
  + 
  +virCond asyncCond;  /* Use to coordinate with async  
 jobs */ 
  +enum libxlDomainAsyncJob asyncJob;  /* Currently active async job */ 
  +int asyncOwner; /* Thread which set current async  
 job */ 
  +int phase;  /* Job phase (mainly for  
 migrations) */ 
  +unsigned long long mask;/* Jobs allowed during async job  
 */ 
  +unsigned long long start;   /* When the async job started */ 
  +virDomainJobInfo info;  /* Async job progress data */ 
  +}; 
  + 
   typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate; 
   typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr; 
   struct _libxlDomainObjPrivate { 
  @@ -81,6 +137,8 @@ struct _libxlDomainObjPrivate { 
   libxl_waiter *dWaiter; 
   int waiterFD; 
   int eventHdl; 
  + 
  +struct

[libvirt] [PATCH 2/2] Add lock for libxl api

2012-11-02 Thread Bamvor Jian Zhang
Add long-running jobs for save, dump. Add normal job for the
api maybe modify the domain.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
 src/libxl/libxl_driver.c | 219 ++-
 1 file changed, 158 insertions(+), 61 deletions(-)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 05944ef..e87b71c 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1507,9 +1507,13 @@ libxlDomainCreateXML(virConnectPtr conn, const char *xml,
 goto cleanup;
 def = NULL;
 
+if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY)  0)
+goto cleanup;
+
 if (libxlVmStart(driver, vm, (flags  VIR_DOMAIN_START_PAUSED) != 0,
  -1)  0) {
-virDomainRemoveInactive(driver-domains, vm);
+if (libxlDomainObjEndJob(driver, vm))
+virDomainRemoveInactive(driver-domains, vm);
 vm = NULL;
 goto cleanup;
 }
@@ -1518,6 +1522,8 @@ libxlDomainCreateXML(virConnectPtr conn, const char *xml,
 if (dom)
 dom-id = vm-def-id;
 
+if (!libxlDomainObjEndJob(driver, vm))
+vm = NULL;
 cleanup:
 virDomainDefFree(def);
 if (vm)
@@ -1624,9 +1630,13 @@ libxlDomainSuspend(virDomainPtr dom)
_(No domain with matching uuid '%s'), uuidstr);
 goto cleanup;
 }
+
+if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY)  0)
+goto cleanup;
+
 if (!virDomainObjIsActive(vm)) {
 virReportError(VIR_ERR_OPERATION_INVALID, %s, _(Domain is not 
running));
-goto cleanup;
+goto endjob;
 }
 
 priv = vm-privateData;
@@ -1636,7 +1646,7 @@ libxlDomainSuspend(virDomainPtr dom)
 virReportError(VIR_ERR_INTERNAL_ERROR,
_(Failed to suspend domain '%d' with libxenlight),
dom-id);
-goto cleanup;
+goto endjob;
 }
 
 virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER);
@@ -1646,10 +1656,14 @@ libxlDomainSuspend(virDomainPtr dom)
 }
 
 if (virDomainSaveStatus(driver-caps, driver-stateDir, vm)  0)
-goto cleanup;
+goto endjob;
 
 ret = 0;
 
+endjob:
+if (!libxlDomainObjEndJob(driver, vm))
+vm = NULL;
+
 cleanup:
 if (vm)
 virDomainObjUnlock(vm);
@@ -1683,9 +1697,12 @@ libxlDomainResume(virDomainPtr dom)
 goto cleanup;
 }
 
+if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY)  0)
+goto cleanup;
+
 if (!virDomainObjIsActive(vm)) {
 virReportError(VIR_ERR_OPERATION_INVALID, %s, _(Domain is not 
running));
-goto cleanup;
+goto endjob;
 }
 
 priv = vm-privateData;
@@ -1695,7 +1712,7 @@ libxlDomainResume(virDomainPtr dom)
 virReportError(VIR_ERR_INTERNAL_ERROR,
_(Failed to resume domain '%d' with libxenlight),
dom-id);
-goto cleanup;
+goto endjob;
 }
 
 virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
@@ -1706,10 +1723,14 @@ libxlDomainResume(virDomainPtr dom)
 }
 
 if (virDomainSaveStatus(driver-caps, driver-stateDir, vm)  0)
-goto cleanup;
+goto endjob;
 
 ret = 0;
 
+endjob:
+if (!libxlDomainObjEndJob(driver, vm))
+vm = NULL;
+
 cleanup:
 if (vm)
 virDomainObjUnlock(vm);
@@ -1741,10 +1762,13 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int 
flags)
 goto cleanup;
 }
 
+if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY)  0)
+goto cleanup;
+
 if (!virDomainObjIsActive(vm)) {
 virReportError(VIR_ERR_OPERATION_INVALID,
%s, _(Domain is not running));
-goto cleanup;
+goto endjob;
 }
 
 priv = vm-privateData;
@@ -1752,7 +1776,7 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int 
flags)
 virReportError(VIR_ERR_INTERNAL_ERROR,
_(Failed to shutdown domain '%d' with libxenlight),
dom-id);
-goto cleanup;
+goto endjob;
 }
 
 /* vm is marked shutoff (or removed from domains list if not persistent)
@@ -1760,6 +1784,10 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int 
flags)
  */
 ret = 0;
 
+endjob:
+if (!libxlDomainObjEndJob(driver, vm))
+vm = NULL;
+
 cleanup:
 if (vm)
 virDomainObjUnlock(vm);
@@ -1794,10 +1822,13 @@ libxlDomainReboot(virDomainPtr dom, unsigned int flags)
 goto cleanup;
 }
 
+if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY)  0)
+goto cleanup;
+
 if (!virDomainObjIsActive(vm)) {
 virReportError(VIR_ERR_OPERATION_INVALID,
%s, _(Domain is not running));
-goto cleanup;
+goto endjob;
 }
 
 priv = vm-privateData;
@@ -1805,10 +1836,14 @@ libxlDomainReboot(virDomainPtr dom

[libvirt] [PATCH 0/2] Add lock in libxl

2012-11-02 Thread Bamvor Jian Zhang
These two patches implement a lock for long-running
job(save, dump and migration) and normal job which will
return in short time but maybe affect the state of virtual
machine.

With these patches, the normal job could not execute while
the long-ruuning job or other normal job is running.

In order to tracking these job, job type for normal job and
long-ruuning job(will be called as async job in code) is
defined.

The abort job is called while user want to cancel such async
job. Note that there is no cancellation function for async
job in xenlight stack. So, abort function just block the
cancellation of user.

Update compare to v1:
1, remove migration relative job functions from lock patch.
2, update comments according to upstream's comments.

Bamvor Jian Zhang (2):
  Introduce a lock for libxl long-running api
  Add lock for libxl api

 src/libxl/libxl_conf.h   |  56 +
 src/libxl/libxl_driver.c | 638 ++-
 2 files changed, 633 insertions(+), 61 deletions(-)

-- 
1.7.12

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 1/2] Introduce a lock for libxl long-running api

2012-11-02 Thread Bamvor Jian Zhang
This patch introduce a lock for protecting the long-running
api (save, dump, migration and so on) from the other api
which may update the status of the virtual machine.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
 src/libxl/libxl_conf.h   |  56 +++
 src/libxl/libxl_driver.c | 419 +++
 2 files changed, 475 insertions(+)

diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index 56bf85c..95a3418 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -73,6 +73,60 @@ struct _libxlDriverPrivate {
 char *saveDir;
 };
 
+# define JOB_MASK(job)  (1  (job - 1))
+# define DEFAULT_JOB_MASK   \
+(JOB_MASK(LIBXL_JOB_DESTROY) |  \
+ JOB_MASK(LIBXL_JOB_ABORT))
+
+/* Jobs which have to be tracked in domain state XML. */
+# define LIBXL_DOMAIN_TRACK_JOBS\
+(JOB_MASK(LIBXL_JOB_DESTROY) |  \
+ JOB_MASK(LIBXL_JOB_ASYNC))
+
+/* Only 1 job is allowed at any time
+ * A job includes *all* libxl.so api, even those just querying
+ * information, not merely actions */
+enum libxlDomainJob {
+LIBXL_JOB_NONE = 0,  /* Always set to 0 for easy if (jobActive) 
conditions */
+LIBXL_JOB_DESTROY,   /* Destroys the domain (cannot be masked out) */
+LIBXL_JOB_MODIFY,/* May change state */
+LIBXL_JOB_ABORT, /* Abort current async job */
+LIBXL_JOB_MIGRATION_OP,  /* Operation influencing outgoing migration */
+
+/* The following item must always be the last item before JOB_LAST */
+LIBXL_JOB_ASYNC, /* Asynchronous job */
+
+LIBXL_JOB_LAST
+};
+VIR_ENUM_DECL(libxlDomainJob)
+
+/* Async job consists of a series of jobs that may change state. Independent
+ * jobs that do not change state (and possibly others if explicitly allowed by
+ * current async job) are allowed to be run even if async job is active.
+ */
+enum libxlDomainAsyncJob {
+LIBXL_ASYNC_JOB_NONE = 0,
+LIBXL_ASYNC_JOB_SAVE,
+LIBXL_ASYNC_JOB_DUMP,
+
+LIBXL_ASYNC_JOB_LAST
+};
+VIR_ENUM_DECL(libxlDomainAsyncJob)
+
+struct libxlDomainJobObj {
+virCond cond;   /* Use to coordinate jobs */
+enum libxlDomainJob active; /* Currently running job */
+int owner;  /* Thread which set current job */
+
+virCond asyncCond;  /* Use to coordinate with async jobs */
+enum libxlDomainAsyncJob asyncJob;  /* Currently active async job */
+int asyncOwner; /* Thread which set current async job 
*/
+int phase;  /* Job phase (mainly for migrations) */
+unsigned long long mask;/* Jobs allowed during async job */
+unsigned long long start;   /* When the async job started */
+virDomainJobInfo info;  /* Async job progress data */
+};
+
 typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate;
 typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr;
 struct _libxlDomainObjPrivate {
@@ -81,6 +135,8 @@ struct _libxlDomainObjPrivate {
 libxl_waiter *dWaiter;
 int waiterFD;
 int eventHdl;
+
+struct libxlDomainJobObj job;
 };
 
 # define LIBXL_SAVE_MAGIC libvirt-xml\n \0 \r
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index f4e9aa6..05944ef 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -45,6 +45,7 @@
 #include xen_xm.h
 #include virtypedparam.h
 #include viruri.h
+#include virtime.h
 
 #define VIR_FROM_THIS VIR_FROM_LIBXL
 
@@ -84,6 +85,309 @@ libxlDriverUnlock(libxlDriverPrivatePtr driver)
 virMutexUnlock(driver-lock);
 }
 
+/* job */
+VIR_ENUM_IMPL(libxlDomainJob, LIBXL_JOB_LAST,
+  none,
+  destroy,
+  modify,
+  abort,
+  migration operation,
+  none,   /* async job is never stored in job.active */
+);
+
+VIR_ENUM_IMPL(libxlDomainAsyncJob, LIBXL_ASYNC_JOB_LAST,
+  none,
+  save,
+  dump,
+);
+
+static int
+libxlDomainObjInitJob(libxlDomainObjPrivatePtr priv)
+{
+memset(priv-job, 0, sizeof(priv-job));
+
+if (virCondInit(priv-job.cond)  0)
+return -1;
+
+if (virCondInit(priv-job.asyncCond)  0) {
+ignore_value(virCondDestroy(priv-job.cond));
+return -1;
+}
+
+return 0;
+}
+
+static void
+libxlDomainObjResetJob(libxlDomainObjPrivatePtr priv)
+{
+struct libxlDomainJobObj *job = priv-job;
+
+job-active = LIBXL_JOB_NONE;
+job-owner = 0;
+}
+
+static void
+libxlDomainObjResetAsyncJob(libxlDomainObjPrivatePtr priv)
+{
+struct libxlDomainJobObj *job = priv-job;
+
+job-asyncJob = LIBXL_ASYNC_JOB_NONE;
+job-asyncOwner = 0;
+job-phase = 0;
+job-mask = DEFAULT_JOB_MASK;
+job-start = 0;
+memset(job-info, 0, sizeof(job-info));
+}
+
+static void
+libxlDomainObjFreeJob(libxlDomainObjPrivatePtr priv)
+{
+ignore_value(virCondDestroy(priv-job.cond));
+ignore_value

[libvirt] [PATCH 2/2] Add lock in libxl api

2012-10-11 Thread Bamvor Jian Zhang
Add long-running jobs for save, dump. Add normal job for the
api maybe modify the domain.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
 src/libxl/libxl_driver.c | 219 ++-
 1 file changed, 158 insertions(+), 61 deletions(-)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index d01d915..28e50b0 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1534,9 +1534,13 @@ libxlDomainCreateXML(virConnectPtr conn, const char *xml,
 goto cleanup;
 def = NULL;
 
+if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY)  0)
+goto cleanup;
+
 if (libxlVmStart(driver, vm, (flags  VIR_DOMAIN_START_PAUSED) != 0,
  -1)  0) {
-virDomainRemoveInactive(driver-domains, vm);
+if (libxlDomainObjEndJob(driver, vm))
+virDomainRemoveInactive(driver-domains, vm);
 vm = NULL;
 goto cleanup;
 }
@@ -1545,6 +1549,8 @@ libxlDomainCreateXML(virConnectPtr conn, const char *xml,
 if (dom)
 dom-id = vm-def-id;
 
+if (!libxlDomainObjEndJob(driver, vm))
+vm = NULL;
 cleanup:
 virDomainDefFree(def);
 if (vm)
@@ -1651,9 +1657,13 @@ libxlDomainSuspend(virDomainPtr dom)
_(No domain with matching uuid '%s'), uuidstr);
 goto cleanup;
 }
+
+if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY)  0)
+goto cleanup;
+
 if (!virDomainObjIsActive(vm)) {
 virReportError(VIR_ERR_OPERATION_INVALID, %s, _(Domain is not 
running));
-goto cleanup;
+goto endjob;
 }
 
 priv = vm-privateData;
@@ -1663,7 +1673,7 @@ libxlDomainSuspend(virDomainPtr dom)
 virReportError(VIR_ERR_INTERNAL_ERROR,
_(Failed to suspend domain '%d' with libxenlight),
dom-id);
-goto cleanup;
+goto endjob;
 }
 
 virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER);
@@ -1673,10 +1683,14 @@ libxlDomainSuspend(virDomainPtr dom)
 }
 
 if (virDomainSaveStatus(driver-caps, driver-stateDir, vm)  0)
-goto cleanup;
+goto endjob;
 
 ret = 0;
 
+endjob:
+if (!libxlDomainObjEndJob(driver, vm))
+vm = NULL;
+
 cleanup:
 if (vm)
 virDomainObjUnlock(vm);
@@ -1710,9 +1724,12 @@ libxlDomainResume(virDomainPtr dom)
 goto cleanup;
 }
 
+if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY)  0)
+goto cleanup;
+
 if (!virDomainObjIsActive(vm)) {
 virReportError(VIR_ERR_OPERATION_INVALID, %s, _(Domain is not 
running));
-goto cleanup;
+goto endjob;
 }
 
 priv = vm-privateData;
@@ -1722,7 +1739,7 @@ libxlDomainResume(virDomainPtr dom)
 virReportError(VIR_ERR_INTERNAL_ERROR,
_(Failed to resume domain '%d' with libxenlight),
dom-id);
-goto cleanup;
+goto endjob;
 }
 
 virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
@@ -1733,10 +1750,14 @@ libxlDomainResume(virDomainPtr dom)
 }
 
 if (virDomainSaveStatus(driver-caps, driver-stateDir, vm)  0)
-goto cleanup;
+goto endjob;
 
 ret = 0;
 
+endjob:
+if (!libxlDomainObjEndJob(driver, vm))
+vm = NULL;
+
 cleanup:
 if (vm)
 virDomainObjUnlock(vm);
@@ -1768,10 +1789,13 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int 
flags)
 goto cleanup;
 }
 
+if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY)  0)
+goto cleanup;
+
 if (!virDomainObjIsActive(vm)) {
 virReportError(VIR_ERR_OPERATION_INVALID,
%s, _(Domain is not running));
-goto cleanup;
+goto endjob;
 }
 
 priv = vm-privateData;
@@ -1779,7 +1803,7 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int 
flags)
 virReportError(VIR_ERR_INTERNAL_ERROR,
_(Failed to shutdown domain '%d' with libxenlight),
dom-id);
-goto cleanup;
+goto endjob;
 }
 
 /* vm is marked shutoff (or removed from domains list if not persistent)
@@ -1787,6 +1811,10 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int 
flags)
  */
 ret = 0;
 
+endjob:
+if (!libxlDomainObjEndJob(driver, vm))
+vm = NULL;
+
 cleanup:
 if (vm)
 virDomainObjUnlock(vm);
@@ -1821,10 +1849,13 @@ libxlDomainReboot(virDomainPtr dom, unsigned int flags)
 goto cleanup;
 }
 
+if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY)  0)
+goto cleanup;
+
 if (!virDomainObjIsActive(vm)) {
 virReportError(VIR_ERR_OPERATION_INVALID,
%s, _(Domain is not running));
-goto cleanup;
+goto endjob;
 }
 
 priv = vm-privateData;
@@ -1832,10 +1863,14 @@ libxlDomainReboot(virDomainPtr dom

[libvirt] [PATCH 0/2] Add lock in libxl

2012-10-11 Thread Bamvor Jian Zhang
These two patches implement a lock for long-running
job(save, dump and migration) and normal job which will
return in short time but maybe affect the state of virtual
machine.

With these patches, the normal job could not execute while
the long-ruuning job or other normal job is running.

In order to tracking these job, job type for normal job and
long-ruuning job(will be called as async job in code) is
defined.

The abort job is called while user want to cancel such async
job. Note that there is no cancellation function for async
job in xenlight stack. So, abort function just block the
cancellation of user.

Bamvor Jian Zhang (2):
  Introduce a lock for libxl long-running api
  Add lock for libxl api

 src/libxl/libxl_conf.h   |  58 +
 src/libxl/libxl_driver.c | 665 ++-
 2 files changed, 662 insertions(+), 61 deletions(-)

-- 
1.7.12

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 1/2] Introduce a lock for libxl long-running api

2012-10-11 Thread Bamvor Jian Zhang
This patch introduce a lock for protecting the long-running
api (save, dump, migration and so on) from the other api
which may update the status of the virtual machine.

Signed-off-by: Bamvor Jian Zhang bjzh...@suse.com
---
 src/libxl/libxl_conf.h   |  58 ++
 src/libxl/libxl_driver.c | 446 +++
 2 files changed, 504 insertions(+)

diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index 56bf85c..dab1466 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -73,6 +73,62 @@ struct _libxlDriverPrivate {
 char *saveDir;
 };
 
+# define JOB_MASK(job)  (1  (job - 1))
+# define DEFAULT_JOB_MASK   \
+(JOB_MASK(LIBXL_JOB_DESTROY) |  \
+ JOB_MASK(LIBXL_JOB_ABORT))
+
+/* Jobs which have to be tracked in domain state XML. */
+# define LIBXL_DOMAIN_TRACK_JOBS\
+(JOB_MASK(LIBXL_JOB_DESTROY) |  \
+ JOB_MASK(LIBXL_JOB_ASYNC))
+
+/* Only 1 job is allowed at any time
+ * A job includes *all* libxl.so api, even those just querying
+ * information, not merely actions */
+enum libxlDomainJob {
+LIBXL_JOB_NONE = 0,  /* Always set to 0 for easy if (jobActive) 
conditions */
+LIBXL_JOB_DESTROY,   /* Destroys the domain (cannot be masked out) */
+LIBXL_JOB_MODIFY,/* May change state */
+LIBXL_JOB_ABORT, /* Abort current async job */
+LIBXL_JOB_MIGRATION_OP,  /* Operation influencing outgoing migration */
+
+/* The following two items must always be the last items before JOB_LAST */
+LIBXL_JOB_ASYNC, /* Asynchronous job */
+
+LIBXL_JOB_LAST
+};
+VIR_ENUM_DECL(libxlDomainJob)
+
+/* Async job consists of a series of jobs that may change state. Independent
+ * jobs that do not change state (and possibly others if explicitly allowed by
+ * current async job) are allowed to be run even if async job is active.
+ */
+enum libxlDomainAsyncJob {
+LIBXL_ASYNC_JOB_NONE = 0,
+LIBXL_ASYNC_JOB_MIGRATION_OUT,
+LIBXL_ASYNC_JOB_MIGRATION_IN,
+LIBXL_ASYNC_JOB_SAVE,
+LIBXL_ASYNC_JOB_DUMP,
+
+LIBXL_ASYNC_JOB_LAST
+};
+VIR_ENUM_DECL(libxlDomainAsyncJob)
+
+struct libxlDomainJobObj {
+virCond cond;   /* Use to coordinate jobs */
+enum libxlDomainJob active; /* Currently running job */
+int owner;  /* Thread which set current job */
+
+virCond asyncCond;  /* Use to coordinate with async jobs */
+enum libxlDomainAsyncJob asyncJob;  /* Currently active async job */
+int asyncOwner; /* Thread which set current async job 
*/
+int phase;  /* Job phase (mainly for migrations) */
+unsigned long long mask;/* Jobs allowed during async job */
+unsigned long long start;   /* When the async job started */
+virDomainJobInfo info;  /* Async job progress data */
+};
+
 typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate;
 typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr;
 struct _libxlDomainObjPrivate {
@@ -81,6 +137,8 @@ struct _libxlDomainObjPrivate {
 libxl_waiter *dWaiter;
 int waiterFD;
 int eventHdl;
+
+struct libxlDomainJobObj job;
 };
 
 # define LIBXL_SAVE_MAGIC libvirt-xml\n \0 \r
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 6fe284f..d01d915 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -45,6 +45,7 @@
 #include xen_xm.h
 #include virtypedparam.h
 #include viruri.h
+#include virtime.h
 
 #define VIR_FROM_THIS VIR_FROM_LIBXL
 
@@ -84,6 +85,336 @@ libxlDriverUnlock(libxlDriverPrivatePtr driver)
 virMutexUnlock(driver-lock);
 }
 
+/* job */
+VIR_ENUM_IMPL(libxlDomainJob, LIBXL_JOB_LAST,
+  none,
+  destroy,
+  modify,
+  abort,
+  migration operation,
+  none,   /* async job is never stored in job.active */
+);
+
+VIR_ENUM_IMPL(libxlDomainAsyncJob, LIBXL_ASYNC_JOB_LAST,
+  none,
+  migration out,
+  migration in,
+  save,
+  dump,
+);
+
+static int
+libxlDomainObjInitJob(libxlDomainObjPrivatePtr priv)
+{
+memset(priv-job, 0, sizeof(priv-job));
+
+if (virCondInit(priv-job.cond)  0)
+return -1;
+
+if (virCondInit(priv-job.asyncCond)  0) {
+ignore_value(virCondDestroy(priv-job.cond));
+return -1;
+}
+
+return 0;
+}
+
+static void
+libxlDomainObjResetJob(libxlDomainObjPrivatePtr priv)
+{
+struct libxlDomainJobObj *job = priv-job;
+
+job-active = LIBXL_JOB_NONE;
+job-owner = 0;
+}
+
+static void
+libxlDomainObjResetAsyncJob(libxlDomainObjPrivatePtr priv)
+{
+struct libxlDomainJobObj *job = priv-job;
+
+job-asyncJob = LIBXL_ASYNC_JOB_NONE;
+job-asyncOwner = 0;
+job-phase = 0;
+job-mask = DEFAULT_JOB_MASK;
+job-start = 0;
+memset(job-info, 0, sizeof(job-info