diff --git a/WHATS_NEW b/WHATS_NEW index 4733f7821..8ad10e865 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,8 @@ Version 2.02.33 - =================================== + Fix mirror log name construction during lvconvert. (2.02.30) + Make monitor_dev_for_events recurse through the stack of LVs. + Clean up some more compiler warnings. Some whitespace tidy-ups. Use stack return macros throughout. Rely upon internally-cached PV labels while corresponding VG lock is held. diff --git a/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c b/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c index decac02be..2d53d4f7a 100644 --- a/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c +++ b/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c @@ -125,8 +125,9 @@ out_parse: return ME_IGNORE; } -static void _temporary_log_fn(int level, const char *file, - int line, const char *format) +static void _temporary_log_fn(int level, const char *file __attribute((unused)), + int line __attribute((unused)), + const char *format) { if (!strncmp(format, "WARNING: ", 9) && (level < 5)) syslog(LOG_CRIT, "%s", format); @@ -164,7 +165,8 @@ static int _remove_failed_devices(const char *device) return (r == 1) ? 0 : -1; } -void process_event(struct dm_task *dmt, enum dm_event_mask event, +void process_event(struct dm_task *dmt, + enum dm_event_mask event __attribute((unused)), void **unused __attribute((unused))) { void *next = NULL; @@ -222,8 +224,11 @@ void process_event(struct dm_task *dmt, enum dm_event_mask event, pthread_mutex_unlock(&_event_mutex); } -int register_device(const char *device, const char *uuid, int major, int minor, - void **unused __attribute((unused))) +int register_device(const char *device, + const char *uuid __attribute((unused)), + int major __attribute((unused)), + int minor __attribute((unused)), + void **unused __attribute((unused))) { int r = 0; @@ -259,8 +264,11 @@ out: return r; } -int unregister_device(const char *device, const char *uuid, int major, int minor, - void **unused __attribute((unused))) +int unregister_device(const char *device, + const char *uuid __attribute((unused)), + int major __attribute((unused)), + int minor __attribute((unused)), + void **unused __attribute((unused))) { pthread_mutex_lock(&_register_mutex); diff --git a/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c b/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c index 75a74c580..28e663a5f 100644 --- a/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c +++ b/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c @@ -54,8 +54,10 @@ struct snap_status { */ static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER; -static void _temporary_log_fn(int level, const char *file, - int line, const char *format) +static void _temporary_log_fn(int level, + const char *file __attribute((unused)), + int line __attribute((unused)), + const char *format) { if (!strncmp(format, "WARNING: ", 9) && (level < 5)) syslog(LOG_CRIT, "%s", format); @@ -115,7 +117,8 @@ fail: dm_event_handler_destroy(dmevh); } -void process_event(struct dm_task *dmt, enum dm_event_mask event, +void process_event(struct dm_task *dmt, + enum dm_event_mask event __attribute((unused)), void **private) { void *next = NULL; @@ -161,8 +164,11 @@ out: pthread_mutex_unlock(&_event_mutex); } -int register_device(const char *device, const char *uuid, int major, int minor, - void **private) +int register_device(const char *device, + const char *uuid __attribute((unused)), + int major __attribute((unused)), + int minor __attribute((unused)), + void **private) { int r = 0; int *percent_warning = (int*)private; @@ -201,8 +207,11 @@ out: return r; } -int unregister_device(const char *device, const char *uuid, int major, int minor, - void **unused __attribute((unused))) +int unregister_device(const char *device, + const char *uuid __attribute((unused)), + int major __attribute((unused)), + int minor __attribute((unused)), + void **unused __attribute((unused))) { pthread_mutex_lock(&_register_mutex); diff --git a/dmeventd/mirror/dmeventd_mirror.c b/dmeventd/mirror/dmeventd_mirror.c index decac02be..2d53d4f7a 100644 --- a/dmeventd/mirror/dmeventd_mirror.c +++ b/dmeventd/mirror/dmeventd_mirror.c @@ -125,8 +125,9 @@ out_parse: return ME_IGNORE; } -static void _temporary_log_fn(int level, const char *file, - int line, const char *format) +static void _temporary_log_fn(int level, const char *file __attribute((unused)), + int line __attribute((unused)), + const char *format) { if (!strncmp(format, "WARNING: ", 9) && (level < 5)) syslog(LOG_CRIT, "%s", format); @@ -164,7 +165,8 @@ static int _remove_failed_devices(const char *device) return (r == 1) ? 0 : -1; } -void process_event(struct dm_task *dmt, enum dm_event_mask event, +void process_event(struct dm_task *dmt, + enum dm_event_mask event __attribute((unused)), void **unused __attribute((unused))) { void *next = NULL; @@ -222,8 +224,11 @@ void process_event(struct dm_task *dmt, enum dm_event_mask event, pthread_mutex_unlock(&_event_mutex); } -int register_device(const char *device, const char *uuid, int major, int minor, - void **unused __attribute((unused))) +int register_device(const char *device, + const char *uuid __attribute((unused)), + int major __attribute((unused)), + int minor __attribute((unused)), + void **unused __attribute((unused))) { int r = 0; @@ -259,8 +264,11 @@ out: return r; } -int unregister_device(const char *device, const char *uuid, int major, int minor, - void **unused __attribute((unused))) +int unregister_device(const char *device, + const char *uuid __attribute((unused)), + int major __attribute((unused)), + int minor __attribute((unused)), + void **unused __attribute((unused))) { pthread_mutex_lock(&_register_mutex); diff --git a/dmeventd/snapshot/dmeventd_snapshot.c b/dmeventd/snapshot/dmeventd_snapshot.c index 75a74c580..28e663a5f 100644 --- a/dmeventd/snapshot/dmeventd_snapshot.c +++ b/dmeventd/snapshot/dmeventd_snapshot.c @@ -54,8 +54,10 @@ struct snap_status { */ static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER; -static void _temporary_log_fn(int level, const char *file, - int line, const char *format) +static void _temporary_log_fn(int level, + const char *file __attribute((unused)), + int line __attribute((unused)), + const char *format) { if (!strncmp(format, "WARNING: ", 9) && (level < 5)) syslog(LOG_CRIT, "%s", format); @@ -115,7 +117,8 @@ fail: dm_event_handler_destroy(dmevh); } -void process_event(struct dm_task *dmt, enum dm_event_mask event, +void process_event(struct dm_task *dmt, + enum dm_event_mask event __attribute((unused)), void **private) { void *next = NULL; @@ -161,8 +164,11 @@ out: pthread_mutex_unlock(&_event_mutex); } -int register_device(const char *device, const char *uuid, int major, int minor, - void **private) +int register_device(const char *device, + const char *uuid __attribute((unused)), + int major __attribute((unused)), + int minor __attribute((unused)), + void **private) { int r = 0; int *percent_warning = (int*)private; @@ -201,8 +207,11 @@ out: return r; } -int unregister_device(const char *device, const char *uuid, int major, int minor, - void **unused __attribute((unused))) +int unregister_device(const char *device, + const char *uuid __attribute((unused)), + int major __attribute((unused)), + int minor __attribute((unused)), + void **unused __attribute((unused))) { pthread_mutex_lock(&_register_mutex); diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 71d54f031..21b125422 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -679,6 +679,7 @@ int monitor_dev_for_events(struct cmd_context *cmd, struct list *tmp, *snh, *snht; struct lv_segment *seg; int (*monitor_fn) (struct lv_segment *s, int e); + uint32_t s; /* skip dmeventd code altogether */ if (dmeventd_monitor_mode() == DMEVENTD_MONITOR_IGNORE) @@ -715,6 +716,19 @@ int monitor_dev_for_events(struct cmd_context *cmd, list_iterate(tmp, &lv->segments) { seg = list_item(tmp, struct lv_segment); + /* Recurse for AREA_LV */ + for (s = 0; s < seg->area_count; s++) { + if (seg_type(seg, s) != AREA_LV) + continue; + if (!monitor_dev_for_events(cmd, seg_lv(seg, s), + monitor)) { + log_error("Failed to %smonitor %s", + monitor ? "" : "un", + seg_lv(seg, s)->name); + r = 0; + } + } + if (!seg_monitored(seg) || (seg->status & PVMOVE)) continue; diff --git a/lib/filters/filter-md.c b/lib/filters/filter-md.c index 26d0296c9..c1ecff726 100644 --- a/lib/filters/filter-md.c +++ b/lib/filters/filter-md.c @@ -19,7 +19,8 @@ #ifdef linux -static int _ignore_md(struct dev_filter *f, struct device *dev) +static int _ignore_md(struct dev_filter *f __attribute((unused)), + struct device *dev) { int ret; diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c index 08fbccf8a..2dac312d5 100644 --- a/lib/metadata/mirror.c +++ b/lib/metadata/mirror.c @@ -1182,7 +1182,7 @@ static struct logical_volume *_create_mirror_log(struct logical_volume *lv, return NULL; } - if (dm_snprintf(log_name, len, "%s%s", lv->name, suffix) < 0) { + if (dm_snprintf(log_name, len, "%s%s", lv_name, suffix) < 0) { log_error("log_name allocation failed."); return NULL; } @@ -1207,7 +1207,9 @@ static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd, int in_sync) { struct logical_volume *log_lv; - const char *suffix; + const char *suffix, *c; + char *lv_name; + size_t len; struct lv_segment *seg; init_mirror_in_sync(in_sync); @@ -1217,15 +1219,34 @@ static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd, return NULL; } - /* Check if the log is for temporary sync layer. */ + /* Mirror log name is lv_name + suffix, determined as the following: + * 1. suffix is: + * o "_mlog" for the original mirror LV. + * o "_mlogtmp_%d" for temporary mirror LV, + * 2. lv_name is: + * o lv->name, if the log is temporary + * o otherwise, the top-level LV name + */ seg = first_seg(lv); if (seg_type(seg, 0) == AREA_LV && - strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER)) + strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER)) { + lv_name = lv->name; suffix = "_mlogtmp_%d"; - else + } else if ((c = strstr(lv->name, MIRROR_SYNC_LAYER))) { + len = c - lv->name + 1; + if (!(lv_name = alloca(len)) || + !dm_snprintf(lv_name, len, "%s", lv->name)) { + log_error("mirror log name allocation failed"); + return 0; + } suffix = "_mlog"; + } else { + lv_name = lv->name; + suffix = "_mlog"; + } - if (!(log_lv = _create_mirror_log(lv, ah, alloc, lv->name, suffix))) { + if (!(log_lv = _create_mirror_log(lv, ah, alloc, + (const char *) lv_name, suffix))) { log_error("Failed to create mirror log."); return NULL; } diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c index 1a7a8e31d..48577e3de 100644 --- a/lib/mirror/mirrored.c +++ b/lib/mirror/mirrored.c @@ -456,7 +456,8 @@ static int _target_monitored(struct lv_segment *seg, int *pending) } /* FIXME This gets run while suspended and performs banned operations. */ -static int _target_set_events(struct lv_segment *seg, int evmask, int set) +static int _target_set_events(struct lv_segment *seg, + int evmask __attribute((unused)), int set) { char *dso, *name; struct logical_volume *lv; diff --git a/lib/report/report.c b/lib/report/report.c index ace48d07e..7e1b67969 100644 --- a/lib/report/report.c +++ b/lib/report/report.c @@ -1049,7 +1049,7 @@ static const struct dm_report_object_type _report_types[] = { #define STR DM_REPORT_FIELD_TYPE_STRING #define NUM DM_REPORT_FIELD_TYPE_NUMBER -#define FIELD(type, strct, sorttype, head, field, width, func, id, desc) {type, sorttype, (off_t)((void *)&_dummy._ ## strct.field - (void *)&_dummy._ ## strct), width, id, head, &_ ## func ## _disp, desc}, +#define FIELD(type, strct, sorttype, head, field, width, func, id, desc) {type, sorttype, (off_t)((uintptr_t)&_dummy._ ## strct.field - (uintptr_t)&_dummy._ ## strct), width, id, head, &_ ## func ## _disp, desc}, static struct dm_report_field_type _fields[] = { #include "columns.h" diff --git a/lib/snapshot/snapshot.c b/lib/snapshot/snapshot.c index c8980be3a..cb166f90c 100644 --- a/lib/snapshot/snapshot.c +++ b/lib/snapshot/snapshot.c @@ -213,7 +213,8 @@ static int _target_registered(struct lv_segment *seg, int *pending) } /* FIXME This gets run while suspended and performs banned operations. */ -static int _target_set_events(struct lv_segment *seg, int events, int set) +static int _target_set_events(struct lv_segment *seg, + int events __attribute((unused)), int set) { char *dso, *name; struct volume_group *vg = seg->lv->vg; diff --git a/test/t-mirror-names.sh b/test/t-mirror-names.sh new file mode 100644 index 000000000..4674a39ff --- /dev/null +++ b/test/t-mirror-names.sh @@ -0,0 +1,206 @@ +#!/bin/sh +# Copyright (C) 2007-2008 Red Hat, Inc. All rights reserved. +# Copyright (C) 2007-2008 NEC Corporation +# +# 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_description="check namings of mirrored LV" +privileges_required_=1 + +. ./test-lib.sh + +dmsetup_has_dm_devdir_support_ || +{ + say "Your version of dmsetup lacks support for changing DM_DEVDIR." + say "Skipping this test" + exit 0 +} + +cleanup_() +{ + test -n "$vg" && { + lvremove -ff $vg + vgremove $vg + } > /dev/null + test -n "$pvs" && { + pvremove $pvs > /dev/null + for d in $pvs; do + dmsetup remove $(basename $d) + done + } + losetup -d $lodev + rm -f $lofile +} + +# --------------------------------------------------------------------- +# config + +nr_pvs=5 +pvsize=$((80 * 1024 * 2)) + +vg=mirror-names-vg-$$ +lv1=lv1 +lv2=lv2 + +# --------------------------------------------------------------------- +# Utilities + +pv_() +{ + echo "$G_dev_/mapper/pv$1" +} + +lv_devices_() +{ + local d + local lv=$1 + shift + local devices=$* + + local devs=$(lvs -a -odevices --noheadings $lv | sed 's/([0-9]*)//g' | + sed 's/ //g' | sed 's/,/ /g') + + for d in $devs; do + (echo $devices | grep -q $d) || return 1 + devices=$(echo $devices | sed "s/$d//") + done + + [ "$(echo $devices | sed 's/ //g')" = "" ] +} + +lv_mirror_log_() +{ + local lv=$1 + + echo $(lvs -a -omirror_log --noheadings $lv | sed 's/ //g') +} + +lv_convert_lv_() +{ + local lv=$1 + + echo $(lvs -a -oconvert_lv --noheadings $lv | sed 's/ //g') +} + +# --------------------------------------------------------------------- +# Initialize PVs and VGs + +test_expect_success \ + 'set up temp file and loopback device' \ + 'lofile=$(pwd)/lofile && lodev=$(loop_setup_ "$lofile")' + +offset=0 +pvs= +for n in $(seq 1 $nr_pvs); do + test_expect_success \ + "create pv$n" \ + 'echo "0 $pvsize linear $lodev $offset" > in && + dmsetup create pv$n < in' + offset=$(($offset + $pvsize)) +done + +for n in $(seq 1 $nr_pvs); do + pvs="$pvs $(pv_ $n)" +done + +test_expect_success \ + "Run this: pvcreate $pvs" \ + 'pvcreate $pvs' + +test_expect_success \ + 'set up a VG' \ + 'vgcreate $vg $pvs' + +# --------------------------------------------------------------------- +# Common environment setup/cleanup for each sub testcases + +prepare_lvs_() +{ + lvremove -ff $vg; + : +} + +check_and_cleanup_lvs_() +{ + lvs -a -o+devices $vg && + lvremove -ff $vg +} + +test_expect_success "check environment setup/cleanup" \ + 'prepare_lvs_ && + check_and_cleanup_lvs_' + +# --------------------------------------------------------------------- +# basic + +test_expect_success "init: lvcreate" "prepare_lvs_" + +test_expect_success "mirror images are ${lv1}_mimage_x" \ + 'lvcreate -l2 -m1 -n $lv1 $vg && + lv_devices_ $vg/$lv1 "$lv1"_mimage_0 "$lv1"_mimage_1' + +test_expect_success "mirror log is ${lv1}_mlog" \ + 'lv_mirror_log_ $vg/$lv1 "$lv1"_mlog' + +test_expect_success "cleanup" "check_and_cleanup_lvs_" + +# --------------------------------------------------------------------- +# lvrename + +test_expect_success "init: lvrename" "prepare_lvs_" + +test_expect_success "renamed mirror names: $lv1 to $lv2" \ + 'lvcreate -l2 -m1 -n $lv1 $vg && + lvrename $vg/$lv1 $vg/$lv2 && + lv_devices_ $vg/$lv2 "$lv2"_mimage_0 "$lv2"_mimage_1 && + lv_mirror_log_ $vg/$lv2 "$lv2"_mlog' + +test_expect_success "cleanup" "check_and_cleanup_lvs_" + +# --------------------------------------------------------------------- +# lvconvert + +test_expect_success "init: lvconvert" "prepare_lvs_" + +test_expect_success "converting mirror names is ${lv1}_mimagetmp_2" \ + 'lvcreate -l2 -m1 -n $lv1 $vg && + lvconvert -m+1 -i1000 -b $vg/$lv1 && + convlv=$(lv_convert_lv_ "$vg/$lv1") && + test "$convlv" = "$lv1"_mimagetmp_2 && + lv_devices_ $vg/$lv1 "$convlv" "$lv1"_mimage_2 && + lv_devices_ "$vg/$convlv" "$lv1"_mimage_0 "$lv1"_mimage_1 && + loglv=$(lv_mirror_log_ "$vg/$convlv") && + test "$loglv" = "$lv1"_mlog' + +test_expect_success "mirror log name after re-adding is ${lv1}_mlog" \ + 'lvconvert --mirrorlog core $vg/$lv1 && + lvconvert --mirrorlog disk $vg/$lv1 && + convlv=$(lv_convert_lv_ "$vg/$lv1") && + lv_devices_ $vg/$lv1 "$convlv" "$lv1"_mimage_2 && + lv_devices_ "$vg/$convlv" "$lv1"_mimage_0 "$lv1"_mimage_1 && + loglv=$(lv_mirror_log_ "$vg/$convlv") && + test "$loglv" = "$lv1"_mlog' + +test_expect_success "renamed converting mirror names: $lv1 to $lv2" \ + 'lvrename $vg/$lv1 $vg/$lv2 && + convlv=$(lv_convert_lv_ "$vg/$lv2") && + lv_devices_ $vg/$lv2 "$convlv" "$lv2"_mimage_2 && + lv_devices_ "$vg/$convlv" "$lv2"_mimage_0 "$lv2"_mimage_1 && + loglv=$(lv_mirror_log_ "$vg/$convlv") && + test "$loglv" = "$lv2"_mlog' + +test_expect_success "cleanup" "check_and_cleanup_lvs_" + +# Temporary mirror log should have "_mlogtmp_" suffix +# but currently lvconvert doesn't have an option to add the log. +# If such feature is added in future, a test for that should +# be added. + +# --------------------------------------------------------------------- +test_done diff --git a/tools/lvm-static.c b/tools/lvm-static.c index 4c3224699..b0c1e12a3 100644 --- a/tools/lvm-static.c +++ b/tools/lvm-static.c @@ -20,7 +20,8 @@ int main(int argc, char **argv) return lvm2_main(argc, argv, 1); } -int lvm_shell(struct cmd_context *cmd, struct cmdline_context *cmdline) +int lvm_shell(struct cmd_context *cmd __attribute((unused)), + struct cmdline_context *cmdline __attribute((unused))) { return 0; } diff --git a/tools/lvm.c b/tools/lvm.c index 7a8c36cc7..7d58ae829 100644 --- a/tools/lvm.c +++ b/tools/lvm.c @@ -121,7 +121,8 @@ static char *_list_args(const char *text, int state) } /* Custom completion function */ -static char **_completion(const char *text, int start_pos, int end_pos) +static char **_completion(const char *text, int start_pos, + int end_pos __attribute((unused))) { char **match_list = NULL; int p = 0; diff --git a/tools/lvm2cmd.c b/tools/lvm2cmd.c index ba37463e0..a8d09bf1c 100644 --- a/tools/lvm2cmd.c +++ b/tools/lvm2cmd.c @@ -20,7 +20,8 @@ void *lvm2_init(void) return cmdlib_lvm2_init(0); } -int lvm_shell(struct cmd_context *cmd, struct cmdline_context *cmdline) +int lvm_shell(struct cmd_context *cmd __attribute((unused)), + struct cmdline_context *cmdline __attribute((unused))) { return 0; }