Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for devid and phys_path keys in vdev disk labels. #4416

Closed
wants to merge 1 commit into from
Closed

Add support for devid and phys_path keys in vdev disk labels. #4416

wants to merge 1 commit into from

Conversation

don-brady
Copy link
Contributor

Add support for devid and phys_path keys in vdev disk labels.

This is foundational work for ZED.

Updates a leaf vdev's persistent device strings on Linux platform

  • only applies for a dedicated leaf vdev (aka whole disk)
  • updated during pool create|add|attach|import
  • used for matching device matching during auto-{online,expand,replace}
  • stored in a leaf disk config label (i.e. alongside 'path' NVP)
  • can opt-out using env var ZFS_VDEV_DEVID_OPT_OUT=YES

See details in http://github.com/zfsonlinux/zfs/issues/3978

Some examples:

# zpool create dozer sdb
# zdb -C | grep 'path:\|devid:'
    path: '/dev/sdb1'
    devid: 'scsi-350000394a8ca4fbc-part1'
    phys_path: 'pci-0000:04:00.0-sas-0x50000394a8ca4fbf-lun-0'

# zpool create tank mpatha
# zdb -C | grep 'path:\|devid:'
    path: '/dev/mapper/mpatha'
    devid: 'dm-uuid-mpath-35000c5006304de3f'

@don-brady
Copy link
Contributor Author

As sort of expected, the build fails since the build VMs don't have libudev-devel package installed.

configure:31509: error: in `/var/lib/buildbot/slaves/zfs/Amazon_2015_09_x86_64__BUILD_/build/zfs':
configure:31511: error: 
    *** libudev.h missing, libudev-devel package required
See `config.log' for more details

What is the best way to get libudev-devel as part of the VM provisioning step?

@behlendorf
Copy link
Contributor

Thanks for opening this PR. I can add the missing dependency to the provisioning script or you could open a PR against the zfs-buildbot to do it, it's located here.

https://github.com/zfsonlinux/zfs-buildbot/blob/master/scripts/bb-dependencies.sh

Adding a dependency is fairly rare so it really hasn't been automated.

@behlendorf
Copy link
Contributor

I've updated the dependencies. If you force update this PR it should build.

@don-brady
Copy link
Contributor Author

Looks like some of the older distros have an older version of libudev that doesn't have udev_device_get_is_initialized (was introduced in ver 165). I'll need to come up with an alternate solution for that function.

@behlendorf
Copy link
Contributor

@don-brady I'd suggest adding a check for that function to user-libudev.m4. Then if it's unavailable, due to an old version of the library, you can provide an alternate implementation if that's feasible.

@don-brady
Copy link
Contributor Author

something like this?

AC_CHECK_LIB([udev], [udev_device_get_is_initialized], AC_DEFINE([
HAVE_UDEV_DEVICE_GET_IS_INITIALIZED], 1, [
Define to 1 if udev_device_get_is_initialized is available.]))

@behlendorf
Copy link
Contributor

Yes, exactly. Then you can add a if !defined(HAVE_UDEV_DEVICE_GET_IS_INITIALIZED) block and implement your own version... assuming that's possible. I'm not sure, I'm not familiar with the libudev at all.

@ryao
Copy link
Contributor

ryao commented Mar 15, 2016

There is a small subset of the community that does not use udev. Most of them use Alpine Linux (many), Gentoo Linux (few) or Funtoo Linux (slightly more than Gentoo), although there could be others that I do not know about. We should add a configure script option that allows those people to disable this functionality so that we do not add a hard dependency.

@behlendorf
Copy link
Contributor

@ryao good point, we can't make this mandatory since not all distributions provide this library. Is there an alternative on Alpine / Gentoo / Funtoo Linux?

@ryao
Copy link
Contributor

ryao commented Mar 15, 2016

@behlendorf Alpine prefers mdev. which has no library for this. On Gentoo and Funtoo (which are 99% identical), the user is free to configure /dev however he wants, including via static nodes. I do not think many people do that though.

It should be possible to use libblkid for some of the information that we are getting out of udev, although each libudev call will need to be examined on a case by case basis. I am heading out to a dental appointment, so I will need to look at this more later.

@don-brady
Copy link
Contributor Author

@ryao @behlendorf I can certainly make this libudev dependent code optional and only available if HAVE_LIBUDEV is defined. But pending features like auto-online and auto-replace are based on a libudev monitor (to get disk events). We may end up requiring alternate code paths for sans-libudev platforms. Is libblkid ubiquitous?

@behlendorf
Copy link
Contributor

That's Linux. Every distribution makes their own choices about what packages to provide. All we can do is lay the ground work and integrate it with the most common packages which provide the required functionality. Hopefully, developers for those distributions will be able to extend the current functionality for their environment and push those patches back upstream.

As for libblkid that should be ubiquitous. It was made mandatory for ZFS on Linux a few weeks back and so far I haven't seen any issues reported.

@don-brady
Copy link
Contributor Author

@behlendorf A TBD. If we make libudev optional here, how do we communicate to developers to pick up the libudev-devel package before building ZFS? Is there a canonical list of recommended xxxx-devel packages for zfs? Thanks.

@behlendorf
Copy link
Contributor

@don-brady we do provide a recommended list of development packages which works for many, but not all, of the common distributions. We'll need to add libudev-devel to that list once this merges. Beyond that the distribution maintainer is usually responsible for taking care of this in their packaging.

http://zfsonlinux.org/generic-deb.html
http://zfsonlinux.org/generic-rpm.html

@ryao
Copy link
Contributor

ryao commented Mar 16, 2016

@don-brady It is possible to write a mdev rule that would provide notification of disk events. I wrote some code to do this in genkernel to setup /dev in the initramfs environment. It was only for add events (although mdev supports remove events too) and I need to do more before it is not a full replacement for udev's setup of /dev/disk/by-* symlinks:

https://gitweb.gentoo.org/proj/genkernel.git/commit/?h=zfs&id=876782989c5bc190ecc37faad40b2c2adc544c12

That said, I do not expect you to write hooks for mdev though. People who care about this will either work on it or ping me until I work on it.

return (udev_device_get_is_initialized(dev));
#else
/* wait for DEVLINKS property to be initialized */
return (udev_device_get_property_value(dev, "DEVLINKS") != NULL);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be the downside to using udev_device_get_property_value() even if udev_device_get_is_initialized() is available? If there really isn't one it might make sense to always use that interface to keep the code simple.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the device is initialized, udev_device_get_is_initialized() is O(1) while udev_list_entry_get_by_name() is at least O(log(N)) as it does a couple binary searches in a sorted array. If it is not initialized, then it just looks in the database while udev_device_get_property_value will go to the uevent file before the database.

The optimization is probably not that useful given that we are running this in a loop with usleep().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, thanks for the explanation. Since this bit of code is pretty clean either way I don't feel too strongly about this. Since @don-brady effectively already did the work to optimize this case when udev_device_get_is_initialized() is available I suggest we leave it as is. I don't see it causes us any long term maintainability issues which is my only real concern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@behlendorf The long term solution might be to improve the zpool_label_disk_wait() to be based on udev monitoring instead of polling a symlink and could eliminate the need for update_vdev_config_dev_strs() to check or wait for udev dev initialization. Perhaps once ZED has the udev monitoring merged we can revisit?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, sounds good we can definitely revisit this. Although we're always going to need to keep the polling behavior as a fallback for compatibility reasons since we can't assume every system has udev monitoring and we need to provide at least basic functionality.

@don-brady
Copy link
Contributor Author

@behlendorf So latest commit has this libudev based feature being optional. Do we have any configs in the build bot fleet that don't have libudev? Might be good idea to validate the non-libudev case (against future regressions). Thanks.

@behlendorf
Copy link
Contributor

@don-brady unfortunately we don't, but it would be a good idea to add one. @ryao adding a Gentoo builder might be a good way to address that.

@behlendorf
Copy link
Contributor

@don-brady is there anything you're planning to add to this PR. If not can you rebase it on master, squash it in to a single commit, and force update the branch. Then we can get one last round of testing and review comments before merging it.

@don-brady
Copy link
Contributor Author

@behlendorf no additional changes planned. I will rebase/squash and update the branch.

AC_CHECK_HEADER([libudev.h], [AC_SUBST([LIBUDEV], ["-ludev"])
AC_DEFINE([HAVE_LIBUDEV], 1, [Define if you have libudev])], [])

AC_CHECK_LIB([udev], [udev_device_get_is_initialized], [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AC_SEARCH_LIBS is apparently the preferred macro these days. @ryao pointed this out recently in the recent e853ba3 commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. I think the value is in having .m4 files be good examples (admittedly I borrowed from another one). In theory I can just drop in AC_SEARCH_LIBS macro and swap the first two arguments.

@don-brady
Copy link
Contributor Author

Looks like all recent builds on Amazon 2015.09 x86_64 SIMD (TEST) are failing in zfs test suite for zpool_scrub_002_pos and zpool_scrub_003_pos tests.

@behlendorf
Copy link
Contributor

I've opened #4450 for the scrub failures. It looks to me like the test case is just racy and the much more capable Amazon SIMD TEST builder is exposing that. We'll either way to fix the test cases or disable them until we do.

Thanks for squashing this, I started looking it over again yesterday but had to run. I'll go over it again.

LIBUDEV=

AC_CHECK_HEADER([libudev.h], [AC_SUBST([LIBUDEV], ["-ludev"])
AC_DEFINE([HAVE_LIBUDEV], 1, [Define if you have libudev])], [])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the indentation on these two checks as well. The first two times I read this it wasn't clear to me the AC_DEFAULT line was inside AC_CHECK_HEADER. Same for AC_CHECK_LIB below. Use the normal cstyle indentation rules here as much as possible.


/*
* For the benefit of legacy ZFS implementations, allow
* for opting out of devid strings in the vdev label.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to add why you might want/need to do this to the comment (or somewhere if I missed it)

@behlendorf
Copy link
Contributor

The patch works well for me and build properly with and without libudev. Just a few small recommended improvements.

I'd also suggest looking to to updating tests/cmd/devname2devid/devname2devid.c so it works as expected. We might find that having this helper available simplified writing test cases.

@don-brady
Copy link
Contributor Author

@behlendorf Thanks for the review feedback! I'll make the recommended changes and take a look at devname2devid

@don-brady
Copy link
Contributor Author

Looks like the bash shell on Debian and Ubuntu builbots is not happy with zloop.sh (a script syntax error encountered).

@behlendorf
Copy link
Contributor

@don-brady yes the updated zloop.sh script really requires bash. I applied a fix to master yesterday so if you rebase against master and update this it should be fine. Sorry about that.

@behlendorf
Copy link
Contributor

Related to #2856

@behlendorf
Copy link
Contributor

@don-brady thanks for refreshing this. The latest version LGTM and works well in my manual testing. Just let me know if you have any more improvements planned or if I should go ahead and merged it. It looks like you got pretty unlucky in the automated testing, so I'm resubmitted those test runs.

@don-brady
Copy link
Contributor Author

@behlendorf No further changes planned. Thanks for the reviews.

@behlendorf
Copy link
Contributor

@ryao can I add your signed off to this?

@behlendorf behlendorf added this to the 0.7.0 milestone Mar 31, 2016
@behlendorf
Copy link
Contributor

@don-brady whoops, we accidentally broke the build on master when I merged this. The updated devname2devid.c utility requires libudev which mean when it's not installed this build fails. We're going to need to make this conditional.

behlendorf added a commit that referenced this pull request Mar 31, 2016
Accidentally introduced by commit 39fc0cb.  The devname2devid utility
which depends on libudev must only be built when libudev headers are
available.  This is accomplished through an AM_CONDITIONAL.

Signed-off-by: Brian Behlendorf <[email protected]>
Issue #4416
@behlendorf
Copy link
Contributor

Rather than revert this commit from master I committed a small follow up patch which causes devname2devid to only get built when libudev is available. I should mention this happened to get missed because as @don-brady rightly point out we don't actually have a builder where the libudev headers are missing.

e4023e4 Only build devname2devid when libudev headers are available
39fc0cb Add support for devid and phys_path keys in vdev disk labels

@drescherjm
Copy link

I am now getting an error building zfs-kmod-9999 in gentoo related to WANT_DEVNAME2DEVID:

  • Running elibtoolize in: zfs-kmod-9999/
  • Running elibtoolize in: zfs-kmod-9999/config/
  • Applying portage/1.2.0 patch ...
  • Applying sed/1.5.6 patch ...
  • Applying as-needed/2.4.3 patch ...

Source prepared.
Configuring source in /var/tmp/portage/sys-fs/zfs-kmod-9999/work/zfs-kmod-9999 ...
Working in BUILD_DIR: "/var/tmp/portage/sys-fs/zfs-kmod-9999/work/zfs-kmod-9999"

  • econf: updating zfs-kmod-9999/config/config.guess with /usr/share/gnuconfig/config.guess
  • econf: updating zfs-kmod-9999/config/config.sub with /usr/share/gnuconfig/config.sub
    /var/tmp/portage/sys-fs/zfs-kmod-9999/work/zfs-kmod-9999/configure --prefix=/usr --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc --localstatedir=/var/lib --disable-dependency-tracking --disable-silent-rules --libdir=/usr/lib64 --docdir=/usr/share/doc/zfs-kmod-9999 --bindir=/bin --sbindir=/sbin --with-config=kernel --with-linux=/usr/src/linux --with-linux-obj=/usr/src/linux --with-spl=/usr/src/spl-0.6.5 --with-spl-obj=/usr/src/spl-0.6.5/4.5.0-gentoo-r1-20160331-vm_gentoo --disable-debug
    checking for gawk... gawk
    checking metadata... git describe
    checking build system type... x86_64-pc-linux-gnu
    checking host system type... x86_64-pc-linux-gnu
    checking target system type... x86_64-pc-linux-gnu
    checking whether to enable maintainer-specific portions of Makefiles... no
    checking whether make supports nested variables... yes
    checking for a BSD-compatible install... /usr/lib/portage/python2.7/ebuild-helpers/xattr/install -c
    checking whether build environment is sane... yes
    checking for a thread-safe mkdir -p... /bin/mkdir -p
    checking whether make sets $(MAKE)... yes
    checking for x86_64-pc-linux-gnu-gcc... x86_64-pc-linux-gnu-gcc
    checking whether the C compiler works... yes
    checking for C compiler default output file name... a.out
    checking for suffix of executables...
    checking whether we are cross compiling... no
    checking for suffix of object files... o
    checking whether we are using the GNU C compiler... yes
    checking whether x86_64-pc-linux-gnu-gcc accepts -g... yes
    checking for x86_64-pc-linux-gnu-gcc option to accept ISO C89... none needed
    checking whether x86_64-pc-linux-gnu-gcc understands -c and -o together... yes
    checking for style of include used by make... GNU
    checking dependency style of x86_64-pc-linux-gnu-gcc... none
    checking how to print strings... printf
    checking for a sed that does not truncate output... /bin/sed
    checking for grep that handles long lines and -e... /bin/grep
    checking for egrep... /bin/grep -E
    checking for fgrep... /bin/grep -F
    checking for ld used by x86_64-pc-linux-gnu-gcc... /usr/x86_64-pc-linux-gnu/bin/ld
    checking if the linker (/usr/x86_64-pc-linux-gnu/bin/ld) is GNU ld... yes
    checking for BSD- or MS-compatible name lister (nm)... /usr/bin/x86_64-pc-linux-gnu-nm -B
    checking the name lister (/usr/bin/x86_64-pc-linux-gnu-nm -B) interface... BSD nm
    checking whether ln -s works... yes
    checking the maximum length of command line arguments... 1572864
    checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
    checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
    checking for /usr/x86_64-pc-linux-gnu/bin/ld option to reload object files... -r
    ...skipping...
    checking whether make_request_fn() returns blk_qc_t... yes
    checking whether generic IO accounting symbols are avaliable... yes
    checking whether asm/fpu/api.h exists... yes
    checking whether debugging is enabled... no
    checking whether dmu tx validation is enabled... no
    checking that generated files are newer than configure... done
    configure: error: conditional "WANT_DEVNAME2DEVID" was never defined.

@behlendorf
Copy link
Contributor

Have you rerun autoreconf -fiv?

@drescherjm
Copy link

This is from an ebuild that builds the latest git. It will create a clean work directory each time.

@behlendorf
Copy link
Contributor

Yes I'm seeing this as well. For the moment you can revert the last two patches. I can't look in to this until tomorrow, but I'll sort it out then. Unless someone beats me to it.

@drescherjm
Copy link

Thanks. I'll hold off the update until this is fixed. I have a recent enough build anyways.

behlendorf added a commit to behlendorf/zfs that referenced this pull request Apr 1, 2016
Accidentally introduced by commit e4023e4.  The AM_CONDITIONAL
cannot be located where it can be invoked conditionally, as in
the `--with-config=user` case.  Relocate it to the top level
ZFS_AC_CONFIG macro along with the other AM_CONDITIONALs.

Signed-off-by: Brian Behlendorf <[email protected]>
Issue openzfs#4416
@drescherjm
Copy link

The latest commit fixed this issue for me. Thanks.

@behlendorf
Copy link
Contributor

@drescherjm great, thanks for confirming the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants