public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* LVM2 daemons/dmeventd/plugins/snapshot/dmevent ...
@ 2011-11-21 12:31 mornfall
0 siblings, 0 replies; 4+ messages in thread
From: mornfall @ 2011-11-21 12:31 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: mornfall@sourceware.org 2011-11-21 12:31:24
Modified files:
daemons/dmeventd/plugins/snapshot: dmeventd_snapshot.c
test/shell : lvextend-snapshot-dmeventd.sh
Log message:
Fix a bug in dmeventd snapshot monitoring code where the monitoring threshold
would grow with subsequent snapshot extensions (RHBZ 754198).
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c.diff?cvsroot=lvm2&r1=1.16&r2=1.17
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/shell/lvextend-snapshot-dmeventd.sh.diff?cvsroot=lvm2&r1=1.1&r2=1.2
--- LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c 2011/10/19 14:31:49 1.16
+++ LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c 2011/11/21 12:31:18 1.17
@@ -40,6 +40,11 @@
int max;
};
+struct dso_state {
+ int percent_check;
+ int known_size;
+};
+
/* FIXME possibly reconcile this with target_percent when we gain
access to regular LVM library here. */
static void _parse_snapshot_params(char *params, struct snap_status *status)
@@ -181,10 +186,11 @@
char *params;
struct snap_status status = { 0 };
const char *device = dm_task_get_name(dmt);
- int percent, *percent_check = (int*)private;
+ int percent;
+ struct dso_state *state = *private;
/* No longer monitoring, waiting for remove */
- if (!*percent_check)
+ if (!state->percent_check)
return;
dmeventd_lvm2_lock();
@@ -204,27 +210,35 @@
} /* else; too bad, but this is best-effort thing... */
}
+ /* Snapshot size had changed. Clear the threshold. */
+ if (state->known_size != status.max) {
+ state->percent_check = CHECK_MINIMUM;
+ state->known_size = status.max;
+ }
+
/*
* If the snapshot has been invalidated or we failed to parse
* the status string. Report the full status string to syslog.
*/
if (status.invalid || !status.max) {
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
- *percent_check = 0;
+ state->percent_check = 0;
goto out;
}
percent = 100 * status.used / status.max;
- if (percent >= *percent_check) {
+ if (percent >= state->percent_check) {
/* Usage has raised more than CHECK_STEP since the last
time. Run actions. */
- *percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
+ state->percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
+
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
/* Try to extend the snapshot, in accord with user-set policies */
if (!_extend(device))
syslog(LOG_ERR, "Failed to extend snapshot %s.", device);
}
+
out:
dmeventd_lvm2_unlock();
}
@@ -235,10 +249,14 @@
int minor __attribute__((unused)),
void **private)
{
- int *percent_check = (int*)private;
+ struct dso_state **state = (struct dso_state **) private;
int r = dmeventd_lvm2_init();
- *percent_check = CHECK_MINIMUM;
+ if (!(*state = dm_malloc(sizeof (struct dso_state))))
+ return 0;
+
+ (*state)->percent_check = CHECK_MINIMUM;
+ (*state)->known_size = 0;
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
return r;
@@ -248,10 +266,13 @@
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
- void **unused __attribute__((unused)))
+ void **private)
{
+ struct dso_state *state = *private;
syslog(LOG_INFO, "No longer monitoring snapshot %s\n",
device);
+
+ dm_free(state);
dmeventd_lvm2_exit();
return 1;
}
--- LVM2/test/shell/lvextend-snapshot-dmeventd.sh 2011/11/21 00:15:46 1.1
+++ LVM2/test/shell/lvextend-snapshot-dmeventd.sh 2011/11/21 12:31:21 1.2
@@ -27,7 +27,7 @@
which mkfs.ext2 || exit 200
-aux prepare_vg 2
+aux prepare_vg 3
aux prepare_dmeventd
lvcreate -l 8 -n base $vg
@@ -44,8 +44,19 @@
post=`percent`
test $pre = $post
+
write 2 5000
pre=`percent`
sleep 10 # dmeventd only checks every 10 seconds :(
post=`percent`
test $pre -gt $post
+
+# check that a second extension happens; we used to fail to extend when the
+# utilisation ended up between THRESH and (THRESH + 10)... see RHBZ 754198
+# (the utilisation after the write should be 57 %)
+
+write 3 5000
+pre=`percent`
+sleep 10 # dmeventd only checks every 10 seconds :(
+post=`percent`
+test $pre -gt $post
^ permalink raw reply [flat|nested] 4+ messages in thread
* LVM2 daemons/dmeventd/plugins/snapshot/dmevent ...
@ 2012-02-13 14:17 zkabelac
0 siblings, 0 replies; 4+ messages in thread
From: zkabelac @ 2012-02-13 14:17 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: zkabelac@sourceware.org 2012-02-13 14:17:04
Modified files:
daemons/dmeventd/plugins/snapshot: dmeventd_snapshot.c
. : WHATS_NEW_DM
Log message:
Make sure dereferenced words[0] and words[1] are defined
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c.diff?cvsroot=lvm2&r1=1.18&r2=1.19
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.556&r2=1.557
--- LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c 2011/12/22 16:37:03 1.18
+++ LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c 2012/02/13 14:17:04 1.19
@@ -144,7 +144,8 @@
break; /* eof, likely */
/* words[0] is the mount point and words[1] is the device path */
- dm_split_words(buffer, 3, 0, words);
+ if (dm_split_words(buffer, 3, 0, words) < 2)
+ continue;
/* find the major/minor of the device */
if (stat(words[0], &st))
--- LVM2/WHATS_NEW_DM 2012/02/13 12:06:39 1.556
+++ LVM2/WHATS_NEW_DM 2012/02/13 14:17:04 1.557
@@ -1,5 +1,6 @@
Version 1.02.71 -
====================================
+ Test for parsed words in _umount() dmeventd snapshot plugin.
Fix memory leak in fail path of parse_loop_device_name() in dmsetup.
Check for missing reply_uuid in dm_event_get_registered_device().
Check for allocation failure in dmeventd restart().
^ permalink raw reply [flat|nested] 4+ messages in thread
* LVM2 daemons/dmeventd/plugins/snapshot/dmevent ...
@ 2010-10-29 16:43 mornfall
0 siblings, 0 replies; 4+ messages in thread
From: mornfall @ 2010-10-29 16:43 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: mornfall@sourceware.org 2010-10-29 16:43:52
Modified files:
daemons/dmeventd/plugins/snapshot: dmeventd_snapshot.c
test : test-utils.sh
Added files:
test : t-snapshot-autoumount-dmeventd.sh
Log message:
Add code to the dmeventd snapshot plugin to automatically unmount snapshots
that have been invalidated.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c.diff?cvsroot=lvm2&r1=1.11&r2=1.12
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/t-snapshot-autoumount-dmeventd.sh.diff?cvsroot=lvm2&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/test-utils.sh.diff?cvsroot=lvm2&r1=1.54&r2=1.55
--- LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c 2010/10/15 16:28:14 1.11
+++ LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c 2010/10/29 16:43:51 1.12
@@ -21,6 +21,7 @@
#include "lvm-string.h"
+#include <sys/wait.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
@@ -31,6 +32,8 @@
/* Do not bother checking snapshots less than 50% full. */
#define CHECK_MINIMUM 50
+#define UMOUNT_COMMAND "/bin/umount"
+
struct snap_status {
int invalid;
int used;
@@ -71,6 +74,47 @@
status->max = atoi(p);
}
+static int _run(const char *cmd, ...)
+{
+ va_list ap;
+ int argc = 1; /* for argv[0], i.e. cmd */
+ int i = 0;
+ const char **argv;
+ pid_t pid = fork();
+ int status;
+
+ if (pid == 0) { /* child */
+ va_start(ap, cmd);
+ while (va_arg(ap, const char *))
+ ++ argc;
+ va_end(ap);
+
+ /* + 1 for the terminating NULL */
+ argv = alloca(sizeof(const char *) * (argc + 1));
+
+ argv[0] = cmd;
+ va_start(ap, cmd);
+ while ((argv[++i] = va_arg(ap, const char *)));
+ va_end(ap);
+
+ execvp(cmd, (char **)argv);
+ syslog(LOG_ERR, "Failed to execute %s: %s.\n", cmd, strerror(errno));
+ exit(127);
+ }
+
+ if (pid > 0) { /* parent */
+ if (waitpid(pid, &status, 0) != pid)
+ return 0; /* waitpid failed */
+ if (!WIFEXITED(status) || WEXITSTATUS(status))
+ return 0; /* the child failed */
+ }
+
+ if (pid < 0)
+ return 0; /* fork failed */
+
+ return 1; /* all good */
+}
+
static int _extend(const char *device)
{
char *vg = NULL, *lv = NULL, *layer = NULL;
@@ -93,6 +137,41 @@
return r == ECMD_PROCESSED;
}
+static void _umount(const char *device, int major, int minor)
+{
+ FILE *mounts;
+ char buffer[4096];
+ char *words[3];
+ struct stat st;
+
+ if (!(mounts = fopen("/proc/mounts", "r"))) {
+ syslog(LOG_ERR, "Could not read /proc/mounts. Not umounting %s.\n", device);
+ return;
+ }
+
+ while (!feof(mounts)) {
+ /* read a line of /proc/mounts */
+ if (!fgets(buffer, sizeof(buffer), mounts))
+ break; /* eof, likely */
+
+ /* words[0] is the mount point and words[1] is the device path */
+ dm_split_words(buffer, 3, 0, words);
+
+ /* find the major/minor of the device */
+ if (stat(words[0], &st))
+ continue; /* can't stat, skip this one */
+
+ if (S_ISBLK(st.st_mode) &&
+ major(st.st_rdev) == major &&
+ minor(st.st_rdev) == minor) {
+ syslog(LOG_ERR, "Unmounting invalid snapshot %s from %s.", device, words[1]);
+ if (!_run(UMOUNT_COMMAND, "-fl", words[1], NULL))
+ syslog(LOG_ERR, "Failed to umount snapshot %s from %s: %s.",
+ device, words[1], strerror(errno));
+ }
+ }
+}
+
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **private)
@@ -117,6 +196,16 @@
_parse_snapshot_params(params, &status);
+ if (status.invalid) {
+ syslog(LOG_ERR, "Trying to umount invalid snapshot %s...\n", device);
+ struct dm_info info;
+ if (dm_task_get_info(dmt, &info)) {
+ dmeventd_lvm2_unlock();
+ _umount(device, info.major, info.minor);
+ return;
+ } /* else; too bad, but this is best-effort thing... */
+ }
+
/*
* If the snapshot has been invalidated or we failed to parse
* the status string. Report the full status string to syslog.
/cvs/lvm2/LVM2/test/t-snapshot-autoumount-dmeventd.sh,v --> standard output
revision 1.1
--- LVM2/test/t-snapshot-autoumount-dmeventd.sh
+++ - 2010-10-29 16:43:52.931121000 +0000
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# no automatic extensions please
+LVM_TEST_CONFIG_SNAPSHOT_AUTOEXTEND="
+ snapshot_autoextend_percent = 0
+ snapshot_autoextend_threshold = 100"
+
+. ./test-utils.sh
+
+which mkfs.ext2 || exit 200
+
+prepare_lvmconf
+
+aux prepare_vg 2
+aux prepare_dmeventd
+
+lvcreate -l 8 -n base $vg
+mkfs.ext2 $DM_DEV_DIR/$vg/base
+
+lvcreate -s -l 4 -n snap $vg/base
+lvchange --monitor y $vg/snap
+
+mkdir mnt
+mount $DM_DEV_DIR/$vg/snap mnt
+mount
+cat /proc/mounts | grep $vg-snap
+
+dd if=/dev/zero of=mnt/file$1 bs=1M count=17
+sync
+sleep 10 # dmeventd only checks every 10 seconds :(
+
+cat /proc/mounts | not grep $vg-snap
--- LVM2/test/test-utils.sh 2010/10/26 01:25:46 1.54
+++ LVM2/test/test-utils.sh 2010/10/29 16:43:52 1.55
@@ -121,6 +121,7 @@
init_udev_transaction
while dmsetup table | grep -q ^$PREFIX; do
for s in `dmsetup info -c -o name --noheading | grep ^$PREFIX`; do
+ umount -fl $DM_DEV_DIR/mapper/$s || true
dmsetup remove $s >& /dev/null || true
done
done
@@ -360,6 +361,11 @@
test -z "$filter" && \
filter='[ "a/dev\/mirror/", "a/dev\/mapper\/.*pv[0-9_]*$/", "r/.*/" ]'
locktype=
+ if test -z "$LVM_TEST_CONFIG_SNAPSHOT_AUTOEXTEND"; then
+ LVM_TEST_CONFIG_SNAPSHOT_AUTOEXTEND="
+ snapshot_autoextend_percent = 50
+ snapshot_autoextend_threshold = 50"
+ fi
if test -n "$LVM_TEST_LOCKING"; then locktype="locking_type = $LVM_TEST_LOCKING"; fi
cat > $TESTDIR/etc/lvm.conf.new <<-EOF
$LVM_TEST_CONFIG
@@ -395,8 +401,7 @@
udev_sync = 1
udev_rules = 1
polling_interval = 0
- snapshot_autoextend_percent = 50
- snapshot_autoextend_threshold = 50
+ $LVM_TEST_CONFIG_SNAPSHOT_AUTOEXTEND
}
EOF
# FIXME remove this workaround after mmap & truncating file problems solved
^ permalink raw reply [flat|nested] 4+ messages in thread
* LVM2 daemons/dmeventd/plugins/snapshot/dmevent ...
@ 2010-10-15 16:28 mornfall
0 siblings, 0 replies; 4+ messages in thread
From: mornfall @ 2010-10-15 16:28 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: mornfall@sourceware.org 2010-10-15 16:28:16
Modified files:
daemons/dmeventd/plugins/snapshot: dmeventd_snapshot.c
doc : example.conf.in
lib/config : defaults.h
test : test-utils.sh
tools : commands.h lvresize.c
Added files:
test : t-lvextend-snapshot-dmeventd.sh
t-lvextend-snapshot-policy.sh
Log message:
Implement automatic snapshot extension with dmeventd, and add two new options
to lvm.conf in the activation section: 'snapshot_autoextend_threshold' and
'snapshot_autoextend_percent', that define how to handle automatic snapshot
extension. The former defines when the snapshot should be extended: when its
space usage exceeds this many percent. The latter defines how much extra space
should be allocated for the snapshot, in percent of its current size.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c.diff?cvsroot=lvm2&r1=1.10&r2=1.11
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/doc/example.conf.in.diff?cvsroot=lvm2&r1=1.14&r2=1.15
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/defaults.h.diff?cvsroot=lvm2&r1=1.69&r2=1.70
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/t-lvextend-snapshot-dmeventd.sh.diff?cvsroot=lvm2&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/t-lvextend-snapshot-policy.sh.diff?cvsroot=lvm2&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/test-utils.sh.diff?cvsroot=lvm2&r1=1.51&r2=1.52
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/commands.h.diff?cvsroot=lvm2&r1=1.155&r2=1.156
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvresize.c.diff?cvsroot=lvm2&r1=1.123&r2=1.124
--- LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c 2010/07/09 15:34:41 1.10
+++ LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c 2010/10/15 16:28:14 1.11
@@ -26,8 +26,10 @@
/* First warning when snapshot is 80% full. */
#define WARNING_THRESH 80
-/* Further warnings at 85%, 90% and 95% fullness. */
-#define WARNING_STEP 5
+/* Run a check every 5%. */
+#define CHECK_STEP 5
+/* Do not bother checking snapshots less than 50% full. */
+#define CHECK_MINIMUM 50
struct snap_status {
int invalid;
@@ -69,6 +71,28 @@
status->max = atoi(p);
}
+static int _extend(const char *device)
+{
+ char *vg = NULL, *lv = NULL, *layer = NULL;
+ char cmd_str[1024];
+ int r = 0;
+
+ if (!dm_split_lvm_name(dmeventd_lvm2_pool(), device, &vg, &lv, &layer)) {
+ syslog(LOG_ERR, "Unable to determine VG name from %s.", device);
+ return 0;
+ }
+ if (sizeof(cmd_str) <= snprintf(cmd_str, sizeof(cmd_str),
+ "lvextend --use-policies %s/%s", vg, lv)) {
+ syslog(LOG_ERR, "Unable to form LVM command: Device name too long.");
+ return 0;
+ }
+
+ r = dmeventd_lvm2_run(cmd_str);
+ syslog(LOG_INFO, "Extension of snapshot %s/%s %s.", vg, lv,
+ (r == ECMD_PROCESSED) ? "finished successfully" : "failed");
+ return r == ECMD_PROCESSED;
+}
+
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **private)
@@ -79,10 +103,10 @@
char *params;
struct snap_status status = { 0 };
const char *device = dm_task_get_name(dmt);
- int percent, *percent_warning = (int*)private;
+ int percent, *percent_check = (int*)private;
/* No longer monitoring, waiting for remove */
- if (!*percent_warning)
+ if (!*percent_check)
return;
dmeventd_lvm2_lock();
@@ -92,21 +116,27 @@
goto out;
_parse_snapshot_params(params, &status);
+
/*
* If the snapshot has been invalidated or we failed to parse
* the status string. Report the full status string to syslog.
*/
if (status.invalid || !status.max) {
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
- *percent_warning = 0;
+ *percent_check = 0;
goto out;
}
percent = 100 * status.used / status.max;
- if (percent >= *percent_warning) {
- syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
- /* Print warning on the next multiple of WARNING_STEP. */
- *percent_warning = (percent / WARNING_STEP) * WARNING_STEP + WARNING_STEP;
+ if (percent >= *percent_check) {
+ /* Usage has raised more than CHECK_STEP since the last
+ time. Run actions. */
+ *percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
+ if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
+ syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
+ /* Try to extend the snapshot, in accord with user-set policies */
+ if (!_extend(device))
+ syslog(LOG_ERR, "Failed to extend snapshot %s.", device);
}
out:
dmeventd_lvm2_unlock();
@@ -118,10 +148,10 @@
int minor __attribute__((unused)),
void **private)
{
- int *percent_warning = (int*)private;
+ int *percent_check = (int*)private;
int r = dmeventd_lvm2_init();
- *percent_warning = WARNING_THRESH; /* Print warning if snapshot is full */
+ *percent_check = CHECK_MINIMUM;
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
return r;
--- LVM2/doc/example.conf.in 2010/10/15 16:24:00 1.14
+++ LVM2/doc/example.conf.in 2010/10/15 16:28:15 1.15
@@ -428,6 +428,25 @@
mirror_log_fault_policy = "allocate"
mirror_image_fault_policy = "remove"
+ # 'snapshot_autoextend_threshold' and 'snapshot_autoextend_percent' define
+ # how to handle automatic snapshot extension. The former defines when the
+ # snapshot should be extended: when its space usage exceeds this many
+ # percent. The latter defines how much extra space should be allocated for
+ # the snapshot, in percent of its current size.
+ #
+ # For example, if you set snapshot_autoextend_threshold to 70 and
+ # snapshot_autoextend_percent to 20, whenever a snapshot exceeds 70% usage,
+ # it will be extended by another 20%. For a 1G snapshot, using up 700M will
+ # trigger a resize to 1.2G. When the usage exceeds 840M, the snapshot will
+ # be extended to 1.44G, and so on.
+ #
+ # Setting snapshot_autoextend_threshold to 100 disables automatic
+ # extensions. The minimum value is 50 (A setting below 50 will be treated
+ # as 50).
+
+ snapshot_autoextend_threshold = 100
+ snapshot_autoextend_percent = 20
+
# While activating devices, I/O to devices being (re)configured is
# suspended, and as a precaution against deadlocks, LVM2 needs to pin
# any memory it is using so it is not paged out. Groups of pages that
--- LVM2/lib/config/defaults.h 2010/10/13 15:40:39 1.69
+++ LVM2/lib/config/defaults.h 2010/10/15 16:28:15 1.70
@@ -148,5 +148,7 @@
#define DEFAULT_MIRROR_DEVICE_FAULT_POLICY "remove"
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
+#define DEFAULT_SNAPSHOT_AUTOEXTEND_THRESHOLD 100
+#define DEFAULT_SNAPSHOT_AUTOEXTEND_PERCENT 20
#endif /* _LVM_DEFAULTS_H */
/cvs/lvm2/LVM2/test/t-lvextend-snapshot-dmeventd.sh,v --> standard output
revision 1.1
--- LVM2/test/t-lvextend-snapshot-dmeventd.sh
+++ - 2010-10-15 16:28:17.556859000 +0000
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+. ./test-utils.sh
+
+extend() {
+ lvextend --use-policies --config "activation { snapshot_extend_threshold = $1 }" $vg/snap
+}
+
+write() {
+ mount $DM_DEV_DIR/$vg/snap mnt
+ dd if=/dev/zero of=mnt/file$1 bs=1k count=$2
+ umount mnt
+}
+
+percent() {
+ lvs $vg/snap -o snap_percent --noheadings | cut -c4- | cut -d. -f1
+}
+
+which mkfs.ext2 || exit 200
+
+aux prepare_vg 2
+aux prepare_dmeventd
+
+lvcreate -l 8 -n base $vg
+mkfs.ext2 $DM_DEV_DIR/$vg/base
+
+lvcreate -s -l 4 -n snap $vg/base
+lvchange --monitor y $vg/snap
+
+mkdir mnt
+
+write 1 4096
+pre=`percent`
+sleep 10 # dmeventd only checks every 10 seconds :(
+post=`percent`
+
+test $pre = $post
+write 2 5000
+pre=`percent`
+sleep 10 # dmeventd only checks every 10 seconds :(
+post=`percent`
+test $pre -gt $post
/cvs/lvm2/LVM2/test/t-lvextend-snapshot-policy.sh,v --> standard output
revision 1.1
--- LVM2/test/t-lvextend-snapshot-policy.sh
+++ - 2010-10-15 16:28:17.692973000 +0000
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+. ./test-utils.sh
+
+extend() {
+ lvextend --use-policies --config "activation { snapshot_extend_threshold = $1 }" $vg/snap
+}
+
+write() {
+ mount $DM_DEV_DIR/$vg/snap mnt
+ dd if=/dev/zero of=mnt/file$1 bs=1k count=$2
+ umount mnt
+}
+
+percent() {
+ lvs $vg/snap -o snap_percent --noheadings | cut -c4- | cut -d. -f1
+}
+
+which mkfs.ext2 || exit 200
+
+aux prepare_vg 2
+lvcreate -l 8 -n base $vg
+mkfs.ext2 $DM_DEV_DIR/$vg/base
+
+lvcreate -s -l 4 -n snap $vg/base
+mkdir mnt
+
+write 1 4096
+pre=`percent`
+extend 50
+post=`percent`
+
+test $pre = $post
+write 2 4096
+pre=`percent`
+extend 50
+post=`percent`
+test $pre -gt $post
--- LVM2/test/test-utils.sh 2010/10/12 16:13:43 1.51
+++ LVM2/test/test-utils.sh 2010/10/15 16:28:15 1.52
@@ -394,6 +394,8 @@
udev_sync = 1
udev_rules = 1
polling_interval = 0
+ snapshot_autoextend_percent = 50
+ snapshot_autoextend_threshold = 50
}
EOF
# FIXME remove this workaround after mmap & truncating file problems solved
--- LVM2/tools/commands.h 2010/10/13 10:34:32 1.155
+++ LVM2/tools/commands.h 2010/10/15 16:28:16 1.156
@@ -259,6 +259,7 @@
"\t{-l|--extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE|ORIGIN}] |\n"
"\t -L|--size [+]LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
"\t[-m|--mirrors Mirrors]\n"
+ "\t[--use-policies]\n"
"\t[-n|--nofsck]\n"
"\t[--noudevsync]\n"
"\t[-r|--resizefs]\n"
@@ -270,7 +271,7 @@
alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, mirrors_ARG,
nofsck_ARG, noudevsync_ARG, resizefs_ARG, size_ARG, stripes_ARG,
- stripesize_ARG, test_ARG, type_ARG)
+ stripesize_ARG, test_ARG, type_ARG, use_policies_ARG)
xx(lvmchange,
"With the device mapper, this is obsolete and does nothing.",
--- LVM2/tools/lvresize.c 2010/08/17 16:25:35 1.123
+++ LVM2/tools/lvresize.c 2010/10/15 16:28:16 1.124
@@ -186,6 +186,7 @@
const char *cmd_name;
char *st;
unsigned dev_dir_found = 0;
+ int use_policy = arg_count(cmd, use_policies_ARG);
lp->sign = SIGN_NONE;
lp->resize = LV_ANY;
@@ -196,34 +197,41 @@
if (!strcmp(cmd_name, "lvextend"))
lp->resize = LV_EXTEND;
- /*
- * Allow omission of extents and size if the user has given us
- * one or more PVs. Most likely, the intent was "resize this
- * LV the best you can with these PVs"
- */
- if ((arg_count(cmd, extents_ARG) + arg_count(cmd, size_ARG) == 0) &&
- (argc >= 2)) {
- lp->extents = 100;
- lp->percent = PERCENT_PVS;
+ if (use_policy) {
+ /* do nothing; _lvresize will handle --use-policies itself */
+ lp->extents = 0;
lp->sign = SIGN_PLUS;
- } else if ((arg_count(cmd, extents_ARG) +
- arg_count(cmd, size_ARG) != 1)) {
- log_error("Please specify either size or extents but not "
- "both.");
- return 0;
- }
-
- if (arg_count(cmd, extents_ARG)) {
- lp->extents = arg_uint_value(cmd, extents_ARG, 0);
- lp->sign = arg_sign_value(cmd, extents_ARG, SIGN_NONE);
- lp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
- }
-
- /* Size returned in kilobyte units; held in sectors */
- if (arg_count(cmd, size_ARG)) {
- lp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0));
- lp->sign = arg_sign_value(cmd, size_ARG, SIGN_NONE);
- lp->percent = PERCENT_NONE;
+ lp->percent = PERCENT_LV;
+ } else {
+ /*
+ * Allow omission of extents and size if the user has given us
+ * one or more PVs. Most likely, the intent was "resize this
+ * LV the best you can with these PVs"
+ */
+ if ((arg_count(cmd, extents_ARG) + arg_count(cmd, size_ARG) == 0) &&
+ (argc >= 2)) {
+ lp->extents = 100;
+ lp->percent = PERCENT_PVS;
+ lp->sign = SIGN_PLUS;
+ } else if ((arg_count(cmd, extents_ARG) +
+ arg_count(cmd, size_ARG) != 1)) {
+ log_error("Please specify either size or extents but not "
+ "both.");
+ return 0;
+ }
+
+ if (arg_count(cmd, extents_ARG)) {
+ lp->extents = arg_uint_value(cmd, extents_ARG, 0);
+ lp->sign = arg_sign_value(cmd, extents_ARG, SIGN_NONE);
+ lp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
+ }
+
+ /* Size returned in kilobyte units; held in sectors */
+ if (arg_count(cmd, size_ARG)) {
+ lp->size = arg_uint64_value(cmd, size_ARG, 0);
+ lp->sign = arg_sign_value(cmd, size_ARG, SIGN_NONE);
+ lp->percent = PERCENT_NONE;
+ }
}
if (lp->resize == LV_EXTEND && lp->sign == SIGN_MINUS) {
@@ -269,6 +277,33 @@
return 1;
}
+static int _adjust_policy_params(struct cmd_context *cmd,
+ struct logical_volume *lv, struct lvresize_params *lp)
+{
+ float percent;
+ percent_range_t range;
+ int policy_threshold, policy_amount;
+
+ policy_threshold =
+ find_config_tree_int(cmd, "activation/snapshot_autoextend_threshold",
+ DEFAULT_SNAPSHOT_AUTOEXTEND_THRESHOLD);
+ policy_amount =
+ find_config_tree_int(cmd, "activation/snapshot_autoextend_percent",
+ DEFAULT_SNAPSHOT_AUTOEXTEND_PERCENT);
+
+ if (policy_threshold >= 100)
+ return 1; /* nothing to do */
+
+ if (!lv_snapshot_percent(lv, &percent, &range))
+ return_0;
+
+ if (range != PERCENT_0_TO_100 || percent <= policy_threshold)
+ return 1; /* nothing to do */
+
+ lp->extents = policy_amount;
+ return 1;
+}
+
static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
struct lvresize_params *lp)
{
@@ -287,6 +322,7 @@
uint32_t seg_extents;
uint32_t sz, str;
struct dm_list *pvh = NULL;
+ int use_policy = arg_count(cmd, use_policies_ARG);
/* does LV exist? */
if (!(lvl = find_lv_in_vg(vg, lp->lv_name))) {
@@ -319,6 +355,14 @@
lv = lvl->lv;
+ if (use_policy) {
+ if (!lv_is_cow(lv)) {
+ log_error("Can't use policy-based resize for non-snapshot volumes.");
+ return ECMD_FAILED;
+ }
+ _adjust_policy_params(cmd, lv, lp);
+ }
+
if (!lv_is_visible(lv)) {
log_error("Can't resize internal logical volume %s", lv->name);
return ECMD_FAILED;
@@ -404,6 +448,8 @@
}
if (lp->extents == lv->le_count) {
+ if (use_policy)
+ return ECMD_PROCESSED; /* Nothing to do. */
if (!lp->resizefs) {
log_error("New size (%d extents) matches existing size "
"(%d extents)", lp->extents, lv->le_count);
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-02-13 14:17 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-21 12:31 LVM2 daemons/dmeventd/plugins/snapshot/dmevent mornfall
-- strict thread matches above, loose matches on Subject: below --
2012-02-13 14:17 zkabelac
2010-10-29 16:43 mornfall
2010-10-15 16:28 mornfall
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).