On Thu, Nov 03, 2016 at 08:18:57PM +0800, Michal Privoznik wrote:
> Now that we are able to store security labels for devices, next
> step is to flush them into a file. For more convenience I've
> chosen JSON format (as we have all the APIs needed for processing
> the format).
> 
> Signed-off-by: Michal Privoznik <mpriv...@redhat.com>
> ---
>  po/POTFILES.in           |   1 +
>  src/libvirt_private.syms |   2 +
>  src/util/virudev.c       | 157 
> +++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/virudev.h       |   5 ++
>  4 files changed, 165 insertions(+)
> 
> diff --git a/po/POTFILES.in b/po/POTFILES.in
> index 1469240..dabc612 100644
> --- a/po/POTFILES.in
> +++ b/po/POTFILES.in
> @@ -248,6 +248,7 @@ src/util/virthreadpool.c
>  src/util/virtime.c
>  src/util/virtpm.c
>  src/util/virtypedparam.c
> +src/util/virudev.c
>  src/util/viruri.c
>  src/util/virusb.c
>  src/util/virutil.c
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 073b00f..ca64c80 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -2579,6 +2579,8 @@ virTypedParamsValidate;
>  
>  # util/virudev.h
>  virUdevMgrAddLabel;
> +virUdevMgrDumpFile;
> +virUdevMgrDumpStr;
>  virUdevMgrNew;
>  virUdevMgrRemoveAllLabels;
>  
> diff --git a/src/util/virudev.c b/src/util/virudev.c
> index f4799e7..7f52149 100644
> --- a/src/util/virudev.c
> +++ b/src/util/virudev.c
> @@ -24,7 +24,9 @@
>  
>  #include "internal.h"
>  #include "viralloc.h"
> +#include "virfile.h"
>  #include "virhash.h"
> +#include "virjson.h"
>  #include "virobject.h"
>  #include "virudev.h"
>  
> @@ -112,6 +114,68 @@ udevSeclabelUpdate(udevSeclabelPtr list,
>  }
>  
>  
> +static virJSONValuePtr
> +udevSeclabelDump(const virSecurityDeviceLabelDef *seclabel)
> +{
> +    virJSONValuePtr object;
> +
> +    if (!(object = virJSONValueNewObject()) ||
> +        virJSONValueObjectAppendString(object, "model", seclabel->model) < 0 
> ||
> +        virJSONValueObjectAppendString(object, "label", seclabel->label) < 0)
> +        goto error;
> +
> +    return object;
> +
> + error:
> +    virJSONValueFree(object);
> +    return NULL;
> +}
> +
> +
> +static int
> +udevSeclabelsDump(void *payload,
> +                  const void *name,
> +                  void *opaque)
> +{
> +    udevSeclabelPtr list = payload;
> +    const char *device = name;
> +    virJSONValuePtr seclabels = opaque;
> +    virJSONValuePtr deviceLabels = NULL;
> +    virJSONValuePtr deviceJSON = NULL;
> +    size_t i;
> +    int ret = -1;
> +
> +    if (!(deviceLabels = virJSONValueNewArray()))
> +        return ret;
> +
> +    for (i = 0; i < list->nseclabels; i++) {
> +        virJSONValuePtr seclabel = udevSeclabelDump(list->seclabels[i]);
> +
> +        if (!seclabel ||
> +            virJSONValueArrayAppend(deviceLabels, seclabel) < 0) {
> +            virJSONValueFree(seclabel);
> +            goto cleanup;
> +        }
> +    }
> +
> +    if (!(deviceJSON = virJSONValueNewObject()) ||
> +        virJSONValueObjectAppendString(deviceJSON, "device", device) < 0 ||
> +        virJSONValueObjectAppend(deviceJSON, "labels", deviceLabels) < 0)
> +        goto cleanup;
> +    deviceLabels = NULL;
> +
> +    if (virJSONValueArrayAppend(seclabels, deviceJSON) < 0)
> +        goto cleanup;
> +    deviceJSON = NULL;
> +
> +    ret = 0;
> + cleanup:
> +    virJSONValueFree(deviceJSON);
> +    virJSONValueFree(deviceLabels);
> +    return ret;
> +}
> +
> +
>  static void
>  virUdevMgrDispose(void *obj)
>  {
> @@ -202,3 +266,96 @@ virUdevMgrRemoveAllLabels(virUdevMgrPtr mgr,
>      virObjectUnlock(mgr);
>      return ret;
>  }
> +
> +
> +static virJSONValuePtr
> +virUdevSeclabelDump(virUdevMgrPtr mgr)
> +{
> +    virJSONValuePtr seclabels;
> +
> +    if (!(seclabels = virJSONValueNewArray()))
> +        return NULL;
> +
> +    if (virHashForEach(mgr->labels, udevSeclabelsDump, seclabels) < 0) {
> +        virJSONValueFree(seclabels);
> +        return NULL;
> +    }
> +
> +    return seclabels;
> +}
> +
> +
> +static char *
> +virUdevMgrDumpInternal(virUdevMgrPtr mgr)
> +{
> +    virJSONValuePtr object = NULL;
> +    virJSONValuePtr child = NULL;
> +    char *ret = NULL;
> +
> +    if (!(object = virJSONValueNewObject()))
> +        goto cleanup;
> +
> +    if (!(child = virUdevSeclabelDump(mgr)))
> +        goto cleanup;
> +
> +    if (virJSONValueObjectAppend(object, "labels", child) < 0) {
> +        virJSONValueFree(child);
> +        goto cleanup;
> +    }
> +
> +    ret = virJSONValueToString(object, true);
> + cleanup:
> +    virJSONValueFree(object);
> +    return ret;
> +}
> +
> +
> +char *
> +virUdevMgrDumpStr(virUdevMgrPtr mgr)
> +{
> +    char *ret;
> +
> +    virObjectLock(mgr);
> +    ret = virUdevMgrDumpInternal(mgr);
> +    virObjectUnlock(mgr);
> +    return ret;
> +}
> +
> +
> +static int
> +virUdevMgrRewriter(int fd, void *opaque)
> +{
> +    const char *str = opaque;
> +
> +    return safewrite(fd, str, strlen(str));
> +}
> +
> +
> +int
> +virUdevMgrDumpFile(virUdevMgrPtr mgr,
> +                   const char *filename)
> +{
> +    int ret = -1;
> +    char *state;
> +
> +    virObjectLock(mgr);
> +
> +    if (!(state = virUdevMgrDumpInternal(mgr)))
> +        goto cleanup;
> +
> +    /* Here we shouldn't use pure virFileWriteStr() as that one is not 
> atomic.
> +     * We can be interrupted in the middle (e.g. due to a context switch) and
> +     * thus leave the file partially written. */
> +    if (virFileRewrite(filename, 0644, virUdevMgrRewriter, state) < 0) {
> +        virReportSystemError(errno,
> +                             _("Unable to save state file %s"),
> +                             filename);
> +        goto cleanup;
> +    }

Dumping the entire DB as a single file is pretty inefficient when you consider
hosts with 1000's of guests with multiple disks attached. As suggested last
time, any database should be one-file per associated disk - there's no
compelling reason to require all disk info to be in a single file AFAICT.


Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to