mirror of
git://sourceware.org/git/lvm2.git
synced 2024-10-06 22:19:30 +03:00
Merge branch 'master' into 2018-05-11-fork-libdm
This commit is contained in:
commit
89fdc0b588
@ -1,6 +1,6 @@
|
||||
#
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of LVM2.
|
||||
#
|
||||
@ -61,6 +61,7 @@ po: tools daemons
|
||||
man: tools
|
||||
all_man: tools
|
||||
scripts: liblvm libdm
|
||||
test: tools daemons
|
||||
|
||||
lib.device-mapper: include.device-mapper
|
||||
libdm.device-mapper: include.device-mapper
|
||||
@ -96,7 +97,7 @@ endif
|
||||
DISTCLEAN_TARGETS += cscope.out
|
||||
CLEAN_DIRS += autom4te.cache
|
||||
|
||||
check check_system check_cluster check_local check_lvmetad check_lvmpolld check_lvmlockd_test check_lvmlockd_dlm check_lvmlockd_sanlock: all
|
||||
check check_system check_cluster check_local check_lvmetad check_lvmpolld check_lvmlockd_test check_lvmlockd_dlm check_lvmlockd_sanlock: test
|
||||
$(MAKE) -C test $(@)
|
||||
|
||||
conf.generate man.generate: tools
|
||||
@ -145,7 +146,7 @@ install_system_dirs:
|
||||
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_RUN_DIR)
|
||||
$(INSTALL_ROOT_DATA) /dev/null $(DESTDIR)$(DEFAULT_CACHE_DIR)/.cache
|
||||
|
||||
install_initscripts:
|
||||
install_initscripts:
|
||||
$(MAKE) -C scripts install_initscripts
|
||||
|
||||
install_systemd_generators:
|
||||
@ -168,6 +169,7 @@ install_tmpfiles_configuration:
|
||||
|
||||
LCOV_TRACES = libdm.info lib.info liblvm.info tools.info \
|
||||
libdaemon/client.info libdaemon/server.info \
|
||||
test/unit.info \
|
||||
daemons/clvmd.info \
|
||||
daemons/dmeventd.info \
|
||||
daemons/lvmetad.info \
|
||||
|
@ -1,5 +1,9 @@
|
||||
Version 2.02.178 -
|
||||
=====================================
|
||||
Remove lvm1 and pool format handling and add filter to ignore them.
|
||||
Move some filter checks to after disks are read.
|
||||
Rework disk scanning and when it is used.
|
||||
Add new io layer and shift code to using it.
|
||||
lvconvert: don't return success on degraded -m raid1 conversion
|
||||
--enable-testing switch for ./configure has been removed.
|
||||
--with-snapshots switch for ./configure has been removed.
|
||||
|
@ -702,29 +702,17 @@ global {
|
||||
activation = 1
|
||||
|
||||
# Configuration option global/fallback_to_lvm1.
|
||||
# Try running LVM1 tools if LVM cannot communicate with DM.
|
||||
# This option only applies to 2.4 kernels and is provided to help
|
||||
# switch between device-mapper kernels and LVM1 kernels. The LVM1
|
||||
# tools need to be installed with .lvm1 suffices, e.g. vgscan.lvm1.
|
||||
# They will stop working once the lvm2 on-disk metadata format is used.
|
||||
# This setting is no longer used.
|
||||
# This configuration option has an automatic default value.
|
||||
# fallback_to_lvm1 = @DEFAULT_FALLBACK_TO_LVM1@
|
||||
# fallback_to_lvm1 = 0
|
||||
|
||||
# Configuration option global/format.
|
||||
# The default metadata format that commands should use.
|
||||
# The -M 1|2 option overrides this setting.
|
||||
#
|
||||
# Accepted values:
|
||||
# lvm1
|
||||
# lvm2
|
||||
#
|
||||
# This setting is no longer used.
|
||||
# This configuration option has an automatic default value.
|
||||
# format = "lvm2"
|
||||
|
||||
# Configuration option global/format_libraries.
|
||||
# Shared libraries that process different metadata formats.
|
||||
# If support for LVM1 metadata was compiled as a shared library use
|
||||
# format_libraries = "liblvm2format1.so"
|
||||
# This setting is no longer used.
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option global/segment_libraries.
|
||||
@ -821,13 +809,6 @@ global {
|
||||
# encountered the internal error. Please only enable for debugging.
|
||||
abort_on_internal_errors = 0
|
||||
|
||||
# Configuration option global/detect_internal_vg_cache_corruption.
|
||||
# Internal verification of VG structures.
|
||||
# Check if CRC matches when a parsed VG is used multiple times. This
|
||||
# is useful to catch unexpected changes to cached VG structures.
|
||||
# Please only enable for debugging.
|
||||
detect_internal_vg_cache_corruption = 0
|
||||
|
||||
# Configuration option global/metadata_read_only.
|
||||
# No operations that change on-disk metadata are permitted.
|
||||
# Additionally, read-only commands that encounter metadata in need of
|
||||
|
5
configure
vendored
5
configure
vendored
@ -6141,7 +6141,7 @@ fi
|
||||
|
||||
|
||||
for ac_header in assert.h ctype.h dirent.h errno.h fcntl.h float.h \
|
||||
getopt.h inttypes.h langinfo.h libgen.h limits.h locale.h paths.h \
|
||||
getopt.h inttypes.h langinfo.h libaio.h libgen.h limits.h locale.h paths.h \
|
||||
signal.h stdarg.h stddef.h stdio.h stdlib.h string.h sys/file.h \
|
||||
sys/ioctl.h syslog.h sys/mman.h sys/param.h sys/resource.h sys/stat.h \
|
||||
sys/time.h sys/types.h sys/utsname.h sys/wait.h time.h \
|
||||
@ -15559,7 +15559,7 @@ _ACEOF
|
||||
|
||||
|
||||
################################################################################
|
||||
ac_config_files="$ac_config_files Makefile make.tmpl libdm/make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/dmfilemapd/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/lvmdbusd daemons/lvmdbusd/lvmdb.py daemons/lvmdbusd/lvm_shell_proxy.py daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/Makefile lib/Makefile lib/locking/Makefile include/lvm-version.h libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile"
|
||||
ac_config_files="$ac_config_files Makefile make.tmpl libdm/make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/dmfilemapd/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/lvmdbusd daemons/lvmdbusd/lvmdb.py daemons/lvmdbusd/lvm_shell_proxy.py daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/Makefile lib/Makefile lib/locking/Makefile include/lvm-version.h libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/api/python_lvm_unit.py test/unit/Makefile tools/Makefile udev/Makefile"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
@ -16326,6 +16326,7 @@ do
|
||||
"scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
|
||||
"test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
|
||||
"test/api/Makefile") CONFIG_FILES="$CONFIG_FILES test/api/Makefile" ;;
|
||||
"test/api/python_lvm_unit.py") CONFIG_FILES="$CONFIG_FILES test/api/python_lvm_unit.py" ;;
|
||||
"test/unit/Makefile") CONFIG_FILES="$CONFIG_FILES test/unit/Makefile" ;;
|
||||
"tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
|
||||
"udev/Makefile") CONFIG_FILES="$CONFIG_FILES udev/Makefile" ;;
|
||||
|
@ -103,7 +103,7 @@ AC_HEADER_SYS_WAIT
|
||||
AC_HEADER_TIME
|
||||
|
||||
AC_CHECK_HEADERS([assert.h ctype.h dirent.h errno.h fcntl.h float.h \
|
||||
getopt.h inttypes.h langinfo.h libgen.h limits.h locale.h paths.h \
|
||||
getopt.h inttypes.h langinfo.h libaio.h libgen.h limits.h locale.h paths.h \
|
||||
signal.h stdarg.h stddef.h stdio.h stdlib.h string.h sys/file.h \
|
||||
sys/ioctl.h syslog.h sys/mman.h sys/param.h sys/resource.h sys/stat.h \
|
||||
sys/time.h sys/types.h sys/utsname.h sys/wait.h time.h \
|
||||
@ -2158,6 +2158,7 @@ scripts/lvmdump.sh
|
||||
scripts/Makefile
|
||||
test/Makefile
|
||||
test/api/Makefile
|
||||
test/api/python_lvm_unit.py
|
||||
test/unit/Makefile
|
||||
tools/Makefile
|
||||
udev/Makefile
|
||||
|
@ -27,6 +27,8 @@ ifeq ("@BUILD_LOCKDDLM@", "yes")
|
||||
LOCK_LIBS += -ldlm_lt
|
||||
endif
|
||||
|
||||
SOURCES2 = lvmlockctl.c
|
||||
|
||||
TARGETS = lvmlockd lvmlockctl
|
||||
|
||||
.PHONY: install_lvmlockd
|
||||
|
@ -229,3 +229,110 @@ It may be worthwhile to change the filters to use the udev info as a hint,
|
||||
or only use udev info for filtering in reporting commands where
|
||||
inaccuracies are not a big problem.)
|
||||
|
||||
|
||||
|
||||
I/O Performance
|
||||
---------------
|
||||
|
||||
. 400 loop devices used as PVs
|
||||
. 40 VGs each with 10 PVs
|
||||
. each VG has one active LV
|
||||
. each of the 10 PVs in vg0 has an artificial 100 ms read delay
|
||||
. read/write/io_submit are system call counts using strace
|
||||
. old is lvm 2.2.175
|
||||
. new is lvm 2.2.178 (shortly before)
|
||||
|
||||
|
||||
Command: pvs
|
||||
------------
|
||||
old: 0m17.422s
|
||||
new: 0m0.331s
|
||||
|
||||
old: read 7773 write 497
|
||||
new: read 2807 write 495 io_submit 448
|
||||
|
||||
|
||||
Command: vgs
|
||||
------------
|
||||
old: 0m20.383s
|
||||
new: 0m0.325s
|
||||
|
||||
old: read 10684 write 129
|
||||
new: read 2807 write 129 io_submit 448
|
||||
|
||||
|
||||
Command: vgck vg0
|
||||
-----------------
|
||||
old: 0m16.212s
|
||||
new: 0m1.290s
|
||||
|
||||
old: read 6372 write 4
|
||||
new: read 2807 write 4 io_submit 458
|
||||
|
||||
|
||||
Command: lvcreate -n test -l1 -an vg0
|
||||
-------------------------------------
|
||||
old: 0m29.271s
|
||||
new: 0m1.351s
|
||||
|
||||
old: read 6503 write 39
|
||||
new: read 2808 write 9 io_submit 488
|
||||
|
||||
|
||||
Command: lvremove vg0/test
|
||||
--------------------------
|
||||
old: 0m29.262s
|
||||
new: 0m1.348s
|
||||
|
||||
old: read 6502 write 36
|
||||
new: read 2807 write 6 io_submit 488
|
||||
|
||||
|
||||
io_submit sources
|
||||
-----------------
|
||||
|
||||
vgs:
|
||||
reads:
|
||||
- 400 for each PV
|
||||
- 40 for each LV
|
||||
- 8 for other devs on the system
|
||||
|
||||
vgck vg0:
|
||||
reads:
|
||||
- 400 for each PV
|
||||
- 40 for each LV
|
||||
- 10 for each PV in vg0 (rescan)
|
||||
- 8 for other devs on the system
|
||||
|
||||
lvcreate -n test -l1 -an vg0
|
||||
reads:
|
||||
- 400 for each PV
|
||||
- 40 for each LV
|
||||
- 10 for each PV in vg0 (rescan)
|
||||
- 8 for other devs on the system
|
||||
writes:
|
||||
- 10 for metadata on each PV in vg0
|
||||
- 10 for precommit on each PV in vg0
|
||||
- 10 for commit on each PV in vg0
|
||||
|
||||
|
||||
|
||||
With lvmetad
|
||||
------------
|
||||
|
||||
Command: pvs
|
||||
------------
|
||||
old: 0m5.405s
|
||||
new: 0m1.404s
|
||||
|
||||
Command: vgs
|
||||
------------
|
||||
old: 0m0.222s
|
||||
new: 0m0.223s
|
||||
|
||||
Command: lvcreate -n test -l1 -an vg0
|
||||
-------------------------------------
|
||||
old: 0m10.128s
|
||||
new: 0m1.137s
|
||||
|
||||
|
||||
|
@ -245,6 +245,9 @@
|
||||
/* Define to 1 if you have the <langinfo.h> header file. */
|
||||
#undef HAVE_LANGINFO_H
|
||||
|
||||
/* Define to 1 if you have the <libaio.h> header file. */
|
||||
#undef HAVE_LIBAIO_H
|
||||
|
||||
/* Define to 1 if you have the <libcman.h> header file. */
|
||||
#undef HAVE_LIBCMAN_H
|
||||
|
||||
|
68
lib/cache/lvmcache.c
vendored
68
lib/cache/lvmcache.c
vendored
@ -643,7 +643,6 @@ void lvmcache_unlock_vgname(const char *vgname)
|
||||
|
||||
/* FIXME Do this per-VG */
|
||||
if (strcmp(vgname, VG_GLOBAL) && !--_vgs_locked) {
|
||||
dev_close_all();
|
||||
dev_size_seqno_inc(); /* invalidate all cached dev sizes */
|
||||
}
|
||||
}
|
||||
@ -811,7 +810,7 @@ const struct format_type *lvmcache_fmt_from_vgname(struct cmd_context *cmd,
|
||||
|
||||
dm_list_iterate_safe(devh, tmp, &devs) {
|
||||
devl = dm_list_item(devh, struct device_list);
|
||||
label_read(devl->dev, NULL, UINT64_C(0));
|
||||
label_read(devl->dev);
|
||||
dm_list_del(&devl->list);
|
||||
dm_free(devl);
|
||||
}
|
||||
@ -977,6 +976,36 @@ int lvmcache_dev_is_unchosen_duplicate(struct device *dev)
|
||||
return _dev_in_device_list(dev, &_unused_duplicate_devs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Treat some duplicate devs as if they were filtered out by filters.
|
||||
* The actual filters are evaluated too early, before a complete
|
||||
* picture of all PVs is available, to eliminate these duplicates.
|
||||
*
|
||||
* By removing the filtered duplicates from unused_duplicate_devs, we remove
|
||||
* the restrictions that are placed on using duplicate devs or VGs with
|
||||
* duplicate devs.
|
||||
*
|
||||
* There may other kinds of duplicates that we want to ignore.
|
||||
*/
|
||||
|
||||
static void _filter_duplicate_devs(struct cmd_context *cmd)
|
||||
{
|
||||
struct dev_types *dt = cmd->dev_types;
|
||||
struct lvmcache_info *info;
|
||||
struct device_list *devl, *devl2;
|
||||
|
||||
dm_list_iterate_items_safe(devl, devl2, &_unused_duplicate_devs) {
|
||||
|
||||
info = lvmcache_info_from_pvid(devl->dev->pvid, NULL, 0);
|
||||
|
||||
if (MAJOR(info->dev->dev) == dt->md_major) {
|
||||
log_debug_devs("Ignoring md component duplicate %s", dev_name(devl->dev));
|
||||
dm_list_del(&devl->list);
|
||||
dm_free(devl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare _found_duplicate_devs entries with the corresponding duplicate dev
|
||||
* in lvmcache. There may be multiple duplicates in _found_duplicate_devs for
|
||||
@ -1279,9 +1308,9 @@ next:
|
||||
int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const char *vgid)
|
||||
{
|
||||
struct dm_list devs;
|
||||
struct device_list *devl;
|
||||
struct device_list *devl, *devl2;
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
struct lvmcache_info *info, *info2;
|
||||
struct lvmcache_info *info;
|
||||
|
||||
if (lvmetad_used())
|
||||
return 1;
|
||||
@ -1310,8 +1339,9 @@ int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const
|
||||
dm_list_add(&devs, &devl->list);
|
||||
}
|
||||
|
||||
dm_list_iterate_items_safe(info, info2, &vginfo->infos)
|
||||
lvmcache_del(info);
|
||||
/* Delete info for each dev, deleting the last info will delete vginfo. */
|
||||
dm_list_iterate_items(devl, &devs)
|
||||
lvmcache_del_dev(devl->dev);
|
||||
|
||||
/* Dropping the last info struct is supposed to drop vginfo. */
|
||||
if ((vginfo = lvmcache_vginfo_from_vgname(vgname, vgid)))
|
||||
@ -1322,6 +1352,11 @@ int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const
|
||||
|
||||
label_scan_devs(cmd, cmd->filter, &devs);
|
||||
|
||||
dm_list_iterate_items_safe(devl, devl2, &devs) {
|
||||
dm_list_del(&devl->list);
|
||||
dm_free(devl);
|
||||
}
|
||||
|
||||
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, vgid))) {
|
||||
log_warn("VG info not found after rescan of %s", vgname);
|
||||
return 0;
|
||||
@ -1439,10 +1474,17 @@ int lvmcache_label_scan(struct cmd_context *cmd)
|
||||
|
||||
dm_list_iterate_items(devl, &add_cache_devs) {
|
||||
log_debug_cache("Rescan preferred device %s for lvmcache", dev_name(devl->dev));
|
||||
label_read(devl->dev, NULL, UINT64_C(0));
|
||||
label_read(devl->dev);
|
||||
}
|
||||
|
||||
dm_list_splice(&_unused_duplicate_devs, &del_cache_devs);
|
||||
|
||||
/*
|
||||
* We might want to move the duplicate device warnings until
|
||||
* after this filtering so that we can skip warning about
|
||||
* duplicates that we are filtering out.
|
||||
*/
|
||||
_filter_duplicate_devs(cmd);
|
||||
}
|
||||
|
||||
/* Perform any format-specific scanning e.g. text files */
|
||||
@ -1630,7 +1672,7 @@ const char *lvmcache_pvid_from_devname(struct cmd_context *cmd,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(label_read(dev, NULL, UINT64_C(0))))
|
||||
if (!label_read(dev))
|
||||
return NULL;
|
||||
|
||||
return dev->pvid;
|
||||
@ -1714,6 +1756,7 @@ void lvmcache_del(struct lvmcache_info *info)
|
||||
|
||||
info->label->labeller->ops->destroy_label(info->label->labeller,
|
||||
info->label);
|
||||
label_destroy(info->label);
|
||||
dm_free(info);
|
||||
}
|
||||
|
||||
@ -2457,15 +2500,6 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
|
||||
}
|
||||
}
|
||||
|
||||
int lvmcache_pvid_is_locked(const char *pvid) {
|
||||
struct lvmcache_info *info;
|
||||
info = lvmcache_info_from_pvid(pvid, NULL, 0);
|
||||
if (!info || !info->vginfo)
|
||||
return 0;
|
||||
|
||||
return lvmcache_vgname_is_locked(info->vginfo->vgname);
|
||||
}
|
||||
|
||||
int lvmcache_fid_add_mdas(struct lvmcache_info *info, struct format_instance *fid,
|
||||
const char *id, int id_len)
|
||||
{
|
||||
|
1
lib/cache/lvmcache.h
vendored
1
lib/cache/lvmcache.h
vendored
@ -132,7 +132,6 @@ struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
|
||||
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted);
|
||||
void lvmcache_commit_metadata(const char *vgname);
|
||||
|
||||
int lvmcache_pvid_is_locked(const char *pvid);
|
||||
int lvmcache_fid_add_mdas(struct lvmcache_info *info, struct format_instance *fid,
|
||||
const char *id, int id_len);
|
||||
int lvmcache_fid_add_mdas_pv(struct lvmcache_info *info, struct format_instance *fid);
|
||||
|
@ -768,7 +768,7 @@ cfg(global_activation_CFG, "activation", global_CFG_SECTION, 0, CFG_TYPE_BOOL, D
|
||||
"the error messages.\n")
|
||||
|
||||
cfg(global_fallback_to_lvm1_CFG, "fallback_to_lvm1", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(1, 0, 18), NULL, 0, NULL,
|
||||
"This setting setting no longer used.\n")
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg(global_format_CFG, "format", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FORMAT, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"This setting is no longer used.\n")
|
||||
|
@ -15,7 +15,7 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "lib/device/bcache.h"
|
||||
#include "device_mapper/misc/dm-logging.h"
|
||||
#include "lib/log/lvm-logging.h"
|
||||
#include "lib/log/log.h"
|
||||
|
||||
#include <errno.h>
|
||||
@ -667,6 +667,7 @@ static void _issue_low_level(struct block *b, enum dir d)
|
||||
|
||||
b->io_dir = d;
|
||||
_set_flags(b, BF_IO_PENDING);
|
||||
cache->nr_io_pending++;
|
||||
|
||||
dm_list_move(&cache->io_pending, &b->list);
|
||||
|
||||
|
@ -73,7 +73,6 @@ static void _dev_init(struct device *dev, int max_error_count)
|
||||
dev->ext.src = DEV_EXT_NONE;
|
||||
|
||||
dm_list_init(&dev->aliases);
|
||||
dm_list_init(&dev->open_list);
|
||||
}
|
||||
|
||||
void dev_destroy_file(struct device *dev)
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "lib/misc/lib.h"
|
||||
#include "lib/device/device.h"
|
||||
#include "lib/metadata/metadata.h"
|
||||
#include "lib/cache/lvmcache.h"
|
||||
#include "lib/mm/memlock.h"
|
||||
#include "lib/locking/locking.h"
|
||||
|
||||
@ -53,7 +52,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static DM_LIST_INIT(_open_devices);
|
||||
static unsigned _dev_size_seqno = 1;
|
||||
|
||||
static const char *_reasons[] = {
|
||||
@ -199,7 +197,7 @@ int dev_get_block_size(struct device *dev, unsigned int *physical_block_size, un
|
||||
*physical_block_size = (unsigned int) dev->phys_block_size;
|
||||
*block_size = (unsigned int) dev->block_size;
|
||||
out:
|
||||
if (needs_open && !dev_close(dev))
|
||||
if (needs_open && !dev_close_immediate(dev))
|
||||
stack;
|
||||
|
||||
return r;
|
||||
@ -349,7 +347,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE64, size) < 0) {
|
||||
log_sys_error("ioctl BLKGETSIZE64", name);
|
||||
if (do_close && !dev_close(dev))
|
||||
if (do_close && !dev_close_immediate(dev))
|
||||
log_sys_error("close", name);
|
||||
return 0;
|
||||
}
|
||||
@ -360,7 +358,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
|
||||
|
||||
log_very_verbose("%s: size is %" PRIu64 " sectors", name, *size);
|
||||
|
||||
if (do_close && !dev_close(dev))
|
||||
if (do_close && !dev_close_immediate(dev))
|
||||
log_sys_error("close", name);
|
||||
|
||||
return 1;
|
||||
@ -380,7 +378,7 @@ static int _dev_read_ahead_dev(struct device *dev, uint32_t *read_ahead)
|
||||
|
||||
if (ioctl(dev->fd, BLKRAGET, &read_ahead_long) < 0) {
|
||||
log_sys_error("ioctl BLKRAGET", dev_name(dev));
|
||||
if (!dev_close(dev))
|
||||
if (!dev_close_immediate(dev))
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@ -391,7 +389,7 @@ static int _dev_read_ahead_dev(struct device *dev, uint32_t *read_ahead)
|
||||
log_very_verbose("%s: read_ahead is %u sectors",
|
||||
dev_name(dev), *read_ahead);
|
||||
|
||||
if (!dev_close(dev))
|
||||
if (!dev_close_immediate(dev))
|
||||
stack;
|
||||
|
||||
return 1;
|
||||
@ -412,13 +410,13 @@ static int _dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64
|
||||
if (ioctl(dev->fd, BLKDISCARD, &discard_range) < 0) {
|
||||
log_error("%s: BLKDISCARD ioctl at offset %" PRIu64 " size %" PRIu64 " failed: %s.",
|
||||
dev_name(dev), offset_bytes, size_bytes, strerror(errno));
|
||||
if (!dev_close(dev))
|
||||
if (!dev_close_immediate(dev))
|
||||
stack;
|
||||
/* It doesn't matter if discard failed, so return success. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!dev_close(dev))
|
||||
if (!dev_close_immediate(dev))
|
||||
stack;
|
||||
|
||||
return 1;
|
||||
@ -597,8 +595,6 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
if ((flags & O_CREAT) && !(flags & O_TRUNC))
|
||||
dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
|
||||
|
||||
dm_list_add(&_open_devices, &dev->open_list);
|
||||
|
||||
log_debug_devs("Opened %s %s%s%s", dev_name(dev),
|
||||
dev->flags & DEV_OPENED_RW ? "RW" : "RO",
|
||||
dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
|
||||
@ -650,7 +646,6 @@ static void _close(struct device *dev)
|
||||
dev->fd = -1;
|
||||
dev->phys_block_size = -1;
|
||||
dev->block_size = -1;
|
||||
dm_list_del(&dev->open_list);
|
||||
|
||||
log_debug_devs("Closed %s", dev_name(dev));
|
||||
|
||||
@ -678,9 +673,7 @@ static int _dev_close(struct device *dev, int immediate)
|
||||
log_debug_devs("%s: Immediate close attempt while still referenced",
|
||||
dev_name(dev));
|
||||
|
||||
/* Close unless device is known to belong to a locked VG */
|
||||
if (immediate ||
|
||||
(dev->open_count < 1 && !lvmcache_pvid_is_locked(dev->pvid)))
|
||||
if (immediate || (dev->open_count < 1))
|
||||
_close(dev);
|
||||
|
||||
return 1;
|
||||
@ -696,18 +689,6 @@ int dev_close_immediate(struct device *dev)
|
||||
return _dev_close(dev, 1);
|
||||
}
|
||||
|
||||
void dev_close_all(void)
|
||||
{
|
||||
struct dm_list *doh, *doht;
|
||||
struct device *dev;
|
||||
|
||||
dm_list_iterate_safe(doh, doht, &_open_devices) {
|
||||
dev = dm_list_struct_base(doh, struct device, open_list);
|
||||
if (dev->open_count < 1)
|
||||
_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int _dev_is_valid(struct device *dev)
|
||||
{
|
||||
return (dev->max_error_count == NO_DEV_ERROR_COUNT_LIMIT ||
|
||||
|
@ -134,8 +134,7 @@ static int _native_dev_is_md(struct device *dev, uint64_t *offset_found, int ful
|
||||
* Those checks can't be satisfied with the initial bcache data, and
|
||||
* would require an extra read i/o at the end of every device. Issuing
|
||||
* an extra read to every device in every command, just to check for
|
||||
* the old md format is a bad tradeoff. It's also not a big issue if
|
||||
* one happens to exist and we don't filter it out.
|
||||
* the old md format is a bad tradeoff.
|
||||
*
|
||||
* When "full" is set, we check a the start and end of the device for
|
||||
* md magic numbers. When "full" is not set, we only check at the
|
||||
@ -143,6 +142,13 @@ static int _native_dev_is_md(struct device *dev, uint64_t *offset_found, int ful
|
||||
* command if it should do a full check (cmd->use_full_md_check),
|
||||
* and set it for commands that could possibly write to an md dev
|
||||
* (pvcreate/vgcreate/vgextend).
|
||||
*
|
||||
* For old md versions with magic numbers at the end of devices,
|
||||
* the md dev components won't be filtered out here when full is 0,
|
||||
* so they will be scanned, and appear as duplicate PVs in lvmcache.
|
||||
* The md device itself will be chosen as the primary duplicate,
|
||||
* and the components are dropped from the list of duplicates in,
|
||||
* i.e. a kind of post-scan filtering.
|
||||
*/
|
||||
if (!full) {
|
||||
sb_offset = 0;
|
||||
|
@ -215,6 +215,9 @@ int dev_subsystem_part_major(struct dev_types *dt, struct device *dev)
|
||||
if (MAJOR(dev->dev) == dt->device_mapper_major)
|
||||
return 1;
|
||||
|
||||
if (MAJOR(dev->dev) == dt->md_major)
|
||||
return 1;
|
||||
|
||||
if (MAJOR(dev->dev) == dt->drbd_major)
|
||||
return 1;
|
||||
|
||||
|
@ -74,7 +74,6 @@ struct device {
|
||||
unsigned size_seqno;
|
||||
uint64_t size;
|
||||
uint64_t end;
|
||||
struct dm_list open_list;
|
||||
struct dev_ext ext;
|
||||
|
||||
const char *vgid; /* if device is an LV */
|
||||
@ -144,7 +143,6 @@ int dev_open_readonly_buffered(struct device *dev);
|
||||
int dev_open_readonly_quiet(struct device *dev);
|
||||
int dev_close(struct device *dev);
|
||||
int dev_close_immediate(struct device *dev);
|
||||
void dev_close_all(void);
|
||||
int dev_test_excl(struct device *dev);
|
||||
|
||||
int dev_fd(struct device *dev);
|
||||
|
@ -251,9 +251,11 @@ static bool _in_bcache(struct device *dev)
|
||||
|
||||
static struct labeller *_find_lvm_header(struct device *dev,
|
||||
char *scan_buf,
|
||||
uint32_t scan_buf_sectors,
|
||||
char *label_buf,
|
||||
uint64_t *label_sector,
|
||||
uint64_t scan_sector)
|
||||
uint64_t block_sector,
|
||||
uint64_t start_sector)
|
||||
{
|
||||
struct labeller_i *li;
|
||||
struct labeller *labeller_ret = NULL;
|
||||
@ -266,25 +268,34 @@ static struct labeller *_find_lvm_header(struct device *dev,
|
||||
* and copy it into label_buf.
|
||||
*/
|
||||
|
||||
for (sector = 0; sector < LABEL_SCAN_SECTORS;
|
||||
for (sector = start_sector; sector < start_sector + LABEL_SCAN_SECTORS;
|
||||
sector += LABEL_SIZE >> SECTOR_SHIFT) {
|
||||
|
||||
/*
|
||||
* The scan_buf passed in is a bcache block, which is
|
||||
* BCACHE_BLOCK_SIZE_IN_SECTORS large. So if start_sector is
|
||||
* one of the last couple sectors in that buffer, we need to
|
||||
* break early.
|
||||
*/
|
||||
if (sector >= scan_buf_sectors)
|
||||
break;
|
||||
|
||||
lh = (struct label_header *) (scan_buf + (sector << SECTOR_SHIFT));
|
||||
|
||||
if (!strncmp((char *)lh->id, LABEL_ID, sizeof(lh->id))) {
|
||||
if (found) {
|
||||
log_error("Ignoring additional label on %s at sector %llu",
|
||||
dev_name(dev), (unsigned long long)(sector + scan_sector));
|
||||
dev_name(dev), (unsigned long long)(block_sector + sector));
|
||||
}
|
||||
if (xlate64(lh->sector_xl) != sector + scan_sector) {
|
||||
log_very_verbose("%s: Label for sector %llu found at sector %llu - ignoring.",
|
||||
dev_name(dev),
|
||||
(unsigned long long)xlate64(lh->sector_xl),
|
||||
(unsigned long long)(sector + scan_sector));
|
||||
if (xlate64(lh->sector_xl) != sector) {
|
||||
log_warn("%s: Label for sector %llu found at sector %llu - ignoring.",
|
||||
dev_name(dev),
|
||||
(unsigned long long)xlate64(lh->sector_xl),
|
||||
(unsigned long long)(block_sector + sector));
|
||||
continue;
|
||||
}
|
||||
if (calc_crc(INITIAL_CRC, (uint8_t *)&lh->offset_xl, LABEL_SIZE -
|
||||
((uint8_t *) &lh->offset_xl - (uint8_t *) lh)) !=
|
||||
xlate32(lh->crc_xl)) {
|
||||
if (calc_crc(INITIAL_CRC, (uint8_t *)&lh->offset_xl,
|
||||
LABEL_SIZE - ((uint8_t *) &lh->offset_xl - (uint8_t *) lh)) != xlate32(lh->crc_xl)) {
|
||||
log_very_verbose("Label checksum incorrect on %s - ignoring", dev_name(dev));
|
||||
continue;
|
||||
}
|
||||
@ -293,14 +304,14 @@ static struct labeller *_find_lvm_header(struct device *dev,
|
||||
}
|
||||
|
||||
dm_list_iterate_items(li, &_labellers) {
|
||||
if (li->l->ops->can_handle(li->l, (char *) lh, sector + scan_sector)) {
|
||||
if (li->l->ops->can_handle(li->l, (char *) lh, block_sector + sector)) {
|
||||
log_very_verbose("%s: %s label detected at sector %llu",
|
||||
dev_name(dev), li->name,
|
||||
(unsigned long long)(sector + scan_sector));
|
||||
(unsigned long long)(block_sector + sector));
|
||||
if (found) {
|
||||
log_error("Ignoring additional label on %s at sector %llu",
|
||||
dev_name(dev),
|
||||
(unsigned long long)(sector + scan_sector));
|
||||
(unsigned long long)(block_sector + sector));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -309,7 +320,7 @@ static struct labeller *_find_lvm_header(struct device *dev,
|
||||
|
||||
memcpy(label_buf, lh, LABEL_SIZE);
|
||||
if (label_sector)
|
||||
*label_sector = sector + scan_sector;
|
||||
*label_sector = block_sector + sector;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -329,7 +340,9 @@ static struct labeller *_find_lvm_header(struct device *dev,
|
||||
* are performed in the processing functions to get that data.
|
||||
*/
|
||||
static int _process_block(struct cmd_context *cmd, struct dev_filter *f,
|
||||
struct device *dev, struct block *bb, int *is_lvm_device)
|
||||
struct device *dev, struct block *bb,
|
||||
uint64_t block_sector, uint64_t start_sector,
|
||||
int *is_lvm_device)
|
||||
{
|
||||
char label_buf[LABEL_SIZE] __attribute__((aligned(8)));
|
||||
struct label *label = NULL;
|
||||
@ -345,7 +358,7 @@ static int _process_block(struct cmd_context *cmd, struct dev_filter *f,
|
||||
* data had been read (here). They set this flag to indicate that the
|
||||
* filters should be retested now that data from the device is ready.
|
||||
*/
|
||||
if (cmd && (dev->flags & DEV_FILTER_AFTER_SCAN)) {
|
||||
if (f && (dev->flags & DEV_FILTER_AFTER_SCAN)) {
|
||||
dev->flags &= ~DEV_FILTER_AFTER_SCAN;
|
||||
|
||||
log_debug_devs("Scan filtering %s", dev_name(dev));
|
||||
@ -374,7 +387,7 @@ static int _process_block(struct cmd_context *cmd, struct dev_filter *f,
|
||||
* FIXME: we don't need to copy one sector from bb->data into label_buf,
|
||||
* we can just point label_buf at one sector in ld->buf.
|
||||
*/
|
||||
if (!(labeller = _find_lvm_header(dev, bb->data, label_buf, §or, 0))) {
|
||||
if (!(labeller = _find_lvm_header(dev, bb->data, BCACHE_BLOCK_SIZE_IN_SECTORS, label_buf, §or, block_sector, start_sector))) {
|
||||
|
||||
/*
|
||||
* Non-PVs exit here
|
||||
@ -567,7 +580,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||
} else {
|
||||
log_debug_devs("Processing data from device %s fd %d block %p", dev_name(devl->dev), devl->dev->bcache_fd, bb);
|
||||
|
||||
ret = _process_block(cmd, f, devl->dev, bb, &is_lvm_device);
|
||||
ret = _process_block(cmd, f, devl->dev, bb, 0, 0, &is_lvm_device);
|
||||
|
||||
if (!ret && is_lvm_device) {
|
||||
log_debug_devs("Scan failed to process %s", dev_name(devl->dev));
|
||||
@ -610,32 +623,46 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* How many blocks to set up in bcache? Is 1024 a good max?
|
||||
*
|
||||
* Currently, we tell bcache to set up N blocks where N
|
||||
* is the number of devices that are going to be scanned.
|
||||
* Reasons why this number may not be be a good choice:
|
||||
*
|
||||
* - there may be a lot of non-lvm devices, which
|
||||
* would make this number larger than necessary
|
||||
*
|
||||
* - each lvm device may use more than one cache
|
||||
* block if the metadata is large enough or it
|
||||
* uses more than one metadata area, which
|
||||
* would make this number smaller than it
|
||||
* should be for the best performance.
|
||||
*
|
||||
* This is even more tricky to estimate when lvmetad
|
||||
* is used, because it's hard to predict how many
|
||||
* devs might need to be scanned when using lvmetad.
|
||||
* This currently just sets up bcache with MIN blocks.
|
||||
*/
|
||||
|
||||
#define MIN_BCACHE_BLOCKS 32
|
||||
#define MAX_BCACHE_BLOCKS 1024
|
||||
|
||||
static int _setup_bcache(int cache_blocks)
|
||||
{
|
||||
struct io_engine *ioe;
|
||||
|
||||
/* No devices can happen, just create bcache with any small number. */
|
||||
if (cache_blocks < MIN_BCACHE_BLOCKS)
|
||||
cache_blocks = MIN_BCACHE_BLOCKS;
|
||||
|
||||
/*
|
||||
* 100 is arbitrary, it's the max number of concurrent aio's
|
||||
* possible, i.e, the number of devices that can be read at
|
||||
* once. Should this be configurable?
|
||||
*/
|
||||
if (cache_blocks > MAX_BCACHE_BLOCKS)
|
||||
cache_blocks = MAX_BCACHE_BLOCKS;
|
||||
|
||||
if (!(ioe = create_async_io_engine())) {
|
||||
log_error("Failed to create bcache io engine.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure one cache block for each device on the system.
|
||||
* We won't generally need to cache that many because some
|
||||
* of the devs will not be lvm devices, and we don't need
|
||||
* an entry for those. We might want to change this.
|
||||
*/
|
||||
if (!(scan_bcache = bcache_create(BCACHE_BLOCK_SIZE_IN_SECTORS, cache_blocks, ioe))) {
|
||||
log_error("Failed to create bcache with %d cache blocks.", cache_blocks);
|
||||
return 0;
|
||||
@ -653,7 +680,7 @@ int label_scan(struct cmd_context *cmd)
|
||||
{
|
||||
struct dm_list all_devs;
|
||||
struct dev_iter *iter;
|
||||
struct device_list *devl;
|
||||
struct device_list *devl, *devl2;
|
||||
struct device *dev;
|
||||
|
||||
log_debug_devs("Finding devices to scan");
|
||||
@ -695,16 +722,17 @@ int label_scan(struct cmd_context *cmd)
|
||||
log_debug_devs("Found %d devices to scan", dm_list_size(&all_devs));
|
||||
|
||||
if (!scan_bcache) {
|
||||
/*
|
||||
* FIXME: there should probably be some max number of
|
||||
* cache blocks we use when setting up bcache.
|
||||
*/
|
||||
if (!_setup_bcache(dm_list_size(&all_devs)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
_scan_list(cmd, cmd->full_filter, &all_devs, NULL);
|
||||
|
||||
dm_list_iterate_items_safe(devl, devl2, &all_devs) {
|
||||
dm_list_del(&devl->list);
|
||||
dm_free(devl);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -834,9 +862,7 @@ void label_scan_destroy(struct cmd_context *cmd)
|
||||
* device, this is not a commonly used function.
|
||||
*/
|
||||
|
||||
/* FIXME: remove unused_sector arg */
|
||||
|
||||
int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector)
|
||||
int label_read(struct device *dev)
|
||||
{
|
||||
struct dm_list one_dev;
|
||||
struct device_list *devl;
|
||||
@ -856,17 +882,7 @@ int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector
|
||||
|
||||
_scan_list(NULL, NULL, &one_dev, &failed);
|
||||
|
||||
/*
|
||||
* FIXME: this ugliness of returning a pointer to the label is
|
||||
* temporary until the callers can be updated to not use this.
|
||||
*/
|
||||
if (labelp) {
|
||||
struct lvmcache_info *info;
|
||||
|
||||
info = lvmcache_info_from_pvid(dev->pvid, dev, 1);
|
||||
if (info)
|
||||
*labelp = lvmcache_get_label(info);
|
||||
}
|
||||
dm_free(devl);
|
||||
|
||||
if (failed)
|
||||
return 0;
|
||||
@ -875,25 +891,66 @@ int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector
|
||||
|
||||
/*
|
||||
* Read a label from a specfic, non-zero sector. This is used in only
|
||||
* one place: pvck -> pv_analyze.
|
||||
* one place: pvck/pv_analyze.
|
||||
*/
|
||||
|
||||
int label_read_sector(struct device *dev, struct label **labelp, uint64_t scan_sector)
|
||||
int label_read_sector(struct device *dev, uint64_t read_sector)
|
||||
{
|
||||
if (scan_sector) {
|
||||
/* TODO: not yet implemented */
|
||||
/* When is this done? When does it make sense? Is it actually possible? */
|
||||
return 0;
|
||||
struct block *bb = NULL;
|
||||
uint64_t block_num;
|
||||
uint64_t block_sector;
|
||||
uint64_t start_sector;
|
||||
int is_lvm_device = 0;
|
||||
int result;
|
||||
int ret;
|
||||
|
||||
block_num = read_sector / BCACHE_BLOCK_SIZE_IN_SECTORS;
|
||||
block_sector = block_num * BCACHE_BLOCK_SIZE_IN_SECTORS;
|
||||
start_sector = read_sector % BCACHE_BLOCK_SIZE_IN_SECTORS;
|
||||
|
||||
label_scan_open(dev);
|
||||
|
||||
bcache_prefetch(scan_bcache, dev->bcache_fd, block_num);
|
||||
|
||||
if (!bcache_get(scan_bcache, dev->bcache_fd, block_num, 0, &bb)) {
|
||||
log_error("Scan failed to read %s at %llu",
|
||||
dev_name(dev), (unsigned long long)block_num);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return label_read(dev, labelp, 0);
|
||||
/*
|
||||
* TODO: check if scan_sector is larger than the bcache block size.
|
||||
* If it is, we need to fetch a later block from bcache.
|
||||
*/
|
||||
|
||||
result = _process_block(NULL, NULL, dev, bb, block_sector, start_sector, &is_lvm_device);
|
||||
|
||||
if (!result && is_lvm_device) {
|
||||
log_error("Scan failed to process %s", dev_name(dev));
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!result || !is_lvm_device) {
|
||||
log_error("Could not find LVM label on %s", dev_name(dev));
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
out:
|
||||
if (bb)
|
||||
bcache_put(bb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only needed when commands are using lvmetad, in which case they
|
||||
* don't do an initial label_scan, but may later need to rescan certain devs
|
||||
* from disk and call this function. FIXME: is there some better number to
|
||||
* choose here?
|
||||
* choose here? How should we predict the number of devices that might need
|
||||
* scanning when using lvmetad?
|
||||
*/
|
||||
|
||||
int label_scan_setup_bcache(void)
|
||||
@ -922,18 +979,10 @@ int label_scan_open(struct device *dev)
|
||||
|
||||
bool dev_read_bytes(struct device *dev, uint64_t start, size_t len, void *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!scan_bcache) {
|
||||
if (!dev_open_readonly(dev))
|
||||
return false;
|
||||
|
||||
ret = dev_read(dev, start, len, 0, data);
|
||||
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
return ret ? true : false;
|
||||
/* Should not happen */
|
||||
log_error("dev_read bcache not set up %s", dev_name(dev));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dev->bcache_fd <= 0) {
|
||||
@ -956,21 +1005,13 @@ bool dev_read_bytes(struct device *dev, uint64_t start, size_t len, void *data)
|
||||
|
||||
bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (test_mode())
|
||||
return true;
|
||||
|
||||
if (!scan_bcache) {
|
||||
if (!dev_open(dev))
|
||||
return false;
|
||||
|
||||
ret = dev_write(dev, start, len, 0, data);
|
||||
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
return ret ? true : false;
|
||||
/* Should not happen */
|
||||
log_error("dev_write bcache not set up %s", dev_name(dev));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dev->bcache_fd <= 0) {
|
||||
@ -1003,7 +1044,7 @@ bool dev_write_zeros(struct device *dev, uint64_t start, size_t len)
|
||||
return true;
|
||||
|
||||
if (!scan_bcache) {
|
||||
log_error("dev_write_zeros %s bcache not set up", dev_name(dev));
|
||||
log_error("dev_write_zeros bcache not set up %s", dev_name(dev));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1037,7 +1078,7 @@ bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val)
|
||||
return true;
|
||||
|
||||
if (!scan_bcache) {
|
||||
log_error("dev_set_bytes %s bcache not set up", dev_name(dev));
|
||||
log_error("dev_set_bytes bcache not set up %s", dev_name(dev));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -109,8 +109,8 @@ void label_scan_invalidate(struct device *dev);
|
||||
void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv);
|
||||
void label_scan_drop(struct cmd_context *cmd);
|
||||
void label_scan_destroy(struct cmd_context *cmd);
|
||||
int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector);
|
||||
int label_read_sector(struct device *dev, struct label **labelp, uint64_t scan_sector);
|
||||
int label_read(struct device *dev);
|
||||
int label_read_sector(struct device *dev, uint64_t scan_sector);
|
||||
void label_scan_confirm(struct device *dev);
|
||||
int label_scan_setup_bcache(void);
|
||||
int label_scan_open(struct device *dev);
|
||||
|
@ -483,7 +483,6 @@ static int _pvremove_check(struct cmd_context *cmd, const char *name,
|
||||
{
|
||||
static const char really_wipe_msg[] = "Really WIPE LABELS from physical volume";
|
||||
struct device *dev;
|
||||
struct label *label;
|
||||
struct pv_list *pvl;
|
||||
struct physical_volume *pv = NULL;
|
||||
int used;
|
||||
@ -498,7 +497,7 @@ static int _pvremove_check(struct cmd_context *cmd, const char *name,
|
||||
|
||||
/* Is there a pv here already? */
|
||||
/* If not, this is an error unless you used -f. */
|
||||
if (!label_read(dev, &label, 0)) {
|
||||
if (!label_read(dev)) {
|
||||
if (force_count)
|
||||
return 1;
|
||||
log_error("No PV label found on %s.", name);
|
||||
|
@ -4058,7 +4058,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
release_vg(correct_vg);
|
||||
correct_vg = NULL;
|
||||
lvmcache_del(info);
|
||||
label_read(pvl->pv->dev, NULL, 0);
|
||||
label_read(pvl->pv->dev);
|
||||
goto restart_scan;
|
||||
}
|
||||
#endif
|
||||
@ -5192,8 +5192,6 @@ static struct volume_group *_recover_vg(struct cmd_context *cmd,
|
||||
|
||||
unlock_vg(cmd, NULL, vg_name);
|
||||
|
||||
dev_close_all();
|
||||
|
||||
if (!lock_vol(cmd, vg_name, LCK_VG_WRITE, NULL))
|
||||
return_NULL;
|
||||
|
||||
|
@ -78,7 +78,6 @@ int exec_cmd(struct cmd_context *cmd, const char *const argv[],
|
||||
if (!pid) {
|
||||
/* Child */
|
||||
reset_locking();
|
||||
dev_close_all();
|
||||
/* FIXME Fix effect of reset_locking on cache then include this */
|
||||
/* destroy_toolcontext(cmd); */
|
||||
/* FIXME Use execve directly */
|
||||
|
@ -186,6 +186,8 @@ int lvm_vg_close(vg_t vg)
|
||||
struct saved_env e = store_user_env(vg->cmd);
|
||||
if (vg_read_error(vg) == FAILED_LOCKING)
|
||||
release_vg(vg);
|
||||
else if (!lvmcache_vgname_is_locked(vg->name))
|
||||
release_vg(vg);
|
||||
else
|
||||
unlock_and_release_vg(vg->cmd, vg, vg->name);
|
||||
restore_user_env(&e);
|
||||
|
@ -503,7 +503,7 @@ Merge LV images that were split from a raid1 LV.
|
||||
Convert LV to a thin LV, using the original LV as an external origin.
|
||||
.br
|
||||
.P
|
||||
\fBlvconvert\fP \fB--type\fP \fBthin\fP \fB--thinpool\fP \fILV\fP \fILV\fP\fI_linear_striped_cache_raid\fP
|
||||
\fBlvconvert\fP \fB--type\fP \fBthin\fP \fB--thinpool\fP \fILV\fP \fILV\fP\fI_linear_striped_thin_cache_raid\fP
|
||||
.br
|
||||
.RS 4
|
||||
.ad l
|
||||
@ -1530,7 +1530,7 @@ Convert LV to a thin LV, using the original LV as an external origin
|
||||
(infers --type thin).
|
||||
.br
|
||||
.P
|
||||
\fBlvconvert\fP \fB-T\fP|\fB--thin\fP \fB--thinpool\fP \fILV\fP \fILV\fP\fI_linear_striped_cache_raid\fP
|
||||
\fBlvconvert\fP \fB-T\fP|\fB--thin\fP \fB--thinpool\fP \fILV\fP \fILV\fP\fI_linear_striped_thin_cache_raid\fP
|
||||
.br
|
||||
.RS 4
|
||||
.ad l
|
||||
@ -1714,7 +1714,9 @@ origin LV (first arg) to reverse a splitsnapshot command.
|
||||
.br
|
||||
-
|
||||
|
||||
Poll LV to continue conversion (also see --startpoll).
|
||||
Poll LV to continue conversion (also see --startpoll)
|
||||
.br
|
||||
or waits till conversion/mirror syncing is finished
|
||||
.br
|
||||
.P
|
||||
\fBlvconvert\fP \fILV\fP\fI_mirror_raid\fP
|
||||
|
@ -38,7 +38,7 @@ normally prevent it, e.g. if the PV is already in a VG.
|
||||
.ad b
|
||||
.br
|
||||
.ad l
|
||||
[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP ]
|
||||
[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ]
|
||||
.ad b
|
||||
.br
|
||||
.ad l
|
||||
@ -266,12 +266,11 @@ The size may be rounded.
|
||||
.ad b
|
||||
.HP
|
||||
.ad l
|
||||
\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP
|
||||
\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP
|
||||
.br
|
||||
Specifies the type of on-disk metadata to use.
|
||||
\fBlvm2\fP (or just \fB2\fP) is the current, standard format.
|
||||
\fBlvm1\fP (or just \fB1\fP) is a historical format that
|
||||
can be used for accessing old data.
|
||||
\fBlvm1\fP (or just \fB1\fP) is no longer used.
|
||||
.ad b
|
||||
.HP
|
||||
.ad l
|
||||
|
@ -51,7 +51,7 @@ vgcfgrestore - Restore volume group configuration
|
||||
.ad b
|
||||
.br
|
||||
.ad l
|
||||
\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP
|
||||
\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP
|
||||
.ad b
|
||||
.br
|
||||
.ad l
|
||||
@ -141,7 +141,7 @@ Common options for command:
|
||||
.
|
||||
.RS 4
|
||||
.ad l
|
||||
[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP ]
|
||||
[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ]
|
||||
.ad b
|
||||
.br
|
||||
.ad l
|
||||
@ -280,12 +280,11 @@ Display long help text.
|
||||
.ad b
|
||||
.HP
|
||||
.ad l
|
||||
\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP
|
||||
\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP
|
||||
.br
|
||||
Specifies the type of on-disk metadata to use.
|
||||
\fBlvm2\fP (or just \fB2\fP) is the current, standard format.
|
||||
\fBlvm1\fP (or just \fB1\fP) is a historical format that
|
||||
can be used for accessing old data.
|
||||
\fBlvm1\fP (or just \fB1\fP) is no longer used.
|
||||
.ad b
|
||||
.HP
|
||||
.ad l
|
||||
|
@ -8,12 +8,9 @@ vgconvert - Change volume group metadata format
|
||||
[ \fIoption_args\fP ]
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
vgconvert converts VG metadata from one format to another. The new
|
||||
metadata format must be able to fit into the space provided by the old
|
||||
vgconvert converts VG metadata from one format to another. This command
|
||||
is no longer used because this version of lvm no longer supports the LVM1
|
||||
format.
|
||||
|
||||
Because the LVM1 format should no longer be used, this command is no
|
||||