[libvirt] [PATCH 2/2] qemu: don't relabel chardev source file if virtlogd is used

Pavel Hrdina phrdina at redhat.com
Mon May 15 14:28:35 UTC 2017


If libvirt uses virtlogd instead of passing the file path directly
to QEMU we shouldn't relabel the chardev source file, otherwise
virtlogd will get a permission denied while reloading.

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

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 src/conf/domain_conf.c          | 20 ++++++++++++++++++++
 src/conf/domain_conf.h          |  1 +
 src/qemu/qemu_command.c         | 12 ++++++++----
 src/security/security_dac.c     |  6 ++++++
 src/security/security_selinux.c |  6 ++++++
 5 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index aa441fae3c..92f011d3a4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2064,6 +2064,7 @@ virDomainChrSourceDefCopy(virDomainChrSourceDefPtr dest,
     }
 
     dest->type = src->type;
+    dest->skipRelabel = src->skipRelabel;
 
     return 0;
 }
@@ -10608,6 +10609,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
     char *append = NULL;
     char *haveTLS = NULL;
     char *tlsFromConfig = NULL;
+    char *skipRelabel = NULL;
     int remaining = 0;
 
     while (cur != NULL) {
@@ -10628,6 +10630,8 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
                 case VIR_DOMAIN_CHR_TYPE_UNIX:
                     if (!append && def->type == VIR_DOMAIN_CHR_TYPE_FILE)
                         append = virXMLPropString(cur, "append");
+                    if (!skipRelabel && def->type == VIR_DOMAIN_CHR_TYPE_FILE)
+                        skipRelabel = virXMLPropString(cur, "skipRelabel");
                     /* PTY path is only parsed from live xml.  */
                     if (!path  &&
                         (def->type != VIR_DOMAIN_CHR_TYPE_PTY ||
@@ -10726,6 +10730,17 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
                            _("Invalid append attribute value '%s'"), append);
             goto error;
         }
+        if (skipRelabel && def->type == VIR_DOMAIN_CHR_TYPE_FILE &&
+            (flags & VIR_DOMAIN_DEF_PARSE_STATUS)) {
+            if (STREQ(skipRelabel, "yes")) {
+                def->skipRelabel = true;
+            } else {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("invalid 'skipRelabel' attribute value '%s'"),
+                               skipRelabel);
+                goto error;
+            }
+        }
         if (!path &&
             def->type != VIR_DOMAIN_CHR_TYPE_PTY) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -10902,6 +10917,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
     VIR_FREE(logfile);
     VIR_FREE(haveTLS);
     VIR_FREE(tlsFromConfig);
+    VIR_FREE(skipRelabel);
 
     return remaining;
 
@@ -22324,6 +22340,10 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
                 def->data.file.append != VIR_TRISTATE_SWITCH_ABSENT)
                 virBufferAsprintf(buf, " append='%s'",
                     virTristateSwitchTypeToString(def->data.file.append));
+            if ((flags & VIR_DOMAIN_DEF_FORMAT_STATUS) &&
+                def->type == VIR_DOMAIN_CHR_TYPE_FILE && def->skipRelabel) {
+                virBufferAddLit(buf, " skipRelabel='yes'");
+            }
             virDomainSourceDefFormatSeclabel(buf, nseclabels, seclabels, flags);
         }
         break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 09fb7aada4..329eb90392 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1166,6 +1166,7 @@ struct _virDomainChrSourceDef {
     } data;
     char *logfile;
     int logappend;
+    bool skipRelabel;
 };
 
 /* A complete character device, both host and domain views.  */
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 813a8515c0..0625075bb2 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4998,6 +4998,7 @@ static int
 qemuBuildChrChardevFileStr(virLogManagerPtr logManager,
                            virCommandPtr cmd,
                            const virDomainDef *def,
+                           virDomainChrSourceDefPtr sourceDef,
                            virBufferPtr buf,
                            const char *filearg, const char *fileval,
                            const char *appendarg, int appendval)
@@ -5011,6 +5012,9 @@ qemuBuildChrChardevFileStr(virLogManagerPtr logManager,
             appendval == VIR_TRISTATE_SWITCH_OFF)
             flags |= VIR_LOG_MANAGER_PROTOCOL_DOMAIN_OPEN_LOG_FILE_TRUNCATE;
 
+        if (sourceDef)
+            sourceDef->skipRelabel = true;
+
         if ((logfd = virLogManagerDomainOpenLogFile(logManager,
                                                     "qemu",
                                                     def->uuid,
@@ -5051,7 +5055,7 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
                        virCommandPtr cmd,
                        virQEMUDriverConfigPtr cfg,
                        const virDomainDef *def,
-                       const virDomainChrSourceDef *dev,
+                       virDomainChrSourceDefPtr dev,
                        const char *alias,
                        virQEMUCapsPtr qemuCaps,
                        bool nowait)
@@ -5093,7 +5097,7 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
             goto cleanup;
         }
         if (qemuBuildChrChardevFileStr(virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FILE_APPEND) ?
-                                       logManager : NULL, cmd, def, &buf,
+                                       logManager : NULL, cmd, def, dev, &buf,
                                        "path", dev->data.file.path,
                                        "append", dev->data.file.append) < 0)
             goto cleanup;
@@ -5209,7 +5213,7 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
                            _("logfile not supported in this QEMU binary"));
             goto cleanup;
         }
-        if (qemuBuildChrChardevFileStr(logManager, cmd, def, &buf,
+        if (qemuBuildChrChardevFileStr(logManager, cmd, def, NULL, &buf,
                                        "logfile", dev->logfile,
                                        "logappend", dev->logappend) < 0)
             goto cleanup;
@@ -5573,7 +5577,7 @@ qemuBuildMonitorCommandLine(virLogManagerPtr logManager,
                             virQEMUDriverConfigPtr cfg,
                             virDomainDefPtr def,
                             virQEMUCapsPtr qemuCaps,
-                            const virDomainChrSourceDef *monitor_chr,
+                            virDomainChrSourceDefPtr monitor_chr,
                             bool monitor_json)
 {
     char *chrdev;
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 922e484942..a4e02ca8bc 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1196,6 +1196,9 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
     if (chr_seclabel && !chr_seclabel->relabel)
         return 0;
 
+    if (!chr_seclabel && dev_source->skipRelabel)
+        return 0;
+
     if (chr_seclabel && chr_seclabel->label) {
         if (virParseOwnershipIds(chr_seclabel->label, &user, &group) < 0)
             return -1;
@@ -1276,6 +1279,9 @@ virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr,
     if (chr_seclabel && !chr_seclabel->relabel)
         return 0;
 
+    if (!chr_seclabel && dev_source->skipRelabel)
+        return 0;
+
     switch ((virDomainChrType) dev_source->type) {
     case VIR_DOMAIN_CHR_TYPE_DEV:
     case VIR_DOMAIN_CHR_TYPE_FILE:
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 612dbc2a83..64ab2795d5 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2216,6 +2216,9 @@ virSecuritySELinuxSetChardevLabel(virSecurityManagerPtr mgr,
     if (chr_seclabel && !chr_seclabel->relabel)
         return 0;
 
+    if (!chr_seclabel && dev_source->skipRelabel)
+        return 0;
+
     if (chr_seclabel)
         imagelabel = chr_seclabel->label;
     if (!imagelabel)
@@ -2289,6 +2292,9 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityManagerPtr mgr,
     if (chr_seclabel && !chr_seclabel->relabel)
         return 0;
 
+    if (!chr_seclabel && dev_source->skipRelabel)
+        return 0;
+
     switch (dev_source->type) {
     case VIR_DOMAIN_CHR_TYPE_DEV:
     case VIR_DOMAIN_CHR_TYPE_FILE:
-- 
2.13.0




More information about the libvir-list mailing list