mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 11:31:16 +00:00
util: Introduce virDevMapperGetTargets
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@redhat.com>
This commit is contained in:
parent
3487973ee0
commit
fd9d1e686d
@ -1670,6 +1670,10 @@ virDBusMessageUnref;
|
|||||||
virDBusSetSharedBus;
|
virDBusSetSharedBus;
|
||||||
|
|
||||||
|
|
||||||
|
# util/virdevmapper.h
|
||||||
|
virDevMapperGetTargets;
|
||||||
|
|
||||||
|
|
||||||
# util/virdnsmasq.h
|
# util/virdnsmasq.h
|
||||||
dnsmasqAddDhcpHost;
|
dnsmasqAddDhcpHost;
|
||||||
dnsmasqAddHost;
|
dnsmasqAddHost;
|
||||||
|
@ -35,6 +35,8 @@ UTIL_SOURCES = \
|
|||||||
util/virdbus.c \
|
util/virdbus.c \
|
||||||
util/virdbus.h \
|
util/virdbus.h \
|
||||||
util/virdbuspriv.h \
|
util/virdbuspriv.h \
|
||||||
|
util/virdevmapper.c \
|
||||||
|
util/virdevmapper.h \
|
||||||
util/virdnsmasq.c \
|
util/virdnsmasq.c \
|
||||||
util/virdnsmasq.h \
|
util/virdnsmasq.h \
|
||||||
util/virebtables.c \
|
util/virebtables.c \
|
||||||
|
199
src/util/virdevmapper.c
Normal file
199
src/util/virdevmapper.c
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
* virdevmapper.c: Functions for handling device mapper
|
||||||
|
*
|
||||||
|
* 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@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"
|
||||||
|
#include "virstring.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)
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDevMapperGetTargetsImpl(const char *path,
|
||||||
|
char ***devPaths_ret,
|
||||||
|
unsigned int ttl)
|
||||||
|
{
|
||||||
|
struct dm_task *dmt = NULL;
|
||||||
|
struct dm_deps *deps;
|
||||||
|
struct dm_info info;
|
||||||
|
char **devPaths = NULL;
|
||||||
|
char **recursiveDevPaths = NULL;
|
||||||
|
size_t i;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
*devPaths_ret = NULL;
|
||||||
|
|
||||||
|
if (virDevMapperInitialize() < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (ttl == 0) {
|
||||||
|
errno = ELOOP;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!dm_task_set_name(dmt, path)) {
|
||||||
|
if (errno == ENOENT) {
|
||||||
|
/* It's okay, @path is not managed by devmapper =>
|
||||||
|
* not a devmapper 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(devPaths, deps->count + 1) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (i = 0; i < deps->count; i++) {
|
||||||
|
if (virAsprintfQuiet(&devPaths[i], "/dev/block/%u:%u",
|
||||||
|
major(deps->device[i]),
|
||||||
|
minor(deps->device[i])) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
recursiveDevPaths = NULL;
|
||||||
|
for (i = 0; i < deps->count; i++) {
|
||||||
|
char **tmpPaths;
|
||||||
|
|
||||||
|
if (virDevMapperGetTargetsImpl(devPaths[i], &tmpPaths, ttl - 1) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (tmpPaths &&
|
||||||
|
virStringListMerge(&recursiveDevPaths, &tmpPaths) < 0) {
|
||||||
|
virStringListFree(tmpPaths);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virStringListMerge(&devPaths, &recursiveDevPaths) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
VIR_STEAL_PTR(*devPaths_ret, devPaths);
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virStringListFree(recursiveDevPaths);
|
||||||
|
virStringListFree(devPaths);
|
||||||
|
dm_task_destroy(dmt);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDevMapperGetTargets:
|
||||||
|
* @path: devmapper target
|
||||||
|
* @devPaths: returned string list of devices
|
||||||
|
*
|
||||||
|
* For given @path figure out its targets, and store them in
|
||||||
|
* @devPaths array. Note, @devPaths is a string list so it's NULL
|
||||||
|
* terminated.
|
||||||
|
*
|
||||||
|
* If @path is not a devmapper device, @devPaths is set to NULL and
|
||||||
|
* success is returned.
|
||||||
|
*
|
||||||
|
* If @path consists of yet another devmapper targets these are
|
||||||
|
* consulted recursively.
|
||||||
|
*
|
||||||
|
* 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,
|
||||||
|
char ***devPaths)
|
||||||
|
{
|
||||||
|
const unsigned int ttl = 32;
|
||||||
|
|
||||||
|
/* Arbitrary limit on recursion level. A devmapper target can
|
||||||
|
* consist of devices or yet another targets. If that's the
|
||||||
|
* case, we have to stop recursion somewhere. */
|
||||||
|
|
||||||
|
return virDevMapperGetTargetsImpl(path, devPaths, ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ! WITH_DEVMAPPER */
|
||||||
|
|
||||||
|
int
|
||||||
|
virDevMapperGetTargets(const char *path ATTRIBUTE_UNUSED,
|
||||||
|
char ***devPaths ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* ! WITH_DEVMAPPER */
|
31
src/util/virdevmapper.h
Normal file
31
src/util/virdevmapper.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* virdevmapper.h: Functions for handling device mapper
|
||||||
|
*
|
||||||
|
* 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@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __VIR_DEVMAPPER_H__
|
||||||
|
# define __VIR_DEVMAPPER_H__
|
||||||
|
|
||||||
|
int
|
||||||
|
virDevMapperGetTargets(const char *path,
|
||||||
|
char ***devPaths);
|
||||||
|
|
||||||
|
#endif /* __VIR_DEVMAPPER_H__ */
|
Loading…
Reference in New Issue
Block a user