summaryrefslogtreecommitdiff
path: root/tools/polldaemon.c
diff options
context:
space:
mode:
authorOndrej Kozina <okozina@redhat.com>2015-04-10 14:08:19 +0200
committerOndrej Kozina <okozina@redhat.com>2015-05-05 20:52:07 +0200
commit76a0dffe6f4869de9ca457119c9d7ced837d4e0b (patch)
tree1a0dc4c1138d1dc6943158428d5e585a7d848d56 /tools/polldaemon.c
parentbda26acf70e92232b1ed644dba6b44ecbff2a058 (diff)
downloadlvm2-76a0dffe6f4869de9ca457119c9d7ced837d4e0b.tar.gz
polldaemon: refactor polling interfaces
Routines responsible for polling of in-progress pvmove, snapshot merge or mirror conversion each used custom lookup functions to find vg and lv involved in polling. Especially pvmove used pvname to lookup pvmove in-progress. The future lvmpolld will poll each operation by vg/lv name (internally by lvid). Also there're plans to make pvmove able to move non-overlaping ranges of extents instead of single PVs as of now. This would also require to identify the opertion in different manner. The poll_operation_id structure together with daemon_parms structure they identify unambiguously the polling task.
Diffstat (limited to 'tools/polldaemon.c')
-rw-r--r--tools/polldaemon.c122
1 files changed, 90 insertions, 32 deletions
diff --git a/tools/polldaemon.c b/tools/polldaemon.c
index 4a4983a79..4c010f564 100644
--- a/tools/polldaemon.c
+++ b/tools/polldaemon.c
@@ -143,7 +143,7 @@ static void _sleep_and_rescan_devices(struct daemon_parms *parms)
}
}
-static int _wait_for_single_lv(struct cmd_context *cmd, const char *name, const char *uuid,
+static int _wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
struct daemon_parms *parms)
{
struct volume_group *vg;
@@ -156,26 +156,26 @@ static int _wait_for_single_lv(struct cmd_context *cmd, const char *name, const
_sleep_and_rescan_devices(parms);
/* Locks the (possibly renamed) VG again */
- vg = parms->poll_fns->get_copy_vg(cmd, name, uuid, READ_FOR_UPDATE);
+ vg = parms->poll_fns->get_copy_vg(cmd, id->vg_name, NULL, READ_FOR_UPDATE);
if (vg_read_error(vg)) {
release_vg(vg);
- log_error("ABORTING: Can't reread VG for %s", name);
+ log_error("ABORTING: Can't reread VG for %s.", id->display_name);
/* What more could we do here? */
return 0;
}
- lv = parms->poll_fns->get_copy_lv(cmd, vg, name, uuid, parms->lv_type);
+ lv = parms->poll_fns->get_copy_lv(cmd, vg, id->lv_name, id->uuid, parms->lv_type);
if (!lv && parms->lv_type == PVMOVE) {
log_print_unless_silent("%s: no pvmove in progress - already finished or aborted.",
- name);
+ id->display_name);
unlock_and_release_vg(cmd, vg, vg->name);
return 1;
}
if (!lv) {
- log_error("ABORTING: Can't find LV in %s for %s",
- vg->name, name);
+ log_error("ABORTING: Can't find LV in %s for %s.",
+ vg->name, id->display_name);
unlock_and_release_vg(cmd, vg, vg->name);
return 0;
}
@@ -185,12 +185,12 @@ static int _wait_for_single_lv(struct cmd_context *cmd, const char *name, const
* queried for its status. We must exit in this case.
*/
if (!lv_is_active_locally(lv)) {
- log_print_unless_silent("%s: Interrupted: No longer active.", name);
+ log_print_unless_silent("%s: Interrupted: No longer active.", id->display_name);
unlock_and_release_vg(cmd, vg, vg->name);
return 1;
}
- if (!_check_lv_status(cmd, vg, lv, name, parms, &finished)) {
+ if (!_check_lv_status(cmd, vg, lv, id->display_name, parms, &finished)) {
unlock_and_release_vg(cmd, vg, vg->name);
return_0;
}
@@ -216,15 +216,65 @@ static int _wait_for_single_lv(struct cmd_context *cmd, const char *name, const
return 1;
}
+struct poll_id_list {
+ struct dm_list list;
+ struct poll_operation_id *id;
+};
+
+static struct poll_operation_id *copy_poll_operation_id(struct dm_pool *mem,
+ const struct poll_operation_id *id)
+{
+ struct poll_operation_id *copy;
+
+ if (!id)
+ return_NULL;
+
+ copy = (struct poll_operation_id *) dm_pool_alloc(mem, sizeof(struct poll_operation_id));
+ if (!copy) {
+ log_error("Poll operation ID allocation failed.");
+ return NULL;
+ }
+
+ copy->display_name = id->display_name ? dm_pool_strdup(mem, id->display_name) : NULL;
+ copy->lv_name = id->lv_name ? dm_pool_strdup(mem, id->lv_name) : NULL;
+ copy->vg_name = id->vg_name ? dm_pool_strdup(mem, id->vg_name) : NULL;
+ copy->uuid = id->uuid ? dm_pool_strdup(mem, id->uuid) : NULL;
+
+ if (!copy->display_name || !copy->lv_name || !copy->vg_name || !copy->uuid) {
+ log_error("Failed to copy one or more poll_operation_id members.");
+ return NULL;
+ }
+
+ return copy;
+}
+
+static struct poll_id_list* poll_id_list_create(struct dm_pool *mem,
+ const struct poll_operation_id *id)
+{
+ struct poll_id_list *idl = (struct poll_id_list *) dm_pool_alloc(mem, sizeof(struct poll_id_list));
+
+ if (!idl) {
+ log_error("Poll ID list allocation failed.");
+ return NULL;
+ }
+
+ if (!(idl->id = copy_poll_operation_id(mem, id))) {
+ dm_pool_free(mem, idl);
+ return NULL;
+ }
+
+ return idl;
+}
+
static int _poll_vg(struct cmd_context *cmd, const char *vgname,
struct volume_group *vg, struct processing_handle *handle)
{
struct daemon_parms *parms;
struct lv_list *lvl;
- struct dm_list *sls;
- struct dm_str_list *sl;
+ struct dm_list idls;
+ struct poll_id_list *idl;
+ struct poll_operation_id id;
struct logical_volume *lv;
- const char *name;
int finished;
if (!handle || !(parms = (struct daemon_parms *) handle->custom_handle)) {
@@ -232,8 +282,7 @@ static int _poll_vg(struct cmd_context *cmd, const char *vgname,
return ECMD_FAILED;
}
- if (!(sls = str_list_create(cmd->mem)))
- return ECMD_FAILED;
+ dm_list_init(&idls);
/*
* first iterate all LVs in a VG and collect LVs suitable
@@ -243,11 +292,11 @@ static int _poll_vg(struct cmd_context *cmd, const char *vgname,
lv = lvl->lv;
if (!(lv->status & parms->lv_type))
continue;
- name = parms->poll_fns->get_copy_name_from_lv(lv);
- if (!name && !parms->aborting)
+ id.display_name = parms->poll_fns->get_copy_name_from_lv(lv);
+ if (!id.display_name && !parms->aborting)
continue;
- if (!name) {
+ if (!id.display_name) {
log_error("Device name for LV %s not found in metadata. "
"(unfinished pvmove mirror removal?)", display_lvname(lv));
goto err;
@@ -256,25 +305,33 @@ static int _poll_vg(struct cmd_context *cmd, const char *vgname,
/* FIXME Need to do the activation from _set_up_pvmove here
* if it's not running and we're not aborting. */
if (!lv_is_active(lv)) {
- log_print_unless_silent("%s: Skipping inactive LV. Try lvchange or vgchange.", name);
+ log_print_unless_silent("%s: Skipping inactive LV. Try lvchange or vgchange.", id.display_name);
continue;
}
- if (!str_list_add(cmd->mem, sls, dm_pool_strdup(cmd->mem, name))) {
- log_error("Failed to clone pvname");
+ id.lv_name = lv->name;
+ id.vg_name = vg->name;
+ id.uuid = lv->lvid.s;
+
+ idl = poll_id_list_create(cmd->mem, &id);
+ if (!idl) {
+ log_error("Failed to create poll_id_list.");
goto err;
}
+
+ dm_list_add(&idls, &idl->list);
}
/* perform the poll operation on LVs collected in previous cycle */
- dm_list_iterate_items(sl, sls) {
- lv = parms->poll_fns->get_copy_lv(cmd, vg, sl->str, NULL, parms->lv_type);
- if (lv && _check_lv_status(cmd, vg, lv, sl->str, parms, &finished) && !finished)
+ dm_list_iterate_items(idl, &idls) {
+ lv = parms->poll_fns->get_copy_lv(cmd, vg, idl->id->lv_name, idl->id->uuid, parms->lv_type);
+ if (lv && _check_lv_status(cmd, vg, lv, idl->id->display_name, parms, &finished) && !finished)
parms->outstanding_count++;
}
err:
- dm_pool_free(cmd->mem, sls);
+ if (!dm_list_empty(&idls))
+ dm_pool_free(cmd->mem, dm_list_item(dm_list_first(&idls), struct poll_id_list));
return ECMD_PROCESSED;
}
@@ -299,8 +356,8 @@ static void _poll_for_all_vgs(struct cmd_context *cmd,
* - 'background' is advisory so a child polldaemon may not be used even
* if it was requested.
*/
-static int _poll_daemon(struct cmd_context *cmd, const char *name,
- const char *uuid, struct daemon_parms *parms)
+static int _poll_daemon(struct cmd_context *cmd, struct poll_operation_id *id,
+ struct daemon_parms *parms)
{
struct processing_handle *handle = NULL;
int daemon_mode = 0;
@@ -319,8 +376,8 @@ static int _poll_daemon(struct cmd_context *cmd, const char *name,
/*
* Process one specific task or all incomplete tasks?
*/
- if (name) {
- if (!_wait_for_single_lv(cmd, name, uuid, parms)) {
+ if (id) {
+ if (!_wait_for_single_lv(cmd, id, parms)) {
stack;
ret = ECMD_FAILED;
}
@@ -382,15 +439,16 @@ static int _daemon_parms_init(struct cmd_context *cmd, struct daemon_parms *parm
return 1;
}
-int poll_daemon(struct cmd_context *cmd, const char *name, const char *uuid,
- unsigned background,
+int poll_daemon(struct cmd_context *cmd, unsigned background,
uint64_t lv_type, struct poll_functions *poll_fns,
- const char *progress_title)
+ const char *progress_title, struct poll_operation_id *id)
{
struct daemon_parms parms;
if (!_daemon_parms_init(cmd, &parms, background, poll_fns, progress_title, lv_type))
return_EINVALID_CMD_LINE;
- return _poll_daemon(cmd, name, uuid, &parms);
+ /* classical polling allows only PMVOVE or 0 values */
+ parms.lv_type &= PVMOVE;
+ return _poll_daemon(cmd, id, &parms);
}