[libvirt] [PATCH v2 1/3] util: Introduce virDevMapperGetTargets

Peter Krempa pkrempa at redhat.com
Mon Mar 26 15:11:45 UTC 2018


On Mon, Mar 26, 2018 at 16:43:01 +0200, Michal Privoznik wrote:
> This helper fetches dependencies for given device mapper target.
> 
> At the same time, we need to provide a dummy log function because
> by default libdevmapper prints out error messages to stderr which
> we need to suppress.
> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  src/libvirt_private.syms |   4 ++
>  src/util/Makefile.inc.am |   2 +
>  src/util/virdevmapper.c  | 160 +++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/virdevmapper.h  |  32 ++++++++++
>  4 files changed, 198 insertions(+)
>  create mode 100644 src/util/virdevmapper.c
>  create mode 100644 src/util/virdevmapper.h

[...]

> diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c
> new file mode 100644
> index 0000000000..9717482da8
> --- /dev/null
> +++ b/src/util/virdevmapper.c
> @@ -0,0 +1,160 @@
> +/*
> + * virdevmapper.c: Functions for handling devmapper
> + *
> + * Copyright (C) 2018 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library.  If not, see
> + * <http://www.gnu.org/licenses/>.
> + *
> + * Authors:
> + *     Michal Privoznik <mprivozn at redhat.com>
> + */
> +
> +#include <config.h>
> +
> +#ifdef MAJOR_IN_MKDEV
> +# include <sys/mkdev.h>
> +#elif MAJOR_IN_SYSMACROS
> +# include <sys/sysmacros.h>
> +#endif
> +
> +#ifdef WITH_DEVMAPPER
> +# include <libdevmapper.h>
> +#endif
> +
> +#include "virdevmapper.h"
> +#include "internal.h"
> +#include "virthread.h"
> +#include "viralloc.h"
> +
> +#ifdef WITH_DEVMAPPER
> +static void
> +virDevMapperDummyLogger(int level ATTRIBUTE_UNUSED,
> +                        const char *file ATTRIBUTE_UNUSED,
> +                        int line ATTRIBUTE_UNUSED,
> +                        int dm_errno ATTRIBUTE_UNUSED,
> +                        const char *fmt ATTRIBUTE_UNUSED,
> +                        ...)
> +{
> +    return;
> +}
> +
> +static int
> +virDevMapperOnceInit(void)
> +{
> +    /* Ideally, we would not need this. But libdevmapper prints
> +     * error messages to stderr by default. Sad but true. */
> +    dm_log_with_errno_init(virDevMapperDummyLogger);
> +    return 0;
> +}
> +
> +
> +VIR_ONCE_GLOBAL_INIT(virDevMapper)
> +
> +/**
> + * virDevMapperGetTargets:
> + * @path: multipath device
> + * @maj: returned array of MAJOR device numbers
> + * @min: returner array of MINOR device numbers
> + * @nmaj: number of items in @maj array
> + *
> + * For given @path figure out its targets, and store them in @maj
> + * and @min arrays. Both arrays have the same number of items
> + * upon return.
> + *
> + * If @path is not a multipath device, @ndevs is set to 0 and
> + * success is returned.
> + *
> + * If we don't have permissions to talk to kernel, -1 is returned
> + * and errno is set to EBADF.
> + *
> + * Returns 0 on success,
> + *        -1 otherwise (with errno set, no libvirt error is
> + *        reported)
> + */
> +int
> +virDevMapperGetTargets(const char *path,
> +                       unsigned int **maj,
> +                       unsigned int **min,
> +                       size_t *nmaj)
> +{
> +    struct dm_task *dmt = NULL;
> +    struct dm_deps *deps;
> +    struct dm_info info;
> +    size_t i;
> +    int ret = -1;
> +
> +    *nmaj = 0;
> +
> +    if (virDevMapperInitialize() < 0)
> +        goto cleanup;

[1]

> +
> +    if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
> +        goto cleanup;

[1]

> +
> +    if (!dm_task_set_name(dmt, path)) {
> +        if (errno == ENOENT) {
> +            /* It's okay, @path is not managed by devmapper =>
> +             * not a multipath device. */
> +            ret = 0;
> +        }
> +        goto cleanup;
> +    }
> +
> +    dm_task_no_open_count(dmt);
> +
> +    if (!dm_task_run(dmt))
> +        goto cleanup;
> +
> +    if (!dm_task_get_info(dmt, &info))
> +        goto cleanup;
> +
> +    if (!info.exists) {
> +        ret = 0;
> +        goto cleanup;
> +    }
> +
> +    if (!(deps = dm_task_get_deps(dmt)))
> +        goto cleanup;
> +
> +    if (VIR_ALLOC_N_QUIET(*maj, deps->count) < 0 ||
> +        VIR_ALLOC_N_QUIET(*min, deps->count) < 0) {
> +        VIR_FREE(*maj);
> +        goto cleanup;
> +    }
> +    *nmaj = deps->count;
> +
> +    for (i = 0; i < deps->count; i++) {
> +        (*maj)[i] = major(deps->device[i]);
> +        (*min)[i] = minor(deps->device[i]);
> +    }
> +
> +    ret = 0;
> + cleanup:
> +    dm_task_destroy(dmt);

[1] dm_task_destroy dereferences the argument without checking it for
NULL first. Replace the two jumps above with direct returns.


> +    return ret;
> +}
> +
> +#else /* ! WITH_DEVMAPPER */
> +
> +int
> +virDevMapperGetTargets(const char *path ATTRIBUTE_UNUSED,
> +                       unsigned int **maj ATTRIBUTE_UNUSED,
> +                       unsigned int **min ATTRIBUTE_UNUSED,
> +                       size_t *nmaj ATTRIBUTE_UNUSED)
> +{
> +    errno = ENOSYS;
> +    return -1;
> +}
> +#endif /* ! WITH_DEVMAPPER */
> diff --git a/src/util/virdevmapper.h b/src/util/virdevmapper.h
> new file mode 100644
> index 0000000000..e88ac0f8ce
> --- /dev/null
> +++ b/src/util/virdevmapper.h
> @@ -0,0 +1,32 @@
> +/*
> + * virdevmapper.h: Functions for handling devmapper
> + *
> + * Copyright (C) 2018 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library.  If not, see
> + * <http://www.gnu.org/licenses/>.
> + *
> + * Authors:
> + *     Michal Privoznik <mprivozn at redhat.com>
> + */
> +
> +#ifndef __VIR_DEVMAPPER_H__
> +# define __VIR_DEVMAPPER_H__
> +
> +int virDevMapperGetTargets(const char *path,
> +                           unsigned int **maj,
> +                           unsigned int **min,
> +                           size_t *nmaj);

Please adhere to the new coding style guidelines for new files.

ACK with the two things above addressed.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20180326/61bfa353/attachment-0001.sig>


More information about the libvir-list mailing list