[libvirt] [PATCH] conf: Generate agent socket path if missing

Michal Privoznik mprivozn at redhat.com
Fri Feb 15 08:53:17 UTC 2013


It's not desired to force users imagine path for a socket they
are not even supposed to connect to. On the other hand, we
already have a release where the qemu agent socket path is
exposed to XML, so we cannot silently drop it from there.
The new path is generated in form:

$LOCALSTATEDIR/lib/libvirt/qemu/$domain.agent
---

This makes the qemu agent to be generated at domain startup phase.
So until that, we generate XML without any path, e.g.:

  <channel type='unix'>
    <source mode='connect'/>
    <target type='virtio' name='org.qemu.guest_agent.0'/>
    <address type='virtio-serial' controller='0' bus='0' port='1'/>
  </channel>

The other possibility is to generate path during XML parse phase, however this
expose something we are lacking for years - callbacks to fill in default values
for not configured ones. The aim so to make libvirt accept this snippet as
valid qemu agent config:

  <channel type='unix'>
    <target type='virtio' name='org.qemu.guest_agent.0'/>
  </channel>

 src/conf/domain_conf.c  | 37 ++++++++++++++++++++-----------------
 src/qemu/qemu_process.c | 30 ++++++++++++++++++++++++++++--
 2 files changed, 48 insertions(+), 19 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7a2b012..6245fec 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -6038,7 +6038,10 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
         break;
 
     case VIR_DOMAIN_CHR_TYPE_UNIX:
-        if (path == NULL) {
+        /* path is not required in special case of qemu guest agent */
+        if (path == NULL &&
+            chr_def->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO &&
+            STRNEQ(chr_def->target.name, "org.qemu.guest_agent.0")) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Missing source path attribute for char device"));
             goto error;
@@ -6135,7 +6138,6 @@ virDomainChrDefParseXML(virCapsPtr caps,
     char *type = NULL;
     const char *nodeName;
     virDomainChrDefPtr def;
-    int remaining;
     bool seenTarget = false;
 
     if (!(def = virDomainChrDefNew()))
@@ -6159,29 +6161,28 @@ virDomainChrDefParseXML(virCapsPtr caps,
     }
 
     cur = node->children;
-    remaining = virDomainChrSourceDefParseXML(&def->source, cur, flags,
-                                              def, ctxt,
-                                              vmSeclabels, nvmSeclabels);
-    if (remaining < 0)
-        goto error;
-    if (remaining) {
-        while (cur != NULL) {
-            if (cur->type == XML_ELEMENT_NODE) {
-                if (xmlStrEqual(cur->name, BAD_CAST "target")) {
-                    seenTarget = true;
-                    if (virDomainChrDefParseTargetXML(caps, vmdef, def, cur) < 0) {
-                        goto error;
-                    }
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE) {
+            if (xmlStrEqual(cur->name, BAD_CAST "target")) {
+                seenTarget = true;
+                if (virDomainChrDefParseTargetXML(caps, vmdef, def, cur) < 0) {
+                    goto error;
                 }
+                break;
             }
-            cur = cur->next;
         }
+        cur = cur->next;
     }
 
     if (!seenTarget &&
         ((def->targetType = virDomainChrDefaultTargetType(caps, vmdef, def->deviceType)) < 0))
         goto cleanup;
 
+    if (virDomainChrSourceDefParseXML(&def->source, node->children,
+                                      flags, def, ctxt,
+                                      vmSeclabels, nvmSeclabels) < 0)
+        goto error;
+
     if (def->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) {
         if (def->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -13307,10 +13308,12 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
         break;
 
     case VIR_DOMAIN_CHR_TYPE_UNIX:
+
         virBufferAsprintf(buf, "      <source mode='%s'",
                           def->data.nix.listen ? "bind" : "connect");
-        virBufferEscapeString(buf, " path='%s'/>\n",
+        virBufferEscapeString(buf, " path='%s'",
                               def->data.nix.path);
+        virBufferAddLit(buf, "/>\n");
         break;
     }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 4251c34..90f072d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2788,6 +2788,31 @@ qemuProcessPrepareMonitorChr(virQEMUDriverConfigPtr cfg,
     return 0;
 }
 
+static int
+qemuProcessPrepareAgentChr(virQEMUDriverConfigPtr cfg,
+                           virDomainObjPtr vm)
+{
+    virDomainChrSourceDefPtr config = qemuFindAgentConfig(vm->def);
+    virDomainChrSourceDefPtr newConfing = qemuFindAgentConfig(vm->newDef);
+
+    if (!config)
+        return 0;
+
+    /* if user hasn't supplied any agent socket path, generate one,
+     * and store it in inactive config as well */
+    if ((config->type == VIR_DOMAIN_CHR_TYPE_UNIX) &&
+        !config->data.nix.path) {
+        if ((virAsprintf(&config->data.nix.path, "%s/%s.agent",
+                         cfg->libDir, vm->def->name) < 0) ||
+            !(newConfing->data.nix.path = strdup(config->data.nix.path))) {
+            virReportOOMError();
+            return -1;
+        }
+        newConfing->data.nix.listen = config->data.nix.listen = true;
+    }
+
+    return 0;
+}
 
 /*
  * Precondition: vm must be locked, and a job must be active.
@@ -3772,8 +3797,9 @@ int qemuProcessStart(virConnectPtr conn,
         goto cleanup;
     }
 
-    VIR_DEBUG("Preparing monitor state");
-    if (qemuProcessPrepareMonitorChr(cfg, priv->monConfig, vm->def->name) < 0)
+    VIR_DEBUG("Preparing monitor and agent state");
+    if ((qemuProcessPrepareMonitorChr(cfg, priv->monConfig, vm->def->name) < 0) ||
+        (qemuProcessPrepareAgentChr(cfg, vm) < 0))
         goto cleanup;
 
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON))
-- 
1.8.0.2




More information about the libvir-list mailing list