Hi, Attached is a patch implementing "--forcesync" option of lvchange to start resync regardless of current log status. If the LV is created with "--nosync" option, the volume type flag of lvs changes from "M" to "m". This is useful to ensure mirrors are resynced after failure in corner case. Comments are welcome. Thanks, -- Jun'ichi Nomura, NEC Corporation of America
Add --forcesync option to lvchange to force resync mirror LV. It also turns 'M' (without initial sync) flag into 'm' (normal mirror) if the LV is created with --nosync. Applicable to LVM2 2.02.09. diff -X dontdiff -urp LVM2/include/log.h LVM2.forcesync-global/include/log.h --- LVM2/include/log.h 2006-08-17 23:42:36.000000000 -0400 +++ LVM2.forcesync-global/include/log.h 2006-09-11 22:17:01.000000000 -0400 @@ -75,6 +75,7 @@ void init_ignorelockingfailure(int level void init_lockingfailed(int level); void init_security_level(int level); void init_mirror_in_sync(int in_sync); +void init_mirror_force_sync(int force_sync); void init_dmeventd_register(int reg); void set_cmd_name(const char *cmd_name); @@ -90,6 +91,7 @@ int ignorelockingfailure(void); int lockingfailed(void); int security_level(void); int mirror_in_sync(void); +int mirror_force_sync(void); int dmeventd_register_mode(void); /* Suppress messages to stdout/stderr (1) or everywhere (2) */ diff -X dontdiff -urp LVM2/lib/log/log.c LVM2.forcesync-global/lib/log/log.c --- LVM2/lib/log/log.c 2006-08-23 04:18:58.000000000 -0400 +++ LVM2.forcesync-global/lib/log/log.c 2006-09-11 21:22:23.000000000 -0400 @@ -48,6 +48,7 @@ static char _cmd_name[30] = ""; static char _msg_prefix[30] = " "; static int _already_logging = 0; static int _mirror_in_sync = 0; +static int _mirror_force_sync = 0; static int _dmeventd_register = DEFAULT_DMEVENTD_MONITOR; static lvm2_log_fn_t _lvm2_log_fn = NULL; @@ -189,6 +190,11 @@ void init_mirror_in_sync(int in_sync) _mirror_in_sync = in_sync; } +void init_mirror_force_sync(int force_sync) +{ + _mirror_force_sync = force_sync; +} + void init_dmeventd_register(int reg) { _dmeventd_register = reg; @@ -268,6 +274,11 @@ int mirror_in_sync(void) return _mirror_in_sync; } +int mirror_force_sync(void) +{ + return _mirror_force_sync; +} + int dmeventd_register_mode(void) { return _dmeventd_register; diff -X dontdiff -urp LVM2/lib/log/log.h LVM2.forcesync-global/lib/log/log.h --- LVM2/lib/log/log.h 2006-08-17 23:42:36.000000000 -0400 +++ LVM2.forcesync-global/lib/log/log.h 2006-09-11 22:17:01.000000000 -0400 @@ -75,6 +75,7 @@ void init_ignorelockingfailure(int level void init_lockingfailed(int level); void init_security_level(int level); void init_mirror_in_sync(int in_sync); +void init_mirror_force_sync(int force_sync); void init_dmeventd_register(int reg); void set_cmd_name(const char *cmd_name); @@ -90,6 +91,7 @@ int ignorelockingfailure(void); int lockingfailed(void); int security_level(void); int mirror_in_sync(void); +int mirror_force_sync(void); int dmeventd_register_mode(void); /* Suppress messages to stdout/stderr (1) or everywhere (2) */ diff -X dontdiff -urp LVM2/lib/mirror/mirrored.c LVM2.forcesync-global/lib/mirror/mirrored.c --- LVM2/lib/mirror/mirrored.c 2006-07-29 00:46:10.000000000 -0400 +++ LVM2.forcesync-global/lib/mirror/mirrored.c 2006-09-11 21:28:16.000000000 -0400 @@ -255,7 +255,9 @@ static int _add_log(struct dev_manager * log_flags |= DM_CORELOG; } - if (mirror_in_sync() && !(seg->status & PVMOVE)) + if (mirror_force_sync()) + log_flags |= DM_FORCESYNC; + else if (mirror_in_sync() && !(seg->status & PVMOVE)) log_flags |= DM_NOSYNC; if (_block_on_error_available && !(seg->status & PVMOVE)) diff -X dontdiff -urp LVM2/tools/args.h LVM2.forcesync-global/tools/args.h --- LVM2/tools/args.h 2006-08-17 23:42:36.000000000 -0400 +++ LVM2.forcesync-global/tools/args.h 2006-09-11 21:23:28.000000000 -0400 @@ -46,6 +46,7 @@ arg(alloc_ARG, '\0', "alloc", alloc_arg) arg(separator_ARG, '\0', "separator", string_arg) arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL) arg(nosync_ARG, '\0', "nosync", NULL) +arg(forcesync_ARG, '\0', "forcesync", NULL) arg(corelog_ARG, '\0', "corelog", NULL) arg(monitor_ARG, '\0', "monitor", yes_no_arg) arg(config_ARG, '\0', "config", string_arg) diff -X dontdiff -urp LVM2/tools/commands.h LVM2.forcesync-global/tools/commands.h --- LVM2/tools/commands.h 2006-08-17 23:42:36.000000000 -0400 +++ LVM2.forcesync-global/tools/commands.h 2006-09-11 21:23:04.000000000 -0400 @@ -61,6 +61,7 @@ xx(lvchange, "\t[-d|--debug]\n" "\t[--deltag Tag]\n" "\t[-f|--force]\n" + "\t[--forcesync]\n" "\t[-h|--help]\n" "\t[--ignorelockingfailure]\n" "\t[--monitor {y|n}]\n" @@ -75,7 +76,7 @@ xx(lvchange, "\tLogicalVolume[Path] [LogicalVolume[Path]...]\n", alloc_ARG, autobackup_ARG, available_ARG, contiguous_ARG, force_ARG, - ignorelockingfailure_ARG, major_ARG, minor_ARG, monitor_ARG, + forcesync_ARG, ignorelockingfailure_ARG, major_ARG, minor_ARG, monitor_ARG, partial_ARG, permission_ARG, persistent_ARG, readahead_ARG, refresh_ARG, addtag_ARG, deltag_ARG, test_ARG) diff -X dontdiff -urp LVM2/tools/lvchange.c LVM2.forcesync-global/tools/lvchange.c --- LVM2/tools/lvchange.c 2006-07-29 02:20:07.000000000 -0400 +++ LVM2.forcesync-global/tools/lvchange.c 2006-09-13 01:19:02.000000000 -0400 @@ -175,6 +175,63 @@ static int lvchange_refresh(struct cmd_c return 1; } +static int lvchange_syncstatus(struct cmd_context *cmd, + struct logical_volume *lv) +{ + struct lvinfo info; + + if (!(lv->status & MIRRORED)) + return 1; + + if (!lv_info(cmd, lv, &info, 0) || !info.exists) { + log_error("Logical volume, %s, is not active", lv->name); + return 0; + } + + init_mirror_force_sync(1); + + if (!(lv->status & MIRROR_NOTSYNCED)) + return lvchange_refresh(cmd, lv); + + /* + * We need to drop MIRROR_NOTSYNCED flag in metadata. + * We can do it only after the logical volume once has been + * activated with force sync to ensure disk log is updated by kernel. + */ + if (!lvchange_refresh(cmd, lv)) { + log_error("Failed to unmark %s not-synced", lv->name); + return 0; + } + + lv->status &= ~MIRROR_NOTSYNCED; + + log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); + if (!vg_write(lv->vg)) { + stack; + return 0; + } + + backup(lv->vg); + + if (!suspend_lv(cmd, lv)) { + log_error("Failed to lock %s", lv->name); + vg_revert(lv->vg); + return 0; + } + + if (!vg_commit(lv->vg)) { + resume_lv(cmd, lv); + return 0; + } + + if (!resume_lv(cmd, lv)) { + log_error("Problem reactivating %s", lv->name); + return 0; + } + + return 1; +} + static int lvchange_alloc(struct cmd_context *cmd, struct logical_volume *lv) { int want_contiguous = 0; @@ -502,6 +559,10 @@ static int lvchange_single(struct cmd_co return ECMD_FAILED; } + if (arg_count(cmd, forcesync_ARG)) + if (!lvchange_syncstatus(cmd, lv)) + return ECMD_FAILED; + if (arg_count(cmd, refresh_ARG)) if (!lvchange_refresh(cmd, lv)) return ECMD_FAILED; @@ -523,9 +584,10 @@ int lvchange(struct cmd_context *cmd, in && !arg_count(cmd, minor_ARG) && !arg_count(cmd, major_ARG) && !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, alloc_ARG) && !arg_count(cmd, monitor_ARG) + && !arg_count(cmd, forcesync_ARG)) { log_error("Need 1 or more of -a, -C, -j, -m, -M, -p, -r, " - "--refresh, --alloc, --addtag, --deltag " + "--forcesync, --refresh, --alloc, --addtag, --deltag " "or --monitor"); return EINVALID_CMD_LINE; }
_______________________________________________ linux-lvm mailing list linux-lvm@redhat.com https://www.redhat.com/mailman/listinfo/linux-lvm read the LVM HOW-TO at http://tldp.org/HOWTO/LVM-HOWTO/