diff options
author | Ondrej Kozina <okozina@redhat.com> | 2015-04-10 14:08:19 +0200 |
---|---|---|
committer | Ondrej Kozina <okozina@redhat.com> | 2015-05-05 20:52:07 +0200 |
commit | 76a0dffe6f4869de9ca457119c9d7ced837d4e0b (patch) | |
tree | 1a0dc4c1138d1dc6943158428d5e585a7d848d56 /tools/polldaemon.c | |
parent | bda26acf70e92232b1ed644dba6b44ecbff2a058 (diff) | |
download | lvm2-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.c | 122 |
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); } |