diff --git a/WHATS_NEW b/WHATS_NEW index 963d58629..202c5b64c 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.11 - ===================================== + Add LV column to reports listing kernel modules needed for activation. Show available fields if report given invalid field. (e.g. lvs -o list) Add timestamp functions with --disable-realtime configure option. Add %VG, %LV and %FREE suffices to lvcreate/lvresize --extents arg. diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 8c0ba0aa4..da2b9df1f 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -51,6 +51,66 @@ int lvm1_present(struct cmd_context *cmd) return 0; } +int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg, + struct list *modules) +{ + unsigned int s; + struct lv_segment *seg2, *snap_seg; + struct list *snh; + + if (seg->segtype->ops->modules_needed && + !seg->segtype->ops->modules_needed(mem, seg, modules)) { + log_error("module string allocation failed"); + return 0; + } + + if (lv_is_origin(seg->lv)) + list_iterate(snh, &seg->lv->snapshot_segs) + if (!list_lv_modules(mem, + list_struct_base(snh, + struct lv_segment, + origin_list)->cow, + modules)) + return_0; + + if (lv_is_cow(seg->lv)) { + snap_seg = find_cow(seg->lv); + if (snap_seg->segtype->ops->modules_needed && + !snap_seg->segtype->ops->modules_needed(mem, snap_seg, + modules)) { + log_error("snap_seg module string allocation failed"); + return 0; + } + } + + for (s = 0; s < seg->area_count; s++) { + switch (seg_type(seg, s)) { + case AREA_LV: + seg2 = find_seg_by_le(seg_lv(seg, s), seg_le(seg, s)); + if (seg2 && !list_segment_modules(mem, seg2, modules)) + return_0; + break; + case AREA_PV: + case AREA_UNASSIGNED: + ; + } + } + + return 1; +} + +int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv, + struct list *modules) +{ + struct lv_segment *seg; + + list_iterate_items(seg, &lv->segments) + if (!list_segment_modules(mem, seg, modules)) + return_0; + + return 1; +} + #ifndef DEVMAPPER_SUPPORT void set_activation(int act) { diff --git a/lib/activate/activate.h b/lib/activate/activate.h index 16bcb7be1..9a4e4d5ea 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -39,6 +39,10 @@ int lvm1_present(struct cmd_context *cmd); int target_present(const char *target_name, int use_modprobe); int target_version(const char *target_name, uint32_t *maj, uint32_t *min, uint32_t *patchlevel); +int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg, + struct list *modules); +int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv, + struct list *modules); void activation_release(void); void activation_exit(void); diff --git a/lib/error/errseg.c b/lib/error/errseg.c index cef9d7f79..00e938947 100644 --- a/lib/error/errseg.c +++ b/lib/error/errseg.c @@ -23,6 +23,7 @@ #include "targets.h" #include "lvm-string.h" #include "activate.h" +#include "str_list.h" static const char *_errseg_name(const struct lv_segment *seg) { @@ -64,6 +65,18 @@ static int _errseg_target_present(void) } #endif +static int _errseg_modules_needed(struct dm_pool *mem, + const struct lv_segment *seg, + struct list *modules) +{ + if (!str_list_add(mem, modules, "error")) { + log_error("error module string list allocation failed"); + return 0; + } + + return 1; +} + static void _errseg_destroy(const struct segment_type *segtype) { dm_free((void *)segtype); @@ -76,6 +89,7 @@ static struct segtype_handler _error_ops = { .add_target_line = _errseg_add_target_line, .target_present = _errseg_target_present, #endif + .modules_needed = _errseg_modules_needed, .destroy = _errseg_destroy, }; diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h index a51f1eeb9..f12673d99 100644 --- a/lib/metadata/segtype.h +++ b/lib/metadata/segtype.h @@ -77,6 +77,9 @@ struct segtype_handler { uint64_t *total_numerator, uint64_t *total_denominator, float *percent); int (*target_present) (void); + int (*modules_needed) (struct dm_pool *mem, + const struct lv_segment *seg, + struct list *modules); void (*destroy) (const struct segment_type * segtype); int (*target_register_events) (struct lv_segment *seg, int events); int (*target_unregister_events) (struct lv_segment *seg, int events); diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c index 9aad5666c..503977c48 100644 --- a/lib/mirror/mirrored.c +++ b/lib/mirror/mirrored.c @@ -26,6 +26,7 @@ #include "targets.h" #include "activate.h" #include "sharedlib.h" +#include "str_list.h" #ifdef DMEVENTD # include @@ -447,6 +448,28 @@ static int _target_unregister_events(struct lv_segment *seg, #endif /* DMEVENTD */ #endif /* DEVMAPPER_SUPPORT */ +static int _mirrored_modules_needed(struct dm_pool *mem, + const struct lv_segment *seg, + struct list *modules) +{ + if (seg->log_lv && + !list_segment_modules(mem, first_seg(seg->log_lv), modules)) + return_0; + + if ((seg->lv->vg->status & CLUSTERED) && + !str_list_add(mem, modules, "clog")) { + log_error("cluster log string list allocation failed"); + return 0; + } + + if (!str_list_add(mem, modules, "mirror")) { + log_error("mirror string list allocation failed"); + return 0; + } + + return 1; +} + static void _mirrored_destroy(const struct segment_type *segtype) { dm_free((void *) segtype); @@ -467,6 +490,7 @@ static struct segtype_handler _mirrored_ops = { .target_unregister_events = _target_unregister_events, #endif #endif + .modules_needed = _mirrored_modules_needed, .destroy = _mirrored_destroy, }; diff --git a/lib/report/columns.h b/lib/report/columns.h index b1d9f34ce..9b11e3fe5 100644 --- a/lib/report/columns.h +++ b/lib/report/columns.h @@ -33,6 +33,7 @@ FIELD(LVS, lv, NUM, "Copy%", lvid, 6, copypercent, "copy_percent") FIELD(LVS, lv, STR, "Move", lvid, 4, movepv, "move_pv") FIELD(LVS, lv, STR, "LV Tags", tags, 7, tags, "lv_tags") FIELD(LVS, lv, STR, "Log", lvid, 3, loglv, "mirror_log") +FIELD(LVS, lv, STR, "Modules", lvid, 7, modules, "modules") FIELD(PVS, pv, STR, "Fmt", id, 3, pvfmt, "pv_fmt") FIELD(PVS, pv, STR, "PV UUID", id, 38, uuid, "pv_uuid") diff --git a/lib/report/report.c b/lib/report/report.c index e9361553a..6a21f2a79 100644 --- a/lib/report/report.c +++ b/lib/report/report.c @@ -21,6 +21,7 @@ #include "display.h" #include "activate.h" #include "segtype.h" +#include "str_list.h" /* * For macro use @@ -200,6 +201,7 @@ static int _devices_disp(struct report_handle *rh, struct field *field, return 1; } + static int _tags_disp(struct report_handle *rh, struct field *field, const void *data) { @@ -230,6 +232,23 @@ static int _tags_disp(struct report_handle *rh, struct field *field, return 1; } +static int _modules_disp(struct report_handle *rh, struct field *field, + const void *data) +{ + const struct logical_volume *lv = (const struct logical_volume *) data; + struct list *modules; + + if (!(modules = str_list_create(rh->mem))) { + log_error("modules str_list allocation failed"); + return 0; + } + + if (!list_lv_modules(rh->mem, lv, modules)) + return_0; + + return _tags_disp(rh, field, modules); +} + static int _vgfmt_disp(struct report_handle *rh, struct field *field, const void *data) { diff --git a/lib/snapshot/snapshot.c b/lib/snapshot/snapshot.c index 9d6f54a69..ded88f21b 100644 --- a/lib/snapshot/snapshot.c +++ b/lib/snapshot/snapshot.c @@ -20,6 +20,7 @@ #include "text_export.h" #include "config.h" #include "activate.h" +#include "str_list.h" static const char *_snap_name(const struct lv_segment *seg) { @@ -126,6 +127,18 @@ static int _snap_target_present(void) } #endif +static int _snap_modules_needed(struct dm_pool *mem, + const struct lv_segment *seg, + struct list *modules) +{ + if (!str_list_add(mem, modules, "snapshot")) { + log_error("snapshot string list allocation failed"); + return 0; + } + + return 1; +} + static void _snap_destroy(const struct segment_type *segtype) { dm_free((void *)segtype); @@ -139,6 +152,7 @@ static struct segtype_handler _snapshot_ops = { .target_percent = _snap_target_percent, .target_present = _snap_target_present, #endif + .modules_needed = _snap_modules_needed, .destroy = _snap_destroy, }; diff --git a/lib/striped/striped.c b/lib/striped/striped.c index 2b83c77ab..b413f0324 100644 --- a/lib/striped/striped.c +++ b/lib/striped/striped.c @@ -189,6 +189,17 @@ static int _striped_target_present(void) } #endif +static int _striped_modules_needed(struct dm_pool *mem, + const struct lv_segment *seg, + struct list *modules) +{ + const char *module; + + module = (seg->area_count == 1) ? "linear" : "striped"; + + return str_list_add(mem, modules, module); +} + static void _striped_destroy(const struct segment_type *segtype) { dm_free((void *)segtype); @@ -205,6 +216,7 @@ static struct segtype_handler _striped_ops = { .add_target_line = _striped_add_target_line, .target_present = _striped_target_present, #endif + .modules_needed = _striped_modules_needed, .destroy = _striped_destroy, }; diff --git a/lib/zero/zero.c b/lib/zero/zero.c index f577cb67f..943ca2691 100644 --- a/lib/zero/zero.c +++ b/lib/zero/zero.c @@ -63,6 +63,18 @@ static int _zero_target_present(void) } #endif +static int _zero_modules_needed(struct dm_pool *mem, + const struct lv_segment *seg, + struct list *modules) +{ + if (!str_list_add(mem, modules, "zero")) { + log_error("zero module string list allocation failed"); + return 0; + } + + return 1; +} + static void _zero_destroy(const struct segment_type *segtype) { dm_free((void *) segtype); @@ -75,6 +87,7 @@ static struct segtype_handler _zero_ops = { .add_target_line = _zero_add_target_line, .target_present = _zero_target_present, #endif + .modules_needed = _zero_modules_needed, .destroy = _zero_destroy, };