mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
dmeventd: use dm_mountinfo_read
Reuse mountinfo reading code from libdm.
This commit is contained in:
parent
7fab9a9dda
commit
810bc4f8c1
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2012 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2011-2013 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@ -53,53 +53,6 @@ struct dso_state {
|
|||||||
# define MKDEV(x,y) makedev((x),(y))
|
# define MKDEV(x,y) makedev((x),(y))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Macros to make string defines */
|
|
||||||
#define TO_STRING_EXP(A) #A
|
|
||||||
#define TO_STRING(A) TO_STRING_EXP(A)
|
|
||||||
|
|
||||||
static int _is_octal(int a)
|
|
||||||
{
|
|
||||||
return (((a) & ~7) == '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert mangled mountinfo into normal ASCII string */
|
|
||||||
static void _unmangle_mountinfo_string(const char *src, char *buf)
|
|
||||||
{
|
|
||||||
if (!src)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (*src) {
|
|
||||||
if ((*src == '\\') &&
|
|
||||||
_is_octal(src[1]) && _is_octal(src[2]) && _is_octal(src[3])) {
|
|
||||||
*buf++ = 64 * (src[1] & 7) + 8 * (src[2] & 7) + (src[3] & 7);
|
|
||||||
src += 4;
|
|
||||||
} else
|
|
||||||
*buf++ = *src++;
|
|
||||||
}
|
|
||||||
*buf = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse one line of mountinfo */
|
|
||||||
static int _parse_mountinfo_line(const char *line, unsigned *maj, unsigned *min, char *buf)
|
|
||||||
{
|
|
||||||
char root[PATH_MAX + 1];
|
|
||||||
char target[PATH_MAX + 1];
|
|
||||||
|
|
||||||
/* TODO: maybe detect availability of %ms glib support ? */
|
|
||||||
if (sscanf(line, "%*u %*u %u:%u %" TO_STRING(PATH_MAX)
|
|
||||||
"s %" TO_STRING(PATH_MAX) "s",
|
|
||||||
maj, min, root, target) < 4)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
_unmangle_mountinfo_string(target, buf);
|
|
||||||
|
|
||||||
#if THIN_DEBUG
|
|
||||||
syslog(LOG_DEBUG, "Mounted %u:%u %s", *maj, *min, buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get dependencies for device, and try to find matching device */
|
/* Get dependencies for device, and try to find matching device */
|
||||||
static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_minor)
|
static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_minor)
|
||||||
{
|
{
|
||||||
@ -238,62 +191,62 @@ static int _run(const char *cmd, ...)
|
|||||||
return 1; /* all good */
|
return 1; /* all good */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mountinfo_s {
|
||||||
|
struct dm_info info;
|
||||||
|
dm_bitset_t minors; /* Bitset for active thin pool minors */
|
||||||
|
const char *device;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int _umount_device(char *buffer, unsigned major, unsigned minor,
|
||||||
|
char *target, void *cb_data)
|
||||||
|
{
|
||||||
|
struct mountinfo_s *data = cb_data;
|
||||||
|
|
||||||
|
if ((major == data->info.major) && dm_bit(data->minors, minor)) {
|
||||||
|
syslog(LOG_INFO, "Unmounting thin volume %s from %s.\n",
|
||||||
|
data->device, target);
|
||||||
|
if (!_run(UMOUNT_COMMAND, "-fl", target, NULL))
|
||||||
|
syslog(LOG_ERR, "Failed to umount thin %s from %s: %s.\n",
|
||||||
|
data->device, target, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find all thin pool users and try to umount them.
|
* Find all thin pool users and try to umount them.
|
||||||
* TODO: work with read-only thin pool support
|
* TODO: work with read-only thin pool support
|
||||||
*/
|
*/
|
||||||
static void _umount(struct dm_task *dmt, const char *device)
|
static void _umount(struct dm_task *dmt, const char *device)
|
||||||
{
|
{
|
||||||
static const char mountinfo[] = "/proc/self/mountinfo";
|
|
||||||
static const size_t MINORS = 4096;
|
static const size_t MINORS = 4096;
|
||||||
FILE *minfo = NULL;
|
struct mountinfo_s data = {
|
||||||
char buffer[4096];
|
.device = device,
|
||||||
char target[PATH_MAX];
|
};
|
||||||
struct dm_info info;
|
|
||||||
unsigned maj, min;
|
|
||||||
dm_bitset_t minors; /* Bitset for active thin pool minors */
|
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, &info))
|
if (!dm_task_get_info(dmt, &data.info))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dmeventd_lvm2_unlock();
|
dmeventd_lvm2_unlock();
|
||||||
|
|
||||||
if (!(minors = dm_bitset_create(NULL, MINORS))) {
|
if (!(data.minors = dm_bitset_create(NULL, MINORS))) {
|
||||||
syslog(LOG_ERR, "Failed to allocate bitset. Not unmounting %s.\n", device);
|
syslog(LOG_ERR, "Failed to allocate bitset. Not unmounting %s.\n", device);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(minfo = fopen(mountinfo, "r"))) {
|
if (!_find_all_devs(data.minors, data.info.major, data.info.minor)) {
|
||||||
syslog(LOG_ERR, "Could not read %s. Not umounting %s.\n", mountinfo, device);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_find_all_devs(minors, info.major, info.minor)) {
|
|
||||||
syslog(LOG_ERR, "Failed to detect mounted volumes for %s.\n", device);
|
syslog(LOG_ERR, "Failed to detect mounted volumes for %s.\n", device);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!feof(minfo)) {
|
if (!dm_mountinfo_read(_umount_device, &data)) {
|
||||||
/* read mountinfo line */
|
syslog(LOG_ERR, "Could not parse mountinfo file.\n");
|
||||||
if (!fgets(buffer, sizeof(buffer), minfo))
|
goto out;
|
||||||
break; /* eof, likely */
|
|
||||||
|
|
||||||
if (_parse_mountinfo_line(buffer, &maj, &min, target) &&
|
|
||||||
(maj == info.major) && dm_bit(minors, min)) {
|
|
||||||
syslog(LOG_INFO, "Unmounting thin volume %s from %s.\n",
|
|
||||||
device, target);
|
|
||||||
if (!_run(UMOUNT_COMMAND, "-fl", target, NULL))
|
|
||||||
syslog(LOG_ERR, "Failed to umount thin %s from %s: %s.\n",
|
|
||||||
device, target, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (minfo && fclose(minfo))
|
if (data.minors)
|
||||||
syslog(LOG_ERR, "Failed to close %s\n", mountinfo);
|
dm_bitset_destroy(data.minors);
|
||||||
|
|
||||||
if (minors)
|
|
||||||
dm_bitset_destroy(minors);
|
|
||||||
dmeventd_lvm2_lock();
|
dmeventd_lvm2_lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user