1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

When suspending, automatically preload newly-visible existing LVs

Let's find out if this makes things better or worse overall...
This commit is contained in:
Alasdair Kergon 2011-06-30 18:25:18 +00:00
parent 812e10ac60
commit 0f2a4ca2b5
5 changed files with 58 additions and 20 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.86 -
=================================
When suspending, automatically preload newly-visible existing LVs.
Report internal error when parameters are missing on table load.
Teardown any stray devices with $COMMON_PREFIX during test runs.
Reinstate correct permissions when creating mirrors. [2.02.85]

View File

@ -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))

View File

@ -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 */

View File

@ -2317,7 +2317,7 @@ static int _rename_sub_lv(struct cmd_context *cmd,
return _rename_single_lv(lv, new_name);
}
/* Callback for _for_each_sub_lv */
/* Callback for for_each_sub_lv */
static int _rename_cb(struct cmd_context *cmd, struct logical_volume *lv,
void *data)
{
@ -2327,32 +2327,31 @@ static int _rename_cb(struct cmd_context *cmd, struct logical_volume *lv,
}
/*
* Loop down sub LVs and call "func" for each.
* "func" is responsible to log necessary information on failure.
* Loop down sub LVs and call fn for each.
* fn is responsible to log necessary information on failure.
*/
static int _for_each_sub_lv(struct cmd_context *cmd, struct logical_volume *lv,
int (*func)(struct cmd_context *cmd,
struct logical_volume *lv,
void *data),
void *data)
int for_each_sub_lv(struct cmd_context *cmd, struct logical_volume *lv,
int (*fn)(struct cmd_context *cmd,
struct logical_volume *lv, void *data),
void *data)
{
struct logical_volume *org;
struct lv_segment *seg;
uint32_t s;
if (lv_is_cow(lv) && lv_is_virtual_origin(org = origin_from_cow(lv)))
if (!func(cmd, org, data))
if (!fn(cmd, org, data))
return_0;
dm_list_iterate_items(seg, &lv->segments) {
if (seg->log_lv && !func(cmd, seg->log_lv, data))
if (seg->log_lv && !fn(cmd, seg->log_lv, data))
return_0;
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_LV)
continue;
if (!func(cmd, seg_lv(seg, s), data))
if (!fn(cmd, seg_lv(seg, s), data))
return_0;
if (!_for_each_sub_lv(cmd, seg_lv(seg, s), func, data))
if (!for_each_sub_lv(cmd, seg_lv(seg, s), fn, data))
return_0;
}
}
@ -2397,7 +2396,7 @@ int lv_rename(struct cmd_context *cmd, struct logical_volume *lv,
/* rename sub LVs */
lv_names.old = lv->name;
lv_names.new = new_name;
if (!_for_each_sub_lv(cmd, lv, _rename_cb, (void *) &lv_names))
if (!for_each_sub_lv(cmd, lv, _rename_cb, (void *) &lv_names))
return 0;
/* rename main LV */

View File

@ -441,6 +441,11 @@ int add_seg_to_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *
int remove_seg_from_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg);
struct lv_segment *get_only_segment_using_this_lv(struct logical_volume *lv);
int for_each_sub_lv(struct cmd_context *cmd, struct logical_volume *lv,
int (*fn)(struct cmd_context *cmd,
struct logical_volume *lv, void *data),
void *data);
/*
* Calculate readahead from underlying PV devices
*/