diff --git a/srcpkgs/accountsservice/template b/srcpkgs/accountsservice/template index f78c90865d9..ceceb35ede4 100644 --- a/srcpkgs/accountsservice/template +++ b/srcpkgs/accountsservice/template @@ -1,6 +1,6 @@ # Template file for 'accountsservice' pkgname=accountsservice -version=0.6.32 +version=0.6.34 revision=1 build_style=gnu-configure configure_args="--disable-static @@ -12,7 +12,7 @@ maintainer="Juan RP " homepage="http://cgit.freedesktop.org/accountsservice/" license="GPL-3" distfiles="http://www.freedesktop.org/software/$pkgname/$pkgname-$version.tar.xz" -checksum=6c03bc431ac9af4ac68c531a35fc97be0a410db65bf3ff24648760a0ddc28526 +checksum=15672a6e87a218e2a2c09947e340cc6617cd5ccb201da6885c409c16362d6b14 long_desc=" The accountsservice project provides a set of D-Bus interfaces for querying and manipulating user account information and an implementation @@ -24,6 +24,7 @@ accountsservice-devel_package() { pkg_install() { vmove usr/include vmove usr/lib/pkgconfig + vmove "usr/lib/*.so" vmove usr/share/gir-1.0 vmove usr/share/gtk-doc } diff --git a/srcpkgs/alsa-lib/template b/srcpkgs/alsa-lib/template index efc4aab020f..09dc2017861 100644 --- a/srcpkgs/alsa-lib/template +++ b/srcpkgs/alsa-lib/template @@ -1,6 +1,6 @@ # Template build file for 'alsa-lib'. pkgname=alsa-lib -version=1.0.27.1 +version=1.0.27.2 revision=1 build_style=gnu-configure hostmakedepends="pkg-config" @@ -10,7 +10,7 @@ maintainer="Juan RP " license="LGPL-2.1" homepage="http://www.alsa-project.org" distfiles="ftp://ftp.alsa-project.org/pub/lib/$pkgname-$version.tar.bz2" -checksum=690e07a3ef6270d40ed2130638dba3c18395aae8db4a109bcc473643ce29a03b +checksum=690ed393e7efd4fc7e3a2d2cda5449298ca0c895197e5914e350882012430d19 long_desc=" The Advanced Linux Sound Architecture (ALSA) provides audio and MIDI functionality to the Linux operating system. diff --git a/srcpkgs/base-system-live/template b/srcpkgs/base-system-live/template index 99f219455c6..4c7c4fab340 100644 --- a/srcpkgs/base-system-live/template +++ b/srcpkgs/base-system-live/template @@ -1,6 +1,6 @@ # Template file for 'base-system-live' pkgname=base-system-live -version=0.28 +version=0.29 revision=1 build_style=meta-template short_desc="Void Linux live base system meta package" @@ -18,7 +18,8 @@ _makedepends="base-files ncurses coreutils findutils diffutils dash bash grep texinfo file sed gawk less util-linux which tar man-db shadow e2fsprogs btrfs-progs xfsprogs f2fs-tools kbd psmisc procps-ng sudo tzdata dhcpcd wpa_supplicant kmod iproute2 iana-etc systemd xbps nvi dosfstools - parted dialog iw wifi-firmware linux-firmware-network dracut-network" + parted dialog iw wifi-firmware linux-firmware-network dracut-network + pciutils" base-system-live_package() { noarch="yes" diff --git a/srcpkgs/base-system/template b/srcpkgs/base-system/template index 8329782f827..24a4b0609dc 100644 --- a/srcpkgs/base-system/template +++ b/srcpkgs/base-system/template @@ -1,6 +1,6 @@ # Template file for 'base-system' pkgname=base-system -version=0.73 +version=0.74 revision=1 build_style=meta-template homepage="https://www.voidlinux.eu/" @@ -8,6 +8,9 @@ short_desc="Void Linux base system meta package" maintainer="Juan RP " license="Public domain" +# XXX merge this with base-system-rpi +only_for_archs="i686 x86_64" + # XXX can't currently use makedepends here: # # 1- conflicts with chroot-* pkgs @@ -15,7 +18,7 @@ license="Public domain" # _depends="base-files>=0.77 ncurses coreutils findutils diffutils dash bash grep texinfo file sed gawk less util-linux which tar man-pages man-db shadow - e2fsprogs btrfs-progs xfsprogs kbd psmisc procps-ng sudo tzdata + e2fsprogs btrfs-progs xfsprogs kbd psmisc procps-ng sudo tzdata pciutils iana-etc systemd cron-daemon openssh>=6.1p1 dhcpcd iproute2 iputils bridge-utils ifenslave iw wpa_supplicant xbps netbsd-wtf nvi wifi-firmware linux void-artwork nss-mdns traceroute ethtool" diff --git a/srcpkgs/chroot-gcc/template b/srcpkgs/chroot-gcc/template index ebadefc1eb5..bb3b04855cf 100644 --- a/srcpkgs/chroot-gcc/template +++ b/srcpkgs/chroot-gcc/template @@ -7,7 +7,7 @@ _mpc_ver=0.8.2 pkgname=chroot-gcc version=${_majorver}.3 -revision=2 +revision=3 wrksrc="gcc-${version}" homepage="http://gcc.gnu.org" short_desc="The GNU C Compiler suite -- for xbps-src use" @@ -110,7 +110,9 @@ do_configure() { fi if [ "$XBPS_TARGET_MACHINE" = "armv6l" ]; then - _floatabi="--with-float=hard" + _args+=" --with-arch=armv6 --with-fpu=vfp --with-float=hard" + elif [ "$XBPS_TARGET_MACHINE" = "armv7l" ]; then + _args+=" --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard" fi if [ "$CROSS_BUILD" ]; then @@ -147,7 +149,7 @@ do_configure() { --without-cloog --without-ppl --disable-libstdcxx-pch \ --disable-libquadmath --disable-libquadmath-support \ --disable-libgomp --disable-libssp --disable-libitm \ - ${_args} ${_floatabi} + ${_args} } do_build() { diff --git a/srcpkgs/cross-arm-linux-gnueabihf/template b/srcpkgs/cross-arm-linux-gnueabihf/template index e84b5312565..7f2b7364b51 100644 --- a/srcpkgs/cross-arm-linux-gnueabihf/template +++ b/srcpkgs/cross-arm-linux-gnueabihf/template @@ -9,11 +9,11 @@ _mpc_version=0.9 _linux_version=3.7.1 _triplet=arm-linux-gnueabihf -_fpuflags="--with-float=hard" +_fpuflags="--with-arch=armv6 --with-fpu=vfp --with-float=hard" _archflags="-march=armv6 -mfpu=vfp -mfloat-abi=hard" pkgname=cross-${_triplet} -version=0.11 +version=0.12 revision=1 short_desc="GNU Cross toolchain for the ${_triplet} LE target (binutils/gcc/glibc)" maintainer="pancake " @@ -39,6 +39,7 @@ checksum=" create_wrksrc=yes disable_debug=yes makedepends="perl flex" +only_for_archs="i686 x86_64" _CROSS_TARGET=${_triplet} _CROSS_SYSROOT="/usr/${_CROSS_TARGET}" @@ -291,7 +292,7 @@ do_clean() { # Packages cross-arm-linux-gnueabihf-libc_package() { - short_desc+=" -- glibc files" + short_desc+=" - glibc files" noarch=yes nostrip=yes noverifyrdeps=yes @@ -308,6 +309,6 @@ cross-arm-linux-gnueabihf_package() { depends="${pkgname}-libc-${version}_${revision}" nostrip_files="libgcc.a libgcov.a libgcc_eh.a" pkg_install() { - vmove usr + vmove all } } diff --git a/srcpkgs/dmd/template b/srcpkgs/dmd/template index 04601b0c69a..d41f07128ff 100644 --- a/srcpkgs/dmd/template +++ b/srcpkgs/dmd/template @@ -1,14 +1,14 @@ # Template file for 'dmd' pkgname=dmd -version=2.061 -revision=3 +version=2.062 +revision=1 wrksrc="dmd2" short_desc="The Digital Mars D compiler" maintainer="Juan RP " homepage="http://www.digitalmars.com/d/2.0/" license="GPL-2" distfiles="http://ftp.digitalmars.com/dmd.${version}.zip" -checksum="13b546b69d628280f245ab19bf4ed27ab66a0085afdaf950e075e68acc7f4c93" +checksum="43249dd1f5ca111006b6a5b7125f8e9326badadb6d9db2105ba93569addc50af" if [ "$XBPS_TARGET_MACHINE" = "x86_64" ]; then _archbits=64 @@ -16,8 +16,7 @@ elif [ "$XBPS_TARGET_MACHINE" = "i686" ]; then _archbits=32 fi -disable_debug=yes -makedepends="unzip" +hostmakedepends="unzip" do_build() { cd src @@ -54,27 +53,26 @@ libphobos_package() { short_desc="The phobos D standard library for DMD" license="Boost License" pkg_install() { - vinstall src/druntime/lib/libdruntime-linux${_archbits}.a 644 usr/lib libdruntime.a - vinstall src/phobos/generated/linux/release/$_archbits/libphobos2.a 644 usr/lib libphobos2.a + vinstall ${wrksrc}/src/druntime/lib/libdruntime-linux${_archbits}.a 644 usr/lib libdruntime.a + vinstall ${wrksrc}/src/phobos/generated/linux/release/$_archbits/libphobos2.a 644 usr/lib libphobos2.a vmkdir usr/include/d - cp -r src/phobos/{*.d,etc,std} ${PKGDESTDIR}/usr/include/d + cp -r ${wrksrc}/src/phobos/{*.d,etc,std} ${PKGDESTDIR}/usr/include/d vmkdir usr/include/d/druntime - cp -r src/druntime/import ${PKGDESTDIR}/usr/include/d/druntime + cp -r ${wrksrc}/src/druntime/import ${PKGDESTDIR}/usr/include/d/druntime vmkdir usr/share/doc/d/ - cp -r html ${PKGDESTDIR}/usr/share/doc/d/ + cp -r ${wrksrc}/html ${PKGDESTDIR}/usr/share/doc/d/ find ${PKGDESTDIR}/usr/share/doc/d -type f | xargs chmod 0644 - vinstall src/druntime/LICENSE 644 usr/share/licenses/libphobos + vinstall ${wrksrc}/src/druntime/LICENSE 644 usr/share/licenses/libphobos } } dmd_package() { depends="libphobos>=${version} gcc" pkg_install() { - vmove etc - vmove usr + vmove all } } diff --git a/srcpkgs/evince/template b/srcpkgs/evince/template index b7310b728f7..043b32b724a 100644 --- a/srcpkgs/evince/template +++ b/srcpkgs/evince/template @@ -1,13 +1,13 @@ # Template file for 'evince' pkgname=evince -version=3.8.2 +version=3.8.3 revision=1 short_desc="GNOME Document viewer for multiple document formats" maintainer="Juan RP " homepage="http://projects.gnome.org/evince/" license="GPL-2" distfiles="${GNOME_SITE}/$pkgname/3.8/$pkgname-$version.tar.xz" -checksum=dd35b54b82190ba01f0c481e2d073ccddaa325ce80964b655dc167752b6bc2f5 +checksum=1526921201fabe833733e7c2552dfbe62085fd18d325a27c2fffb332e5e418bd build_style=gnu-configure configure_args="--enable-introspection --disable-schemas-compile @@ -26,7 +26,7 @@ makedepends="tiff-devel libarchive-devel nautilus-devel>=3.8.0 libevince_package() { short_desc+=" - runtime libraries" pkg_install() { - vmove "usr/lib/*.so*" + vmove "usr/lib/*.so.*" vmove usr/lib/girepository-1.0 } } @@ -37,6 +37,7 @@ evince-devel_package() { pkg_install() { vmove usr/include vmove usr/lib/pkgconfig + vmove "usr/lib/*.so" vmove usr/share/gir-1.0 vmove usr/share/gtk-doc } diff --git a/srcpkgs/gcc/template b/srcpkgs/gcc/template index 572e5d543cb..6992452cf1d 100644 --- a/srcpkgs/gcc/template +++ b/srcpkgs/gcc/template @@ -2,7 +2,7 @@ pkgname=gcc _majorver=4.7 version=${_majorver}.3 -revision=2 +revision=3 short_desc="The GNU C Compiler" maintainer="Juan RP " homepage="http://gcc.gnu.org" @@ -11,7 +11,7 @@ distfiles="http://ftp.gnu.org/pub/gnu/gcc/gcc-$version/gcc-$version.tar.bz2" checksum=2f7c37eb4fc14422ff2358a9ef59c974a75ab41204ef0e49fc34ab1d8981a9c3 hostmakedepends="perl flex" -makedepends="zlib-devel gmp-devel mpfr-devel mpc-devel ppl-devel>=1.0 cloog-devel" +makedepends="zlib-devel gmp-devel mpfr-devel mpc-devel ppl-devel>=1.0 cloog-devel isl-devel" if [ "$XBPS_TARGET_MACHINE" = "x86_64" ]; then # Required stuff for multilib packages. @@ -43,7 +43,9 @@ do_configure() { _langs="c,c++,lto" _args="--disable-multilib" if [ "$XBPS_TARGET_MACHINE" = "armv6l" ]; then - _args+=" --with-float=hard" + _args+=" --with-arch=armv6 --with-fpu=vfp --with-float=hard" + elif [ "$XBPS_TARGET_MACHINE" = "armv7l" ]; then + _args+=" --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard" fi _args+=" --host=$XBPS_CROSS_TRIPLET" else @@ -500,6 +502,6 @@ gcc-c++_package() { gcc_package() { depends="binutils libgomp>=${_majorver} libitm>=${_majorver} libssp-devel>=${_majorver}" pkg_install() { - vmove usr + vmove all } } diff --git a/srcpkgs/gptfdisk/template b/srcpkgs/gptfdisk/template index b36524557d9..f454c04ea95 100644 --- a/srcpkgs/gptfdisk/template +++ b/srcpkgs/gptfdisk/template @@ -1,6 +1,6 @@ # Template file for 'gptdisk' pkgname=gptfdisk -version=0.8.6 +version=0.8.7 revision=1 makedepends="ncurses-devel popt-devel icu-devel>=49 libuuid-devel" short_desc="GPT fdisk text-mode partitioning tool" @@ -8,10 +8,10 @@ maintainer="Juan RP " homepage="http://www.rodsbooks.com/gdisk/" license="GPL-2" distfiles="${SOURCEFORGE_SITE}/$pkgname/$pkgname-$version.tar.gz" -checksum=4579cd54842459699970e24720dda7fb0aa217027818623089c321bc62a647b2 +checksum=39e61d9f3701e95db1bcb83ce8fb211b22f33548e3c75b17f22067c6968e91e3 do_build() { - make ${makejobs} + make CXX="$CXX" ${makejobs} } do_install() { diff --git a/srcpkgs/libassuan/template b/srcpkgs/libassuan/template index ebf89bed28b..085e3815a16 100644 --- a/srcpkgs/libassuan/template +++ b/srcpkgs/libassuan/template @@ -1,7 +1,7 @@ # Template file for 'libassuan' pkgname=libassuan -version=2.0.3 -revision=2 +version=2.1.1 +revision=1 build_style=gnu-configure makedepends="libgpg-error-devel" short_desc="IPC library used by some GnuPG related software" @@ -9,7 +9,7 @@ maintainer="Juan RP " license="GPL-2" homepage="http://www.gnupg.org/related_software/libassuan" distfiles="ftp://ftp.gnupg.org/gcrypt/$pkgname/$pkgname-$version.tar.bz2" -checksum=bad5682374c76bcc0abb1a7a34c9557af6874a477500748e64a7d3def79cac1b +checksum=23e2d67779b88e90d29fe1df6b157109f1c2a647d0f1b2a0f4295bb3c0b2039d long_desc=" Libassuan is a small library implementing the so-called Assuan protocol. This protocol is used for IPC between most newer GnuPG components. Both, server @@ -20,11 +20,12 @@ if [ "$CROSS_BUILD" ]; then fi libassuan-devel_package() { - depends="libgpg-error-devel libassuan>=${version}" - short_desc="${short_desc} - development files" + depends="libgpg-error-devel libassuan-${version}_${revision}" + short_desc+=" - development files" pkg_install() { vmove usr/bin vmove usr/include + vmove "usr/lib/*.so" vmove usr/share } } diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-add-dm-disable-udev-env-var-and-fix-noudevsync-arg.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-add-dm-disable-udev-env-var-and-fix-noudevsync-arg.patch new file mode 100644 index 00000000000..d2f1570b5c0 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-add-dm-disable-udev-env-var-and-fix-noudevsync-arg.patch @@ -0,0 +1,252 @@ +commit 03ed86585e1bfbaf5df1e3488b6268b8887ca427 +Author: Peter Rajnoha +Date: Tue May 14 11:17:52 2013 +0200 + + lvm2-2_02_99-add-dm-disable-udev-env-var-and-fix-noudevsync-arg.patch +--- + WHATS_NEW | 2 ++ + WHATS_NEW_DM | 1 + + lib/commands/toolcontext.c | 62 ++++++++++++++++++++++++++++++++++------------ + libdm/libdm-common.c | 43 ++++++++++++++++++++++++++------ + tools/lvmcmdline.c | 4 +-- + 5 files changed, 86 insertions(+), 26 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 1bdfeb0..8516f40 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,7 @@ + Version 2.02.99 - + =================================== ++ Recognize DM_DISABLE_UDEV environment variable for a complete fallback. ++ Do not verify udev operations if --noudevsync command option is used. + Fix blkdeactivate to handle nested mountpoints and mangled mount paths. + Fix a crash-inducing race condition in lvmetad while updating metadata. + Fix possible race while removing metadata from lvmetad. +diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM +index e0b8d51..9574fdf 100644 +--- a/WHATS_NEW_DM ++++ b/WHATS_NEW_DM +@@ -1,5 +1,6 @@ + Version 1.02.78 - + =================================== ++ Add DM_DISABLE_UDEV environment variable to manage dev nodes by libdm only. + Automatically deactivate failed preloaded dm tree node. + Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled. + +diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c +index eb1a90b..80d0f3e 100644 +--- a/lib/commands/toolcontext.c ++++ b/lib/commands/toolcontext.c +@@ -211,6 +211,21 @@ static void _init_logging(struct cmd_context *cmd) + reset_lvm_errno(1); + } + ++static int _check_disable_udev(const char *msg) { ++ if (getenv("DM_DISABLE_UDEV")) { ++ log_very_verbose("DM_DISABLE_UDEV environment variable set. " ++ "Overriding configuration to use " ++ "udev_rules=0, udev_sync=0, verify_udev_operations=1."); ++ if (udev_is_running()) ++ log_warn("Udev is running and DM_DISABLE_UDEV environment variable is set. " ++ "Bypassing udev, LVM will %s.", msg); ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ + #ifdef UDEV_SYNC_SUPPORT + /* + * Until the DM_UEVENT_GENERATED_FLAG was introduced in kernel patch +@@ -237,6 +252,7 @@ static int _process_config(struct cmd_context *cmd) + const struct dm_config_value *cv; + int64_t pv_min_kb; + const char *lvmetad_socket; ++ int udev_disabled = 0; + + /* umask */ + cmd->default_settings.umask = find_config_tree_int(cmd, +@@ -310,13 +326,20 @@ static int _process_config(struct cmd_context *cmd) + return 0; + } + +- cmd->default_settings.udev_rules = find_config_tree_int(cmd, +- "activation/udev_rules", +- DEFAULT_UDEV_RULES); ++ /* ++ * If udev is disabled using DM_DISABLE_UDEV environment ++ * variable, override existing config and hardcode these: ++ * - udev_rules = 0 ++ * - udev_sync = 0 ++ * - udev_fallback = 1 ++ */ ++ udev_disabled = _check_disable_udev("manage logical volume symlinks in device directory"); + +- cmd->default_settings.udev_sync = find_config_tree_int(cmd, +- "activation/udev_sync", +- DEFAULT_UDEV_SYNC); ++ cmd->default_settings.udev_rules = udev_disabled ? 0 : ++ find_config_tree_int(cmd, "activation/udev_rules", DEFAULT_UDEV_RULES); ++ ++ cmd->default_settings.udev_sync = udev_disabled ? 0 : ++ find_config_tree_int(cmd, "activation/udev_sync", DEFAULT_UDEV_SYNC); + + init_retry_deactivation(find_config_tree_int(cmd, "activation/retry_deactivation", + DEFAULT_RETRY_DEACTIVATION)); +@@ -326,14 +349,12 @@ static int _process_config(struct cmd_context *cmd) + + #ifdef UDEV_SYNC_SUPPORT + /* +- * We need udev rules to be applied, otherwise we would end up with no +- * nodes and symlinks! However, we can disable the synchronization itself +- * in runtime and still have only udev to create the nodes and symlinks +- * without any fallback. ++ * Use udev fallback automatically in case udev ++ * is disabled via DM_DISABLE_UDEV environment ++ * variable or udev rules are switched off. + */ +- cmd->default_settings.udev_fallback = cmd->default_settings.udev_rules ? +- find_config_tree_int(cmd, "activation/verify_udev_operations", +- DEFAULT_VERIFY_UDEV_OPERATIONS) : 1; ++ cmd->default_settings.udev_fallback = !cmd->default_settings.udev_rules || udev_disabled ? 1 : ++ find_config_tree_int(cmd, "activation/verify_udev_operations", DEFAULT_VERIFY_UDEV_OPERATIONS); + + /* Do not rely fully on udev if the udev support is known to be incomplete. */ + if (!cmd->default_settings.udev_fallback && !_dm_driver_has_stable_udev_support()) { +@@ -693,9 +714,18 @@ static int _init_dev_cache(struct cmd_context *cmd) + if (!dev_cache_init(cmd)) + return_0; + +- device_list_from_udev = udev_is_running() ? +- find_config_tree_bool(cmd, "devices/obtain_device_list_from_udev", +- DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV) : 0; ++ /* ++ * Override existing config and hardcode device_list_from_udev = 0 if: ++ * - udev is not running ++ * - udev is disabled using DM_DISABLE_UDEV environment variable ++ */ ++ if (_check_disable_udev("obtain device list by scanning device directory")) ++ device_list_from_udev = 0; ++ else ++ device_list_from_udev = udev_is_running() ? ++ find_config_tree_bool(cmd, "devices/obtain_device_list_from_udev", ++ DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV) : 0; ++ + init_obtain_device_list_from_udev(device_list_from_udev); + + if (!(cn = find_config_tree_node(cmd, "devices/scan"))) { +diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c +index afdac89..075fba8 100644 +--- a/libdm/libdm-common.c ++++ b/libdm/libdm-common.c +@@ -74,6 +74,8 @@ static dm_string_mangling_t _name_mangling_mode = DEFAULT_DM_NAME_MANGLING; + static struct selabel_handle *_selabel_handle = NULL; + #endif + ++static int _udev_disabled = 0; ++ + #ifdef UDEV_SYNC_SUPPORT + static int _semaphore_supported = -1; + static int _udev_running = -1; +@@ -85,6 +87,9 @@ void dm_lib_init(void) + { + const char *env; + ++ if ((env = getenv("DM_DISABLE_UDEV"))) ++ _udev_disabled = 1; ++ + env = getenv(DM_DEFAULT_NAME_MANGLING_MODE_ENV_VAR_NAME); + if (env && *env) { + if (!strcasecmp(env, "none")) +@@ -1814,6 +1819,26 @@ out: + return r; + } + ++static void _set_cookie_flags(struct dm_task *dmt, uint16_t flags) ++{ ++ if (!dm_cookie_supported()) ++ return; ++ ++ if (_udev_disabled) { ++ /* ++ * If udev is disabled, hardcode this functionality: ++ * - we want libdm to create the nodes ++ * - we don't want the /dev/mapper and any subsystem ++ * related content to be created by udev if udev ++ * rules are installed ++ */ ++ flags &= ~DM_UDEV_DISABLE_LIBRARY_FALLBACK; ++ flags |= DM_UDEV_DISABLE_DM_RULES_FLAG | DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG; ++ } ++ ++ dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT; ++} ++ + #ifndef UDEV_SYNC_SUPPORT + void dm_udev_set_sync_support(int sync_with_udev) + { +@@ -1835,8 +1860,8 @@ int dm_udev_get_checking(void) + + int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) + { +- if (dm_cookie_supported()) +- dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT; ++ _set_cookie_flags(dmt, flags); ++ + *cookie = 0; + dmt->cookie_set = 1; + +@@ -1908,8 +1933,13 @@ static void _check_udev_sync_requirements_once(void) + if (_semaphore_supported < 0) + _semaphore_supported = _check_semaphore_is_supported(); + +- if (_udev_running < 0) ++ if (_udev_running < 0) { + _udev_running = _check_udev_is_running(); ++ if (_udev_disabled && _udev_running) ++ log_warn("Udev is running and DM_DISABLE_UDEV environment variable is set. " ++ "Bypassing udev, device-mapper library will manage device " ++ "nodes in device directory."); ++ } + } + + void dm_udev_set_sync_support(int sync_with_udev) +@@ -1922,8 +1952,8 @@ int dm_udev_get_sync_support(void) + { + _check_udev_sync_requirements_once(); + +- return _semaphore_supported && dm_cookie_supported() && +- _udev_running && _sync_with_udev; ++ return !_udev_disabled && _semaphore_supported && ++ dm_cookie_supported() &&_udev_running && _sync_with_udev; + } + + void dm_udev_set_checking(int checking) +@@ -2203,8 +2233,7 @@ int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) + { + int semid; + +- if (dm_cookie_supported()) +- dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT; ++ _set_cookie_flags(dmt, flags); + + if (!dm_udev_get_sync_support()) { + *cookie = 0; +diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c +index 39a8c58..652d57e 100644 +--- a/tools/lvmcmdline.c ++++ b/tools/lvmcmdline.c +@@ -901,10 +901,8 @@ static int _get_settings(struct cmd_context *cmd) + } else + init_trust_cache(0); + +- if (arg_count(cmd, noudevsync_ARG)) { ++ if (arg_count(cmd, noudevsync_ARG)) + cmd->current_settings.udev_sync = 0; +- cmd->current_settings.udev_fallback = 1; +- } + + /* Handle synonyms */ + if (!_merge_synonym(cmd, resizable_ARG, resizeable_ARG) || diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-also-autoactivate-on-coldplug.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-also-autoactivate-on-coldplug.patch new file mode 100644 index 00000000000..c1ceda9ba17 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-also-autoactivate-on-coldplug.patch @@ -0,0 +1,73 @@ +commit 764195207d4773cf6f1674a2fb16e9a0acda304a +Author: Peter Rajnoha +Date: Fri Apr 19 12:17:53 2013 +0200 + + udev: also autoactivate on coldplug + + Commit 756bcabbfe297688ba240a880bc2b55265ad33f0 fixed autoactivation + to not trigger on each uevent for a PV that appeared in the system + most notably the events that are triggered artificially (udevadm + trigger or as the result of the WATCH udev rule being applied that + consequently generates CHANGE uevents). This fixed a situation in + which VGs/LVs were activated when they should not. + + BUT we still need to care about the coldplug used at boot to + retrigger the ADD events - the "udevadm trigger --action=add"! + + For non-DM-based PVs, this is already covered as for these we + run the autoactivation on ADD event only. + + However, for DM-based PVs, we still need to run the + autoactivation even for the artificial ADD event, reusing + the udev DB content from previous proper CHANGE event that + came with the DM device activation. + + Simply, this patch fixes a situation in which we run extra + "udevadm trigger --action=add" (or echo add > /sys/block//uevent) + for DM-based PVs (cryptsetup devices, multipath devices, any + other DM devices...). + + Without this patch, while using lvmetad + autoactivation, + any VG/LV that has a DM-based PV and for which we do not + call the activation directly, the VG/LV is not activated. + + For example a VG with an LV with root FS on it which is directly + activated in initrd and then missing activation of the rest + of the LVs in the VG because of unhandled uevent retrigger on + boot after switching to root FS (the "coldplug"). + + (No WHATS_NEW here as this fixes the commit mentioned + above and which was not released yet.) +--- + udev/10-dm.rules.in | 5 ++++- + udev/69-dm-lvm-metad.rules.in | 1 + + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in +index cfee145..512d156 100644 +--- a/udev/10-dm.rules.in ++++ b/udev/10-dm.rules.in +@@ -77,7 +77,10 @@ LABEL="dm_flags_done" + # before (e.g. in initrd). If udev is used in initrd, we require the udev init + # script to not remove the existing udev database so we can reuse the information + # stored at the time of device activation in the initrd. +-ACTION=="add", ENV{DM_UDEV_RULES_VSN}!="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="dm_disable" ++ACTION!="add", GOTO="dm_no_coldplug" ++ENV{DM_UDEV_RULES_VSN}!="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="dm_disable" ++ENV{DM_ACTIVATION}="1" ++LABEL="dm_no_coldplug" + + # "dm" sysfs subdirectory is available in newer versions of DM + # only (kernels >= 2.6.29). We have to check for its existence +diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in +index b16a27a..66c58b3 100644 +--- a/udev/69-dm-lvm-metad.rules.in ++++ b/udev/69-dm-lvm-metad.rules.in +@@ -26,6 +26,7 @@ ACTION=="remove", GOTO="lvm_scan" + KERNEL!="dm-[0-9]*", ACTION!="add", GOTO="lvm_end" + + # If the PV is a dm device, scan only after proper mapping activation (CHANGE event + DM_ACTIVATION=1) ++# or after a coldplug (event retrigger) with "add" event (ADD event + DM_ACTIVATION=1) + KERNEL=="dm-[0-9]*", ENV{DM_ACTIVATION}!="1", GOTO="lvm_end" + + LABEL="lvm_scan" diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-avoid-global-lock-in-pvs-when-lvmetad-is-in-use.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-avoid-global-lock-in-pvs-when-lvmetad-is-in-use.patch new file mode 100644 index 00000000000..e1ecef04306 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-avoid-global-lock-in-pvs-when-lvmetad-is-in-use.patch @@ -0,0 +1,34 @@ +commit 9cff3357bd69f15497af8c03774df07081d361dd +Author: Peter Rajnoha +Date: Tue May 14 11:04:08 2013 +0200 + + lvm2-2_02_99-avoid-global-lock-in-pvs-when-lvmetad-is-in-use.patch +--- + WHATS_NEW | 1 + + tools/toollib.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 62efb53..25e07ee 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Avoid a global lock in pvs when lvmetad is in use. + Fix crash in pvscan --cache -aay triggered by non-mda PV. + Fix lvm2app to return all property sizes in bytes. + Add lvm.conf option global/thin_disabled_features. +diff --git a/tools/toollib.c b/tools/toollib.c +index 5fe94e0..dce42f4 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -701,7 +701,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, + int opt = 0; + int ret_max = ECMD_PROCESSED; + int ret = 0; +- int lock_global = !(flags & READ_WITHOUT_LOCK) && !(flags & READ_FOR_UPDATE); ++ int lock_global = !(flags & READ_WITHOUT_LOCK) && !(flags & READ_FOR_UPDATE) && !lvmetad_active(); + + struct pv_list *pvl; + struct physical_volume *pv; diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-close-dmeventd-fifo-fds-on-exec.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-close-dmeventd-fifo-fds-on-exec.patch new file mode 100644 index 00000000000..5fa9f6fd97f --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-close-dmeventd-fifo-fds-on-exec.patch @@ -0,0 +1,109 @@ +commit b7e453f3821c4a896e00a29800351687d3365f64 +Author: Peter Rajnoha +Date: Tue May 14 11:26:40 2013 +0200 + + lvm2-2_02_99-close-dmeventd-fifo-fds-on-exec.patch +--- + WHATS_NEW_DM | 1 + + daemons/dmeventd/dmeventd.c | 37 ++++++++++++++++++++++++++++--------- + 2 files changed, 29 insertions(+), 9 deletions(-) + +diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM +index 9574fdf..30d01f9 100644 +--- a/WHATS_NEW_DM ++++ b/WHATS_NEW_DM +@@ -1,5 +1,6 @@ + Version 1.02.78 - + =================================== ++ Close open dmeventd FIFO file descriptors on exec (FD_CLOEXEC). + Add DM_DISABLE_UDEV environment variable to manage dev nodes by libdm only. + Automatically deactivate failed preloaded dm tree node. + Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled. +diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c +index 13148c3..5f2339f 100644 +--- a/daemons/dmeventd/dmeventd.c ++++ b/daemons/dmeventd/dmeventd.c +@@ -1237,7 +1237,8 @@ static int _get_timeout(struct message_data *message_data) + /* Initialize a fifos structure with path names. */ + static void _init_fifos(struct dm_event_fifos *fifos) + { +- memset(fifos, 0, sizeof(*fifos)); ++ fifos->client = -1; ++ fifos->server = -1; + + fifos->client_path = DM_EVENT_FIFO_CLIENT; + fifos->server_path = DM_EVENT_FIFO_SERVER; +@@ -1254,7 +1255,7 @@ static int _open_fifos(struct dm_event_fifos *fifos) + syslog(LOG_ERR, "%s: Failed to create client fifo %s: %m.\n", + __func__, fifos->client_path); + (void) dm_prepare_selinux_context(NULL, 0); +- return 0; ++ goto fail; + } + + /* Create server fifo. */ +@@ -1263,7 +1264,7 @@ static int _open_fifos(struct dm_event_fifos *fifos) + syslog(LOG_ERR, "%s: Failed to create server fifo %s: %m.\n", + __func__, fifos->server_path); + (void) dm_prepare_selinux_context(NULL, 0); +- return 0; ++ goto fail; + } + + (void) dm_prepare_selinux_context(NULL, 0); +@@ -1281,31 +1282,49 @@ static int _open_fifos(struct dm_event_fifos *fifos) + if (chmod(fifos->client_path, 0600)) { + syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n", + fifos->client_path); +- return 0; ++ goto fail; + } + + if (chmod(fifos->server_path, 0600)) { + syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n", + fifos->server_path); +- return 0; ++ goto fail; + } + + /* Need to open read+write or we will block or fail */ + if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) { + syslog(LOG_ERR, "Failed to open fifo server %s: %m.\n", + fifos->server_path); +- return 0; ++ goto fail; ++ } ++ ++ if (fcntl(fifos->server, F_SETFD, FD_CLOEXEC) < 0) { ++ syslog(LOG_ERR, "Failed to set FD_CLOEXEC for fifo server %s: %m.\n", ++ fifos->server_path); ++ goto fail; + } + + /* Need to open read+write for select() to work. */ + if ((fifos->client = open(fifos->client_path, O_RDWR)) < 0) { + syslog(LOG_ERR, "Failed to open fifo client %s: %m", fifos->client_path); +- if (close(fifos->server)) +- syslog(LOG_ERR, "Failed to close fifo server %s: %m", fifos->server_path); +- return 0; ++ goto fail; ++ } ++ ++ if (fcntl(fifos->client, F_SETFD, FD_CLOEXEC) < 0) { ++ syslog(LOG_ERR, "Failed to set FD_CLOEXEC for fifo client %s: %m.\n", ++ fifos->client_path); ++ goto fail; + } + + return 1; ++fail: ++ if (fifos->server >= 0 && close(fifos->server)) ++ syslog(LOG_ERR, "Failed to close fifo server %s: %m", fifos->server_path); ++ ++ if (fifos->client >= 0 && close(fifos->client)) ++ syslog(LOG_ERR, "Failed to close fifo client %s: %m", fifos->client_path); ++ ++ return 0; + } + + /* diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-exit-pvscan-cache-immediately-if-cluster-locking-used-or-lvmetad-not-used.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-exit-pvscan-cache-immediately-if-cluster-locking-used-or-lvmetad-not-used.patch new file mode 100644 index 00000000000..8883b375f84 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-exit-pvscan-cache-immediately-if-cluster-locking-used-or-lvmetad-not-used.patch @@ -0,0 +1,41 @@ + WHATS_NEW | 1 + + tools/pvscan.c | 15 +++++++++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 12307ed..e247391 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Exit pvscan --cache immediately if cluster locking used or lvmetad not used. + Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. + Remove dependency on fedora-storage-init.service in lvm2 systemd units. + Depend on lvm2-lvmetad.socket in lvm2-monitor.service systemd unit. +diff --git a/tools/pvscan.c b/tools/pvscan.c +index 3d5ddef..34ab792 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -119,6 +119,21 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv) + char *buf; + activation_handler handler = NULL; + ++ /* ++ * Return here immediately if lvmetad is not used. ++ * Also return if locking_type=3 (clustered) as we ++ * dont't support cluster + lvmetad yet. ++ * ++ * This is to avoid taking the global lock uselessly ++ * and to prevent hangs in clustered environment. ++ */ ++ /* TODO: Remove this once lvmetad + cluster supported! */ ++ if (find_config_tree_int(cmd, "global/locking_type", 1) == 3 || ++ !find_config_tree_int(cmd, "global/use_lvmetad", 0)) { ++ log_debug("_pvscan_lvmetad: immediate return"); ++ return ret; ++ } ++ + if (arg_count(cmd, activate_ARG)) { + if (arg_uint_value(cmd, activate_ARG, CHANGE_AAY) != CHANGE_AAY) { + log_error("Only --activate ay allowed with pvscan."); diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-fire-pvscan-cache-on-change-event-for-md-devs.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-fire-pvscan-cache-on-change-event-for-md-devs.patch new file mode 100644 index 00000000000..bb1e09ed08f --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-fire-pvscan-cache-on-change-event-for-md-devs.patch @@ -0,0 +1,50 @@ +commit 2ac217d408470dcecb69b83d9cbf7a254747fa5b +Author: Peter Rajnoha +Date: Fri May 3 13:20:07 2013 +0200 + + udev: fire pvscan --cache properly on CHANGE event for MD devices + + Commit 756bcabbfe297688ba240a880bc2b55265ad33f0 restricted the + situations at which the LVM autoactivation fires - only on ADD + event for devices other than DM. However, this caused a problem + for MD devices... + + MD devices are activated in a very similar way as DM devices: + the MD dev is created on first appeareance of MD array member + (ADD event) and stays *inactive* until the array is complete. + Just then the MD dev turns to active state and this is reported + to userspace by CHANGE event. + + Unfortunately, we can't differentiate between the CHANGE event + coming from udev trigger/WATCH rule and CHANGE event coming from + the transition to active state - MD would need to add similar logic + we already use to detect this in DM world. For now, we just have + to enable pvscan --cache on *all* CHANGE events for MD so the + autoactivation of the LVM volumes on top of MD works. + + A downside of this is that a spurious CHANGE event for MD dev + can cause the LVM volumes on top of it to be automatically activated. + However, one should not open/change the device underneath until + the device above in the stack is removed! So this situation should + only happen if one opens the MD dev for read-write by mistake + (and hence firing the CHANGE event because of the WATCH udev rule), + or if calling udev trigger manually for the MD dev. + + (No WHATS_NEW here as this fixes the commit mentioned + above and which has not been released yet.) +--- + udev/69-dm-lvm-metad.rules.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in +index 66c58b3..a0e48a1 100644 +--- a/udev/69-dm-lvm-metad.rules.in ++++ b/udev/69-dm-lvm-metad.rules.in +@@ -21,6 +21,7 @@ SUBSYSTEM!="block", GOTO="lvm_end" + ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_end" + + ACTION=="remove", GOTO="lvm_scan" ++ACTION=="change", KERNEL=="md[0-9]*", GOTO="lvm_scan" + + # If the PV is not a dm device, scan only after device addition (ADD event) + KERNEL!="dm-[0-9]*", ACTION!="add", GOTO="lvm_end" diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-autoactivation-to-not-autoactivate-vg-lv-on-each-pv-change.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-autoactivation-to-not-autoactivate-vg-lv-on-each-pv-change.patch new file mode 100644 index 00000000000..ddcf3d7b214 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-autoactivation-to-not-autoactivate-vg-lv-on-each-pv-change.patch @@ -0,0 +1,62 @@ +commit 0bf7bdf5216eae93cff7abb47a76b39270d71413 +Author: Peter Rajnoha +Date: Tue Apr 9 10:07:15 2013 +0200 + + 0 +--- + WHATS_NEW | 1 + + udev/10-dm.rules.in | 2 +- + udev/69-dm-lvm-metad.rules.in | 16 ++++++++++++---- + 3 files changed, 14 insertions(+), 5 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 67a24c7..c481e68 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Fix autoactivation to not autoactivate VG/LV on each change of the PVs used. + Skip mlocking [vectors] on arm architecture. + Exit pvscan --cache immediately if cluster locking used or lvmetad not used. + Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. +diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in +index 29af467..cfee145 100644 +--- a/udev/10-dm.rules.in ++++ b/udev/10-dm.rules.in +@@ -45,7 +45,7 @@ ENV{DISK_RO}=="1", GOTO="dm_disable" + # in libdevmapper so we need to detect this and try to behave correctly. + # For such spurious events, regenerate all flags from current udev database content + # (this information would normally be inaccessible for spurious ADD and CHANGE events). +-ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_flags_done" ++ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}="1", GOTO="dm_flags_done" + IMPORT{db}="DM_UDEV_DISABLE_DM_RULES_FLAG" + IMPORT{db}="DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG" + IMPORT{db}="DM_UDEV_DISABLE_DISK_RULES_FLAG" +diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in +index 706c03b..b16a27a 100644 +--- a/udev/69-dm-lvm-metad.rules.in ++++ b/udev/69-dm-lvm-metad.rules.in +@@ -17,10 +17,18 @@ + SUBSYSTEM!="block", GOTO="lvm_end" + (LVM_EXEC_RULE) + +-# Device-mapper devices are processed only on change event or on supported synthesized event. +-KERNEL=="dm-[0-9]*", ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="lvm_end" +- + # Only process devices already marked as a PV - this requires blkid to be called before. +-ENV{ID_FS_TYPE}=="LVM2_member|LVM1_member", RUN+="(LVM_EXEC)/lvm pvscan --cache --activate ay --major $major --minor $minor" ++ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_end" ++ ++ACTION=="remove", GOTO="lvm_scan" ++ ++# If the PV is not a dm device, scan only after device addition (ADD event) ++KERNEL!="dm-[0-9]*", ACTION!="add", GOTO="lvm_end" ++ ++# If the PV is a dm device, scan only after proper mapping activation (CHANGE event + DM_ACTIVATION=1) ++KERNEL=="dm-[0-9]*", ENV{DM_ACTIVATION}!="1", GOTO="lvm_end" ++ ++LABEL="lvm_scan" ++RUN+="(LVM_EXEC)/lvm pvscan --cache --activate ay --major $major --minor $minor" + + LABEL="lvm_end" diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch new file mode 100644 index 00000000000..a9dab213acb --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch @@ -0,0 +1,93 @@ +commit 5025178f95b122c6862dc7d925a7c089f5fb61a8 +Author: Peter Rajnoha +Date: Tue May 14 11:05:50 2013 +0200 + + lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch +--- + WHATS_NEW | 1 + + scripts/blkdeactivate.sh.in | 30 ++++++++++++++++++++++++------ + 2 files changed, 25 insertions(+), 6 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 35c5e43..1bdfeb0 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Fix blkdeactivate to handle nested mountpoints and mangled mount paths. + Fix a crash-inducing race condition in lvmetad while updating metadata. + Fix possible race while removing metadata from lvmetad. + Fix possible deadlock when querying and updating lvmetad at the same time. +diff --git a/scripts/blkdeactivate.sh.in b/scripts/blkdeactivate.sh.in +index 740bac5..be00c24 100644 +--- a/scripts/blkdeactivate.sh.in ++++ b/scripts/blkdeactivate.sh.in +@@ -39,6 +39,7 @@ LVM="@sbindir@/lvm" + LSBLK="/bin/lsblk -r --noheadings -o TYPE,KNAME,NAME,MOUNTPOINT" + LSBLK_VARS="local devtype local kname local name local mnt" + LSBLK_READ="read -r devtype kname name mnt" ++SORT_MNT="/bin/sort -r -u -k 4" + + # Do not unmount mounted devices by default. + DO_UMOUNT=0 +@@ -122,9 +123,11 @@ is_top_level_device() { + device_umount () { + test -z "$mnt" && return 0; + ++ test "$devtype" != "lvm" && test "${kname:0:3}" != "dm-" && return 0 ++ + if test -z "${SKIP_UMOUNT_LIST["$mnt"]}" -a "$DO_UMOUNT" -eq "1"; then + echo " UMOUNT: unmounting $name ($kname) mounted on $mnt" +- $UMOUNT "$mnt" || add_device_to_skip_list ++ $UMOUNT "$(printf $mnt)" || add_device_to_skip_list + else + echo " [SKIP]: unmount of $name ($kname) mounted on $mnt" + add_device_to_skip_list +@@ -142,9 +145,6 @@ deactivate_holders () { + # check if the device not on the skip list already + test -z ${SKIP_DEVICE_LIST["$kname"]} || return 1 + +- # try to unmount it if mounted +- device_umount || return 1 +- + # try to deactivate the holder + test $skip -eq 1 && skip=0 && continue + deactivate || return 1 +@@ -226,7 +226,16 @@ deactivate_all() { + echo "Deactivating block devices:" + + if test $# -eq 0; then +- # Deactivate all devices ++ ####################### ++ # Process all devices # ++ ####################### ++ ++ # Unmount all relevant mountpoints first ++ while $LSBLK_READ; do ++ device_umount ++ done <<< "`$LSBLK | $SORT_MNT`" ++ ++ # Do deactivate + while $LSBLK_READ; do + # 'disk' is at the bottom already and it's a real device + test "$devtype" = "disk" && continue +@@ -249,8 +258,17 @@ deactivate_all() { + deactivate || skip=1 + done <<< "`$LSBLK -s`" + else +- # Deactivate only specified devices ++ ################################## ++ # Process only specified devices # ++ ################################## ++ + while test $# -ne 0; do ++ # Unmount all relevant mountpoints first ++ while $LSBLK_READ; do ++ device_umount ++ done <<< "`$LSBLK $1 | $SORT_MNT`" ++ ++ # Do deactivate + # Single dm device tree deactivation. + if test -b "$1"; then + $LSBLK_READ <<< "`$LSBLK --nodeps $1`" diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-crash-in-pvscan-cache-aay-triggered-by-non-mda-pv.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-crash-in-pvscan-cache-aay-triggered-by-non-mda-pv.patch new file mode 100644 index 00000000000..491a1e5df2e --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-crash-in-pvscan-cache-aay-triggered-by-non-mda-pv.patch @@ -0,0 +1,175 @@ +commit 5e247adf415942fcc0a5b888567f51a148619b65 +Author: Peter Rajnoha +Date: Tue May 14 11:03:46 2013 +0200 + + lvm2-2_02_99-fix-crash-in-pvscan-cache-aay-triggered-by-non-mda-pv.patch +--- + WHATS_NEW | 1 + + lib/cache/lvmetad.c | 12 ++++------ + lib/cache/lvmetad.h | 3 ++- + test/shell/lvmetad-pvscan-nomda.sh | 49 ++++++++++++++++++++++++++++++++++++++ + tools/pvscan.c | 22 +++++++++++++++-- + 5 files changed, 76 insertions(+), 11 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 5231745..62efb53 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Fix crash in pvscan --cache -aay triggered by non-mda PV. + Fix lvm2app to return all property sizes in bytes. + Add lvm.conf option global/thin_disabled_features. + Add lvconvert support to swap thin pool metadata volume. +diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c +index 72e07fd..a636f43 100644 +--- a/lib/cache/lvmetad.c ++++ b/lib/cache/lvmetad.c +@@ -675,7 +675,7 @@ int lvmetad_pv_found(const struct id *pvid, struct device *device, const struct + daemon_reply reply; + struct lvmcache_info *info; + struct dm_config_tree *pvmeta, *vgmeta; +- const char *status; ++ const char *status, *vgid; + int result; + + if (!lvmetad_active() || test_mode()) +@@ -724,11 +724,6 @@ int lvmetad_pv_found(const struct id *pvid, struct device *device, const struct + NULL); + dm_config_destroy(vgmeta); + } else { +- if (handler) { +- log_error(INTERNAL_ERROR "Handler needs existing VG."); +- dm_free(pvmeta); +- return 0; +- } + /* There are no MDAs on this PV. */ + reply = _lvmetad_send("pv_found", "pvmeta = %t", pvmeta, NULL); + } +@@ -744,10 +739,11 @@ int lvmetad_pv_found(const struct id *pvid, struct device *device, const struct + + if (result && handler) { + status = daemon_reply_str(reply, "status", ""); ++ vgid = daemon_reply_str(reply, "vgid", ""); + if (!strcmp(status, "partial")) +- handler(vg, 1, CHANGE_AAY); ++ handler(_lvmetad_cmd, vgid, 1, CHANGE_AAY); + else if (!strcmp(status, "complete")) +- handler(vg, 0, CHANGE_AAY); ++ handler(_lvmetad_cmd, vgid, 0, CHANGE_AAY); + else if (!strcmp(status, "orphan")) + ; + else +diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h +index 5f0f552..c644069 100644 +--- a/lib/cache/lvmetad.h ++++ b/lib/cache/lvmetad.h +@@ -22,7 +22,8 @@ struct cmd_context; + struct dm_config_tree; + enum activation_change; + +-typedef int (*activation_handler) (struct volume_group *vg, int partial, ++typedef int (*activation_handler) (struct cmd_context *cmd, ++ const char *vgid, int partial, + enum activation_change activate); + + #ifdef LVMETAD_SUPPORT +diff --git a/test/shell/lvmetad-pvscan-nomda.sh b/test/shell/lvmetad-pvscan-nomda.sh +new file mode 100644 +index 0000000..c04a275 +--- /dev/null ++++ b/test/shell/lvmetad-pvscan-nomda.sh +@@ -0,0 +1,49 @@ ++#!/bin/sh ++# Copyright (C) 2012 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 ++ ++. lib/test ++ ++test -e LOCAL_LVMETAD || skip ++kill $(cat LOCAL_LVMETAD) ++rm LOCAL_LVMETAD ++ ++aux prepare_devs 2 ++ ++pvcreate --metadatacopies 0 $dev1 ++pvcreate --metadatacopies 1 $dev2 ++vgcreate $vg1 $dev1 $dev2 ++lvcreate -n foo -l 1 -an --zero n $vg1 ++ ++# start lvmetad but make sure it doesn't know about $dev1 or $dev2 ++aux disable_dev $dev1 ++aux disable_dev $dev2 ++aux prepare_lvmetad ++lvs ++mv LOCAL_LVMETAD XXX ++aux enable_dev $dev2 ++aux enable_dev $dev1 ++mv XXX LOCAL_LVMETAD ++ ++aux lvmconf 'global/use_lvmetad = 0' ++check inactive $vg1 foo ++aux lvmconf 'global/use_lvmetad = 1' ++ ++pvscan --cache $dev2 -aay ++ ++aux lvmconf 'global/use_lvmetad = 0' ++check inactive $vg1 foo ++aux lvmconf 'global/use_lvmetad = 1' ++ ++pvscan --cache $dev1 -aay ++ ++aux lvmconf 'global/use_lvmetad = 0' ++check active $vg1 foo ++aux lvmconf 'global/use_lvmetad = 1' +diff --git a/tools/pvscan.c b/tools/pvscan.c +index fbd524b..1e844c5 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -91,18 +91,36 @@ static void _pvscan_display_single(struct cmd_context *cmd, + display_size(cmd, (uint64_t) (pv_pe_count(pv) - pv_pe_alloc_count(pv)) * pv_pe_size(pv))); + } + +-static int _auto_activation_handler(struct volume_group *vg, int partial, ++static int _auto_activation_handler(struct cmd_context *cmd, ++ const char *vgid, int partial, + activation_change_t activate) + { ++ struct volume_group *vg; ++ int consistent = 0; ++ struct id vgid_raw; ++ + /* TODO: add support for partial and clustered VGs */ +- if (partial || vg_is_clustered(vg)) ++ if (partial) + return 1; + ++ id_read_format(&vgid_raw, vgid); ++ /* NB. This is safe because we know lvmetad is running and we won't hit ++ * disk. */ ++ if (!(vg = vg_read_internal(cmd, NULL, (const char *) &vgid_raw, 0, &consistent))) ++ return 1; ++ ++ if (vg_is_clustered(vg)) { ++ release_vg(vg); ++ return 1; ++ } ++ + if (!vgchange_activate(vg->cmd, vg, activate)) { + log_error("%s: autoactivation failed.", vg->name); ++ release_vg(vg); + return 0; + } + ++ release_vg(vg); + return 1; + } + diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-dmsetup-splitname-to-not-fail-if-used-without-c-switch.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-dmsetup-splitname-to-not-fail-if-used-without-c-switch.patch new file mode 100644 index 00000000000..2ad182b1ac7 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-dmsetup-splitname-to-not-fail-if-used-without-c-switch.patch @@ -0,0 +1,47 @@ +commit f03877ecb56f32d91dd98e8e3331164f472f8b77 +Author: Peter Rajnoha +Date: Tue May 14 11:48:51 2013 +0200 + + lvm2-2_02_99-fix-dmsetup-splitname-to-not-fail-if-used-without-c-switch.patch +--- + WHATS_NEW_DM | 1 + + tools/dmsetup.c | 8 +++++--- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM +index 30d01f9..34a0f70 100644 +--- a/WHATS_NEW_DM ++++ b/WHATS_NEW_DM +@@ -1,5 +1,6 @@ + Version 1.02.78 - + =================================== ++ Fix 'dmsetup splitname -o' to not fail if used without '-c' switch (1.02.68). + Close open dmeventd FIFO file descriptors on exec (FD_CLOEXEC). + Add DM_DISABLE_UDEV environment variable to manage dev nodes by libdm only. + Automatically deactivate failed preloaded dm tree node. +diff --git a/tools/dmsetup.c b/tools/dmsetup.c +index 196c170..2dc3abd 100644 +--- a/tools/dmsetup.c ++++ b/tools/dmsetup.c +@@ -3749,9 +3749,6 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir) + return 0; + } + +- if (!_process_options(_string_args[OPTIONS_ARG])) +- return 0; +- + if (_switches[TABLE_ARG] && _switches[NOTABLE_ARG]) { + fprintf(stderr, "--table and --notable are incompatible.\n"); + return 0; +@@ -3824,6 +3821,11 @@ int main(int argc, char **argv) + if (!strcmp(cmd->name, "mangle")) + dm_set_name_mangling_mode(DM_STRING_MANGLING_NONE); + ++ if (!_process_options(_string_args[OPTIONS_ARG])) { ++ fprintf(stderr, "Couldn't process command line.\n"); ++ goto out; ++ } ++ + if (_switches[COLS_ARG]) { + if (!_report_init(cmd)) + goto out; diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-handling-of-reappeared-and-missing-pvs-in-lvmetad.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-handling-of-reappeared-and-missing-pvs-in-lvmetad.patch new file mode 100644 index 00000000000..446e50ae34b --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-handling-of-reappeared-and-missing-pvs-in-lvmetad.patch @@ -0,0 +1,64 @@ +commit 5bad6200b66259dde0c1cf3bd6295e65a5ade3c9 +Author: Peter Rajnoha +Date: Tue May 14 12:57:54 2013 +0200 + + lvm2-2_02_99-fix-handling-of-reappeared-and-missing-pvs-in-lvmetad.patch +--- + lib/cache/lvmetad.c | 8 +++++++- + lib/metadata/metadata.c | 4 ++-- + lib/metadata/metadata.h | 3 +++ + 3 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c +index a636f43..d8ad4dd 100644 +--- a/lib/cache/lvmetad.c ++++ b/lib/cache/lvmetad.c +@@ -354,14 +354,20 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna + if ((info = lvmcache_info_from_pvid((const char *)&pvl->pv->id, 0))) { + pvl->pv->label_sector = lvmcache_get_label(info)->sector; + pvl->pv->dev = lvmcache_device(info); ++ if (!pvl->pv->dev) ++ pvl->pv->status |= MISSING_PV; ++ else ++ check_reappeared_pv(vg, pvl->pv); + if (!lvmcache_fid_add_mdas_pv(info, fid)) { + vg = NULL; + goto_out; /* FIXME error path */ + } +- } /* else probably missing */ ++ } else ++ pvl->pv->status |= MISSING_PV; /* probably missing */ + } + + lvmcache_update_vg(vg, 0); ++ vg_mark_partial_lvs(vg, 1); + } + + out: +diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c +index c210a63..2cca93c 100644 +--- a/lib/metadata/metadata.c ++++ b/lib/metadata/metadata.c +@@ -2870,8 +2870,8 @@ int vg_missing_pv_count(const struct volume_group *vg) + return ret; + } + +-static void check_reappeared_pv(struct volume_group *correct_vg, +- struct physical_volume *pv) ++void check_reappeared_pv(struct volume_group *correct_vg, ++ struct physical_volume *pv) + { + struct pv_list *pvl; + +diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h +index 19bf742..630c4ca 100644 +--- a/lib/metadata/metadata.h ++++ b/lib/metadata/metadata.h +@@ -492,4 +492,7 @@ int is_mirror_image_removable(struct logical_volume *mimage_lv, void *baton); + uint64_t find_min_mda_size(struct dm_list *mdas); + char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tags); + ++void check_reappeared_pv(struct volume_group *correct_vg, ++ struct physical_volume *pv); ++ + #endif diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-lv_is_active-in-lvcreate.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-lv_is_active-in-lvcreate.patch new file mode 100644 index 00000000000..3b2281b1f7e --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-lv_is_active-in-lvcreate.patch @@ -0,0 +1,44 @@ +commit 191de7c40463b04ef80b424982221784df0a99ed +Author: Peter Rajnoha +Date: Tue May 14 11:02:39 2013 +0200 + + lvm2-2_02_99-fix-lv_is_active-in-lvcreate.patch +--- + lib/metadata/lv_manip.c | 10 ++-------- + test/shell/lvcreate-usage.sh | 2 ++ + 2 files changed, 4 insertions(+), 8 deletions(-) + +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index a59e03f..557df58 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -4348,14 +4348,8 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l + log_warn("WARNING: See global/mirror_segtype_default in lvm.conf."); + } + +- if (!lv_is_active(org)) { +- log_error("Check for existence of active snapshot " +- "origin '%s' failed.", org->name); +- return NULL; +- } +- origin_active = 1; +- +- if (vg_is_clustered(vg) && ++ if ((origin_active = lv_is_active(org)) && ++ vg_is_clustered(vg) && + !lv_is_active_exclusive_locally(org)) { + log_error("%s must be active exclusively to" + " create snapshot", org->name); +diff --git a/test/shell/lvcreate-usage.sh b/test/shell/lvcreate-usage.sh +index ddde401..c9c906a 100644 +--- a/test/shell/lvcreate-usage.sh ++++ b/test/shell/lvcreate-usage.sh +@@ -64,6 +64,8 @@ lvcreate -l1 -n $lv3 $vg + not lvcreate -l1 -n $lv4 $vg + + lvremove -ff $vg/$lv3 ++# check snapshot of inactive origin ++lvchange -an $vg/$lv1 + lvcreate -l1 -s -n $lv3 $vg/$lv1 + not lvcreate -l1 -n $lv4 $vg + not lvcreate -l1 -m1 -n $lv4 $vg diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-possible-deadlock-in-lvmetad-for-parallel-update-and-query.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-possible-deadlock-in-lvmetad-for-parallel-update-and-query.patch new file mode 100644 index 00000000000..62f4307bb82 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-possible-deadlock-in-lvmetad-for-parallel-update-and-query.patch @@ -0,0 +1,35 @@ +commit 509ba58eaa537a8db2e0bd41d8c56c52a68e8512 +Author: Peter Rajnoha +Date: Tue May 14 11:04:30 2013 +0200 + + lvm2-2_02_99-fix-possible-deadlock-in-lvmetad-for-parallel-update-and-query.patch +--- + WHATS_NEW | 1 + + daemons/lvmetad/lvmetad-core.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 25e07ee..4728466 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Fix possible deadlock when querying and updating lvmetad at the same time. + Avoid a global lock in pvs when lvmetad is in use. + Fix crash in pvscan --cache -aay triggered by non-mda PV. + Fix lvm2app to return all property sizes in bytes. +diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c +index 0a1c884..3f417da 100644 +--- a/daemons/lvmetad/lvmetad-core.c ++++ b/daemons/lvmetad/lvmetad-core.c +@@ -675,8 +675,8 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid + + lock_vgid_to_metadata(s); + old = dm_hash_lookup(s->vgid_to_metadata, _vgid); +- lock_vg(s, _vgid); + unlock_vgid_to_metadata(s); ++ lock_vg(s, _vgid); + + seq = dm_config_find_int(metadata, "metadata/seqno", -1); + diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-possible-race-in-lvmetad-remove_metadata.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-possible-race-in-lvmetad-remove_metadata.patch new file mode 100644 index 00000000000..5ca87f52ad2 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-possible-race-in-lvmetad-remove_metadata.patch @@ -0,0 +1,54 @@ +commit 8f17dc8027f1d9fd188468c26eb8c0a9957cc9cb +Author: Peter Rajnoha +Date: Tue May 14 11:04:52 2013 +0200 + + lvm2-2_02_99-fix-possible-race-in-lvmetad-remove_metadata.patch +--- + WHATS_NEW | 1 + + daemons/lvmetad/lvmetad-core.c | 14 +++++++++----- + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 4728466..20a8125 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Fix possible race while removing metadata from lvmetad. + Fix possible deadlock when querying and updating lvmetad at the same time. + Avoid a global lock in pvs when lvmetad is in use. + Fix crash in pvscan --cache -aay triggered by non-mda PV. +diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c +index 3f417da..fed9296 100644 +--- a/daemons/lvmetad/lvmetad-core.c ++++ b/daemons/lvmetad/lvmetad-core.c +@@ -605,19 +605,23 @@ static int remove_metadata(lvmetad_state *s, const char *vgid, int update_pvids) + lock_vgid_to_metadata(s); + old = dm_hash_lookup(s->vgid_to_metadata, vgid); + oldname = dm_hash_lookup(s->vgid_to_vgname, vgid); +- unlock_vgid_to_metadata(s); + +- if (!old) ++ if (!old) { ++ unlock_vgid_to_metadata(s); + return 0; ++ } ++ + assert(oldname); + +- if (update_pvids) +- /* FIXME: What should happen when update fails */ +- update_pvid_to_vgid(s, old, "#orphan", 0); + /* need to update what we have since we found a newer version */ + dm_hash_remove(s->vgid_to_metadata, vgid); + dm_hash_remove(s->vgid_to_vgname, vgid); + dm_hash_remove(s->vgname_to_vgid, oldname); ++ unlock_vgid_to_metadata(s); ++ ++ if (update_pvids) ++ /* FIXME: What should happen when update fails */ ++ update_pvid_to_vgid(s, old, "#orphan", 0); + dm_config_destroy(old); + return 1; + } diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-premature-dm-version-checking-which-caused-useless-mapper-control-access.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-premature-dm-version-checking-which-caused-useless-mapper-control-access.patch new file mode 100644 index 00000000000..f565786eff9 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-fix-premature-dm-version-checking-which-caused-useless-mapper-control-access.patch @@ -0,0 +1,182 @@ +commit 811db05e50b042c7ce3dc3ca9cfd3eccac464caa +Author: Peter Rajnoha +Date: Tue May 14 11:22:58 2013 +0200 + + lvm2-2_02_99-fix-premature-dm-version-checking-which-caused-useless-mapper-control-access.patch +--- + WHATS_NEW | 1 + + lib/activate/dev_manager.c | 58 +++++++++++++++++++++++++++++++++++++++++++--- + lib/commands/toolcontext.c | 46 +++++++----------------------------- + 3 files changed, 64 insertions(+), 41 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 8516f40..eb7897d 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Fix premature DM version checking which caused useless mapper/control access. + Recognize DM_DISABLE_UDEV environment variable for a complete fallback. + Do not verify udev operations if --noudevsync command option is used. + Fix blkdeactivate to handle nested mountpoints and mangled mount paths. +diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c +index 31c1c27..7abd43b 100644 +--- a/lib/activate/dev_manager.c ++++ b/lib/activate/dev_manager.c +@@ -1016,6 +1016,58 @@ int dev_manager_mknodes(const struct logical_volume *lv) + return r; + } + ++#ifdef UDEV_SYNC_SUPPORT ++/* ++ * Until the DM_UEVENT_GENERATED_FLAG was introduced in kernel patch ++ * 856a6f1dbd8940e72755af145ebcd806408ecedd ++ * some operations could not be performed by udev, requiring our fallback code. ++ */ ++static int _dm_driver_has_stable_udev_support(void) ++{ ++ char vsn[80]; ++ unsigned maj, min, patchlevel; ++ ++ return driver_version(vsn, sizeof(vsn)) && ++ (sscanf(vsn, "%u.%u.%u", &maj, &min, &patchlevel) == 3) && ++ (maj == 4 ? min >= 18 : maj > 4); ++} ++ ++static int _check_udev_fallback(struct cmd_context *cmd) ++{ ++ struct config_info *settings = &cmd->current_settings; ++ ++ if (settings->udev_fallback != -1) ++ goto out; ++ ++ /* ++ * Use udev fallback automatically in case udev ++ * is disabled via DM_DISABLE_UDEV environment ++ * variable or udev rules are switched off. ++ */ ++ settings->udev_fallback = !settings->udev_rules ? 1 : ++ find_config_tree_bool(cmd, "activation/verify_udev_operations", ++ DEFAULT_VERIFY_UDEV_OPERATIONS); ++ ++ /* Do not rely fully on udev if the udev support is known to be incomplete. */ ++ if (!settings->udev_fallback && !_dm_driver_has_stable_udev_support()) { ++ log_very_verbose("Kernel driver has incomplete udev support so " ++ "LVM will check and perform some operations itself."); ++ settings->udev_fallback = 1; ++ } ++out: ++ return settings->udev_fallback; ++} ++ ++#else /* UDEV_SYNC_SUPPORT */ ++ ++static int _check_udev_fallback(struct cmd_context *cmd) ++{ ++ /* We must use old node/symlink creation code if not compiled with udev support at all! */ ++ return cmd->current_settings.udev_fallback = 1; ++} ++ ++#endif /* UDEV_SYNC_SUPPORT */ ++ + static uint16_t _get_udev_flags(struct dev_manager *dm, struct logical_volume *lv, + const char *layer) + { +@@ -1025,7 +1077,7 @@ static uint16_t _get_udev_flags(struct dev_manager *dm, struct logical_volume *l + * Instruct also libdevmapper to disable udev + * fallback in accordance to LVM2 settings. + */ +- if (!dm->cmd->current_settings.udev_fallback) ++ if (!_check_udev_fallback(dm->cmd)) + udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK; + + /* +@@ -2036,7 +2088,7 @@ static int _create_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root + int r = 1; + + /* Nothing to do if udev fallback is disabled. */ +- if (!dm->cmd->current_settings.udev_fallback) { ++ if (!_check_udev_fallback(dm->cmd)) { + fs_set_create(); + return 1; + } +@@ -2084,7 +2136,7 @@ static int _remove_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root + int r = 1; + + /* Nothing to do if udev fallback is disabled. */ +- if (!dm->cmd->current_settings.udev_fallback) ++ if (!_check_udev_fallback(dm->cmd)) + return 1; + + while ((child = dm_tree_next_child(&handle, root, 0))) { +diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c +index 80d0f3e..61d5c26 100644 +--- a/lib/commands/toolcontext.c ++++ b/lib/commands/toolcontext.c +@@ -226,23 +226,6 @@ static int _check_disable_udev(const char *msg) { + return 0; + } + +-#ifdef UDEV_SYNC_SUPPORT +-/* +- * Until the DM_UEVENT_GENERATED_FLAG was introduced in kernel patch +- * 856a6f1dbd8940e72755af145ebcd806408ecedd +- * some operations could not be performed by udev, requiring our fallback code. +- */ +-static int _dm_driver_has_stable_udev_support(void) +-{ +- char vsn[80]; +- unsigned maj, min, patchlevel; +- +- return driver_version(vsn, sizeof(vsn)) && +- (sscanf(vsn, "%u.%u.%u", &maj, &min, &patchlevel) == 3) && +- (maj == 4 ? min >= 18 : maj > 4); +-} +-#endif +- + static int _process_config(struct cmd_context *cmd) + { + mode_t old_umask; +@@ -341,33 +324,20 @@ static int _process_config(struct cmd_context *cmd) + cmd->default_settings.udev_sync = udev_disabled ? 0 : + find_config_tree_int(cmd, "activation/udev_sync", DEFAULT_UDEV_SYNC); + ++ /* ++ * Set udev_fallback lazily on first use since it requires ++ * checking DM driver version which is an extra ioctl! ++ * This also prevents unnecessary use of mapper/control. ++ * If udev is disabled globally, set fallback mode immediately. ++ */ ++ cmd->default_settings.udev_fallback = udev_disabled ? 1 : -1; ++ + init_retry_deactivation(find_config_tree_int(cmd, "activation/retry_deactivation", + DEFAULT_RETRY_DEACTIVATION)); + + init_activation_checks(find_config_tree_int(cmd, "activation/checks", + DEFAULT_ACTIVATION_CHECKS)); + +-#ifdef UDEV_SYNC_SUPPORT +- /* +- * Use udev fallback automatically in case udev +- * is disabled via DM_DISABLE_UDEV environment +- * variable or udev rules are switched off. +- */ +- cmd->default_settings.udev_fallback = !cmd->default_settings.udev_rules || udev_disabled ? 1 : +- find_config_tree_int(cmd, "activation/verify_udev_operations", DEFAULT_VERIFY_UDEV_OPERATIONS); +- +- /* Do not rely fully on udev if the udev support is known to be incomplete. */ +- if (!cmd->default_settings.udev_fallback && !_dm_driver_has_stable_udev_support()) { +- log_very_verbose("Kernel driver has incomplete udev support so " +- "LVM will check and perform some operations itself."); +- cmd->default_settings.udev_fallback = 1; +- } +- +-#else +- /* We must use old node/symlink creation code if not compiled with udev support at all! */ +- cmd->default_settings.udev_fallback = 1; +-#endif +- + cmd->use_linear_target = find_config_tree_int(cmd, + "activation/use_linear_target", + DEFAULT_USE_LINEAR_TARGET); diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-hardcode-use_lvmetad0-if-cluster-locking-used-and-issue-warning-msg.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-hardcode-use_lvmetad0-if-cluster-locking-used-and-issue-warning-msg.patch new file mode 100644 index 00000000000..450196ea33e --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-hardcode-use_lvmetad0-if-cluster-locking-used-and-issue-warning-msg.patch @@ -0,0 +1,58 @@ +diff --git a/WHATS_NEW b/WHATS_NEW +index c0ae3df..5887ec7 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,3 +1,7 @@ ++Version 2.02.99 - ++=================================== ++ Hardcode use_lvmetad=0 if cluster locking used and issue a warning msg. ++ + Version 2.02.98 - 15th October 2012 + =================================== + Switch from DEBUG() to DEBUGLOG() in lvmetad as -DDEBUG is already used. +diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c +index d7f8ece..eb1a90b 100644 +--- a/lib/commands/toolcontext.c ++++ b/lib/commands/toolcontext.c +@@ -413,7 +413,15 @@ static int _process_config(struct cmd_context *cmd) + lvmetad_set_socket(lvmetad_socket); + cn = find_config_tree_node(cmd, "devices/global_filter"); + lvmetad_set_token(cn ? cn->v : NULL); +- lvmetad_set_active(find_config_tree_int(cmd, "global/use_lvmetad", 1)); ++ ++ if (find_config_tree_int(cmd, "global/locking_type", 1) == 3 && ++ find_config_tree_int(cmd, "global/use_lvmetad", 1)) { ++ log_warn("WARNING: configuration setting use_lvmetad overriden to 0 due to locking_type 3. " ++ "Clustered environment not supported by lvmetad yet."); ++ lvmetad_set_active(0); ++ } else ++ lvmetad_set_active(find_config_tree_int(cmd, "global/use_lvmetad", 1)); ++ + lvmetad_init(cmd); + + return 1; +diff --git a/test/shell/lvmetad-no-cluster.sh b/test/shell/lvmetad-no-cluster.sh +new file mode 100644 +index 0000000..db68e77 +--- /dev/null ++++ b/test/shell/lvmetad-no-cluster.sh +@@ -0,0 +1,19 @@ ++#!/bin/sh ++# Copyright (C) 2012 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 ++ ++. lib/test ++ ++test -e LOCAL_CLVMD || skip ++aux prepare_vg 2 ++aux prepare_lvmetad ++vgs -vv 2> errs ++cat errs ++grep 'use_lvmetad' errs diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-init-lvmetad-lazily-to-avoid-early-socket-access-on-config-overrides.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-init-lvmetad-lazily-to-avoid-early-socket-access-on-config-overrides.patch new file mode 100644 index 00000000000..9709d34b242 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-init-lvmetad-lazily-to-avoid-early-socket-access-on-config-overrides.patch @@ -0,0 +1,111 @@ +diff --git a/WHATS_NEW b/WHATS_NEW +index 5887ec7..d0e0cd4 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Initialize lvmetad lazily to avoid early socket access on config overrides. + Hardcode use_lvmetad=0 if cluster locking used and issue a warning msg. + + Version 2.02.98 - 15th October 2012 +diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c +index 6a374ac..72e07fd 100644 +--- a/lib/cache/lvmetad.c ++++ b/lib/cache/lvmetad.c +@@ -33,7 +33,8 @@ static struct cmd_context *_lvmetad_cmd = NULL; + + void lvmetad_disconnect(void) + { +- daemon_close(_lvmetad); ++ if (_lvmetad_connected) ++ daemon_close(_lvmetad); + _lvmetad_connected = 0; + _lvmetad_cmd = NULL; + } +@@ -41,19 +42,25 @@ void lvmetad_disconnect(void) + void lvmetad_init(struct cmd_context *cmd) + { + if (!_lvmetad_use && !access(LVMETAD_PIDFILE, F_OK)) +- log_warn("WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!"); ++ log_warn("WARNING: lvmetad is running but disabled." ++ " Restart lvmetad before enabling it!"); ++ _lvmetad_cmd = cmd; ++} ++ ++static void _lvmetad_connect() ++{ + if (_lvmetad_use && _lvmetad_socket && !_lvmetad_connected) { + assert(_lvmetad_socket); + _lvmetad = lvmetad_open(_lvmetad_socket); +- if (_lvmetad.socket_fd >= 0 && !_lvmetad.error) { ++ if (_lvmetad.socket_fd >= 0 && !_lvmetad.error) + _lvmetad_connected = 1; +- _lvmetad_cmd = cmd; +- } + } + } + + void lvmetad_warning(void) + { ++ if (!_lvmetad_connected) ++ _lvmetad_connect(); + if (_lvmetad_use && (_lvmetad.socket_fd < 0 || _lvmetad.error)) + log_warn("WARNING: Failed to connect to lvmetad: %s. Falling back to internal scanning.", + strerror(_lvmetad.error)); +@@ -61,7 +68,11 @@ void lvmetad_warning(void) + + int lvmetad_active(void) + { +- return _lvmetad_use && _lvmetad_connected; ++ if (!_lvmetad_use) ++ return 0; ++ if (!_lvmetad_connected) ++ _lvmetad_connect(); ++ return _lvmetad_connected; + } + + void lvmetad_set_active(int active) +@@ -873,6 +884,11 @@ int lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler) + char *future_token; + int was_silent; + ++ if (!lvmetad_active()) { ++ log_error("Cannot proceed since lvmetad is not active."); ++ return 0; ++ } ++ + if (!(iter = dev_iter_create(cmd->lvmetad_filter, 1))) { + log_error("dev_iter creation failed"); + return 0; +diff --git a/test/shell/lvmetad-override.sh b/test/shell/lvmetad-override.sh +new file mode 100644 +index 0000000..3fb281a +--- /dev/null ++++ b/test/shell/lvmetad-override.sh +@@ -0,0 +1,25 @@ ++#!/bin/sh ++# Copyright (C) 2012 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 ++ ++. lib/test ++ ++test -e LOCAL_LVMETAD || skip ++aux prepare_pvs 2 ++ ++vgcreate $vg1 $dev1 $dev2 ++lvchange -ay $vg1 2>&1 | not grep "Failed to connect" ++kill $(cat LOCAL_LVMETAD) ++lvchange -ay $vg1 2>&1 | grep "Failed to connect" ++lvchange -ay $vg1 --sysinit 2>&1 | not grep "Failed to connect" ++lvchange -ay $vg1 --config 'global { use_lvmetad = 0 }' 2>&1 | not grep "Failed to connect" ++aux lvmconf "global/use_lvmetad = 0" ++lvchange -ay $vg1 --config 'global { use_lvmetad = 1 }' 2>&1 | grep "Failed to connect" ++ diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-lvmetad-fix-a-race-in-metadata-update.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-lvmetad-fix-a-race-in-metadata-update.patch new file mode 100644 index 00000000000..9e5a178b9f1 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-lvmetad-fix-a-race-in-metadata-update.patch @@ -0,0 +1,86 @@ +commit 98c5eb308690d990b957012db9d48b6722ea93cb +Author: Peter Rajnoha +Date: Tue May 14 12:47:24 2013 +0200 + + lvm2-2_02_99-lvmetad-fix-a-race-in-metadata-update.patch +--- + WHATS_NEW | 1 + + daemons/lvmetad/lvmetad-core.c | 21 +++++++++++++-------- + 2 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 20a8125..35c5e43 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Fix a crash-inducing race condition in lvmetad while updating metadata. + Fix possible race while removing metadata from lvmetad. + Fix possible deadlock when querying and updating lvmetad at the same time. + Avoid a global lock in pvs when lvmetad is in use. +diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c +index fed9296..1f855a7 100644 +--- a/daemons/lvmetad/lvmetad-core.c ++++ b/daemons/lvmetad/lvmetad-core.c +@@ -450,7 +450,8 @@ static response vg_lookup(lvmetad_state *s, request r) + + DEBUGLOG(s, "vg_lookup: updated uuid = %s, name = %s", uuid, name); + +- if (!uuid) ++ /* Check the name here. */ ++ if (!uuid || !name) + return reply_unknown("VG not found"); + + cft = lock_vg(s, uuid); +@@ -679,16 +680,14 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid + + lock_vgid_to_metadata(s); + old = dm_hash_lookup(s->vgid_to_metadata, _vgid); ++ oldname = dm_hash_lookup(s->vgid_to_vgname, _vgid); + unlock_vgid_to_metadata(s); + lock_vg(s, _vgid); + + seq = dm_config_find_int(metadata, "metadata/seqno", -1); + +- if (old) { ++ if (old) + haveseq = dm_config_find_int(old->root, "metadata/seqno", -1); +- oldname = dm_hash_lookup(s->vgid_to_vgname, _vgid); +- assert(oldname); +- } + + if (seq < 0) + goto out; +@@ -740,7 +739,7 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid + if (haveseq >= 0 && haveseq < seq) { + INFO(s, "Updating metadata for %s at %d to %d", _vgid, haveseq, seq); + /* temporarily orphan all of our PVs */ +- remove_metadata(s, vgid, 1); ++ update_pvid_to_vgid(s, old, "#orphan", 0); + } + + lock_vgid_to_metadata(s); +@@ -750,14 +749,20 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid + dm_hash_insert(s->vgid_to_metadata, vgid, cft) && + dm_hash_insert(s->vgid_to_vgname, vgid, cfgname) && + dm_hash_insert(s->vgname_to_vgid, name, (void*) vgid)) ? 1 : 0; ++ ++ if (retval && oldname && strcmp(name, oldname)) ++ dm_hash_remove(s->vgname_to_vgid, oldname); ++ ++ if (haveseq >= 0 && haveseq < seq) ++ dm_config_destroy(old); ++ + unlock_vgid_to_metadata(s); + + if (retval) +- /* FIXME: What should happen when update fails */ + retval = update_pvid_to_vgid(s, cft, vgid, 1); + + unlock_pvid_to_vgid(s); +-out: ++out: /* FIXME: We should probably abort() on partial failures. */ + if (!retval && cft) + dm_config_destroy(cft); + unlock_vg(s, _vgid); diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-properly-set-cookie_set-var-on-dm_task_set_cookie-call.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-properly-set-cookie_set-var-on-dm_task_set_cookie-call.patch new file mode 100644 index 00000000000..1608ed9fafa --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-properly-set-cookie_set-var-on-dm_task_set_cookie-call.patch @@ -0,0 +1,32 @@ +diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM +index 2d0b05c..3f8d9c9 100644 +--- a/WHATS_NEW_DM ++++ b/WHATS_NEW_DM +@@ -1,3 +1,7 @@ ++Version 1.02.78 - ++=================================== ++ Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled. ++ + Version 1.02.77 - 15th October 2012 + =================================== + Support unmount of thin volumes from pool above thin pool threshold. +diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c +index b8533ed..afdac89 100644 +--- a/libdm/libdm-common.c ++++ b/libdm/libdm-common.c +@@ -1838,6 +1838,7 @@ int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) + if (dm_cookie_supported()) + dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT; + *cookie = 0; ++ dmt->cookie_set = 1; + + return 1; + } +@@ -2207,6 +2208,7 @@ int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) + + if (!dm_udev_get_sync_support()) { + *cookie = 0; ++ dmt->cookie_set = 1; + return 1; + } + diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-python-implement-proper-refcounting-for-parent-objects.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-python-implement-proper-refcounting-for-parent-objects.patch new file mode 100644 index 00000000000..c498492aafc --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-python-implement-proper-refcounting-for-parent-objects.patch @@ -0,0 +1,470 @@ +commit 0e47639a44e1630250ea10643f5a440281edfdce +Author: Andy Grover +Date: Wed Oct 17 12:55:25 2012 -0700 + + python-lvm: Implement proper refcounting for parent objects + + Our object nesting: + + lib -> VG -> LV -> lvseg + -> PV -> pvseg + + Implement refcounting and checks to ensure parent objects are not + dealloced before their children. Also ensure calls to self or child's + methods are handled cleanly for objects that have been closed or removed. + + Ensure all functions that are object methods have a first parameter named + 'self', for consistency + + Rename local vars that reference a Python object to '*obj', in order to + differentiate from liblvm handles + + Fix a misspelled pv method name + + Signed-off-by: Andy Grover +--- + python/liblvm.c | 152 +++++++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 106 insertions(+), 46 deletions(-) + +diff --git a/python/liblvm.c b/python/liblvm.c +index 8a73ced..024d769 100644 +--- a/python/liblvm.c ++++ b/python/liblvm.c +@@ -35,21 +35,25 @@ typedef struct { + typedef struct { + PyObject_HEAD + lv_t lv; /* lv handle */ ++ vgobject *parent_vgobj; + } lvobject; + + typedef struct { + PyObject_HEAD + pv_t pv; /* pv handle */ ++ vgobject *parent_vgobj; + } pvobject; + + typedef struct { + PyObject_HEAD + lvseg_t lv_seg; /* lv segment handle */ ++ lvobject *parent_lvobj; + } lvsegobject; + + typedef struct { + PyObject_HEAD + pvseg_t pv_seg; /* pv segment handle */ ++ pvobject *parent_pvobj; + } pvsegobject; + + static PyTypeObject LibLVMvgType; +@@ -347,6 +351,7 @@ liblvm_vg_dealloc(vgobject *self) + + #define VG_VALID(vgobject) \ + do { \ ++ LVM_VALID(); \ + if (!vgobject->vg) { \ + PyErr_SetString(PyExc_UnboundLocalError, "VG object invalid"); \ + return NULL; \ +@@ -785,18 +790,18 @@ liblvm_lvm_vg_set_extent_size(vgobject *self, PyObject *args) + } + + static PyObject * +-liblvm_lvm_vg_list_lvs(vgobject *vg) ++liblvm_lvm_vg_list_lvs(vgobject *self) + { + struct dm_list *lvs; + struct lvm_lv_list *lvl; + PyObject * pytuple; +- lvobject * self; ++ lvobject * lvobj; + int i = 0; + +- VG_VALID(vg); ++ VG_VALID(self); + + /* unlike other LVM api calls, if there are no results, we get NULL */ +- lvs = lvm_vg_list_lvs(vg->vg); ++ lvs = lvm_vg_list_lvs(self->vg); + if (!lvs) + return Py_BuildValue("()"); + +@@ -806,14 +811,17 @@ liblvm_lvm_vg_list_lvs(vgobject *vg) + + dm_list_iterate_items(lvl, lvs) { + /* Create and initialize the object */ +- self = PyObject_New(lvobject, &LibLVMlvType); +- if (!self) { ++ lvobj = PyObject_New(lvobject, &LibLVMlvType); ++ if (!lvobj) { + Py_DECREF(pytuple); + return NULL; + } + +- self->lv = lvl->lv; +- PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); ++ lvobj->parent_vgobj = self; ++ Py_INCREF(lvobj->parent_vgobj); ++ ++ lvobj->lv = lvl->lv; ++ PyTuple_SET_ITEM(pytuple, i, (PyObject *) lvobj); + i++; + } + +@@ -849,49 +857,53 @@ liblvm_lvm_vg_get_tags(vgobject *self) + } + + static PyObject * +-liblvm_lvm_vg_create_lv_linear(vgobject *vg, PyObject *args) ++liblvm_lvm_vg_create_lv_linear(vgobject *self, PyObject *args) + { + const char *vgname; + uint64_t size; +- lvobject *self; ++ lvobject *lvobj; + +- VG_VALID(vg); ++ VG_VALID(self); + + if (!PyArg_ParseTuple(args, "sl", &vgname, &size)) { + return NULL; + } + +- if ((self = PyObject_New(lvobject, &LibLVMlvType)) == NULL) ++ if ((lvobj = PyObject_New(lvobject, &LibLVMlvType)) == NULL) + return NULL; + +- if ((self->lv = lvm_vg_create_lv_linear(vg->vg, vgname, size))== NULL) { ++ if ((lvobj->lv = lvm_vg_create_lv_linear(self->vg, vgname, size)) == NULL) { + PyErr_SetObject(LibLVMError, liblvm_get_last_error()); +- Py_DECREF(self); ++ Py_DECREF(lvobj); + return NULL; + } + +- return (PyObject *)self; ++ lvobj->parent_vgobj = self; ++ Py_INCREF(lvobj->parent_vgobj); ++ ++ return (PyObject *)lvobj; + } + + static void + liblvm_lv_dealloc(lvobject *self) + { ++ Py_DECREF(self->parent_vgobj); + PyObject_Del(self); + } + + static PyObject * +-liblvm_lvm_vg_list_pvs(vgobject *vg) ++liblvm_lvm_vg_list_pvs(vgobject *self) + { + struct dm_list *pvs; + struct lvm_pv_list *pvl; + PyObject * pytuple; +- pvobject * self; ++ pvobject * pvobj; + int i = 0; + +- VG_VALID(vg); ++ VG_VALID(self); + + /* unlike other LVM api calls, if there are no results, we get NULL */ +- pvs = lvm_vg_list_pvs(vg->vg); ++ pvs = lvm_vg_list_pvs(self->vg); + if (!pvs) + return Py_BuildValue("()"); + +@@ -901,14 +913,17 @@ liblvm_lvm_vg_list_pvs(vgobject *vg) + + dm_list_iterate_items(pvl, pvs) { + /* Create and initialize the object */ +- self = PyObject_New(pvobject, &LibLVMpvType); +- if (!self) { ++ pvobj = PyObject_New(pvobject, &LibLVMpvType); ++ if (!pvobj) { + Py_DECREF(pytuple); + return NULL; + } + +- self->pv = pvl->pv; +- PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); ++ pvobj->parent_vgobj = self; ++ Py_INCREF(pvobj->parent_vgobj); ++ ++ pvobj->pv = pvl->pv; ++ PyTuple_SET_ITEM(pytuple, i, (PyObject *) pvobj); + i++; + } + +@@ -922,7 +937,7 @@ static PyObject * + liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) + { + const char *id; +- lvobject *rc; ++ lvobject *lvobj; + lv_t lv = NULL; + + VG_VALID(self); +@@ -936,13 +951,16 @@ liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) + return NULL; + } + +- rc = PyObject_New(lvobject, &LibLVMlvType); +- if (!rc) { ++ lvobj = PyObject_New(lvobject, &LibLVMlvType); ++ if (!lvobj) { + return NULL; + } + +- rc->lv = lv; +- return (PyObject *)rc; ++ lvobj->parent_vgobj = self; ++ Py_INCREF(lvobj->parent_vgobj); ++ ++ lvobj->lv = lv; ++ return (PyObject *)lvobj; + } + + static PyObject * +@@ -980,6 +998,7 @@ liblvm_lvm_pv_from_N(vgobject *self, PyObject *arg, pv_fetch_by_N method) + return NULL; + } + ++ Py_INCREF(self); + rc->pv = pv; + return (PyObject *)rc; + } +@@ -999,6 +1018,7 @@ liblvm_lvm_pv_from_uuid(vgobject *self, PyObject *arg) + static void + liblvm_pv_dealloc(pvobject *self) + { ++ Py_DECREF(self->parent_vgobj); + PyObject_Del(self); + } + +@@ -1006,6 +1026,7 @@ liblvm_pv_dealloc(pvobject *self) + + #define LV_VALID(lvobject) \ + do { \ ++ VG_VALID(lvobject->parent_vgobj); \ + if (!lvobject->lv) { \ + PyErr_SetString(PyExc_UnboundLocalError, "LV object invalid"); \ + return NULL; \ +@@ -1242,17 +1263,17 @@ liblvm_lvm_lv_resize(lvobject *self, PyObject *args) + } + + static PyObject * +-liblvm_lvm_lv_list_lvsegs(lvobject *lv) ++liblvm_lvm_lv_list_lvsegs(lvobject *self) + { + struct dm_list *lvsegs; + lvseg_list_t *lvsegl; + PyObject * pytuple; +- lvsegobject *self; ++ lvsegobject *lvsegobj; + int i = 0; + +- LV_VALID(lv); ++ LV_VALID(self); + +- lvsegs = lvm_lv_list_lvsegs(lv->lv); ++ lvsegs = lvm_lv_list_lvsegs(self->lv); + if (!lvsegs) { + return Py_BuildValue("()"); + } +@@ -1263,14 +1284,17 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) + + dm_list_iterate_items(lvsegl, lvsegs) { + /* Create and initialize the object */ +- self = PyObject_New(lvsegobject, &LibLVMlvsegType); +- if (!self) { ++ lvsegobj = PyObject_New(lvsegobject, &LibLVMlvsegType); ++ if (!lvsegobj) { + Py_DECREF(pytuple); + return NULL; + } + +- self->lv_seg = lvsegl->lvseg; +- PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); ++ lvsegobj->parent_lvobj = self; ++ Py_INCREF(lvsegobj->parent_lvobj); ++ ++ lvsegobj->lv_seg = lvsegl->lvseg; ++ PyTuple_SET_ITEM(pytuple, i, (PyObject *) lvsegobj); + i++; + } + +@@ -1281,7 +1305,8 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) + + #define PV_VALID(pvobject) \ + do { \ +- if (!pvobject->pv || !libh) { \ ++ VG_VALID(pvobject->parent_vgobj); \ ++ if (!pvobject->pv) { \ + PyErr_SetString(PyExc_UnboundLocalError, "PV object invalid"); \ + return NULL; \ + } \ +@@ -1290,18 +1315,24 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) + static PyObject * + liblvm_lvm_pv_get_name(pvobject *self) + { ++ PV_VALID(self); ++ + return Py_BuildValue("s", lvm_pv_get_name(self->pv)); + } + + static PyObject * + liblvm_lvm_pv_get_uuid(pvobject *self) + { ++ PV_VALID(self); ++ + return Py_BuildValue("s", lvm_pv_get_uuid(self->pv)); + } + + static PyObject * + liblvm_lvm_pv_get_mda_count(pvobject *self) + { ++ PV_VALID(self); ++ + return Py_BuildValue("l", lvm_pv_get_mda_count(self->pv)); + } + +@@ -1323,18 +1354,24 @@ liblvm_lvm_pv_get_property(pvobject *self, PyObject *args) + static PyObject * + liblvm_lvm_pv_get_dev_size(pvobject *self) + { ++ PV_VALID(self); ++ + return Py_BuildValue("l", lvm_pv_get_dev_size(self->pv)); + } + + static PyObject * + liblvm_lvm_pv_get_size(pvobject *self) + { ++ PV_VALID(self); ++ + return Py_BuildValue("l", lvm_pv_get_size(self->pv)); + } + + static PyObject * + liblvm_lvm_pv_get_free(pvobject *self) + { ++ PV_VALID(self); ++ + return Py_BuildValue("l", lvm_pv_get_free(self->pv)); + } + +@@ -1344,6 +1381,8 @@ liblvm_lvm_pv_resize(pvobject *self, PyObject *args) + uint64_t new_size; + int rval; + ++ PV_VALID(self); ++ + if (!PyArg_ParseTuple(args, "l", &new_size)) { + return NULL; + } +@@ -1358,17 +1397,17 @@ liblvm_lvm_pv_resize(pvobject *self, PyObject *args) + } + + static PyObject * +-liblvm_lvm_lv_list_pvsegs(pvobject *pv) ++liblvm_lvm_pv_list_pvsegs(pvobject *self) + { + struct dm_list *pvsegs; + pvseg_list_t *pvsegl; + PyObject *pytuple; +- pvsegobject *self; ++ pvsegobject *pvsegobj; + int i = 0; + +- PV_VALID(pv); ++ PV_VALID(self); + +- pvsegs = lvm_pv_list_pvsegs(pv->pv); ++ pvsegs = lvm_pv_list_pvsegs(self->pv); + if (!pvsegs) { + return Py_BuildValue("()"); + } +@@ -1379,14 +1418,17 @@ liblvm_lvm_lv_list_pvsegs(pvobject *pv) + + dm_list_iterate_items(pvsegl, pvsegs) { + /* Create and initialize the object */ +- self = PyObject_New(pvsegobject, &LibLVMpvsegType); +- if (!self) { ++ pvsegobj = PyObject_New(pvsegobject, &LibLVMpvsegType); ++ if (!pvsegobj) { + Py_DECREF(pytuple); + return NULL; + } + +- self->pv_seg = pvsegl->pvseg; +- PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); ++ pvsegobj->parent_pvobj = self; ++ Py_INCREF(pvsegobj->parent_pvobj); ++ ++ pvsegobj->pv_seg = pvsegl->pvseg; ++ PyTuple_SET_ITEM(pytuple, i, (PyObject *) pvsegobj); + i++; + } + +@@ -1395,9 +1437,16 @@ liblvm_lvm_lv_list_pvsegs(pvobject *pv) + + /* LV seg methods */ + ++/* ++ * No way to close/destroy an lvseg, just need to make sure parents are ++ * still good ++ */ ++#define LVSEG_VALID(lvsegobject) LV_VALID(lvsegobject->parent_lvobj) ++ + static void + liblvm_lvseg_dealloc(lvsegobject *self) + { ++ Py_DECREF(self->parent_lvobj); + PyObject_Del(self); + } + +@@ -1407,6 +1456,8 @@ liblvm_lvm_lvseg_get_property(lvsegobject *self, PyObject *args) + const char *name; + struct lvm_property_value prop_value; + ++ LVSEG_VALID(self); ++ + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + +@@ -1416,9 +1467,16 @@ liblvm_lvm_lvseg_get_property(lvsegobject *self, PyObject *args) + + /* PV seg methods */ + ++/* ++ * No way to close/destroy a pvseg, just need to make sure parents are ++ * still good ++ */ ++#define PVSEG_VALID(pvsegobject) PV_VALID(pvsegobject->parent_pvobj) ++ + static void + liblvm_pvseg_dealloc(pvsegobject *self) + { ++ Py_DECREF(self->parent_pvobj); + PyObject_Del(self); + } + +@@ -1428,6 +1486,8 @@ liblvm_lvm_pvseg_get_property(pvsegobject *self, PyObject *args) + const char *name; + struct lvm_property_value prop_value; + ++ PVSEG_VALID(self); ++ + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + +@@ -1522,7 +1582,7 @@ static PyMethodDef liblvm_pv_methods[] = { + { "getDevSize", (PyCFunction)liblvm_lvm_pv_get_dev_size, METH_NOARGS }, + { "getFree", (PyCFunction)liblvm_lvm_pv_get_free, METH_NOARGS }, + { "resize", (PyCFunction)liblvm_lvm_pv_resize, METH_VARARGS }, +- { "listPVsegs", (PyCFunction)liblvm_lvm_lv_list_pvsegs, METH_NOARGS }, ++ { "listPVsegs", (PyCFunction)liblvm_lvm_pv_list_pvsegs, METH_NOARGS }, + { NULL, NULL} /* sentinel */ + }; + diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-python-remove-liblvm-object.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-python-remove-liblvm-object.patch new file mode 100644 index 00000000000..aef2284ea7b --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-python-remove-liblvm-object.patch @@ -0,0 +1,793 @@ +commit 84a4d4b970bb9aaf540ad5fa82276b1caf5aa9bd +Author: Andy Grover +Date: Mon Oct 15 13:26:01 2012 -0700 + + python-lvm: Remove liblvm object + + Instead of requiring users to create a liblvm object, and then calling + methods on it, the module acquires a liblvm handle as part of + initialization. This makes it impossible to instantiate a liblvm object + with a different systemdir, but there is an alternate envvar method for + that obscure use case. + + Signed-off-by: Andy Grover +--- + python/liblvm.c | 269 ++++++++++++++++++++------------------------------------ + 1 file changed, 97 insertions(+), 172 deletions(-) + +diff --git a/python/liblvm.c b/python/liblvm.c +index cbfa170..4518cf4 100644 +--- a/python/liblvm.c ++++ b/python/liblvm.c +@@ -24,39 +24,32 @@ + #include + #include "lvm2app.h" + +-typedef struct { +- PyObject_HEAD +- lvm_t libh; /* lvm lib handle */ +-} lvmobject; ++static lvm_t libh; ++ + + typedef struct { + PyObject_HEAD + vg_t vg; /* vg handle */ +- lvmobject *lvm_obj; + } vgobject; + + typedef struct { + PyObject_HEAD + lv_t lv; /* lv handle */ +- lvmobject *lvm_obj; + } lvobject; + + typedef struct { + PyObject_HEAD + pv_t pv; /* pv handle */ +- lvmobject *lvm_obj; + } pvobject; + + typedef struct { + PyObject_HEAD + lvseg_t lv_seg; /* lv segment handle */ +- lvmobject *lvm_obj; + } lvsegobject; + + typedef struct { + PyObject_HEAD + pvseg_t pv_seg; /* pv segment handle */ +- lvmobject *lvm_obj; + } pvsegobject; + + static PyTypeObject LibLVMvgType; +@@ -67,100 +60,51 @@ static PyTypeObject LibLVMpvsegType; + + static PyObject *LibLVMError; + +- +-/* ---------------------------------------------------------------------- +- * LVM object initialization/deallocation +- */ +- +-static int +-liblvm_init(lvmobject *self, PyObject *arg) +-{ +- char *systemdir = NULL; +- +- if (!PyArg_ParseTuple(arg, "|s", &systemdir)) +- return -1; +- +- self->libh = lvm_init(systemdir); +- if (lvm_errno(self->libh)) { +- PyErr_SetFromErrno(PyExc_OSError); +- return -1; +- } +- +- return 0; +-} +- +-static void +-liblvm_dealloc(lvmobject *self) +-{ +- /* if already closed, don't reclose it */ +- if (self->libh != NULL){ +- lvm_quit(self->libh); +- } +- +- PyObject_Del(self); +-} +- +-#define LVM_VALID(lvmobject) \ ++#define LVM_VALID() \ + do { \ +- if (!lvmobject->libh) { \ +- PyErr_SetString(PyExc_UnboundLocalError, "LVM object invalid"); \ ++ if (!libh) { \ ++ PyErr_SetString(PyExc_UnboundLocalError, "LVM handle invalid"); \ + return NULL; \ + } \ + } while (0) + + static PyObject * +-liblvm_get_last_error(lvmobject *self) ++liblvm_get_last_error(void) + { + PyObject *info; + +- LVM_VALID(self); ++ LVM_VALID(); + + if((info = PyTuple_New(2)) == NULL) + return NULL; + +- PyTuple_SetItem(info, 0, PyInt_FromLong((long) lvm_errno(self->libh))); +- PyTuple_SetItem(info, 1, PyString_FromString(lvm_errmsg(self->libh))); ++ PyTuple_SetItem(info, 0, PyInt_FromLong((long) lvm_errno(libh))); ++ PyTuple_SetItem(info, 1, PyString_FromString(lvm_errmsg(libh))); + + return info; + } + + static PyObject * +-liblvm_library_get_version(lvmobject *self) ++liblvm_library_get_version(void) + { +- LVM_VALID(self); ++ LVM_VALID(); + + return Py_BuildValue("s", lvm_library_get_version()); + } + +- +-static PyObject * +-liblvm_close(lvmobject *self) +-{ +- LVM_VALID(self); +- +- /* if already closed, don't reclose it */ +- if (self->libh != NULL) +- lvm_quit(self->libh); +- +- self->libh = NULL; +- +- Py_INCREF(Py_None); +- return Py_None; +-} +- + static PyObject * +-liblvm_lvm_list_vg_names(lvmobject *self) ++liblvm_lvm_list_vg_names(void) + { + struct dm_list *vgnames; + struct lvm_str_list *strl; + PyObject * pytuple; + int i = 0; + +- LVM_VALID(self); ++ LVM_VALID(); + +- vgnames = lvm_list_vg_names(self->libh); ++ vgnames = lvm_list_vg_names(libh); + if (!vgnames) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -177,18 +121,18 @@ liblvm_lvm_list_vg_names(lvmobject *self) + } + + static PyObject * +-liblvm_lvm_list_vg_uuids(lvmobject *self) ++liblvm_lvm_list_vg_uuids(void) + { + struct dm_list *uuids; + struct lvm_str_list *strl; + PyObject * pytuple; + int i = 0; + +- LVM_VALID(self); ++ LVM_VALID(); + +- uuids = lvm_list_vg_uuids(self->libh); ++ uuids = lvm_list_vg_uuids(libh); + if (!uuids) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -205,12 +149,12 @@ liblvm_lvm_list_vg_uuids(lvmobject *self) + } + + static PyObject * +-liblvm_lvm_percent_to_float(lvmobject *self, PyObject *arg) ++liblvm_lvm_percent_to_float(PyObject *arg) + { + double converted; + int percent; + +- LVM_VALID(self); ++ LVM_VALID(); + + if (!PyArg_ParseTuple(arg, "i", &percent)) + return NULL; +@@ -220,18 +164,18 @@ liblvm_lvm_percent_to_float(lvmobject *self, PyObject *arg) + } + + static PyObject * +-liblvm_lvm_vgname_from_pvid(lvmobject *self, PyObject *arg) ++liblvm_lvm_vgname_from_pvid(PyObject *self, PyObject *arg) + { + const char *pvid; + const char *vgname; + +- LVM_VALID(self); ++ LVM_VALID(); + + if (!PyArg_ParseTuple(arg, "s", &pvid)) + return NULL; + +- if((vgname = lvm_vgname_from_pvid(self->libh, pvid)) == NULL) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); ++ if((vgname = lvm_vgname_from_pvid(libh, pvid)) == NULL) { ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -239,18 +183,18 @@ liblvm_lvm_vgname_from_pvid(lvmobject *self, PyObject *arg) + } + + static PyObject * +-liblvm_lvm_vgname_from_device(lvmobject *self, PyObject *arg) ++liblvm_lvm_vgname_from_device(PyObject *self, PyObject *arg) + { + const char *device; + const char *vgname; + +- LVM_VALID(self); ++ LVM_VALID(); + + if (!PyArg_ParseTuple(arg, "s", &device)) + return NULL; + +- if((vgname = lvm_vgname_from_device(self->libh, device)) == NULL) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); ++ if((vgname = lvm_vgname_from_device(libh, device)) == NULL) { ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -259,18 +203,18 @@ liblvm_lvm_vgname_from_device(lvmobject *self, PyObject *arg) + + + static PyObject * +-liblvm_lvm_config_find_bool(lvmobject *self, PyObject *arg) ++liblvm_lvm_config_find_bool(PyObject *self, PyObject *arg) + { + const char *config; + int rval; + PyObject *rc; + +- LVM_VALID(self); ++ LVM_VALID(); + + if (!PyArg_ParseTuple(arg, "s", &config)) + return NULL; + +- if ((rval = lvm_config_find_bool(self->libh, config, -10)) == -10) { ++ if ((rval = lvm_config_find_bool(libh, config, -10)) == -10) { + /* Retrieving error information yields no error in this case */ + PyErr_Format(PyExc_ValueError, "config path not found"); + return NULL; +@@ -283,14 +227,14 @@ liblvm_lvm_config_find_bool(lvmobject *self, PyObject *arg) + } + + static PyObject * +-liblvm_lvm_config_reload(lvmobject *self) ++liblvm_lvm_config_reload(void) + { + int rval; + +- LVM_VALID(self); ++ LVM_VALID(); + +- if((rval = lvm_config_reload(self->libh)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); ++ if((rval = lvm_config_reload(libh)) == -1) { ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -300,14 +244,14 @@ liblvm_lvm_config_reload(lvmobject *self) + + + static PyObject * +-liblvm_lvm_scan(lvmobject *self) ++liblvm_lvm_scan(void) + { + int rval; + +- LVM_VALID(self); ++ LVM_VALID(); + +- if((rval = lvm_scan(self->libh)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); ++ if((rval = lvm_scan(libh)) == -1) { ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -316,18 +260,18 @@ liblvm_lvm_scan(lvmobject *self) + } + + static PyObject * +-liblvm_lvm_config_override(lvmobject *self, PyObject *arg) ++liblvm_lvm_config_override(PyObject *self, PyObject *arg) + { + const char *config; + int rval; + +- LVM_VALID(self); ++ LVM_VALID(); + + if (!PyArg_ParseTuple(arg, "s", &config)) + return NULL; + +- if ((rval = lvm_config_override(self->libh, config)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); ++ if ((rval = lvm_config_override(libh, config)) == -1) { ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -340,14 +284,14 @@ liblvm_lvm_config_override(lvmobject *self, PyObject *arg) + + + static PyObject * +-liblvm_lvm_vg_open(lvmobject *lvm, PyObject *args) ++liblvm_lvm_vg_open(PyObject *self, PyObject *args) + { + const char *vgname; + const char *mode = NULL; + +- vgobject *self; ++ vgobject *vgobj; + +- LVM_VALID(lvm); ++ LVM_VALID(); + + if (!PyArg_ParseTuple(args, "s|s", &vgname, &mode)) { + return NULL; +@@ -356,42 +300,38 @@ liblvm_lvm_vg_open(lvmobject *lvm, PyObject *args) + if (mode == NULL) + mode = "r"; + +- if ((self = PyObject_New(vgobject, &LibLVMvgType)) == NULL) ++ if ((vgobj = PyObject_New(vgobject, &LibLVMvgType)) == NULL) + return NULL; + +- if ((self->vg = lvm_vg_open(lvm->libh, vgname, mode, 0))== NULL) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(lvm)); +- Py_DECREF(self); ++ if ((vgobj->vg = lvm_vg_open(libh, vgname, mode, 0))== NULL) { ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } +- self->lvm_obj = lvm; + +- return (PyObject *)self; ++ return (PyObject *)vgobj; + } + + static PyObject * +-liblvm_lvm_vg_create(lvmobject *lvm, PyObject *args) ++liblvm_lvm_vg_create(PyObject *self, PyObject *args) + { + const char *vgname; +- vgobject *self; ++ vgobject *vgobj; + +- LVM_VALID(lvm); ++ LVM_VALID(); + + if (!PyArg_ParseTuple(args, "s", &vgname)) { + return NULL; + } + +- if ((self = PyObject_New(vgobject, &LibLVMvgType)) == NULL) ++ if ((vgobj = PyObject_New(vgobject, &LibLVMvgType)) == NULL) + return NULL; + +- if ((self->vg = lvm_vg_create(lvm->libh, vgname))== NULL) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(lvm)); +- Py_DECREF(self); ++ if ((vgobj->vg = lvm_vg_create(libh, vgname))== NULL) { ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } +- self->lvm_obj = lvm; + +- return (PyObject *)self; ++ return (PyObject *)vgobj; + } + + static void +@@ -462,7 +402,7 @@ liblvm_lvm_vg_remove(vgobject *self) + return Py_None; + + error: +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -488,7 +428,7 @@ liblvm_lvm_vg_extend(vgobject *self, PyObject *args) + return Py_None; + + error: +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -514,7 +454,7 @@ liblvm_lvm_vg_reduce(vgobject *self, PyObject *args) + return Py_None; + + error: +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -538,7 +478,7 @@ liblvm_lvm_vg_add_tag(vgobject *self, PyObject *args) + return Py_BuildValue("i", rval); + + error: +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -564,7 +504,7 @@ liblvm_lvm_vg_remove_tag(vgobject *self, PyObject *args) + return Py_None; + + error: +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + + } +@@ -658,13 +598,13 @@ liblvm_lvm_vg_get_free_extent_count(vgobject *self) + + /* Builds a python tuple ([string|number], bool) from a struct lvm_property_value */ + static PyObject * +-get_property(lvmobject *h, struct lvm_property_value *prop) ++get_property(struct lvm_property_value *prop) + { + PyObject *pytuple; + PyObject *setable; + + if( !prop->is_valid ) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(h)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -703,7 +643,7 @@ liblvm_lvm_vg_get_property(vgobject *self, PyObject *args) + return NULL; + + prop_value = lvm_vg_get_property(self->vg, name); +- return get_property(self->lvm_obj, &prop_value); ++ return get_property(&prop_value); + } + + static PyObject * +@@ -791,7 +731,7 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) + return Py_None; + + lvmerror: +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + bail: + free(string_value); + if( variant_type_arg ) { +@@ -838,7 +778,7 @@ liblvm_lvm_vg_set_extent_size(vgobject *self, PyObject *args) + } + + if ((rval = lvm_vg_set_extent_size(self->vg, new_size)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -875,7 +815,6 @@ liblvm_lvm_vg_list_lvs(vgobject *vg) + } + + self->lv = lvl->lv; +- self->lvm_obj = vg->lvm_obj; + PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); + i++; + } +@@ -895,7 +834,7 @@ liblvm_lvm_vg_get_tags(vgobject *self) + + tags = lvm_vg_get_tags(self->vg); + if (!tags) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -928,11 +867,10 @@ liblvm_lvm_vg_create_lv_linear(vgobject *vg, PyObject *args) + return NULL; + + if ((self->lv = lvm_vg_create_lv_linear(vg->vg, vgname, size))== NULL) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(vg->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + Py_DECREF(self); + return NULL; + } +- self->lvm_obj = vg->lvm_obj; + + return (PyObject *)self; + } +@@ -972,7 +910,6 @@ liblvm_lvm_vg_list_pvs(vgobject *vg) + } + + self->pv = pvl->pv; +- self->lvm_obj = vg->lvm_obj; + PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); + i++; + } +@@ -997,7 +934,7 @@ liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) + + lv = method(self->vg, id); + if( !lv ) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1007,7 +944,6 @@ liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) + } + + rc->lv = lv; +- rc->lvm_obj = self->lvm_obj; + return (PyObject *)rc; + } + +@@ -1037,7 +973,7 @@ liblvm_lvm_pv_from_N(vgobject *self, PyObject *arg, pv_fetch_by_N method) + + pv = method(self->vg, id); + if( !pv ) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1047,7 +983,6 @@ liblvm_lvm_pv_from_N(vgobject *self, PyObject *arg, pv_fetch_by_N method) + } + + rc->pv = pv; +- rc->lvm_obj = self->lvm_obj; + return (PyObject *)rc; + } + +@@ -1104,7 +1039,7 @@ liblvm_lvm_lv_activate(lvobject *self) + LV_VALID(self); + + if ((rval = lvm_lv_activate(self->lv)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1120,7 +1055,7 @@ liblvm_lvm_lv_deactivate(lvobject *self) + LV_VALID(self); + + if ((rval = lvm_lv_deactivate(self->lv)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1136,7 +1071,7 @@ liblvm_lvm_vg_remove_lv(lvobject *self) + LV_VALID(self); + + if ((rval = lvm_vg_remove_lv(self->lv)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1149,7 +1084,7 @@ liblvm_lvm_vg_remove_lv(lvobject *self) + /* This will return a tuple of (value, bool) with the value being a string or + integer and bool indicating if property is settable */ + static PyObject * +-liblvm_lvm_lv_get_property(lvobject *self, PyObject *args) ++liblvm_lvm_lv_get_property(lvobject *self, PyObject *args) + { + const char *name; + struct lvm_property_value prop_value; +@@ -1160,7 +1095,7 @@ liblvm_lvm_lv_get_property(lvobject *self, PyObject *args) + return NULL; + + prop_value = lvm_lv_get_property(self->lv, name); +- return get_property(self->lvm_obj, &prop_value); ++ return get_property(&prop_value); + } + + static PyObject * +@@ -1210,7 +1145,7 @@ liblvm_lvm_lv_add_tag(lvobject *self, PyObject *args) + } + + if ((rval = lvm_lv_add_tag(self->lv, tag)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1231,7 +1166,7 @@ liblvm_lvm_lv_remove_tag(lvobject *self, PyObject *args) + } + + if ((rval = lvm_lv_remove_tag(self->lv, tag)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1251,7 +1186,7 @@ liblvm_lvm_lv_get_tags(lvobject *self) + + tags = lvm_lv_get_tags(self->lv); + if (!tags) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1279,7 +1214,7 @@ liblvm_lvm_lv_rename(lvobject *self, PyObject *args) + return NULL; + + if ((rval = lvm_lv_rename(self->lv, new_name)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1300,7 +1235,7 @@ liblvm_lvm_lv_resize(lvobject *self, PyObject *args) + } + + if ((rval = lvm_lv_resize(self->lv, new_size)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1337,7 +1272,6 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) + } + + self->lv_seg = lvsegl->lvseg; +- self->lvm_obj = lv->lvm_obj; + PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); + i++; + } +@@ -1349,7 +1283,7 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) + + #define PV_VALID(pvobject) \ + do { \ +- if (!pvobject->pv || !pvobject->lvm_obj) { \ ++ if (!pvobject->pv || !libh) { \ + PyErr_SetString(PyExc_UnboundLocalError, "PV object invalid"); \ + return NULL; \ + } \ +@@ -1385,7 +1319,7 @@ liblvm_lvm_pv_get_property(pvobject *self, PyObject *args) + return NULL; + + prop_value = lvm_pv_get_property(self->pv, name); +- return get_property(self->lvm_obj, &prop_value); ++ return get_property(&prop_value); + } + + static PyObject * +@@ -1417,7 +1351,7 @@ liblvm_lvm_pv_resize(pvobject *self, PyObject *args) + } + + if ((rval = lvm_pv_resize(self->pv, new_size)) == -1) { +- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); ++ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + +@@ -1454,7 +1388,6 @@ liblvm_lvm_lv_list_pvsegs(pvobject *pv) + } + + self->pv_seg = pvsegl->pvseg; +- self->lvm_obj = pv->lvm_obj; + PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); + i++; + } +@@ -1480,7 +1413,7 @@ liblvm_lvm_lvseg_get_property(lvsegobject *self, PyObject *args) + return NULL; + + prop_value = lvm_lvseg_get_property(self->lv_seg, name); +- return get_property(self->lvm_obj, &prop_value); ++ return get_property(&prop_value); + } + + /* PV seg methods */ +@@ -1501,7 +1434,7 @@ liblvm_lvm_pvseg_get_property(pvsegobject *self, PyObject *args) + return NULL; + + prop_value = lvm_pvseg_get_property(self->pv_seg, name); +- return get_property(self->lvm_obj, &prop_value); ++ return get_property(&prop_value); + } + + /* ---------------------------------------------------------------------- +@@ -1513,7 +1446,6 @@ static PyMethodDef Liblvm_methods[] = { + { "getVersion", (PyCFunction)liblvm_library_get_version, METH_NOARGS }, + { "vgOpen", (PyCFunction)liblvm_lvm_vg_open, METH_VARARGS }, + { "vgCreate", (PyCFunction)liblvm_lvm_vg_create, METH_VARARGS }, +- { "close", (PyCFunction)liblvm_close, METH_NOARGS }, + { "configFindBool", (PyCFunction)liblvm_lvm_config_find_bool, METH_VARARGS }, + { "configReload", (PyCFunction)liblvm_lvm_config_reload, METH_NOARGS }, + { "configOverride", (PyCFunction)liblvm_lvm_config_override, METH_VARARGS }, +@@ -1606,18 +1538,6 @@ static PyMethodDef liblvm_pvseg_methods[] = { + { NULL, NULL} /* sentinel */ + }; + +-static PyTypeObject LiblvmType = { +- PyObject_HEAD_INIT(&PyType_Type) +- .tp_name = "liblvm.Liblvm", +- .tp_basicsize = sizeof(lvmobject), +- .tp_new = PyType_GenericNew, +- .tp_dealloc = (destructor)liblvm_dealloc, +- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +- .tp_doc = "Liblvm objects", +- .tp_methods = Liblvm_methods, +- .tp_init = (initproc)liblvm_init, +-}; +- + static PyTypeObject LibLVMvgType = { + PyObject_HEAD_INIT(&PyType_Type) + .tp_name = "liblvm.Liblvm_vg", +@@ -1673,13 +1593,20 @@ static PyTypeObject LibLVMpvsegType = { + .tp_methods = liblvm_pvseg_methods, + }; + ++static void ++liblvm_cleanup(void) ++{ ++ lvm_quit(libh); ++ libh = NULL; ++} ++ + PyMODINIT_FUNC + initlvm(void) + { + PyObject *m; + +- if (PyType_Ready(&LiblvmType) < 0) +- return; ++ libh = lvm_init(NULL); ++ + if (PyType_Ready(&LibLVMvgType) < 0) + return; + if (PyType_Ready(&LibLVMlvType) < 0) +@@ -1695,9 +1622,6 @@ initlvm(void) + if (m == NULL) + return; + +- Py_INCREF(&LiblvmType); +- PyModule_AddObject(m, "Liblvm", (PyObject *)&LiblvmType); +- + LibLVMError = PyErr_NewException("Liblvm.LibLVMError", + NULL, NULL); + if (LibLVMError) { +@@ -1708,4 +1632,5 @@ initlvm(void) + PyModule_AddObject(m, "LibLVMError", LibLVMError); + } + ++ Py_AtExit(liblvm_cleanup); + } diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-python-update-example-to-work-with-lvm-object-removal.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-python-update-example-to-work-with-lvm-object-removal.patch new file mode 100644 index 00000000000..621d1dfcee7 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-python-update-example-to-work-with-lvm-object-removal.patch @@ -0,0 +1,103 @@ +commit 10ba799ab08001d5435425e65f039f20cadd306e +Author: Tony Asleson +Date: Mon Oct 15 13:54:19 2012 -0700 + + python-lvm: Update example to work with lvm object removal. + + Signed-off-by: Tony Asleson + Signed-off-by: Andy Grover +--- + python/example.py | 35 +++++++++++++++-------------------- + 1 file changed, 15 insertions(+), 20 deletions(-) + +diff --git a/python/example.py b/python/example.py +index 67bb7e4..5c14ee1 100644 +--- a/python/example.py ++++ b/python/example.py +@@ -31,9 +31,9 @@ def print_pv(pv): + + + #Dump some information about a specific volume group +-def print_vg(h, vg_name): ++def print_vg(vg_name): + #Open read only +- vg = h.vgOpen(vg_name, 'r') ++ vg = lvm.vgOpen(vg_name, 'r') + + print 'Volume group:', vg_name, 'Size: ', vg.getSize() + +@@ -55,13 +55,13 @@ def print_vg(h, vg_name): + vg.close() + + #Returns the name of a vg with space available +-def find_vg_with_free_space(h): ++def find_vg_with_free_space(): + free_space = 0 + rc = None + +- vg_names = l.listVgNames() ++ vg_names = lvm.listVgNames() + for v in vg_names: +- vg = h.vgOpen(v, 'r') ++ vg = lvm.vgOpen(v, 'r') + c_free = vg.getFreeSize() + if c_free > free_space: + free_space = c_free +@@ -72,13 +72,13 @@ def find_vg_with_free_space(h): + + #Walk through the volume groups and fine one with space in which we can + #create a new logical volume +-def create_delete_logical_volume(h): +- vg_name = find_vg_with_free_space(h) ++def create_delete_logical_volume(): ++ vg_name = find_vg_with_free_space() + + print 'Using volume group ', vg_name, ' for example' + + if vg_name: +- vg = h.vgOpen(vg_name, 'w') ++ vg = lvm.vgOpen(vg_name, 'w') + lv = vg.createLvLinear('python_lvm_ok_to_delete', vg.getFreeSize()) + + if lv: +@@ -93,11 +93,11 @@ def create_delete_logical_volume(h): + #Remove tag + lv.removeTag(t) + ++ lv.deactivate() ++ + #Try to rename +- lv.rename("python_lvm_ok_to_be_removed_shortly") ++ lv.rename("python_lvm_renamed") + print 'LV name= ', lv.getName() +- +- lv.deactivate() + lv.remove() + + vg.close() +@@ -105,21 +105,16 @@ def create_delete_logical_volume(h): + print 'No free space available to create demo lv!' + + if __name__ == '__main__': +- #Create a new LVM instance +- l = lvm.Liblvm() +- + #What version +- print 'lvm version=', l.getVersion() ++ print 'lvm version=', lvm.getVersion() + + #Get a list of volume group names +- vg_names = l.listVgNames() ++ vg_names = lvm.listVgNames() + + #For each volume group display some information about each of them + for vg_i in vg_names: +- print_vg(l, vg_i) ++ print_vg(vg_i) + + #Demo creating a logical volume +- create_delete_logical_volume(l) ++ create_delete_logical_volume() + +- #Close +- l.close() diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-python-whitespace-and-conditional-cleanup.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-python-whitespace-and-conditional-cleanup.patch new file mode 100644 index 00000000000..454e7b790fc --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-python-whitespace-and-conditional-cleanup.patch @@ -0,0 +1,205 @@ +commit 12b631a6768e6f2a2005ef8ea91c0afbc2455c54 +Author: Andy Grover +Date: Mon Oct 15 13:34:43 2012 -0700 + + python-lvm: whitespace and Yoda conditionals + + Signed-off-by: Andy Grover +--- + python/liblvm.c | 50 ++++++++++++++++++++++++-------------------------- + 1 file changed, 24 insertions(+), 26 deletions(-) + +diff --git a/python/liblvm.c b/python/liblvm.c +index 4518cf4..8a73ced 100644 +--- a/python/liblvm.c ++++ b/python/liblvm.c +@@ -75,7 +75,7 @@ liblvm_get_last_error(void) + + LVM_VALID(); + +- if((info = PyTuple_New(2)) == NULL) ++ if ((info = PyTuple_New(2)) == NULL) + return NULL; + + PyTuple_SetItem(info, 0, PyInt_FromLong((long) lvm_errno(libh))); +@@ -174,7 +174,7 @@ liblvm_lvm_vgname_from_pvid(PyObject *self, PyObject *arg) + if (!PyArg_ParseTuple(arg, "s", &pvid)) + return NULL; + +- if((vgname = lvm_vgname_from_pvid(libh, pvid)) == NULL) { ++ if ((vgname = lvm_vgname_from_pvid(libh, pvid)) == NULL) { + PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } +@@ -193,7 +193,7 @@ liblvm_lvm_vgname_from_device(PyObject *self, PyObject *arg) + if (!PyArg_ParseTuple(arg, "s", &device)) + return NULL; + +- if((vgname = lvm_vgname_from_device(libh, device)) == NULL) { ++ if ((vgname = lvm_vgname_from_device(libh, device)) == NULL) { + PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } +@@ -233,7 +233,7 @@ liblvm_lvm_config_reload(void) + + LVM_VALID(); + +- if((rval = lvm_config_reload(libh)) == -1) { ++ if ((rval = lvm_config_reload(libh)) == -1) { + PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } +@@ -250,7 +250,7 @@ liblvm_lvm_scan(void) + + LVM_VALID(); + +- if((rval = lvm_scan(libh)) == -1) { ++ if ((rval = lvm_scan(libh)) == -1) { + PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } +@@ -603,7 +603,7 @@ get_property(struct lvm_property_value *prop) + PyObject *pytuple; + PyObject *setable; + +- if( !prop->is_valid ) { ++ if (!prop->is_valid) { + PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } +@@ -612,7 +612,7 @@ get_property(struct lvm_property_value *prop) + if (!pytuple) + return NULL; + +- if( prop->is_integer ) { ++ if (prop->is_integer) { + PyTuple_SET_ITEM(pytuple, 0, Py_BuildValue("K", prop->value.integer)); + } else { + PyTuple_SET_ITEM(pytuple, 0, PyString_FromString(prop->value.string)); +@@ -661,11 +661,11 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) + + lvm_property = lvm_vg_get_property(self->vg, property_name); + +- if( !lvm_property.is_valid ) { ++ if (!lvm_property.is_valid ) { + goto lvmerror; + } + +- if(PyObject_IsInstance(variant_type_arg, (PyObject*)&PyString_Type)) { ++ if (PyObject_IsInstance(variant_type_arg, (PyObject*)&PyString_Type)) { + + if (!lvm_property.is_string) { + PyErr_Format(PyExc_ValueError, "Property requires string value"); +@@ -676,7 +676,7 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) + leak when calling into set_property, need to verify*/ + string_value = strdup(PyString_AsString(variant_type_arg)); + lvm_property.value.string = string_value; +- if(!lvm_property.value.string) { ++ if (!lvm_property.value.string) { + PyErr_NoMemory(); + goto bail; + } +@@ -688,14 +688,12 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) + goto bail; + } + +- if(PyObject_IsInstance(variant_type_arg, (PyObject*)&PyInt_Type)) { ++ if (PyObject_IsInstance(variant_type_arg, (PyObject*)&PyInt_Type)) { + int temp_py_int = PyInt_AsLong(variant_type_arg); + + /* -1 could be valid, need to see if an exception was gen. */ +- if( -1 == temp_py_int ) { +- if( PyErr_Occurred() ) { +- goto bail; +- } ++ if (temp_py_int == -1 && PyErr_Occurred()) { ++ goto bail; + } + + if (temp_py_int < 0) { +@@ -704,10 +702,10 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) + } + + lvm_property.value.integer = temp_py_int; +- } else if(PyObject_IsInstance(variant_type_arg, (PyObject*)&PyLong_Type)){ ++ } else if (PyObject_IsInstance(variant_type_arg, (PyObject*)&PyLong_Type)){ + /* This will fail on negative numbers */ + unsigned long long temp_py_long = PyLong_AsUnsignedLongLong(variant_type_arg); +- if( (unsigned long long)-1 == temp_py_long ) { ++ if (temp_py_long == (unsigned long long)-1) { + goto bail; + } + +@@ -718,11 +716,11 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) + } + } + +- if( -1 == lvm_vg_set_property(self->vg, property_name, &lvm_property) ) { ++ if (lvm_vg_set_property(self->vg, property_name, &lvm_property) == -1) { + goto lvmerror; + } + +- if( -1 == lvm_vg_write(self->vg)) { ++ if (lvm_vg_write(self->vg) == -1) { + goto lvmerror; + } + +@@ -734,7 +732,7 @@ lvmerror: + PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + bail: + free(string_value); +- if( variant_type_arg ) { ++ if (variant_type_arg) { + Py_DECREF(variant_type_arg); + variant_type_arg = NULL; + } +@@ -933,13 +931,13 @@ liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) + return NULL; + + lv = method(self->vg, id); +- if( !lv ) { ++ if (!lv) { + PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + + rc = PyObject_New(lvobject, &LibLVMlvType); +- if( !rc ) { ++ if (!rc) { + return NULL; + } + +@@ -972,13 +970,13 @@ liblvm_lvm_pv_from_N(vgobject *self, PyObject *arg, pv_fetch_by_N method) + return NULL; + + pv = method(self->vg, id); +- if( !pv ) { ++ if (!pv) { + PyErr_SetObject(LibLVMError, liblvm_get_last_error()); + return NULL; + } + + rc = PyObject_New(pvobject, &LibLVMpvType); +- if( !rc ) { ++ if (!rc) { + return NULL; + } + +@@ -1255,7 +1253,7 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) + LV_VALID(lv); + + lvsegs = lvm_lv_list_lvsegs(lv->lv); +- if(!lvsegs) { ++ if (!lvsegs) { + return Py_BuildValue("()"); + } + +@@ -1371,7 +1369,7 @@ liblvm_lvm_lv_list_pvsegs(pvobject *pv) + PV_VALID(pv); + + pvsegs = lvm_pv_list_pvsegs(pv->pv); +- if(!pvsegs) { ++ if (!pvsegs) { + return Py_BuildValue("()"); + } + diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-skip-mlocking-verctors-on-arm-arch.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-skip-mlocking-verctors-on-arm-arch.patch new file mode 100644 index 00000000000..3eeec364664 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-skip-mlocking-verctors-on-arm-arch.patch @@ -0,0 +1,27 @@ + WHATS_NEW | 1 + + lib/mm/memlock.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/WHATS_NEW b/WHATS_NEW +index e247391..67a24c7 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Skip mlocking [vectors] on arm architecture. + Exit pvscan --cache immediately if cluster locking used or lvmetad not used. + Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. + Remove dependency on fedora-storage-init.service in lvm2 systemd units. +diff --git a/lib/mm/memlock.c b/lib/mm/memlock.c +index 2240a1d..6d0996a 100644 +--- a/lib/mm/memlock.c ++++ b/lib/mm/memlock.c +@@ -84,6 +84,7 @@ static int _default_priority; + static const char * const _ignore_maps[] = { + "[vdso]", + "[vsyscall]", ++ "[vectors]", + }; + + /* default blacklist for maps */ diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-synchronize-with-udev-in-pvscan-cache-and-fix-dangling-udev_sync-cookies.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-synchronize-with-udev-in-pvscan-cache-and-fix-dangling-udev_sync-cookies.patch new file mode 100644 index 00000000000..bbdd76e7092 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-synchronize-with-udev-in-pvscan-cache-and-fix-dangling-udev_sync-cookies.patch @@ -0,0 +1,33 @@ +commit 0bcd33ecffb97f09e1ffb75868844cea40f3cd77 +Author: Peter Rajnoha +Date: Tue Apr 9 10:07:49 2013 +0200 + + 1 +--- + WHATS_NEW | 1 + + tools/pvscan.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/WHATS_NEW b/WHATS_NEW +index c481e68..03345d8 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.02.99 - + =================================== ++ Synchronize with udev in pvscan --cache and fix dangling udev_sync cookies. + Fix autoactivation to not autoactivate VG/LV on each change of the PVs used. + Skip mlocking [vectors] on arm architecture. + Exit pvscan --cache immediately if cluster locking used or lvmetad not used. +diff --git a/tools/pvscan.c b/tools/pvscan.c +index 34ab792..fbd524b 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -223,6 +223,7 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv) + } + + out: ++ sync_local_dev_names(cmd); + unlock_vg(cmd, VG_GLOBAL); + + return ret; diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-various-thin-support-related-fixes.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-various-thin-support-related-fixes.patch new file mode 100644 index 00000000000..ff76e345daa --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-various-thin-support-related-fixes.patch @@ -0,0 +1,2066 @@ +commit 426de775ff89de7fd9a01f3168e18a711615d23a +Author: Peter Rajnoha +Date: Tue May 14 11:02:19 2013 +0200 + + lvm2-2_02_99-various-thin-support-related-fixes.patch +--- + WHATS_NEW | 11 ++ + WHATS_NEW_DM | 1 + + doc/example.conf.in | 27 +++++ + lib/activate/activate.h | 1 + + lib/config/defaults.h | 3 + + lib/format_text/archiver.c | 24 ++-- + lib/format_text/archiver.h | 4 +- + lib/metadata/lv.c | 5 + + lib/metadata/lv.h | 1 + + lib/metadata/lv_manip.c | 11 +- + lib/metadata/metadata-exported.h | 5 +- + lib/metadata/metadata.h | 2 + + lib/metadata/mirror.c | 9 +- + lib/metadata/thin_manip.c | 18 +++ + lib/report/columns.h | 2 +- + lib/report/properties.c | 22 ++-- + lib/report/report.c | 3 +- + lib/thin/thin.c | 93 +++++++++++---- + libdm/libdm-deptree.c | 5 + + liblvm/lvm_lv.c | 8 +- + man/lvconvert.8.in | 114 +++++++++++++++--- + man/lvcreate.8.in | 18 +-- + man/vgcfgrestore.8.in | 9 ++ + test/api/thin_percent.c | 10 ++ + test/api/thin_percent.sh | 2 +- + test/shell/lvconvert-thin.sh | 81 ++++++++++--- + test/shell/thin-defaults.sh | 35 ++++++ + test/shell/thin-restore.sh | 34 ++++++ + tools/args.h | 1 + + tools/commands.h | 10 +- + tools/lvchange.c | 8 +- + tools/lvconvert.c | 245 +++++++++++++++++++++++++-------------- + tools/lvcreate.c | 117 +++++-------------- + tools/toollib.c | 195 +++++++++++++++++++++++++++++++ + tools/toollib.h | 14 +++ + tools/vgcfgrestore.c | 5 +- + 36 files changed, 860 insertions(+), 293 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 03345d8..5231745 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,16 @@ + Version 2.02.99 - + =================================== ++ Fix lvm2app to return all property sizes in bytes. ++ Add lvm.conf option global/thin_disabled_features. ++ Add lvconvert support to swap thin pool metadata volume. ++ Implement internal function detach_pool_metadata_lv(). ++ Fix lvm2app and return lvseg discards property as string. ++ Allow forced vgcfgrestore of lvm2 metadata with thin volumes. ++ Add lvm.conf thin pool defs thin_pool_{chunk_size|discards|zero}. ++ Support discards for non-power-of-2 thin pool chunks. ++ Support allocation of pool metadata with lvconvert command. ++ Move common functionality for thin lvcreate and lvconvert to toollib. ++ Use lv_is_active() instead of lv_info() call. + Synchronize with udev in pvscan --cache and fix dangling udev_sync cookies. + Fix autoactivation to not autoactivate VG/LV on each change of the PVs used. + Skip mlocking [vectors] on arm architecture. +diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM +index 3f8d9c9..e0b8d51 100644 +--- a/WHATS_NEW_DM ++++ b/WHATS_NEW_DM +@@ -1,5 +1,6 @@ + Version 1.02.78 - + =================================== ++ Automatically deactivate failed preloaded dm tree node. + Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled. + + Version 1.02.77 - 15th October 2012 +diff --git a/doc/example.conf.in b/doc/example.conf.in +index 442ad64..1bf89d3 100644 +--- a/doc/example.conf.in ++++ b/doc/example.conf.in +@@ -232,6 +232,23 @@ allocation { + # Set to 1 to guarantee that thin pool metadata will always + # be placed on different PVs from the pool data. + thin_pool_metadata_require_separate_pvs = 0 ++ ++ # Specify the minimal chunk size (in KB) for thin pool volumes. ++ # Use of the larger chunk size may improve perfomance for plain ++ # thin volumes, however using them for snapshot volumes is less efficient, ++ # as it consumes more space and takes extra time for copying. ++ # When unset, lvm tries to estimate chunk size starting from 64KB ++ # Supported values are in range from 64 to 1048576. ++ # thin_pool_chunk_size = 64 ++ ++ # Specify discards behavior of the thin pool volume. ++ # Select one of "ignore", "nopassdown", "passdown" ++ # thin_pool_discards = "passdown" ++ ++ # Set to 0, to disable zeroing of thin pool data chunks before their ++ # first use. ++ # N.B. zeroing larger thin pool chunk size degrades performance. ++ # thin_pool_zero = 1 + } + + # This section that allows you to configure the nature of the +@@ -507,6 +524,16 @@ global { + # String with options passed with thin_check command. By default, + # option '-q' is for quiet output. + thin_check_options = [ "-q" ] ++ ++ # If set, given features are not used by thin driver. ++ # This can be helpful not just for testing, but i.e. allows to avoid ++ # using problematic implementation of some thin feature. ++ # Features: ++ # block_size ++ # discards ++ # discards_non_power_2 ++ # ++ # thin_disabled_features = [ "discards", "block_size" ] + } + + activation { +diff --git a/lib/activate/activate.h b/lib/activate/activate.h +index ba24d2a..0a0c97e 100644 +--- a/lib/activate/activate.h ++++ b/lib/activate/activate.h +@@ -51,6 +51,7 @@ enum { + THIN_FEATURE_EXTERNAL_ORIGIN = (1 << 1), + THIN_FEATURE_HELD_ROOT = (1 << 2), + THIN_FEATURE_BLOCK_SIZE = (1 << 3), ++ THIN_FEATURE_DISCARDS_NON_POWER_2 = (1 << 4), + }; + + void set_activation(int activation); +diff --git a/lib/config/defaults.h b/lib/config/defaults.h +index 9730a2d..348fa75 100644 +--- a/lib/config/defaults.h ++++ b/lib/config/defaults.h +@@ -69,6 +69,9 @@ + #define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */ + #define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */ + #define DEFAULT_THIN_POOL_OPTIMAL_SIZE (128 * 1024 * 1024) /* KB */ ++#define DEFAULT_THIN_POOL_CHUNK_SIZE 64 /* KB */ ++#define DEFAULT_THIN_POOL_DISCARDS "passdown" ++#define DEFAULT_THIN_POOL_ZERO 1 + + #define DEFAULT_UMASK 0077 + +diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c +index ccefb4c..8599e3b 100644 +--- a/lib/format_text/archiver.c ++++ b/lib/format_text/archiver.c +@@ -347,7 +347,7 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg) + + /* ORPHAN and VG locks held before calling this */ + int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name, +- const char *file) ++ const char *file, int force) + { + struct volume_group *vg; + int missing_pvs, r = 0; +@@ -360,14 +360,20 @@ int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name, + return_0; + + /* FIXME: Restore support is missing for now */ +- dm_list_iterate_items(lvl, &vg->lvs) ++ dm_list_iterate_items(lvl, &vg->lvs) { + if (lv_is_thin_type(lvl->lv)) { +- log_error("Cannot restore Volume Group %s with " +- "thin logical volumes. " +- "(not yet supported).", vg->name); +- r = 0; +- goto out; ++ if (!force) { ++ log_error("Consider using option --force to restore " ++ "Volume Group %s with thin volumes.", ++ vg->name); ++ goto out; ++ } else { ++ log_warn("WARNING: Forced restore of Volume Group " ++ "%s with thin volumes.", vg->name); ++ break; ++ } + } ++ } + + missing_pvs = vg_missing_pv_count(vg); + if (missing_pvs == 0) +@@ -381,7 +387,7 @@ out: + return r; + } + +-int backup_restore(struct cmd_context *cmd, const char *vg_name) ++int backup_restore(struct cmd_context *cmd, const char *vg_name, int force) + { + char path[PATH_MAX]; + +@@ -391,7 +397,7 @@ int backup_restore(struct cmd_context *cmd, const char *vg_name) + return 0; + } + +- return backup_restore_from_file(cmd, vg_name, path); ++ return backup_restore_from_file(cmd, vg_name, path, force); + } + + int backup_to_file(const char *file, const char *desc, struct volume_group *vg) +diff --git a/lib/format_text/archiver.h b/lib/format_text/archiver.h +index 7346f93..ddff687 100644 +--- a/lib/format_text/archiver.h ++++ b/lib/format_text/archiver.h +@@ -53,8 +53,8 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd, + const char *vg_name, const char *file); + int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg); + int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name, +- const char *file); +-int backup_restore(struct cmd_context *cmd, const char *vg_name); ++ const char *file, int force); ++int backup_restore(struct cmd_context *cmd, const char *vg_name, int force); + + int backup_to_file(const char *file, const char *desc, struct volume_group *vg); + +diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c +index 4032f34..34b428a 100644 +--- a/lib/metadata/lv.c ++++ b/lib/metadata/lv.c +@@ -123,6 +123,11 @@ char *lvseg_segtype_dup(struct dm_pool *mem, const struct lv_segment *seg) + return dm_pool_strdup(mem, seg->segtype->ops->name(seg)); + } + ++char *lvseg_discards_dup(struct dm_pool *mem, const struct lv_segment *seg) ++{ ++ return dm_pool_strdup(mem, get_pool_discards_name(seg->discards)); ++} ++ + uint64_t lvseg_chunksize(const struct lv_segment *seg) + { + uint64_t size; +diff --git a/lib/metadata/lv.h b/lib/metadata/lv.h +index 0daab62..838b002 100644 +--- a/lib/metadata/lv.h ++++ b/lib/metadata/lv.h +@@ -74,6 +74,7 @@ uint64_t lvseg_start(const struct lv_segment *seg); + uint64_t lvseg_size(const struct lv_segment *seg); + uint64_t lvseg_chunksize(const struct lv_segment *seg); + char *lvseg_segtype_dup(struct dm_pool *mem, const struct lv_segment *seg); ++char *lvseg_discards_dup(struct dm_pool *mem, const struct lv_segment *seg); + char *lvseg_tags_dup(const struct lv_segment *seg); + char *lvseg_devices(struct dm_pool *mem, const struct lv_segment *seg); + char *lvseg_seg_pe_ranges(struct dm_pool *mem, const struct lv_segment *seg); +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index d469fe8..a59e03f 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -4217,7 +4217,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l + struct logical_volume *pool_lv; + struct lv_list *lvl; + int origin_active = 0; +- struct lvinfo info; + + if (new_lv_name && find_lv_in_vg(vg, new_lv_name)) { + log_error("Logical volume \"%s\" already exists in " +@@ -4349,12 +4348,12 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l + log_warn("WARNING: See global/mirror_segtype_default in lvm.conf."); + } + +- if (!lv_info(cmd, org, 0, &info, 0, 0)) { ++ if (!lv_is_active(org)) { + log_error("Check for existence of active snapshot " + "origin '%s' failed.", org->name); + return NULL; + } +- origin_active = info.exists; ++ origin_active = 1; + + if (vg_is_clustered(vg) && + !lv_is_active_exclusive_locally(org)) { +@@ -4696,8 +4695,8 @@ revert_new_lv: + return NULL; + } + +-int lv_create_single(struct volume_group *vg, +- struct lvcreate_params *lp) ++struct logical_volume *lv_create_single(struct volume_group *vg, ++ struct lvcreate_params *lp) + { + struct logical_volume *lv; + +@@ -4725,5 +4724,5 @@ int lv_create_single(struct volume_group *vg, + out: + log_print_unless_silent("Logical volume \"%s\" created", lv->name); + +- return 1; ++ return lv; + } +diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h +index d149f95..11ca5be 100644 +--- a/lib/metadata/metadata-exported.h ++++ b/lib/metadata/metadata-exported.h +@@ -609,6 +609,7 @@ struct lvcreate_params { + uint32_t mirrors; /* mirror */ + + const struct segment_type *segtype; /* all */ ++ unsigned target_attr; /* all */ + + /* size */ + uint32_t extents; /* all */ +@@ -625,8 +626,8 @@ struct lvcreate_params { + struct dm_list tags; /* all */ + }; + +-int lv_create_single(struct volume_group *vg, +- struct lvcreate_params *lp); ++struct logical_volume *lv_create_single(struct volume_group *vg, ++ struct lvcreate_params *lp); + + /* + * Functions for layer manipulation +diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h +index 7bc7eaf..19bf742 100644 +--- a/lib/metadata/metadata.h ++++ b/lib/metadata/metadata.h +@@ -460,6 +460,8 @@ int fixup_imported_mirrors(struct volume_group *vg); + */ + int attach_pool_metadata_lv(struct lv_segment *pool_seg, + struct logical_volume *pool_metadata_lv); ++int detach_pool_metadata_lv(struct lv_segment *pool_seg, ++ struct logical_volume **pool_metadata_lv); + int attach_pool_data_lv(struct lv_segment *pool_seg, + struct logical_volume *pool_data_lv); + int attach_pool_lv(struct lv_segment *seg, struct logical_volume *pool_lv, +diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c +index c4683df..084c93a 100644 +--- a/lib/metadata/mirror.c ++++ b/lib/metadata/mirror.c +@@ -282,7 +282,6 @@ static int _init_mirror_log(struct cmd_context *cmd, + struct dm_list *tags, int remove_on_failure) + { + struct str_list *sl; +- struct lvinfo info; + uint64_t orig_status = log_lv->status; + int was_active = 0; + +@@ -298,14 +297,13 @@ static int _init_mirror_log(struct cmd_context *cmd, + } + + /* If the LV is active, deactivate it first. */ +- if (lv_info(cmd, log_lv, 0, &info, 0, 0) && info.exists) { +- (void)deactivate_lv(cmd, log_lv); ++ if (lv_is_active(log_lv)) { + /* + * FIXME: workaround to fail early + * Ensure that log is really deactivated because deactivate_lv + * on cluster do not fail if there is log_lv with different UUID. + */ +- if (lv_info(cmd, log_lv, 0, &info, 0, 0) && info.exists) { ++ if (!deactivate_lv(cmd, log_lv)) { + log_error("Aborting. Unable to deactivate mirror log."); + goto revert_new_lv; + } +@@ -1714,7 +1712,6 @@ int remove_mirror_log(struct cmd_context *cmd, + int force) + { + percent_t sync_percent; +- struct lvinfo info; + struct volume_group *vg = lv->vg; + + /* Unimplemented features */ +@@ -1724,7 +1721,7 @@ int remove_mirror_log(struct cmd_context *cmd, + } + + /* Had disk log, switch to core. */ +- if (lv_info(cmd, lv, 0, &info, 0, 0) && info.exists) { ++ if (lv_is_active(lv)) { + if (!lv_mirror_percent(cmd, lv, 0, &sync_percent, + NULL)) { + log_error("Unable to determine mirror sync status."); +diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c +index e7e96df..e2762a0 100644 +--- a/lib/metadata/thin_manip.c ++++ b/lib/metadata/thin_manip.c +@@ -30,6 +30,24 @@ int attach_pool_metadata_lv(struct lv_segment *pool_seg, struct logical_volume * + return add_seg_to_segs_using_this_lv(metadata_lv, pool_seg); + } + ++int detach_pool_metadata_lv(struct lv_segment *pool_seg, struct logical_volume **metadata_lv) ++{ ++ struct logical_volume *lv = pool_seg->metadata_lv; ++ ++ if (!lv || !lv_is_thin_pool_metadata(lv) || ++ !remove_seg_from_segs_using_this_lv(lv, pool_seg)) { ++ log_error(INTERNAL_ERROR "LV %s is invalid thin pool.", pool_seg->lv->name); ++ return 0; ++ } ++ ++ lv_set_visible(lv); ++ lv->status &= ~THIN_POOL_METADATA; ++ *metadata_lv = lv; ++ pool_seg->metadata_lv = NULL; ++ ++ return 1; ++} ++ + int attach_pool_data_lv(struct lv_segment *pool_seg, struct logical_volume *pool_data_lv) + { + if (!set_lv_segment_area_lv(pool_seg, 0, pool_data_lv, 0, THIN_POOL_DATA)) +diff --git a/lib/report/columns.h b/lib/report/columns.h +index 6299a2b..11b3f3f 100644 +--- a/lib/report/columns.h ++++ b/lib/report/columns.h +@@ -140,7 +140,7 @@ FIELD(SEGS, seg, NUM, "Region", region_size, 6, size32, region_size, "For mirror + FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, chunksize, "For snapshots, the unit of data used when tracking changes.", 0) + FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, chunk_size, "For snapshots, the unit of data used when tracking changes.", 0) + FIELD(SEGS, seg, NUM, "#Thins", list, 4, thincount, thin_count, "For thin pools, the number of thin volumes in this pool.", 0) +-FIELD(SEGS, seg, NUM, "Discards", list, 8, discards, discards, "For thin pools, how discards are handled.", 0) ++FIELD(SEGS, seg, STR, "Discards", list, 8, discards, discards, "For thin pools, how discards are handled.", 0) + FIELD(SEGS, seg, NUM, "Zero", list, 4, thinzero, zero, "For thin pools, if zeroing is enabled.", 0) + FIELD(SEGS, seg, NUM, "TransId", list, 4, transactionid, transaction_id, "For thin pools, the transaction id.", 0) + FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, seg_start, "Offset within the LV to the start of the segment in current units.", 0) +diff --git a/lib/report/properties.c b/lib/report/properties.c +index c4f6ab9..a871d66 100644 +--- a/lib/report/properties.c ++++ b/lib/report/properties.c +@@ -183,7 +183,7 @@ GET_LV_NUM_PROPERTY_FN(seg_count, dm_list_size(&lv->segments)) + #define _seg_count_set _not_implemented_set + GET_LV_STR_PROPERTY_FN(origin, lv_origin_dup(lv->vg->vgmem, lv)) + #define _origin_set _not_implemented_set +-GET_LV_NUM_PROPERTY_FN(origin_size, lv_origin_size(lv)) ++GET_LV_NUM_PROPERTY_FN(origin_size, (SECTOR_SIZE * lv_origin_size(lv))) + #define _origin_size_set _not_implemented_set + GET_LV_NUM_PROPERTY_FN(snap_percent, _snap_percent(lv)) + #define _snap_percent_set _not_implemented_set +@@ -231,7 +231,7 @@ GET_VG_NUM_PROPERTY_FN(vg_free, (SECTOR_SIZE * vg_free(vg))) + #define _vg_free_set _not_implemented_set + GET_VG_STR_PROPERTY_FN(vg_sysid, vg_system_id_dup(vg)) + #define _vg_sysid_set _not_implemented_set +-GET_VG_NUM_PROPERTY_FN(vg_extent_size, vg->extent_size) ++GET_VG_NUM_PROPERTY_FN(vg_extent_size, (SECTOR_SIZE * vg->extent_size)) + #define _vg_extent_size_set _not_implemented_set + GET_VG_NUM_PROPERTY_FN(vg_extent_count, vg->extent_count) + #define _vg_extent_count_set _not_implemented_set +@@ -267,17 +267,17 @@ GET_LVSEG_STR_PROPERTY_FN(segtype, lvseg_segtype_dup(lvseg->lv->vg->vgmem, lvseg + #define _segtype_set _not_implemented_set + GET_LVSEG_NUM_PROPERTY_FN(stripes, lvseg->area_count) + #define _stripes_set _not_implemented_set +-GET_LVSEG_NUM_PROPERTY_FN(stripesize, lvseg->stripe_size) ++GET_LVSEG_NUM_PROPERTY_FN(stripesize, (SECTOR_SIZE * lvseg->stripe_size)) + #define _stripesize_set _not_implemented_set +-GET_LVSEG_NUM_PROPERTY_FN(stripe_size, lvseg->stripe_size) ++GET_LVSEG_NUM_PROPERTY_FN(stripe_size, (SECTOR_SIZE * lvseg->stripe_size)) + #define _stripe_size_set _not_implemented_set +-GET_LVSEG_NUM_PROPERTY_FN(regionsize, lvseg->region_size) ++GET_LVSEG_NUM_PROPERTY_FN(regionsize, (SECTOR_SIZE * lvseg->region_size)) + #define _regionsize_set _not_implemented_set +-GET_LVSEG_NUM_PROPERTY_FN(region_size, lvseg->region_size) ++GET_LVSEG_NUM_PROPERTY_FN(region_size, (SECTOR_SIZE * lvseg->region_size)) + #define _region_size_set _not_implemented_set +-GET_LVSEG_NUM_PROPERTY_FN(chunksize, lvseg_chunksize(lvseg)) ++GET_LVSEG_NUM_PROPERTY_FN(chunksize, (SECTOR_SIZE * lvseg_chunksize(lvseg))) + #define _chunksize_set _not_implemented_set +-GET_LVSEG_NUM_PROPERTY_FN(chunk_size, lvseg_chunksize(lvseg)) ++GET_LVSEG_NUM_PROPERTY_FN(chunk_size, (SECTOR_SIZE * lvseg_chunksize(lvseg))) + #define _chunk_size_set _not_implemented_set + GET_LVSEG_NUM_PROPERTY_FN(thin_count, dm_list_size(&lvseg->lv->segs_using_this_lv)) + #define _thin_count_set _not_implemented_set +@@ -285,9 +285,9 @@ GET_LVSEG_NUM_PROPERTY_FN(zero, lvseg->zero_new_blocks) + #define _zero_set _not_implemented_set + GET_LVSEG_NUM_PROPERTY_FN(transaction_id, lvseg->transaction_id) + #define _transaction_id_set _not_implemented_set +-GET_LVSEG_NUM_PROPERTY_FN(discards, lvseg->discards) ++GET_LVSEG_STR_PROPERTY_FN(discards, lvseg_discards_dup(lvseg->lv->vg->vgmem, lvseg)) + #define _discards_set _not_implemented_set +-GET_LVSEG_NUM_PROPERTY_FN(seg_start, lvseg_start(lvseg)) ++GET_LVSEG_NUM_PROPERTY_FN(seg_start, (SECTOR_SIZE * lvseg_start(lvseg))) + #define _seg_start_set _not_implemented_set + GET_LVSEG_NUM_PROPERTY_FN(seg_start_pe, lvseg->le) + #define _seg_start_pe_set _not_implemented_set +@@ -305,7 +305,7 @@ GET_LVSEG_STR_PROPERTY_FN(devices, lvseg_devices(lvseg->lv->vg->vgmem, lvseg)) + /* PVSEG */ + GET_PVSEG_NUM_PROPERTY_FN(pvseg_start, pvseg->pe) + #define _pvseg_start_set _not_implemented_set +-GET_PVSEG_NUM_PROPERTY_FN(pvseg_size, pvseg->len) ++GET_PVSEG_NUM_PROPERTY_FN(pvseg_size, (SECTOR_SIZE * pvseg->len)) + #define _pvseg_size_set _not_implemented_set + + +diff --git a/lib/report/report.c b/lib/report/report.c +index eeca282..b1e2bc1 100644 +--- a/lib/report/report.c ++++ b/lib/report/report.c +@@ -830,7 +830,6 @@ static int _snpercent_disp(struct dm_report *rh __attribute__((unused)), struct + const void *data, void *private __attribute__((unused))) + { + const struct logical_volume *lv = (const struct logical_volume *) data; +- struct lvinfo info; + percent_t snap_percent; + uint64_t *sortval; + char *repstr; +@@ -847,7 +846,7 @@ static int _snpercent_disp(struct dm_report *rh __attribute__((unused)), struct + } + + if ((!lv_is_cow(lv) && !lv_is_merging_origin(lv)) || +- !lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) || !info.exists) { ++ !lv_is_active(lv)) { + *sortval = UINT64_C(0); + dm_report_field_set_value(field, "", sortval); + return 1; +diff --git a/lib/thin/thin.c b/lib/thin/thin.c +index 2b6c71f..d7c45ca 100644 +--- a/lib/thin/thin.c ++++ b/lib/thin/thin.c +@@ -37,6 +37,9 @@ + log_error(t " segment %s of logical volume %s.", ## p, \ + dm_config_parent_name(sn), seg->lv->name), 0; + ++/* TODO: using static field here, maybe should be a part of segment_type */ ++static unsigned _feature_mask; ++ + static int _thin_target_present(struct cmd_context *cmd, + const struct lv_segment *seg, + unsigned *attributes); +@@ -282,10 +285,15 @@ static int _thin_pool_add_target_line(struct dev_manager *dm, + return_0; + + if (attr & THIN_FEATURE_DISCARDS) { ++ /* Use ignore for discards ignore or non-power-of-2 chunk_size and <1.5 target */ + /* FIXME: Check whether underlying dev supports discards */ +- if (!dm_tree_node_set_thin_pool_discard(node, +- seg->discards == THIN_DISCARDS_IGNORE, +- seg->discards == THIN_DISCARDS_NO_PASSDOWN)) ++ if (((!(attr & THIN_FEATURE_DISCARDS_NON_POWER_2) && ++ (seg->chunk_size & (seg->chunk_size - 1))) || ++ (seg->discards == THIN_DISCARDS_IGNORE)) && ++ !dm_tree_node_set_thin_pool_discard(node, 1, 0)) ++ return_0; ++ else if (!dm_tree_node_set_thin_pool_discard(node, 0, ++ (seg->discards == THIN_DISCARDS_NO_PASSDOWN))) + return_0; + } else if (seg->discards != THIN_DISCARDS_IGNORE) + log_warn_suppress(_no_discards++, "WARNING: Thin pool target does " +@@ -534,10 +542,28 @@ static int _thin_target_present(struct cmd_context *cmd, + const struct lv_segment *seg, + unsigned *attributes) + { ++ /* List of features with their kernel target version */ ++ static const struct feature { ++ uint32_t maj; ++ uint32_t min; ++ unsigned thin_feature; ++ const char *feature; ++ } const _features[] = { ++ { 1, 1, THIN_FEATURE_DISCARDS, "discards" }, ++ { 1, 1, THIN_FEATURE_EXTERNAL_ORIGIN, "external_origin" }, ++ { 1, 4, THIN_FEATURE_BLOCK_SIZE, "block_size" }, ++ { 1, 5, THIN_FEATURE_DISCARDS_NON_POWER_2, "discards_non_power_2" }, ++ }; ++ ++ static const char _lvmconf[] = "global/thin_disabled_features"; + static int _checked = 0; + static int _present = 0; +- static int _attrs = 0; ++ static unsigned _attrs = 0; + uint32_t maj, min, patchlevel; ++ unsigned i; ++ const struct dm_config_node *cn; ++ const struct dm_config_value *cv; ++ const char *str; + + if (!_checked) { + _present = target_present(cmd, THIN_MODULE, 1); +@@ -547,29 +573,46 @@ static int _thin_target_present(struct cmd_context *cmd, + return 0; + } + +- if (maj >=1 && min >= 1) +- _attrs |= THIN_FEATURE_DISCARDS; +- else +- /* FIXME Log this as WARNING later only if the user asked for the feature to be used but it's not present */ +- log_debug("Target " THIN_MODULE " does not support discards."); +- +- if (maj >=1 && min >= 1) +- _attrs |= THIN_FEATURE_EXTERNAL_ORIGIN; +- else +- /* FIXME Log this as WARNING later only if the user asked for the feature to be used but it's not present */ +- log_debug("Target " THIN_MODULE " does not support external origins."); +- +- if (maj >=1 && min >= 4) +- _attrs |= THIN_FEATURE_BLOCK_SIZE; +- else +- /* FIXME Log this as WARNING later only if the user asked for the feature to be used but it's not present */ +- log_debug("Target " THIN_MODULE " does not support non power of 2 block sizes."); ++ for (i = 0; i < sizeof(_features)/sizeof(*_features); i++) ++ if (maj >= _features[i].maj && min >= _features[i].min) ++ _attrs |= _features[i].thin_feature; ++ else ++ log_very_verbose("Target " THIN_MODULE " does not support %s.", ++ _features[i].feature); + + _checked = 1; + } + +- if (attributes) +- *attributes = _attrs; ++ if (attributes) { ++ if (!_feature_mask) { ++ /* Support runtime lvm.conf changes, N.B. avoid 32 feature */ ++ if ((cn = find_config_tree_node(cmd, _lvmconf))) { ++ for (cv = cn->v; cv; cv = cv->next) { ++ if (cv->type != DM_CFG_STRING) { ++ log_error("Ignoring invalid string in config file %s.", ++ _lvmconf); ++ continue; ++ } ++ str = cv->v.str; ++ if (!*str) { ++ log_error("Ignoring empty string in config file %s.", ++ _lvmconf); ++ continue; ++ } ++ for (i = 0; i < sizeof(_features)/sizeof(*_features); i++) ++ if (strcasecmp(str, _features[i].feature) == 0) ++ _feature_mask |= _features[i].thin_feature; ++ } ++ } ++ _feature_mask = ~_feature_mask; ++ for (i = 0; i < sizeof(_features)/sizeof(*_features); i++) ++ if ((_attrs & _features[i].thin_feature) && ++ !(_feature_mask & _features[i].thin_feature)) ++ log_very_verbose("Target "THIN_MODULE " %s support disabled by %s", ++ _features[i].feature, _lvmconf); ++ } ++ *attributes = _attrs & _feature_mask; ++ } + + return _present; + } +@@ -671,5 +714,9 @@ int init_multiple_segtypes(struct cmd_context *cmd, struct segtype_library *segl + log_very_verbose("Initialised segtype: %s", segtype->name); + } + ++ ++ /* Reset mask for recalc */ ++ _feature_mask = 0; ++ + return 1; + } +diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c +index 096eba2..e4a574d 100644 +--- a/libdm/libdm-deptree.c ++++ b/libdm/libdm-deptree.c +@@ -2496,6 +2496,11 @@ int dm_tree_preload_children(struct dm_tree_node *dnode, + log_error("Unable to resume %s (%" PRIu32 + ":%" PRIu32 ")", child->name, child->info.major, + child->info.minor); ++ if (!_deactivate_node(child->name, child->info.major, child->info.minor, ++ &child->dtree->cookie, child->udev_flags, 0)) ++ log_error("Unable to deactivate %s (%" PRIu32 ++ ":%" PRIu32 ")", child->name, child->info.major, ++ child->info.minor); + r = 0; + continue; + } +diff --git a/liblvm/lvm_lv.c b/liblvm/lvm_lv.c +index d47a857..b2a604d 100644 +--- a/liblvm/lvm_lv.c ++++ b/liblvm/lvm_lv.c +@@ -146,7 +146,7 @@ lv_t lvm_vg_create_lv_linear(vg_t vg, const char *name, uint64_t size) + { + struct lvcreate_params lp = { 0 }; + uint64_t extents; +- struct lv_list *lvl; ++ struct logical_volume *lv; + + if (vg_read_error(vg)) + return NULL; +@@ -162,11 +162,9 @@ lv_t lvm_vg_create_lv_linear(vg_t vg, const char *name, uint64_t size) + _lv_set_default_params(&lp, vg, name, extents); + if (!_lv_set_default_linear_params(vg->cmd, &lp)) + return_NULL; +- if (!lv_create_single(vg, &lp)) ++ if (!(lv = lv_create_single(vg, &lp))) + return_NULL; +- if (!(lvl = find_lv_in_vg(vg, name))) +- return NULL; +- return (lv_t) lvl->lv; ++ return (lv_t) lv; + } + + /* +diff --git a/man/lvconvert.8.in b/man/lvconvert.8.in +index 2659719..4fe9bdd 100644 +--- a/man/lvconvert.8.in ++++ b/man/lvconvert.8.in +@@ -40,7 +40,7 @@ lvconvert \- convert a logical volume from linear to mirror or snapshot + .B lvconvert + .BR \-s | \-\-snapshot + .RB [ \-c | \-\-chunksize +-.IR ChunkSize ] ++.IR ChunkSize [ bBsSkK ]] + .RB [ \-h | \-? | \-\-help ] + .RB [ \-\-noudevsync ] + .RB [ \-v | \-\-verbose ] +@@ -59,17 +59,6 @@ lvconvert \- convert a logical volume from linear to mirror or snapshot + .RB [ \-\-version ] + .IR LogicalVolume [ Path ]... + .sp +-.B lvconvert \-\-thinpool +-.IR ThinPoolLogicalVolume { Name | Path } +-.RB [ \-c | \-\-chunksize +-.IR ChunkSize ] +-.RB [ \-h | \-? | \-\-help ] +-.RB [ \-v | \-\-verbose ] +-.RB [ \-\-version ] +-.RB [ \-Z | \-\-zero +-.RI { y | n }] +-.IR ThinMetadataLogicalVolume { Name | Path } +-.sp + .B lvconvert \-\-repair + .RB [ \-h | \-? | \-\-help ] + .RB [ \-v | \-\-verbose ] +@@ -83,6 +72,31 @@ lvconvert \- convert a logical volume from linear to mirror or snapshot + .RB [ \-\-version ] + .IR LogicalVolume [ Path ] + .RI [ PhysicalVolume [ Path ]...] ++.sp ++.B lvconvert \-\-thinpool ++.IR ThinPoolLogicalVolume { Name | Path } ++.RB [ \-c | \-\-chunksize ++.IR ChunkSize [ bBsSkKmMgG ]] ++.RB [ \-\-discards ++.RI { ignore | nopassdown | passdown }] ++.RB [[ \-\-poolmetadata ++.IR ThinPoolMetadataLogicalVolume { Name | Path }] ++| ++.RB [ \-\-poolmetadatasize ++.IR ThinPoolMetadataSize [ bBsSkKmMgG ]] ++.RB [ \-r | \-\-readahead ++.RI { ReadAheadSectors | auto | none }] ++.RB [ \-\-stripes ++.I Stripes ++.RB [ \-I | \-\-stripesize ++.IR StripeSize ]]] ++.RB [ \-Z | \-\-zero ++.RI { y | n }] ++.RB [ \-h | \-? | \-\-help ] ++.RB [ \-v | \-\-verbose ] ++.RB [ \-\-version ] ++.RI [ PhysicalVolume [ Path ][ :PE [ -PE ]]...] ++.sp + + .SH DESCRIPTION + lvconvert is used to change the segment type (i.e. linear, mirror, etc) or +@@ -102,8 +116,9 @@ the freed extents come first from the specified PhysicalVolumes. + See \fBlvm\fP(8) for common options. + .br + Exactly one of +-.BR \-\-splitmirrors ", " \-\-mirrors ", " \-\-repair ", " \-\-snapshot +-or \fB\-\-merge\fP arguments is required. ++.BR \-\-merge ", " \-\-mirrors ", " \-\-repair ", " \-\-replace ++.RB ", " \-\-snapshot ", " \-\-splitmirrors " or " \-\-thinpool ++arguments is required. + .TP + .BR \-m ", " \-\-mirrors " " \fIMirrors + Specifies the degree of the mirror you wish to create. +@@ -170,12 +185,28 @@ implementation and not with the original device-mapper mirror implementation. + Create a snapshot from existing logical volume using another + existing logical volume as its origin. + .TP +-.BR \-c ", " \-\-chunksize " " \fIChunkSize +-Power of 2 chunk size for the snapshot logical volume between 4KiB and 512KiB. ++.BR \-c ", " \-\-chunksize " " \fIChunkSize [ \fIbBsSkKmMgG ] ++Gives the size of chunk for snapshot and thin pool logical volumes. ++For snapshots the value must be power of 2 between 4KiB and 512KiB ++and the default value is 4. ++For thin pools the value must be between 64KiB and ++1GiB and the default value starts with 64 and scales ++up to fit the pool metadata size within 128MB, ++if the pool metadata size is not specified. ++Older dm thin pool target version (<1.4) requires the value to be power of 2. ++The newer version requires to be the multiple of 64KiB, however discard is ++not supported for non power of 2 values. ++Default unit is in kilobytes. ++.TP ++.BR \-\-discards " {" \fIignore | \fInopassdown | \fIpassdown } ++Sets discards behavior for thin pool. ++Default is \fIpassdown\fP. + .TP + .BR \-Z ", " \-\-zero " {" \fIy | \fIn } + Controls zeroing of the first KB of data in the snapshot. + If the volume is read-only the snapshot will not be zeroed. ++For thin pool volumes it controls zeroing of provisioned blocks. ++Note: Provisioning of large zeroed chunks impacts performance. + .TP + .B \-\-merge + Merges a snapshot into its origin volume or merges a raid1 image that has +@@ -195,6 +226,35 @@ merge finishes, the merged snapshot is removed. Multiple snapshots may + be specified on the commandline or a @tag may be used to specify + multiple snapshots be merged to their respective origin. + .TP ++.BR \-\-poolmetadata " " \fIThinPoolMetadataLogicalVolume { \fIName | \fIPath } ++Specifies thin pool metadata logical volume. ++The size should be in between 2MiB and 16GiB. ++Thin pool is specified with the option ++\fB\-\-thinpool\fP. ++When the specified thin pool already exists, ++the thin pool's metadata volume will be swapped with the given LV. ++Properties of the thin pool like chunk size, discards or zero ++are preserved by default in this case. ++It can be useful for thin pool metadata repair or its offline resize, ++since the content of metadata becomes accessible for ++thin provisioning tools \fBthin_dump\fP(8) and \fBthin_restore\fP(8). ++.TP ++.BR \-\-poolmetadatasize " " \fIThinPoolMetadataSize [ \fIbBsSkKmMgG ] ++Sets the size of thin pool's metadata logical volume, ++if the pool metadata volume is undefined. ++Thin pool is specified with the option ++\fB\-\-thinpool\fP. ++Supported value is in the range between 2MiB and 16GiB. ++The default value is estimated with this formula ++(Pool_LV_size / Pool_LV_chunk_size * 64b). ++Default unit is megabytes. ++.TP ++.IR \fB\-r ", " \fB\-\-readahead " {" ReadAheadSectors | auto | none } ++Sets read ahead sector count of thin pool metadata logical volume. ++The default value is "auto" which allows the kernel to choose ++a suitable value automatically. ++"None" is equivalent to specifying zero. ++.TP + .B \-\-repair + Repair a mirror after suffering a disk failure. The mirror will be brought back + into a consistent state. By default, the original number of mirrors will be +@@ -210,6 +270,24 @@ Remove the specified device (\fIPhysicalVolume\fP) and replace it with one + that is available in the volume group or from the specific list provided. + This option is only available to RAID segment types + (e.g. "raid1", "raid5", etc). ++.TP ++.BR \-\-stripes " " \fIStripes ++Gives the number of stripes. ++This is equal to the number of physical volumes to scatter ++the logical volume. ++.TP ++.BR \-I ", " \-\-stripesize " " \fIStripeSize ++Gives the number of kilobytes for the granularity of the stripes. ++.br ++StripeSize must be 2^n (n = 2 to 9) for metadata in LVM1 format. ++For metadata in LVM2 format, the stripe size may be a larger ++power of 2 but must not exceed the physical extent size. ++.TP ++.IR \fB\-\-thinpool " " ThinPoolLogicalVolume { Name | Path } ++Changes logical volume into a thin pool volume. The volume ++will store the pool's data. ++Thin pool metadata logical volume can be specified with the option ++\fB\-\-poolmetadata\fP or allocated with \fB\-\-poolmetadatasize\fP. + + .SH Examples + Converts the linear logical volume "vg00/lvol1" to a two-way mirror +@@ -304,4 +382,6 @@ available in the volume group. + .BR lvextend (8), + .BR lvreduce (8), + .BR lvdisplay (8), +-.BR lvscan (8) ++.BR lvscan (8), ++.BR thin_dump(8), ++.BR thin_restore(8) +diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in +index fb54cc6..0616150 100644 +--- a/man/lvcreate.8.in ++++ b/man/lvcreate.8.in +@@ -53,11 +53,11 @@ lvcreate \- create a logical volume in an existing volume group + .RB [ \-t | \-\-test ] + .RB [ \-T | \-\-thin + .RB [ \-c | \-\-chunksize +-.IR ChunkSize ] ++.IR ChunkSize [ bBsSkKmMgG ]] + .RB [ \-\-discards + .RI { ignore | nopassdown | passdown }] + .RB [ \-\-poolmetadatasize +-.IR MetadataSize [ bBsSkKmMgG ]]] ++.IR ThinPoolMetadataSize [ bBsSkKmMgG ]]] + .RB [ \-\-thinpool + .IR ThinPoolLogicalVolume { Name | Path }] + .RB [ \-\-type +@@ -76,7 +76,7 @@ lvcreate \- create a logical volume in an existing volume group + .BR \-L | \-\-size + .IR LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]] + .RB [ \-c | \-\-chunksize +-.IR ChunkSize ] ++.IR ChunkSize [ bBsSkK ]] + .RB [ \-\-noudevsync ] + .RB [ \-\-ignoremonitoring ] + .RB [ \-\-monitor " {" \fIy | \fIn }] +@@ -125,14 +125,14 @@ always assumed and it can't be overridden. If clustered locking is enabled, + \fB\-a\fIey\fR will activate exclusively on one node and \fB\-a\fIly\fR will + activate only on the local node. + .TP +-.BR \-c ", " \-\-chunksize " " \fIChunkSize ++.BR \-c ", " \-\-chunksize " " \fIChunkSize [ \fIbBsSkKmMgG ] + Gives the size of chunk for snapshot and thin pool logical volumes. + For snapshots the value must be power of 2 between 4KiB and 512KiB + and the default value is 4. + For thin pools the value must be between 64KiB and +-1048576KiB and the default value starts with 64 and scales ++1GiB and the default value starts with 64 and scales + up to fit the pool metadata size within 128MB, +-if the poolmetadata size is not specified. ++if the pool metadata size is not specified. + Older dm thin pool target version (<1.4) requires the value to be power of 2. + The newer version requires to be the multiple of 64KiB, however discard is + not supported for non power of 2 values. +@@ -144,7 +144,7 @@ logical volumes. Default is no contiguous allocation based + on a next free principle. + .TP + .BR \-\-discards " {" \fIignore | \fInopassdown | \fIpassdown } +-Set discards behavior. ++Set discards behavior for thin pool. + Default is \fIpassdown\fP. + .TP + .BR \-i ", " \-\-stripes " " \fIStripes +@@ -236,7 +236,7 @@ Set access permissions to read only or read and write. + .br + Default is read and write. + .TP +-.IR \fB\-\-poolmetadatasize " " MetadataSize [ bBsSkKmMgG ] ++.IR \fB\-\-poolmetadatasize " " ThinPoolMetadataSize [ bBsSkKmMgG ] + Set the size of thin pool's metadata logical volume. + Supported value is in range between 2MiB and 16GiB. + Default value is (Pool_LV_size / Pool_LV_chunk_size * 64b). +@@ -364,7 +364,7 @@ a parity drive for a total of 4 devices) and a stripesize of 64KiB: + .B lvcreate \-\-type raid5 \-L 5G \-i 3 \-I 64 \-n my_lv vg00 + + Creates 100MiB pool logical volume for thin provisioning +-build with 2 stripes 64KiB and chunk size 128KiB together with ++build with 2 stripes 64KiB and chunk size 256KiB together with + 1TiB thin provisioned logical volume "vg00/thin_lv": + .sp + .B lvcreate \-i 2 \-I 64 \-c 256 \-L100M \-T vg00/pool \-V 1T \-\-name thin_lv +diff --git a/man/vgcfgrestore.8.in b/man/vgcfgrestore.8.in +index 3b7b038..7b8dd59 100644 +--- a/man/vgcfgrestore.8.in ++++ b/man/vgcfgrestore.8.in +@@ -6,6 +6,7 @@ vgcfgrestore \- restore volume group descriptor area + .RB [ \-d | \-\-debug ] + .RB [ \-f | \-\-file + .RI < filename >] ++.RB [ \-\-force ] + .RB [ \-l [ l ]| \-\-list ] + .RB [ \-h | \-\-help ] + .RB [ \-M | \-\-metadatatype +@@ -32,6 +33,14 @@ May be used with the \fB\-f\fP option. Does not restore \fIVolumeGroupName\fP. + Name of LVM metadata backup file + Specifies a metadata backup or archive file to be used for restoring + VolumeGroupName. Often this file has been created with \fBvgcfgbackup\fP. ++.TP ++.B \-\-force ++To restore metadata with thin pool volumes, user currently ++needs to use this flag. The tool DOES NOT make any validation. ++.br ++WARNING: Restoring lvm2 metadata that are not matching thin pool ++kernel metadata may lead to the destruction of the pool content. ++Use with extreme caution. + .SH REPLACING PHYSICAL VOLUMES + \fBvgdisplay \-\-partial \-\-verbose\fP will show you the UUIDs and sizes of + any PVs that are no longer present. +diff --git a/test/api/thin_percent.c b/test/api/thin_percent.c +index 2c8b19b..ae511df 100644 +--- a/test/api/thin_percent.c ++++ b/test/api/thin_percent.c +@@ -23,6 +23,8 @@ int main(int argc, char *argv[]) + vg_t vg; + lv_t lv; + struct lvm_property_value v; ++ struct dm_list *lvsegs; ++ struct lvm_lvseg_list *lvl; + + handle = lvm_init(NULL); + assert(handle); +@@ -33,6 +35,14 @@ int main(int argc, char *argv[]) + lv = lvm_lv_from_name(vg, "pool"); + assert(lv); + ++ lvsegs = lvm_lv_list_lvsegs(lv); ++ assert(lvsegs && (dm_list_size(lvsegs) == 1)); ++ dm_list_iterate_items(lvl, lvsegs) { ++ v = lvm_lvseg_get_property(lvl->lvseg, "discards"); ++ assert(v.is_valid && v.is_string); ++ assert(strcmp(v.value.string, "passdown") == 0); ++ } ++ + v = lvm_lv_get_property(lv, "data_percent"); + assert(v.is_valid); + assert(v.value.integer == 25 * PERCENT_1); +diff --git a/test/api/thin_percent.sh b/test/api/thin_percent.sh +index 9287cf3..e14e807 100644 +--- a/test/api/thin_percent.sh ++++ b/test/api/thin_percent.sh +@@ -30,7 +30,7 @@ dd if=/dev/urandom of="$DM_DEV_DIR/$vg/thin" count=2 bs=256K + lvcreate -s $vg/thin -n snap + dd if=/dev/urandom of="$DM_DEV_DIR/$vg/snap" count=3 bs=256K + +-lvs $vg ++lvs -o+discards $vg + + aux apitest thin_percent $vg + +diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh +index 97ccc09..4634aa2 100644 +--- a/test/shell/lvconvert-thin.sh ++++ b/test/shell/lvconvert-thin.sh +@@ -12,6 +12,13 @@ + + . lib/test + ++prepare_lvs() ++{ ++ lvremove -f $vg ++ lvcreate -L10M -n $lv1 $vg ++ lvcreate -L8M -n $lv2 $vg ++} ++ + # + # Main + # +@@ -19,25 +26,73 @@ aux have_thin 1 0 0 || skip + + aux prepare_pvs 4 64 + +-vgcreate $vg -s 64K $(cat DEVICES) ++# build one large PV ++vgcreate $vg1 $(cut -d ' ' -f -3 DEVICES) ++lvcreate -s -l 100%FREE -n $lv $vg1 --virtualsize 64T ++aux lvmconf 'devices/filter = [ "a/dev\/mapper\/.*$/", "a/dev\/LVMTEST/", "r/.*/" ]' ++ ++pvcreate "$DM_DEV_DIR/$vg1/$lv" ++vgcreate $vg -s 64K $(cut -d ' ' -f 4 DEVICES) "$DM_DEV_DIR/$vg1/$lv" + + # create mirrored LVs for data and metadata volumes +-lvcreate -aey -l8 -m1 --mirrorlog core -n $lv1 $vg +-lvcreate -aey -l4 -m1 --mirrorlog core -n $lv2 $vg ++lvcreate -aey -L10M -m1 --mirrorlog core -n $lv1 $vg ++lvcreate -aey -L8M -m1 --mirrorlog core -n $lv2 $vg ++lvchange -an $vg/$lv1 ++ ++ ++# conversion fails for internal volumes ++not lvconvert --thinpool $vg/${lv1}_mimage_0 ++not lvconvert --thinpool $vg/$lv1 --poolmetadata $vg/${lv2}_mimage_0 ++# can't use --readahead with --poolmetadata ++not lvconvert --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 --readahead 512 ++ ++lvconvert --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 ++ ++prepare_lvs ++lvconvert -c 64 --stripes 2 --thinpool $vg/$lv1 --readahead 48 ++ ++lvremove -f $vg ++lvcreate -L1T -n $lv1 $vg ++lvconvert -c 8M --thinpool $vg/$lv1 ++ ++lvremove -f $vg ++# test with bigger sizes ++lvcreate -L1T -n $lv1 $vg ++lvcreate -L8M -n $lv2 $vg ++lvcreate -L1M -n $lv3 $vg + +-lvconvert -c 64K --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 ++# chunk size is bigger then size of thin pool data ++not lvconvert -c 1G --thinpool $vg/$lv3 ++# stripes can't be used with poolmetadata ++not lvconvert --stripes 2 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 ++# too small metadata (<2M) ++not lvconvert -c 64 --thinpool $vg/$lv1 --poolmetadata $vg/$lv3 ++# too small chunk size fails ++not lvconvert -c 4 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 ++# too big chunk size fails ++not lvconvert -c 2G --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 ++# negative chunk size fails ++not lvconvert -c -256 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 ++# non power of 2 fails ++not lvconvert -c 88 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 + +-lvcreate -V10M -T $vg/$lv1 --name $lv3 ++# Warning about smaller then suggested ++lvconvert -c 256 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 |& tee err ++grep "WARNING: Chunk size is smaller" err + +-# check lvrename work properly +-lvrename $vg/$lv1 $vg/pool +-check lv_field $vg/pool name "pool" ++lvremove -f $vg ++lvcreate -L1T -n $lv1 $vg ++lvcreate -L32G -n $lv2 $vg ++# Warning about bigger then needed ++lvconvert --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 |& tee err ++grep "WARNING: Maximum size" err + +-lvrename $vg/$lv3 $vg/$lv4 +-check lv_field $vg/$lv4 name "$lv4" ++lvremove -f $vg ++lvcreate -L24T -n $lv1 $vg ++# Warning about bigger then needed (24T data and 16G -> 128K chunk) ++lvconvert -c 64 --thinpool $vg/$lv1 |& tee err ++grep "WARNING: Chunk size is too small" err + +-# not yet supported conversions +-not lvconvert -m 1 $vg/pool +-not lvconvert -m 1 $vg/$lv3 ++#lvs -a -o+chunk_size,stripe_size,seg_pe_ranges + + vgremove -ff $vg +diff --git a/test/shell/thin-defaults.sh b/test/shell/thin-defaults.sh +new file mode 100644 +index 0000000..677d2f1 +--- /dev/null ++++ b/test/shell/thin-defaults.sh +@@ -0,0 +1,35 @@ ++#!/bin/bash ++# Copyright (C) 2012 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 defaults entered through lvm.conf ++ ++. lib/test ++ ++# ++# Main ++# ++aux have_thin 1 0 0 || skip ++ ++aux prepare_vg 2 ++ ++lvcreate -T -L8M $vg/pool0 ++ ++aux lvmconf "allocation/thin_pool_chunk_size = 128" \ ++ "allocation/thin_pool_discards = \"ignore\"" \ ++ "allocation/thin_pool_zero = 0" ++ ++lvcreate -T -L8M $vg/pool1 ++ ++check lv_field $vg/pool1 chunksize "128.00k" ++check lv_field $vg/pool1 discards "ignore" ++check lv_field $vg/pool1 zero 0 ++ ++vgremove -f $vg +diff --git a/test/shell/thin-restore.sh b/test/shell/thin-restore.sh +new file mode 100644 +index 0000000..7580ae4 +--- /dev/null ++++ b/test/shell/thin-restore.sh +@@ -0,0 +1,34 @@ ++#!/bin/bash ++# Copyright (C) 2012 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 restore operation of thin pool metadata ++ ++. lib/test ++ ++# ++# Main ++# ++aux have_thin 1 0 0 || skip ++ ++aux prepare_vg 2 ++ ++lvcreate -T -L8M $vg/pool -V10M -n $lv1 ++ ++vgcfgbackup -f backup $vg ++ ++# use of --force is mandatory ++not vgcfgrestore -f backup $vg ++ ++vgcfgrestore -f backup --force $vg ++ ++check lv_field $vg/pool transaction_id 1 ++ ++vgremove -f $vg +diff --git a/tools/args.h b/tools/args.h +index 0d9605a..d4d6c40 100644 +--- a/tools/args.h ++++ b/tools/args.h +@@ -73,6 +73,7 @@ arg(poll_ARG, '\0', "poll", yes_no_arg, 0) + arg(poolmetadata_ARG, '\0', "poolmetadata", string_arg, 0) + arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", size_mb_arg, 0) + arg(discards_ARG, '\0', "discards", discards_arg, 0) ++arg(force_long_ARG, '\0', "force", NULL, ARG_COUNTABLE) + arg(stripes_long_ARG, '\0', "stripes", int_arg, 0) + arg(sysinit_ARG, '\0', "sysinit", NULL, 0) + arg(thinpool_ARG, '\0', "thinpool", string_arg, 0) +diff --git a/tools/commands.h b/tools/commands.h +index 6415d34..986539e 100644 +--- a/tools/commands.h ++++ b/tools/commands.h +@@ -147,13 +147,16 @@ xx(lvconvert, + "--thinpool ThinPoolLogicalVolume[Path]\n" + "\t[--chunksize size]\n" + "\t[--discards {ignore|nopassdown|passdown}]\n" +- "\t[[--poolmetadatasize size] | --poolmetadata ThinMetadataLogicalVolume[Path]]\n" ++ "\t[--poolmetadata ThinMetadataLogicalVolume[Path] |\n" ++ "\t [--poolmetadatasize size]\n" ++ "\t [-r|--readahead ReadAheadSectors|auto|none]\n" ++ "\t [--stripes Stripes [-I|--stripesize StripeSize]]]\n" + "\t[-Z|--zero {y|n}]\n" + "\t[-d|--debug] [-h|-?|--help] [-v|--verbose]\n", + + alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG, interval_ARG, + merge_ARG, mirrorlog_ARG, mirrors_ARG, name_ARG, noudevsync_ARG, +- regionsize_ARG, repair_ARG, replace_ARG, snapshot_ARG, splitmirrors_ARG, ++ readahead_ARG, regionsize_ARG, repair_ARG, replace_ARG, snapshot_ARG, splitmirrors_ARG, + trackchanges_ARG, type_ARG, stripes_long_ARG, stripesize_ARG, test_ARG, + chunksize_ARG, discards_ARG, poolmetadata_ARG, poolmetadatasize_ARG, thinpool_ARG, + use_policies_ARG, yes_ARG, force_ARG, zero_ARG) +@@ -722,6 +725,7 @@ xx(vgcfgrestore, + "vgcfgrestore " "\n" + "\t[-d|--debug] " "\n" + "\t[-f|--file filename] " "\n" ++ "\t[--force]\n" + "\t[-l[l]|--list [--list]]" "\n" + "\t[-M|--metadatatype 1|2]" "\n" + "\t[-h|--help]" "\n" +@@ -730,7 +734,7 @@ xx(vgcfgrestore, + "\t[--version] " "\n" + "\tVolumeGroupName", + +- file_ARG, list_ARG, metadatatype_ARG, test_ARG) ++ file_ARG, force_long_ARG, list_ARG, metadatatype_ARG, test_ARG) + + xx(vgchange, + "Change volume group attributes", +diff --git a/tools/lvchange.c b/tools/lvchange.c +index 04facdd..7156eeb 100644 +--- a/tools/lvchange.c ++++ b/tools/lvchange.c +@@ -111,13 +111,7 @@ static int lvchange_pool_update(struct cmd_context *cmd, + if (arg_count(cmd, discards_ARG)) { + discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_IGNORE); + if (discards != first_seg(lv)->discards) { +- if ((discards != THIN_DISCARDS_IGNORE) && +- (first_seg(lv)->chunk_size & +- (first_seg(lv)->chunk_size - 1))) +- log_error("Cannot change discards state for " +- "logical volume \"%s\" " +- "with non power of 2 chunk size.", lv->name); +- else if (((discards == THIN_DISCARDS_IGNORE) || ++ if (((discards == THIN_DISCARDS_IGNORE) || + (first_seg(lv)->discards == THIN_DISCARDS_IGNORE)) && + lv_is_active(lv)) + log_error("Cannot change discards state for active " +diff --git a/tools/lvconvert.c b/tools/lvconvert.c +index 132a69d..c584180 100644 +--- a/tools/lvconvert.c ++++ b/tools/lvconvert.c +@@ -39,8 +39,10 @@ struct lvconvert_params { + uint32_t keep_mimages; + uint32_t stripes; + uint32_t stripe_size; ++ uint32_t read_ahead; + + const struct segment_type *segtype; ++ unsigned target_attr; + + alloc_policy_t alloc; + +@@ -155,6 +157,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd, + int pagesize = lvm_getpagesize(); + + memset(lp, 0, sizeof(*lp)); ++ lp->target_attr = ~0; + + if ((arg_count(cmd, snapshot_ARG) || arg_count(cmd, merge_ARG)) && + (arg_count(cmd, mirrorlog_ARG) || arg_count(cmd, mirrors_ARG) || +@@ -268,6 +271,8 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd, + if (lp->merge) { /* Snapshot merge */ + if (arg_count(cmd, regionsize_ARG) || arg_count(cmd, chunksize_ARG) || + arg_count(cmd, zero_ARG) || arg_count(cmd, regionsize_ARG) || ++ arg_count(cmd, poolmetadata_ARG) || arg_count(cmd, poolmetadatasize_ARG) || ++ arg_count(cmd, readahead_ARG) || + arg_count(cmd, stripes_long_ARG) || arg_count(cmd, stripesize_ARG)) { + log_error("Only --background and --interval are valid " + "arguments for snapshot merge"); +@@ -335,53 +340,21 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd, + return 0; + } + ++ if (!get_pool_params(cmd, ++ &lp->chunk_size, ++ &lp->discards, ++ &lp->poolmetadata_size, ++ &lp->zero)) ++ return_0; ++ + if (arg_count(cmd, poolmetadata_ARG)) { +- lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, ""); +- } else if (arg_count(cmd, poolmetadatasize_ARG)) { +- if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) { +- log_error("Negative pool metadata size is invalid."); ++ if (arg_count(cmd, poolmetadatasize_ARG)) { ++ log_error("--poolmetadatasize is invalid with --poolmetadata."); + return 0; + } +- lp->poolmetadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG, UINT64_C(0)); +- +- if (lp->poolmetadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { +- if (arg_count(cmd, poolmetadatasize_ARG)) +- log_warn("WARNING: Maximum supported pool metadata size is 16GB."); +- lp->poolmetadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; +- } else if (lp->poolmetadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) { +- if (arg_count(cmd, poolmetadatasize_ARG)) +- log_warn("WARNING: Minimum supported pool metadata size is 2M."); +- lp->poolmetadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE; +- } +- +- log_verbose("Setting pool metadata size to %" PRIu64 " sectors.", +- lp->poolmetadata_size); ++ lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, ""); + } + +- if (arg_count(cmd, chunksize_ARG)) { +- if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) { +- log_error("Negative chunk size is invalid."); +- return 0; +- } +- lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, +- DM_THIN_MIN_DATA_BLOCK_SIZE); +- +- if ((lp->chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) || +- (lp->chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) { +- log_error("Chunk size must be in the range %uK to %uK.", +- (DM_THIN_MIN_DATA_BLOCK_SIZE / 2), +- (DM_THIN_MAX_DATA_BLOCK_SIZE / 2)); +- return 0; +- } +- } else +- lp->chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE; +- +- log_verbose("Setting pool metadata chunk size to %u sectors.", +- lp->chunk_size); +- +- if (arg_count(cmd, zero_ARG)) +- lp->zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n"); +- + /* If --thinpool contains VG name, extract it. */ + if ((tmp_str = strchr(lp->pool_data_lv_name, (int) '/'))) { + if (!(lp->vg_name = extract_vgname(cmd, lp->pool_data_lv_name))) +@@ -460,7 +433,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd, + } + + if (activation() && lp->segtype && lp->segtype->ops->target_present && +- !lp->segtype->ops->target_present(cmd, NULL, NULL)) { ++ !lp->segtype->ops->target_present(cmd, NULL, &lp->target_attr)) { + log_error("%s: Required device-mapper target(s) not " + "detected in your kernel", lp->segtype->name); + return 0; +@@ -1826,12 +1799,20 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, + { + int r = 0; + char *name; ++ const char *old_name; + int len; + struct lv_segment *seg; + struct logical_volume *data_lv; + struct logical_volume *metadata_lv; ++ struct logical_volume *pool_metadata_lv; ++ ++ if (!lv_is_visible(pool_lv)) { ++ log_error("Can't convert internal LV %s/%s.", ++ pool_lv->vg->name, pool_lv->name); ++ return 0; ++ } + +- if (lv_is_thin_type(pool_lv)) { ++ if (lv_is_thin_type(pool_lv) && !lp->pool_metadata_lv_name) { + log_error("Can't use thin logical volume %s/%s for thin pool data.", + pool_lv->vg->name, pool_lv->name); + return 0; +@@ -1839,19 +1820,48 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, + + /* We are changing target type, so deactivate first */ + if (!deactivate_lv(cmd, pool_lv)) { +- log_error("Can't deactivate logical volume %s/%s.", ++ log_error("Aborting. Failed to deactivate logical volume %s/%s.", + pool_lv->vg->name, pool_lv->name); + return 0; + } + ++ len = strlen(pool_lv->name) + 16; ++ if (!(name = dm_pool_alloc(pool_lv->vg->vgmem, len))) { ++ log_error("Can't allocate new name."); ++ return 0; ++ } ++ ++ if (dm_snprintf(name, len, "%s_tmeta", pool_lv->name) < 0) { ++ log_error("Failed to create layer name."); ++ return 0; ++ } ++ + if (lp->pool_metadata_lv_name) { ++ if (arg_count(cmd, stripesize_ARG) || arg_count(cmd, stripes_long_ARG)) { ++ log_error("Can't use --stripes and --stripesize with --poolmetadata."); ++ return 0; ++ } ++ if (arg_count(cmd, readahead_ARG)) { ++ log_error("Can't use --readahead with --poolmetadata."); ++ return 0; ++ } + metadata_lv = find_lv(pool_lv->vg, lp->pool_metadata_lv_name); + if (!metadata_lv) { +- log_error("Unknown metadata LV %s", lp->pool_metadata_lv_name); ++ log_error("Unknown metadata LV %s.", lp->pool_metadata_lv_name); ++ return 0; ++ } ++ if (!lv_is_visible(metadata_lv)) { ++ log_error("Can't convert internal LV %s/%s.", ++ metadata_lv->vg->name, metadata_lv->name); ++ return 0; ++ } ++ if (metadata_lv->status & LOCKED) { ++ log_error("Can't convert locked LV %s/%s.", ++ metadata_lv->vg->name, metadata_lv->name); + return 0; + } + if (metadata_lv == pool_lv) { +- log_error("Can't use same LV for thin data and metadata LV %s", ++ log_error("Can't use same LV for thin pool data and metadata LV %s.", + lp->pool_metadata_lv_name); + return 0; + } +@@ -1861,37 +1871,95 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, + metadata_lv->vg->name, metadata_lv->name); + return 0; + } +- } else if (arg_count(cmd, poolmetadatasize_ARG)) { +- /* FIXME: allocate metadata LV! */ +- metadata_lv = NULL; +- log_error("Uncreated metadata."); +- return 0; +- } else { +- log_error("Uknown metadata."); +- return 0; +- } + +- len = strlen(pool_lv->name) + 16; +- if (!(name = dm_pool_alloc(pool_lv->vg->vgmem, len))) { +- log_error("Cannot allocate new name."); +- return 0; +- } ++ /* Swap normal LV with pool's metadata LV ? */ ++ if (lv_is_thin_pool(pool_lv)) { ++ if (!deactivate_lv(cmd, metadata_lv)) { ++ log_error("Aborting. Failed to deactivate thin metadata lv."); ++ return 0; ++ } ++ if (!arg_count(cmd, yes_ARG) && ++ yes_no_prompt("Do you want to swap metadata of %s/%s pool with " ++ "volume %s/%s? [y/n]: ", ++ pool_lv->vg->name, pool_lv->name, ++ pool_lv->vg->name, metadata_lv->name) == 'n') { ++ log_error("Conversion aborted."); ++ return 0; ++ } ++ seg = first_seg(pool_lv); ++ /* Swap names between old and new metadata LV */ ++ if (!detach_pool_metadata_lv(seg, &pool_metadata_lv)) ++ return_0; ++ old_name = metadata_lv->name; ++ if (!lv_rename_update(cmd, metadata_lv, "pvmove_tmeta", 0)) ++ return_0; ++ if (!lv_rename_update(cmd, pool_metadata_lv, old_name, 0)) ++ return_0; + +- if (!lv_is_active(metadata_lv)) { +- if (!deactivate_lv(cmd, metadata_lv)) { +- log_error("Can't deactivate logical volume %s/%s.", +- metadata_lv->vg->name, metadata_lv->name); +- return 0; ++ if (!arg_count(cmd, chunksize_ARG)) ++ lp->chunk_size = seg->chunk_size; ++ else if ((lp->chunk_size != seg->chunk_size) && ++ !arg_count(cmd, force_ARG) && ++ yes_no_prompt("Do you really want to change chunk size %s to %s for %s/%s " ++ "pool volume? [y/n]: ", display_size(cmd, seg->chunk_size), ++ display_size(cmd, lp->chunk_size), ++ pool_lv->vg->name, pool_lv->name) == 'n') { ++ log_error("Conversion aborted."); ++ return 0; ++ } ++ if (!arg_count(cmd, discards_ARG)) ++ lp->discards = seg->discards; ++ if (!arg_count(cmd, zero_ARG)) ++ lp->zero = seg->zero_new_blocks; ++ ++ goto mda_write; + } +- if (!activate_lv_local(cmd, metadata_lv)) { ++ ++ if (!lv_is_active(metadata_lv) && ++ !activate_lv_local(cmd, metadata_lv)) { + log_error("Aborting. Failed to activate thin metadata lv."); + return 0; + } +- } ++ if (!set_lv(cmd, metadata_lv, UINT64_C(0), 0)) { ++ log_error("Aborting. Failed to wipe thin metadata lv."); ++ return 0; ++ } + +- if (!set_lv(cmd, metadata_lv, UINT64_C(0), 0)) { +- log_error("Aborting. Failed to wipe thin metadata lv."); +- return 0; ++ lp->poolmetadata_size = ++ (uint64_t) metadata_lv->le_count * metadata_lv->vg->extent_size; ++ if (lp->poolmetadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { ++ log_warn("WARNING: Maximum size used by metadata is %s, rest is unused.", ++ display_size(cmd, 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)); ++ lp->poolmetadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; ++ } else if (lp->poolmetadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) { ++ log_error("Logical volume %s/%s is too small (<%s) for metadata.", ++ metadata_lv->vg->name, metadata_lv->name, ++ display_size(cmd, 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)); ++ return 0; ++ } ++ if (!update_pool_params(cmd, lp->target_attr, ++ pool_lv->le_count, pool_lv->vg->extent_size, ++ &lp->chunk_size, &lp->discards, ++ &lp->poolmetadata_size)) ++ return_0; ++ } else { ++ if (!update_pool_params(cmd, lp->target_attr, ++ pool_lv->le_count, pool_lv->vg->extent_size, ++ &lp->chunk_size, &lp->discards, ++ &lp->poolmetadata_size)) ++ return_0; ++ ++ if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size)) ++ return_0; ++ /* Hmm _read_activation_params */ ++ lp->read_ahead = arg_uint_value(cmd, readahead_ARG, ++ cmd->default_settings.read_ahead); ++ ++ if (!(metadata_lv = alloc_pool_metadata(pool_lv, lp->alloc, name, ++ lp->pvh, lp->read_ahead, ++ lp->stripes, lp->stripe_size, ++ lp->poolmetadata_size))) ++ return_0; + } + + if (!deactivate_lv(cmd, metadata_lv)) { +@@ -1900,14 +1968,6 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, + return 0; + } + +- if (dm_snprintf(name, len, "%s_tmeta", pool_lv->name) < 0) +- return_0; +- +- /* Rename deactivated metadata LV to have _tmeta suffix */ +- /* Implicit checks if metadata_lv is visible */ +- if (!lv_rename_update(cmd, metadata_lv, name, 0)) +- return_0; +- + /* + * Since we wish to have underlaying dev, to match _tdata + * rename data LV first, also checks for visible LV +@@ -1925,18 +1985,26 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, + seg->segtype = lp->segtype; + seg->lv->status |= THIN_POOL; + +- seg->chunk_size = lp->chunk_size; +- seg->zero_new_blocks = lp->zero ? 1 : 0; +- seg->discards = lp->discards; ++ /* Drop reference as attach_pool_data_lv() takes it again */ ++ remove_seg_from_segs_using_this_lv(data_lv, seg); ++ if (!attach_pool_data_lv(seg, data_lv)) ++ return_0; ++ + seg->low_water_mark = 0; + seg->transaction_id = 0; + +- if (!attach_pool_metadata_lv(seg, metadata_lv)) ++mda_write: ++ seg->chunk_size = lp->chunk_size; ++ seg->discards = lp->discards; ++ seg->zero_new_blocks = lp->zero ? 1 : 0; ++ ++ /* Rename deactivated metadata LV to have _tmeta suffix */ ++ /* Implicit checks if metadata_lv is visible */ ++ if (strcmp(metadata_lv->name, name) && ++ !lv_rename_update(cmd, metadata_lv, name, 0)) + return_0; + +- /* Drop reference as attach_pool_data_lv() takes it again */ +- remove_seg_from_segs_using_this_lv(data_lv, seg); +- if (!attach_pool_data_lv(seg, data_lv)) ++ if (!attach_pool_metadata_lv(seg, metadata_lv)) + return_0; + + if (!vg_write(pool_lv->vg) || !vg_commit(pool_lv->vg)) +@@ -1945,6 +2013,11 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, + if (!activate_lv_excl(cmd, pool_lv)) { + log_error("Failed to activate pool logical volume %s/%s.", + pool_lv->vg->name, pool_lv->name); ++ /* Deactivate subvolumes */ ++ if (!deactivate_lv(cmd, seg_lv(seg, 0))) ++ log_error("Failed to deactivate pool data logical volume."); ++ if (!deactivate_lv(cmd, seg->metadata_lv)) ++ log_error("Failed to deactivate pool metadata logical volume."); + goto out; + } + +diff --git a/tools/lvcreate.c b/tools/lvcreate.c +index 3ea8f46..1fcbde3 100644 +--- a/tools/lvcreate.c ++++ b/tools/lvcreate.c +@@ -234,7 +234,6 @@ static int _update_extents_params(struct volume_group *vg, + { + uint32_t pv_extent_count; + struct logical_volume *origin = NULL; +- int changed = 0; + uint32_t size_rest; + uint32_t stripesize_extents; + +@@ -308,38 +307,11 @@ static int _update_extents_params(struct volume_group *vg, + } + + if (lp->create_thin_pool) { +- if (!arg_count(vg->cmd, poolmetadatasize_ARG)) { +- /* Defaults to nr_pool_blocks * 64b */ +- lp->poolmetadatasize = (uint64_t) lp->extents * vg->extent_size / +- (uint64_t) (lp->chunk_size * (SECTOR_SIZE / UINT64_C(64))); +- +- /* Check if we could eventually use bigger chunk size */ +- if (!arg_count(vg->cmd, chunksize_ARG)) { +- while ((lp->poolmetadatasize > +- (DEFAULT_THIN_POOL_OPTIMAL_SIZE / SECTOR_SIZE)) && +- (lp->chunk_size < DM_THIN_MAX_DATA_BLOCK_SIZE)) { +- lp->chunk_size <<= 1; +- lp->poolmetadatasize >>= 1; +- changed++; +- } +- if (changed) +- log_verbose("Changed chunksize to %u sectors.", +- lp->chunk_size); +- } +- } +- +- if (lp->poolmetadatasize > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { +- if (arg_count(vg->cmd, poolmetadatasize_ARG)) +- log_warn("WARNING: Maximum supported pool metadata size is 16GB."); +- lp->poolmetadatasize = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; +- } else if (lp->poolmetadatasize < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) { +- if (arg_count(vg->cmd, poolmetadatasize_ARG)) +- log_warn("WARNING: Minimum supported pool metadata size is 2M."); +- lp->poolmetadatasize = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE; +- } +- +- log_verbose("Setting pool metadata size to %" PRIu64 " sectors.", +- lp->poolmetadatasize); ++ if (!update_pool_params(vg->cmd, lp->target_attr, ++ lp->extents, vg->extent_size, ++ &lp->chunk_size, &lp->discards, ++ &lp->poolmetadatasize)) ++ return_0; + + if (!(lp->poolmetadataextents = + extents_from_size(vg->cmd, lp->poolmetadatasize, vg->extent_size))) +@@ -386,16 +358,9 @@ static int _read_size_params(struct lvcreate_params *lp, + if (lp->thin && (arg_count(cmd, size_ARG) || arg_count(cmd, extents_ARG))) + lp->create_thin_pool = 1; + +- if (arg_count(cmd, poolmetadatasize_ARG)) { +- if (!seg_is_thin(lp)) { +- log_error("--poolmetadatasize may only be specified when allocating the thin pool."); +- return 0; +- } +- if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) { +- log_error("Negative poolmetadatasize is invalid."); +- return 0; +- } +- lp->poolmetadatasize = arg_uint64_value(cmd, poolmetadatasize_ARG, UINT64_C(0)); ++ if (arg_count(cmd, poolmetadatasize_ARG) && !seg_is_thin(lp)) { ++ log_error("--poolmetadatasize may only be specified when allocating the thin pool."); ++ return 0; + } + + /* Size returned in kilobyte units; held in sectors */ +@@ -679,11 +644,11 @@ static int _lvcreate_params(struct lvcreate_params *lp, + struct arg_value_group_list *current_group; + const char *segtype_str; + const char *tag; +- unsigned attr = 0; + + memset(lp, 0, sizeof(*lp)); + memset(lcp, 0, sizeof(*lcp)); + dm_list_init(&lp->tags); ++ lp->target_attr = ~0; + + /* + * Check selected options are compatible and determine segtype +@@ -796,7 +761,7 @@ static int _lvcreate_params(struct lvcreate_params *lp, + } + + if (activation() && lp->segtype->ops->target_present && +- !lp->segtype->ops->target_present(cmd, NULL, &attr)) { ++ !lp->segtype->ops->target_present(cmd, NULL, &lp->target_attr)) { + log_error("%s: Required device-mapper target(s) not " + "detected in your kernel", lp->segtype->name); + return 0; +@@ -812,16 +777,23 @@ static int _lvcreate_params(struct lvcreate_params *lp, + } + } + ++ /* ++ * Should we zero the lv. ++ */ ++ lp->zero = strcmp(arg_str_value(cmd, zero_ARG, ++ (lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? "n" : "y"), "n"); ++ + if (!_lvcreate_name_params(lp, cmd, &argc, &argv) || + !_read_size_params(lp, lcp, cmd) || + !get_stripe_params(cmd, &lp->stripes, &lp->stripe_size) || ++ (lp->create_thin_pool && ++ !get_pool_params(cmd, &lp->chunk_size, &lp->discards, ++ &lp->poolmetadatasize, &lp->zero)) || + !_read_mirror_params(lp, cmd) || + !_read_raid_params(lp, cmd)) + return_0; + +- if (lp->create_thin_pool) +- lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN); +- else if (arg_count(cmd, discards_ARG)) { ++ if (!lp->create_thin_pool && arg_count(cmd, discards_ARG)) { + log_error("--discards is only available for thin pool creation."); + return 0; + } +@@ -831,58 +803,27 @@ static int _lvcreate_params(struct lvcreate_params *lp, + else if (lp->thin && !lp->create_thin_pool) { + if (arg_count(cmd, chunksize_ARG)) + log_warn("WARNING: Ignoring --chunksize when using an existing pool."); +- } else if (lp->snapshot || lp->create_thin_pool) { ++ } else if (lp->snapshot) { + if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) { + log_error("Negative chunk size is invalid"); + return 0; + } +- if (lp->snapshot) { +- lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8); +- if (lp->chunk_size < 8 || lp->chunk_size > 1024 || +- (lp->chunk_size & (lp->chunk_size - 1))) { +- log_error("Chunk size must be a power of 2 in the " +- "range 4K to 512K"); +- return 0; +- } +- } else { +- lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, +- DM_THIN_MIN_DATA_BLOCK_SIZE); +- if ((lp->chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) || +- (lp->chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) { +- log_error("Chunk size must be in the range %uK to %uK", +- (DM_THIN_MIN_DATA_BLOCK_SIZE / 2), +- (DM_THIN_MAX_DATA_BLOCK_SIZE / 2)); +- return 0; +- } +- if (!(attr & THIN_FEATURE_BLOCK_SIZE) && +- (lp->chunk_size & (lp->chunk_size - 1))) { +- log_error("Chunk size must be a power of 2 for this thin target version."); +- return 0; +- } else if (lp->chunk_size & (DM_THIN_MIN_DATA_BLOCK_SIZE - 1)) { +- log_error("Chunk size must be multiple of %uK.", +- DM_THIN_MIN_DATA_BLOCK_SIZE / 2); +- return 0; +- } else if ((lp->discards != THIN_DISCARDS_IGNORE) && +- (lp->chunk_size & (lp->chunk_size - 1))) { +- log_warn("WARNING: Using discards ignore for chunk size non power of 2."); +- lp->discards = THIN_DISCARDS_IGNORE; +- } ++ lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8); ++ if (lp->chunk_size < 8 || lp->chunk_size > 1024 || ++ (lp->chunk_size & (lp->chunk_size - 1))) { ++ log_error("Chunk size must be a power of 2 in the " ++ "range 4K to 512K"); ++ return 0; + } +- log_verbose("Setting chunksize to %u sectors.", lp->chunk_size); ++ log_verbose("Setting chunksize to %s.", display_size(cmd, lp->chunk_size)); + + if (!lp->thin && lp->snapshot && !(lp->segtype = get_segtype_from_string(cmd, "snapshot"))) + return_0; +- } else if (arg_count(cmd, chunksize_ARG)) { ++ } else if (arg_count(cmd, chunksize_ARG) && !lp->create_thin_pool) { + log_error("-c is only available with snapshots and thin pools"); + return 0; + } + +- /* +- * Should we zero the lv. +- */ +- lp->zero = strcmp(arg_str_value(cmd, zero_ARG, +- (lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? "n" : "y"), "n"); +- + if (lp->mirrors > DEFAULT_MIRROR_MAX_IMAGES) { + log_error("Only up to %d images in mirror supported currently.", + DEFAULT_MIRROR_MAX_IMAGES); +diff --git a/tools/toollib.c b/tools/toollib.c +index 3fe1c14..5fe94e0 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -15,6 +15,7 @@ + + #include "tools.h" + #include ++#include + + const char *command_name(struct cmd_context *cmd) + { +@@ -1521,6 +1522,200 @@ int get_activation_monitoring_mode(struct cmd_context *cmd, + return 1; + } + ++int get_pool_params(struct cmd_context *cmd, ++ uint32_t *chunk_size, ++ thin_discards_t *discards, ++ uint64_t *pool_metadata_size, ++ int *zero) ++{ ++ const char *dstr; ++ ++ if (arg_count(cmd, zero_ARG)) { ++ *zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n"); ++ log_very_verbose("Setting pool zeroing: %u", *zero); ++ } else ++ *zero = find_config_tree_int(cmd, ++ "allocation/thin_pool_zero", ++ DEFAULT_THIN_POOL_ZERO); ++ ++ if (arg_count(cmd, discards_ARG)) { ++ *discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, 0); ++ log_very_verbose("Setting pool discards: %s", ++ get_pool_discards_name(*discards)); ++ } else { ++ dstr = find_config_tree_str(cmd, ++ "allocation/thin_pool_discards", ++ DEFAULT_THIN_POOL_DISCARDS); ++ if (!get_pool_discards(dstr, discards)) ++ return_0; ++ } ++ ++ if (arg_count(cmd, chunksize_ARG)) { ++ if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) { ++ log_error("Negative chunk size is invalid."); ++ return 0; ++ } ++ *chunk_size = arg_uint_value(cmd, chunksize_ARG, ++ DM_THIN_MIN_DATA_BLOCK_SIZE); ++ log_very_verbose("Setting pool chunk size: %s", ++ display_size(cmd, *chunk_size)); ++ } else ++ *chunk_size = find_config_tree_int(cmd, ++ "allocation/thin_pool_chunk_size", ++ DEFAULT_THIN_POOL_CHUNK_SIZE) * 2; ++ ++ if ((*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) || ++ (*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) { ++ log_error("Chunk size must be in the range %s to %s.", ++ display_size(cmd, DM_THIN_MIN_DATA_BLOCK_SIZE), ++ display_size(cmd, DM_THIN_MAX_DATA_BLOCK_SIZE)); ++ return 0; ++ } ++ ++ if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) { ++ log_error("Negative pool metadata size is invalid."); ++ return 0; ++ } ++ *pool_metadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG, UINT64_C(0)); ++ ++ return 1; ++} ++ ++int update_pool_params(struct cmd_context *cmd, unsigned attr, ++ uint32_t data_extents, uint32_t extent_size, ++ uint32_t *chunk_size, thin_discards_t *discards, ++ uint64_t *pool_metadata_size) ++{ ++ size_t estimate_chunk_size; ++ ++ if (!(attr & THIN_FEATURE_BLOCK_SIZE) && ++ (*chunk_size & (*chunk_size - 1))) { ++ log_error("Chunk size must be a power of 2 for this thin target version."); ++ return 0; ++ } else if (*chunk_size & (DM_THIN_MIN_DATA_BLOCK_SIZE - 1)) { ++ log_error("Chunk size must be multiple of %s.", ++ display_size(cmd, DM_THIN_MIN_DATA_BLOCK_SIZE)); ++ return 0; ++ } else if ((*discards != THIN_DISCARDS_IGNORE) && ++ (*chunk_size & (*chunk_size - 1))) { ++ log_warn("WARNING: Using discards ignore for chunk size non power of 2."); ++ *discards = THIN_DISCARDS_IGNORE; ++ } ++ ++ if (!*pool_metadata_size) { ++ /* Defaults to nr_pool_blocks * 64b converted to size in sectors */ ++ *pool_metadata_size = (uint64_t) data_extents * extent_size / ++ (*chunk_size * (SECTOR_SIZE / UINT64_C(64))); ++ /* Check if we could eventually use bigger chunk size */ ++ if (!arg_count(cmd, chunksize_ARG)) { ++ while ((*pool_metadata_size > ++ (DEFAULT_THIN_POOL_OPTIMAL_SIZE / SECTOR_SIZE)) && ++ (*chunk_size < DM_THIN_MAX_DATA_BLOCK_SIZE)) { ++ *chunk_size <<= 1; ++ *pool_metadata_size >>= 1; ++ } ++ log_verbose("Setting chunk size to %s.", ++ display_size(cmd, *chunk_size)); ++ } else if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { ++ /* Suggest bigger chunk size */ ++ estimate_chunk_size = (uint64_t) data_extents * extent_size / ++ (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE * ++ (SECTOR_SIZE / UINT64_C(64))); ++ log_warn("WARNING: Chunk size is too small for pool, suggested minimum is %s.", ++ display_size(cmd, 1 << (ffs(estimate_chunk_size) + 1))); ++ } ++ ++ /* Round up to extent size */ ++ if (*pool_metadata_size % extent_size) ++ *pool_metadata_size += extent_size - *pool_metadata_size % extent_size; ++ } else { ++ estimate_chunk_size = (uint64_t) data_extents * extent_size / ++ (*pool_metadata_size * (SECTOR_SIZE / UINT64_C(64))); ++ /* Check to eventually use bigger chunk size */ ++ if (!arg_count(cmd, chunksize_ARG)) { ++ *chunk_size = estimate_chunk_size; ++ ++ if (*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) ++ *chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE; ++ else if (*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE) ++ *chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE; ++ ++ log_verbose("Setting chunk size %s.", ++ display_size(cmd, *chunk_size)); ++ } else if (*chunk_size < estimate_chunk_size) { ++ /* Suggest bigger chunk size */ ++ log_warn("WARNING: Chunk size is smaller then suggested minimum size %s.", ++ display_size(cmd, estimate_chunk_size)); ++ } ++ } ++ ++ if ((uint64_t) *chunk_size > (uint64_t) data_extents * extent_size) { ++ log_error("Chunk size is bigger then pool data size."); ++ return 0; ++ } ++ ++ if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { ++ if (arg_count(cmd, poolmetadatasize_ARG)) ++ log_warn("WARNING: Maximum supported pool metadata size is %s.", ++ display_size(cmd, 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)); ++ *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; ++ } else if (*pool_metadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) { ++ if (arg_count(cmd, poolmetadatasize_ARG)) ++ log_warn("WARNING: Minimum supported pool metadata size is %s.", ++ display_size(cmd, 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)); ++ *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE; ++ } ++ ++ log_verbose("Setting pool metadata size to %s.", ++ display_size(cmd, *pool_metadata_size)); ++ ++ return 1; ++} ++ ++struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv, ++ alloc_policy_t alloc, ++ const char *name, ++ struct dm_list *pvh, ++ uint32_t read_ahead, ++ uint32_t stripes, ++ uint32_t stripe_size, ++ uint64_t size) ++{ ++ struct logical_volume *metadata_lv; ++ struct lvcreate_params lvc; ++ ++ /* FIXME: Make lvm2api usable */ ++ memset(&lvc, 0, sizeof(lvc)); ++ ++ if (!(lvc.extents = extents_from_size(pool_lv->vg->cmd, size, ++ pool_lv->vg->extent_size))) ++ return_0; ++ ++ if (!(lvc.segtype = get_segtype_from_string(pool_lv->vg->cmd, "striped"))) ++ return_0; ++ ++ dm_list_init(&lvc.tags); ++ ++ /* FIXME: allocate properly space for metadata_lv */ ++ lvc.activate = CHANGE_ALY; ++ lvc.alloc = alloc; ++ lvc.lv_name = name; ++ lvc.major = -1; ++ lvc.minor = -1; ++ lvc.permission = LVM_READ | LVM_WRITE; ++ lvc.pvh = pvh; ++ lvc.read_ahead = read_ahead; ++ lvc.stripe_size = stripe_size; ++ lvc.stripes = stripes; ++ lvc.vg_name = pool_lv->vg->name; ++ lvc.zero = 1; ++ ++ if (!(metadata_lv = lv_create_single(pool_lv->vg, &lvc))) ++ return_0; ++ ++ return metadata_lv; ++} ++ + /* + * Generic stripe parameter checks. + */ +diff --git a/tools/toollib.h b/tools/toollib.h +index b3b0a7c..80c01fd 100644 +--- a/tools/toollib.h ++++ b/tools/toollib.h +@@ -111,6 +111,20 @@ int pvcreate_params_validate(struct cmd_context *cmd, + + int get_activation_monitoring_mode(struct cmd_context *cmd, + int *monitoring_mode); ++int get_pool_params(struct cmd_context *cmd, ++ uint32_t *chunk_size, ++ thin_discards_t *discards, ++ uint64_t *pool_metadata_size, ++ int *zero); ++int update_pool_params(struct cmd_context *cmd, unsigned attr, ++ uint32_t data_extents, uint32_t extent_size, ++ uint32_t *chunk_size, thin_discards_t *discards, ++ uint64_t *pool_metadata_size); ++struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv, ++ alloc_policy_t alloc, const char *name, ++ struct dm_list *pvh, uint32_t read_ahead, ++ uint32_t stripes, uint32_t stripe_size, ++ uint64_t size); + int get_stripe_params(struct cmd_context *cmd, uint32_t *stripes, + uint32_t *stripe_size); + +diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c +index d62df99..20ca16b 100644 +--- a/tools/vgcfgrestore.c ++++ b/tools/vgcfgrestore.c +@@ -62,8 +62,9 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv) + + if (!(arg_count(cmd, file_ARG) ? + backup_restore_from_file(cmd, vg_name, +- arg_str_value(cmd, file_ARG, "")) : +- backup_restore(cmd, vg_name))) { ++ arg_str_value(cmd, file_ARG, ""), ++ arg_count(cmd, force_long_ARG)) : ++ backup_restore(cmd, vg_name, arg_count(cmd, force_long_ARG)))) { + unlock_vg(cmd, VG_ORPHANS); + unlock_vg(cmd, vg_name); + log_error("Restore failed."); diff --git a/srcpkgs/lvm2/patches/lvm2-2_02_99-various-updates-and-fixes-for-systemd-units.patch b/srcpkgs/lvm2/patches/lvm2-2_02_99-various-updates-and-fixes-for-systemd-units.patch new file mode 100644 index 00000000000..33ab47f56ff --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-2_02_99-various-updates-and-fixes-for-systemd-units.patch @@ -0,0 +1,48 @@ +commit 8dedeaa0183d2c87764a4012e443af9597d28575 +Author: Peter Rajnoha +Date: Wed Oct 31 14:15:54 2012 +0100 + + 0 +--- + WHATS_NEW | 3 +++ + scripts/lvm2_monitoring_systemd_red_hat.service.in | 7 ++++--- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index d0e0cd4..12307ed 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,8 @@ + Version 2.02.99 - + =================================== ++ Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. ++ Remove dependency on fedora-storage-init.service in lvm2 systemd units. ++ Depend on lvm2-lvmetad.socket in lvm2-monitor.service systemd unit. + Initialize lvmetad lazily to avoid early socket access on config overrides. + Hardcode use_lvmetad=0 if cluster locking used and issue a warning msg. + +diff --git a/scripts/lvm2_monitoring_systemd_red_hat.service.in b/scripts/lvm2_monitoring_systemd_red_hat.service.in +index 6c4c55f..e6b4814 100644 +--- a/scripts/lvm2_monitoring_systemd_red_hat.service.in ++++ b/scripts/lvm2_monitoring_systemd_red_hat.service.in +@@ -1,8 +1,8 @@ + [Unit] + Description=Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling + Documentation=man:dmeventd(8) man:lvcreate(8) man:lvchange(8) man:vgchange(8) +-Requires=dm-event.socket +-After=dm-event.socket fedora-storage-init.service fedora-storage-init-late.service lvm2-activation.service lvm2-lvmetad.service ++Requires=dm-event.socket lvm2-lvmetad.socket ++After=dm-event.socket lvm2-lvmetad.socket lvm2-activation.service lvm2-lvmetad.service + Before=local-fs.target + DefaultDependencies=no + Conflicts=shutdown.target +@@ -11,7 +11,8 @@ Conflicts=shutdown.target + Type=oneshot + Environment=LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES=1 + ExecStart=@sbindir@/lvm vgchange --monitor y +-ExecStop=@sbindir@/lvm vgchange --monitor n ++# The lvmetad must be disabled here, it needs https://bugzilla.redhat.com/show_bug.cgi?id=843587 to be resolved first. ++ExecStop=@sbindir@/lvm vgchange --monitor n --config 'global{use_lvmetad=0}' + RemainAfterExit=yes + + [Install] diff --git a/srcpkgs/lvm2/patches/lvm2-enable-lvmetad-by-default.patch b/srcpkgs/lvm2/patches/lvm2-enable-lvmetad-by-default.patch new file mode 100644 index 00000000000..e7286162f53 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-enable-lvmetad-by-default.patch @@ -0,0 +1,30 @@ + doc/example.conf.in | 2 +- + lib/commands/toolcontext.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/doc/example.conf.in b/doc/example.conf.in +index 10cfe16..442ad64 100644 +--- a/doc/example.conf.in ++++ b/doc/example.conf.in +@@ -491,7 +491,7 @@ global { + # + # If lvmetad has been running while use_lvmetad was 0, it MUST be stopped + # before changing use_lvmetad to 1 and started again afterwards. +- use_lvmetad = 0 ++ use_lvmetad = 1 + + # Full path of the utility called to check that a thin metadata device + # is in a state that allows it to be used. +diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c +index d72b0c0..d7f8ece 100644 +--- a/lib/commands/toolcontext.c ++++ b/lib/commands/toolcontext.c +@@ -413,7 +413,7 @@ static int _process_config(struct cmd_context *cmd) + lvmetad_set_socket(lvmetad_socket); + cn = find_config_tree_node(cmd, "devices/global_filter"); + lvmetad_set_token(cn ? cn->v : NULL); +- lvmetad_set_active(find_config_tree_int(cmd, "global/use_lvmetad", 0)); ++ lvmetad_set_active(find_config_tree_int(cmd, "global/use_lvmetad", 1)); + lvmetad_init(cmd); + + return 1; diff --git a/srcpkgs/lvm2/patches/lvm2-set-default-preferred_names.patch b/srcpkgs/lvm2/patches/lvm2-set-default-preferred_names.patch new file mode 100644 index 00000000000..5e1e1b65d05 --- /dev/null +++ b/srcpkgs/lvm2/patches/lvm2-set-default-preferred_names.patch @@ -0,0 +1,15 @@ +--- LVM2.2.02.58/doc/example.conf.in 2010-01-07 19:54:21.000000000 +0000 ++++ LVM2.2.02.58-new/doc/example.conf.in 2010-01-20 18:30:32.000000000 +0000 +@@ -23,10 +23,10 @@ + # same block device and the tools need to display a name for device, + # all the pathnames are matched against each item in the following + # list of regular expressions in turn and the first match is used. +- preferred_names = [ ] ++ # preferred_names = [ ] + + # Try to avoid using undescriptive /dev/dm-N names, if present. +- # preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ] ++ preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ] + + # A filter that tells LVM2 to only use a restricted set of devices. + # The filter consists of an array of regular expressions. These diff --git a/srcpkgs/lvm2/patches/series b/srcpkgs/lvm2/patches/series new file mode 100644 index 00000000000..f3e8fab8476 --- /dev/null +++ b/srcpkgs/lvm2/patches/series @@ -0,0 +1,29 @@ +lvm2-set-default-preferred_names.patch +lvm2-enable-lvmetad-by-default.patch +lvm2-2_02_99-python-remove-liblvm-object.patch +lvm2-2_02_99-python-whitespace-and-conditional-cleanup.patch +lvm2-2_02_99-python-update-example-to-work-with-lvm-object-removal.patch +lvm2-2_02_99-python-implement-proper-refcounting-for-parent-objects.patch +lvm2-2_02_99-properly-set-cookie_set-var-on-dm_task_set_cookie-call.patch +lvm2-2_02_99-hardcode-use_lvmetad0-if-cluster-locking-used-and-issue-warning-msg.patch +lvm2-2_02_99-init-lvmetad-lazily-to-avoid-early-socket-access-on-config-overrides.patch +lvm2-2_02_99-various-updates-and-fixes-for-systemd-units.patch +lvm2-2_02_99-exit-pvscan-cache-immediately-if-cluster-locking-used-or-lvmetad-not-used.patch +lvm2-2_02_99-skip-mlocking-verctors-on-arm-arch.patch +lvm2-2_02_99-fix-autoactivation-to-not-autoactivate-vg-lv-on-each-pv-change.patch +lvm2-2_02_99-synchronize-with-udev-in-pvscan-cache-and-fix-dangling-udev_sync-cookies.patch +lvm2-2_02_99-also-autoactivate-on-coldplug.patch +lvm2-2_02_99-fire-pvscan-cache-on-change-event-for-md-devs.patch +lvm2-2_02_99-various-thin-support-related-fixes.patch +lvm2-2_02_99-fix-lv_is_active-in-lvcreate.patch +lvm2-2_02_99-fix-crash-in-pvscan-cache-aay-triggered-by-non-mda-pv.patch +lvm2-2_02_99-avoid-global-lock-in-pvs-when-lvmetad-is-in-use.patch +lvm2-2_02_99-fix-possible-deadlock-in-lvmetad-for-parallel-update-and-query.patch +lvm2-2_02_99-fix-possible-race-in-lvmetad-remove_metadata.patch +lvm2-2_02_99-lvmetad-fix-a-race-in-metadata-update.patch +lvm2-2_02_99-fix-handling-of-reappeared-and-missing-pvs-in-lvmetad.patch +lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch +lvm2-2_02_99-add-dm-disable-udev-env-var-and-fix-noudevsync-arg.patch +lvm2-2_02_99-fix-premature-dm-version-checking-which-caused-useless-mapper-control-access.patch +lvm2-2_02_99-close-dmeventd-fifo-fds-on-exec.patch +lvm2-2_02_99-fix-dmsetup-splitname-to-not-fail-if-used-without-c-switch.patch diff --git a/srcpkgs/lvm2/template b/srcpkgs/lvm2/template index f90ed5fd979..a4f67b2161b 100644 --- a/srcpkgs/lvm2/template +++ b/srcpkgs/lvm2/template @@ -1,7 +1,8 @@ # Template file for 'lvm2' pkgname=lvm2 version=2.02.98 -revision=4 +revision=5 +patch_args="-Np1" wrksrc=LVM2.${version} build_style=gnu-configure configure_args="--disable-selinux --enable-readline --enable-pkgconfig @@ -92,7 +93,6 @@ lvm2_package() { /etc/lvm/backup 0755 root root" conf_files="/etc/lvm/lvm.conf" pkg_install() { - vmove etc - vmove usr + vmove all } } diff --git a/srcpkgs/nodejs/template b/srcpkgs/nodejs/template index e35d34e7dc8..0eeb5fad0ce 100644 --- a/srcpkgs/nodejs/template +++ b/srcpkgs/nodejs/template @@ -1,6 +1,6 @@ # Template file for 'nodejs' pkgname=nodejs -version=0.10.12 +version=0.10.13 revision=1 wrksrc=node-v${version} short_desc="Evented I/O for V8 javascript" @@ -8,7 +8,7 @@ maintainer="davehome " license="MIT" homepage="http://nodejs.org/" distfiles="${homepage}/dist/v${version}/node-v${version}.tar.gz" -checksum=7339a7c333454a567a41c900b6ef2f6c89e8c778062c173beb029611b29496b6 +checksum=a102fad260d216b95611ddd57aeb6531c92ad1038508390654423feb1b51c059 hostmakedepends="which pkg-config python" makedepends="openssl-devel zlib-devel" diff --git a/srcpkgs/xen/patches/blktaplib.h.redefinition.patch b/srcpkgs/xen/patches/blktaplib.h.redefinition.patch deleted file mode 100644 index 093cff63214..00000000000 --- a/srcpkgs/xen/patches/blktaplib.h.redefinition.patch +++ /dev/null @@ -1,265 +0,0 @@ -Do not redefine READ and WRITE, which are defined in linux/fs.h. Instead prefix them -with XEN to avoid namespace clash. - ---- tools/blktap2/include/blktaplib.h.orig 2011-01-10 11:10:18.362560374 +0100 -+++ tools/blktap2/include/blktaplib.h 2011-01-10 11:11:53.007679832 +0100 -@@ -197,8 +197,8 @@ typedef struct msg_lock { - int uuid_len; - } msg_lock_t; - --#define READ 0 --#define WRITE 1 -+#define XEN_READ 0 -+#define XEN_WRITE 1 - - /*Control Messages between manager and tapdev*/ - #define CTLMSG_PARAMS 1 ---- tools/blktap/lib/blktaplib.h.orig 2011-01-10 11:12:38.633561491 +0100 -+++ tools/blktap/lib/blktaplib.h 2011-01-10 11:12:47.110717080 +0100 -@@ -195,8 +195,8 @@ typedef struct msg_pid { - pid_t pid; - } msg_pid_t; - --#define READ 0 --#define WRITE 1 -+#define XEN_READ 0 -+#define XEN_WRITE 1 - - /*Control Messages between manager and tapdev*/ - #define CTLMSG_PARAMS 1 ---- tools/blktap/drivers/blktapctrl.c.orig 2010-08-25 12:22:07.000000000 +0200 -+++ tools/blktap/drivers/blktapctrl.c 2011-01-10 11:30:15.176697136 +0100 -@@ -128,13 +128,13 @@ static int get_tapdisk_pid(blkif_t *blki - { - int ret; - -- if ((ret = write_msg(blkif->fds[WRITE], CTLMSG_PID, blkif, NULL)) -+ if ((ret = write_msg(blkif->fds[XEN_WRITE], CTLMSG_PID, blkif, NULL)) - <= 0) { - DPRINTF("Write_msg failed - CTLMSG_PID(%d)\n", ret); - return -EINVAL; - } - -- if ((ret = read_msg(blkif->fds[READ], CTLMSG_PID_RSP, blkif)) -+ if ((ret = read_msg(blkif->fds[XEN_READ], CTLMSG_PID_RSP, blkif)) - <= 0) { - DPRINTF("Read_msg failure - CTLMSG_PID(%d)\n", ret); - return -EINVAL; -@@ -576,8 +576,8 @@ static int connect_qemu(blkif_t *blkif, - } - - DPRINTF("Using tapdisk-ioemu connection\n"); -- blkif->fds[READ] = dom0_readfd; -- blkif->fds[WRITE] = dom0_writefd; -+ blkif->fds[XEN_READ] = dom0_readfd; -+ blkif->fds[XEN_WRITE] = dom0_writefd; - - if (refresh_pid) { - get_tapdisk_pid(blkif); -@@ -587,8 +587,8 @@ static int connect_qemu(blkif_t *blkif, - } else if (access(rdctldev, R_OK | W_OK) == 0) { - /* Use existing pipe to the device model */ - DPRINTF("Using qemu-dm connection\n"); -- blkif->fds[READ] = open_ctrl_socket(wrctldev); -- blkif->fds[WRITE] = open_ctrl_socket(rdctldev); -+ blkif->fds[XEN_READ] = open_ctrl_socket(wrctldev); -+ blkif->fds[XEN_WRITE] = open_ctrl_socket(rdctldev); - } else { - /* No device model => try with tapdisk-ioemu */ - DPRINTF("No device model\n"); -@@ -598,7 +598,7 @@ static int connect_qemu(blkif_t *blkif, - free(rdctldev); - free(wrctldev); - -- if (blkif->fds[READ] == -1 || blkif->fds[WRITE] == -1) -+ if (blkif->fds[XEN_READ] == -1 || blkif->fds[XEN_WRITE] == -1) - return -1; - - DPRINTF("Attached to qemu blktap pipes\n"); -@@ -621,10 +621,10 @@ static int connect_tapdisk(blkif_t *blki - "%s/tapctrlwrite%d", BLKTAP_CTRL_DIR, minor) == -1) - goto fail; - -- blkif->fds[READ] = open_ctrl_socket(rdctldev); -- blkif->fds[WRITE] = open_ctrl_socket(wrctldev); -+ blkif->fds[XEN_READ] = open_ctrl_socket(rdctldev); -+ blkif->fds[XEN_WRITE] = open_ctrl_socket(wrctldev); - -- if (blkif->fds[READ] == -1 || blkif->fds[WRITE] == -1) -+ if (blkif->fds[XEN_READ] == -1 || blkif->fds[XEN_WRITE] == -1) - goto fail; - - /*launch the new process*/ -@@ -683,8 +683,8 @@ static int blktapctrl_new_blkif(blkif_t - - } else { - DPRINTF("Process exists!\n"); -- blkif->fds[READ] = exist->fds[READ]; -- blkif->fds[WRITE] = exist->fds[WRITE]; -+ blkif->fds[XEN_READ] = exist->fds[XEN_READ]; -+ blkif->fds[XEN_WRITE] = exist->fds[XEN_WRITE]; - } - - add_disktype(blkif, type); -@@ -703,13 +703,13 @@ static int blktapctrl_new_blkif(blkif_t - - /* Both of the following read and write calls will block up to - * max_timeout val*/ -- if (write_msg(blkif->fds[WRITE], CTLMSG_PARAMS, blkif, ptr) -+ if (write_msg(blkif->fds[XEN_WRITE], CTLMSG_PARAMS, blkif, ptr) - <= 0) { - DPRINTF("Write_msg failed - CTLMSG_PARAMS\n"); - goto fail; - } - -- if (read_msg(blkif->fds[READ], CTLMSG_IMG, blkif) <= 0) { -+ if (read_msg(blkif->fds[XEN_READ], CTLMSG_IMG, blkif) <= 0) { - DPRINTF("Read_msg failure - CTLMSG_IMG\n"); - goto fail; - } -@@ -725,12 +725,12 @@ fail: - static int map_new_blktapctrl(blkif_t *blkif) - { - DPRINTF("Received a poll for a new devmap\n"); -- if (write_msg(blkif->fds[WRITE], CTLMSG_NEWDEV, blkif, NULL) <= 0) { -+ if (write_msg(blkif->fds[XEN_WRITE], CTLMSG_NEWDEV, blkif, NULL) <= 0) { - DPRINTF("Write_msg failed - CTLMSG_NEWDEV\n"); - return -EINVAL; - } - -- if (read_msg(blkif->fds[READ], CTLMSG_NEWDEV_RSP, blkif) <= 0) { -+ if (read_msg(blkif->fds[XEN_READ], CTLMSG_NEWDEV_RSP, blkif) <= 0) { - DPRINTF("Read_msg failed - CTLMSG_NEWDEV_RSP\n"); - return -EINVAL; - } -@@ -743,15 +743,15 @@ static int unmap_blktapctrl(blkif_t *blk - { - DPRINTF("Unmapping vbd\n"); - -- if (write_msg(blkif->fds[WRITE], CTLMSG_CLOSE, blkif, NULL) <= 0) { -+ if (write_msg(blkif->fds[XEN_WRITE], CTLMSG_CLOSE, blkif, NULL) <= 0) { - DPRINTF("Write_msg failed - CTLMSG_CLOSE\n"); - return -EINVAL; - } - - if (del_disktype(blkif)) { - DPRINTF("Closing communication pipe to pid %d\n", blkif->tappid); -- close(blkif->fds[WRITE]); -- close(blkif->fds[READ]); -+ close(blkif->fds[XEN_WRITE]); -+ close(blkif->fds[XEN_READ]); - } - - return 0; ---- tools/blktap/drivers/tapdisk.c.orig 2011-01-10 11:33:42.160375869 +0100 -+++ tools/blktap/drivers/tapdisk.c 2011-01-10 11:36:42.820168882 +0100 -@@ -138,10 +138,10 @@ static inline int LOCAL_FD_SET(fd_set *r - if (ptr->tap_fd) { - FD_SET(ptr->tap_fd, readfds); - td_for_each_disk(ptr->s, dd) { -- if (dd->io_fd[READ]) -- FD_SET(dd->io_fd[READ], readfds); -- maxfds = (dd->io_fd[READ] > maxfds ? -- dd->io_fd[READ] : maxfds); -+ if (dd->io_fd[INPUT]) -+ FD_SET(dd->io_fd[INPUT], readfds); -+ maxfds = (dd->io_fd[INPUT] > maxfds ? -+ dd->io_fd[INPUT] : maxfds); - } - maxfds = (ptr->tap_fd > maxfds ? ptr->tap_fd : maxfds); - } -@@ -380,7 +380,7 @@ static int read_msg(char *buf) - struct td_state *s = NULL; - fd_list_entry_t *entry; - -- length = read(fds[READ], buf, MSG_SIZE); -+ length = read(fds[INPUT], buf, MSG_SIZE); - - if (length > 0 && length >= sizeof(msg_hdr_t)) - { -@@ -435,7 +435,7 @@ static int read_msg(char *buf) - msg->type = CTLMSG_IMG_FAIL; - msg->len = msglen; - } -- len = write(fds[WRITE], buf, msglen); -+ len = write(fds[OUTPUT], buf, msglen); - free(path); - return 1; - -@@ -457,7 +457,7 @@ static int read_msg(char *buf) - : CTLMSG_NEWDEV_FAIL); - msg->len = msglen; - -- len = write(fds[WRITE], buf, msglen); -+ len = write(fds[OUTPUT], buf, msglen); - return 1; - - case CTLMSG_CLOSE: -@@ -479,7 +479,7 @@ static int read_msg(char *buf) - process = getpid(); - msg_pid->pid = process; - -- len = write(fds[WRITE], buf, msglen); -+ len = write(fds[OUTPUT], buf, msglen); - return 1; - - default: -@@ -782,12 +782,12 @@ int main(int argc, char *argv[]) - signal (SIGINT, sig_handler); - - /*Open the control channel*/ -- fds[READ] = open(argv[1],O_RDWR|O_NONBLOCK); -- fds[WRITE] = open(argv[2],O_RDWR|O_NONBLOCK); -+ fds[INPUT] = open(argv[1],O_RDWR|O_NONBLOCK); -+ fds[OUTPUT] = open(argv[2],O_RDWR|O_NONBLOCK); - -- if ( (fds[READ] < 0) || (fds[WRITE] < 0) ) -+ if ( (fds[INPUT] < 0) || (fds[OUTPUT] < 0) ) - { -- DPRINTF("FD open failed [%d,%d]\n", fds[READ], fds[WRITE]); -+ DPRINTF("FD open failed [%d,%d]\n", fds[INPUT], fds[OUTPUT]); - exit(-1); - } - -@@ -803,8 +803,8 @@ int main(int argc, char *argv[]) - { - ret = 0; - FD_ZERO(&readfds); -- FD_SET(fds[READ], &readfds); -- maxfds = fds[READ]; -+ FD_SET(fds[INPUT], &readfds); -+ maxfds = fds[INPUT]; - - /*Set all tap fds*/ - LOCAL_FD_SET(&readfds); -@@ -822,10 +822,10 @@ int main(int argc, char *argv[]) - tapdev_info_t *info = ptr->s->ring_info; - - td_for_each_disk(ptr->s, dd) { -- if (dd->io_fd[READ] && -- FD_ISSET(dd->io_fd[READ], -+ if (dd->io_fd[INPUT] && -+ FD_ISSET(dd->io_fd[INPUT], - &readfds)) { -- io_done(dd, READ); -+ io_done(dd, INPUT); - progress_made = 1; - } - } -@@ -851,13 +851,13 @@ int main(int argc, char *argv[]) - ptr = ptr->next; - } - -- if (FD_ISSET(fds[READ], &readfds)) -+ if (FD_ISSET(fds[INPUT], &readfds)) - read_msg(buf); - } - } - free(buf); -- close(fds[READ]); -- close(fds[WRITE]); -+ close(fds[INPUT]); -+ close(fds[OUTPUT]); - - ptr = fd_start; - while (ptr != NULL) { diff --git a/srcpkgs/xen/patches/gdbsx-glibc-2.17.patch b/srcpkgs/xen/patches/gdbsx-glibc-2.17.patch deleted file mode 100644 index 5d9b33ba00f..00000000000 --- a/srcpkgs/xen/patches/gdbsx-glibc-2.17.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- tools/debugger/gdbsx/xg/xg_main.c -+++ tools/debugger/gdbsx/xg/xg_main.c -@@ -34,6 +34,7 @@ - * XGTRC(): generic trace utility - */ - -+#include - #include - #include - #include diff --git a/srcpkgs/xen/patches/qemu-timer_settime-librt.patch b/srcpkgs/xen/patches/qemu-timer_settime-librt.patch deleted file mode 100644 index f16d79412eb..00000000000 --- a/srcpkgs/xen/patches/qemu-timer_settime-librt.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- tools/qemu-xen/Makefile.target.orig 2013-06-04 15:51:15.320999319 +0200 -+++ tools/qemu-xen/Makefile.target 2013-06-04 15:51:37.360864318 +0200 -@@ -205,7 +205,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virt - obj-$(CONFIG_KVM) += kvm.o kvm-all.o - obj-$(CONFIG_NO_KVM) += kvm-stub.o - obj-y += memory.o --LIBS+=-lz -+LIBS+=-lz -lrt - - QEMU_CFLAGS += $(VNC_TLS_CFLAGS) - QEMU_CFLAGS += $(VNC_SASL_CFLAGS) ---- tools/qemu-xen-traditional/Makefile.target -+++ tools/qemu-xen-traditional/Makefile.target -@@ -520,7 +520,7 @@ - OBJS+=block-raw-posix.o - endif - --LIBS+=-lz -+LIBS+=-lz -lm -lrt - ifdef CONFIG_ALSA - LIBS += -lasound - endif diff --git a/srcpkgs/xen/template b/srcpkgs/xen/template index 2e3f341c116..df85b56979c 100644 --- a/srcpkgs/xen/template +++ b/srcpkgs/xen/template @@ -1,6 +1,6 @@ # Template file for 'xen' pkgname=xen -version=4.2.2 +version=4.3.0 wrksrc=xen-${version} revision=3 short_desc="Xen Hypervisor and Utilities" @@ -8,7 +8,7 @@ maintainer="Juan RP " homepage="http://xen.org" license="GPL-2" distfiles="http://bits.xensource.com/oss-xen/release/$version/xen-$version.tar.gz" -checksum=c9bfe91a5e72f8545acebad9889d64368020359bfe18044c0e683133e55ae005 +checksum=e1e9faabe4886e2227aacdbde74410653b233d66642ca1972a860cbec6439961 long_desc=" This package provides the official Xen Hypervisor and related utilities for starting/stopping/accessing unprivileged domains (domUs)." @@ -20,7 +20,7 @@ hostmakedepends="which wget bison pkg-config" makedepends="lzo-devel openssl-devel e2fsprogs-devel zlib-devel gnutls-devel>=3.1.5 libbluetooth-devel pciutils-devel libX11-devel libXext-devel SDL-devel MesaLib-devel ncurses-devel liblzma-devel python-devel yajl-devel libuuid-devel libglib-devel iproute2 - bridge-utils dev86 acpica-utils" + bridge-utils dev86 acpica-utils pixman-devel" if [ "${XBPS_MACHINE}" = "x86_64" ]; then makedepends+=" gcc-multilib" @@ -56,18 +56,17 @@ do_install() { vmkdir usr/share/examples/xen mv ${DESTDIR}/etc/xen/x*example* ${DESTDIR}/usr/share/examples/xen mv ${DESTDIR}/etc/xen/cpupool ${DESTDIR}/usr/share/examples/xen - mv ${DESTDIR}/etc/init.d/xendomains ${DESTDIR}/etc/xen/scripts # Remove useless stuff. rm -rf ${DESTDIR}/etc/init.d ${DESTDIR}/usr/local rm -f ${DESTDIR}/install.sh ${DESTDIR}/usr/lib64 rm -rf ${DESTDIR}/usr/bin/qemu-*-xen - rm -rf ${DESTDIR}/usr/share/qemu-xen - rm -f ${DESTDIR}/boot/xen{,-4,-4.2}.gz + rm -f ${DESTDIR}/boot/xen{,-4,-4.3}.gz rm -f ${DESTDIR}/usr/sbin/xen-python-path rm -f ${DESTDIR}/{install,COPYING,README,usr/lib/lib} rm -rf ${DESTDIR}/etc/udev + rm -f ${DESTDIR}//usr/libexec/qemu-bridge-helper # Move bash-completion to the correct dir. vmkdir usr/share/bash-completion/completions