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 | |
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.
-rw-r--r-- | tools/lvconvert.c | 69 | ||||
-rw-r--r-- | tools/polldaemon.c | 122 | ||||
-rw-r--r-- | tools/polldaemon.h | 12 | ||||
-rw-r--r-- | tools/pvmove.c | 153 | ||||
-rw-r--r-- | tools/pvmove_poll.c | 27 | ||||
-rw-r--r-- | tools/pvmove_poll.h | 9 | ||||
-rw-r--r-- | tools/toollib.c | 2 | ||||
-rw-r--r-- | tools/tools.h | 5 |
8 files changed, 291 insertions, 108 deletions
diff --git a/tools/lvconvert.c b/tools/lvconvert.c index 41aaad64e..5b2ab65c2 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -720,37 +720,68 @@ static struct poll_functions _lvconvert_thin_merge_fns = { .finish_copy = lvconvert_merge_finish, }; +static void _destroy_id(struct cmd_context *cmd, struct poll_operation_id *id) +{ + if (!id) + return; + + dm_pool_free(cmd->mem, (void *)id); +} + +static struct poll_operation_id *_create_id(struct cmd_context *cmd, + const char *vg_name, + const char *lv_name, + const char *uuid) +{ + char lv_full_name[NAME_LEN]; + struct poll_operation_id *id = dm_pool_alloc(cmd->mem, sizeof(struct poll_operation_id)); + if (!id) { + log_error("Poll operation ID allocation failed."); + return NULL; + } + + if (dm_snprintf(lv_full_name, sizeof(lv_full_name), "%s/%s", vg_name, lv_name) < 0) { + log_error(INTERNAL_ERROR "Name \"%s/%s\" is too long.", vg_name, lv_name); + _destroy_id(cmd, id); + return NULL; + } + + id->display_name = dm_pool_strdup(cmd->mem, lv_full_name); + id->vg_name = vg_name ? dm_pool_strdup(cmd->mem, vg_name) : NULL; + id->lv_name = id->display_name ? strchr(id->display_name, '/') + 1 : NULL; + id->uuid = uuid ? dm_pool_strdup(cmd->mem, uuid) : NULL; + + if (!id->vg_name || !id->lv_name || !id->display_name || !id->uuid) { + log_error("Failed to copy one or more poll operation ID members."); + _destroy_id(cmd, id); + id = NULL; + } + + return id; +} + int lvconvert_poll(struct cmd_context *cmd, struct logical_volume *lv, unsigned background) { - /* - * FIXME allocate an "object key" structure with split - * out members (vg_name, lv_name, uuid, etc) and pass that - * around the lvconvert and polldaemon code - * - will avoid needless work, e.g. extract_vgname() - * - unfortunately there are enough overloaded "name" dragons in - * the polldaemon, lvconvert, pvmove code that a comprehensive - * audit/rework is needed - */ - char uuid[sizeof(lv->lvid)]; - char lv_full_name[NAME_LEN]; int is_thin, r; + struct poll_operation_id *id = _create_id(cmd, lv->vg->name, lv->name, lv->lvid.s); - if (dm_snprintf(lv_full_name, sizeof(lv_full_name), "%s/%s", lv->vg->name, lv->name) < 0) { - log_error(INTERNAL_ERROR "Name \"%s/%s\" is too long.", lv->vg->name, lv->name); + if (!id) { + log_error("Failed to allocate poll identifier for lvconvert."); return ECMD_FAILED; } - memcpy(uuid, &lv->lvid, sizeof(lv->lvid)); - if (lv_is_merging_origin(lv)) { is_thin = seg_is_thin_volume(find_snapshot(lv)); - r = poll_daemon(cmd, lv_full_name, uuid, background, 0, + r = poll_daemon(cmd, background, + (MERGING | (is_thin ? THIN_VOLUME : SNAPSHOT)), is_thin ? &_lvconvert_thin_merge_fns : &_lvconvert_merge_fns, - "Merged"); + "Merged", id); } else - r = poll_daemon(cmd, lv_full_name, uuid, background, 0, - &_lvconvert_mirror_fns, "Converted"); + r = poll_daemon(cmd, background, CONVERTING, + &_lvconvert_mirror_fns, "Converted", id); + + _destroy_id(cmd, id); return r; } 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); } diff --git a/tools/polldaemon.h b/tools/polldaemon.h index 177900745..9c33250d4 100644 --- a/tools/polldaemon.h +++ b/tools/polldaemon.h @@ -52,6 +52,13 @@ struct poll_functions { struct dm_list *lvs_changed); }; +struct poll_operation_id { + const char *vg_name; + const char *lv_name; + const char *display_name; + const char *uuid; +}; + struct daemon_parms { unsigned interval; unsigned wait_before_testing; @@ -64,10 +71,9 @@ struct daemon_parms { struct poll_functions *poll_fns; }; -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); progress_t poll_mirror_progress(struct cmd_context *cmd, struct logical_volume *lv, const char *name, diff --git a/tools/pvmove.c b/tools/pvmove.c index 90cf5fe6b..70fba9912 100644 --- a/tools/pvmove.c +++ b/tools/pvmove.c @@ -569,8 +569,24 @@ out: return r; } +static int _copy_id_components(struct cmd_context *cmd, + const struct logical_volume *lv, char **vg_name, + char **lv_name, union lvid *lvid) +{ + if (!(*vg_name = dm_pool_strdup(cmd->mem, lv->vg->name)) || + !(*lv_name = dm_pool_strdup(cmd->mem, lv->name))) { + log_error("Failed to clone VG or LV name."); + return 0; + } + + *lvid = lv->lvid; + + return 1; +} + static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name, - int argc, char **argv) + int argc, char **argv, union lvid *lvid, char **vg_name, + char **lv_mirr_name) { const char *lv_name = NULL; char *pv_name_arg; @@ -613,7 +629,7 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name, /* Read VG */ log_verbose("Finding volume group \"%s\"", pv_vg_name(pv)); - vg = get_vg(cmd, pv_vg_name(pv)); + vg = poll_get_copy_vg(cmd, pv_vg_name(pv), NULL, READ_FOR_UPDATE); if (vg_read_error(vg)) { release_vg(vg); return_ECMD_FAILED; @@ -674,6 +690,9 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name, if (!_update_metadata(cmd, vg, lv_mirr, lvs_changed, exclusive)) goto_out; + if (!_copy_id_components(cmd, lv_mirr, vg_name, lv_mirr_name, lvid)) + goto out; + /* LVs are all in status LOCKED */ r = ECMD_PROCESSED; out: @@ -682,30 +701,122 @@ out: return r; } +static int _read_poll_id_from_pvname(struct cmd_context *cmd, const char *pv_name, + union lvid *lvid, char **vg_name, char **lv_name, + unsigned *in_progress) +{ + int ret = 0; + struct logical_volume *lv; + struct physical_volume *pv; + struct volume_group *vg; + + if (!pv_name) { + log_error(INTERNAL_ERROR "Invalid PV name parameter."); + return 0; + } + + if (!(pv = find_pv_by_name(cmd, pv_name, 0, 0))) + return_0; + + /* need read-only access */ + vg = poll_get_copy_vg(cmd, pv_vg_name(pv), NULL, 0); + if (vg_read_error(vg)) { + log_error("ABORTING: Can't read VG for %s.", pv_name); + release_vg(vg); + free_pv_fid(pv); + return 0; + } + + if (!(lv = find_pvmove_lv(vg, pv_dev(pv), PVMOVE))) { + log_print_unless_silent("%s: no pvmove in progress - already finished or aborted.", + pv_name); + ret = 1; + *in_progress = 0; + } else if (_copy_id_components(cmd, lv, vg_name, lv_name, lvid)) { + ret = 1; + *in_progress = 1; + } + + unlock_and_release_vg(cmd, vg, pv_vg_name(pv)); + free_pv_fid(pv); + return ret; +} + static struct poll_functions _pvmove_fns = { .get_copy_name_from_lv = get_pvmove_pvname_from_lv_mirr, - .get_copy_vg = pvmove_get_copy_vg, - .get_copy_lv = find_pvmove_lv_from_pvname, + .get_copy_vg = poll_get_copy_vg, + .get_copy_lv = poll_get_copy_lv, .poll_progress = poll_mirror_progress, .update_metadata = pvmove_update_metadata, .finish_copy = pvmove_finish, }; +static void _destroy_id(struct cmd_context *cmd, struct poll_operation_id *id) +{ + if (!id) + return; + + dm_pool_free(cmd->mem, id); +} + +static struct poll_operation_id *_create_id(struct cmd_context *cmd, + const char *pv_name, + const char *vg_name, + const char *lv_name, + const char *uuid) +{ + struct poll_operation_id *id = dm_pool_alloc(cmd->mem, sizeof(struct poll_operation_id)); + if (!id) { + log_error("Poll operation ID allocation failed."); + return NULL; + } + + id->vg_name = vg_name ? dm_pool_strdup(cmd->mem, vg_name) : NULL; + id->lv_name = lv_name ? dm_pool_strdup(cmd->mem, lv_name) : NULL; + id->display_name = pv_name ? dm_pool_strdup(cmd->mem, pv_name) : NULL; + id->uuid = uuid ? dm_pool_strdup(cmd->mem, uuid) : NULL; + + if (!id->vg_name || !id->lv_name || !id->display_name || !id->uuid) { + log_error("Failed to copy one or more poll operation ID members."); + _destroy_id(cmd, id); + id = NULL; + } + + return id; +} + int pvmove_poll(struct cmd_context *cmd, const char *pv_name, - unsigned background) + const char *uuid, const char *vg_name, + const char *lv_name, unsigned background) { + int r; + struct poll_operation_id *id = NULL; + if (test_mode()) return ECMD_PROCESSED; - return poll_daemon(cmd, pv_name, NULL, background, PVMOVE, &_pvmove_fns, - "Moved"); + if (uuid) { + id = _create_id(cmd, pv_name, vg_name, lv_name, uuid); + if (!id) { + log_error("Failed to allocate poll identifier for pvmove."); + return ECMD_FAILED; + } + } + + r = poll_daemon(cmd, background, PVMOVE, &_pvmove_fns, "Moved", id); + + _destroy_id(cmd, id); + + return r; } int pvmove(struct cmd_context *cmd, int argc, char **argv) { - char *pv_name = NULL; char *colon; int ret; + unsigned in_progress = 1; + union lvid *lvid = NULL; + char *pv_name = NULL, *vg_name = NULL, *lv_name = NULL; /* dm raid1 target must be present in every case */ if (!_pvmove_target_present(cmd, 0)) { @@ -715,8 +826,13 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv) } if (argc) { + if (!(lvid = dm_pool_alloc(cmd->mem, sizeof(*lvid)))) { + log_error("Failed to allocate lvid."); + return ECMD_FAILED; + } + if (!(pv_name = dm_pool_strdup(cmd->mem, argv[0]))) { - log_error("Failed to clone PV name"); + log_error("Failed to clone PV name."); return ECMD_FAILED; } @@ -726,13 +842,20 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv) if (colon) *colon = '\0'; - if (!arg_count(cmd, abort_ARG) && - (ret = _set_up_pvmove(cmd, pv_name, argc, argv)) != - ECMD_PROCESSED) { - stack; - return ret; + if (!arg_count(cmd, abort_ARG)) { + if ((ret = _set_up_pvmove(cmd, pv_name, argc, argv, lvid, &vg_name, &lv_name)) != ECMD_PROCESSED) { + stack; + return ret; + } + } else { + if (!_read_poll_id_from_pvname(cmd, pv_name, lvid, &vg_name, &lv_name, &in_progress)) + return_ECMD_FAILED; + + if (!in_progress) + return ECMD_PROCESSED; } } - return pvmove_poll(cmd, pv_name, arg_is_set(cmd, background_ARG)); + return pvmove_poll(cmd, pv_name, lvid ? lvid->s : NULL, vg_name, lv_name, + arg_is_set(cmd, background_ARG)); } diff --git a/tools/pvmove_poll.c b/tools/pvmove_poll.c index eeaf390f4..61ebd238e 100644 --- a/tools/pvmove_poll.c +++ b/tools/pvmove_poll.c @@ -16,13 +16,6 @@ #include "pvmove_poll.h" #include "tools.h" -struct volume_group *get_vg(struct cmd_context *cmd, const char *vgname) -{ - dev_close_all(); - - return vg_read_for_update(cmd, vgname, NULL, 0); -} - static int _is_pvmove_image_removable(struct logical_volume *mimage_lv, void *baton) { @@ -201,23 +194,3 @@ int pvmove_finish(struct cmd_context *cmd, struct volume_group *vg, return r; } - -struct volume_group *pvmove_get_copy_vg(struct cmd_context *cmd, const char *name, - const char *uuid __attribute__((unused)), - uint32_t flags __attribute__((unused))) -{ - struct physical_volume *pv; - struct volume_group *vg; - - /* Reread all metadata in case it got changed */ - if (!(pv = find_pv_by_name(cmd, name, 0, 0))) { - log_error("ABORTING: Can't reread PV %s", name); - /* What more could we do here? */ - return NULL; - } - - vg = get_vg(cmd, pv_vg_name(pv)); - free_pv_fid(pv); - - return vg; -} diff --git a/tools/pvmove_poll.h b/tools/pvmove_poll.h index ae7505a7b..b12458f64 100644 --- a/tools/pvmove_poll.h +++ b/tools/pvmove_poll.h @@ -15,16 +15,11 @@ #ifndef _LVM_PVMOVE_H #define _LVM_PVMOVE_H -/* FIXME: remove it after refactoring completes */ -#include <stdint.h> - struct cmd_context; struct dm_list; struct logical_volume; struct volume_group; -struct volume_group *get_vg(struct cmd_context *cmd, const char *vgname); - int pvmove_update_metadata(struct cmd_context *cmd, struct volume_group *vg, struct logical_volume *lv_mirr, struct dm_list *lvs_changed, unsigned flags); @@ -32,8 +27,4 @@ int pvmove_update_metadata(struct cmd_context *cmd, struct volume_group *vg, int pvmove_finish(struct cmd_context *cmd, struct volume_group *vg, struct logical_volume *lv_mirr, struct dm_list *lvs_changed); -struct volume_group *pvmove_get_copy_vg(struct cmd_context *cmd, - const char *name, const char *uuid, - uint32_t flags); - #endif /* _LVM_PVMOVE_H */ diff --git a/tools/toollib.c b/tools/toollib.c index d29bebf6e..e6c3cdb5e 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -921,7 +921,7 @@ void lv_spawn_background_polling(struct cmd_context *cmd, (pvname = get_pvmove_pvname_from_lv_mirr(lv_mirr))) { log_verbose("Spawning background pvmove process for %s.", pvname); - pvmove_poll(cmd, pvname, 1); + pvmove_poll(cmd, pvname, lv_mirr->lvid.s, lv_mirr->vg->name, lv_mirr->name, 1); } if (lv_is_converting(lv) || lv_is_merging(lv)) { diff --git a/tools/tools.h b/tools/tools.h index 1f344b07e..e959d8007 100644 --- a/tools/tools.h +++ b/tools/tools.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. - * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved. * * This file is part of LVM2. * @@ -176,7 +176,8 @@ int32_t grouped_arg_int_value(const struct arg_values *av, int a, const int32_t const char *command_name(struct cmd_context *cmd); -int pvmove_poll(struct cmd_context *cmd, const char *pv, unsigned background); +int pvmove_poll(struct cmd_context *cmd, const char *pv_name, const char *uuid, + const char *vg_name, const char *lv_name, unsigned background); int lvconvert_poll(struct cmd_context *cmd, struct logical_volume *lv, unsigned background); int mirror_remove_missing(struct cmd_context *cmd, |