On Fri, Jul 12, 2019 at 12:23:44PM -0400, Stefan Berger wrote: > Run 'swtpm socket --print-capabilities' and > 'swtpm_setup --print-capabilities' to get the JSON object of the > features the programs are supporting and parse them into a bitmap. > > Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxx> > --- > src/libvirt_private.syms | 2 + > src/util/virtpm.c | 134 +++++++++++++++++++++++++++++++++++++-- > src/util/virtpm.h | 15 +++++ > 3 files changed, 147 insertions(+), 4 deletions(-) > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 5b3c176862..5200adae3f 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -3181,6 +3181,8 @@ virTPMEmulatorInit; > virTPMGetSwtpm; > virTPMGetSwtpmIoctl; > virTPMGetSwtpmSetup; > +virTPMSwtpmFeatureTypeFromString; > +virTPMSwtpmSetupFeatureTypeFromString; > > > # util/virtypedparam.h > diff --git a/src/util/virtpm.c b/src/util/virtpm.c > index e4735f9c4d..692033e899 100644 > --- a/src/util/virtpm.c > +++ b/src/util/virtpm.c > @@ -27,9 +27,22 @@ > #include "viralloc.h" > #include "virfile.h" > #include "virtpm.h" > +#include "vircommand.h" > +#include "virbitmap.h" > +#include "virjson.h" > > #define VIR_FROM_THIS VIR_FROM_NONE > > +VIR_ENUM_IMPL(virTPMSwtpmFeature, > + VIR_TPM_SWTPM_FEATURE_LAST, > + "cmdarg-pwd-fd", > +); > + > +VIR_ENUM_IMPL(virTPMSwtpmSetupFeature, > + VIR_TPM_SWTPM_SETUP_FEATURE_LAST, > + "cmdarg-pwdfile-fd", > +); > + > /** > * virTPMCreateCancelPath: > * @devpath: Path to the TPM device > @@ -74,17 +87,22 @@ virTPMCreateCancelPath(const char *devpath) > } > > /* > - * executables for the swtpm; to be found on the host > + * executables for the swtpm; to be found on the host along with > + * capabilties bitmap > */ > static char *swtpm_path; > static struct stat swtpm_stat; > +static virBitmapPtr swtpm_caps; > > static char *swtpm_setup; > static struct stat swtpm_setup_stat; > +static virBitmapPtr swtpm_setup_caps; > > static char *swtpm_ioctl; > static struct stat swtpm_ioctl_stat; > > +typedef int (*TypeFromStringFn)(const char *); > + > const char * > virTPMGetSwtpm(void) > { > @@ -109,6 +127,99 @@ virTPMGetSwtpmIoctl(void) > return swtpm_ioctl; > } > > +/* virTPMExecGetCaps > + * > + * Execute the prepared command and parse the returned JSON object > + * to get the capabilities supported by the executable. > + * A JSON object like this is expected: > + * > + * { > + * "type": "swtpm", > + * "features": [ > + * "cmdarg-seccomp", > + * "cmdarg-key-fd", > + * "cmdarg-pwd-fd" > + * ] > + * } > + */ > +static virBitmapPtr > +virTPMExecGetCaps(virCommandPtr cmd, > + TypeFromStringFn typeFromStringFn) > +{ > + int exitstatus; > + virBitmapPtr bitmap; > + VIR_AUTOFREE(char *) outbuf = NULL; > + VIR_AUTOPTR(virJSONValue) json = NULL; > + virJSONValuePtr featureList; > + virJSONValuePtr item; > + size_t idx; > + const char *str; > + int typ; > + > + virCommandSetOutputBuffer(cmd, &outbuf); > + if (virCommandRun(cmd, &exitstatus) < 0) > + return NULL; > + > + if (!(bitmap = virBitmapNewEmpty())) > + return NULL; > + > + /* older version does not support --print-capabilties -- that's fine */ > + if (exitstatus != 0) > + return bitmap; We can't distinguish from an old version that lacks --print-capabilties and from a new version that crashed when running --print-capabilties. The latter shouldn't happen in general, but I thin kwe ought to at least put a VIR_DEBUG in here to make it obvious we're treating this as if we hit an old binary when looking at logs. > + > + json = virJSONValueFromString(outbuf); > + if (!json) > + goto error_bad_json; > + > + featureList = virJSONValueObjectGetArray(json, "features"); > + if (!featureList) > + goto error_bad_json; > + > + if (!virJSONValueIsArray(featureList)) > + goto error_bad_json; > + > + for (idx = 0; idx < virJSONValueArraySize(featureList); idx++) { > + item = virJSONValueArrayGet(featureList, idx); > + if (!item) > + continue; > + > + str = virJSONValueGetString(item); > + if (!str) > + goto error_bad_json; > + typ = typeFromStringFn(str); > + if (typ < 0) > + continue; > + > + if (virBitmapSetBitExpand(bitmap, typ) < 0) > + goto cleanup; > + } > + > + cleanup: > + return bitmap; > + > + error_bad_json: > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Unexpected JSON format: %s"), outbuf); > + goto cleanup; > +} > @@ -142,7 +261,7 @@ virTPMEmulatorInit(void) > size_t i; > > for (i = 0; i < ARRAY_CARDINALITY(prgs); i++) { > - char *path; > + VIR_AUTOFREE(char *) path = NULL; > bool findit = *prgs[i].path == NULL; > struct stat statbuf; > char *tmp; > @@ -174,18 +293,25 @@ virTPMEmulatorInit(void) > virReportError(VIR_ERR_INTERNAL_ERROR, > _("%s is not an executable"), > path); > - VIR_FREE(path); > return -1; > } > if (stat(path, prgs[i].stat) < 0) { > virReportSystemError(errno, > _("Could not stat %s"), path); > - VIR_FREE(path); > return -1; > } If you re-post this series, just use VIR_AUTOFREE straightaway in the earlier patch. With the debug line added Reviewed-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list