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:
parent
812e10ac60
commit
0f2a4ca2b5
@ -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]
|
||||
|
@ -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))
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user