summaryrefslogtreecommitdiffstats
path: root/lib/activate
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2011-06-30 18:25:18 +0000
committerAlasdair Kergon <agk@redhat.com>2011-06-30 18:25:18 +0000
commit0f2a4ca2b5f5de1481dedee45f5516db14c492b8 (patch)
tree60baa3f17bb08fc6530ee9512675c335aaddb0b4 /lib/activate
parent812e10ac600bd9cfcefa3e180630a5c25ed7c9f7 (diff)
downloadlvm2-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.c39
-rw-r--r--lib/activate/dev_manager.c8
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 */