From: Lennart Poettering Date: Fri, 2 Jun 2023 08:31:55 +0000 (+0200) Subject: umount: similar as previous commit, split out DM detaching X-Git-Tag: v254-rc1~299^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b44411c7028dc95eb3fd0745562ddf303a0d3372;p=thirdparty%2Fsystemd.git umount: similar as previous commit, split out DM detaching --- diff --git a/src/shutdown/detach-dm.c b/src/shutdown/detach-dm.c new file mode 100644 index 00000000000..8a6408e4d20 --- /dev/null +++ b/src/shutdown/detach-dm.c @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/*** + Copyright © 2010 ProFUSION embedded systems +***/ + +#include +#include + +#include "sd-device.h" + +#include "alloc-util.h" +#include "blockdev-util.h" +#include "detach-dm.h" +#include "device-util.h" +#include "devnum-util.h" +#include "errno-util.h" +#include "fd-util.h" +#include "sync-util.h" +#include "umount.h" + +static int dm_list_get(MountPoint **head) { + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + sd_device *d; + int r; + + assert(head); + + r = sd_device_enumerator_new(&e); + if (r < 0) + return r; + + r = sd_device_enumerator_allow_uninitialized(e); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_subsystem(e, "block", true); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_sysname(e, "dm-*"); + if (r < 0) + return r; + + FOREACH_DEVICE(e, d) { + _cleanup_free_ char *p = NULL; + const char *dn; + MountPoint *m; + dev_t devnum; + + if (sd_device_get_devnum(d, &devnum) < 0 || + sd_device_get_devname(d, &dn) < 0) + continue; + + p = strdup(dn); + if (!p) + return -ENOMEM; + + m = new(MountPoint, 1); + if (!m) + return -ENOMEM; + + *m = (MountPoint) { + .path = TAKE_PTR(p), + .devnum = devnum, + }; + + LIST_PREPEND(mount_point, *head, m); + } + + return 0; +} + +static int delete_dm(MountPoint *m) { + _cleanup_close_ int fd = -EBADF; + int r; + + assert(m); + assert(major(m->devnum) != 0); + assert(m->path); + + fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC); + if (fd < 0) + return -errno; + + r = fsync_path_at(AT_FDCWD, m->path); + if (r < 0) + log_debug_errno(r, "Failed to sync DM block device %s, ignoring: %m", m->path); + + return RET_NERRNO(ioctl(fd, DM_DEV_REMOVE, &(struct dm_ioctl) { + .version = { + DM_VERSION_MAJOR, + DM_VERSION_MINOR, + DM_VERSION_PATCHLEVEL + }, + .data_size = sizeof(struct dm_ioctl), + .dev = m->devnum, + })); +} + +static int dm_points_list_detach(MountPoint **head, bool *changed, bool last_try) { + int n_failed = 0, r; + dev_t rootdev = 0; + + assert(head); + assert(changed); + + (void) get_block_device("/", &rootdev); + + LIST_FOREACH(mount_point, m, *head) { + if (major(rootdev) != 0 && rootdev == m->devnum) { + n_failed ++; + continue; + } + + log_info("Detaching DM %s (" DEVNUM_FORMAT_STR ").", m->path, DEVNUM_FORMAT_VAL(m->devnum)); + r = delete_dm(m); + if (r < 0) { + log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not detach DM %s: %m", m->path); + n_failed++; + continue; + } + + *changed = true; + mount_point_free(head, m); + } + + return n_failed; +} + +int dm_detach_all(bool *changed, bool last_try) { + _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, dm_list_head); + int r; + + assert(changed); + + LIST_HEAD_INIT(dm_list_head); + + r = dm_list_get(&dm_list_head); + if (r < 0) + return r; + + return dm_points_list_detach(&dm_list_head, changed, last_try); +} diff --git a/src/shutdown/detach-dm.h b/src/shutdown/detach-dm.h new file mode 100644 index 00000000000..b5f50a3bbf4 --- /dev/null +++ b/src/shutdown/detach-dm.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +/*** + Copyright © 2010 ProFUSION embedded systems +***/ + +#include + +int dm_detach_all(bool *changed, bool last_try); diff --git a/src/shutdown/meson.build b/src/shutdown/meson.build index a41dc772b5e..1e30f57cbb9 100644 --- a/src/shutdown/meson.build +++ b/src/shutdown/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: LGPL-2.1-or-later systemd_shutdown_sources = files( + 'detach-dm.c', 'detach-md.c', 'shutdown.c', 'umount.c', diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c index 44dd765ad61..6fa0107a5dd 100644 --- a/src/shutdown/shutdown.c +++ b/src/shutdown/shutdown.c @@ -23,6 +23,7 @@ #include "cgroup-util.h" #include "constants.h" #include "coredump-util.h" +#include "detach-dm.h" #include "detach-md.h" #include "errno-util.h" #include "exec-util.h" diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c index 17722d71054..85f0eb9fe64 100644 --- a/src/shutdown/umount.c +++ b/src/shutdown/umount.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -289,57 +288,6 @@ static int loopback_list_get(MountPoint **head) { return 0; } -static int dm_list_get(MountPoint **head) { - _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; - sd_device *d; - int r; - - assert(head); - - r = sd_device_enumerator_new(&e); - if (r < 0) - return r; - - r = sd_device_enumerator_allow_uninitialized(e); - if (r < 0) - return r; - - r = sd_device_enumerator_add_match_subsystem(e, "block", true); - if (r < 0) - return r; - - r = sd_device_enumerator_add_match_sysname(e, "dm-*"); - if (r < 0) - return r; - - FOREACH_DEVICE(e, d) { - _cleanup_free_ char *p = NULL; - const char *dn; - MountPoint *m; - dev_t devnum; - - if (sd_device_get_devnum(d, &devnum) < 0 || - sd_device_get_devname(d, &dn) < 0) - continue; - - p = strdup(dn); - if (!p) - return -ENOMEM; - - m = new(MountPoint, 1); - if (!m) - return -ENOMEM; - - *m = (MountPoint) { - .path = TAKE_PTR(p), - .devnum = devnum, - }; - - LIST_PREPEND(mount_point, *head, m); - } - - return 0; -} static int delete_loopback(const char *device) { _cleanup_close_ int fd = -EBADF; @@ -416,33 +364,6 @@ static int delete_loopback(const char *device) { return -EBUSY; /* Nothing changed, the device is still attached, hence it apparently is still busy */ } -static int delete_dm(MountPoint *m) { - _cleanup_close_ int fd = -EBADF; - int r; - - assert(m); - assert(major(m->devnum) != 0); - assert(m->path); - - fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC); - if (fd < 0) - return -errno; - - r = fsync_path_at(AT_FDCWD, m->path); - if (r < 0) - log_debug_errno(r, "Failed to sync DM block device %s, ignoring: %m", m->path); - - return RET_NERRNO(ioctl(fd, DM_DEV_REMOVE, &(struct dm_ioctl) { - .version = { - DM_VERSION_MAJOR, - DM_VERSION_MINOR, - DM_VERSION_PATCHLEVEL - }, - .data_size = sizeof(struct dm_ioctl), - .dev = m->devnum, - })); -} - static bool nonunmountable_path(const char *path) { return path_equal(path, "/") #if ! HAVE_SPLIT_USR @@ -789,36 +710,6 @@ static int loopback_points_list_detach(MountPoint **head, bool *changed, bool la return n_failed; } -static int dm_points_list_detach(MountPoint **head, bool *changed, bool last_try) { - int n_failed = 0, r; - dev_t rootdev = 0; - - assert(head); - assert(changed); - - (void) get_block_device("/", &rootdev); - - LIST_FOREACH(mount_point, m, *head) { - if (major(rootdev) != 0 && rootdev == m->devnum) { - n_failed ++; - continue; - } - - log_info("Detaching DM %s (" DEVNUM_FORMAT_STR ").", m->path, DEVNUM_FORMAT_VAL(m->devnum)); - r = delete_dm(m); - if (r < 0) { - log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not detach DM %s: %m", m->path); - n_failed++; - continue; - } - - *changed = true; - mount_point_free(head, m); - } - - return n_failed; -} - static int umount_all_once(bool *changed, bool last_try) { _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head); int r; @@ -881,18 +772,3 @@ int loopback_detach_all(bool *changed, bool last_try) { return loopback_points_list_detach(&loopback_list_head, changed, last_try); } - -int dm_detach_all(bool *changed, bool last_try) { - _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, dm_list_head); - int r; - - assert(changed); - - LIST_HEAD_INIT(dm_list_head); - - r = dm_list_get(&dm_list_head); - if (r < 0) - return r; - - return dm_points_list_detach(&dm_list_head, changed, last_try); -} diff --git a/src/shutdown/umount.h b/src/shutdown/umount.h index 0b25a45f5b8..7a849ca8a65 100644 --- a/src/shutdown/umount.h +++ b/src/shutdown/umount.h @@ -10,7 +10,6 @@ int umount_all(bool *changed, bool last_try); int swapoff_all(bool *changed); int loopback_detach_all(bool *changed, bool last_try); -int dm_detach_all(bool *changed, bool last_try); /* This is exported just for testing */ typedef struct MountPoint {