]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
tpm: Move qemuTPMEmulatorInit to virTPMEmulatorInit in virtpm.c
authorStefan Berger <stefanb@linux.vnet.ibm.com>
Thu, 25 Jul 2019 18:22:02 +0000 (14:22 -0400)
committerDaniel P. Berrangé <berrange@redhat.com>
Fri, 26 Jul 2019 09:29:57 +0000 (10:29 +0100)
Move qemuTPMEmulatorInit to virTPMEmulatorInit in virtpm.c and introduce
a few functions to query the executables needed for virCommands.

Add locking to protect the tool paths and return a copy of the tool paths
to callers wanting to access them so that we can run the initialization
function multiples time later on and detect when the executable gets updated.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
src/libvirt_private.syms
src/qemu/qemu_tpm.c
src/util/virtpm.c
src/util/virtpm.h

index ff5a77b0e27dfa936eae2ce83719365155bb5521..4cdbb8059621581cba92cb92967c29fe8541614b 100644 (file)
@@ -3177,6 +3177,10 @@ virTimeStringThenRaw;
 
 # util/virtpm.h
 virTPMCreateCancelPath;
+virTPMEmulatorInit;
+virTPMGetSwtpm;
+virTPMGetSwtpmIoctl;
+virTPMGetSwtpmSetup;
 
 
 # util/virtypedparam.h
index cc8c69433b285420e2d98f0d310139fde0fac8ab..7282b01bfe430781a15dcb11f06d9300ddb7de80 100644 (file)
 #include "configmake.h"
 #include "dirname.h"
 #include "qemu_tpm.h"
+#include "virtpm.h"
 
 #define VIR_FROM_THIS VIR_FROM_NONE
 
 VIR_LOG_INIT("qemu.tpm");
 
-/*
- * executables for the swtpm; to be found on the host
- */
-static char *swtpm_path;
-static char *swtpm_setup;
-static char *swtpm_ioctl;
-
-/*
- * qemuTPMEmulatorInit
- *
- * Initialize the Emulator functions by searching for necessary
- * executables that we will use to start and setup the swtpm
- */
-static int
-qemuTPMEmulatorInit(void)
-{
-    if (!swtpm_path) {
-        swtpm_path = virFindFileInPath("swtpm");
-        if (!swtpm_path) {
-            virReportSystemError(ENOENT, "%s",
-                                 _("Unable to find 'swtpm' binary in $PATH"));
-            return -1;
-        }
-        if (!virFileIsExecutable(swtpm_path)) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("TPM emulator %s is not an executable"),
-                           swtpm_path);
-            VIR_FREE(swtpm_path);
-            return -1;
-        }
-    }
-
-    if (!swtpm_setup) {
-        swtpm_setup = virFindFileInPath("swtpm_setup");
-        if (!swtpm_setup) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Could not find 'swtpm_setup' in PATH"));
-            return -1;
-        }
-        if (!virFileIsExecutable(swtpm_setup)) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("'%s' is not an executable"),
-                           swtpm_setup);
-            VIR_FREE(swtpm_setup);
-            return -1;
-        }
-    }
-
-    if (!swtpm_ioctl) {
-        swtpm_ioctl = virFindFileInPath("swtpm_ioctl");
-        if (!swtpm_ioctl) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Could not find swtpm_ioctl in PATH"));
-            return -1;
-        }
-        if (!virFileIsExecutable(swtpm_ioctl)) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("swtpm_ioctl program %s is not an executable"),
-                           swtpm_ioctl);
-            VIR_FREE(swtpm_ioctl);
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
-
 /*
  * qemuTPMCreateEmulatorStoragePath
  *
@@ -345,12 +278,13 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir,
                       pid_t *pid)
 {
     int ret;
+    VIR_AUTOFREE(char *) swtpm = virTPMGetSwtpm();
     char *pidfile = qemuTPMEmulatorCreatePidFilename(swtpmStateDir,
                                                      shortName);
     if (!pidfile)
         return -ENOMEM;
 
-    ret = virPidFileReadPathIfAlive(pidfile, pid, swtpm_path);
+    ret = virPidFileReadPathIfAlive(pidfile, pid, swtpm);
 
     VIR_FREE(pidfile);
 
@@ -386,7 +320,7 @@ qemuTPMEmulatorPrepareHost(virDomainTPMDefPtr tpm,
 {
     int ret = -1;
 
-    if (qemuTPMEmulatorInit() < 0)
+    if (virTPMEmulatorInit() < 0)
         return -1;
 
     /* create log dir ... allow 'tss' user to cd into it */
@@ -471,6 +405,10 @@ qemuTPMEmulatorRunSetup(const char *storagepath,
     int ret = -1;
     char uuid[VIR_UUID_STRING_BUFLEN];
     char *vmid = NULL;
+    VIR_AUTOFREE(char *)swtpm_setup = virTPMGetSwtpmSetup();
+
+    if (!swtpm_setup)
+        return -1;
 
     if (!privileged && tpmversion == VIR_DOMAIN_TPM_VERSION_1_2)
         return virFileWriteStr(logfile,
@@ -562,6 +500,10 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDefPtr tpm,
     virCommandPtr cmd = NULL;
     bool created = false;
     char *pidfile;
+    VIR_AUTOFREE(char *) swtpm = virTPMGetSwtpm();
+
+    if (!swtpm)
+        return NULL;
 
     if (qemuTPMCreateEmulatorStorage(tpm->data.emulator.storagepath,
                                      &created, swtpm_user, swtpm_group) < 0)
@@ -575,7 +517,7 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDefPtr tpm,
 
     unlink(tpm->data.emulator.source.data.nix.path);
 
-    cmd = virCommandNew(swtpm_path);
+    cmd = virCommandNew(swtpm);
     if (!cmd)
         goto error;
 
@@ -639,8 +581,12 @@ qemuTPMEmulatorStop(const char *swtpmStateDir,
     virCommandPtr cmd;
     char *pathname;
     char *errbuf = NULL;
+    VIR_AUTOFREE(char *) swtpm_ioctl = virTPMGetSwtpmIoctl();
+
+    if (!swtpm_ioctl)
+        return;
 
-    if (qemuTPMEmulatorInit() < 0)
+    if (virTPMEmulatorInit() < 0)
         return;
 
     if (!(pathname = qemuTPMCreateEmulatorSocket(swtpmStateDir, shortName)))
index 583b9a64a4039fbf91c11c9c9018416aae01da47..d35848d2f236b6bb22cba398805b7e8a6ee12755 100644 (file)
@@ -72,3 +72,125 @@ virTPMCreateCancelPath(const char *devpath)
  cleanup:
     return path;
 }
+
+/*
+ * executables for the swtpm; to be found on the host
+ */
+static virMutex swtpm_tools_lock = VIR_MUTEX_INITIALIZER;
+static char *swtpm_path;
+static char *swtpm_setup;
+static char *swtpm_ioctl;
+
+char *
+virTPMGetSwtpm(void)
+{
+    char *s;
+
+    if (!swtpm_path && virTPMEmulatorInit() < 0)
+        return NULL;
+
+    virMutexLock(&swtpm_tools_lock);
+    ignore_value(VIR_STRDUP(s, swtpm_path));
+    virMutexUnlock(&swtpm_tools_lock);
+
+    return s;
+}
+
+char *
+virTPMGetSwtpmSetup(void)
+{
+    char *s;
+
+    if (!swtpm_setup && virTPMEmulatorInit() < 0)
+        return NULL;
+
+    virMutexLock(&swtpm_tools_lock);
+    ignore_value(VIR_STRDUP(s, swtpm_setup));
+    virMutexUnlock(&swtpm_tools_lock);
+
+    return s;
+}
+
+char *
+virTPMGetSwtpmIoctl(void)
+{
+    char *s;
+
+    if (!swtpm_ioctl && virTPMEmulatorInit() < 0)
+        return NULL;
+
+    virMutexLock(&swtpm_tools_lock);
+    ignore_value(VIR_STRDUP(s, swtpm_ioctl));
+    virMutexUnlock(&swtpm_tools_lock);
+
+    return s;
+}
+
+/*
+ * virTPMEmulatorInit
+ *
+ * Initialize the Emulator functions by searching for necessary
+ * executables that we will use to start and setup the swtpm
+ */
+int
+virTPMEmulatorInit(void)
+{
+    int ret = -1;
+
+    virMutexLock(&swtpm_tools_lock);
+
+    if (!swtpm_path) {
+        swtpm_path = virFindFileInPath("swtpm");
+        if (!swtpm_path) {
+            virReportSystemError(ENOENT, "%s",
+                                 _("Unable to find 'swtpm' binary in $PATH"));
+            goto cleanup;
+        }
+        if (!virFileIsExecutable(swtpm_path)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("TPM emulator %s is not an executable"),
+                           swtpm_path);
+            VIR_FREE(swtpm_path);
+            goto cleanup;
+        }
+    }
+
+    if (!swtpm_setup) {
+        swtpm_setup = virFindFileInPath("swtpm_setup");
+        if (!swtpm_setup) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Could not find 'swtpm_setup' in PATH"));
+            goto cleanup;
+        }
+        if (!virFileIsExecutable(swtpm_setup)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("'%s' is not an executable"),
+                           swtpm_setup);
+            VIR_FREE(swtpm_setup);
+            goto cleanup;
+        }
+    }
+
+    if (!swtpm_ioctl) {
+        swtpm_ioctl = virFindFileInPath("swtpm_ioctl");
+        if (!swtpm_ioctl) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Could not find swtpm_ioctl in PATH"));
+            goto cleanup;
+        }
+        if (!virFileIsExecutable(swtpm_ioctl)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("swtpm_ioctl program %s is not an executable"),
+                           swtpm_ioctl);
+            VIR_FREE(swtpm_ioctl);
+            goto cleanup;
+        }
+    }
+
+    ret = 0;
+
+ cleanup:
+    virMutexUnlock(&swtpm_tools_lock);
+
+    return ret;
+}
index 4408bdb2175af48ccc7bd1b05812edf9f094eb44..2311f04ae572e4c36dc23ba7566b929c047dd5ca 100644 (file)
@@ -21,3 +21,8 @@
 #pragma once
 
 char *virTPMCreateCancelPath(const char *devpath) ATTRIBUTE_NOINLINE;
+
+char *virTPMGetSwtpm(void);
+char *virTPMGetSwtpmSetup(void);
+char *virTPMGetSwtpmIoctl(void);
+int virTPMEmulatorInit(void);