diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c index 4e51c7e85..fb452c6fd 100644 --- a/lib/locking/file_locking.c +++ b/lib/locking/file_locking.c @@ -244,6 +244,10 @@ int init_file_locking(struct locking_type *locking, struct config_file *cf) if (!create_dir(_lock_dir)) return 0; + /* Trap a read-only file system */ + if ((access(_lock_dir, R_OK | W_OK | X_OK) == -1) && (errno == EROFS)) + return 0; + list_init(&_lock_list); if (sigfillset(&_intsigset) || sigfillset(&_fullsigset)) { diff --git a/lib/locking/locking.c b/lib/locking/locking.c index 0073d4893..6ebf10804 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -75,24 +75,32 @@ int init_locking(int type, struct config_file *cf) init_no_locking(&_locking, cf); log_print("WARNING: Locking disabled. Be careful! " "This could corrupt your metadata."); - break; + return 1; + case 1: if (!init_file_locking(&_locking, cf)) - return 0; + break; log_very_verbose("File-based locking enabled."); - break; + return 1; case 2: if (!init_external_locking(&_locking, cf)) - return 0; + break; log_very_verbose("External locking enabled."); - break; + return 1; default: log_error("Unknown locking type requested."); return 0; } + if (!ignorelockingfailure()) + return 0; + + log_verbose("Locking disabled - only read operations permitted."); + + init_no_locking(&_locking, cf); + return 1; } diff --git a/lib/log/log.c b/lib/log/log.c index f6cf07cd4..ce576fcf5 100644 --- a/lib/log/log.c +++ b/lib/log/log.c @@ -18,6 +18,7 @@ static int _syslog = 0; static int _indent = 1; static int _log_cmd_name = 0; static int _log_suppress = 0; +static int _ignorelockingfailure = 0; static char _cmd_name[30] = ""; static char _msg_prefix[30] = " "; @@ -66,6 +67,11 @@ void init_partial(int level) _partial = level; } +void init_ignorelockingfailure(int level) +{ + _ignorelockingfailure = level; +} + void init_cmd_name(int status) { _log_cmd_name = status; @@ -100,6 +106,11 @@ int partial_mode() return _partial; } +int ignorelockingfailure() +{ + return _ignorelockingfailure; +} + void init_debug(int level) { _debug_level = level; diff --git a/lib/log/log.h b/lib/log/log.h index 810f2fddb..112e2df56 100644 --- a/lib/log/log.h +++ b/lib/log/log.h @@ -52,12 +52,14 @@ void init_debug(int level); void init_cmd_name(int status); void init_msg_prefix(const char *prefix); void init_indent(int indent); +void init_ignorelockingfailure(int level); void set_cmd_name(const char *cmd_name); int test_mode(void); int partial_mode(void); int debug_level(void); +int ignorelockingfailure(void); /* Suppress messages to stdout/stderr */ void log_suppress(int suppress); diff --git a/tools/args.h b/tools/args.h index b2eda99c6..ecfb1d12c 100644 --- a/tools/args.h +++ b/tools/args.h @@ -11,6 +11,7 @@ arg(version_ARG, '\0', "version", NULL) arg(quiet_ARG, '\0', "quiet", NULL) arg(physicalvolumesize_ARG, '\0', "setphysicalvolumesize", size_arg) +arg(ignorelockingfailure_ARG, '\0', "ignorelockingfailure", NULL) /* Allow some variations */ arg(resizable_ARG, '\0', "resizable", yes_no_arg) diff --git a/tools/commands.h b/tools/commands.h index 036acd16e..bac069290 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -63,7 +63,8 @@ xx(lvchange, autobackup_ARG, available_ARG, contiguous_ARG, minor_ARG, persistent_ARG, partial_ARG, - permission_ARG, readahead_ARG, test_ARG) + permission_ARG, readahead_ARG, test_ARG, + ignorelockingfailure_ARG) xx(lvcreate, "Create a logical volume", @@ -103,7 +104,7 @@ xx(lvdisplay, "\t[-v/--verbose]\n" "\tLogicalVolume[Path] [LogicalVolume[Path]...]\n", - colon_ARG, disk_ARG, maps_ARG, partial_ARG) + colon_ARG, disk_ARG, maps_ARG, partial_ARG, ignorelockingfailure_ARG) xx(lvextend, "Add space to a logical volume", @@ -230,7 +231,7 @@ xx(lvscan, "\t[-v|--verbose] " "\n" "\t[--version]\n", - blockdevice_ARG, disk_ARG, partial_ARG) + blockdevice_ARG, disk_ARG, partial_ARG, ignorelockingfailure_ARG); xx(pvchange, "Change attributes of physical volume(s)", @@ -291,7 +292,7 @@ xx(pvdisplay, "\t[-v/--verbose]\n" "\tPhysicalVolumePath [PhysicalVolumePath...]\n", - colon_ARG, maps_ARG, short_ARG) + colon_ARG, maps_ARG, short_ARG, ignorelockingfailure_ARG) xx(pvmove, "Move extents from one physical volume to another", @@ -334,7 +335,8 @@ xx(pvscan, "\t[-v|--verbose] " "\n" "\t[--version]\n", - exported_ARG, novolumegroup_ARG, partial_ARG, short_ARG, uuid_ARG) + exported_ARG, novolumegroup_ARG, partial_ARG, short_ARG, uuid_ARG, + ignorelockingfailure_ARG) xx(vgcfgbackup, "Backup volume group configuration(s)", @@ -345,7 +347,7 @@ xx(vgcfgbackup, "\t[-v|--verbose]" "\n" "\t[-V|--version] " "\n" "\t[VolumeGroupName...]\n", - file_ARG) + file_ARG, partial_ARG, ignorelockingfailure_ARG) xx(vgcfgrestore, "Restore volume group configuration", @@ -379,7 +381,7 @@ xx(vgchange, autobackup_ARG, available_ARG, logicalvolume_ARG, partial_ARG, resizeable_ARG, resizable_ARG, allocation_ARG, - test_ARG) + test_ARG, ignorelockingfailure_ARG) xx(vgck, "Check the consistency of volume group(s)", @@ -418,7 +420,8 @@ xx(vgdisplay, "\t[--version]" "\n" "\t[VolumeGroupName...] ]\n", - activevolumegroups_ARG, colon_ARG, disk_ARG, short_ARG, partial_ARG) + activevolumegroups_ARG, colon_ARG, disk_ARG, short_ARG, partial_ARG, + ignorelockingfailure_ARG) xx(vgexport, "Unregister volume group(s) from the system", @@ -524,7 +527,7 @@ xx(vgscan, "\t[-h/-?/--help]\n" "\t[-P/--partial] " "\n" "\t[-v/--verbose]\n" , - partial_ARG) + partial_ARG, ignorelockingfailure_ARG) xx(vgsplit, "Move physical volumes into a new volume group", diff --git a/tools/lvchange.c b/tools/lvchange.c index 6e6942e51..8f9b50ca2 100644 --- a/tools/lvchange.c +++ b/tools/lvchange.c @@ -41,6 +41,13 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv) return EINVALID_CMD_LINE; } + if (arg_count(cmd, ignorelockingfailure_ARG) && + (arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) || + arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG))) { + log_error("Only -a permitted with --ignorelockingfailure"); + return EINVALID_CMD_LINE; + } + if (!argc) { log_error("Please give logical volume path(s)"); return EINVALID_CMD_LINE; diff --git a/tools/lvm.c b/tools/lvm.c index f6434a1a4..366b906bc 100644 --- a/tools/lvm.c +++ b/tools/lvm.c @@ -640,6 +640,11 @@ static int process_common_commands(struct command *com) } else init_partial(0); + if (arg_count(cmd, ignorelockingfailure_ARG)) + init_ignorelockingfailure(1); + else + init_ignorelockingfailure(0); + /* Handle synonyms */ if (!merge_synonym(resizable_ARG, resizeable_ARG) || !merge_synonym(allocation_ARG, allocatable_ARG) || diff --git a/tools/vgchange.c b/tools/vgchange.c index 87424f06e..9deeb4535 100644 --- a/tools/vgchange.c +++ b/tools/vgchange.c @@ -63,6 +63,12 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv) return EINVALID_CMD_LINE; } + if (arg_count(cmd, ignorelockingfailure_ARG) && + !arg_count(cmd, available_ARG)) { + log_error("--ignorelockingfailure only available with -a"); + return EINVALID_CMD_LINE; + } + if (arg_count(cmd, available_ARG) == 1 && arg_count(cmd, autobackup_ARG)) { log_error("-A option not necessary with -a option");