diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ff5a77b0e2..4cdbb80596 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3177,6 +3177,10 @@ virTimeStringThenRaw; # util/virtpm.h virTPMCreateCancelPath; +virTPMEmulatorInit; +virTPMGetSwtpm; +virTPMGetSwtpmIoctl; +virTPMGetSwtpmSetup; # util/virtypedparam.h diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c index cc8c69433b..7282b01bfe 100644 --- a/src/qemu/qemu_tpm.c +++ b/src/qemu/qemu_tpm.c @@ -41,79 +41,12 @@ #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 (qemuTPMEmulatorInit() < 0) + if (!swtpm_ioctl) + return; + + if (virTPMEmulatorInit() < 0) return; if (!(pathname = qemuTPMCreateEmulatorSocket(swtpmStateDir, shortName))) diff --git a/src/util/virtpm.c b/src/util/virtpm.c index 583b9a64a4..d35848d2f2 100644 --- a/src/util/virtpm.c +++ b/src/util/virtpm.c @@ -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; +} diff --git a/src/util/virtpm.h b/src/util/virtpm.h index 4408bdb217..2311f04ae5 100644 --- a/src/util/virtpm.h +++ b/src/util/virtpm.h @@ -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);