mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
qemu: Read back the profile name after creation of a TPM instance
Get the JSON profile that the swtpm instance was created with from the output of 'swtpm socket --tpm2 --print-info 0x20 --tpmstate ...'. Get the name of the profile from the JSON and set it in the current and persistent emulator descriptions as 'name' attribute and have the persistent description stored with this update. The user should avoid setting this 'name' attribute since it is meant to be read-only. The following is an example of how the XML could look like: <profile source='local:restricted' name='custom:restricted'/> If the user provided no profile node, and therefore swtpm_setup picked its default profile, the XML may now shows the 'name' attribute with the name of the profile. This makes the 'source' attribute now optional. <profile name='default-v1'/> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
957bda01c8
commit
d79542eec6
@ -8135,7 +8135,7 @@ Example: usage of the TPM Emulator
|
|||||||
<active_pcr_banks>
|
<active_pcr_banks>
|
||||||
<sha256/>
|
<sha256/>
|
||||||
</active_pcr_banks>
|
</active_pcr_banks>
|
||||||
<profile source='local:restricted' removeDisabled='check'/>
|
<profile source='local:restricted' removeDisabled='check' name='custom:restricted'/>
|
||||||
</backend>
|
</backend>
|
||||||
</tpm>
|
</tpm>
|
||||||
</devices>
|
</devices>
|
||||||
@ -8233,12 +8233,14 @@ Example: usage of the TPM Emulator
|
|||||||
``profile``
|
``profile``
|
||||||
The ``profile`` node is used to set a profile for a TPM 2.0 given in the
|
The ``profile`` node is used to set a profile for a TPM 2.0 given in the
|
||||||
source attribute. This profile will be set when the TPM is initially
|
source attribute. This profile will be set when the TPM is initially
|
||||||
created and after that cannot be changed anymore. If no profile is provided,
|
created and after that cannot be changed anymore. Once a profile has been
|
||||||
then swtpm will use the latest built-in 'default' profile or the default
|
set the name attribute will be updated with the name of the profile that
|
||||||
profile set in swtpm_setup.conf. Otherwise swtpm_setup will search for a
|
is running. If no profile is provided, then swtpm will use the latest
|
||||||
profile with the given name with appended .json suffix in a configurable
|
built-in 'default' profile or the default profile set in swtpm_setup.conf.
|
||||||
local and then in a distro directory. If none could be found in either, it
|
Otherwise swtpm_setup will search for a profile with the given name with
|
||||||
will fall back trying to use a built-in one.
|
appended .json suffix in a configurable local and then in a distro
|
||||||
|
directory. If none could be found in either, it will fall back trying to
|
||||||
|
use a built-in one.
|
||||||
|
|
||||||
The built-in 'null' profile provides backwards compatibility with
|
The built-in 'null' profile provides backwards compatibility with
|
||||||
libtpms v0.9 but also restricts the user to use only TPM features that were
|
libtpms v0.9 but also restricts the user to use only TPM features that were
|
||||||
|
@ -3479,6 +3479,7 @@ void virDomainTPMDefFree(virDomainTPMDef *def)
|
|||||||
g_free(def->data.emulator.logfile);
|
g_free(def->data.emulator.logfile);
|
||||||
virBitmapFree(def->data.emulator.activePcrBanks);
|
virBitmapFree(def->data.emulator.activePcrBanks);
|
||||||
g_free(def->data.emulator.profile.source);
|
g_free(def->data.emulator.profile.source);
|
||||||
|
g_free(def->data.emulator.profile.name);
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
|
case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
|
||||||
virObjectUnref(def->data.external.source);
|
virObjectUnref(def->data.external.source);
|
||||||
@ -10925,10 +10926,7 @@ virDomainTPMDefParseXML(virDomainXMLOption *xmlopt,
|
|||||||
|
|
||||||
if ((profile = virXPathNode("./backend/profile[1]", ctxt))) {
|
if ((profile = virXPathNode("./backend/profile[1]", ctxt))) {
|
||||||
def->data.emulator.profile.source = virXMLPropString(profile, "source");
|
def->data.emulator.profile.source = virXMLPropString(profile, "source");
|
||||||
if (!def->data.emulator.profile.source) {
|
def->data.emulator.profile.name = virXMLPropString(profile, "name");
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s", _("missing profile source"));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (virXMLPropEnum(profile, "removeDisabled",
|
if (virXMLPropEnum(profile, "removeDisabled",
|
||||||
virDomainTPMProfileRemoveDisabledTypeFromString,
|
virDomainTPMProfileRemoveDisabledTypeFromString,
|
||||||
VIR_XML_PROP_NONZERO,
|
VIR_XML_PROP_NONZERO,
|
||||||
@ -25139,16 +25137,23 @@ virDomainTPMDefFormat(virBuffer *buf,
|
|||||||
virDomainTPMSourceTypeTypeToString(def->data.emulator.source_type));
|
virDomainTPMSourceTypeTypeToString(def->data.emulator.source_type));
|
||||||
virBufferEscapeString(&backendChildBuf, " path='%s'/>\n", def->data.emulator.source_path);
|
virBufferEscapeString(&backendChildBuf, " path='%s'/>\n", def->data.emulator.source_path);
|
||||||
}
|
}
|
||||||
if (def->data.emulator.profile.source) {
|
if (def->data.emulator.profile.source ||
|
||||||
|
def->data.emulator.profile.name) {
|
||||||
g_auto(virBuffer) profileAttrBuf = VIR_BUFFER_INITIALIZER;
|
g_auto(virBuffer) profileAttrBuf = VIR_BUFFER_INITIALIZER;
|
||||||
|
|
||||||
virBufferAsprintf(&profileAttrBuf, " source='%s'",
|
if (def->data.emulator.profile.source) {
|
||||||
def->data.emulator.profile.source);
|
virBufferAsprintf(&profileAttrBuf, " source='%s'",
|
||||||
|
def->data.emulator.profile.source);
|
||||||
|
}
|
||||||
if (def->data.emulator.profile.removeDisabled) {
|
if (def->data.emulator.profile.removeDisabled) {
|
||||||
virBufferAsprintf(&profileAttrBuf, " removeDisabled='%s'",
|
virBufferAsprintf(&profileAttrBuf, " removeDisabled='%s'",
|
||||||
virDomainTPMProfileRemoveDisabledTypeToString(def->data.emulator.profile.removeDisabled));
|
virDomainTPMProfileRemoveDisabledTypeToString(def->data.emulator.profile.removeDisabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (def->data.emulator.profile.name) {
|
||||||
|
virBufferAsprintf(&profileAttrBuf, " name='%s'",
|
||||||
|
def->data.emulator.profile.name);
|
||||||
|
}
|
||||||
virXMLFormatElement(&backendChildBuf, "profile", &profileAttrBuf, NULL);
|
virXMLFormatElement(&backendChildBuf, "profile", &profileAttrBuf, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1494,6 +1494,7 @@ struct _virDomainTPMEmulatorDef {
|
|||||||
virBitmap *activePcrBanks;
|
virBitmap *activePcrBanks;
|
||||||
struct {
|
struct {
|
||||||
char *source; /* 'source' profile was created from */
|
char *source; /* 'source' profile was created from */
|
||||||
|
char *name; /* name read from active profile */
|
||||||
virDomainTPMProfileRemoveDisabled removeDisabled;
|
virDomainTPMProfileRemoveDisabled removeDisabled;
|
||||||
} profile;
|
} profile;
|
||||||
};
|
};
|
||||||
|
@ -6061,9 +6061,11 @@
|
|||||||
<define name="tpm-backend-emulator-profile">
|
<define name="tpm-backend-emulator-profile">
|
||||||
<optional>
|
<optional>
|
||||||
<element name="profile">
|
<element name="profile">
|
||||||
<attribute name="source">
|
<optional>
|
||||||
<ref name="profileName"/>
|
<attribute name="source">
|
||||||
</attribute>
|
<ref name="profileName"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
<optional>
|
<optional>
|
||||||
<attribute name="removeDisabled">
|
<attribute name="removeDisabled">
|
||||||
<choice>
|
<choice>
|
||||||
@ -6072,6 +6074,11 @@
|
|||||||
</choice>
|
</choice>
|
||||||
</attribute>
|
</attribute>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="name">
|
||||||
|
<ref name="profileName"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
</define>
|
</define>
|
||||||
|
@ -175,6 +175,7 @@ qemuExtDevicesStart(virQEMUDriver *driver,
|
|||||||
virDomainObj *vm,
|
virDomainObj *vm,
|
||||||
bool incomingMigration)
|
bool incomingMigration)
|
||||||
{
|
{
|
||||||
|
virDomainDef *persistentDef = vm->newDef;
|
||||||
virDomainDef *def = vm->def;
|
virDomainDef *def = vm->def;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
@ -189,9 +190,11 @@ qemuExtDevicesStart(virQEMUDriver *driver,
|
|||||||
|
|
||||||
for (i = 0; i < def->ntpms; i++) {
|
for (i = 0; i < def->ntpms; i++) {
|
||||||
virDomainTPMDef *tpm = def->tpms[i];
|
virDomainTPMDef *tpm = def->tpms[i];
|
||||||
|
virDomainTPMDef *persistentTPMDef = persistentDef->tpms[i];
|
||||||
|
|
||||||
if (tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR &&
|
if (tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR &&
|
||||||
qemuExtTPMStart(driver, vm, tpm, incomingMigration) < 0)
|
qemuExtTPMStart(driver, vm, tpm, persistentTPMDef,
|
||||||
|
incomingMigration) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,15 +628,89 @@ qemuTPMVirCommandSwtpmAddTPMState(virCommand *cmd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* qemuTPMEmulatorUpdateProfileName:
|
||||||
|
*
|
||||||
|
* @emulator: TPM emulator definition
|
||||||
|
* @persistentTPMDef: TPM definition from the persistent domain definition
|
||||||
|
* @cfg: virQEMUDriverConfig
|
||||||
|
* @saveDef: whether caller should save the persistent domain def
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
qemuTPMEmulatorUpdateProfileName(virDomainTPMEmulatorDef *emulator,
|
||||||
|
virDomainTPMDef *persistentTPMDef,
|
||||||
|
const virQEMUDriverConfig *cfg,
|
||||||
|
bool *saveDef)
|
||||||
|
{
|
||||||
|
g_autoptr(virJSONValue) object = NULL;
|
||||||
|
g_autofree char *stderr_buf = NULL;
|
||||||
|
g_autofree char *stdout_buf = NULL;
|
||||||
|
g_autoptr(virCommand) cmd = NULL;
|
||||||
|
g_autofree char *swtpm = NULL;
|
||||||
|
virJSONValue *active_profile;
|
||||||
|
const char *profile_name;
|
||||||
|
int exitstatus;
|
||||||
|
|
||||||
|
if (emulator->version != VIR_DOMAIN_TPM_VERSION_2_0 ||
|
||||||
|
!virTPMSwtpmCapsGet(VIR_TPM_SWTPM_FEATURE_CMDARG_PRINT_INFO))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
swtpm = virTPMGetSwtpm();
|
||||||
|
if (!swtpm)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
cmd = virCommandNew(swtpm);
|
||||||
|
|
||||||
|
virCommandSetUID(cmd, cfg->swtpm_user); /* should be uid of 'tss' or 'root' */
|
||||||
|
virCommandSetGID(cmd, cfg->swtpm_group);
|
||||||
|
|
||||||
|
virCommandAddArgList(cmd, "socket", "--print-info", "0x20", "--tpm2", NULL);
|
||||||
|
|
||||||
|
qemuTPMVirCommandSwtpmAddTPMState(cmd, emulator);
|
||||||
|
|
||||||
|
if (qemuTPMVirCommandSwtpmAddEncryption(cmd, emulator, swtpm) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
virCommandClearCaps(cmd);
|
||||||
|
|
||||||
|
virCommandSetOutputBuffer(cmd, &stdout_buf);
|
||||||
|
virCommandSetErrorBuffer(cmd, &stderr_buf);
|
||||||
|
|
||||||
|
if (virCommandRun(cmd, &exitstatus) < 0 || exitstatus != 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Could not run '%1$s --print-info'. exitstatus: %2$d; stderr: %3$s"),
|
||||||
|
swtpm, exitstatus, stderr_buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(object = virJSONValueFromString(stdout_buf)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!(active_profile = virJSONValueObjectGetObject(object, "ActiveProfile")))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
profile_name = virJSONValueObjectGetString(active_profile, "Name");
|
||||||
|
|
||||||
|
g_free(emulator->profile.name);
|
||||||
|
emulator->profile.name = g_strdup(profile_name);
|
||||||
|
|
||||||
|
*saveDef = true;
|
||||||
|
g_free(persistentTPMDef->data.emulator.profile.name);
|
||||||
|
persistentTPMDef->data.emulator.profile.name = g_strdup(profile_name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* qemuTPMEmulatorBuildCommand:
|
* qemuTPMEmulatorBuildCommand:
|
||||||
*
|
*
|
||||||
* @tpm: TPM definition
|
* @tpm: TPM definition
|
||||||
|
* @persistentTPMDef: TPM definition from the persistent domain definition
|
||||||
* @vmname: The name of the VM
|
* @vmname: The name of the VM
|
||||||
* @vmuuid: The UUID of the VM
|
* @vmuuid: The UUID of the VM
|
||||||
* @privileged: whether we are running in privileged mode
|
* @privileged: whether we are running in privileged mode
|
||||||
* @cfg: virQEMUDriverConfig
|
* @cfg: virQEMUDriverConfig
|
||||||
* @incomingMigration: whether we have an incoming migration
|
* @incomingMigration: whether we have an incoming migration
|
||||||
|
* @saveDef: whether caller should save the persistent domain def
|
||||||
*
|
*
|
||||||
* Create the virCommand use for starting the emulator
|
* Create the virCommand use for starting the emulator
|
||||||
* Do some initializations on the way, such as creation of storage
|
* Do some initializations on the way, such as creation of storage
|
||||||
@ -644,11 +718,13 @@ qemuTPMVirCommandSwtpmAddTPMState(virCommand *cmd,
|
|||||||
*/
|
*/
|
||||||
static virCommand *
|
static virCommand *
|
||||||
qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
|
qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
|
||||||
|
virDomainTPMDef *persistentTPMDef,
|
||||||
const char *vmname,
|
const char *vmname,
|
||||||
const unsigned char *vmuuid,
|
const unsigned char *vmuuid,
|
||||||
bool privileged,
|
bool privileged,
|
||||||
const virQEMUDriverConfig *cfg,
|
const virQEMUDriverConfig *cfg,
|
||||||
bool incomingMigration)
|
bool incomingMigration,
|
||||||
|
bool *saveDef)
|
||||||
{
|
{
|
||||||
g_autoptr(virCommand) cmd = NULL;
|
g_autoptr(virCommand) cmd = NULL;
|
||||||
bool created = false;
|
bool created = false;
|
||||||
@ -697,6 +773,11 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
|
|||||||
incomingMigration) < 0)
|
incomingMigration) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (run_setup && !incomingMigration &&
|
||||||
|
qemuTPMEmulatorUpdateProfileName(&tpm->data.emulator, persistentTPMDef,
|
||||||
|
cfg, saveDef) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (!incomingMigration &&
|
if (!incomingMigration &&
|
||||||
qemuTPMEmulatorReconfigure(&tpm->data.emulator, cfg, secretuuid) < 0)
|
qemuTPMEmulatorReconfigure(&tpm->data.emulator, cfg, secretuuid) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -996,6 +1077,7 @@ qemuExtTPMEmulatorSetupCgroup(const char *swtpmStateDir,
|
|||||||
* @driver: QEMU driver
|
* @driver: QEMU driver
|
||||||
* @vm: the domain object
|
* @vm: the domain object
|
||||||
* @tpm: TPM definition
|
* @tpm: TPM definition
|
||||||
|
* @persistentTPMDef: TPM definition from persistent domain definition
|
||||||
* @shortName: short and unique name of the domain
|
* @shortName: short and unique name of the domain
|
||||||
* @incomingMigration: whether we have an incoming migration
|
* @incomingMigration: whether we have an incoming migration
|
||||||
*
|
*
|
||||||
@ -1008,6 +1090,7 @@ qemuTPMEmulatorStart(virQEMUDriver *driver,
|
|||||||
virDomainObj *vm,
|
virDomainObj *vm,
|
||||||
const char *shortName,
|
const char *shortName,
|
||||||
virDomainTPMDef *tpm,
|
virDomainTPMDef *tpm,
|
||||||
|
virDomainTPMDef *persistentTPMDef,
|
||||||
bool incomingMigration)
|
bool incomingMigration)
|
||||||
{
|
{
|
||||||
g_autoptr(virCommand) cmd = NULL;
|
g_autoptr(virCommand) cmd = NULL;
|
||||||
@ -1016,6 +1099,7 @@ qemuTPMEmulatorStart(virQEMUDriver *driver,
|
|||||||
g_autofree char *pidfile = NULL;
|
g_autofree char *pidfile = NULL;
|
||||||
virTimeBackOffVar timebackoff;
|
virTimeBackOffVar timebackoff;
|
||||||
const unsigned long long timeout = 1000; /* ms */
|
const unsigned long long timeout = 1000; /* ms */
|
||||||
|
bool saveDef = false;
|
||||||
pid_t pid = -1;
|
pid_t pid = -1;
|
||||||
bool lockMetadataException = false;
|
bool lockMetadataException = false;
|
||||||
|
|
||||||
@ -1024,12 +1108,18 @@ qemuTPMEmulatorStart(virQEMUDriver *driver,
|
|||||||
/* stop any left-over TPM emulator for this VM */
|
/* stop any left-over TPM emulator for this VM */
|
||||||
qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName);
|
qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName);
|
||||||
|
|
||||||
if (!(cmd = qemuTPMEmulatorBuildCommand(tpm, vm->def->name, vm->def->uuid,
|
if (!(cmd = qemuTPMEmulatorBuildCommand(tpm, persistentTPMDef,
|
||||||
|
vm->def->name, vm->def->uuid,
|
||||||
driver->privileged,
|
driver->privileged,
|
||||||
cfg,
|
cfg,
|
||||||
incomingMigration)))
|
incomingMigration,
|
||||||
|
&saveDef)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (saveDef &&
|
||||||
|
virDomainDefSave(vm->newDef, driver->xmlopt, cfg->configDir) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (qemuExtDeviceLogCommand(driver, vm, cmd, "TPM Emulator") < 0)
|
if (qemuExtDeviceLogCommand(driver, vm, cmd, "TPM Emulator") < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1213,6 +1303,7 @@ int
|
|||||||
qemuExtTPMStart(virQEMUDriver *driver,
|
qemuExtTPMStart(virQEMUDriver *driver,
|
||||||
virDomainObj *vm,
|
virDomainObj *vm,
|
||||||
virDomainTPMDef *tpm,
|
virDomainTPMDef *tpm,
|
||||||
|
virDomainTPMDef *persistentTPMDef,
|
||||||
bool incomingMigration)
|
bool incomingMigration)
|
||||||
{
|
{
|
||||||
g_autofree char *shortName = virDomainDefGetShortName(vm->def);
|
g_autofree char *shortName = virDomainDefGetShortName(vm->def);
|
||||||
@ -1220,7 +1311,8 @@ qemuExtTPMStart(virQEMUDriver *driver,
|
|||||||
if (!shortName)
|
if (!shortName)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return qemuTPMEmulatorStart(driver, vm, shortName, tpm, incomingMigration);
|
return qemuTPMEmulatorStart(driver, vm, shortName, tpm, persistentTPMDef,
|
||||||
|
incomingMigration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,9 +44,10 @@ void qemuExtTPMCleanupHost(virQEMUDriver *driver,
|
|||||||
int qemuExtTPMStart(virQEMUDriver *driver,
|
int qemuExtTPMStart(virQEMUDriver *driver,
|
||||||
virDomainObj *vm,
|
virDomainObj *vm,
|
||||||
virDomainTPMDef *def,
|
virDomainTPMDef *def,
|
||||||
|
virDomainTPMDef *persistentDefTPM,
|
||||||
bool incomingMigration)
|
bool incomingMigration)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
|
||||||
ATTRIBUTE_NONNULL(3)
|
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
|
||||||
G_GNUC_WARN_UNUSED_RESULT;
|
G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
void qemuExtTPMStop(virQEMUDriver *driver,
|
void qemuExtTPMStop(virQEMUDriver *driver,
|
||||||
|
@ -42,6 +42,7 @@ VIR_ENUM_IMPL(virTPMSwtpmFeature,
|
|||||||
"cmdarg-migration",
|
"cmdarg-migration",
|
||||||
"nvram-backend-dir",
|
"nvram-backend-dir",
|
||||||
"nvram-backend-file",
|
"nvram-backend-file",
|
||||||
|
"cmdarg-print-info",
|
||||||
);
|
);
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virTPMSwtpmSetupFeature,
|
VIR_ENUM_IMPL(virTPMSwtpmSetupFeature,
|
||||||
|
@ -33,6 +33,7 @@ typedef enum {
|
|||||||
VIR_TPM_SWTPM_FEATURE_CMDARG_MIGRATION,
|
VIR_TPM_SWTPM_FEATURE_CMDARG_MIGRATION,
|
||||||
VIR_TPM_SWTPM_FEATURE_NVRAM_BACKEND_DIR,
|
VIR_TPM_SWTPM_FEATURE_NVRAM_BACKEND_DIR,
|
||||||
VIR_TPM_SWTPM_FEATURE_NVRAM_BACKEND_FILE,
|
VIR_TPM_SWTPM_FEATURE_NVRAM_BACKEND_FILE,
|
||||||
|
VIR_TPM_SWTPM_FEATURE_CMDARG_PRINT_INFO,
|
||||||
|
|
||||||
VIR_TPM_SWTPM_FEATURE_LAST
|
VIR_TPM_SWTPM_FEATURE_LAST
|
||||||
} virTPMSwtpmFeature;
|
} virTPMSwtpmFeature;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<input type='keyboard' bus='ps2'/>
|
<input type='keyboard' bus='ps2'/>
|
||||||
<tpm model='tpm-crb'>
|
<tpm model='tpm-crb'>
|
||||||
<backend type='emulator' version='2.0'>
|
<backend type='emulator' version='2.0'>
|
||||||
<profile source='local:restricted' removeDisabled='check'/>
|
<profile source='local:restricted' removeDisabled='check' name='custom:restricted'/>
|
||||||
</backend>
|
</backend>
|
||||||
</tpm>
|
</tpm>
|
||||||
<audio id='1' type='none'/>
|
<audio id='1' type='none'/>
|
||||||
|
Loading…
Reference in New Issue
Block a user