diff options
author | Alasdair Kergon <agk@redhat.com> | 2011-06-30 18:25:18 +0000 |
---|---|---|
committer | Alasdair Kergon <agk@redhat.com> | 2011-06-30 18:25:18 +0000 |
commit | 0f2a4ca2b5f5de1481dedee45f5516db14c492b8 (patch) | |
tree | 60baa3f17bb08fc6530ee9512675c335aaddb0b4 /lib/activate | |
parent | 812e10ac600bd9cfcefa3e180630a5c25ed7c9f7 (diff) | |
download | lvm2-0f2a4ca2b5f5de1481dedee45f5516db14c492b8.tar.gz lvm2-0f2a4ca2b5f5de1481dedee45f5516db14c492b8.tar.xz lvm2-0f2a4ca2b5f5de1481dedee45f5516db14c492b8.zip |
When suspending, automatically preload newly-visible existing LVs
Let's find out if this makes things better or worse overall...
Diffstat (limited to 'lib/activate')
-rw-r--r-- | lib/activate/activate.c | 39 | ||||
-rw-r--r-- | lib/activate/dev_manager.c | 8 |
2 files changed, 40 insertions, 7 deletions
diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 2f922940..89d7b23d 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -1097,6 +1097,26 @@ int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv, #endif } +struct detached_lv_data { + struct logical_volume *lv_pre; + struct lv_activate_opts *laopts; + int *flush_required; +}; + +static int _preload_detached_lv(struct cmd_context *cmd, struct logical_volume *lv, void *data) +{ + struct detached_lv_data *detached = data; + struct lv_list *lvl_pre; + + if ((lvl_pre = find_lv_in_vg(detached->lv_pre->vg, lv->name))) { + if (lv_is_visible(lvl_pre->lv) && lv_is_active(lv) && + !_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required)) + return_0; + } + + return 1; +} + static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s, struct lv_activate_opts *laopts, int error_if_not_suspended) { @@ -1105,6 +1125,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s, struct seg_list *sl; struct lvinfo info; int r = 0, lockfs = 0, flush_required = 0; + struct detached_lv_data detached; if (!activation()) return 1; @@ -1172,9 +1193,21 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s, } if (!_lv_preload(lvl_pre->lv, laopts, &flush_required)) goto_out; - } else if (!_lv_preload(lv_pre, laopts, &flush_required)) - /* FIXME Revert preloading */ - goto_out; + } else { + if (!_lv_preload(lv_pre, laopts, &flush_required)) + /* FIXME Revert preloading */ + goto_out; + + /* + * Search for existing LVs that have become detached and preload them. + */ + detached.lv_pre = lv_pre; + detached.laopts = laopts; + detached.flush_required = &flush_required; + + if (!for_each_sub_lv(cmd, lv, &_preload_detached_lv, &detached)) + goto_out; + } } if (!monitor_dev_for_events(cmd, lv, laopts, 0)) diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 209aff7b..018447e9 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -1096,11 +1096,11 @@ static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, struct logi return NULL; } - if (!_add_lv_to_dtree(dm, dtree, lv, origin_only)) + if (!_add_lv_to_dtree(dm, dtree, lv, lv_is_origin(lv) ? origin_only : 0)) goto_bad; /* Add any snapshots of this LV */ - if (!origin_only) + if (!origin_only && lv_is_origin(lv)) dm_list_iterate_safe(snh, snht, &lv->snapshot_segs) if (!_add_lv_to_dtree(dm, dtree, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow, 0)) goto_bad; @@ -1714,7 +1714,7 @@ static int _tree_action(struct dev_manager *dm, struct logical_volume *lv, /* Restore fs cookie */ dm_tree_set_cookie(root, fs_get_cookie()); - if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, laopts->origin_only ? "real" : NULL))) + if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, (lv_is_origin(lv) && laopts->origin_only) ? "real" : NULL))) goto_out; /* Only process nodes with uuid of "LVM-" plus VG id. */ @@ -1744,7 +1744,7 @@ static int _tree_action(struct dev_manager *dm, struct logical_volume *lv, case PRELOAD: case ACTIVATE: /* Add all required new devices to tree */ - if (!_add_new_lv_to_dtree(dm, dtree, lv, laopts, laopts->origin_only ? "real" : NULL)) + if (!_add_new_lv_to_dtree(dm, dtree, lv, laopts, (lv_is_origin(lv) && laopts->origin_only) ? "real" : NULL)) goto_out; /* Preload any devices required before any suspensions */ |