Re: [systemd-devel] ExecStop IPC over same socket used for activation?
On Wed, Feb 11, 2015 at 09:29:29PM +0100, Lennart Poettering wrote: Ineed, analysis seems correct. I now made this change: http://lists.freedesktop.org/archives/systemd-devel/2015-February/028058.html Didn't test it though, please test if this fixes things for you! Thanks Lennart, I ran a test script that usually reproduced the issue in less than a minute for the past few hours without any issues. Looks good to me. - Chris ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] ExecStop IPC over same socket used for activation?
Hi, Lee Duncan and I were looking at a situation with iscsid where a systemctl stop command would sometimes print a job canceled message, and the service would be immediately restarted. The problem seems to be that the ExecStop command is sending a shutdown request over an IPC socket, the same IPC socket used for socket activation. I've captured debug logging of the failure, and it seems to show systemd moving the socket unit back to a listening state before the ExecStop command is run. The shutdown message then triggers a start job, which cancels the pending stop job, the daemon receives the message and exits, but is then restarted right away. This doesn't seem like too crazy of a way to shut things down, should the coordination between the service and the socket unit be waiting for for the ExecStop to complete before monitoring for socket activation again? - Chris Leech ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 2/5] mount: check options as well as fstype for network mounts
When creating a new mount unit after an event on /proc/self/mountinfo, check the mount options as well as the fstype to determine if this is a remote mount that requires network access. Signed-off-by: Chris Leech cle...@redhat.com --- src/core/mount.c | 21 - 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index 74a1da8..81e9fde 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -63,16 +63,20 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata); static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata); +static bool mount_needs_network(const char *options, const char *fstype) { +if (mount_test_option(options, _netdev)) +return true; + +if (fstype fstype_is_network(fstype)) +return true; + +return false; +} + static bool mount_is_network(MountParameters *p) { assert(p); -if (mount_test_option(p-options, _netdev)) -return true; - -if (p-fstype fstype_is_network(p-fstype)) -return true; - -return false; +return mount_needs_network(p-options, p-fstype); } static bool mount_is_bind(MountParameters *p) { @@ -1403,8 +1407,7 @@ static int mount_add_one( if (m-running_as == SYSTEMD_SYSTEM) { const char* target; -target = fstype_is_network(fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET; - +target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET; r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true); if (r 0) goto fail; -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 5/5] mount: auto-detect iSCSI and FCoE as requiring network
This adds auto detection for iSCSI and some FCoE drivers and treats mounts to file-systems on those devices as remote-fs. Signed-off-by: Chris Leech cle...@redhat.com --- src/core/mount.c | 168 +++ 1 file changed, 158 insertions(+), 10 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index 513dcec..52a4ba7 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -26,6 +26,7 @@ #include signal.h #include libmount.h #include sys/inotify.h +#include libudev.h #include manager.h #include unit.h @@ -44,6 +45,7 @@ #include bus-errors.h #include exit-status.h #include def.h +#include udev-util.h static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { [MOUNT_DEAD] = UNIT_INACTIVE, @@ -64,20 +66,166 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata); static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata); -static bool mount_needs_network(const char *options, const char *fstype) { +static bool scsi_host_is(struct udev_device *host, const char *type) { +_cleanup_free_ char *path; +struct stat st; + +assert(host); +assert(type); + +/* a type_host device created by the scsi transport class + * should exists for all the transport types looked for */ + +if (asprintf(path, %s/%s_host, udev_device_get_syspath(host), type) 0) { +log_oom(); +return false; +} +return stat(path, st) == 0 S_ISDIR(st.st_mode); +} + +static bool scsi_host_is_network(struct udev_device *block) { +struct udev_device *host = NULL; +struct udev *udev; + +assert(block); +udev = udev_device_get_udev(block); + +host = udev_device_get_parent_with_subsystem_devtype(block, scsi, scsi_host); +if (!host) +return false; + +/* iSCSI */ +if (scsi_host_is(host, iscsi)) +return true; + +/* FCoE appears as an FC host with a parent FCoE Ctlr device + * This will at least detect the software fcoe module and bnx2fc on kernels = 3.5 */ +if (scsi_host_is(host, fc)) { +_cleanup_free_ char *fc_host_path = NULL; +_cleanup_udev_device_unref_ struct udev_device *fc_host = NULL; +struct udev_device *fcoe_ctlr = NULL; + +if (asprintf(fc_host_path, %s/fc_host/%s, udev_device_get_syspath(host), udev_device_get_sysname(host)) 0) { +log_oom(); +return false; +}; +fc_host = udev_device_new_from_syspath(udev, fc_host_path); +fcoe_ctlr = udev_device_get_parent_with_subsystem_devtype(fc_host, fcoe, fcoe_ctlr); +if (fcoe_ctlr) +return true; +} + +return false; +} + +static int dot_filter(const struct dirent *d) { +if (streq(., d-d_name) || streq(.., d-d_name)) +return 0; +return 1; +} + +static inline bool is_partition(struct udev_device *block) { +const char *devtype; + +devtype = udev_device_get_devtype(block); +if (streq(devtype, partition)) { +return true; +} +return false; +} + +static bool block_needs_network(struct udev_device *block) { +struct udev_device *parent = NULL; +_cleanup_free_ char *slaves_path = NULL; +_cleanup_free_ struct dirent **slaves = NULL; +struct udev *udev; +int n, i; +bool rc = false; + +assert(block); +udev = udev_device_get_udev(block); + +if (scsi_host_is_network(block)) +return true; + +/* if this is a partition, check the parent device */ + +if (is_partition(block)) { +parent = udev_device_get_parent(block); +if (parent block_needs_network(parent)) +return true; +} + +/* if this block device has slaves check them as well + * this handles DM maps including LVM and multipath */ + +if (asprintf(slaves_path, %s/slaves, udev_device_get_syspath(block)) 0) { +log_oom(); +return false; +} + +n = scandir(slaves_path, slaves, dot_filter, alphasort); +for (i = 0; i n; i++) { +_cleanup_udev_device_unref_ struct udev_device *slave = NULL; +_cleanup_free_ char *newpath = NULL; +_cleanup_free_ char *rp = NULL; + +if (asprintf(newpath, %s/%s, slaves_path, slaves[i]-d_name) 0) { +log_oom(); +goto free_the_slaves; +} +rp = realpath(newpath, NULL); +if (!rp
[systemd-devel] [PATCH v2 0/5] mount unit handling improvments with libmount
This patch set is an attempt to use libmount for mount unit handling, in order to address the issues I raised with the _netdev option and remote-fs ordering not working as expected. In addition, given the feedback on my previous posting I went ahead and implemented auto-detection of iSCSI and the FCoE drivers that need a functioning network interface and userspace support. It's somewhat based on the transport detection from lsblk, but using libudev and with a different FCoE check. Changes in v2: Removed all existing mountinfo parsing code that was previously left as a fall-back for building without libmount, which is now a hard build requirement. Added iSCSI and FCoE auto-detection. Chris Leech (5): mount: use libmount to enumerate /proc/self/mountinfo mount: check options as well as fstype for network mounts mount: monitor for utab changes with inotify mount: add remote-fs dependencies if needed after change mount: auto-detect iSCSI and FCoE as requiring network .travis.yml| 2 +- Makefile.am| 4 +- README | 1 + configure.ac | 10 ++ src/core/build.h | 7 ++ src/core/manager.c | 2 +- src/core/manager.h | 2 + src/core/mount.c | 309 - 8 files changed, 282 insertions(+), 55 deletions(-) -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 4/5] mount: add remote-fs dependencies if needed after change
This is an attempt to add it the remote-fs dependencies to a mount unit if the options change, like when the utab options are picked up after mountinfo has already been processed. It just adds the remote-fs dependencies, leaving the local-fs ones in place. With this change I always get mount units with proper remote-fs dependencies when mounted with the _netdev option. Signed-off-by: Chris Leech cle...@redhat.com --- src/core/mount.c | 13 + 1 file changed, 13 insertions(+) diff --git a/src/core/mount.c b/src/core/mount.c index ef45115..513dcec 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1433,6 +1433,19 @@ static int mount_add_one( } } +if (m-running_as == SYSTEMD_SYSTEM) { +const char* target; + +target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : NULL; +/* _netdev option may have shown up late, or on a + * remount. Add remote-fs dependencies, even though + * local-fs ones may already be there */ +if (target) { +unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true); +load_extras = true; +} +} + if (u-load_state == UNIT_NOT_FOUND) { u-load_state = UNIT_LOADED; u-load_error = 0; -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 3/5] mount: monitor for utab changes with inotify
Parsing the mount table with libmount races against the mount command, which will handle the actual mounting before updating utab. This means the poll event on /proc/self/mountinfo can kick of a reparse in systemd before the utab information is available. This change adds in an additional event source using inotify to watch for changes to utab. It only watches for IN_MOVED_TO events, matching libmount behavior of always overwriting this file using rename(2). This does add a second pass through the mount table parsing when utab is updated. Signed-off-by: Chris Leech cle...@redhat.com --- src/core/manager.c | 2 +- src/core/manager.h | 2 ++ src/core/mount.c | 50 -- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/core/manager.c b/src/core/manager.c index 2bc1058..e71a96a 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -548,7 +548,7 @@ int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) { m-idle_pipe[0] = m-idle_pipe[1] = m-idle_pipe[2] = m-idle_pipe[3] = -1; -m-pin_cgroupfs_fd = m-notify_fd = m-signal_fd = m-time_change_fd = m-dev_autofs_fd = m-private_listen_fd = m-kdbus_fd = -1; +m-pin_cgroupfs_fd = m-notify_fd = m-signal_fd = m-time_change_fd = m-dev_autofs_fd = m-private_listen_fd = m-kdbus_fd = m-utab_inotify_fd = -1; m-current_job_id = 1; /* start as id #1, so that we can leave #0 around as null-like value */ m-ask_password_inotify_fd = -1; diff --git a/src/core/manager.h b/src/core/manager.h index ab72548..bdeea14 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -182,6 +182,8 @@ struct Manager { /* Data specific to the mount subsystem */ FILE *proc_self_mountinfo; sd_event_source *mount_event_source; +int utab_inotify_fd; +sd_event_source *mount_utab_event_source; /* Data specific to the swap filesystem */ FILE *proc_swaps; diff --git a/src/core/mount.c b/src/core/mount.c index 81e9fde..ef45115 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -25,6 +25,7 @@ #include sys/epoll.h #include signal.h #include libmount.h +#include sys/inotify.h #include manager.h #include unit.h @@ -1548,11 +1549,13 @@ static void mount_shutdown(Manager *m) { assert(m); m-mount_event_source = sd_event_source_unref(m-mount_event_source); +m-mount_utab_event_source = sd_event_source_unref(m-mount_utab_event_source); if (m-proc_self_mountinfo) { fclose(m-proc_self_mountinfo); m-proc_self_mountinfo = NULL; } +m-utab_inotify_fd = safe_close(m-utab_inotify_fd); } static int mount_get_timeout(Unit *u, uint64_t *timeout) { @@ -1592,12 +1595,32 @@ static int mount_enumerate(Manager *m) { goto fail; } +if (m-utab_inotify_fd 0) { +m-utab_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); +if (m-utab_inotify_fd 0) +goto fail_with_errno; + +r = inotify_add_watch(m-utab_inotify_fd, /run/mount, IN_MOVED_TO); +if (r 0) +goto fail_with_errno; + +r = sd_event_add_io(m-event, m-mount_utab_event_source, m-utab_inotify_fd, EPOLLIN, mount_dispatch_io, m); +if (r 0) +goto fail; + +r = sd_event_source_set_priority(m-mount_utab_event_source, -10); +if (r 0) +goto fail; +} + r = mount_load_proc_self_mountinfo(m, false); if (r 0) goto fail; return 0; +fail_with_errno: +r = -errno; fail: mount_shutdown(m); return r; @@ -1609,11 +1632,34 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, int r; assert(m); -assert(revents EPOLLPRI); +assert(revents (EPOLLPRI | EPOLLIN)); /* The manager calls this for every fd event happening on the * /proc/self/mountinfo file, which informs us about mounting - * table changes */ + * table changes + * This may also be called for /run/mount events */ + +if (fd == m-utab_inotify_fd) { +char inotify_buffer[sizeof(struct inotify_event) + NAME_MAX + 1]; +struct inotify_event *event; +char *p; +int rescan = 0; + +while ((r = read(fd, inotify_buffer, sizeof(inotify_buffer))) 0) { +for (p = inotify_buffer; p inotify_buffer + r; ) { +event = (struct inotify_event *) p; +/* only care about changes to utab, but we have + * to monitor the directory to reliably get + * notifications
[systemd-devel] [PATCH v2 1/5] mount: use libmount to enumerate /proc/self/mountinfo
This lets libmount add in user options from /run/mount/utab, like _netdev which is needed to get proper ordering against remote-fs.target Signed-off-by: Chris Leech cle...@redhat.com --- .travis.yml | 2 +- Makefile.am | 4 +++- README | 1 + configure.ac | 10 + src/core/build.h | 7 ++ src/core/mount.c | 65 ++-- 6 files changed, 52 insertions(+), 37 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7e5251c..4ea2bc2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ compiler: - gcc before_install: - sudo apt-get update -qq - - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf python2.7-dev + - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libmount-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf python2.7-dev script: ./autogen.sh ./configure --enable-gtk-doc --enable-gtk-doc-pdf make V=1 sudo ./systemd-machine-id-setup make check make distcheck after_failure: cat test-suite.log notifications: diff --git a/Makefile.am b/Makefile.am index 3f9f3fa..042fb0e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1149,6 +1149,7 @@ libsystemd_core_la_CFLAGS = \ $(KMOD_CFLAGS) \ $(APPARMOR_CFLAGS) \ $(SECCOMP_CFLAGS) \ + $(MOUNT_CFLAGS) \ -pthread libsystemd_core_la_LIBADD = \ @@ -1161,7 +1162,8 @@ libsystemd_core_la_LIBADD = \ $(AUDIT_LIBS) \ $(KMOD_LIBS) \ $(APPARMOR_LIBS) \ - $(SECCOMP_LIBS) + $(SECCOMP_LIBS) \ + $(MOUNT_LIBS) if HAVE_SECCOMP libsystemd_core_la_LIBADD += \ diff --git a/README b/README index aefb349..84c6ed4 100644 --- a/README +++ b/README @@ -106,6 +106,7 @@ REQUIREMENTS: glibc = 2.14 libcap +libmount = 2.20 (from util-linux) libseccomp = 1.0.0 (optional) libblkid = 2.20 (from util-linux) (optional) libkmod = 15 (optional) diff --git a/configure.ac b/configure.ac index 2c8be53..ecd53a4 100644 --- a/configure.ac +++ b/configure.ac @@ -427,6 +427,15 @@ fi AM_CONDITIONAL(HAVE_BLKID, [test $have_blkid = yes]) # -- +have_libmount=no +PKG_CHECK_MODULES(MOUNT, [ mount = 2.20 ], +[AC_DEFINE(HAVE_LIBMOUNT, 1, [Define if libmount is available]) have_libmount=yes], have_libmount=no) +if test x$have_libmount = xno; then +AC_MSG_ERROR([*** libmount support required but libraries not found]) +fi +AM_CONDITIONAL(HAVE_LIBMOUNT, [test $have_libmount = yes]) + +# -- have_seccomp=no AC_ARG_ENABLE(seccomp, AS_HELP_STRING([--disable-seccomp], [Disable optional SECCOMP support])) if test x$enable_seccomp != xno; then @@ -1375,6 +1384,7 @@ AC_MSG_RESULT([ efi: ${have_efi} kmod:${have_kmod} blkid: ${have_blkid} +libmount:${have_libmount} dbus:${have_dbus} nss-myhostname: ${have_myhostname} gudev: ${enable_gudev} diff --git a/src/core/build.h b/src/core/build.h index 24873ab..4f639ed 100644 --- a/src/core/build.h +++ b/src/core/build.h @@ -117,6 +117,12 @@ #define _BLKID_FEATURE_ -BLKID #endif +#ifdef HAVE_LIBMOUNT +#define _LIBMOUNT_FEATURE_ +LIBMOUNT +#else +#define _LIBMOUNT_FEATURE_ -LIBMOUNT +#endif + #ifdef HAVE_ELFUTILS #define _ELFUTILS_FEATURE_ +ELFUTILS #else @@ -152,6 +158,7 @@ _LZ4_FEATURE_ \ _SECCOMP_FEATURE_ \ _BLKID_FEATURE_ \ +_LIBMOUNT_FEATURE_\ _ELFUTILS_FEATURE_\ _KMOD_FEATURE_\ _IDN_FEATURE_ diff --git a/src/core/mount.c b/src/core/mount.c index 8b787f6..74a1da8 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -24,6 +24,7 @@ #include mntent.h #include sys/epoll.h #include signal.h +#include libmount.h #include manager.h #include unit.h @@ -1492,55 +1493,47 @@ fail: return r; } +static inline void mnt_free_table_p(struct libmnt_table **tb) { +mnt_free_table(*tb); +} + +static inline void mnt_free_iter_p(struct libmnt_iter **itr) { +mnt_free_iter(*itr); +} + static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags
Re: [systemd-devel] [RFC 1/4] use libmount to enumerate /proc/self/mountinfo
On Sat, Nov 15, 2014 at 02:09:26PM +0100, Tom Gundersen wrote: Usually we don't do this kind of fallback, but rather disable the relevant functionality if the lib is not available. In this case I guess it means making support for .mount units optional. I could imagine someone doing that in very specialised use cases, but maybe it makes more sense to make the library a hard dependency for now... OK, I was following the optional lead from libblkid and I guess thinking about non util-linux/libmount mount implementations (busybox?). But I see that util-linux is listed as a hard dependency anyway, so I'll remove the fallback code and send updated patches. - Chris ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC 4/4] add remote-fs dependencies if needed after change
On Sun, Nov 09, 2014 at 08:32:05AM +0300, Andrei Borzenkov wrote: В Thu, 6 Nov 2014 21:11:03 -0800 Chris Leech cle...@redhat.com пишет: This is an attempt to add it the remote-fs dependencies to a mount unit if the options change, like when the utab options are picked up after mountinfo has already been processed. It just adds the remote-fs dependencies, leaving the local-fs ones in place. With this change I always get mount units with proper remote-fs dependencies when mounted with the _netdev option. It it not working for -o remount,_netdev. But that looks like a libmount issue in that the ROOT field is not being set in utab on a remount, so if the initial mount did not require a utab entry then remount options never get merge in properly in mnt_table_parse_mtab --- src/core/mount.c | 13 + 1 file changed, 13 insertions(+) diff --git a/src/core/mount.c b/src/core/mount.c index 7d77021..092a720 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1436,6 +1436,19 @@ static int mount_add_one( } } +if (m-running_as == SYSTEMD_SYSTEM) { +const char* target; + +target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : NULL; +/* _netdev option may have shown up late, or on a + * remount. Add remote-fs dependencies, even though + * local-fs ones may already be there */ +if (target) { +unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true); +load_extras = true; +} +} Should not it also add After on network.target to ensure it is unmounted before network is down on shutdown? May be simply calling mount_add_default_dependencies() would be appropriate here. Setting load_extras to true causes mount_add_extras to be called further down in this function, which calls mount_add_default_dependencies. So in testing I did see the After get added as well. But if there's a better way to clean up the mount unit adding code I'm all for it. - Chris ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC 0/4] use libmount for mount unit handling
This patchset is an attempt to use libmount for mount unit handling, in order to address the issues I raised with the _netdev option and remote-fs ordering not working as expected. The first three patches I think are fairly complete, while the final patch may need additional work to get everything right. Also, as I mention in that patch description, remounts aren't picking up utab settings but I think that's a libmount issue. Thanks for taking the time to look at this, Chris Leech (4): use libmount to enumerate /proc/self/mountinfo check options as well as fstype for network mounts monitor for utab changes with inotify add remote-fs dependencies if needed after change .travis.yml| 2 +- Makefile.am| 4 +- README | 1 + configure.ac | 13 + src/core/build.h | 7 +++ src/core/manager.c | 2 +- src/core/manager.h | 2 + src/core/mount.c | 145 + 8 files changed, 163 insertions(+), 13 deletions(-) -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC 4/4] add remote-fs dependencies if needed after change
This is an attempt to add it the remote-fs dependencies to a mount unit if the options change, like when the utab options are picked up after mountinfo has already been processed. It just adds the remote-fs dependencies, leaving the local-fs ones in place. With this change I always get mount units with proper remote-fs dependencies when mounted with the _netdev option. It it not working for -o remount,_netdev. But that looks like a libmount issue in that the ROOT field is not being set in utab on a remount, so if the initial mount did not require a utab entry then remount options never get merge in properly in mnt_table_parse_mtab --- src/core/mount.c | 13 + 1 file changed, 13 insertions(+) diff --git a/src/core/mount.c b/src/core/mount.c index 7d77021..092a720 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1436,6 +1436,19 @@ static int mount_add_one( } } +if (m-running_as == SYSTEMD_SYSTEM) { +const char* target; + +target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : NULL; +/* _netdev option may have shown up late, or on a + * remount. Add remote-fs dependencies, even though + * local-fs ones may already be there */ +if (target) { +unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true); +load_extras = true; +} +} + if (u-load_state == UNIT_NOT_FOUND) { u-load_state = UNIT_LOADED; u-load_error = 0; -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC 2/4] check options as well as fstype for network mounts
When creating a new mount unit after an event on /proc/self/mountinfo, check the mount options as well as the fstype to determine if this is a remote mount that requires network access. --- src/core/mount.c | 21 - 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index a639515..2bc7b14 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -68,16 +68,20 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata); static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata); +static bool mount_needs_network(const char *options, const char *fstype) { +if (mount_test_option(options, _netdev)) +return true; + +if (fstype fstype_is_network(fstype)) +return true; + +return false; +} + static bool mount_is_network(MountParameters *p) { assert(p); -if (mount_test_option(p-options, _netdev)) -return true; - -if (p-fstype fstype_is_network(p-fstype)) -return true; - -return false; +return mount_needs_network(p-options, p-fstype); } static bool mount_is_bind(MountParameters *p) { @@ -1408,8 +1412,7 @@ static int mount_add_one( if (m-running_as == SYSTEMD_SYSTEM) { const char* target; -target = fstype_is_network(fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET; - +target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET; r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true); if (r 0) goto fail; -- 1.9.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC 3/4] monitor for utab changes with inotify
Parsing the mount table with libmount races against the mount command, which will handle the actual mounting before updating utab. This means the poll event on /proc/self/mountinfo can kick of a reparse in systemd before the utab information is available. This change adds in an additional event source using inotify to watch for changes to utab. It only watches for IN_MOVED_TO events, matching libmount behavior of always overwriting this file using rename(2). This does add a second pass through the mount table parsing when utab is updated. --- src/core/manager.c | 2 +- src/core/manager.h | 2 ++ src/core/mount.c | 57 +- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/core/manager.c b/src/core/manager.c index 129f6dd..7362149 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -554,7 +554,7 @@ int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) { m-idle_pipe[0] = m-idle_pipe[1] = m-idle_pipe[2] = m-idle_pipe[3] = -1; -m-pin_cgroupfs_fd = m-notify_fd = m-signal_fd = m-time_change_fd = m-dev_autofs_fd = m-private_listen_fd = m-kdbus_fd = -1; +m-pin_cgroupfs_fd = m-notify_fd = m-signal_fd = m-time_change_fd = m-dev_autofs_fd = m-private_listen_fd = m-kdbus_fd = m-utab_inotify_fd = -1; m-current_job_id = 1; /* start as id #1, so that we can leave #0 around as null-like value */ m-ask_password_inotify_fd = -1; diff --git a/src/core/manager.h b/src/core/manager.h index ab72548..bdeea14 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -182,6 +182,8 @@ struct Manager { /* Data specific to the mount subsystem */ FILE *proc_self_mountinfo; sd_event_source *mount_event_source; +int utab_inotify_fd; +sd_event_source *mount_utab_event_source; /* Data specific to the swap filesystem */ FILE *proc_swaps; diff --git a/src/core/mount.c b/src/core/mount.c index 2bc7b14..7d77021 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -26,9 +26,8 @@ #include signal.h #ifdef HAVE_LIBMOUNT +#include sys/inotify.h #include libmount.h -#else -#define mnt_init_debug(m) do {} while (0) #endif #include manager.h @@ -1615,11 +1614,13 @@ static void mount_shutdown(Manager *m) { assert(m); m-mount_event_source = sd_event_source_unref(m-mount_event_source); +m-mount_utab_event_source = sd_event_source_unref(m-mount_utab_event_source); if (m-proc_self_mountinfo) { fclose(m-proc_self_mountinfo); m-proc_self_mountinfo = NULL; } +m-utab_inotify_fd = safe_close(m-utab_inotify_fd); } static int mount_get_timeout(Unit *u, uint64_t *timeout) { @@ -1640,8 +1641,6 @@ static int mount_enumerate(Manager *m) { int r; assert(m); -mnt_init_debug(0); - if (!m-proc_self_mountinfo) { m-proc_self_mountinfo = fopen(/proc/self/mountinfo, re); if (!m-proc_self_mountinfo) @@ -1658,6 +1657,27 @@ static int mount_enumerate(Manager *m) { if (r 0) goto fail; } +#ifdef HAVE_LIBMOUNT +mnt_init_debug(0); + +if (m-utab_inotify_fd 0) { +m-utab_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); +if (m-utab_inotify_fd 0) +goto fail_with_errno; + +r = inotify_add_watch(m-utab_inotify_fd, /run/mount, IN_MOVED_TO); +if (r 0) +goto fail_with_errno; + +r = sd_event_add_io(m-event, m-mount_utab_event_source, m-utab_inotify_fd, EPOLLIN, mount_dispatch_io, m); +if (r 0) +goto fail; + +r = sd_event_source_set_priority(m-mount_utab_event_source, -10); +if (r 0) +goto fail; +} +#endif r = mount_load_proc_self_mountinfo(m, false); if (r 0) @@ -1665,6 +1685,8 @@ static int mount_enumerate(Manager *m) { return 0; +fail_with_errno: +r = -errno; fail: mount_shutdown(m); return r; @@ -1676,12 +1698,37 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, int r; assert(m); -assert(revents EPOLLPRI); +assert(revents (EPOLLPRI | EPOLLIN)); /* The manager calls this for every fd event happening on the * /proc/self/mountinfo file, which informs us about mounting * table changes */ +#ifdef HAVE_LIBMOUNT +/* This may also be called for /run/mount events */ +if (fd == m-utab_inotify_fd) { +char inotify_buffer[sizeof(struct inotify_event) + NAME_MAX + 1]; +struct inotify_event *event; +char *p; +int rescan = 0; + +while ((r =
[systemd-devel] [RFC 1/4] use libmount to enumerate /proc/self/mountinfo
This lets libmount add in user options from /run/mount/utab, like _netdev which is needed to get proper ordering against remote-fs.target --- .travis.yml | 2 +- Makefile.am | 4 +++- README | 1 + configure.ac | 13 src/core/build.h | 7 +++ src/core/mount.c | 62 6 files changed, 87 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7e5251c..4ea2bc2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ compiler: - gcc before_install: - sudo apt-get update -qq - - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf python2.7-dev + - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libmount-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf python2.7-dev script: ./autogen.sh ./configure --enable-gtk-doc --enable-gtk-doc-pdf make V=1 sudo ./systemd-machine-id-setup make check make distcheck after_failure: cat test-suite.log notifications: diff --git a/Makefile.am b/Makefile.am index 461ffa9..3deffe8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1163,6 +1163,7 @@ libsystemd_core_la_CFLAGS = \ $(KMOD_CFLAGS) \ $(APPARMOR_CFLAGS) \ $(SECCOMP_CFLAGS) \ + $(MOUNT_CFLAGS) \ -pthread libsystemd_core_la_LIBADD = \ @@ -1177,7 +1178,8 @@ libsystemd_core_la_LIBADD = \ $(CAP_LIBS) \ $(KMOD_LIBS) \ $(APPARMOR_LIBS) \ - $(SECCOMP_LIBS) + $(SECCOMP_LIBS) \ + $(MOUNT_LIBS) if HAVE_SECCOMP libsystemd_core_la_LIBADD += \ diff --git a/README b/README index aefb349..89abc3e 100644 --- a/README +++ b/README @@ -108,6 +108,7 @@ REQUIREMENTS: libcap libseccomp = 1.0.0 (optional) libblkid = 2.20 (from util-linux) (optional) +libmount = 2.20 (from util-linux) (optional) libkmod = 15 (optional) PAM = 1.1.2 (optional) libcryptsetup (optional) diff --git a/configure.ac b/configure.ac index 05fc00d..85ff053 100644 --- a/configure.ac +++ b/configure.ac @@ -426,6 +426,18 @@ fi AM_CONDITIONAL(HAVE_BLKID, [test $have_blkid = yes]) # -- +have_libmount=no +AC_ARG_ENABLE(libmount, AS_HELP_STRING([--disable-libmount], [disable libmount support])) +if test x$enable_libmount != xno; then +PKG_CHECK_MODULES(MOUNT, [ mount = 2.20 ], +[AC_DEFINE(HAVE_LIBMOUNT, 1, [Define if libmount is available]) have_libmount=yes], have_libmount=no) +if test x$have_libmount = xno -a x$enable_libmount = xyes; then +AC_MSG_ERROR([*** libmount support requested but libraries not found]) +fi +fi +AM_CONDITIONAL(HAVE_LIBMOUNT, [test $have_libmount = yes]) + +# -- have_seccomp=no AC_ARG_ENABLE(seccomp, AS_HELP_STRING([--disable-seccomp], [Disable optional SECCOMP support])) if test x$enable_seccomp != xno; then @@ -1374,6 +1386,7 @@ AC_MSG_RESULT([ efi: ${have_efi} kmod:${have_kmod} blkid: ${have_blkid} +libmount:${have_libmount} dbus:${have_dbus} nss-myhostname: ${have_myhostname} gudev: ${enable_gudev} diff --git a/src/core/build.h b/src/core/build.h index d5e5550..5644693 100644 --- a/src/core/build.h +++ b/src/core/build.h @@ -117,6 +117,12 @@ #define _BLKID_FEATURE_ -BLKID #endif +#ifdef HAVE_LIBMOUNT +#define _LIBMOUNT_FEATURE_ +LIBMOUNT +#else +#define _LIBMOUNT_FEATURE_ -LIBMOUNT +#endif + #ifdef HAVE_ELFUTILS #define _ELFUTILS_FEATURE_ +ELFUTILS #else @@ -152,6 +158,7 @@ _LZ4_FEATURE_ \ _SECCOMP_FEATURE_ \ _BLKID_FEATURE_ \ +_LIBMOUNT_FEATURE_\ _ELFUTILS_FEATURE_\ _KMOD_FEATURE_\ _IDN_FEATURE_ diff --git a/src/core/mount.c b/src/core/mount.c index 8b787f6..a639515 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -25,6 +25,12 @@ #include sys/epoll.h #include signal.h +#ifdef HAVE_LIBMOUNT +#include libmount.h +#else +#define mnt_init_debug(m) do {} while (0) +#endif + #include manager.h #include unit.h #include mount.h @@ -1492,6 +1498,58 @@ fail:
Re: [systemd-devel] remote-fs ordering, iSCSI and _netdev
On Fri, Oct 31, 2014 at 09:32:57AM +0100, Karel Zak wrote: It would be really better to have within systemd a generic function is_net_blkdev() than rely on external fragile configuration. I have doubts that anyone uses -o _netdev on command line when manually mounts filesystem. The one thing I do like about _netdev, is that if it works is a simple workaround that can be documented for when more complicated detection schemes fail. Rather than trying to keep a list of all known network filesystem and block protocols up to date. Not sure, maybe it's possible to detect this by scsi info in /sys. I took a look at what lsscsi is doing to guess at transport type. iSCSI is kind of ugly, FCoE is really ugly, and for both of those there exists a variety of drivers with varying levels of dependence on the networking layer. It would be nice to work on getting some of the more common works working automatically, but _netdev seems like a nice failsafe. I'm sending an RFC patchset with a start at addressing this. - Chris ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] remote-fs ordering, iSCSI and _netdev
On Thu, Oct 30, 2014 at 12:10:16PM +0100, Karel Zak wrote: On Tue, Oct 28, 2014 at 02:29:35AM +0100, Lennart Poettering wrote: On Mon, 27.10.14 14:10, Chris Leech (cle...@redhat.com) wrote: So for any mounts to remote block devices (unlike remote file system protocols which are detected by the fs name), unless there is an fstab entry at the time fstab-generator is run they get treated like local fs mounts and connectivity to the storage target may be disrupted before unmounting (possibly resulting in file system errors). I'm currently at a loss for how to handle this, other than to claim that if filesystems are going to be left mounted they should be added to fstab and a daemon-reload is required. IIRC mount nowadays stores the full mount option string, including all the userspace-only options in /run. We could either read those directly from there in systemd, or we could make systemd make use of libmount to get that information. _netdev is information about device rather than about filesystem. Would be possible to have this info (this is iSCSI) in udev db? Yes, the _netdev option is ugly. For iSCSI specifically, we'd have to trace the block device back to the scsi_host, then match that up with an iscsi_host from the transport class. Or come up with some change to make that process easier. And it would need to work for dm/md device over the actually scsi device. You know, all userpsace mount options suck, it's always fragile to maintain mount options in userspace (due to namespaces, ...) Karel, what are the details there? Would it be OK if we read the files in /run directly to augment whatever we got from /proc/self/mountinfo? I'd like to keep /run/mount/utab as private libmount file. It would be better to use mnt_table_parse_mtab() libmount function to get parsed mountinfo + userspace mount options. IMHO you can implement it as optional feature #ifdef HAVE_LIBMOUNT to optionally use mnt_table_parse_mtab() from libmount rather than directly parse /proc/self/mountinfo. Thanks for the direction, I've worked up a patch that does this and using libmount here was pretty easy. Unfortunatly with systemd triggering off of the change event from /proc/self/mountinfo, it ends up racing with the mount command to access /run/mount/utab and the _netdev option I'm looking for isn't consistantly picked up. I'll see what else I can come up with. - Chris ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] remote-fs ordering, iSCSI and _netdev
On Tue, Oct 28, 2014 at 06:41:32AM +0300, Andrei Borzenkov wrote: В Mon, 27 Oct 2014 14:10:47 -0700 Chris Leech cle...@redhat.com пишет: But there are two cases that are problematic, adding entries to fstab at runtime and manually mounting without adding to fstab (while still using the _netdev option, some hint is needed). The first case actually ends up being the second, with the possible work-around of always remembering to run a daemon-reload after editing fstab to run fstab-generator again. Even known network filesystems still have a problem. If network filesystem is mounted on boot, it pulls in network-online.target which (hopefully) serves as synchronization point on shutdown. If there is no network filesystem to mount at boot, network-online.target is not started. If you mount NFS manually later there is nothing to wait for on shutdown so network could be teared down before filesystem is unmounted. Hmm, I hadn't noticed that with iSCSI because a service gets started to connect to the target so the dependencies can be taken care of there. Should the remote mount unit be generating a Wants dependency along with the Before/After to ensure the synchronization point targets are active? Or would that not work for some reason? - Chris ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] remote-fs ordering, iSCSI and _netdev
On Tue, Oct 28, 2014 at 01:57:06AM +0100, Zbigniew Jędrzejewski-Szmek wrote: On Mon, Oct 27, 2014 at 02:10:47PM -0700, Chris Leech wrote: ... If there's no matching mount unit from fstab-generator, one gets created dynamically when the fs is mounted by monitoring /proc/self/mountinfo. Actually, it is more correct to say that a unit *always* get created based on /proc/self/mountinfo. If there was a unit previously, it is replaced by the new one, but inherits the dependencies. In effect it leads to the behaviour you described. Thanks for making that clear. So for any mounts to remote block devices (unlike remote file system protocols which are detected by the fs name), unless there is an fstab entry at the time fstab-generator is run they get treated like local fs mounts and connectivity to the storage target may be disrupted before unmounting (possibly resulting in file system errors). Yes, that seems right. It seems reasonable to change the code which generates units based on /p/s/mounintinfo to behave as if _netdev option was specified, for the known network filesystem types. That's in place and (I'm haven't been testing it but I think) working. The problem is with network block devices where the fstype is the on-disk filesystem. - Chris ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] remote-fs ordering, iSCSI and _netdev
Hi, I was hoping someone could help me make sure I'm not overlooking something with trying to manage mounts on iSCSI disks. I have an iscsi.service which starts and stops sessions to iSCSI targets. It's set with Before=remote-fs-pre.target and Wants=remote-fs-pre.target to ensure that remote fs ordering is enabled. Unfortunately mount points only get configured as remote if there is a record in /etc/fstab at the time fstab-generator is run. At boot fstab-generator is picking up on the _netdev option in fstab, and the generated mount units are ordered against remote-fs properly. If I leave a filesystem mounted at shutdown, it will be unmounted before the iSCSI session is destroyed or the network is shut down and everything works as expected. But there are two cases that are problematic, adding entries to fstab at runtime and manually mounting without adding to fstab (while still using the _netdev option, some hint is needed). The first case actually ends up being the second, with the possible work-around of always remembering to run a daemon-reload after editing fstab to run fstab-generator again. If there's no matching mount unit from fstab-generator, one gets created dynamically when the fs is mounted by monitoring /proc/self/mountinfo. While the core mount unit code checks for _netdev, it's never present in mountinfo. Back in the days of a userspace managed mtab, the _netdev flag was stashed there and could be looked for later, but not so any longer. So for any mounts to remote block devices (unlike remote file system protocols which are detected by the fs name), unless there is an fstab entry at the time fstab-generator is run they get treated like local fs mounts and connectivity to the storage target may be disrupted before unmounting (possibly resulting in file system errors). I'm currently at a loss for how to handle this, other than to claim that if filesystems are going to be left mounted they should be added to fstab and a daemon-reload is required. Thanks in advance for any ideas, - Chris ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC] iscsi unit files and helper script
On Tue, Dec 11, 2012 at 03:47:03PM -0600, Mike Christie wrote: Thanks for working on this. Just one question. Is this patch for some other package? How does it relate to the unit files in Tomasz's patchset? He unit files with the same name. I just diffed against an empty directory to show what I was testing with, it might have made more sense for this to not be a patch but I was on a roll. There's a difference between running as forking or simple here, but that's not a big deal. And I've been making changes to my iscsi.service for automatic starting and stoping of sessions today, getting the ordering right to not run into problems with automatic mount points. I haven't run into any problems with the patches I posted, but I'm not happy with the unit files just yet. - Chris On 12/10/2012 04:08 PM, Chris Leech wrote: iSCSI service and socket files, and the iscsi_mark_root_nodes helper script to preserve sessions started in the initramfs. diff -Naur a/iscsid.service b/iscsid.service --- a/iscsid.service1969-12-31 16:00:00.0 -0800 +++ b/iscsid.service2012-12-10 13:38:38.643307001 -0800 @@ -0,0 +1,9 @@ +[Unit] +Description=Open-iSCSI +Documentation=man:iscsid(8) man:iscsiadm(8) +After=network.target NetworkManager-wait-online.service iscsiuio.service tgtd.service targetcli.service + +[Service] +Type=simple +ExecStart=/usr/sbin/iscsid -f -n +ExecStop=/sbin/iscsiadm -k 0 2 diff -Naur a/iscsid.socket b/iscsid.socket --- a/iscsid.socket 1969-12-31 16:00:00.0 -0800 +++ b/iscsid.socket 2012-12-10 13:38:38.643307001 -0800 @@ -0,0 +1,9 @@ +[Unit] +Description=Open-iSCSI iscsid Socket +Documentation=man:iscsid(8) man:iscsiadm(8) + +[Socket] +ListenStream=@ISCSIADM_ABSTRACT_NAMESPACE + +[Install] +WantedBy=sockets.target diff -Naur a/iscsi.service b/iscsi.service --- a/iscsi.service 1969-12-31 16:00:00.0 -0800 +++ b/iscsi.service 2012-12-10 13:38:38.643307001 -0800 @@ -0,0 +1,18 @@ +[Unit] +Description=Login and scanning of iSCSI devices +Documentation=man:iscsiadm(8) man:iscsid(8) +#Requires=iscsid.service +#BindTo=iscsid.service +After=network.target NetworkManager-wait-online.service iscsid.service +ConditionPathExists=/etc/iscsi/initiatorname.iscsi + +[Service] +Type=oneshot +ExecStart=/usr/libexec/iscsi_mark_root_nodes +ExecStart=/sbin/iscsiadm -m node --loginall=automatic +ExecStop=/bin/sync +ExecStop=/sbin/iscsiadm -m node --logoutall=automatic +RemainAfterExit=true + +[Install] +WantedBy=remote-fs.target diff -Naur a/iscsiuio.service b/iscsiuio.service --- a/iscsiuio.service 1969-12-31 16:00:00.0 -0800 +++ b/iscsiuio.service 2012-12-10 13:38:38.643307001 -0800 @@ -0,0 +1,11 @@ +[Unit] +Description=iSCSI UserSpace I/O driver +Documentation=man:iscsiuio(8) +Requires=iscsid.service +BindTo=iscsid.service +Before=iscsid.service +After=network.target NetworkManager-wait-online.service + +[Service] +Type=simple +ExecStart=/usr/sbin/iscsiuio -f diff -Naur a/iscsiuio.socket b/iscsiuio.socket --- a/iscsiuio.socket 1969-12-31 16:00:00.0 -0800 +++ b/iscsiuio.socket 2012-12-10 13:38:38.643307001 -0800 @@ -0,0 +1,9 @@ +[Unit] +Description=Open-iSCSI iscsiuio +Documentation=man:iscsiuio(8) + +[Socket] +ListenStream=@ISCSID_UIP_ABSTRACT_NAMESPACE + +[Install] +WantedBy=sockets.target diff -Naur a/usr/libexec/iscsi_mark_root_nodes b/usr/libexec/iscsi_mark_root_nodes --- a/usr/libexec/iscsi_mark_root_nodes 1969-12-31 16:00:00.0 -0800 +++ b/usr/libexec/iscsi_mark_root_nodes 2012-12-10 13:38:47.322082141 -0800 @@ -0,0 +1,14 @@ +#!/bin/bash + +ISCSIADM=/sbin/iscsiadm +SESSION_FILE=/run/initramfs/iscsi.sessions + +if [ ! -f $SESSION_FILE ] ; then + exit 0 +fi + +while read t num i target; do + ip=${i%:*} + $ISCSIADM -m node -p $ip -T $target -o update -n node.startup -v onboot +done $SESSION_FILE + ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC] iscsid / systemd / dracut integration effort
On Mon, Dec 10, 2012 at 11:56:07PM +, Jóhann B. Guðmundsson wrote: On 12/10/2012 10:08 PM, Chris Leech wrote: 2) Proper ordering of the iscsi.service for non-root filesystems. Any and all feedback and/or help welcome. Looking the unit file for iscsid I do believe I missed this ( basically the same as multipath unit ) since you know it's early boot special, root and all that ;) [Unit] # Before or After lvm2-activation-early.service DefaultDependencies=no Conflicts=shutdown.target [Install] WantedBy=sysinit.target Thanks, this got me going in the right direction. These unit files seems to be working much better for me, with the startup and shutdown ordering between iscsi, iscsid, and remote-fs mounts sorted out. I'm not sure about the tgtd/targetcli stuff, not sure what the original need there was. My non-root test install with /home on iSCSI also has a swap partition on it, and that's still causing me all sorts of trouble if I don't comment it out in fstab. Trying to order all this before swap.target blew up in my face pretty good. - Chris --- iscsi.service --- [Unit] Description=Login and scanning of iSCSI devices Documentation=man:iscsiadm(8) man:iscsid(8) DefaultDependencies=no Conflicts=shutdown.target After=systemd-remount-fs.service network.target iscsid.service iscsiuio.service Before=remote-fs.target ConditionPathExists=/etc/iscsi/initiatorname.iscsi [Service] Type=oneshot ExecStart=/usr/libexec/iscsi_mark_root_nodes ExecStart=/sbin/iscsiadm -m node --loginall=automatic ExecStop=/bin/sync ExecStop=/sbin/iscsiadm -m node --logoutall=automatic RemainAfterExit=true [Install] WantedBy=sysinit.target --- iscsid.service --- [Unit] Description=Open-iSCSI Documentation=man:iscsid(8) man:iscsiadm(8) DefaultDependencies=no Conflicts=shutdown.target After=network.target tgtd.service targetcli.service Before=remote-fs-pre.target [Service] Type=simple ExecStart=/usr/sbin/iscsid -f -n ExecStop=/sbin/iscsiadm -k 0 2 --- iscsid.socket --- [Unit] Description=Open-iSCSI iscsid Socket Documentation=man:iscsid(8) man:iscsiadm(8) [Socket] ListenStream=@ISCSIADM_ABSTRACT_NAMESPACE [Install] WantedBy=sockets.target ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC] iscsid: add --initrd option to set run from initrd hint for systemd
See http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons --- usr/iscsid.c | 8 1 file changed, 8 insertions(+) diff --git a/usr/iscsid.c b/usr/iscsid.c index b4bb65b..7d71085 100644 --- a/usr/iscsid.c +++ b/usr/iscsid.c @@ -61,6 +61,7 @@ static pid_t log_pid; static gid_t gid; static int daemonize = 1; static int mgmt_ipc_fd; +static int initrd = 0; static struct option const long_options[] = { {config, required_argument, NULL, 'c'}, @@ -73,6 +74,7 @@ static struct option const long_options[] = { {pid, required_argument, NULL, 'p'}, {help, no_argument, NULL, 'h'}, {version, no_argument, NULL, 'v'}, + {initrd, no_argument, initrd, 1}, {NULL, 0, NULL, 0}, }; @@ -95,6 +97,7 @@ Open-iSCSI initiator daemon.\n\ -p, --pid=pidfile use pid file (default PID_FILE ).\n\ -h, --help display this help and exit\n\ -v, --version display version and exit\n\ + --initrdrun from initrd\n\ ); } exit(status); @@ -383,12 +386,17 @@ int main(int argc, char *argv[]) case 'h': usage(0); break; + case 0: + break; default: usage(1); break; } } + if (initrd) + argv[0][0] = '@'; + /* initialize logger */ log_pid = log_init(program_name, DEFAULT_AREA_SIZE, daemonize ? log_do_log_daemon : log_do_log_std, NULL); -- 1.7.11.7 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC] iscsiadm, iscsid: newroot command to survive switch_root
When started from initramfs, iscsid needs to be able to chroot itself to the runtime filesystem before the switch_root occurs. In the initramfs iscsiadm --newroot {root fs mount before switch} should be called before the switch_root. --- usr/iscsiadm.c | 30 +- usr/mgmt_ipc.c | 11 +++ usr/mgmt_ipc.h | 6 +- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c index 8f9de05..7b601b3 100644 --- a/usr/iscsiadm.c +++ b/usr/iscsiadm.c @@ -111,9 +111,10 @@ static struct option const long_options[] = {packetsize, required_argument, NULL, 'b'}, {count, required_argument, NULL, 'c'}, {interval, required_argument, NULL, 'i'}, + {newroot, required_argument, NULL, 'N'}, {NULL, 0, NULL, 0}, }; -static char *short_options = RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:u; +static char *short_options = RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:uN:; static void usage(int status) { @@ -251,6 +252,22 @@ static void kill_iscsid(int priority) } } +static void do_newroot(char *newroot) +{ + iscsiadm_req_t req; + iscsiadm_rsp_t rsp; + int rc; + + memset(req, 0, sizeof(req)); + req.command = MGMT_IPC_NEWROOT; + strncpy(req.u.newroot.path, newroot, PATH_MAX); + rc = iscsid_exec_req(req, rsp, 0); + if (rc) { + iscsi_err_print_msg(rc); + log_error(Could not send NEWROOT command); + } +} + /* * TODO: we can display how the ifaces are related to node records. * And we can add a scsi_host mode which would display how @@ -2411,6 +2428,7 @@ main(int argc, char **argv) uint32_t host_no = -1; struct user_param *param; struct list_head params; + char *newroot = NULL; INIT_LIST_HEAD(params); INIT_LIST_HEAD(ifaces); @@ -2433,6 +2451,9 @@ main(int argc, char **argv) while ((ch = getopt_long(argc, argv, short_options, long_options, longindex)) = 0) { switch (ch) { + case 'N': + newroot = strndup(optarg, PATH_MAX); + break; case 'k': killiscsid = atoi(optarg); if (killiscsid 0) { @@ -2579,6 +2600,13 @@ main(int argc, char **argv) goto free_ifaces; } + if (newroot) { + do_newroot(newroot); + free(newroot); + newroot = NULL; + goto free_ifaces; + } + if (mode 0) usage(ISCSI_ERR_INVAL); diff --git a/usr/mgmt_ipc.c b/usr/mgmt_ipc.c index f34f688..b4170ce 100644 --- a/usr/mgmt_ipc.c +++ b/usr/mgmt_ipc.c @@ -226,6 +226,16 @@ mgmt_ipc_immediate_stop(queue_task_t *qtask) } static int +mgmt_ipc_newroot(queue_task_t *qtask) +{ + char *newroot = qtask-req.u.newroot.path; + if (chdir(newroot) || chroot(.) || chdir(/)) + return ISCSI_ERR; + mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS); + return ISCSI_SUCCESS; +} + +static int mgmt_ipc_conn_remove(queue_task_t *qtask) { return ISCSI_ERR; @@ -534,6 +544,7 @@ static mgmt_ipc_fn_t * mgmt_ipc_functions[__MGMT_IPC_MAX_COMMAND] = { [MGMT_IPC_NOTIFY_DEL_NODE] = mgmt_ipc_notify_del_node, [MGMT_IPC_NOTIFY_ADD_PORTAL] = mgmt_ipc_notify_add_portal, [MGMT_IPC_NOTIFY_DEL_PORTAL] = mgmt_ipc_notify_del_portal, +[MGMT_IPC_NEWROOT] = mgmt_ipc_newroot, }; void mgmt_ipc_handle(int accept_fd) diff --git a/usr/mgmt_ipc.h b/usr/mgmt_ipc.h index 55972ed..102 100644 --- a/usr/mgmt_ipc.h +++ b/usr/mgmt_ipc.h @@ -22,6 +22,7 @@ #include types.h #include iscsi_if.h #include config.h +#include limits.h #define ISCSIADM_NAMESPACE ISCSIADM_ABSTRACT_NAMESPACE #define PEERUSER_MAX 64 @@ -46,6 +47,7 @@ typedef enum iscsiadm_cmd { MGMT_IPC_NOTIFY_DEL_NODE= 17, MGMT_IPC_NOTIFY_ADD_PORTAL = 18, MGMT_IPC_NOTIFY_DEL_PORTAL = 19, + MGMT_IPC_NEWROOT= 20, __MGMT_IPC_MAX_COMMAND } iscsiadm_cmd_e; @@ -75,8 +77,10 @@ typedef struct iscsiadm_req { int param; /* TODO: make this variable len to support */ char value[IFNAMSIZ + 1]; - } set_host_param; + struct ipc_msg_newroot { + char path[PATH_MAX + 1]; + } newroot; } u; } iscsiadm_req_t; -- 1.7.11.7 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC] iscsi unit files and helper script
iSCSI service and socket files, and the iscsi_mark_root_nodes helper script to preserve sessions started in the initramfs. diff -Naur a/iscsid.service b/iscsid.service --- a/iscsid.service1969-12-31 16:00:00.0 -0800 +++ b/iscsid.service2012-12-10 13:38:38.643307001 -0800 @@ -0,0 +1,9 @@ +[Unit] +Description=Open-iSCSI +Documentation=man:iscsid(8) man:iscsiadm(8) +After=network.target NetworkManager-wait-online.service iscsiuio.service tgtd.service targetcli.service + +[Service] +Type=simple +ExecStart=/usr/sbin/iscsid -f -n +ExecStop=/sbin/iscsiadm -k 0 2 diff -Naur a/iscsid.socket b/iscsid.socket --- a/iscsid.socket 1969-12-31 16:00:00.0 -0800 +++ b/iscsid.socket 2012-12-10 13:38:38.643307001 -0800 @@ -0,0 +1,9 @@ +[Unit] +Description=Open-iSCSI iscsid Socket +Documentation=man:iscsid(8) man:iscsiadm(8) + +[Socket] +ListenStream=@ISCSIADM_ABSTRACT_NAMESPACE + +[Install] +WantedBy=sockets.target diff -Naur a/iscsi.service b/iscsi.service --- a/iscsi.service 1969-12-31 16:00:00.0 -0800 +++ b/iscsi.service 2012-12-10 13:38:38.643307001 -0800 @@ -0,0 +1,18 @@ +[Unit] +Description=Login and scanning of iSCSI devices +Documentation=man:iscsiadm(8) man:iscsid(8) +#Requires=iscsid.service +#BindTo=iscsid.service +After=network.target NetworkManager-wait-online.service iscsid.service +ConditionPathExists=/etc/iscsi/initiatorname.iscsi + +[Service] +Type=oneshot +ExecStart=/usr/libexec/iscsi_mark_root_nodes +ExecStart=/sbin/iscsiadm -m node --loginall=automatic +ExecStop=/bin/sync +ExecStop=/sbin/iscsiadm -m node --logoutall=automatic +RemainAfterExit=true + +[Install] +WantedBy=remote-fs.target diff -Naur a/iscsiuio.service b/iscsiuio.service --- a/iscsiuio.service 1969-12-31 16:00:00.0 -0800 +++ b/iscsiuio.service 2012-12-10 13:38:38.643307001 -0800 @@ -0,0 +1,11 @@ +[Unit] +Description=iSCSI UserSpace I/O driver +Documentation=man:iscsiuio(8) +Requires=iscsid.service +BindTo=iscsid.service +Before=iscsid.service +After=network.target NetworkManager-wait-online.service + +[Service] +Type=simple +ExecStart=/usr/sbin/iscsiuio -f diff -Naur a/iscsiuio.socket b/iscsiuio.socket --- a/iscsiuio.socket 1969-12-31 16:00:00.0 -0800 +++ b/iscsiuio.socket 2012-12-10 13:38:38.643307001 -0800 @@ -0,0 +1,9 @@ +[Unit] +Description=Open-iSCSI iscsiuio +Documentation=man:iscsiuio(8) + +[Socket] +ListenStream=@ISCSID_UIP_ABSTRACT_NAMESPACE + +[Install] +WantedBy=sockets.target diff -Naur a/usr/libexec/iscsi_mark_root_nodes b/usr/libexec/iscsi_mark_root_nodes --- a/usr/libexec/iscsi_mark_root_nodes 1969-12-31 16:00:00.0 -0800 +++ b/usr/libexec/iscsi_mark_root_nodes 2012-12-10 13:38:47.322082141 -0800 @@ -0,0 +1,14 @@ +#!/bin/bash + +ISCSIADM=/sbin/iscsiadm +SESSION_FILE=/run/initramfs/iscsi.sessions + +if [ ! -f $SESSION_FILE ] ; then + exit 0 +fi + +while read t num i target; do + ip=${i%:*} + $ISCSIADM -m node -p $ip -T $target -o update -n node.startup -v onboot +done $SESSION_FILE + ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [RFC] dracut iscsi module: early attempt to launch iscsid from the initramfs
Not complete, but working well for iBFT configured iSCSI boot for me. --- modules.d/95iscsi/cleanup-iscsi.sh| 3 ++- modules.d/95iscsi/iscsid-initrd.service | 10 ++ modules.d/95iscsi/iscsid-initrd.socket| 9 + modules.d/95iscsi/iscsiroot.sh| 26 ++ modules.d/95iscsi/iscsiuio-initrd.service | 11 +++ modules.d/95iscsi/iscsiuio-initrd.socket | 9 + modules.d/95iscsi/module-setup.sh | 14 -- 7 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 modules.d/95iscsi/iscsid-initrd.service create mode 100644 modules.d/95iscsi/iscsid-initrd.socket create mode 100644 modules.d/95iscsi/iscsiuio-initrd.service create mode 100644 modules.d/95iscsi/iscsiuio-initrd.socket diff --git a/modules.d/95iscsi/cleanup-iscsi.sh b/modules.d/95iscsi/cleanup-iscsi.sh index a2d5951..0dc0ceb 100755 --- a/modules.d/95iscsi/cleanup-iscsi.sh +++ b/modules.d/95iscsi/cleanup-iscsi.sh @@ -2,5 +2,6 @@ # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- # ex: ts=8 sw=4 sts=4 et filetype=sh -[ -e /sys/module/bnx2i ] killproc iscsiuio +NEWROOT=/sysroot +iscsiadm --newroot $NEWROOT diff --git a/modules.d/95iscsi/iscsid-initrd.service b/modules.d/95iscsi/iscsid-initrd.service new file mode 100644 index 000..16dc4c4 --- /dev/null +++ b/modules.d/95iscsi/iscsid-initrd.service @@ -0,0 +1,10 @@ +[Unit] +Description=Open-iSCSI +Documentation=man:iscsid(8) man:iscsiadm(8) +After=network.target NetworkManager-wait-online.service + +[Service] +Type=forking +ExecStart=/usr/sbin/iscsid --initrd +PIDFile=/var/run/iscsid.pid +KillMode=none diff --git a/modules.d/95iscsi/iscsid-initrd.socket b/modules.d/95iscsi/iscsid-initrd.socket new file mode 100644 index 000..58a8d12 --- /dev/null +++ b/modules.d/95iscsi/iscsid-initrd.socket @@ -0,0 +1,9 @@ +[Unit] +Description=Open-iSCSI iscsid Socket +Documentation=man:iscsid(8) man:iscsiadm(8) + +[Socket] +ListenStream=@ISCSIADM_ABSTRACT_NAMESPACE + +[Install] +WantedBy=sockets.target diff --git a/modules.d/95iscsi/iscsiroot.sh b/modules.d/95iscsi/iscsiroot.sh index 1a8cc8d..c2766a1 100755 --- a/modules.d/95iscsi/iscsiroot.sh +++ b/modules.d/95iscsi/iscsiroot.sh @@ -49,7 +49,9 @@ if getargbool 0 rd.iscsi.firmware -d -y iscsi_firmware ; then iscsi_param=$iscsi_param --param $p done -iscsistart -b $iscsi_param +# iscsistart -b $iscsi_param +iscsiadm -m fw -l +iscsiadm -m session /run/initramfs/iscsi.sessions exit 0 fi @@ -146,17 +148,17 @@ handle_netroot() # force udevsettle to break $hookdir/initqueue/work -iscsistart -i $iscsi_initiator -t $iscsi_target_name\ --g $iscsi_target_group -a $iscsi_target_ip \ --p $iscsi_target_port \ -${iscsi_username+-u $iscsi_username} \ -${iscsi_password+-w $iscsi_password} \ -${iscsi_in_username+-U $iscsi_in_username} \ -${iscsi_in_password+-W $iscsi_in_password} \ - ${iscsi_iface_name+--param iface.iscsi_ifacename=$iscsi_iface_name} \ - ${iscsi_netdev_name+--param iface.net_ifacename=$iscsi_netdev_name} \ -${iscsi_param} \ - || : +#iscsistart -i $iscsi_initiator -t $iscsi_target_name\ +#-g $iscsi_target_group -a $iscsi_target_ip \ +#-p $iscsi_target_port \ +#${iscsi_username+-u $iscsi_username} \ +#${iscsi_password+-w $iscsi_password} \ +#${iscsi_in_username+-U $iscsi_in_username} \ +#${iscsi_in_password+-W $iscsi_in_password} \ +# ${iscsi_iface_name+--param iface.iscsi_ifacename=$iscsi_iface_name} \ +# ${iscsi_netdev_name+--param iface.net_ifacename=$iscsi_netdev_name} \ +#${iscsi_param} \ +# || : } # loop over all netroot parameter diff --git a/modules.d/95iscsi/iscsiuio-initrd.service b/modules.d/95iscsi/iscsiuio-initrd.service new file mode 100644 index 000..54883df --- /dev/null +++ b/modules.d/95iscsi/iscsiuio-initrd.service @@ -0,0 +1,11 @@ +[Unit] +Description=iSCSI UserSpace I/O driver +Documentation=man:iscsiuio(8) +Before=iscsid.service +After=network.target NetworkManager-wait-online.service + +[Service] +Type=forking +ExecStart=/usr/sbin/iscsiuio --initrd +PIDFile=/var/run/iscsiuio.pid +KillMode=none diff --git a/modules.d/95iscsi/iscsiuio-initrd.socket b/modules.d/95iscsi/iscsiuio-initrd.socket new file mode 100644 index 000..9eacc56 --- /dev/null +++ b/modules.d/95iscsi/iscsiuio-initrd.socket @@ -0,0 +1,9 @@ +[Unit] +Description=Open-iSCSI iscsiuio +Documentation=man:iscsiuio(8) + +[Socket] +ListenStream=@ISCSID_UIP_ABSTRACT_NAMESPACE + +[Install] +WantedBy=sockets.target diff --git a/modules.d/95iscsi/module-setup.sh b/modules.d/95iscsi/module-setup.sh index d251a0d..7acabbe 100755 --- a/modules.d/95iscsi/module-setup.sh +++ b/modules.d/95iscsi/module-setup.sh @@ -5,7 +5,7 @@ check() { local _rootdev # If our prerequisites are not met, fail anyways. -
[systemd-devel] [RFC] iscsid / systemd / dracut integration effort
Sorry about the cross-posting, but I think that in order to get this right I'm going to need as much feedback as I can get. I think I've got this working pretty well now (at least for my iBFT configured iSCSI root test case), although the dracut module still needs work. This is based on the iscsid socket activation patch from Tomasz Torcz and the unit files from Tomasz and Jóhann B. Guðmundsson. Attempting to start iscsid using systemd unit files (socket activated or not) was impacting my iscsi-root test setup. Rather than try to preserve the old logic that used the _netdev mount flag to determine when iscsid could be safely shutdown, I've been working on following the guidelines for root storage daemons http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons. 1) I patched iscsid to set argv[0][0] = '@' if a new --initrd flag is passed on the command line. It's simple, it works, we don't kill iscsid before the root filesystem is unmounted. 2) When starting iscsid from the initrd, I then ran into issues of iscsid not functioning properly after the switch_root. It's not mentioned in the RootStorageDaemons documentation, but if a process left running from the initrd needs further filesystem access at runtime it will need to be able to chroot itself before the switch_root. I patched iscsid and iscsiadm with a newroot command (using plymouth as an example), and used a dracut clenaup hook to call iscsiadm --newroot /sysroot. 3) Related to #2, launching iscsid as a Type=simple service from the initrd (I'm testing this with Fedora 18 beta, where dracut uses systemd in the initrd) results in STDOUT/STDERR access after the switch_root failing with EPIPE. It seems that the connection to the journal process is dead once the initrd instantiated systemd-journald is replaced with the runtime process. I can at least keep iscsid functioning if I run it as Type=forking, but I'm not sure if I'm losing runtime logging or not. I may be able to do something with the StandardOutput and StandardError options in the service file. 4) None of this helps if the sessions are shutdown when we still need them. Rather than the all-or-nothing _netdev mount option checks that have been used in the past, I'm attempting to use the fact that iscsiadm will skip over session that match a node with startup=onboot set when doing a logoutall. The iscsi_mark_root_nodes script is borrowed from the SUSE init scripts in the open-iscsi repos written by Hannes Reinecke. I've made minor changes to export the list of sessions activated in the initramfs, and then mark those as onboot when starting iscsi.service. Things that still need looking into. 1) Command line configured iSCSI parameters. If iscsistart is to be fully removed something needs to setup the node from the command line. Or iscsistart needs to be able to run alongside iscsid. 2) Proper ordering of the iscsi.service for non-root filesystems. Any and all feedback and/or help welcome. - Chris ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel