-2.02.19-cvs (2007-01-11)
+2.02.19-cvs (2007-01-12)
Version 2.02.19 -
===================================
+ Report dmeventd mirror monitoring status.
+ Fix dmeventd mirror status line processing.
Version 2.02.18 - 11th January 2007
===================================
#include "libdevmapper.h"
#include "libdevmapper-event.h"
#include "lvm2cmd.h"
-#include "lvm-string.h"
#include <errno.h>
#include <signal.h>
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 */
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];
#include "libdevmapper.h"
#include "libdevmapper-event.h"
#include "lvm2cmd.h"
-#include "lvm-string.h"
#include <errno.h>
#include <signal.h>
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 */
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];
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;
list_iterate(tmp, &lv->segments) {
seg = list_item(tmp, struct lv_segment);
+ if (!seg_monitored(seg) || (seg->status & PVMOVE))
+ continue;
reg = NULL;
+ /* 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 (seg->segtype->ops->target_register_events)
+ 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 (seg->segtype->ops->target_unregister_events)
- reg = seg->segtype->ops->target_unregister_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;
}
}
- if (register_dev_for_events(cmd, lv, 0) != 1)
+ if (register_dev_for_events(cmd, lv, 0) < 0)
/* FIXME Consider aborting here */
stack;
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;
return 0;
}
- if (register_dev_for_events(cmd, lv, 0) != 1)
+ if (register_dev_for_events(cmd, lv, 0) < 0)
stack;
memlock_inc();
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;
#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)
#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)
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,
}
#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;
}
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;
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()))
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;
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()))
.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
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);
(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;
}
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;
}
/*
- * returns the number of monitored devices, not the number
- * of _new_ monitored devices
+ * returns the number of _new_ monitored devices
*/
return count;
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");
}
"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");
}