summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--daemons/dmeventd/plugins/thin/dmeventd_thin.c259
1 files changed, 2 insertions, 257 deletions
diff --git a/daemons/dmeventd/plugins/thin/dmeventd_thin.c b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
index e1b1f7706..bd70e78fa 100644
--- a/daemons/dmeventd/plugins/thin/dmeventd_thin.c
+++ b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
@@ -67,246 +67,6 @@ DM_EVENT_LOG_FN("thin")
#define UUID_PREFIX "LVM-"
-/* Figure out device UUID has LVM- prefix and is OPEN */
-static int _has_unmountable_prefix(int major, int minor)
-{
- struct dm_task *dmt;
- struct dm_info info;
- const char *uuid;
- int r = 0;
-
- if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
- return_0;
-
- if (!dm_task_set_major_minor(dmt, major, minor, 1))
- goto_out;
-
- if (!dm_task_no_flush(dmt))
- stack;
-
- if (!dm_task_run(dmt))
- goto out;
-
- if (!dm_task_get_info(dmt, &info))
- goto out;
-
- if (!info.exists || !info.open_count)
- goto out; /* Not open -> not mounted */
-
- if (!(uuid = dm_task_get_uuid(dmt)))
- goto out;
-
- /* Check it's public mountable LV
- * has prefix LVM- and UUID size is 68 chars */
- if (memcmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) ||
- strlen(uuid) != 68)
- goto out;
-
-#if THIN_DEBUG
- log_debug("Found logical volume %s (%u:%u).", uuid, major, minor);
-#endif
- r = 1;
-out:
- dm_task_destroy(dmt);
-
- return r;
-}
-
-/* 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)
-{
- struct dm_task *dmt;
- const struct dm_deps *deps;
- struct dm_info info;
- int major, minor;
- int r = 0;
-
- if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
- return 0;
-
- if (!dm_task_set_name(dmt, name))
- goto out;
-
- if (!dm_task_no_open_count(dmt))
- goto out;
-
- if (!dm_task_run(dmt))
- goto out;
-
- if (!dm_task_get_info(dmt, &info))
- goto out;
-
- if (!(deps = dm_task_get_deps(dmt)))
- goto out;
-
- if (!info.exists || deps->count != 1)
- goto out;
-
- major = (int) MAJOR(deps->device[0]);
- minor = (int) MINOR(deps->device[0]);
- if ((major != tp_major) || (minor != tp_minor))
- goto out;
-
- *dev_minor = info.minor;
-
- if (!_has_unmountable_prefix(major, info.minor))
- goto out;
-
-#if THIN_DEBUG
- {
- char dev_name[PATH_MAX];
- if (dm_device_get_name(major, minor, 0, dev_name, sizeof(dev_name)))
- log_debug("Found %s (%u:%u) depends on %s.",
- name, major, *dev_minor, dev_name);
- }
-#endif
- r = 1;
-out:
- dm_task_destroy(dmt);
-
- return r;
-}
-
-/* Get all active devices */
-static int _find_all_devs(dm_bitset_t bs, int tp_major, int tp_minor)
-{
- struct dm_task *dmt;
- struct dm_names *names;
- unsigned next = 0;
- int minor, r = 1;
-
- if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
- return 0;
-
- if (!dm_task_run(dmt)) {
- r = 0;
- goto out;
- }
-
- if (!(names = dm_task_get_names(dmt))) {
- r = 0;
- goto out;
- }
-
- if (!names->dev)
- goto out;
-
- do {
- names = (struct dm_names *)((char *) names + next);
- if (_has_deps(names->name, tp_major, tp_minor, &minor))
- dm_bit_set(bs, minor);
- next = names->next;
- } while (next);
-
-out:
- dm_task_destroy(dmt);
-
- return r;
-}
-
-static int _run(const char *cmd, ...)
-{
- va_list ap;
- int argc = 1; /* for argv[0], i.e. cmd */
- int i = 0;
- const char **argv;
- pid_t pid = fork();
- int status;
-
- if (pid == 0) { /* child */
- va_start(ap, cmd);
- while (va_arg(ap, const char *))
- ++argc;
- va_end(ap);
-
- /* + 1 for the terminating NULL */
- argv = alloca(sizeof(const char *) * (argc + 1));
-
- argv[0] = cmd;
- va_start(ap, cmd);
- while ((argv[++i] = va_arg(ap, const char *)));
- va_end(ap);
-
- execvp(cmd, (char **)argv);
- log_sys_error("exec", cmd);
- exit(127);
- }
-
- if (pid > 0) { /* parent */
- if (waitpid(pid, &status, 0) != pid)
- return 0; /* waitpid failed */
- if (!WIFEXITED(status) || WEXITSTATUS(status))
- return 0; /* the child failed */
- }
-
- if (pid < 0)
- return 0; /* fork failed */
-
- return 1; /* all good */
-}
-
-struct mountinfo_s {
- const char *device;
- struct dm_info info;
- dm_bitset_t minors; /* Bitset for active thin pool minors */
-};
-
-static int _umount_device(char *buffer, unsigned major, unsigned minor,
- char *target, void *cb_data)
-{
- struct mountinfo_s *data = cb_data;
- char *words[10];
-
- if ((major == data->info.major) && dm_bit(data->minors, minor)) {
- if (dm_split_words(buffer, DM_ARRAY_SIZE(words), 0, words) < DM_ARRAY_SIZE(words))
- words[9] = NULL; /* just don't show device name */
- log_info("Unmounting thin %s (%d:%d) of thin pool %s (%u:%u) from mount point \"%s\".",
- words[9] ? : "", major, minor, data->device,
- data->info.major, data->info.minor,
- target);
- if (!_run(UMOUNT_COMMAND, "-fl", target, NULL))
- log_error("Failed to lazy umount thin %s (%d:%d) from %s: %s.",
- words[9], major, minor, target, strerror(errno));
- }
-
- return 1;
-}
-
-/*
- * Find all thin pool LV users and try to umount them.
- * TODO: work with read-only thin pool support
- */
-static void _umount(struct dm_task *dmt)
-{
- /* TODO: Convert to use hash to reduce memory usage */
- static const size_t MINORS = (1U << 20); /* 20 bit */
- struct mountinfo_s data = { NULL };
-
- if (!dm_task_get_info(dmt, &data.info))
- return;
-
- data.device = dm_task_get_name(dmt);
-
- if (!(data.minors = dm_bitset_create(NULL, MINORS))) {
- log_error("Failed to allocate bitset. Not unmounting %s.", data.device);
- goto out;
- }
-
- if (!_find_all_devs(data.minors, data.info.major, data.info.minor)) {
- log_error("Failed to detect mounted volumes for %s.", data.device);
- goto out;
- }
-
- if (!dm_mountinfo_read(_umount_device, &data)) {
- log_error("Could not parse mountinfo file.");
- goto out;
- }
-
-out:
- if (data.minors)
- dm_bitset_destroy(data.minors);
-}
-
static int _run_command(struct dso_state *state)
{
char val[2][36];
@@ -407,7 +167,6 @@ void process_event(struct dm_task *dmt,
char *target_type = NULL;
char *params;
int needs_policy = 0;
- int needs_umount = 0;
struct dm_task *new_dmt = NULL;
#if THIN_DEBUG
@@ -461,7 +220,6 @@ void process_event(struct dm_task *dmt,
if (!dm_get_status_thin_pool(state->mem, params, &tps)) {
log_error("Failed to parse status.");
- needs_umount = 1;
goto out;
}
@@ -499,9 +257,6 @@ void process_event(struct dm_task *dmt,
state->metadata_percent_check = (state->metadata_percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
needs_policy = 1;
-
- if (state->metadata_percent >= UMOUNT_THRESH)
- needs_umount = 1;
}
state->data_percent = dm_make_percent(tps->used_data_blocks, tps->total_data_blocks);
@@ -518,9 +273,6 @@ void process_event(struct dm_task *dmt,
state->data_percent_check = (state->data_percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
needs_policy = 1;
-
- if (state->data_percent >= UMOUNT_THRESH)
- needs_umount = 1;
}
/* Reduce number of _use_policy() calls by power-of-2 factor till frequency of MAX_FAILS is reached.
@@ -539,16 +291,9 @@ void process_event(struct dm_task *dmt,
} else
state->max_fails = 1; /* Reset on success */
- if (needs_policy &&
- _use_policy(dmt, state))
- needs_umount = 0; /* No umount when command was successful */
+ if (needs_policy)
+ _use_policy(dmt, state);
out:
- if (needs_umount) {
- _umount(dmt);
- /* Until something changes, do not retry any more actions */
- state->data_percent_check = state->metadata_percent_check = (DM_PERCENT_1 * 101);
- }
-
if (tps)
dm_pool_free(state->mem, tps);