Re: [libvirt] [PATCH] qemu: Allow domain reboot after core dump

2011-09-23 Thread Sheldon

yes, the patch can work, when I execute virsh dump --reboot domian file

and the type of file is: QEMU's suspend to disk image


  
??: [libvirt] [PATCH] qemu: Allow domain reboot after core dump
??: Tue, 20 Sep 2011 13:34:27 +0200
???:Michal Privoznik mpriv...@redhat.com
???:libvir-list@redhat.com



This patch introduces possibility to reboot domain after core dump
finishes. The new flag VIR_DUMP_REBOOT was added to
virDomainCoreDumpFlags. The new functionality is accessible via virsh
too: virsh dump --rebootdomain
---
  include/libvirt/libvirt.h.in |1 +
  src/qemu/qemu_driver.c   |8 +++-
  tools/virsh.c|3 +++
  3 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 39155a6..8c41f5a 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -748,6 +748,7 @@ typedef enum {
  VIR_DUMP_CRASH= (1  0), /* crash after dump */
  VIR_DUMP_LIVE = (1  1), /* live dump */
  VIR_DUMP_BYPASS_CACHE = (1  2), /* avoid file system cache pollution */
+VIR_DUMP_REBOOT   = (1  3), /* reboot domain after dump finishes */
  } virDomainCoreDumpFlags;

  /* Domain migration flags. */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e2f428f..22576a8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3104,7 +3104,8 @@ static int qemudDomainCoreDump(virDomainPtr dom,
  int ret = -1;
  virDomainEventPtr event = NULL;

-virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH | VIR_DUMP_BYPASS_CACHE, -1);
+virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH |
+  VIR_DUMP_BYPASS_CACHE | VIR_DUMP_REBOOT, -1);

  qemuDriverLock(driver);
  vm = virDomainFindByUUID(driver-domains, dom-uuid);
@@ -3189,6 +3190,11 @@ cleanup:
  if (event)
  qemuDomainEventQueue(driver, event);
  qemuDriverUnlock(driver);
+
+if ((ret == 0)  (flags  VIR_DUMP_REBOOT)) {
+qemuDomainReboot(dom, 0);
+}
+
  return ret;
  }

diff --git a/tools/virsh.c b/tools/virsh.c
index d575425..74f6a79 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2840,6 +2840,7 @@ static const vshCmdOptDef opts_dump[] = {
  {crash, VSH_OT_BOOL, 0, N_(crash the domain after core dump)},
  {bypass-cache, VSH_OT_BOOL, 0,
   N_(avoid file system cache when saving)},
+{reboot, VSH_OT_BOOL, 0, N_(reboot the domain after core dump)},
  {domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id or uuid)},
  {file, VSH_OT_DATA, VSH_OFLAG_REQ, N_(where to dump the core)},
  {NULL, 0, 0, NULL}
@@ -2869,6 +2870,8 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
  flags |= VIR_DUMP_CRASH;
  if (vshCommandOptBool(cmd, bypass-cache))
  flags |= VIR_DUMP_BYPASS_CACHE;
+if (vshCommandOptBool(cmd, reboot))
+flags |= VIR_DUMP_REBOOT;

  if (virDomainCoreDump(dom, to, flags)  0) {
  vshError(ctl, _(Failed to core dump domain %s to %s), name, to);
--
1.7.3.4

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



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

[libvirt] [PATCH v3 2/2] add interface for blkio.weight_device

2011-09-23 Thread Hu Tao
This patch adds a parameter --weight-device to virsh command
blkiotune for setting/getting blkio.weight_device.
---
 daemon/remote.c  |5 +
 include/libvirt/libvirt.h.in |9 ++
 src/conf/domain_conf.c   |  114 -
 src/conf/domain_conf.h   |   16 
 src/libvirt_private.syms |1 +
 src/qemu/qemu_cgroup.c   |   22 +
 src/qemu/qemu_driver.c   |  191 +-
 src/util/cgroup.c|   33 +++
 src/util/cgroup.h|3 +
 tools/virsh.c|   52 ++--
 tools/virsh.pod  |5 +-
 11 files changed, 437 insertions(+), 14 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 82ee13b..bee1b94 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1566,6 +1566,7 @@ remoteDispatchDomainGetBlkioParameters(virNetServerPtr 
server ATTRIBUTE_UNUSED,
 int nparams = args-nparams;
 unsigned int flags;
 int rv = -1;
+int i;
 struct daemonClientPrivate *priv =
 virNetServerClientGetPrivateData(client);
 
@@ -1610,6 +1611,10 @@ success:
 cleanup:
 if (rv  0)
 virNetMessageSaveError(rerr);
+for (i = 0; i  nparams; i++) {
+if (params[i].type == VIR_TYPED_PARAM_STRING)
+VIR_FREE(params[i].value.s);
+}
 VIR_FREE(params);
 if (dom)
 virDomainFree(dom);
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 448a0e7..a1f2c98 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1139,6 +1139,15 @@ char *  
virDomainGetSchedulerType(virDomainPtr domain,
 
 #define VIR_DOMAIN_BLKIO_WEIGHT weight
 
+/**
+ * VIR_DOMAIN_BLKIO_WEIGHT_DEVICE:
+ *
+ * Macro for the blkio tunable weight_device: it represents the
+ * per device weight.
+ */
+
+#define VIR_DOMAIN_BLKIO_WEIGHT_DEVICE weight_device
+
 /* Set Blkio tunables for the domain*/
 int virDomainSetBlkioParameters(virDomainPtr domain,
 virTypedParameterPtr params,
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7463d7c..75b17cd 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -566,6 +566,82 @@ VIR_ENUM_IMPL(virDomainNumatuneMemMode, 
VIR_DOMAIN_NUMATUNE_MEM_LAST,
 #define VIR_DOMAIN_XML_WRITE_FLAGS  VIR_DOMAIN_XML_SECURE
 #define VIR_DOMAIN_XML_READ_FLAGS   VIR_DOMAIN_XML_INACTIVE
 
+/**
+ * virBlkioWeightDeviceToStr:
+ *
+ * This function returns a string representing device weights that is
+ * suitable for writing to /cgroup/blkio/blkio.weight_device, given
+ * a list of weight devices.
+ */
+int virBlkioWeightDeviceToStr(virBlkioWeightDevicePtr weightdevices,
+  int ndevices,
+  char **result)
+{
+int i;
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+for (i = 0; i  ndevices; i++) {
+virBufferAsprintf(buf, %d:%d %d\n,
+  weightdevices[i].major,
+  weightdevices[i].minor,
+  weightdevices[i].weight);
+}
+
+*result = virBufferContentAndReset(buf);
+return 0;
+}
+
+/**
+ * virDomainBlkioWeightDeviceParseXML
+ *
+ * this function parses a XML node:
+ *
+ *   device
+ * path/fully/qulaified/device/path/path
+ * weightweight/weight
+ *   /device
+ *
+ * and fills a virBlkioWeightDevice struct.
+ */
+static int virDomainBlkioWeightDeviceParseXML(xmlNodePtr root,
+  virBlkioWeightDevicePtr dw)
+{
+char *c;
+struct stat s;
+xmlNodePtr node;
+
+if (!dw)
+return -1;
+
+node = root-children;
+while (node) {
+if (node-type == XML_ELEMENT_NODE) {
+if (xmlStrEqual(node-name, BAD_CAST path)) {
+c = (char *)xmlNodeGetContent(node);
+if (!c)
+return -1;
+if (stat(c, s) == -1)
+return -1;
+if ((s.st_mode  S_IFMT) == S_IFBLK) {
+dw-major = major(s.st_rdev);
+dw-minor = minor(s.st_rdev);
+} else
+return -1;
+dw-path = (char *)xmlNodeGetContent(node);
+} else if (xmlStrEqual(node-name, BAD_CAST weight)) {
+c = (char *)xmlNodeGetContent(node);
+dw-weight = atoi(c);
+VIR_FREE(c);
+}
+}
+node = node-next;
+}
+
+return 0;
+}
+
+
+
 static void
 virDomainObjListDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
 {
@@ -1230,6 +1306,8 @@ void virDomainDefFree(virDomainDefPtr def)
 VIR_FREE(def-emulator);
 VIR_FREE(def-description);
 
+VIR_FREE(def-blkio.weight_devices);
+
 virDomainWatchdogDefFree(def-watchdog);
 
 virDomainMemballoonDefFree(def-memballoon);
@@ -6464,6 +6542,20 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr 
caps,
 

[libvirt] [PATCH v3 1/2] Add VIR_TYPED_PARAM_STRING

2011-09-23 Thread Hu Tao
This makes string can be transported between client and server.
For compatibility,

o new server should not send strings to old client if it
  doesn't see the flag VIR_DOMAIN_TYPED_STRING_OKAY.
o new client that wants to be able to send/receive strings
  should always set the flag VIR_DOMAIN_TYPED_STRING_OKAY;
  if it is rejected by a old server that doesn't understand
  VIR_DOMAIN_TYPED_STRING_OKAY, then the client should have
  a second try with out flag VIR_DOMAIN_TYPED_STRING_OKAY
  to cope with an old server.

Ideas of compatibility are coming from Eric, thanks.
---
 daemon/remote.c  |   17 +
 include/libvirt/libvirt.h.in |5 -
 src/remote/remote_driver.c   |   17 +
 src/remote/remote_protocol.x |2 ++
 src/remote_protocol-structs  |2 ++
 5 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 245d41c..82ee13b 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -672,6 +672,15 @@ remoteSerializeTypedParameters(virTypedParameterPtr params,
 case VIR_TYPED_PARAM_BOOLEAN:
 val[i].value.remote_typed_param_value_u.b = params[i].value.b;
 break;
+case VIR_TYPED_PARAM_STRING:
+if (params[i].value.s) {
+val[i].value.remote_typed_param_value_u.s = 
strdup(params[i].value.s);
+if (val[i].value.remote_typed_param_value_u.s == NULL) {
+virReportOOMError();
+goto cleanup;
+}
+}
+break;
 default:
 virNetError(VIR_ERR_RPC, _(unknown parameter type: %d),
 params[i].type);
@@ -750,6 +759,14 @@ remoteDeserializeTypedParameters(remote_typed_param 
*args_params_val,
 params[i].value.b =
 args_params_val[i].value.remote_typed_param_value_u.b;
 break;
+case VIR_TYPED_PARAM_STRING:
+params[i].value.s =
+strdup(args_params_val[i].value.remote_typed_param_value_u.s);
+if (params[i].value.s == NULL) {
+virReportOOMError();
+goto cleanup;
+}
+break;
 default:
 virNetError(VIR_ERR_INTERNAL_ERROR, _(unknown parameter type: 
%d),
 params[i].type);
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 39155a6..448a0e7 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -205,6 +205,7 @@ typedef enum {
 VIR_DOMAIN_AFFECT_CURRENT = 0,  /* Affect current domain state.  */
 VIR_DOMAIN_AFFECT_LIVE= 1  0, /* Affect running domain state.  */
 VIR_DOMAIN_AFFECT_CONFIG  = 1  1, /* Affect persistent domain state.  */
+VIR_DOMAIN_TYPED_STRING_OKAY = 1  2,
 } virDomainModificationImpact;
 
 /**
@@ -489,7 +490,8 @@ typedef enum {
 VIR_TYPED_PARAM_LLONG   = 3, /* long long case */
 VIR_TYPED_PARAM_ULLONG  = 4, /* unsigned long long case */
 VIR_TYPED_PARAM_DOUBLE  = 5, /* double case */
-VIR_TYPED_PARAM_BOOLEAN = 6  /* boolean(character) case */
+VIR_TYPED_PARAM_BOOLEAN = 6, /* boolean(character) case */
+VIR_TYPED_PARAM_STRING  = 7  /* string case */
 } virTypedParameterType;
 
 /**
@@ -520,6 +522,7 @@ struct _virTypedParameter {
 unsigned long long int ul;  /* type is ULLONG */
 double d;   /* type is DOUBLE */
 char b; /* type is BOOLEAN */
+char *s;/* type is STRING */
 } value; /* parameter value */
 };
 
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 1217d94..85eaeea 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1276,6 +1276,15 @@ remoteSerializeTypedParameters(virTypedParameterPtr 
params,
 case VIR_TYPED_PARAM_BOOLEAN:
 val[i].value.remote_typed_param_value_u.b = params[i].value.b;
 break;
+case VIR_TYPED_PARAM_STRING:
+if (params[i].value.s) {
+val[i].value.remote_typed_param_value_u.s = 
strdup(params[i].value.s);
+if (val[i].value.remote_typed_param_value_u.s == NULL) {
+virReportOOMError();
+goto cleanup;
+}
+}
+break;
 default:
 remoteError(VIR_ERR_RPC, _(unknown parameter type: %d),
 params[i].type);
@@ -1347,6 +1356,14 @@ remoteDeserializeTypedParameters(remote_typed_param 
*ret_params_val,
 params[i].value.b =
 ret_params_val[i].value.remote_typed_param_value_u.b;
 break;
+case VIR_TYPED_PARAM_STRING:
+params[i].value.s =
+strdup(ret_params_val[i].value.remote_typed_param_value_u.s);
+if (params[i].value.s == NULL) {
+virReportOOMError();
+goto 

[libvirt] [PATCH v3 0/2] add blkio.weight_device support

2011-09-23 Thread Hu Tao
This series adds support for blkio.weight_device.

changes from v2:

- fix the compatibility issue of TYPED_STRING with old clients
  and old servers
- modify XML format for weight_device as danp suggested


Hu Tao (2):
  Add VIR_TYPED_PARAM_STRING
  add interface for blkio.weight_device

 daemon/remote.c  |   22 +
 include/libvirt/libvirt.h.in |   14 +++-
 src/conf/domain_conf.c   |  114 -
 src/conf/domain_conf.h   |   16 
 src/libvirt_private.syms |1 +
 src/qemu/qemu_cgroup.c   |   22 +
 src/qemu/qemu_driver.c   |  191 +-
 src/remote/remote_driver.c   |   17 
 src/remote/remote_protocol.x |2 +
 src/remote_protocol-structs  |2 +
 src/util/cgroup.c|   33 +++
 src/util/cgroup.h|3 +
 tools/virsh.c|   52 ++--
 tools/virsh.pod  |5 +-
 14 files changed, 479 insertions(+), 15 deletions(-)

-- 
1.7.3.1

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


[libvirt] [RFC PATCH] Prevent defining a domain has disk used by other domain

2011-09-23 Thread Osier Yang
$subject + If the disk is shared and readonly.

If the disk is not shared or readonly, the later started domain
will relabel the disk, thus the first domain will lose the permission
to write to the disk and be corrupt.

--
I'm not sure if it's the design to allow multiple domains use
same disk not shared and readonly. So this patch just gives a
demo of the implementation (it skips the checking of nbd disk,
and only changes qemu driver), to see whether if the pricinple
is right or not.
---
 src/conf/domain_conf.c   |   34 ++
 src/conf/domain_conf.h   |2 ++
 src/libvirt_private.syms |1 +
 src/qemu/qemu_driver.c   |   24 
 4 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7463d7c..b64450b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -655,6 +655,40 @@ virDomainObjPtr virDomainFindByName(const 
virDomainObjListPtr doms,
 return obj;
 }
 
+static int
+virDomainObjListSearchDiskPath(const void *payload,
+   const void *name ATTRIBUTE_UNUSED,
+   const void *data)
+{
+virDomainObjPtr obj = (virDomainObjPtr)payload;
+int i;
+int want = 0;
+const char *path = NULL;
+
+path = (const char *)data;
+
+virDomainObjLock(obj);
+for (i = 0; obj-def-ndisks; i++) {
+if (STREQ(obj-def-disks[i]-src, path)) {
+want = 1;
+break;
+}
+}
+virDomainObjUnlock(obj);
+
+return want;
+}
+
+virDomainObjPtr
+virDomainFindByDiskPath(const virDomainObjListPtr doms,
+const char *path)
+{
+virDomainObjPtr obj = NULL;
+obj = virHashSearch(doms-objs, virDomainObjListSearchDiskPath, path);
+if (obj)
+virDomainObjLock(obj);
+return obj;
+}
 
 bool virDomainObjTaint(virDomainObjPtr obj,
enum virDomainTaintFlags taint)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 371f270..d7d42dd 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1549,6 +1549,8 @@ virDomainObjPtr virDomainFindByUUID(const 
virDomainObjListPtr doms,
 const unsigned char *uuid);
 virDomainObjPtr virDomainFindByName(const virDomainObjListPtr doms,
 const char *name);
+virDomainObjPtr virDomainFindByDiskPath(const virDomainObjListPtr doms,
+const char *path);
 
 bool virDomainObjTaint(virDomainObjPtr obj,
enum virDomainTaintFlags taint);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8235ea1..c33cb2d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -302,6 +302,7 @@ virDomainFSTypeToString;
 virDomainFindByID;
 virDomainFindByName;
 virDomainFindByUUID;
+virDomainFindByDiskPath;
 virDomainGetRootFilesystem;
 virDomainGraphicsAuthConnectedTypeFromString;
 virDomainGraphicsAuthConnectedTypeToString;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0d0bea2..a448a0b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4796,6 +4796,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, 
const char *xml) {
 virDomainPtr dom = NULL;
 virDomainEventPtr event = NULL;
 int dupVM;
+int i;
 
 qemuDriverLock(driver);
 if (!(def = virDomainDefParseString(driver-caps, xml,
@@ -4809,6 +4810,29 @@ static virDomainPtr qemudDomainDefine(virConnectPtr 
conn, const char *xml) {
 if ((dupVM = virDomainObjIsDuplicate(driver-domains, def, 0))  0)
 goto cleanup;
 
+/* Make sure no disk is used by other domain, if it's not
+ * either shareable or readonly.
+ */
+for (i = 0; i  def-ndisks; i++) {
+/* XXX: Do we also need to check if same hostport is used by
+ * other domain for disk of nbd type?
+ */
+if (def-disks[i]-type == VIR_DOMAIN_DISK_TYPE_NETWORK 
+def-disks[i]-protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)
+continue;
+
+if (!def-disks[i]-shared 
+!def-disks[i]-readonly 
+(vm = virDomainFindByDiskPath(driver-domains,
+  def-disks[i]-src))) {
+qemuReportError(VIR_ERR_INVALID_ARG,
+_(disk '%s' already used by domain '%s'),
+def-disks[i]-src,
+vm-def-name);
+goto cleanup;
+}
+}
+
 if (qemudCanonicalizeMachine(driver, def)  0)
 goto cleanup;
 
-- 
1.7.6

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


Re: [libvirt] [RFC PATCH] Prevent defining a domain has disk used by other domain

2011-09-23 Thread Daniel P. Berrange
On Fri, Sep 23, 2011 at 03:59:04PM +0800, Osier Yang wrote:
 $subject + If the disk is shared and readonly.
 
 If the disk is not shared or readonly, the later started domain
 will relabel the disk, thus the first domain will lose the permission
 to write to the disk and be corrupt.
 
 --
 I'm not sure if it's the design to allow multiple domains use
 same disk not shared and readonly. So this patch just gives a
 demo of the implementation (it skips the checking of nbd disk,
 and only changes qemu driver), to see whether if the pricinple
 is right or not.
 ---
  src/conf/domain_conf.c   |   34 ++
  src/conf/domain_conf.h   |2 ++
  src/libvirt_private.syms |1 +
  src/qemu/qemu_driver.c   |   24 
  4 files changed, 61 insertions(+), 0 deletions(-)

NACK, defining two guests with the same disk is not a bug.
Only *starting* two guests with the same disk is a problem,
and that is what the lock manager code is protecting against.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|

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


Re: [libvirt] [RFC PATCH] Prevent defining a domain has disk used by other domain

2011-09-23 Thread Osier Yang
于 2011年09月23日 15:59, Osier Yang 写道:
 $subject + If the disk is shared and readonly.

s/disk is/disk is not/


 If the disk is not shared or readonly, the later started domain
 will relabel the disk, thus the first domain will lose the permission
 to write to the disk and be corrupt.

 --
 I'm not sure if it's the design to allow multiple domains use
 same disk not shared and readonly. So this patch just gives a
 demo of the implementation (it skips the checking of nbd disk,
 and only changes qemu driver), 

Hmm, preventing the relabeling in security driver instead might be the
more proper way? (If the disk source is used by other *running* domain,
then quit relabeling and exit with error).

However, this won't prevent one using same disk source for multiple domains
if security_driver is disabled.

And if security_driver is disabled, there will be no permission problem, all
the domains can write to the same disk source, thus it might cause
inconsistency
between the domains or corrupt.

 to see whether if the pricinple
 is right or not.
 ---
  src/conf/domain_conf.c   |   34 ++
  src/conf/domain_conf.h   |2 ++
  src/libvirt_private.syms |1 +
  src/qemu/qemu_driver.c   |   24 
  4 files changed, 61 insertions(+), 0 deletions(-)

 diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
 index 7463d7c..b64450b 100644
 --- a/src/conf/domain_conf.c
 +++ b/src/conf/domain_conf.c
 @@ -655,6 +655,40 @@ virDomainObjPtr virDomainFindByName(const 
 virDomainObjListPtr doms,
  return obj;
  }
  
 +static int
 +virDomainObjListSearchDiskPath(const void *payload,
 +   const void *name ATTRIBUTE_UNUSED,
 +   const void *data)
 +{
 +virDomainObjPtr obj = (virDomainObjPtr)payload;
 +int i;
 +int want = 0;
 +const char *path = NULL;
 +
 +path = (const char *)data;
 +
 +virDomainObjLock(obj);
 +for (i = 0; obj-def-ndisks; i++) {
 +if (STREQ(obj-def-disks[i]-src, path)) {
 +want = 1;
 +break;
 +}
 +}
 +virDomainObjUnlock(obj);
 +
 +return want;
 +}
 +
 +virDomainObjPtr
 +virDomainFindByDiskPath(const virDomainObjListPtr doms,
 +const char *path)
 +{
 +virDomainObjPtr obj = NULL;
 +obj = virHashSearch(doms-objs, virDomainObjListSearchDiskPath, path);
 +if (obj)
 +virDomainObjLock(obj);
 +return obj;
 +}
  
  bool virDomainObjTaint(virDomainObjPtr obj,
 enum virDomainTaintFlags taint)
 diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
 index 371f270..d7d42dd 100644
 --- a/src/conf/domain_conf.h
 +++ b/src/conf/domain_conf.h
 @@ -1549,6 +1549,8 @@ virDomainObjPtr virDomainFindByUUID(const 
 virDomainObjListPtr doms,
  const unsigned char *uuid);
  virDomainObjPtr virDomainFindByName(const virDomainObjListPtr doms,
  const char *name);
 +virDomainObjPtr virDomainFindByDiskPath(const virDomainObjListPtr doms,
 +const char *path);
  
  bool virDomainObjTaint(virDomainObjPtr obj,
 enum virDomainTaintFlags taint);
 diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
 index 8235ea1..c33cb2d 100644
 --- a/src/libvirt_private.syms
 +++ b/src/libvirt_private.syms
 @@ -302,6 +302,7 @@ virDomainFSTypeToString;
  virDomainFindByID;
  virDomainFindByName;
  virDomainFindByUUID;
 +virDomainFindByDiskPath;
  virDomainGetRootFilesystem;
  virDomainGraphicsAuthConnectedTypeFromString;
  virDomainGraphicsAuthConnectedTypeToString;
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index 0d0bea2..a448a0b 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -4796,6 +4796,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr 
 conn, const char *xml) {
  virDomainPtr dom = NULL;
  virDomainEventPtr event = NULL;
  int dupVM;
 +int i;
  
  qemuDriverLock(driver);
  if (!(def = virDomainDefParseString(driver-caps, xml,
 @@ -4809,6 +4810,29 @@ static virDomainPtr qemudDomainDefine(virConnectPtr 
 conn, const char *xml) {
  if ((dupVM = virDomainObjIsDuplicate(driver-domains, def, 0))  0)
  goto cleanup;
  
 +/* Make sure no disk is used by other domain, if it's not
 + * either shareable or readonly.
 + */
 +for (i = 0; i  def-ndisks; i++) {
 +/* XXX: Do we also need to check if same hostport is used by
 + * other domain for disk of nbd type?
 + */
 +if (def-disks[i]-type == VIR_DOMAIN_DISK_TYPE_NETWORK 
 +def-disks[i]-protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)
 +continue;
 +
 +if (!def-disks[i]-shared 
 +!def-disks[i]-readonly 
 +(vm = virDomainFindByDiskPath(driver-domains,
 +  def-disks[i]-src))
 ) {
 +  

[libvirt] [PATCH v2 12/12] qemu: Cancel p2p migration when connection breaks

2011-09-23 Thread Jiri Denemark
If a connection to destination host is lost during peer-to-peer
migration (because keepalive protocol timed out), we won't be able to
finish the migration and it doesn't make sense to wait for qemu to
transmit all data. This patch automatically cancels such migration
without waiting for virDomainAbortJob to be called.
---
 src/qemu/qemu_migration.c |   39 +--
 1 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 301d8ba..fb3b411 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -901,7 +901,8 @@ qemuMigrationUpdateJobStatus(struct qemud_driver *driver,
 
 static int
 qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm,
-   enum qemuDomainAsyncJob asyncJob)
+   enum qemuDomainAsyncJob asyncJob,
+   virConnectPtr dconn)
 {
 qemuDomainObjPrivatePtr priv = vm-privateData;
 const char *job;
@@ -929,6 +930,12 @@ qemuMigrationWaitForCompletion(struct qemud_driver 
*driver, virDomainObjPtr vm,
 if (qemuMigrationUpdateJobStatus(driver, vm, job, asyncJob)  0)
 goto cleanup;
 
+if (dconn  virConnectIsAlive(dconn) = 0) {
+qemuReportError(VIR_ERR_OPERATION_FAILED, %s,
+_(Lost connection to destination host));
+goto cleanup;
+}
+
 virDomainObjUnlock(vm);
 qemuDriverUnlock(driver);
 
@@ -1491,7 +1498,8 @@ qemuMigrationRun(struct qemud_driver *driver,
  int *cookieoutlen,
  unsigned long flags,
  unsigned long resource,
- qemuMigrationSpecPtr spec)
+ qemuMigrationSpecPtr spec,
+ virConnectPtr dconn)
 {
 int ret = -1;
 unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND;
@@ -1610,7 +1618,8 @@ qemuMigrationRun(struct qemud_driver *driver,
 goto cancel;
 
 if (qemuMigrationWaitForCompletion(driver, vm,
-   QEMU_ASYNC_JOB_MIGRATION_OUT)  0)
+   QEMU_ASYNC_JOB_MIGRATION_OUT,
+   dconn)  0)
 goto cleanup;
 
 /* When migration completed, QEMU will have paused the
@@ -1667,7 +1676,8 @@ static int doNativeMigrate(struct qemud_driver *driver,
char **cookieout,
int *cookieoutlen,
unsigned long flags,
-   unsigned long resource)
+   unsigned long resource,
+   virConnectPtr dconn)
 {
 qemuDomainObjPrivatePtr priv = vm-privateData;
 xmlURIPtr uribits = NULL;
@@ -1725,7 +1735,7 @@ static int doNativeMigrate(struct qemud_driver *driver,
 }
 
 ret = qemuMigrationRun(driver, vm, cookiein, cookieinlen, cookieout,
-   cookieoutlen, flags, resource, spec);
+   cookieoutlen, flags, resource, spec, dconn);
 
 cleanup:
 if (spec.destType == MIGRATION_DEST_FD)
@@ -1746,7 +1756,8 @@ static int doTunnelMigrate(struct qemud_driver *driver,
char **cookieout,
int *cookieoutlen,
unsigned long flags,
-   unsigned long resource)
+   unsigned long resource,
+   virConnectPtr dconn)
 {
 qemuDomainObjPrivatePtr priv = vm-privateData;
 virNetSocketPtr sock = NULL;
@@ -1809,7 +1820,7 @@ static int doTunnelMigrate(struct qemud_driver *driver,
 }
 
 ret = qemuMigrationRun(driver, vm, cookiein, cookieinlen, cookieout,
-   cookieoutlen, flags, resource, spec);
+   cookieoutlen, flags, resource, spec, dconn);
 
 cleanup:
 if (spec.destType == MIGRATION_DEST_FD) {
@@ -1912,12 +1923,12 @@ static int doPeer2PeerMigrate2(struct qemud_driver 
*driver,
 if (flags  VIR_MIGRATE_TUNNELLED)
 ret = doTunnelMigrate(driver, vm, st,
   NULL, 0, NULL, NULL,
-  flags, resource);
+  flags, resource, dconn);
 else
 ret = doNativeMigrate(driver, vm, uri_out,
   cookie, cookielen,
   NULL, NULL, /* No out cookie with v2 migration */
-  flags, resource);
+  flags, resource, dconn);
 
 /* Perform failed. Make sure Finish doesn't overwrite the error */
 if (ret  0)
@@ -2058,12 +2069,12 @@ static int doPeer2PeerMigrate3(struct qemud_driver 
*driver,
 ret = doTunnelMigrate(driver, vm, st,
   cookiein, cookieinlen,
   cookieout, cookieoutlen,
-  

[libvirt] [PATCH v2 02/12] Implement common keepalive handling

2011-09-23 Thread Jiri Denemark
These APIs are used by both client and server RPC layer to handle
processing of keepalive messages.
---
 po/POTFILES.in |1 +
 src/Makefile.am|3 +-
 src/rpc/virkeepalive.c |  464 
 src/rpc/virkeepalive.h |   58 ++
 4 files changed, 525 insertions(+), 1 deletions(-)
 create mode 100644 src/rpc/virkeepalive.c
 create mode 100644 src/rpc/virkeepalive.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5ce35ae..71254dd 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -72,6 +72,7 @@ src/qemu/qemu_monitor_text.c
 src/qemu/qemu_process.c
 src/remote/remote_client_bodies.h
 src/remote/remote_driver.c
+src/rpc/virkeepalive.c
 src/rpc/virnetclient.c
 src/rpc/virnetclientprogram.c
 src/rpc/virnetclientstream.c
diff --git a/src/Makefile.am b/src/Makefile.am
index ff890e1..d983d28 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1326,7 +1326,8 @@ libvirt_net_rpc_la_SOURCES = \
rpc/virnetprotocol.h rpc/virnetprotocol.c \
rpc/virnetsocket.h rpc/virnetsocket.c \
rpc/virnettlscontext.h rpc/virnettlscontext.c \
-   rpc/virkeepaliveprotocol.h rpc/virkeepaliveprotocol.c
+   rpc/virkeepaliveprotocol.h rpc/virkeepaliveprotocol.c \
+   rpc/virkeepalive.h rpc/virkeepalive.c
 if HAVE_SASL
 libvirt_net_rpc_la_SOURCES += \
rpc/virnetsaslcontext.h rpc/virnetsaslcontext.c
diff --git a/src/rpc/virkeepalive.c b/src/rpc/virkeepalive.c
new file mode 100644
index 000..5536b61
--- /dev/null
+++ b/src/rpc/virkeepalive.c
@@ -0,0 +1,464 @@
+/*
+ * virkeepalive.c: keepalive handling
+ *
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Jiri Denemark jdene...@redhat.com
+ */
+
+#include config.h
+
+#include memory.h
+#include threads.h
+#include virfile.h
+#include logging.h
+#include util.h
+#include virterror_internal.h
+#include virnetsocket.h
+#include virkeepaliveprotocol.h
+#include virkeepalive.h
+
+#define VIR_FROM_THIS VIR_FROM_RPC
+#define virNetError(code, ...)\
+virReportErrorHelper(VIR_FROM_THIS, code, __FILE__,   \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
+struct _virKeepAlive {
+int refs;
+virMutex lock;
+
+int interval;
+unsigned int count;
+unsigned int countToDeath;
+time_t lastPacketReceived;
+bool advertised;
+int timer;
+
+virNetMessagePtr response;
+int responseTimer;
+
+virKeepAliveSendFunc sendCB;
+virKeepAliveDeadFunc deadCB;
+virKeepAliveFreeFunc freeCB;
+void *client;
+};
+
+
+static void
+virKeepAliveLock(virKeepAlivePtr ka)
+{
+virMutexLock(ka-lock);
+}
+
+static void
+virKeepAliveUnlock(virKeepAlivePtr ka)
+{
+virMutexUnlock(ka-lock);
+}
+
+
+static virNetMessagePtr
+virKeepAliveMessage(int proc)
+{
+virNetMessagePtr msg;
+
+if (!(msg = virNetMessageNew(false)))
+return NULL;
+
+msg-header.prog = KEEPALIVE_PROGRAM;
+msg-header.vers = KEEPALIVE_VERSION;
+msg-header.type = VIR_NET_MESSAGE;
+msg-header.proc = proc;
+
+if (virNetMessageEncodeHeader(msg)  0 ||
+virNetMessageEncodePayloadEmpty(msg)  0) {
+virNetMessageFree(msg);
+return NULL;
+}
+
+return msg;
+}
+
+
+static int
+virKeepAliveSend(virKeepAlivePtr ka, virNetMessagePtr msg)
+{
+int ret;
+const char *proc;
+void *client = ka-client;
+virKeepAliveSendFunc sendCB = ka-sendCB;
+
+switch (msg-header.proc) {
+case KEEPALIVE_PROC_ADVERTISE:
+proc = advertisement;
+break;
+case KEEPALIVE_PROC_PING:
+proc = request;
+break;
+case KEEPALIVE_PROC_PONG:
+proc = response;
+break;
+}
+
+VIR_DEBUG(Sending keepalive %s to client %p, proc, ka-client);
+
+ka-refs++;
+virKeepAliveUnlock(ka);
+
+if ((ret = sendCB(client, msg))  0) {
+VIR_WARN(Failed to send keepalive %s to client %p, proc, client);
+virNetMessageFree(msg);
+}
+
+virKeepAliveLock(ka);
+ka-refs--;
+
+return ret;
+}
+
+
+int
+virKeepAliveAdvertise(virKeepAlivePtr ka)
+{
+virNetMessagePtr msg;
+int ret = -1;
+
+virKeepAliveLock(ka);
+
+VIR_DEBUG(Advertising keepalive support to client %p, 

[libvirt] [PATCH v2 01/12] Define keepalive protocol

2011-09-23 Thread Jiri Denemark
The keepalive program has three procedures: ADVERTISE, PING, and PONG.
All are used only in asynchronous messages and the sender doesn't wait
for any reply. However, the party which receives PING messages is
supposed to react by sending PONG message the other party, but no
explicit binding between PING and PONG messages is made. ADVERTISE is
sent by a client to indicate it supports keepalive protocol. Server is
not allowed to send any keepalive message until it sees ADVERTISE.
---
 .gitignore |1 +
 src/Makefile.am|   12 +---
 src/rpc/virkeepaliveprotocol.x |8 
 3 files changed, 18 insertions(+), 3 deletions(-)
 create mode 100644 src/rpc/virkeepaliveprotocol.x

diff --git a/.gitignore b/.gitignore
index 41fa50f..3859fab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,6 +65,7 @@
 /src/locking/qemu-sanlock.conf
 /src/remote/*_client_bodies.h
 /src/remote/*_protocol.[ch]
+/src/rpc/virkeepaliveprotocol.[ch]
 /src/rpc/virnetprotocol.[ch]
 /src/util/virkeymaps.h
 /tests/*.log
diff --git a/src/Makefile.am b/src/Makefile.am
index 738ee91..ff890e1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -266,7 +266,8 @@ PDWTAGS = \
 PROTOCOL_STRUCTS = \
$(srcdir)/remote_protocol-structs \
$(srcdir)/qemu_protocol-structs \
-   $(srcdir)/virnetprotocol-structs
+   $(srcdir)/virnetprotocol-structs \
+   $(srcdir)/virkeepaliveprotocol-structs
 if WITH_REMOTE
 # The .o file that pdwtags parses is created as a side effect of running
 # libtool; but from make's perspective we depend on the .lo file.
@@ -274,6 +275,7 @@ $(srcdir)/%_protocol-structs: 
libvirt_driver_remote_la-%_protocol.lo
$(PDWTAGS)
 $(srcdir)/virnetprotocol-structs: libvirt_net_rpc_la-virnetprotocol.lo
$(PDWTAGS)
+$(srcdir)/virkeepaliveprotocol-structs: 
libvirt_net_rpc_la-virkeepaliveprotocol.lo
 else !WITH_REMOTE
 # These generated files must live in git, because they cannot be re-generated
 # when configured --without-remote.
@@ -1307,12 +1309,15 @@ noinst_LTLIBRARIES += \
 
 EXTRA_DIST += \
rpc/virnetprotocol.x \
+   rpc/virkeepaliveprotocol.x \
rpc/gendispatch.pl \
rpc/genprotocol.pl
 
 VIR_NET_RPC_GENERATED = \
$(srcdir)/rpc/virnetprotocol.h \
-   $(srcdir)/rpc/virnetprotocol.c
+   $(srcdir)/rpc/virnetprotocol.c \
+   $(srcdir)/rpc/virkeepaliveprotocol.h \
+   $(srcdir)/rpc/virkeepaliveprotocol.c
 
 BUILT_SOURCES += $(VIR_NET_RPC_GENERATED)
 
@@ -1320,7 +1325,8 @@ libvirt_net_rpc_la_SOURCES = \
rpc/virnetmessage.h rpc/virnetmessage.c \
rpc/virnetprotocol.h rpc/virnetprotocol.c \
rpc/virnetsocket.h rpc/virnetsocket.c \
-   rpc/virnettlscontext.h rpc/virnettlscontext.c
+   rpc/virnettlscontext.h rpc/virnettlscontext.c \
+   rpc/virkeepaliveprotocol.h rpc/virkeepaliveprotocol.c
 if HAVE_SASL
 libvirt_net_rpc_la_SOURCES += \
rpc/virnetsaslcontext.h rpc/virnetsaslcontext.c
diff --git a/src/rpc/virkeepaliveprotocol.x b/src/rpc/virkeepaliveprotocol.x
new file mode 100644
index 000..326ea78
--- /dev/null
+++ b/src/rpc/virkeepaliveprotocol.x
@@ -0,0 +1,8 @@
+const KEEPALIVE_PROGRAM = 0x6b656570;
+const KEEPALIVE_VERSION = 1;
+
+enum keepalive_procedure {
+KEEPALIVE_PROC_ADVERTISE = 1,
+KEEPALIVE_PROC_PING = 2,
+KEEPALIVE_PROC_PONG = 3
+};
-- 
1.7.6.1

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


[libvirt] [PATCH v2 06/12] Add support for async close of client RPC socket

2011-09-23 Thread Jiri Denemark
---
 src/rpc/virnetclient.c |   76 ++--
 1 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 7ea9a27..45b0edb 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -92,9 +92,13 @@ struct _virNetClient {
 
 size_t nstreams;
 virNetClientStreamPtr *streams;
+
+bool wantClose;
 };
 
 
+void virNetClientRequestClose(virNetClientPtr client);
+
 static int virNetClientSendInternal(virNetClientPtr client,
 virNetMessagePtr msg,
 bool expectReply,
@@ -297,12 +301,14 @@ void virNetClientFree(virNetClientPtr client)
 }
 
 
-void virNetClientClose(virNetClientPtr client)
+static void
+virNetClientCloseLocked(virNetClientPtr client)
 {
-if (!client)
+VIR_DEBUG(client=%p, sock=%p, client, client-sock);
+
+if (!client-sock)
 return;
 
-virNetClientLock(client);
 virNetSocketRemoveIOCallback(client-sock);
 virNetSocketFree(client-sock);
 client-sock = NULL;
@@ -312,6 +318,41 @@ void virNetClientClose(virNetClientPtr client)
 virNetSASLSessionFree(client-sasl);
 client-sasl = NULL;
 #endif
+client-wantClose = false;
+}
+
+void virNetClientClose(virNetClientPtr client)
+{
+if (!client)
+return;
+
+virNetClientLock(client);
+virNetClientCloseLocked(client);
+virNetClientUnlock(client);
+}
+
+void
+virNetClientRequestClose(virNetClientPtr client)
+{
+VIR_DEBUG(client=%p, client);
+
+virNetClientLock(client);
+
+/* If there is a thread polling for data on the socket, set wantClose flag
+ * and wake the thread up or just immediately close the socket when no-one
+ * is polling on it.
+ */
+if (client-waitDispatch) {
+char ignore = 1;
+int len = sizeof(ignore);
+
+client-wantClose = true;
+if (safewrite(client-wakeupSendFD, ignore, len) != len)
+VIR_ERROR(_(failed to wake up polling thread));
+} else {
+virNetClientCloseLocked(client);
+}
+
 virNetClientUnlock(client);
 }
 
@@ -856,11 +897,12 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
 int timeout = -1;
 bool discardNonBlocking;
 
-/* If we have existing SASL decoded data we
- * don't want to sleep in the poll(), just
- * check if any other FDs are also ready
+/* If we have existing SASL decoded data we don't want to sleep in
+ * the poll(), just check if any other FDs are also ready.
+ * If the connection is going to be closed, we don't want to sleep in
+ * poll() either.
  */
-if (virNetSocketHasCachedData(client-sock))
+if (virNetSocketHasCachedData(client-sock) || client-wantClose)
 timeout = 0;
 
 fds[0].events = fds[0].revents = 0;
@@ -922,6 +964,11 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
 if (virNetSocketHasCachedData(client-sock))
 fds[0].revents |= POLLIN;
 
+/* If wantClose flag is set, pretend there was an error on the socket
+ */
+if (client-wantClose)
+fds[0].revents = POLLERR;
+
 if (fds[1].revents) {
 VIR_DEBUG(Woken up from poll by other thread);
 if (saferead(client-wakeupReadFD, ignore, sizeof(ignore)) != 
sizeof(ignore)) {
@@ -1041,6 +1088,8 @@ error:
 if (client-waitDispatch) {
 VIR_DEBUG(Passing the buck to %p, client-waitDispatch);
 virCondSignal(client-waitDispatch-cond);
+} else if (client-wantClose) {
+virNetClientCloseLocked(client);
 }
 return -1;
 }
@@ -1182,7 +1231,8 @@ static int virNetClientIO(virNetClientPtr client,
 virResetLastError();
 rv = virNetClientIOEventLoop(client, thiscall);
 
-virNetSocketUpdateIOCallback(client-sock, VIR_EVENT_HANDLE_READABLE);
+if (client-sock)
+virNetSocketUpdateIOCallback(client-sock, VIR_EVENT_HANDLE_READABLE);
 
 if (rv == 0 
 virGetLastError())
@@ -1206,7 +1256,7 @@ void virNetClientIncomingEvent(virNetSocketPtr sock,
 goto done;
 
 /* This should be impossible, but it doesn't hurt to check */
-if (client-waitDispatch)
+if (client-waitDispatch || client-wantClose)
 goto done;
 
 VIR_DEBUG(Event fired %p %d, sock, events);
@@ -1251,6 +1301,12 @@ virNetClientSendInternal(virNetClientPtr client,
 
 virNetClientLock(client);
 
+if (!client-sock || client-wantClose) {
+virNetError(VIR_ERR_INTERNAL_ERROR, %s,
+_(Client socket is closed));
+goto unlock;
+}
+
 /* We don't need call-cond for non-blocking calls since there's no
  * thread to be woken up anyway
  */
@@ -1290,6 +1346,8 @@ cleanup:
 } else {
 VIR_FREE(call);
 }
+
+unlock:
 virNetClientUnlock(client);
 return ret;
 }
-- 
1.7.6.1

--
libvir-list mailing list

[libvirt] [PATCH v2 04/12] Implement keepalive protocol in libvirt daemon

2011-09-23 Thread Jiri Denemark
---
 daemon/libvirtd.aug  |4 +
 daemon/libvirtd.c|   11 
 daemon/libvirtd.conf |   15 +
 daemon/remote.c  |   38 +
 src/remote/remote_protocol.x |2 +-
 src/rpc/virnetserver.c   |   10 +++
 src/rpc/virnetserver.h   |2 +
 src/rpc/virnetserverclient.c |  126 +++---
 src/rpc/virnetserverclient.h |6 ++
 9 files changed, 204 insertions(+), 10 deletions(-)

diff --git a/daemon/libvirtd.aug b/daemon/libvirtd.aug
index ce00db5..6cd3f28 100644
--- a/daemon/libvirtd.aug
+++ b/daemon/libvirtd.aug
@@ -66,6 +66,9 @@ module Libvirtd =
let auditing_entry = int_entry audit_level
   | bool_entry audit_logging
 
+   let keepalive_entry = int_entry keepalive_interval
+   | int_entry keepalive_count
+
(* Each enty in the config is one of the following three ... *)
let entry = network_entry
  | sock_acl_entry
@@ -75,6 +78,7 @@ module Libvirtd =
  | processing_entry
  | logging_entry
  | auditing_entry
+ | keepalive_entry
let comment = [ label #comment . del /#[ \t]*/ #  .  store /([^ 
\t\n][^\n]*)?/ . del /\n/ \n ]
let empty = [ label #empty . eol ]
 
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index d1bc3dd..4ad2b2e 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -146,6 +146,9 @@ struct daemonConfig {
 
 int audit_level;
 int audit_logging;
+
+int keepalive_interval;
+unsigned int keepalive_count;
 };
 
 enum {
@@ -899,6 +902,9 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
 data-audit_level = 1;
 data-audit_logging = 0;
 
+data-keepalive_interval = 5;
+data-keepalive_count = 5;
+
 localhost = virGetHostname(NULL);
 if (localhost == NULL) {
 /* we couldn't resolve the hostname; assume that we are
@@ -1062,6 +1068,9 @@ daemonConfigLoad(struct daemonConfig *data,
 GET_CONF_STR (conf, filename, log_outputs);
 GET_CONF_INT (conf, filename, log_buffer_size);
 
+GET_CONF_INT (conf, filename, keepalive_interval);
+GET_CONF_INT (conf, filename, keepalive_count);
+
 virConfFree (conf);
 return 0;
 
@@ -1452,6 +1461,8 @@ int main(int argc, char **argv) {
 config-max_workers,
 config-prio_workers,
 config-max_clients,
+config-keepalive_interval,
+config-keepalive_count,
 config-mdns_adv ? config-mdns_name : NULL,
 use_polkit_dbus,
 remoteClientInitHook))) {
diff --git a/daemon/libvirtd.conf b/daemon/libvirtd.conf
index da3983e..4f6ab9f 100644
--- a/daemon/libvirtd.conf
+++ b/daemon/libvirtd.conf
@@ -366,3 +366,18 @@
 # it with the output of the 'uuidgen' command and then
 # uncomment this entry
 #host_uuid = ----
+
+###
+# Keepalive protocol:
+# This allows libvirtd to detect broken client connections or even
+# dead client.  A keepalive message is sent to a client after
+# keepalive_interval seconds of inactivity to check if the client is
+# still responding; keepalive_count is a maximum number of keepalive
+# messages that are allowed to be sent to the client without getting
+# any response before the connection is considered broken.  In other
+# words, the connection is automatically closed approximately after
+# keepalive_interval * (keepalive_count + 1) seconds since the last
+# message received from the client.
+#
+#keepalive_interval = 5
+#keepalive_count = 5
diff --git a/daemon/remote.c b/daemon/remote.c
index 245d41c..946bb7e 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -3112,6 +3112,44 @@ cleanup:
 }
 
 
+static int
+remoteDispatchSupportsFeature(virNetServerPtr server ATTRIBUTE_UNUSED,
+  virNetServerClientPtr client,
+  virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+  virNetMessageErrorPtr rerr,
+  remote_supports_feature_args *args,
+  remote_supports_feature_ret *ret)
+{
+int rv = -1;
+int supported;
+struct daemonClientPrivate *priv =
+virNetServerClientGetPrivateData(client);
+
+if (!priv-conn) {
+virNetError(VIR_ERR_INTERNAL_ERROR, %s, _(connection not open));
+goto cleanup;
+}
+
+if (args-feature == VIR_DRV_FEATURE_PROGRAM_KEEPALIVE) {
+supported = 1;
+goto done;
+}
+
+if ((supported = virDrvSupportsFeature(priv-conn, args-feature))  0)
+goto cleanup;
+
+done:
+ret-supported = supported;
+rv = 0;
+
+cleanup:
+if (rv  0)
+virNetMessageSaveError(rerr);
+return rv;
+}
+
+
+
 /*- Helpers. -*/
 

[libvirt] [PATCH v2 00/12] Implement keepalive protocol for libvirt RPC

2011-09-23 Thread Jiri Denemark
This patchset can also be found at

https://gitorious.org/~jirka/libvirt/jirka-staging/commits/keepalive

This allows us to detect broken connections between server and client without
waiting for TCP timeout and dead deamon/client. By default a connection is
considered broken after about 30 seconds of no messages received from remote
party. After that period, the connection is automatically closed.

The main reason for implementing this is that peer-to-peer migration can now be
canceled when a connection between source and target breaks. Although this will
really work only after qemu fixes migrate_cancel command so that it doesn't
block when outgoing TCP buffers are full.

Version 2 adds virConnectIsAlive API and uses it to detect that a connection was
closed as a result of keepalive timeout.

The only patch that was changed in v2 is Add keepalive support into
domain-events examples. All other patches are either new or without any change
from v1.

Jiri Denemark (12):
  Define keepalive protocol
  Implement common keepalive handling
  Introduce two public APIs for keepalive protocol
  Implement keepalive protocol in libvirt daemon
  Add support for non-blocking calls in client RPC
  Add support for async close of client RPC socket
  Implement keepalive protocol in remote driver
  Introduce virConnectIsAlive API
  Implement virConnectIsAlive in all drivers
  Add keepalive support into domain-events examples
  qemu: Add support for keepalive messages during p2p migration
  qemu: Cancel p2p migration when connection breaks

 .gitignore |1 +
 daemon/libvirtd.aug|4 +
 daemon/libvirtd.c  |   11 +
 daemon/libvirtd.conf   |   15 +
 daemon/remote.c|   38 ++
 examples/domain-events/events-c/event-test.c   |   13 +-
 examples/domain-events/events-python/event-test.py |5 +-
 include/libvirt/libvirt.h.in   |6 +
 po/POTFILES.in |1 +
 src/Makefile.am|   13 +-
 src/driver.h   |   12 +
 src/esx/esx_driver.c   |   18 +
 src/hyperv/hyperv_driver.c |   18 +
 src/libvirt.c  |  143 ++
 src/libvirt_internal.h |   10 +-
 src/libvirt_public.syms|7 +
 src/libxl/libxl_driver.c   |8 +
 src/lxc/lxc_driver.c   |7 +
 src/openvz/openvz_driver.c |7 +
 src/phyp/phyp_driver.c |   18 +
 src/qemu/libvirtd_qemu.aug |2 +
 src/qemu/qemu.conf |   16 +
 src/qemu/qemu_conf.c   |   11 +
 src/qemu/qemu_conf.h   |3 +
 src/qemu/qemu_driver.c |6 +
 src/qemu/qemu_migration.c  |   49 ++-
 src/qemu/test_libvirtd_qemu.aug|6 +
 src/remote/remote_driver.c |   48 ++
 src/remote/remote_protocol.x   |2 +-
 src/rpc/virkeepalive.c |  464 
 src/rpc/virkeepalive.h |   58 +++
 src/rpc/virkeepaliveprotocol.x |8 +
 src/rpc/virnetclient.c |  335 --
 src/rpc/virnetclient.h |6 +
 src/rpc/virnetserver.c |   10 +
 src/rpc/virnetserver.h |2 +
 src/rpc/virnetserverclient.c   |  126 +-
 src/rpc/virnetserverclient.h   |6 +
 src/test/test_driver.c |6 +
 src/uml/uml_driver.c   |7 +
 src/vbox/vbox_tmpl.c   |6 +
 src/vmware/vmware_driver.c |7 +
 src/xen/xen_driver.c   |8 +
 src/xenapi/xenapi_driver.c |   12 +
 44 files changed, 1483 insertions(+), 76 deletions(-)
 create mode 100644 src/rpc/virkeepalive.c
 create mode 100644 src/rpc/virkeepalive.h
 create mode 100644 src/rpc/virkeepaliveprotocol.x

-- 
1.7.6.1

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


[libvirt] [PATCH v2 09/12] Implement virConnectIsAlive in all drivers

2011-09-23 Thread Jiri Denemark
---
 src/esx/esx_driver.c   |   18 ++
 src/hyperv/hyperv_driver.c |   18 ++
 src/libxl/libxl_driver.c   |8 
 src/lxc/lxc_driver.c   |7 +++
 src/openvz/openvz_driver.c |7 +++
 src/phyp/phyp_driver.c |   18 ++
 src/qemu/qemu_driver.c |6 ++
 src/remote/remote_driver.c |   18 ++
 src/rpc/virnetclient.c |   14 ++
 src/rpc/virnetclient.h |1 +
 src/test/test_driver.c |6 ++
 src/uml/uml_driver.c   |7 +++
 src/vbox/vbox_tmpl.c   |6 ++
 src/vmware/vmware_driver.c |7 +++
 src/xen/xen_driver.c   |8 
 src/xenapi/xenapi_driver.c |   12 
 16 files changed, 161 insertions(+), 0 deletions(-)

diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index f1102ea..c71f4f8 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -4145,6 +4145,23 @@ esxIsSecure(virConnectPtr conn)
 
 
 static int
+esxIsAlive(virConnectPtr conn)
+{
+esxPrivate *priv = conn-privateData;
+
+/* XXX we should be able to do something better than this is simple, safe,
+ * and good enough for now. In worst case, the function will return true
+ * even though the connection is not alive.
+ */
+if (priv-host)
+return 1;
+else
+return 0;
+}
+
+
+
+static int
 esxDomainIsActive(virDomainPtr domain)
 {
 int result = -1;
@@ -4813,6 +4830,7 @@ static virDriver esxDriver = {
 .domainSnapshotCurrent = esxDomainSnapshotCurrent, /* 0.8.0 */
 .domainRevertToSnapshot = esxDomainRevertToSnapshot, /* 0.8.0 */
 .domainSnapshotDelete = esxDomainSnapshotDelete, /* 0.8.0 */
+.isAlive = esxIsAlive, /* 0.9.7 */
 };
 
 
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index b022fee..bf8575c 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -1100,6 +1100,23 @@ hypervIsSecure(virConnectPtr conn)
 
 
 static int
+hypervIsAlive(virConnectPtr conn)
+{
+hypervPrivate *priv = conn-privateData;
+
+/* XXX we should be able to do something better than this is simple, safe,
+ * and good enough for now. In worst case, the function will return true
+ * even though the connection is not alive.
+ */
+if (priv-client)
+return 1;
+else
+return 0;
+}
+
+
+
+static int
 hypervDomainIsActive(virDomainPtr domain)
 {
 int result = -1;
@@ -1257,6 +1274,7 @@ static virDriver hypervDriver = {
 .domainManagedSave = hypervDomainManagedSave, /* 0.9.5 */
 .domainHasManagedSaveImage = hypervDomainHasManagedSaveImage, /* 0.9.5 */
 .domainManagedSaveRemove = hypervDomainManagedSaveRemove, /* 0.9.5 */
+.isAlive = hypervIsAlive, /* 0.9.7 */
 };
 
 
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index d324632..42503d6 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3875,6 +3875,13 @@ libxlDomainEventDeregisterAny(virConnectPtr conn, int 
callbackID)
 }
 
 
+static int
+libxlIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+return 1;
+}
+
+
 static virDriver libxlDriver = {
 .no = VIR_DRV_LIBXL,
 .name = xenlight,
@@ -3948,6 +3955,7 @@ static virDriver libxlDriver = {
 .domainIsUpdated = libxlDomainIsUpdated, /* 0.9.0 */
 .domainEventRegisterAny = libxlDomainEventRegisterAny, /* 0.9.0 */
 .domainEventDeregisterAny = libxlDomainEventDeregisterAny, /* 0.9.0 */
+.isAlive = libxlIsAlive, /* 0.9.7 */
 };
 
 static virStateDriver libxlStateDriver = {
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 6cf7203..28a7f9c 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -185,6 +185,12 @@ static int lxcIsEncrypted(virConnectPtr conn 
ATTRIBUTE_UNUSED)
 }
 
 
+static int lxcIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+return 1;
+}
+
+
 static char *lxcGetCapabilities(virConnectPtr conn) {
 lxc_driver_t *driver = conn-privateData;
 char *xml;
@@ -2986,6 +2992,7 @@ static virDriver lxcDriver = {
 .domainEventRegisterAny = lxcDomainEventRegisterAny, /* 0.8.0 */
 .domainEventDeregisterAny = lxcDomainEventDeregisterAny, /* 0.8.0 */
 .domainOpenConsole = lxcDomainOpenConsole, /* 0.8.6 */
+.isAlive = lxcIsAlive, /* 0.9.7 */
 };
 
 static virStateDriver lxcStateDriver = {
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 69ff444..8a4e6cf 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -1426,6 +1426,12 @@ static int openvzIsSecure(virConnectPtr conn 
ATTRIBUTE_UNUSED) {
 return 1;
 }
 
+static int
+openvzIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+return 1;
+}
+
 static char *openvzGetCapabilities(virConnectPtr conn) {
 struct openvz_driver *driver = conn-privateData;
 char *ret;
@@ -1714,6 +1720,7 @@ static virDriver openvzDriver = {
 .domainIsActive = openvzDomainIsActive, /* 0.7.3 */
 .domainIsPersistent = openvzDomainIsPersistent, 

[libvirt] [PATCH v2 03/12] Introduce two public APIs for keepalive protocol

2011-09-23 Thread Jiri Denemark
This introduces virConnectAllowKeepAlive and virConnectStartKeepAlive
public APIs which can be used by a client connecting to remote server to
indicate support for keepalive protocol. Both APIs are handled directly
by remote driver and not transmitted over the wire to the server.
---
 include/libvirt/libvirt.h.in |5 ++
 src/driver.h |9 
 src/libvirt.c|  107 ++
 src/libvirt_internal.h   |   10 +++-
 src/libvirt_public.syms  |6 ++
 5 files changed, 135 insertions(+), 2 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 39155a6..6f61cc0 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -3210,6 +3210,11 @@ typedef struct _virTypedParameter virMemoryParameter;
  */
 typedef virMemoryParameter *virMemoryParameterPtr;
 
+int virConnectAllowKeepAlive(virConnectPtr conn);
+int virConnectStartKeepAlive(virConnectPtr conn,
+ int interval,
+ unsigned int count);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/driver.h b/src/driver.h
index 3792003..cd17d83 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -718,6 +718,13 @@ typedef int
 (*virDrvDomainBlockPull)(virDomainPtr dom, const char *path,
  unsigned long bandwidth, unsigned int flags);
 
+typedef int
+(*virDrvAllowKeepAlive)(virConnectPtr conn);
+
+typedef int
+(*virDrvStartKeepAlive)(virConnectPtr conn,
+int interval,
+unsigned int count);
 
 /**
  * _virDriver:
@@ -872,6 +879,8 @@ struct _virDriver {
 virDrvDomainGetBlockJobInfo domainGetBlockJobInfo;
 virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed;
 virDrvDomainBlockPull domainBlockPull;
+virDrvAllowKeepAlive allowKeepAlive;
+virDrvStartKeepAlive startKeepAlive;
 };
 
 typedef int
diff --git a/src/libvirt.c b/src/libvirt.c
index 8f94b11..138f367 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -16590,3 +16590,110 @@ error:
 virDispatchError(dom-conn);
 return -1;
 }
+
+/**
+ * virConnectAllowKeepAlive:
+ * @conn: pointer to a hypervisor connection
+ *
+ * Tell remote party we support keepalive messages so the it can use them and
+ * we will respond to them.  To actually start sending keepalive messages to a
+ * client needs to call virConnectStartKeepAlive().
+ *
+ * Note: client has to implement and run event loop to be able to respond to
+ * asynchronous keepalive messages.  If a client doesn't run event loop but
+ * still calls this API, every connection made may be automatically closed by
+ * remote party after a certain period of inactivity.
+ *
+ * Returns -1 on error, 0 on success, 1 when remote party doesn't support
+ * keepalive messages.
+ */
+int virConnectAllowKeepAlive(virConnectPtr conn)
+{
+int ret = -1;
+
+VIR_DEBUG(conn=%p, conn);
+
+virResetLastError();
+
+if (!VIR_IS_CONNECT(conn)) {
+virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+virDispatchError(NULL);
+return -1;
+}
+
+if (!VIR_DRV_SUPPORTS_FEATURE(conn-driver, conn,
+  VIR_DRV_FEATURE_PROGRAM_KEEPALIVE)) {
+VIR_DEBUG(Remote party doesn't support keepalive messages);
+return 1;
+}
+
+if (conn-driver-allowKeepAlive) {
+ret = conn-driver-allowKeepAlive(conn);
+if (ret  0)
+goto error;
+return ret;
+}
+
+virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+virDispatchError(conn);
+return -1;
+}
+
+/**
+ * virConnectStartKeepAlive:
+ * @conn: pointer to a hypervisor connection
+ * @interval: number of seconds of inactivity before a keepalive message is 
sent
+ * @count: number of messages that can be sent in a row
+ *
+ * Start sending keepalive messages after interval second of inactivity and
+ * consider the connection to be broken when no response is received after
+ * count keepalive messages sent in a row.  In other words, sending count + 1
+ * keepalive message results in closing the connection.
+ *
+ * This API may be called only after calling virConnectAllowKeepAlive and
+ * checking it returned 0, which ensures remote party supports keepalive
+ * protocol.  Failure to do so will be detected and reported as an error.
+ *
+ * Note: client has to implement and run event loop to be able to use keepalive
+ * messages.  Failture to do so may result in connections being closed
+ * unexpectedly.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int virConnectStartKeepAlive(virConnectPtr conn,
+ int interval,
+ unsigned int count)
+{
+int ret = -1;
+
+VIR_DEBUG(conn=%p, interval=%d, count=%u, conn, interval, count);
+
+virResetLastError();
+
+if (!VIR_IS_CONNECT(conn)) {
+virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+

[libvirt] [PATCH v2 05/12] Add support for non-blocking calls in client RPC

2011-09-23 Thread Jiri Denemark
When a client wants to send a keepalive message it needs to do so in a
non-blocking way to avoid blocking its event loop. This patch adds
dontBlock flag which says that the call should be processed without
blocking. Such calls do not have a thread waiting for the result
associated with them. This means, that sending such call fails if no
thread is dispatching and writing to the socket would block. In case
there is a thread waiting for its (normal) call to finish, sending
non-blocking call just pushes it into the queue and lets the dispatching
thread send it. The thread which has the buck tries to send all
non-blocking calls in the queue in a best effort way---if sending them
would block or there's an error on the socket, non-blocking calls are
simply removed from the queue and discarded.
---
 src/rpc/virnetclient.c |  149 
 1 files changed, 113 insertions(+), 36 deletions(-)

diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 055361d..7ea9a27 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -55,6 +55,7 @@ struct _virNetClientCall {
 
 virNetMessagePtr msg;
 bool expectReply;
+bool dontBlock;
 
 virCond cond;
 
@@ -94,6 +95,11 @@ struct _virNetClient {
 };
 
 
+static int virNetClientSendInternal(virNetClientPtr client,
+virNetMessagePtr msg,
+bool expectReply,
+bool dontBlock);
+
 static void virNetClientLock(virNetClientPtr client)
 {
 virMutexLock(client-lock);
@@ -848,6 +854,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
 char ignore;
 sigset_t oldmask, blockedsigs;
 int timeout = -1;
+bool discardNonBlocking;
 
 /* If we have existing SASL decoded data we
  * don't want to sleep in the poll(), just
@@ -865,6 +872,11 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
 fds[0].events |= POLLIN;
 if (tmp-mode == VIR_NET_CLIENT_MODE_WAIT_TX)
 fds[0].events |= POLLOUT;
+/* We don't want to sleep in poll if any of the calls is
+ * non-blocking
+ */
+if (tmp-dontBlock)
+timeout = 0;
 
 tmp = tmp-next;
 }
@@ -937,35 +949,63 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
 goto error;
 }
 
-/* Iterate through waiting threads and if
- * any are complete then tell 'em to wakeup
+/* Iterate through waiting calls and
+ * - remove all completed nonblocking calls
+ * - remove all nonblocking calls in case poll() would block
+ * - remove all nonblocking calls if we got error from poll()
+ * - wake up threads waiting for calls that have been completed
  */
+discardNonBlocking = ret == 0 ||
+ (fds[0].revents  POLLHUP) ||
+ (fds[0].revents  POLLERR);
 tmp = client-waitDispatch;
 prev = NULL;
 while (tmp) {
+virNetClientCallPtr next = tmp-next;
+
 if (tmp != thiscall 
-tmp-mode == VIR_NET_CLIENT_MODE_COMPLETE) {
+(tmp-mode == VIR_NET_CLIENT_MODE_COMPLETE ||
+ (discardNonBlocking  tmp-dontBlock))) {
 /* Take them out of the list */
 if (prev)
 prev-next = tmp-next;
 else
 client-waitDispatch = tmp-next;
 
-/* And wake them up
- * ...they won't actually wakeup until
- * we release our mutex a short while
- * later...
- */
-VIR_DEBUG(Waking up sleep %p %p, tmp, client-waitDispatch);
-virCondSignal(tmp-cond);
+if (tmp-dontBlock) {
+/* tmp is a non-blocking call, no-one is waiting for it so
+ * we just free it here
+ */
+if (tmp-mode != VIR_NET_CLIENT_MODE_COMPLETE) {
+VIR_DEBUG(Can't finish nonblocking call %p without
+   blocking or error, tmp);
+}
+virNetMessageFree(tmp-msg);
+VIR_FREE(tmp);
+} else {
+/* And wake them up
+ * ...they won't actually wakeup until
+ * we release our mutex a short while
+ * later...
+ */
+VIR_DEBUG(Waking up sleep %p %p,
+  tmp, client-waitDispatch);
+virCondSignal(tmp-cond);
+}
 } else {
 prev = tmp;
 }
-tmp = tmp-next;
+tmp = next;
 }
 
 /* 

[libvirt] [PATCH v2 11/12] qemu: Add support for keepalive messages during p2p migration

2011-09-23 Thread Jiri Denemark
---
 src/qemu/libvirtd_qemu.aug  |2 ++
 src/qemu/qemu.conf  |   16 
 src/qemu/qemu_conf.c|   11 +++
 src/qemu/qemu_conf.h|3 +++
 src/qemu/qemu_migration.c   |   10 ++
 src/qemu/test_libvirtd_qemu.aug |6 ++
 6 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index 6c145c7..ad34e42 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -52,6 +52,8 @@ module Libvirtd_qemu =
  | int_entry max_processes
  | str_entry lock_manager
  | int_entry max_queued
+ | int_entry keepalive_interval
+ | int_entry keepalive_count
 
(* Each enty in the config is one of the following three ... *)
let entry = vnc_entry
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 4da5d5a..e623bc3 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -316,3 +316,19 @@
 # Note, that job lock is per domain.
 #
 # max_queued = 0
+
+###
+# Keepalive protocol:
+# This allows qemu driver to detect broken connections to remote
+# libvirtd during peer-to-peer migration.  A keepalive message is
+# sent to the deamon after keepalive_interval seconds of inactivity
+# to check if the deamon is still responding; keepalive_count is a
+# maximum number of keepalive messages that are allowed to be sent
+# to the deamon without getting any response before the connection
+# is considered broken.  In other words, the connection is
+# automatically closed approximately after
+# keepalive_interval * (keepalive_count + 1) seconds since the last
+# message received from the deamon.
+#
+#keepalive_interval = 5
+#keepalive_count = 5
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index d1bf075..19f24b1 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -118,6 +118,9 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
   virLockManagerPluginNew(nop, NULL, 0)))
 return -1;
 
+driver-keepAliveInterval = 5;
+driver-keepAliveCount = 5;
+
 /* Just check the file is readable before opening it, otherwise
  * libvirt emits an error.
  */
@@ -462,6 +465,14 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
 CHECK_TYPE(max_queued, VIR_CONF_LONG);
 if (p) driver-max_queued = p-l;
 
+p = virConfGetValue(conf, keepalive_interval);
+CHECK_TYPE(keepalive_interval, VIR_CONF_LONG);
+if (p) driver-keepAliveInterval = p-l;
+
+p = virConfGetValue(conf, keepalive_count);
+CHECK_TYPE(keepalive_count, VIR_CONF_LONG);
+if (p) driver-keepAliveCount = p-l;
+
 virConfFree (conf);
 return 0;
 }
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index e8b92a4..70c3fda 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -138,6 +138,9 @@ struct qemud_driver {
  * of guests which will be automatically killed
  * when the virConnectPtr is closed*/
 virHashTablePtr autodestroy;
+
+int keepAliveInterval;
+unsigned int keepAliveCount;
 };
 
 typedef struct _qemuDomainCmdlineDef qemuDomainCmdlineDef;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 0a5a13d..301d8ba 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2173,6 +2173,7 @@ static int doPeer2PeerMigrate(struct qemud_driver *driver,
 virConnectPtr dconn = NULL;
 bool p2p;
 virErrorPtr orig_err = NULL;
+int rc;
 
 VIR_DEBUG(driver=%p, sconn=%p, vm=%p, xmlin=%s, dconnuri=%s, 
   uri=%s, flags=%lx, dname=%s, resource=%lu,
@@ -2193,6 +2194,15 @@ static int doPeer2PeerMigrate(struct qemud_driver 
*driver,
 }
 
 qemuDomainObjEnterRemoteWithDriver(driver, vm);
+if ((rc = virConnectAllowKeepAlive(dconn)) == 0) {
+rc = virConnectStartKeepAlive(dconn, driver-keepAliveInterval,
+  driver-keepAliveCount);
+}
+qemuDomainObjExitRemoteWithDriver(driver, vm);
+if (rc  0)
+goto cleanup;
+
+qemuDomainObjEnterRemoteWithDriver(driver, vm);
 p2p = VIR_DRV_SUPPORTS_FEATURE(dconn-driver, dconn,
VIR_DRV_FEATURE_MIGRATION_P2P);
 /* v3proto reflects whether the caller used Perform3, but with
diff --git a/src/qemu/test_libvirtd_qemu.aug b/src/qemu/test_libvirtd_qemu.aug
index b1f9114..f7476ae 100644
--- a/src/qemu/test_libvirtd_qemu.aug
+++ b/src/qemu/test_libvirtd_qemu.aug
@@ -115,6 +115,9 @@ vnc_auto_unix_socket = 1
 max_processes = 12345
 
 lock_manager = \fcntl\
+
+keepalive_interval = 1
+keepalive_count = 42
 
 
test Libvirtd_qemu.lns get conf =
@@ -240,3 +243,6 @@ lock_manager = \fcntl\
 { max_processes = 12345 }
 { #empty }
 { lock_manager = fcntl }
+{ #empty }
+{ keepalive_interval = 1 }
+{ keepalive_count = 42 }
-- 
1.7.6.1

--
libvir-list mailing list

[libvirt] [PATCH v2 07/12] Implement keepalive protocol in remote driver

2011-09-23 Thread Jiri Denemark
---
 src/remote/remote_driver.c |   30 +
 src/rpc/virnetclient.c |  102 ++-
 src/rpc/virnetclient.h |5 ++
 3 files changed, 134 insertions(+), 3 deletions(-)

diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 1217d94..e218c40 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -4082,6 +4082,34 @@ done:
 }
 
 
+static int
+remoteAllowKeepAlive(virConnectPtr conn)
+{
+struct private_data *priv = conn-privateData;
+int ret = -1;
+
+remoteDriverLock(priv);
+ret = virNetClientKeepAliveAdvertise(priv-client);
+remoteDriverUnlock(priv);
+
+return ret;
+}
+
+
+static int
+remoteStartKeepAlive(virConnectPtr conn, int interval, unsigned int count)
+{
+struct private_data *priv = conn-privateData;
+int ret = -1;
+
+remoteDriverLock(priv);
+ret = virNetClientKeepAliveStart(priv-client, interval, count);
+remoteDriverUnlock(priv);
+
+return ret;
+}
+
+
 #include remote_client_bodies.h
 #include qemu_client_bodies.h
 
@@ -4430,6 +4458,8 @@ static virDriver remote_driver = {
 .domainGetBlockJobInfo = remoteDomainGetBlockJobInfo, /* 0.9.4 */
 .domainBlockJobSetSpeed = remoteDomainBlockJobSetSpeed, /* 0.9.4 */
 .domainBlockPull = remoteDomainBlockPull, /* 0.9.4 */
+.allowKeepAlive = remoteAllowKeepAlive, /* 0.9.7 */
+.startKeepAlive = remoteStartKeepAlive, /* 0.9.7 */
 };
 
 static virNetworkDriver network_driver = {
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 45b0edb..dee5059 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -29,6 +29,7 @@
 
 #include virnetclient.h
 #include virnetsocket.h
+#include virkeepalive.h
 #include memory.h
 #include threads.h
 #include virfile.h
@@ -93,11 +94,12 @@ struct _virNetClient {
 size_t nstreams;
 virNetClientStreamPtr *streams;
 
+virKeepAlivePtr keepalive;
 bool wantClose;
 };
 
 
-void virNetClientRequestClose(virNetClientPtr client);
+static void virNetClientRequestClose(virNetClientPtr client);
 
 static int virNetClientSendInternal(virNetClientPtr client,
 virNetMessagePtr msg,
@@ -127,11 +129,71 @@ static void virNetClientEventFree(void *opaque)
 virNetClientFree(client);
 }
 
+int
+virNetClientKeepAliveAdvertise(virNetClientPtr client)
+{
+virKeepAlivePtr ka;
+int ret = -1;
+
+virNetClientLock(client);
+if ((ka = client-keepalive))
+virKeepAliveRef(ka);
+virNetClientUnlock(client);
+
+if (ka) {
+ret = virKeepAliveAdvertise(ka);
+virKeepAliveFree(ka);
+} else {
+virNetError(VIR_ERR_INTERNAL_ERROR, %s,
+_(the caller doesn't support keepalive protocol;
+   perhaps it's missing event loop implementation));
+}
+
+return ret;
+}
+
+int
+virNetClientKeepAliveStart(virNetClientPtr client,
+   int interval,
+   unsigned int count)
+{
+int ret = -1;
+
+virNetClientLock(client);
+
+if (!client-keepalive) {
+virNetError(VIR_ERR_INTERNAL_ERROR, %s,
+_(the caller doesn't support keepalive protocol;
+   perhaps it's missing event loop implementation));
+goto cleanup;
+}
+
+ret = virKeepAliveStart(client-keepalive, interval, count);
+
+cleanup:
+virNetClientUnlock(client);
+return ret;
+}
+
+static void
+virNetClientKeepAliveDeadCB(void *opaque)
+{
+virNetClientRequestClose(opaque);
+}
+
+static int
+virNetClientKeepAliveSendCB(void *opaque,
+virNetMessagePtr msg)
+{
+return virNetClientSendInternal(opaque, msg, false, true);
+}
+
 static virNetClientPtr virNetClientNew(virNetSocketPtr sock,
const char *hostname)
 {
 virNetClientPtr client = NULL;
 int wakeupFD[2] = { -1, -1 };
+virKeepAlivePtr ka = NULL;
 
 if (pipe2(wakeupFD, O_CLOEXEC)  0) {
 virReportSystemError(errno, %s,
@@ -164,9 +226,21 @@ static virNetClientPtr virNetClientNew(virNetSocketPtr 
sock,
   client,
   virNetClientEventFree)  0) {
 client-refs--;
-VIR_DEBUG(Failed to add event watch, disabling events);
+VIR_DEBUG(Failed to add event watch, disabling events and support for
+   keepalive messages);
+} else {
+/* Keepalive protocol consists of async messages so it can only be used
+ * if the client supports them */
+if (!(ka = virKeepAliveNew(-1, 0, client,
+   virNetClientKeepAliveSendCB,
+   virNetClientKeepAliveDeadCB,
+   virNetClientEventFree)))
+goto error;
+/* keepalive object has a reference to client */
+client-refs++;
 }
 
+client-keepalive = ka;
 

[libvirt] [PATCH v2 08/12] Introduce virConnectIsAlive API

2011-09-23 Thread Jiri Denemark
This API can be used to check if the socket associated with
virConnectPtr is still open or it was closed (probably because keepalive
protocol timed out). If there the connection is local (i.e., no socket
is associated with the connection, it is trivially always alive.
---
 include/libvirt/libvirt.h.in |1 +
 src/driver.h |3 +++
 src/libvirt.c|   36 
 src/libvirt_public.syms  |1 +
 4 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 6f61cc0..3767582 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2546,6 +2546,7 @@ int virInterfaceIsActive(virInterfacePtr iface);
 
 int virConnectIsEncrypted(virConnectPtr conn);
 int virConnectIsSecure(virConnectPtr conn);
+int virConnectIsAlive(virConnectPtr conn);
 
 /*
  * CPU specification API
diff --git a/src/driver.h b/src/driver.h
index cd17d83..8c01690 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -506,6 +506,8 @@ typedef int
 typedef int
 (*virDrvConnectIsSecure)(virConnectPtr conn);
 typedef int
+(*virDrvConnectIsAlive)(virConnectPtr conn);
+typedef int
 (*virDrvDomainIsActive)(virDomainPtr dom);
 typedef int
 (*virDrvDomainIsPersistent)(virDomainPtr dom);
@@ -881,6 +883,7 @@ struct _virDriver {
 virDrvDomainBlockPull domainBlockPull;
 virDrvAllowKeepAlive allowKeepAlive;
 virDrvStartKeepAlive startKeepAlive;
+virDrvConnectIsAlive isAlive;
 };
 
 typedef int
diff --git a/src/libvirt.c b/src/libvirt.c
index 138f367..19ac4b5 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -16697,3 +16697,39 @@ error:
 virDispatchError(conn);
 return -1;
 }
+
+/**
+ * virConnectIsAlive:
+ * @conn: pointer to the connection object
+ *
+ * Determine if the connection to the hypervisor is still alive
+ *
+ * A connection will be classed as alive if it is either local, or running
+ * over a channel (TCP or UNIX socket) which is not closed.
+ *
+ * Returns 1 if alive, 0 if dead, -1 on error
+ */
+int virConnectIsAlive(virConnectPtr conn)
+{
+VIR_DEBUG(conn=%p, conn);
+
+virResetLastError();
+
+if (!VIR_IS_CONNECT(conn)) {
+virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+virDispatchError(NULL);
+return -1;
+}
+if (conn-driver-isAlive) {
+int ret;
+ret = conn-driver-isAlive(conn);
+if (ret  0)
+goto error;
+return ret;
+}
+
+virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+virDispatchError(conn);
+return -1;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index f7441d7..e60f66d 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -492,6 +492,7 @@ LIBVIRT_0.9.5 {
 LIBVIRT_0.9.7 {
 global:
 virConnectAllowKeepAlive;
+virConnectIsAlive;
 virConnectStartKeepAlive;
 } LIBVIRT_0.9.5;
 
-- 
1.7.6.1

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


[libvirt] [PATCH v2 10/12] Add keepalive support into domain-events examples

2011-09-23 Thread Jiri Denemark
---
Notes:
Version 2:
- automatically exit when a connection is closed because of
  keepalive timeout

 examples/domain-events/events-c/event-test.c   |   13 -
 examples/domain-events/events-python/event-test.py |5 -
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/examples/domain-events/events-c/event-test.c 
b/examples/domain-events/events-c/event-test.c
index 6a3ed26..e310eb4 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -390,7 +390,18 @@ int main(int argc, char **argv)
 (callback5ret != -1) 
 (callback6ret != -1) 
 (callback7ret != -1)) {
-while (run) {
+int rc;
+
+if ((rc = virConnectAllowKeepAlive(dconn)) == 0)
+rc = virConnectStartKeepAlive(dconn, 5, 3);
+if (rc  0) {
+virErrorPtr err = virGetLastError();
+fprintf(stderr, Failed to start keepalive protocol: %s\n,
+err  err-message ? err-message : Unknown error);
+run = 0;
+}
+
+while (run  virConnectIsAlive(dconn) == 1) {
 if (virEventRunDefaultImpl()  0) {
 virErrorPtr err = virGetLastError();
 fprintf(stderr, Failed to run event loop: %s\n,
diff --git a/examples/domain-events/events-python/event-test.py 
b/examples/domain-events/events-python/event-test.py
index 76fda2b..bc854b8 100644
--- a/examples/domain-events/events-python/event-test.py
+++ b/examples/domain-events/events-python/event-test.py
@@ -518,11 +518,14 @@ def main():
 vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG, 
myDomainEventWatchdogCallback, None)
 vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS, 
myDomainEventGraphicsCallback, None)
 
+vc.allowKeepAlive()
+vc.startKeepAlive(5, 3)
+
 # The rest of your app would go here normally, but for sake
 # of demo we'll just go to sleep. The other option is to
 # run the event loop in your main thread if your app is
 # totally event based.
-while 1:
+while vc.isAlive() == 1:
 time.sleep(1)
 
 
-- 
1.7.6.1

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


Re: [libvirt] [PATCH] qemu: Allow domain reboot after core dump

2011-09-23 Thread Sheldon

yes, the patch can work, when I execute virsh dump --reboot domain file

and the type of file is: QEMU's suspend to disk image

but the guest does not reboot. The guest does nothing.

but I try  virsh shutdown domain,  the guest Ubuntu OS pop up a dialog 
box with four options: Shut Down, Restart, Suspend and HIbernate.


  

??: [libvirt] [PATCH] qemu: Allow domain reboot after core dump
??: Tue, 20 Sep 2011 13:34:27 +0200
???:Michal Privoznik mpriv...@redhat.com
???:libvir-list@redhat.com



This patch introduces possibility to reboot domain after core dump
finishes. The new flag VIR_DUMP_REBOOT was added to
virDomainCoreDumpFlags. The new functionality is accessible via virsh
too: virsh dump --rebootdomain
---
  include/libvirt/libvirt.h.in |1 +
  src/qemu/qemu_driver.c   |8 +++-
  tools/virsh.c|3 +++
  3 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 39155a6..8c41f5a 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -748,6 +748,7 @@ typedef enum {
  VIR_DUMP_CRASH= (1  0), /* crash after dump */
  VIR_DUMP_LIVE = (1  1), /* live dump */
  VIR_DUMP_BYPASS_CACHE = (1  2), /* avoid file system cache pollution */
+VIR_DUMP_REBOOT   = (1  3), /* reboot domain after dump finishes */
  } virDomainCoreDumpFlags;

  /* Domain migration flags. */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e2f428f..22576a8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3104,7 +3104,8 @@ static int qemudDomainCoreDump(virDomainPtr dom,
  int ret = -1;
  virDomainEventPtr event = NULL;

-virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH | VIR_DUMP_BYPASS_CACHE, -1);
+virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH |
+  VIR_DUMP_BYPASS_CACHE | VIR_DUMP_REBOOT, -1);

  qemuDriverLock(driver);
  vm = virDomainFindByUUID(driver-domains, dom-uuid);
@@ -3189,6 +3190,11 @@ cleanup:
  if (event)
  qemuDomainEventQueue(driver, event);
  qemuDriverUnlock(driver);
+
+if ((ret == 0)  (flags  VIR_DUMP_REBOOT)) {
+qemuDomainReboot(dom, 0);
+}
+
  return ret;
  }

diff --git a/tools/virsh.c b/tools/virsh.c
index d575425..74f6a79 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2840,6 +2840,7 @@ static const vshCmdOptDef opts_dump[] = {
  {crash, VSH_OT_BOOL, 0, N_(crash the domain after core dump)},
  {bypass-cache, VSH_OT_BOOL, 0,
   N_(avoid file system cache when saving)},
+{reboot, VSH_OT_BOOL, 0, N_(reboot the domain after core dump)},
  {domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id or uuid)},
  {file, VSH_OT_DATA, VSH_OFLAG_REQ, N_(where to dump the core)},
  {NULL, 0, 0, NULL}
@@ -2869,6 +2870,8 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
  flags |= VIR_DUMP_CRASH;
  if (vshCommandOptBool(cmd, bypass-cache))
  flags |= VIR_DUMP_BYPASS_CACHE;
+if (vshCommandOptBool(cmd, reboot))
+flags |= VIR_DUMP_REBOOT;

  if (virDomainCoreDump(dom, to, flags)  0) {
  vshError(ctl, _(Failed to core dump domain %s to %s), name, to);
--
1.7.3.4

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

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

Re: [libvirt] [PATCH] storage: Do not use comma as seperator for lvs output

2011-09-23 Thread Eli Qiao

于 2011年09月22日 17:08, Osier Yang 写道:

于 2011年09月22日 16:41, Eli 写道:

hi Osier:
于 2011年09月22日 15:08, Osier Yang 写道:

于 2011年09月22日 14:31, Eli 写道:

hi Osier :
于 2011年09月21日 17:07, Osier Yang 写道:

* src/storage/storage_backend_logical.c:

If a logical vol is created with multiple stripes. (e.g. --stripes 
3),

the device field of lvs output will have multiple fileds which are
seperated by comma. It means the RE we write in the codes will not
work well anymore. E.g. (lvs output for a stripped vol, uses # as
seperator here):

test_stripes##fSLSZH-zAS2-yAIb-n4mV-Al9u-HA3V-oo9K1B#\
/dev/sdc1(10240),/dev/sdd1(0)#42949672960#4194304

The RE we uses:

 const char *regexes[] = {
 
^\\s*(\\S+),(\\S*),(\\S+),(\\S+)\\((\\S+)\\),(\\S+),([0-9]+),?\\s*$

 };

This patch changes the seperator into # to fix the problem.

Related RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=727474
---
  src/storage/storage_backend_logical.c |7 ---
  1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/storage/storage_backend_logical.c 
b/src/storage/storage_backend_logical.c

index 4f42047..45f77ad 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -187,19 +187,20 @@ 
virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,

   *
   * NB can be multiple rows per volume if they have many extents
   *
- * NB lvs from some distros (e.g. SLES10 SP2) outputs 
trailing , on each line

+ * NB lvs from some distros (e.g. SLES10 SP2) outputs trailing
+ * @separator on each line
   *
   * NB Encrypted logical volumes can print ':' in their name, 
so it is

   *not a suitable separator (rhbz 470693).
   */
  const char *regexes[] = {
-
^\\s*(\\S+),(\\S*),(\\S+),(\\S+)\\((\\S+)\\),(\\S+),([0-9]+),?\\s*$
+
^\\s*(\\S+)#(\\S*)#(\\S+)#(\\S+)\\((\\S+)\\)#(\\S+)#([0-9]+)#?\\s*$

  };
  int vars[] = {
  7
  };
  const char *prog[] = {
-LVS, --separator, ,, --noheadings, --units, b,
+LVS, --separator, #, --noheadings, --units, b,
  --unbuffered, --nosuffix, --options,
  lv_name,origin,uuid,devices,seg_size,vg_extent_size,
  pool-def-source.name, NULL


I reproduced the bug :

[root@localhost bin]# ./virsh -d 5 pool-create-as vg_ssd logical 
--target /dev/vg_ssd

error: Failed to create pool vg_ssd
error: cannot open volume '/dev/vg_ssd/test_stripes,': No such file 
or directory


and then I tested this patch , it seems work well.

[root@localhost bin]# ./virsh -d 5 pool-create-as vg_ssd logical 
--target /dev/vg_ssd

Pool vg_ssd created

[root@localhost bin]# ./virsh pool-info vg_ssd
Name: vg_ssd
UUID: c45cc84e-7879-cc15-ee78-2d2dda6b531d
State: running
Persistent: no
Autostart: no
Capacity: 200.00 MB
Allocation: 152.00 MB
Available: 48.00 MB



Thanks for the testing, Eli,

Could you also check what's the vol XML?  I want to confirm if the
extents in sourcedevice/device/sourcedisplays well,
though it looks to me there is no path element defined for 
extents

in the storage vol schema yet.


1. my vol XML is like this:

  virsh # vol-dumpxml test_stripes --pool vg_ssd
volume
nametest_stripes/name
key1pc6Gf-1hn2-WGnw-ASKt-uX6w-xUed-qERq50/key
*source
device path='/dev/sdb(0),/dev/sdc'
*



do you mean the xml should like this :
device path='/dev/sdb(0)'
extent start='0' end='xxx'/
/device
device path='/dev/sdc'
extent start='xxx' end='yyy'/
/device

This is expected, and is what's Daniel Berrange worried about.


*extent start='0' end='159383552'/
/device
/source*


Thanks
Osier



--
best regards
eli

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

[libvirt] [PATCH v3] qemu: Allow domain reboot after core dump

2011-09-23 Thread Michal Privoznik
This patch introduces possibility to reboot domain after core dump
finishes. The new flag VIR_DUMP_REBOOT was added to
virDomainCoreDumpFlags. The new functionality is accessible via virsh
too: virsh dump --reboot domain
---
diff to v2:
-issue reset command instead of qemuDomainReboot

 include/libvirt/libvirt.h.in |1 +
 src/qemu/qemu_driver.c   |   54 +++--
 tools/virsh.c|3 ++
 3 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 39155a6..8c41f5a 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -748,6 +748,7 @@ typedef enum {
 VIR_DUMP_CRASH= (1  0), /* crash after dump */
 VIR_DUMP_LIVE = (1  1), /* live dump */
 VIR_DUMP_BYPASS_CACHE = (1  2), /* avoid file system cache pollution */
+VIR_DUMP_REBOOT   = (1  3), /* reboot domain after dump finishes */
 } virDomainCoreDumpFlags;
 
 /* Domain migration flags. */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0d0bea2..3e05e14 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2860,6 +2860,47 @@ getCompressionType(struct qemud_driver *driver)
 return compress;
 }
 
+static int
+doSystemReset(struct qemud_driver *driver,
+  virDomainObjPtr *vm)
+{
+int ret = -1;
+qemuDomainObjPrivatePtr priv;
+
+/* Okay, this should never happen, but doesn't hurt to check. */
+if (!driver || !vm || !*vm) {
+qemuReportError(VIR_ERR_INTERNAL_ERROR, %s,
+_(invalid argument supplied));
+goto cleanup;
+}
+
+priv = (*vm)-privateData;
+
+if (qemuDomainObjBeginJob(driver, *vm, QEMU_JOB_MODIFY)  0)
+goto cleanup;
+
+if (!virDomainObjIsActive(*vm)) {
+qemuReportError(VIR_ERR_INTERNAL_ERROR, %s,
+_(guest unexpectedly quit));
+goto endjob;
+}
+
+qemuDomainObjEnterMonitorWithDriver(driver, *vm);
+if (qemuMonitorSystemReset(priv-mon)  0) {
+qemuDomainObjExitMonitorWithDriver(driver, *vm);
+goto endjob;
+}
+qemuDomainObjExitMonitorWithDriver(driver, *vm);
+
+ret = 0;
+
+endjob:
+if (qemuDomainObjEndJob(driver, *vm) == 0)
+*vm = NULL;
+cleanup:
+return ret;
+}
+
 static int qemudDomainCoreDump(virDomainPtr dom,
const char *path,
unsigned int flags)
@@ -2870,7 +2911,8 @@ static int qemudDomainCoreDump(virDomainPtr dom,
 int ret = -1;
 virDomainEventPtr event = NULL;
 
-virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH | VIR_DUMP_BYPASS_CACHE, -1);
+virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH |
+  VIR_DUMP_BYPASS_CACHE | VIR_DUMP_REBOOT, -1);
 
 qemuDriverLock(driver);
 vm = virDomainFindByUUID(driver-domains, dom-uuid);
@@ -2949,11 +2991,17 @@ endjob:
 }
 
 cleanup:
-if (vm)
-virDomainObjUnlock(vm);
 if (event)
 qemuDomainEventQueue(driver, event);
+
+if ((ret == 0)  (flags  VIR_DUMP_REBOOT)  vm) {
+ret = doSystemReset(driver, vm);
+}
+
+if (vm)
+virDomainObjUnlock(vm);
 qemuDriverUnlock(driver);
+
 return ret;
 }
 
diff --git a/tools/virsh.c b/tools/virsh.c
index e5ea9d7..bdff33c 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2899,6 +2899,7 @@ static const vshCmdOptDef opts_dump[] = {
 {crash, VSH_OT_BOOL, 0, N_(crash the domain after core dump)},
 {bypass-cache, VSH_OT_BOOL, 0,
  N_(avoid file system cache when saving)},
+{reboot, VSH_OT_BOOL, 0, N_(reboot the domain after core dump)},
 {domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id or uuid)},
 {file, VSH_OT_DATA, VSH_OFLAG_REQ, N_(where to dump the core)},
 {NULL, 0, 0, NULL}
@@ -2928,6 +2929,8 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
 flags |= VIR_DUMP_CRASH;
 if (vshCommandOptBool(cmd, bypass-cache))
 flags |= VIR_DUMP_BYPASS_CACHE;
+if (vshCommandOptBool(cmd, reboot))
+flags |= VIR_DUMP_REBOOT;
 
 if (virDomainCoreDump(dom, to, flags)  0) {
 vshError(ctl, _(Failed to core dump domain %s to %s), name, to);
-- 
1.7.3.4

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


Re: [libvirt] [PATCH] selinux: Correctly report warning if virt_use_nfs not set

2011-09-23 Thread Michal Privoznik
On 22.09.2011 18:56, Laine Stump wrote:
 On 09/22/2011 05:48 AM, Michal Privoznik wrote:
 Previous patch c9b37fee tried to deal with virt_use_nfs. But
 setfilecon() returns EOPNOTSUPP on NFS so we need to move the
 warning to else branch.
 
 I have a vague memory of the error code of something like this changing
 from some other error on an older version of RHEL to EOPNOTSUPP on newer
 version. It may have been for something else, but may be worth checking
 out to make sure this patch gives the desired results with, e.g. RHEL5
 and RHEL6.0 as well as 6.2 and Fedora.
 

Thanks. Pushed with this squashed in:


diff --git a/src/security/security_selinux.c
b/src/security/security_selinux.c
index 9a9a305..19ca801 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -419,7 +419,7 @@ SELinuxSetFilecon(const char *path, char *tcon)
  * The user hopefully set one of the necessary SELinux
  * virt_use_{nfs,usb,pci}  boolean tunables to allow it...
  */
-if (setfilecon_errno != EOPNOTSUPP) {
+if (setfilecon_errno != EOPNOTSUPP  setfilecon_errno !=
ENOTSUP) {
 virReportSystemError(setfilecon_errno,
  _(unable to set security context '%s'
on '%s'),
  tcon, path);

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


[libvirt] 1 of 85 tests failed

2011-09-23 Thread vicom
hello send you result. /usr/bin/make check-TESTSmake[5]: Entering directory `/root/libvirt/libvirt-0.8.8/gnulib/tests'PASS: test-alignofPASS: test-alloca-optPASS: test-areadlinkPASS: test-arpa_inetPASS: test-base64PASS: test-binary-io.shPASS: test-c-ctypePASS: test-canonicalize-lgplPASS: test-chownPASS: test-count-one-bitsPASS: test-md5PASS: test-environPASS: test-errnoPASS: test-fcntl-hPASS: test-fseeko.shPASS: test-fseeko2.shPASS: test-funcPASS: test-getaddrinfoPASS: test-getdelimPASS: test-getgroupsPASS: test-gethostnamePASS: test-getlinePASS: test-gettimeofdayPASS: test-ignore-valuePASS: test-inet_ntopPASS: test-inet_ptonStarting test_lock ... OKStarting test_rwlock ... OKStarting test_recursive_lock ... OKStarting test_once ... OKPASS: test-lockPASS: test-lseek.shPASS: test-lstatPASS: test-mallocaPASS: test-memchrPASS: test-netdbPASS: test-netinet_intest-open.h:60: assertion failed/bin/bash: line 5: 9235 Aborted EXEEXT='' srcdir='.' abs_aux_dir='/root/libvirt/libvirt-0.8.8/build-aux' MAKE='/usr/bin/make' ${dir}$tstFAIL: test-openPASS: test-perror.shPASS: test-pipePASS: test-poll-hUnconnected socket test... passedConnected sockets test... passedGeneral socket test with fork... passedPipe test... passedPASS: test-pollPASS: test-random_rPASS: test-rawmemchrPASS: test-readlinkPASS: test-realloc-gnuPASS: test-schedUnconnected socket test... passedConnected sockets test... passedGeneral socket test with fork... passedPipe test... passedPASS: test-selectPASS: test-select-in.shPASS: test-select-out.shPASS: test-sigactionPASS: test-signalPASS: test-sigpipe.shPASS: test-sleepPASS: test-snprintfPASS: test-socketsPASS: test-statPASS: test-stat-timePASS: test-stdboolPASS: test-stddefPASS: test-stdintPASS: test-stdioPASS: test-stdlibPASS: test-strchrnulPASS: test-strerrorPASS: test-strerror_rPASS: test-stringPASS: test-stringsPASS: test-strnlenPASS: test-symlinkPASS: test-sys_ioctlPASS: test-sys_selectPASS: test-sys_socketPASS: test-sys_statPASS: test-sys_timePASS: test-sys_utsnamePASS: test-sys_waitPASS: test-termiosPASS: test-timePASS: test-unamePASS: test-unistdPASS: test-unsetenvPASS: test-usleepPASS: test-vasnprintfPASS: test-vasprintftest-vc-list-files-git.sh: skipped test: git not found in PATHSKIP: test-vc-list-files-git.shtest-vc-list-files-cvs.sh: skipped test: cvs not found in PATHSKIP: test-vc-list-files-cvs.shPASS: test-verifyPASS: test-verify.shPASS: test-wcharPASS: test-xalloc-die.sh===1 of 85 tests failed(2 tests were not run)Please report to libvir-list@redhat.com===make[5]: *** [check-TESTS] Error 1make[5]: Leaving directory `/root/libvirt/libvirt-0.8.8/gnulib/tests'make[4]: *** [check-am] Error 2make[4]: Leaving directory `/root/libvirt/libvirt-0.8.8/gnulib/tests'make[3]: *** [check-recursive] Error 1make[3]: Leaving directory `/root/libvirt/libvirt-0.8.8/gnulib/tests'make[2]: *** [check] Error 2make[2]: Leaving directory `/root/libvirt/libvirt-0.8.8/gnulib/tests'make[1]: *** [check-recursive] Error 1make[1]: Leaving directory `/root/libvirt/libvirt-0.8.8'make: *** [debian/stamp-makefile-check] Error 2dpkg-buildpackage: error: debian/rules build gave error exit status 2root@ubuntu:~/libvirt/libvirt-0.8.8# /bin/bash: line 5: 9235 Aborted EXEEXT='' srcdir='.' abs_aux_dir='/root/libvirt/libvirt-0.8.8/build-aux' MAKE='/usr/bin/make' ${dir}$tst-bash: /bin/bash:: No such file or directoryroot@ubuntu:~/libvirt/libvirt-0.8.8# test-open.h:60: assertion failedtest-open.h:60:: command not foundroot@ubuntu:~/libvirt/libvirt-0.8.8#  -- Tavs bezmaksas pasts Inbox.lv

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

Re: [libvirt] 1 of 85 tests failed

2011-09-23 Thread Eric Blake

On 09/22/2011 11:54 PM, vi...@inbox.lv wrote:

hello send you result.

/usr/bin/make check-TESTS
make[5]: Entering directory `/root/libvirt/libvirt-0.8.8/gnulib/tests'


Thanks for the report.  0.8.8 is rather old.  Would you mind repeating 
your test on 0.9.6?



test-open.h:60: assertion failed
/bin/bash: line 5: 9235 Aborted EXEEXT='' srcdir='.'
abs_aux_dir='/root/libvirt/libvirt-0.8.8/build-aux' MAKE='/usr/bin/make' 
${dir}$tst
FAIL: test-open


Also, what platform was this on?  That particular line of the test 
appears to be in a portion of the file testing that /dev/null returns 
EOF on read attempts; if that's not working, your system likely has much 
bigger problems.  I doubt that this is an actual bug in open(), so much 
as an issue in your setup.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

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


Re: [libvirt] [PATCHv3] Add unsafe cache mode support for disk driver

2011-09-23 Thread Eric Blake

On 09/22/2011 01:33 PM, Oskari Saarenmaa wrote:

QEMU 0.13 introduced cache=unsafe for -drive, this patch exposes
it in the libvirt layer.

   * Introduced a new QEMU capability flag ($prefix_CACHE_UNSAFE),
 as even if $prefix_CACHE_V2 is set, we can't known if unsafe


s/known/know/


 is supported.

   * Improved the reliability of qemu cache type detection.
---
  Updated patch based on Eric Blake's comments and rebased it to c4111bd0




+++ b/docs/formatdomain.html.in
@@ -996,10 +996,15 @@
li
  The optionalcodecache/code  attribute controls the
  cache mechanism, possible values are default, none,
-writethrough, writeback, and directsync. directsync
-is like writethrough, but it bypasses the host page
-cache.
-span class=sinceSince 0.6.0/span
+writethrough, writeback, directsync (like
+writethrough, but it bypasses the host page cache) and
+unsafe (host may cache all disk io and sync requests from


s/io and/io, and/


@@ -912,12 +914,16 @@ qemuCapsComputeCmdFlags(const char *help,
  else if (strstr(help, -domid))
  qemuCapsSet(flags, QEMU_CAPS_DOMID);
  if (strstr(help, -drive)) {
+const char *cache = strstr(help, cache=);
+
  qemuCapsSet(flags, QEMU_CAPS_DRIVE);
-if (strstr(help, cache=)
-!strstr(help, cache=on|off)) {
-qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_V2);
-if (strstr(help, directsync))
+if (cache  (p = strchr(cache, ']'))) {
+if (memmem(cache, p - cache, on|off, sizeof(on|off) - 1) == 
NULL)
+qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_V2);
+if (memmem(cache, p - cache, directsync, sizeof(directsync) - 
1))
  qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC);
+if (memmem(cache, p - cache, unsafe, sizeof(unsafe) - 1))
+qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_UNSAFE);


Nice!  And indeed, unsafe but not directsync is present in qemu 0.14.0, 
so this does need another capability bit.


ACK and pushed.

--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

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


Re: [libvirt] [PATCH 1/2] Modify generic ethernet interface so it will work when sVirt is enabled with qemu

2011-09-23 Thread Eric Blake

On 09/20/2011 05:17 PM, Tyler Coumbes wrote:

Add a generic utility library for working with the TUN driver (/dev/net/tun).


Thanks for posting these patches.  Next time, can you convince your 
mailer to send the series as a single thread (that is, make both 1/2 and 
2/2 have In-Reply-To set to point to 0/2)?  'git send-email' makes this 
relatively easy.  Also, sending patches with a diffstat makes it easier 
to see at a glance how much the patch involves.




---

diff --git a/src/Makefile.am b/src/Makefile.am
index 738ee91..ddd1b77 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -88,7 +88,8 @@ UTIL_SOURCES =
\
util/xml.c util/xml.h   \
util/virterror.c util/virterror_internal.h  \
util/virkeycode.c util/virkeycode.h \
-   util/virkeymaps.h
+   util/virkeymaps.h \
+   util/tunctl.c util/tunctl.h


Being a new file, it would probably be better to go with a name starting 
with 'vir', as in virtunctl (that is, this file represents libvirt's 
wrappers around TUN, and not a generic TUN manipulation library).




  EXTRA_DIST += $(srcdir)/util/virkeymaps.h $(srcdir)/util/keymaps.csv \
$(srcdir)/util/virkeycode-mapgen.py
@@ -1182,6 +1183,8 @@ if WITH_NETWORK
  USED_SYM_FILES += libvirt_network.syms
  endif

+USED_SYM_FILES += libvirt_tunctl.syms


If [vir]tunctl is compiled unconditionally, then we don't need a new 
.syms file - just stick the new symbols in libvirt_private.syms.  On the 
other hand, since TUN tends to be a Linux-specific concept, I think you 
need to compile this code conditionally, at which point maybe the 
existing libvirt_linux.syms is a better fit.



+
  EXTRA_DIST += \
libvirt_public.syms \
libvirt_private.syms\


And if all else fails and you really do need to create a new .syms file, 
then it needs to be listed in EXTRA_DIST.



diff --git a/src/libvirt_tunctl.syms b/src/libvirt_tunctl.syms
new file mode 100644
index 000..d1e00bb
--- /dev/null
+++ b/src/libvirt_tunctl.syms
@@ -0,0 +1,5 @@
+#tunctl.h
+createTap;
+delTap;
+tapSetInterfaceUp;
+tapSetInterfaceMac;


This naming isn't namespace clean.  It might be better to go with:

virTunCreateTap
virTunDeleteTap
virTunSetInterfaceUp
virTunSetInterfaceMac

Oh, and if all of the functions are named tap instead of tun, then maybe 
naming the file virtap instead of virtun would make more sense.  Which 
is it, tap or tun?



diff --git a/src/util/tunctl.c b/src/util/tunctl.c
new file mode 100644
index 000..e758e6d
--- /dev/null
+++ b/src/util/tunctl.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2007, 2009, 2011 Red Hat, Inc.


It's okay to list earlier years if your file was copying substantial 
layout from another file with those years, but if the file really is 
from scratch, it may be okay to list just 2011.

What file were you copying from,


+ *
+ * Authors:
+ */


Feel free to list yourself, if you'd like.  This line looks awkward with 
no author listing.



+
+# includeconfig.h
+# include tunctl.h
+# include virfile.h
+
+# includestdlib.h
+# includestdio.h
+# includestring.h
+# includeunistd.h
+# includefcntl.h
+# includeerrno.h
+# includearpa/inet.h
+# includesys/types.h
+# includesys/socket.h
+# includesys/ioctl.h
+# includepaths.h
+# includesys/wait.h
+
+# includelinux/param.h  /* HZ */


Yep, definitely Linux-specific, so the Makefile.am will need to be 
written so that this file is only conditionally compiled - basically, 
your new file should be in the same conditionals as the existing 
src/util/bridge.c.



+# ifdef IFF_VNET_HDR
+static int tapProbeVnetHdr(int tapfd)
+{
+#  if defined(IFF_VNET_HDR)  defined(TUNGETFEATURES)  defined(TUNGETIFF)


This looks very similar to brProbeVnetHdr in src/util/bridge.c.  If you 
are going to refactor code into a new file for larger reuse later, then 
it may be better to do the full code motion in a single commit, rather 
than to add the new function now and delete the original code later. 
That's not a hard-and-fast rule, but whichever way you go, it would be 
nice to mention in the commit message that you are adding the new code 
here in order to refactor common code out of bridge.c later.  It took me 
a while to realize that you were reusing code rather than writing it 
from scratch.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

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


Re: [libvirt] [PATCH] qemu: Check for ejected media during startup and migration

2011-09-23 Thread Michal Privoznik
On 16.09.2011 17:38, Eric Blake wrote:
 On 09/14/2011 01:52 AM, Michal Privoznik wrote:
 On 14.09.2011 01:05, Eric Blake wrote:
 On 09/13/2011 05:03 PM, Eric Blake wrote:
 On 09/13/2011 10:14 AM, Michal Privoznik wrote:
 If the daemon is restarted so we reconnect to monitor, cdrom media
 can be ejected. In that case we don't want to show it in domain xml,
 or require it on migration destination.

 To check for disk status use 'info block' monitor command.

 Yuck - this is still polling-based (we have to ask qemu every time we
 want to dumpxml). Whatever happened to the proposal of having
 interrupt-based cdrom events, where qemu sends an event any time the
 virtual tray changes state (whether by monitor command or
 guest-initiated), and libvirt monitors those events to update its
 internal state at that time, so that libvirt's internal state is always
 accurate?

 For reference:
 https://www.redhat.com/archives/libvir-list/2011-August/msg00487.html

 My patch does not touch dumpxml. It access monitor only on process
 reconnect and in early migration phase. In both cases we access monitor
 anyway.
 
 That is, you are polling the status at any location where you would be
 doing an internal dumpxml.  So while this is not exposing things to the
 user (and thus less polling), it is still doing polling.  I'm also
 worried about virDomainSave and virDomainSnapshotCreateXML needing to be
 hooked into doing these sorts of polling, to work correctly.
 
 I'd feel much better revisiting this issue post-0.9.5 - it's too
 invasive to fix right now.
 
 But I agree that events would be nicer, but I don't think they are gonna
 be implemented in near future. However, even if they would have been
 implemented now, we need to check the tray during process reconnect.
 
 You have a point there - but that is a one-time poll, rather than on
 every operation that needs to preserve xml state.
 
 Because if the libvirtd was down and during this time guest ejected
 cdrom and qemu sent event, we would not catch it - because we are not
 running. So in order to keep things consistent, we must check tray
 during startup.
 Migration is the same. Even if qemu will sent events at one time, we
 still need to check if we are talking to older qemu.
 
 This should be capability-based - we should know whether the qemu we are
 talking to supports nothing (0.14), polling (is it in qemu yet? or still
 just pending), or events (even further down the road), and make
 appropriate decisions on how much to probe according to the qemu we are
 talking to.
 

So I think the conclusion is: we need both, extended 'info block' (to do
one-time poll on startup) and events (any later on).

And I agree with that. However, qemu implements only the first part -
extended 'info block' command so far. As soon as it will implement
events too, we can adapt to them = make the check in migration early
phase dependent on qemu capabilities. But I think the current patch is
the best we can do right now.

Michal

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


Re: [libvirt] [PATCH] storage: Do not break the whole vol lookup process in the middle

2011-09-23 Thread Eric Blake

On 09/21/2011 04:36 AM, Osier Yang wrote:

* src/storage/storage_driver.c: As virStorageVolLookupByPath lookups
all the pool objs of the drivers, breaking when failing on getting
the stable path of the pool will just breaks the lookup process, it
can cause the API fails even if the vol exists indeed. It won't get
any benifit. This patch is to fix it.


s/benifit/benefit/


---
  src/storage/storage_driver.c |   14 ++
  1 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index c05b74e..8a3b5be 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1247,14 +1247,13 @@ storageVolumeLookupByPath(virConnectPtr conn,

  stable_path = virStorageBackendStablePath(driver-pools.objs[i],
cleanpath);
-/*
- * virStorageBackendStablePath already does
- * virStorageReportError if it fails; we just need to keep
- * propagating the return code
- */
  if (stable_path == NULL) {
-virStoragePoolObjUnlock(driver-pools.objs[i]);
-goto cleanup;
+/* Don't break the whole lookup process if fails on


s/if fails/if it fails/


+ * getting the stabe path for some of the pool.


s/stabe/stable/ s/pool./pools./


+ */
+VIR_WARN(Failed to get stable path for pool '%s',
+ driver-pools.objs[i]-def-name);
+continue;


You still need to call virStoragePoolObjUnlock prior to continue, 
otherwise you have a resource leak.



  }

  vol = virStorageVolDefFindByPath(driver-pools.objs[i],
@@ -1274,7 +1273,6 @@ storageVolumeLookupByPath(virConnectPtr conn,
  virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
%s, _(no storage vol with matching path));

-cleanup:
  VIR_FREE(cleanpath);
  storageDriverUnlock(driver);
  return ret;


I like the idea, but it would be worth seeing a v2.

--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

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


Re: [libvirt] [PATCH v3] qemu: Allow domain reboot after core dump

2011-09-23 Thread Eric Blake

On 09/23/2011 03:47 AM, Michal Privoznik wrote:

This patch introduces possibility to reboot domain after core dump
finishes. The new flag VIR_DUMP_REBOOT was added to
virDomainCoreDumpFlags. The new functionality is accessible via virsh
too: virsh dump --rebootdomain
---
diff to v2:
-issue reset command instead of qemuDomainReboot

  include/libvirt/libvirt.h.in |1 +
  src/qemu/qemu_driver.c   |   54 +++--
  tools/virsh.c|3 ++
  3 files changed, 55 insertions(+), 3 deletions(-)


Missing documentation of the new flag in src/libvirt.c and 
tools/virsh.pod.  Also, is the new flag compatible with VIR_DUMP_CRASH 
or VIR_DUMP_LIVE?  For example, we already declare _CRASH and _LIVE as 
mutually exclusive, and off-hand, it seems like REBOOT is exclusive with 
both of these as well.


Also, I'd split this patch into two pieces - one for documenting the new 
API (include/, src/libvirt.c, tools/), and the other for the qemu 
implementation of the new API (since most of my technical concerns are 
over the qemu implementation).


Independent of your patch, I also just realized that 
virDomainSave[Flags], virDomainRestore[Flags], 
virDomainSaveImageGetXMLDesc, virDomainSaveImageDefineXML, and 
virDomainCoreDump all have the same design issue: they are not very nice 
for remote management.  Each of these functions convert a relative path 
name into absolute name on the client side, before passing the string to 
the remote side, even though the actual file to be used is on the remote 
side.  This is not always guaranteed to work, and also leaves things 
stuck with the file being on the remote side (no way to dump the core 
across the network back to the client, like there is with 
virDomainScreenshot).


At some point, we may want to introduce new API that performs these 
types of operations on a stream, where the client can then manage the 
stream.  And/or we may want to introduce a way to specify the file to 
manipulate as a virStorageVolPtr, or even a string relative to a 
virStoragePoolPtr, for more precise control of where the file ends up 
without having to first absolutize the file argument in the client.



+++ b/src/qemu/qemu_driver.c
@@ -2860,6 +2860,47 @@ getCompressionType(struct qemud_driver *driver)
  return compress;
  }

+static int
+doSystemReset(struct qemud_driver *driver,
+  virDomainObjPtr *vm)
+{
+int ret = -1;
+qemuDomainObjPrivatePtr priv;
+
+/* Okay, this should never happen, but doesn't hurt to check. */
+if (!driver || !vm || !*vm) {
+qemuReportError(VIR_ERR_INTERNAL_ERROR, %s,
+_(invalid argument supplied));
+goto cleanup;
+}
+
+priv = (*vm)-privateData;
+
+if (qemuDomainObjBeginJob(driver, *vm, QEMU_JOB_MODIFY)  0)
+goto cleanup;
+
+if (!virDomainObjIsActive(*vm)) {
+qemuReportError(VIR_ERR_INTERNAL_ERROR, %s,
+_(guest unexpectedly quit));
+goto endjob;
+}


Just wondering if this is a case where it would actually make sense to 
start up a new qemu process, instead of just report that the guest 
unexpectedly quit.



+
+qemuDomainObjEnterMonitorWithDriver(driver, *vm);
+if (qemuMonitorSystemReset(priv-mon)  0) {
+qemuDomainObjExitMonitorWithDriver(driver, *vm);


This is the key point of this new function.  But I can't help but wonder...


+goto endjob;
+}
+qemuDomainObjExitMonitorWithDriver(driver, *vm);
+
+ret = 0;
+
+endjob:
+if (qemuDomainObjEndJob(driver, *vm) == 0)
+*vm = NULL;
+cleanup:
+return ret;
+}
+
  static int qemudDomainCoreDump(virDomainPtr dom,
 const char *path,
 unsigned int flags)
@@ -2870,7 +2911,8 @@ static int qemudDomainCoreDump(virDomainPtr dom,
  int ret = -1;
  virDomainEventPtr event = NULL;

-virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH | VIR_DUMP_BYPASS_CACHE, -1);
+virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH |
+  VIR_DUMP_BYPASS_CACHE | VIR_DUMP_REBOOT, -1);

  qemuDriverLock(driver);
  vm = virDomainFindByUUID(driver-domains, dom-uuid);
@@ -2949,11 +2991,17 @@ endjob:
  }

  cleanup:
-if (vm)
-virDomainObjUnlock(vm);
  if (event)
  qemuDomainEventQueue(driver, event);
+
+if ((ret == 0)  (flags  VIR_DUMP_REBOOT)  vm) {
+ret = doSystemReset(driver,vm);


This ends up starting a second job.  Wouldn't it be better to reuse the 
first job, by checking for VIR_DUMP_REBOOT in the endjob label alongside 
the check for 'resume  paused', and make the call to 
qemuMonitorSystemReset instead of qemuProcessStartCPUs at that point, so 
that the cleanup label remains untouched?


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com

Re: [libvirt] [PATCHv2] qemu: add ability to set PCI device rombar on or off

2011-09-23 Thread Eric Blake

On 09/22/2011 10:05 AM, Laine Stump wrote:

(This addresses Eric's comments in his review of V1. BTW, I'm a bit
surprised nobody has commented about the choice of name/placement of
the new attribute - speak now or forever hold your peace :-))


I was okay with the xml naming - but I agree that if anyone else has a 
better suggestion, now is the time to speak up :)




This patch was made in response to:

   https://bugzilla.redhat.com/show_bug.cgi?id=738095

In short, qemu's default for the rombar setting (which makes the
firmware ROM of a PCI device visible/not on the guest) was previously
0 (not visible), but they recently changed the default to 1
(visible). Unfortunately, there are some PCI devices that fail in the
guest when rombar is 1, so the setting must be exposed in libvirt to
prevent a regression in behavior (it will still require explicitly
settingrom bar='off'/  in the guest XML).

rombar is forced on/off by adding:

   rom bar='on|off'/

inside ahostdev  element that defines a PCI device. It is currently
ignored for all other types of devices.




+++ b/docs/formatdomain.html.in
@@ -1371,6 +1371,7 @@
  lt;address bus='0x06' slot='0x02' function='0x0'/gt;
lt;/sourcegt;
lt;boot order='1'/gt;
+lt;rom bar='0'/gt;


s/0/off/


  lt;/hostdevgt;
lt;/devicesgt;
.../pre
@@ -1402,6 +1403,18 @@
used together with general boot elements in
a href=#elementsOSBIOSBIOS bootloader/a  section.
span class=sinceSince 0.8.8/span/dd
+dtcoderom/code/dt
+ddThecoderom/code  element is used to change how a PCI
+device's ROM is presented to the guest. Thecodebar/code
+attribute can be set to on or off, and determines whether
+or not the device's ROM will be visible in the guest's memory
+map. (In PCI documentation, the rombar setting controls the
+presence of the Base Address Register for the ROM). If no rom
+bar is specified, the qemu default will be used (older
+versions of qemu used a default of off, while newer qemus
+have a default of on).span class=sinceSince
+0.9.6/span


looks much nicer, now that my v1 comments are incorporated, but still 
one nit:


s/0.9.6/0.9.7/


@@ -10387,6 +10407,18 @@ virDomainHostdevDefFormat(virBufferPtr buf,
  if (virDomainDeviceInfoFormat(buf,def-info, flags)  0)
  return -1;

+if (def-rombar) {
+const char *rombar
+= virDomainPciRombarModeTypeToString(def-rombar);
+if (!rombar) {
+virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _(unexpected rom bar value %d),
+ def-rombar);
+return -1;
+}
+virBufferAsprintf(buf, rom bar='%s'/\n, rombar);


Aargh - Thunderbird strikes me again.  When will they EVER fix their 
horrible whitespace munging bug?


This will conflict with my snapshotdomain reindentation patch series - 
so whoever applies first gets the easier side of the bargain :)



+}
+
  virBufferAddLit(buf, /hostdev\n);

  return 0;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 371f270..262c970 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -936,6 +936,14 @@ enum virDomainHostdevSubsysType {
  VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST
  };

+enum virDomainPciRombarMode {
+VIR_DOMAIN_PCI_ROMBAR_DEFAULT = 0,
+VIR_DOMAIN_PCI_ROMBAR_ON,
+VIR_DOMAIN_PCI_ROMBAR_OFF,
+
+VIR_DOMAIN_PCI_ROMBAR_LAST
+};
+
  typedef struct _virDomainHostdevDef virDomainHostdevDef;
  typedef virDomainHostdevDef *virDomainHostdevDefPtr;
  struct _virDomainHostdevDef {
@@ -964,6 +972,7 @@ struct _virDomainHostdevDef {
  } source;
  int bootIndex;
  virDomainDeviceInfo info; /* Guest address */
+int rombar;   /* rombar on/off/unspecified */


Your comment could go out of date if the enum grows. Lately, I've been 
listing fields like this as:


int rombar; /* enum virDomainPciRombarMode */

which stays correct even if we later add new values to the enum.


+++ b/src/qemu/qemu_capabilities.h
@@ -110,6 +110,7 @@ enum qemuCapsFlags {
  QEMU_CAPS_PCI_OHCI  = 71, /* -device pci-ohci */
  QEMU_CAPS_USB_REDIR = 72, /* -device usb-redir */
  QEMU_CAPS_USB_HUB   = 73, /* -device usb-hub */
+QEMU_CAPS_PCI_ROMBAR= 74, /* -device rombar=0|1 */


Needs an obvious rebase for NO_SHUTDOWN and DRIVE_CACHE_UNSAFE.

ACK to the idea.  I think my findings are small enough that I'm okay if 
you push with nits fixed rather than posting a v3 patch, although you 
may still want to wait for any other comments on the proposed xml spelling.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

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


Re: [libvirt] [PATCH v3 1/2] Add VIR_TYPED_PARAM_STRING

2011-09-23 Thread Eric Blake

On 09/23/2011 12:40 AM, Hu Tao wrote:

This makes string can be transported between client and server.
For compatibility,

 o new server should not send strings to old client if it
   doesn't see the flag VIR_DOMAIN_TYPED_STRING_OKAY.
 o new client that wants to be able to send/receive strings
   should always set the flag VIR_DOMAIN_TYPED_STRING_OKAY;
   if it is rejected by a old server that doesn't understand
   VIR_DOMAIN_TYPED_STRING_OKAY, then the client should have
   a second try with out flag VIR_DOMAIN_TYPED_STRING_OKAY
   to cope with an old server.


These points should probably be documented in libvirt.h.in, as well.

I'm also thinking that libvirt.c should do some argument validation - 
for every API that uses a virTypedParameter array, it should validate 
that no VIR_TYPED_PARAM_STRING occurs if the flag is not present.



+++ b/daemon/remote.c
@@ -672,6 +672,15 @@ remoteSerializeTypedParameters(virTypedParameterPtr params,
  case VIR_TYPED_PARAM_BOOLEAN:
  val[i].value.remote_typed_param_value_u.b = params[i].value.b;
  break;
+case VIR_TYPED_PARAM_STRING:
+if (params[i].value.s) {
+val[i].value.remote_typed_param_value_u.s = 
strdup(params[i].value.s);
+if (val[i].value.remote_typed_param_value_u.s == NULL) {
+virReportOOMError();
+goto cleanup;
+}
+}
+break;
  default:


Memory leak.  The cleanup: label must free any successfully allocated 
remote_typed_param_value_u.s contents prior to the failure point.



  virNetError(VIR_ERR_RPC, _(unknown parameter type: %d),
  params[i].type);
@@ -750,6 +759,14 @@ remoteDeserializeTypedParameters(remote_typed_param 
*args_params_val,
  params[i].value.b =
  args_params_val[i].value.remote_typed_param_value_u.b;
  break;
+case VIR_TYPED_PARAM_STRING:
+params[i].value.s =
+strdup(args_params_val[i].value.remote_typed_param_value_u.s);
+if (params[i].value.s == NULL) {
+virReportOOMError();
+goto cleanup;
+}
+break;
  default:
  virNetError(VIR_ERR_INTERNAL_ERROR, _(unknown parameter type: 
%d),
  params[i].type);


Memory leak.  The cleanup: label must now iterate over params, and free 
any successfully allocated params[i].value.s allocated prior to a failure.



diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 39155a6..448a0e7 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -205,6 +205,7 @@ typedef enum {
  VIR_DOMAIN_AFFECT_CURRENT = 0,  /* Affect current domain state.  */
  VIR_DOMAIN_AFFECT_LIVE= 1  0, /* Affect running domain state.  */
  VIR_DOMAIN_AFFECT_CONFIG  = 1  1, /* Affect persistent domain state.  */
+VIR_DOMAIN_TYPED_STRING_OKAY = 1  2,
  } virDomainModificationImpact;


I'm not sure if this is the best place to stick this enum value; it 
might fit better if it is listed (and documented!) closer to the rest of 
virTypedParameterType stuff.  But I agree with setting it to the value 
of 12, since all current clients of virTypedParameterType seem to be 
using VIR_DOMAIN_AFFECT_* and nothing further.




  /**
@@ -489,7 +490,8 @@ typedef enum {
  VIR_TYPED_PARAM_LLONG   = 3, /* long long case */
  VIR_TYPED_PARAM_ULLONG  = 4, /* unsigned long long case */
  VIR_TYPED_PARAM_DOUBLE  = 5, /* double case */
-VIR_TYPED_PARAM_BOOLEAN = 6  /* boolean(character) case */
+VIR_TYPED_PARAM_BOOLEAN = 6, /* boolean(character) case */
+VIR_TYPED_PARAM_STRING  = 7  /* string case */


Put a trailing comma after 7, so that the next addition (if any) doesn't 
have to touch two lines like this addition did.



  } virTypedParameterType;

  /**
@@ -520,6 +522,7 @@ struct _virTypedParameter {
  unsigned long long int ul;  /* type is ULLONG */
  double d;   /* type is DOUBLE */
  char b; /* type is BOOLEAN */
+char *s;/* type is STRING */


Here, I'd use:

char *s; /* type is STRING, see also VIR_DOMAIN_TYPED_STRING_OKAY */


  } value; /* parameter value */
  };

diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 1217d94..85eaeea 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1276,6 +1276,15 @@ remoteSerializeTypedParameters(virTypedParameterPtr 
params,
  case VIR_TYPED_PARAM_BOOLEAN:
  val[i].value.remote_typed_param_value_u.b = params[i].value.b;
  break;
+case VIR_TYPED_PARAM_STRING:
+if (params[i].value.s) {
+val[i].value.remote_typed_param_value_u.s = 
strdup(params[i].value.s);
+if 

Re: [libvirt] [PATCH v3 2/2] add interface for blkio.weight_device

2011-09-23 Thread Eric Blake

On 09/23/2011 12:40 AM, Hu Tao wrote:

This patch adds a parameter --weight-device to virsh command
blkiotune for setting/getting blkio.weight_device.
---
  daemon/remote.c  |5 +
  include/libvirt/libvirt.h.in |9 ++
  src/conf/domain_conf.c   |  114 -
  src/conf/domain_conf.h   |   16 
  src/libvirt_private.syms |1 +
  src/qemu/qemu_cgroup.c   |   22 +
  src/qemu/qemu_driver.c   |  191 +-
  src/util/cgroup.c|   33 +++
  src/util/cgroup.h|3 +
  tools/virsh.c|   52 ++--
  tools/virsh.pod  |5 +-
  11 files changed, 437 insertions(+), 14 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 82ee13b..bee1b94 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1566,6 +1566,7 @@ remoteDispatchDomainGetBlkioParameters(virNetServerPtr 
server ATTRIBUTE_UNUSED,
  int nparams = args-nparams;
  unsigned int flags;
  int rv = -1;
+int i;
  struct daemonClientPrivate *priv =
  virNetServerClientGetPrivateData(client);

@@ -1610,6 +1611,10 @@ success:
  cleanup:
  if (rv  0)
  virNetMessageSaveError(rerr);
+for (i = 0; i  nparams; i++) {
+if (params[i].type == VIR_TYPED_PARAM_STRING)
+VIR_FREE(params[i].value.s);
+}
  VIR_FREE(params);


This for loop seems like something that will be done frequently enough 
that it might be worth factoring it into a util file for managing 
virTypedParameters.  Something like: virTypedParameterFree(params).



  if (dom)
  virDomainFree(dom);
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 448a0e7..a1f2c98 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1139,6 +1139,15 @@ char *  
virDomainGetSchedulerType(virDomainPtr domain,

  #define VIR_DOMAIN_BLKIO_WEIGHT weight

+/**
+ * VIR_DOMAIN_BLKIO_WEIGHT_DEVICE:
+ *
+ * Macro for the blkio tunable weight_device: it represents the
+ * per device weight.
+ */


Also mention that this name refers to a VIR_TYPED_PARAMETER_STRING.


+/**
+ * virDomainBlkioWeightDeviceParseXML
+ *
+ * this function parses a XML node:
+ *
+ *device
+ *path/fully/qulaified/device/path/path


s/qulaified/qualified/


+ *weightweight/weight
+ */device
+ *
+ * and fills a virBlkioWeightDevice struct.
+ */
+static int virDomainBlkioWeightDeviceParseXML(xmlNodePtr root,
+  virBlkioWeightDevicePtr dw)
+{
+char *c;
+struct stat s;
+xmlNodePtr node;
+
+if (!dw)
+return -1;
+
+node = root-children;
+while (node) {
+if (node-type == XML_ELEMENT_NODE) {
+if (xmlStrEqual(node-name, BAD_CAST path)) {
+c = (char *)xmlNodeGetContent(node);
+if (!c)
+return -1;
+if (stat(c,s) == -1)
+return -1;


This stat() ties the parse to the existence of the node.  But that seems 
wrong - it should be possible to define a domain with XML that refers to 
a node that does not yet exist, provided that the node later exists at 
the time we try to start the domain.



+if ((s.st_mode  S_IFMT) == S_IFBLK) {
+dw-major = major(s.st_rdev);
+dw-minor = minor(s.st_rdev);


Also, breaking the parse into major/minor this early makes the result 
unmigratable, since we can't guarantee major/minor stability across 
hosts.  I think you have to store the name, not the major/minor, here in 
the domain_conf representation of the device weight, and only convert to 
major/minor in the hypervisor that is actually enforcing the limits.



+} else
+return -1;
+dw-path = (char *)xmlNodeGetContent(node);
+} else if (xmlStrEqual(node-name, BAD_CAST weight)) {
+c = (char *)xmlNodeGetContent(node);
+dw-weight = atoi(c);


atoi is unsafe.  It cannot detect errors.  You should use virStrToLong_i 
(or similar) instead.



@@ -10499,10 +10591,26 @@ virDomainDefFormatInternal(virDomainDefPtr def,
def-mem.cur_balloon);

  /* add blkiotune only if there are any */
-if (def-blkio.weight) {
+if (def-blkio.weight || def-blkio.weight_devices) {
  virBufferAsprintf(buf, blkiotune\n);
-virBufferAsprintf(buf, weight%u/weight\n,
-  def-blkio.weight);
+
+if (def-blkio.weight)
+virBufferAsprintf(buf, weight%u/weight\n,


(Stupid Thunderbird for munging whitespace).

This will conflict with my patch series for indenting domainsnapshot. 
 Shouldn't be too hard to figure out, but it boils down to who gets 
acked first.



+++ b/src/qemu/qemu_driver.c
@@ -44,6 +44,7 @@
  #includesys/ioctl.h
  #includesys/un.h
  #includebyteswap.h
+#includectype.h


This 

Re: [libvirt] [RFC PATCH] Prevent defining a domain has disk used by other domain

2011-09-23 Thread Eric Blake
On 09/23/2011 02:17 AM, Osier Yang wrote:
 Hmm, preventing the relabeling in security driver instead might be the
 more proper way? (If the disk source is used by other *running* domain,
 then quit relabeling and exit with error).

No, prevent the relabeling in the lock manager.  If one domain is
running and the lock manager is running, that should be sufficient to
prevent any other domain from starting with the same disk, even before
we get to the labeling point.

 
 However, this won't prevent one using same disk source for multiple domains
 if security_driver is disabled.
 
 And if security_driver is disabled, there will be no permission problem, all
 the domains can write to the same disk source, thus it might cause
 inconsistency
 between the domains or corrupt.
 
 to see whether if the pricinple
 is right or not.

The principle here is whether the lock manager is running.  Only if you
can still reproduce the problem with a lock manager (whether sanlock or
fcntl) do we have a bug to fix.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

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


Re: [libvirt] [libvirt-virshcmdref 08/10] update documentation for command migrate-getspeed

2011-09-23 Thread Eric Blake

On 09/14/2011 01:28 AM, Hu Tao wrote:

---
  common.sh   |2 +-
  source/migrate-getspeed.xml |   55 +++
  2 files changed, 56 insertions(+), 1 deletions(-)
  create mode 100644 source/migrate-getspeed.xml

diff --git a/common.sh b/common.sh
index a84c832..6454fe9 100755
--- a/common.sh
+++ b/common.sh
@@ -5,7 +5,7 @@ DOMAIN_COMMANDS=attach-device attach-disk attach-interface 
autostart
domname domuuid domxml-from-native domxml-to-native dump dumpxml echo
edit freecell hostname inject-nmi managedsave managedsave-remove
maxvcpus memtune migrate migrate-setmaxdowntime migrate-setspeed
-  reboot restore resume
+  migrate-getspeed reboot restore resume


Not quite alphabetical, so I fixed that.  ACK, and I've pushed 6-8. 
Just 9 and 10 left to review.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

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


Re: [libvirt] [libvirt-virshcmdref 10/10] update documentation for command vcpucount

2011-09-23 Thread Eric Blake

On 09/14/2011 01:29 AM, Hu Tao wrote:

---
  source/vcpucount.xml |   67 -
  1 files changed, 65 insertions(+), 2 deletions(-)


ACK and pushed 9 and 10.  Sorry it took me so long to get through this 
series.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

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


Re: [libvirt] [PATCH v3] qemu: Allow domain reboot after core dump

2011-09-23 Thread Dave Allan
On Fri, Sep 23, 2011 at 11:47:24AM +0200, Michal Privoznik wrote:
 This patch introduces possibility to reboot domain after core dump
 finishes. The new flag VIR_DUMP_REBOOT was added to
 virDomainCoreDumpFlags. The new functionality is accessible via virsh
 too: virsh dump --reboot domain
 ---
 diff to v2:
 -issue reset command instead of qemuDomainReboot

We should name the option --reset rather than --reboot then.

  include/libvirt/libvirt.h.in |1 +
  src/qemu/qemu_driver.c   |   54 +++--
  tools/virsh.c|3 ++
  3 files changed, 55 insertions(+), 3 deletions(-)
 
 diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
 index 39155a6..8c41f5a 100644
 --- a/include/libvirt/libvirt.h.in
 +++ b/include/libvirt/libvirt.h.in
 @@ -748,6 +748,7 @@ typedef enum {
  VIR_DUMP_CRASH= (1  0), /* crash after dump */
  VIR_DUMP_LIVE = (1  1), /* live dump */
  VIR_DUMP_BYPASS_CACHE = (1  2), /* avoid file system cache pollution */
 +VIR_DUMP_REBOOT   = (1  3), /* reboot domain after dump finishes */
  } virDomainCoreDumpFlags;
  
  /* Domain migration flags. */
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index 0d0bea2..3e05e14 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -2860,6 +2860,47 @@ getCompressionType(struct qemud_driver *driver)
  return compress;
  }
  
 +static int
 +doSystemReset(struct qemud_driver *driver,
 +  virDomainObjPtr *vm)
 +{
 +int ret = -1;
 +qemuDomainObjPrivatePtr priv;
 +
 +/* Okay, this should never happen, but doesn't hurt to check. */
 +if (!driver || !vm || !*vm) {
 +qemuReportError(VIR_ERR_INTERNAL_ERROR, %s,
 +_(invalid argument supplied));
 +goto cleanup;
 +}
 +
 +priv = (*vm)-privateData;
 +
 +if (qemuDomainObjBeginJob(driver, *vm, QEMU_JOB_MODIFY)  0)
 +goto cleanup;
 +
 +if (!virDomainObjIsActive(*vm)) {
 +qemuReportError(VIR_ERR_INTERNAL_ERROR, %s,
 +_(guest unexpectedly quit));
 +goto endjob;
 +}
 +
 +qemuDomainObjEnterMonitorWithDriver(driver, *vm);
 +if (qemuMonitorSystemReset(priv-mon)  0) {
 +qemuDomainObjExitMonitorWithDriver(driver, *vm);
 +goto endjob;
 +}
 +qemuDomainObjExitMonitorWithDriver(driver, *vm);
 +
 +ret = 0;
 +
 +endjob:
 +if (qemuDomainObjEndJob(driver, *vm) == 0)
 +*vm = NULL;
 +cleanup:
 +return ret;
 +}
 +
  static int qemudDomainCoreDump(virDomainPtr dom,
 const char *path,
 unsigned int flags)
 @@ -2870,7 +2911,8 @@ static int qemudDomainCoreDump(virDomainPtr dom,
  int ret = -1;
  virDomainEventPtr event = NULL;
  
 -virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH | VIR_DUMP_BYPASS_CACHE, 
 -1);
 +virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH |
 +  VIR_DUMP_BYPASS_CACHE | VIR_DUMP_REBOOT, -1);
  
  qemuDriverLock(driver);
  vm = virDomainFindByUUID(driver-domains, dom-uuid);
 @@ -2949,11 +2991,17 @@ endjob:
  }
  
  cleanup:
 -if (vm)
 -virDomainObjUnlock(vm);
  if (event)
  qemuDomainEventQueue(driver, event);
 +
 +if ((ret == 0)  (flags  VIR_DUMP_REBOOT)  vm) {
 +ret = doSystemReset(driver, vm);
 +}
 +
 +if (vm)
 +virDomainObjUnlock(vm);
  qemuDriverUnlock(driver);
 +
  return ret;
  }
  
 diff --git a/tools/virsh.c b/tools/virsh.c
 index e5ea9d7..bdff33c 100644
 --- a/tools/virsh.c
 +++ b/tools/virsh.c
 @@ -2899,6 +2899,7 @@ static const vshCmdOptDef opts_dump[] = {
  {crash, VSH_OT_BOOL, 0, N_(crash the domain after core dump)},
  {bypass-cache, VSH_OT_BOOL, 0,
   N_(avoid file system cache when saving)},
 +{reboot, VSH_OT_BOOL, 0, N_(reboot the domain after core dump)},
  {domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id or uuid)},
  {file, VSH_OT_DATA, VSH_OFLAG_REQ, N_(where to dump the core)},
  {NULL, 0, 0, NULL}
 @@ -2928,6 +2929,8 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
  flags |= VIR_DUMP_CRASH;
  if (vshCommandOptBool(cmd, bypass-cache))
  flags |= VIR_DUMP_BYPASS_CACHE;
 +if (vshCommandOptBool(cmd, reboot))
 +flags |= VIR_DUMP_REBOOT;
  
  if (virDomainCoreDump(dom, to, flags)  0) {
  vshError(ctl, _(Failed to core dump domain %s to %s), name, to);
 -- 
 1.7.3.4
 
 --
 libvir-list mailing list
 libvir-list@redhat.com
 https://www.redhat.com/mailman/listinfo/libvir-list

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


[libvirt] [PATCH] nodedev: document virsh nodedev-* commands

2011-09-23 Thread Eric Blake
This section of the man page was completely missing; I stumbled on
it when I had no clue that I had to use nodedev-reattach after
I was done playing with hostdev device passthrough to one of my
guests.

* tools/virsh.pod (NODEDEV COMMANDS): New section.
---

I also need to write something useful for http://libvirt.org/formatnode.html,
but that's a patch for another day.

Please double-check this for technical accuracy.

 tools/virsh.pod |  315 ++-
 1 files changed, 241 insertions(+), 74 deletions(-)

diff --git a/tools/virsh.pod b/tools/virsh.pod
index 43ed1ea..e9f415a 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1163,84 +1163,251 @@ is not available the processes will provide an exit 
code of 1.

 =back

-=head1 DEVICE COMMANDS
+=head1 NODEDEV COMMANDS
+
+The following commands manipulate host devices that are intended to be
+passed through to guest domains via hostdev elements in a domain's
+devices section.  A node device key is generally specified by the bus
+name followed by its address, using underscores between all components,
+such as pci__00_02_1, usb_1_5_3, or net_eth1_00_27_13_6a_fe_00.
+The Bnodedev-list gives the full list of host devices that are known
+to libvirt, although this includes devices that cannot be assigned to
+a guest (for example, attempting to detach the PCI device that controls
+the host's hard disk controller where the guest's disk images live could
+cause the host system to lock up or reboot).
+
+For more information on node device definition see:
+Lhttp://libvirt.org/formatnode.html.
+
+Passthrough devices cannot be simultaneously used by the host and its
+guest domains.  Attempts to use a passthrough hostdev for a guest may
+have the ability to behave as if Bnodedev-dettach had been called,
+although making this call explicitly is safe.  Once a guest no longer
+needs a passthrough device, reversing the process so that the host can
+again use the device requires the explicit use of Bnodedev-reattach.

-The following commands manipulate devices associated to domains.
-The domain-id can be specified as a short integer, a name or a full UUID.
-To better understand the values allowed as options for the command
-reading the documentation at Lhttp://libvirt.org/formatdomain.html on the
-format of the device sections to get the most accurate set of accepted values.
+=over 4
+
+=item Bnodedev-create IFILE
+
+Create a device on the host node that can then be assigned to virtual
+machines. Normally, libvirt is able to automatically determine which
+host nodes are available for use, but this allows registration of
+host hardware that libvirt did not automatically detect.  Ifile
+contains xml for a top-level device description of a node device.
+
+=item Bnodedev-destroy Inodedev
+
+Destroy (stop) a device on the host.  Note that this makes libvirt
+quit managing a host device, and may even make that device unusable
+by the rest of the physical host until a reboot.
+
+=item Bnodedev-dettach Inodedev
+
+Detach Inodedev from the host, so that it can safely be used by
+guests via hostdev passthrough.  This is reversed with
+Bnodedev-reattach.
+
+=item Bnodedev-dumpxml Inodedev
+
+Dump a device XML representation for the given node device, including
+such information as the device name, which bus owns the device, the
+vendor and product id, and any capabilities of the device usable by
+libvirt (such as whether device reset is supported).
+
+=item Bnodedev-list Icap I--tree
+
+List all of the devices available on the node that are known by libvirt.
+If Icap is used, the list is filtered to show only the nodes that
+include the given capability.  If I--tree is used, the output is
+formatted in a tree representing parents of each node.
+
+=item Bnodedev-reattach Inodedev
+
+Declare that Inodedev is no longer in use by any guests, and that
+the host can resume normal use of the device.  While libvirt can
+sometimes perform an implicit Bnodedev-dettach when creating a
+guest, it currently requires an explicit Bnodedev-reattach after
+the last guest use of the device before the host regains full control.
+
+=item Bnodedev-reset Inodedev
+
+Trigger a device reset for Inodedev, useful prior to transferring
+a node device between guest passthrough or the host.  Libvirt will
+often do this action implicitly when required, but this command
+allows an explicit reset when needed.
+
+=back
+
+=head1 SNAPSHOT COMMMANDS
+
+The following commands manipulate domain snapshots.  Snapshots take the
+disk, memory, and device state of a domain at a point-of-time, and save it
+for future use.  They have many uses, from saving a clean copy of an OS
+image to saving a domain's state before a potentially destructive operation.
+Snapshots are identified with a unique name.  See
+Lhttp://libvirt.org/formatsnapshot.html for documentation of the XML format
+used to represent properties of snapshots.

 =over 4

-=item Battach-device Idomain-id IFILE
-