Version 2.02.57 -
====================================
+ Add --poll flag to vgchange and lvchange.
Propagate commit and revert metadata notification to other nodes in cluster.
Use proper mask for VG lock mode in clvmd.
Add possibility to drop precommitted metadata in lvmcache.
#define DEFAULT_MIRROR_MAX_IMAGES 8 /* limited by kernel DM_KCOPYD_MAX_REGIONS */
#define DEFAULT_DMEVENTD_MIRROR_LIB "libdevmapper-event-lvm2mirror.so"
#define DEFAULT_DMEVENTD_MONITOR 1
+#define DEFAULT_BACKGROUND_POLLING 1
#define DEFAULT_UMASK 0077
static char _cmd_name[30] = "";
static int _mirror_in_sync = 0;
static int _dmeventd_monitor = DEFAULT_DMEVENTD_MONITOR;
+static int _background_polling = DEFAULT_BACKGROUND_POLLING;
static int _ignore_suspended_devices = 0;
static int _error_message_produced = 0;
static unsigned _is_static = 0;
_dmeventd_monitor = reg;
}
+void init_background_polling(int polling)
+{
+ _background_polling = polling;
+}
+
void init_ignore_suspended_devices(int ignore)
{
_ignore_suspended_devices = ignore;
return _trust_cache;
}
+int background_polling()
+{
+ return _background_polling;
+}
+
int ignorelockingfailure()
{
return _ignorelockingfailure;
void init_security_level(int level);
void init_mirror_in_sync(int in_sync);
void init_dmeventd_monitor(int reg);
+void init_background_polling(int polling);
void init_ignore_suspended_devices(int ignore);
void init_error_message_produced(int produced);
void init_is_static(unsigned value);
int lockingfailed(void);
int security_level(void);
int mirror_in_sync(void);
+int background_polling(void);
int ignore_suspended_devices(void);
const char *log_command_name(void);
unsigned is_static(void);
[\-\-ignorelockingfailure]
[\-\-ignoremonitoring]
[\-\-monitor {y|n}]
+[\-\-poll {y|n}]
[\-\-noudevsync]
[\-M|\-\-persistent y|n] [\-\-minor minor]
[\-P|\-\-partial]
\fBmirror_image_fault_policy\fP and \fBmirror_log_fault_policy\fP
set in \fBlvm.conf\fP.
.TP
+.I \-\-poll y|n
+Controls whether or not a logical volume's progress is polled. It may
+not be appropriate to immediately poll the progress of a logical
+volume's transformation when it is activated (for example, when merging
+a snapshot into the root FS). The progress polling of an incomplete
+pvmove or lvconvert can be deferred using \fB--poll n\fP and restarted
+using \fB--poll y\fP.
+.TP
.I \-\-noudevsync
Disable udev synchronisation. The
process will not wait for notification from udev.
.RB [ \-A | \-\-autobackup " {" y | n }]
.RB [ \-a | \-\-available " [e|l] {" y | n }]
.RB [ \-\-monitor " {" y | n }]
+.RB [ \-\-poll " {" y | n }]
.RB [ \-c | \-\-clustered " {" y | n }]
.RB [ \-u | \-\-uuid ]
.RB [ \-d | \-\-debug]
set in
.BR lvm.conf (5).
.TP
+.BR \-\-poll " " { y | n }
+Controls whether or not a logical volume's progress is polled. It may
+not be appropriate to immediately poll the progress of a logical
+volume's transformation when it is activated (for example, when merging
+a snapshot into the root FS). The progress polling of an incomplete
+pvmove or lvconvert can be deferred using \fB--poll n\fP and restarted
+using \fB--poll y\fP.
+.TP
.BR \-\-noudevsync
Disable udev synchronisation. The
process will not wait for notification from udev.
# Required-Stop: $local_fs
# Default-Start: 1 2 3 4 5
# Default-Stop: 0 6
-# Short-Description: Monitoring of LVM2 mirrors, snapshots etc. using dmeventd
+# Short-Description: Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
### END INIT INFO
. /etc/init.d/functions
VGSLIST=`$VGS --noheadings -o name 2> /dev/null`
for vg in $VGSLIST
do
- action "Starting monitoring for VG $vg:" $VGCHANGE --monitor y $vg || ret=$?
+ action "Starting monitoring for VG $vg:" $VGCHANGE --monitor y --poll y $vg || ret=$?
done
return $ret
arg(virtualoriginsize_ARG, '\0', "virtualoriginsize", size_mb_arg, 0)
arg(virtualsize_ARG, '\0', "virtualsize", size_mb_arg, 0)
arg(noudevsync_ARG, '\0', "noudevsync", NULL, 0)
+arg(poll_ARG, '\0', "poll", yes_no_arg, 0)
/* Allow some variations */
arg(resizable_ARG, '\0', "resizable", yes_no_arg, 0)
"\t[--ignorelockingfailure]\n"
"\t[--ignoremonitoring]\n"
"\t[--monitor {y|n}]\n"
+ "\t[--poll {y|n}]\n"
"\t[--noudevsync]\n"
"\t[-M|--persistent y|n] [--major major] [--minor minor]\n"
"\t[-P|--partial] " "\n"
alloc_ARG, autobackup_ARG, available_ARG, contiguous_ARG, force_ARG,
ignorelockingfailure_ARG, ignoremonitoring_ARG, major_ARG, minor_ARG,
monitor_ARG, noudevsync_ARG, partial_ARG, permission_ARG, persistent_ARG,
- readahead_ARG, resync_ARG, refresh_ARG, addtag_ARG, deltag_ARG, test_ARG,
- yes_ARG)
+ poll_ARG, readahead_ARG, resync_ARG, refresh_ARG, addtag_ARG, deltag_ARG,
+ test_ARG, yes_ARG)
xx(lvconvert,
"Change logical volume layout",
"\t[--ignorelockingfailure]\n"
"\t[--ignoremonitoring]\n"
"\t[--monitor {y|n}]\n"
+ "\t[--poll {y|n}]\n"
"\t[--noudevsync]\n"
"\t[--refresh]\n"
"\t[-t|--test]" "\n"
addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG, available_ARG,
clustered_ARG, deltag_ARG, ignorelockingfailure_ARG, ignoremonitoring_ARG,
logicalvolume_ARG, maxphysicalvolumes_ARG, monitor_ARG, noudevsync_ARG,
- partial_ARG, physicalextentsize_ARG, refresh_ARG, resizeable_ARG,
+ partial_ARG, physicalextentsize_ARG, poll_ARG, refresh_ARG, resizeable_ARG,
resizable_ARG, test_ARG, uuid_ARG)
xx(vgck,
return 1;
}
+static int lvchange_background_polling(struct cmd_context *cmd,
+ struct logical_volume *lv)
+{
+ struct lvinfo info;
+
+ if (!lv_info(cmd, lv, &info, 0, 0) || !info.exists) {
+ log_error("Logical volume, %s, is not active", lv->name);
+ return 0;
+ }
+
+ if (background_polling())
+ lv_spawn_background_polling(cmd, lv);
+
+ return 1;
+}
+
static int lvchange_availability(struct cmd_context *cmd,
struct logical_volume *lv)
{
return_0;
}
- lv_spawn_background_polling(cmd, lv);
+ if (background_polling())
+ lv_spawn_background_polling(cmd, lv);
}
return 1;
(is_static() || arg_count(cmd, ignoremonitoring_ARG)) ?
DMEVENTD_MONITOR_IGNORE : DEFAULT_DMEVENTD_MONITOR));
+ init_background_polling(arg_int_value(cmd, poll_ARG,
+ DEFAULT_BACKGROUND_POLLING));
+
/* access permission change */
if (arg_count(cmd, permission_ARG)) {
if (!archive(lv->vg)) {
}
}
+ if (!arg_count(cmd, available_ARG) &&
+ !arg_count(cmd, refresh_ARG) &&
+ arg_count(cmd, poll_ARG)) {
+ if (!lvchange_background_polling(cmd, lv)) {
+ stack;
+ return ECMD_FAILED;
+ }
+ }
+
if (doit != docmds) {
stack;
return ECMD_FAILED;
&& !arg_count(cmd, persistent_ARG) && !arg_count(cmd, addtag_ARG)
&& !arg_count(cmd, deltag_ARG) && !arg_count(cmd, refresh_ARG)
&& !arg_count(cmd, alloc_ARG) && !arg_count(cmd, monitor_ARG)
- && !arg_count(cmd, resync_ARG)) {
+ && !arg_count(cmd, poll_ARG) && !arg_count(cmd, resync_ARG)) {
log_error("Need 1 or more of -a, -C, -j, -m, -M, -p, -r, "
- "--resync, --refresh, --alloc, --addtag, --deltag "
- "or --monitor");
+ "--resync, --refresh, --alloc, --addtag, --deltag, "
+ "--monitor or --poll");
return EINVALID_CMD_LINE;
}
return count;
}
+static int _poll_lvs_in_vg(struct cmd_context *cmd,
+ struct volume_group *vg)
+{
+ struct lv_list *lvl;
+ struct logical_volume *lv;
+ struct lvinfo info;
+ int lv_active;
+ int count = 0;
+
+ dm_list_iterate_items(lvl, &vg->lvs) {
+ lv = lvl->lv;
+
+ if (!lv_info(cmd, lv, &info, 0, 0))
+ lv_active = 0;
+ else
+ lv_active = info.exists;
+
+ if (!lv_active ||
+ !(lv->status & (PVMOVE|CONVERTING)))
+ continue;
+
+ lv_spawn_background_polling(cmd, lv);
+ count++;
+ }
+
+ /*
+ * returns the number of polled devices
+ * - there is no way to know if lv is already being polled
+ */
+
+ return count;
+}
+
static int _activate_lvs_in_vg(struct cmd_context *cmd,
struct volume_group *vg, int activate)
{
} else if (!activate_lv(cmd, lv))
continue;
- if (activate != CHANGE_AN && activate != CHANGE_ALN &&
+ if (background_polling() &&
+ activate != CHANGE_AN && activate != CHANGE_ALN &&
(lv->status & (PVMOVE|CONVERTING)))
lv_spawn_background_polling(cmd, lv);
return ECMD_PROCESSED;
}
+static int _vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg)
+{
+ int polled;
+
+ if (lvs_in_vg_activated(vg) && background_polling()) {
+ polled = _poll_lvs_in_vg(cmd, vg);
+ log_print("Background polling started for %d logical volume(s) "
+ "in volume group \"%s\"",
+ polled, vg->name);
+ }
+
+ return ECMD_PROCESSED;
+}
+
static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg)
{
int lv_open, active, monitored;
(is_static() || arg_count(cmd, ignoremonitoring_ARG)) ?
DMEVENTD_MONITOR_IGNORE : DEFAULT_DMEVENTD_MONITOR));
+ init_background_polling(arg_int_value(cmd, poll_ARG,
+ DEFAULT_BACKGROUND_POLLING));
+
if (arg_count(cmd, available_ARG))
r = _vgchange_available(cmd, vg);
else if (arg_count(cmd, monitor_ARG))
r = _vgchange_monitoring(cmd, vg);
+ else if (arg_count(cmd, poll_ARG))
+ r = _vgchange_background_polling(cmd, vg);
+
else if (arg_count(cmd, resizeable_ARG))
r = _vgchange_resizeable(cmd, vg);
arg_count(cmd, addtag_ARG) + arg_count(cmd, uuid_ARG) +
arg_count(cmd, physicalextentsize_ARG) +
arg_count(cmd, clustered_ARG) + arg_count(cmd, alloc_ARG) +
- arg_count(cmd, monitor_ARG) + arg_count(cmd, refresh_ARG))) {
- log_error("One of -a, -c, -l, -p, -s, -x, --refresh, "
- "--uuid, --alloc, --addtag or --deltag required");
+ arg_count(cmd, monitor_ARG) + arg_count(cmd, poll_ARG) +
+ arg_count(cmd, refresh_ARG))) {
+ log_error("Need 1 or more of -a, -c, -l, -p, -s, -x, "
+ "--refresh, --uuid, --alloc, --addtag, --deltag, "
+ "--monitor or --poll");
return EINVALID_CMD_LINE;
}