From 8ef6eb30d94164f99a10eef236f529aee0d924c3 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Fri, 12 Jan 2007 20:38:30 +0000 Subject: [PATCH] Report dmeventd mirror monitoring status. --- VERSION | 2 +- WHATS_NEW | 2 + .../dmeventd/plugins/mirror/dmeventd_mirror.c | 15 +++-- dmeventd/mirror/dmeventd_mirror.c | 15 +++-- lib/activate/activate.c | 60 +++++++++++++++---- lib/metadata/segtype.h | 9 ++- lib/mirror/mirrored.c | 52 ++++++++++++---- tools/lvchange.c | 6 +- tools/lvrename.c | 8 +++ tools/vgchange.c | 7 +-- 10 files changed, 133 insertions(+), 43 deletions(-) diff --git a/VERSION b/VERSION index 3ea304933..748508560 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.02.19-cvs (2007-01-11) +2.02.19-cvs (2007-01-12) diff --git a/WHATS_NEW b/WHATS_NEW index 7aaf9659f..7d18746af 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,7 @@ Version 2.02.19 - =================================== + Report dmeventd mirror monitoring status. + Fix dmeventd mirror status line processing. Version 2.02.18 - 11th January 2007 =================================== diff --git a/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c b/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c index ffbedfa71..571a264ca 100644 --- a/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c +++ b/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c @@ -15,7 +15,6 @@ #include "libdevmapper.h" #include "libdevmapper-event.h" #include "lvm2cmd.h" -#include "lvm-string.h" #include #include @@ -62,8 +61,12 @@ static int _get_mirror_event(char *params) int log_argc, num_devs; /* - * Unused: 0 409600 mirror - * Used : 2 253:4 253:5 400/400 1 AA 3 cluster 253:3 A + * dm core parms: 0 409600 mirror + * Mirror core parms: 2 253:4 253:5 400/400 + * New-style failure params: 1 AA + * New-style log params: 3 cluster 253:3 A + * or 3 disk 253:3 A + * or 1 core */ /* number of devices */ @@ -74,9 +77,9 @@ static int _get_mirror_event(char *params) goto out_parse; p += strlen(p) + 1; - /* devices names + max log parameters */ - args = dm_malloc((num_devs + 8) * sizeof(char *)); - if (!args || dm_split_words(p, num_devs + 8, 0, args) < num_devs + 8) + /* devices names + "400/400" + "1 AA" + 1 or 3 log parms + NULL */ + args = dm_malloc((num_devs + 7) * sizeof(char *)); + if (!args || dm_split_words(p, num_devs + 7, 0, args) < num_devs + 5) goto out_parse; dev_status_str = args[2 + num_devs]; diff --git a/dmeventd/mirror/dmeventd_mirror.c b/dmeventd/mirror/dmeventd_mirror.c index ffbedfa71..571a264ca 100644 --- a/dmeventd/mirror/dmeventd_mirror.c +++ b/dmeventd/mirror/dmeventd_mirror.c @@ -15,7 +15,6 @@ #include "libdevmapper.h" #include "libdevmapper-event.h" #include "lvm2cmd.h" -#include "lvm-string.h" #include #include @@ -62,8 +61,12 @@ static int _get_mirror_event(char *params) int log_argc, num_devs; /* - * Unused: 0 409600 mirror - * Used : 2 253:4 253:5 400/400 1 AA 3 cluster 253:3 A + * dm core parms: 0 409600 mirror + * Mirror core parms: 2 253:4 253:5 400/400 + * New-style failure params: 1 AA + * New-style log params: 3 cluster 253:3 A + * or 3 disk 253:3 A + * or 1 core */ /* number of devices */ @@ -74,9 +77,9 @@ static int _get_mirror_event(char *params) goto out_parse; p += strlen(p) + 1; - /* devices names + max log parameters */ - args = dm_malloc((num_devs + 8) * sizeof(char *)); - if (!args || dm_split_words(p, num_devs + 8, 0, args) < num_devs + 8) + /* devices names + "400/400" + "1 AA" + 1 or 3 log parms + NULL */ + args = dm_malloc((num_devs + 7) * sizeof(char *)); + if (!args || dm_split_words(p, num_devs + 7, 0, args) < num_devs + 5) goto out_parse; dev_status_str = args[2 + num_devs]; diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 4e8239a3d..d2ab86ce9 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -655,10 +655,11 @@ int register_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv, int do_reg) { #ifdef DMEVENTD + int i, pending = 0, registered; int r = 0; struct list *tmp; struct lv_segment *seg; - int (*reg) (struct lv_segment *, int events); + int (*reg) (struct cmd_context *c, struct lv_segment *s, int e); if (do_reg && !dmeventd_register_mode()) return 1; @@ -666,24 +667,59 @@ int register_dev_for_events(struct cmd_context *cmd, list_iterate(tmp, &lv->segments) { seg = list_item(tmp, struct lv_segment); + if (!seg_monitored(seg) || (seg->status & PVMOVE)) + continue; reg = NULL; - if (do_reg) { - if (seg->segtype->ops->target_register_events) - reg = seg->segtype->ops->target_register_events; - } else if (seg->segtype->ops->target_unregister_events) - reg = seg->segtype->ops->target_unregister_events; + /* Check monitoring status */ + if (seg->segtype->ops->target_registered) + registered = seg->segtype->ops->target_registered(seg, &pending); + else + continue; /* segtype doesn't support registration */ + /* + * FIXME: We should really try again if pending + */ + registered = (pending) ? 0 : registered; + + if (do_reg) { + if (registered) + log_verbose("%s/%s already monitored.", lv->vg->name, lv->name); + else if (seg->segtype->ops->target_register_events) + reg = seg->segtype->ops->target_register_events; + } else { + if (!registered) + log_verbose("%s/%s already not monitored.", lv->vg->name, lv->name); + else if (seg->segtype->ops->target_unregister_events) + reg = seg->segtype->ops->target_unregister_events; + } + + /* Do [un]monitor */ if (!reg) continue; /* FIXME specify events */ - if (!reg(seg, 0)) { + if (!reg(cmd, seg, 0)) { stack; return -1; } - r = 1; + /* Check [un]monitor results */ + /* Try a couple times if pending, but not forever... */ + for (i = 0; i < 10; i++) { + pending = 0; + registered = seg->segtype->ops->target_registered(seg, &pending); + if (pending || + (!registered && do_reg) || + (registered && !do_reg)) + log_very_verbose("%s/%s %smonitoring still pending.", + lv->vg->name, lv->name, do_reg ? "" : "un"); + else + break; + sleep(1); + } + + r = (registered && do_reg) || (!registered && !do_reg); } return r; @@ -728,7 +764,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s, } } - if (register_dev_for_events(cmd, lv, 0) != 1) + if (register_dev_for_events(cmd, lv, 0) < 0) /* FIXME Consider aborting here */ stack; @@ -786,7 +822,7 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s, memlock_dec(); fs_unlock(); - if (register_dev_for_events(cmd, lv, 1) != 1) + if (register_dev_for_events(cmd, lv, 1) < 0) stack; return 1; @@ -832,7 +868,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s) return 0; } - if (register_dev_for_events(cmd, lv, 0) != 1) + if (register_dev_for_events(cmd, lv, 0) < 0) stack; memlock_inc(); @@ -905,7 +941,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, memlock_dec(); fs_unlock(); - if (!register_dev_for_events(cmd, lv, 1) != 1) + if (!register_dev_for_events(cmd, lv, 1) < 0) stack; return r; diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h index 3d3985cb2..e62fb7a10 100644 --- a/lib/metadata/segtype.h +++ b/lib/metadata/segtype.h @@ -32,6 +32,7 @@ struct dev_manager; #define SEG_FORMAT1_SUPPORT 0x00000010U #define SEG_VIRTUAL 0x00000020U #define SEG_CANNOT_BE_ZEROED 0x00000040U +#define SEG_MONITORED 0x00000080U #define seg_is_mirrored(seg) ((seg)->segtype->flags & SEG_AREAS_MIRRORED ? 1 : 0) #define seg_is_striped(seg) ((seg)->segtype->flags & SEG_AREAS_STRIPED ? 1 : 0) @@ -39,6 +40,7 @@ struct dev_manager; #define seg_is_virtual(seg) ((seg)->segtype->flags & SEG_VIRTUAL ? 1 : 0) #define seg_can_split(seg) ((seg)->segtype->flags & SEG_CAN_SPLIT ? 1 : 0) #define seg_cannot_be_zeroed(seg) ((seg)->segtype->flags & SEG_CANNOT_BE_ZEROED ? 1 : 0) +#define seg_monitored(seg) ((seg)->segtype->flags & SEG_MONITORED ? 1 : 0) #define segtype_is_striped(segtype) ((segtype)->flags & SEG_AREAS_STRIPED ? 1 : 0) #define segtype_is_mirrored(segtype) ((segtype)->flags & SEG_AREAS_MIRRORED ? 1 : 0) @@ -81,8 +83,11 @@ struct segtype_handler { 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); + int (*target_registered) (struct lv_segment *seg, int *pending); + int (*target_register_events) (struct cmd_context *cmd, + struct lv_segment *seg, int events); + int (*target_unregister_events) (struct cmd_context *cmd, + struct lv_segment *seg, int events); }; struct segment_type *get_segtype_from_string(struct cmd_context *cmd, diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c index a95d2950e..4437d2ff2 100644 --- a/lib/mirror/mirrored.c +++ b/lib/mirror/mirrored.c @@ -368,13 +368,12 @@ static int _mirrored_target_present(const struct lv_segment *seg __attribute((un } #ifdef DMEVENTD -static int _setup_registration(struct dm_pool *mem, struct cmd_context *cmd, - char **dso) +static int _setup_registration(struct cmd_context *cmd, char **dso) { char *path; const char *libpath; - if (!(path = dm_pool_alloc(mem, PATH_MAX))) { + if (!(path = dm_pool_alloc(cmd->mem, PATH_MAX))) { log_error("Failed to allocate dmeventd library path."); return 0; } @@ -389,9 +388,40 @@ static int _setup_registration(struct dm_pool *mem, struct cmd_context *cmd, return 1; } +static int _target_registered(struct lv_segment *seg, int *pending) +{ + char *dso, *name; + struct logical_volume *lv; + struct volume_group *vg; + enum dm_event_type events = 0; + + lv = seg->lv; + vg = lv->vg; + + *pending = 0; + if (!_setup_registration(vg->cmd, &dso)) { + stack; + return 0; + } + + if (!(name = build_dm_name(vg->cmd->mem, vg->name, lv->name, NULL))) + return_0; + + if (!dm_event_get_registered_device(&dso, &name, &events, 0)) + return 0; + + if (events & DM_EVENT_REGISTRATION_PENDING) { + *pending = 1; + events &= ~DM_EVENT_REGISTRATION_PENDING; + } + + return events; +} + /* FIXME This gets run while suspended and performs banned operations. */ /* FIXME Merge these two functions */ -static int _target_register_events(struct lv_segment *seg, +static int _target_register_events(struct cmd_context *cmd, + struct lv_segment *seg, int events) { char *dso, *name; @@ -402,12 +432,12 @@ static int _target_register_events(struct lv_segment *seg, lv = seg->lv; vg = lv->vg; - if (!_setup_registration(vg->cmd->mem, vg->cmd, &dso)) { + if (!_setup_registration(cmd, &dso)) { stack; return 0; } - if (!(name = build_dm_name(vg->cmd->mem, vg->name, lv->name, NULL))) + if (!(name = build_dm_name(cmd->mem, vg->name, lv->name, NULL))) return_0; if (!(handler = dm_event_handler_create())) @@ -427,7 +457,8 @@ static int _target_register_events(struct lv_segment *seg, return 1; } -static int _target_unregister_events(struct lv_segment *seg, +static int _target_unregister_events(struct cmd_context *cmd, + struct lv_segment *seg, int events) { char *dso; @@ -440,10 +471,10 @@ static int _target_unregister_events(struct lv_segment *seg, vg = lv->vg; /* FIXME Remove this and use handle to avoid config file race */ - if (!_setup_registration(vg->cmd->mem, vg->cmd, &dso)) + if (!_setup_registration(cmd, &dso)) return_0; - if (!(name = build_dm_name(vg->cmd->mem, vg->name, lv->name, NULL))) + if (!(name = build_dm_name(cmd->mem, vg->name, lv->name, NULL))) return_0; if (!(handler = dm_event_handler_create())) @@ -504,6 +535,7 @@ static struct segtype_handler _mirrored_ops = { .target_percent = _mirrored_target_percent, .target_present = _mirrored_target_present, #ifdef DMEVENTD + .target_registered = _target_registered, .target_register_events = _target_register_events, .target_unregister_events = _target_unregister_events, #endif @@ -530,7 +562,7 @@ struct segment_type *init_segtype(struct cmd_context *cmd) segtype->ops = &_mirrored_ops; segtype->name = "mirror"; segtype->private = NULL; - segtype->flags = SEG_AREAS_MIRRORED; + segtype->flags = SEG_AREAS_MIRRORED | SEG_MONITORED; log_very_verbose("Initialised segtype: %s", segtype->name); diff --git a/tools/lvchange.c b/tools/lvchange.c index 4f1210080..f49f23773 100644 --- a/tools/lvchange.c +++ b/tools/lvchange.c @@ -104,8 +104,10 @@ static int lvchange_registration(struct cmd_context *cmd, (dmeventd_register_mode()) ? "" : "un", lv->name); r = 0; } else if (!r) { - log_verbose("Logical volume %s needs no monitoring.", - lv->name); + log_verbose("Logical volume %s needs no %smonitoring, or is already %smonitored", + (dmeventd_register_mode()) ? "" : "un", + lv->name, + (dmeventd_register_mode()) ? "" : "un"); r = 1; } diff --git a/tools/lvrename.c b/tools/lvrename.c index f29b52b9f..67c8d1e34 100644 --- a/tools/lvrename.c +++ b/tools/lvrename.c @@ -152,6 +152,14 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv) goto error; } + if ((lv->status & MIRRORED) || + (lv->status & MIRROR_LOG) || + (lv->status & MIRROR_IMAGE)) { + log_error("Mirrored LV, \"%s\" cannot be renamed: %s", + lv->name, strerror(ENOSYS)); + goto error; + } + if (!archive(lv->vg)) { stack; goto error; diff --git a/tools/vgchange.c b/tools/vgchange.c index 2db2f067a..42762d84e 100644 --- a/tools/vgchange.c +++ b/tools/vgchange.c @@ -53,8 +53,7 @@ static int _register_lvs_in_vg(struct cmd_context *cmd, } /* - * returns the number of monitored devices, not the number - * of _new_ monitored devices + * returns the number of _new_ monitored devices */ return count; @@ -117,7 +116,7 @@ static int _vgchange_monitoring(struct cmd_context *cmd, struct volume_group *vg if ((active = lvs_in_vg_activated(vg))) { monitored = _register_lvs_in_vg(cmd, vg, dmeventd_register_mode()); log_print("%d logical volume(s) in volume group " - "\"%s\" now %smonitored", + "\"%s\" %smonitored", monitored, vg->name, (dmeventd_register_mode()) ? "" : "un"); } @@ -157,7 +156,7 @@ static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg) "already active", active, vg->name); monitored = _register_lvs_in_vg(cmd, vg, dmeventd_register_mode()); log_verbose("%d existing logical volume(s) in volume " - "group \"%s\" now %smonitored", + "group \"%s\" %smonitored", monitored, vg->name, dmeventd_register_mode() ? "" : "un"); }