mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-24 21:34:08 +03:00
Merge pull request #17118 from poettering/sync-shutdown-loop
fsync() block devices before detaching them during shutdown
This commit is contained in:
commit
c7828862b3
@ -23,6 +23,7 @@
|
|||||||
#include "device-util.h"
|
#include "device-util.h"
|
||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
|
#include "fs-util.h"
|
||||||
#include "fstab-util.h"
|
#include "fstab-util.h"
|
||||||
#include "libmount-util.h"
|
#include "libmount-util.h"
|
||||||
#include "mount-setup.h"
|
#include "mount-setup.h"
|
||||||
@ -387,8 +388,15 @@ static int delete_loopback(const char *device) {
|
|||||||
assert(device);
|
assert(device);
|
||||||
|
|
||||||
fd = open(device, O_RDONLY|O_CLOEXEC);
|
fd = open(device, O_RDONLY|O_CLOEXEC);
|
||||||
if (fd < 0)
|
if (fd < 0) {
|
||||||
|
log_debug_errno(errno, "Failed to open loopback device %s: %m", device);
|
||||||
return errno == ENOENT ? 0 : -errno;
|
return errno == ENOENT ? 0 : -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loopback block devices don't sync in-flight blocks when we clear the fd, hence sync explicitly
|
||||||
|
* first */
|
||||||
|
if (fsync(fd) < 0)
|
||||||
|
log_debug_errno(errno, "Failed to sync loop block device %s, ignoring: %m", device);
|
||||||
|
|
||||||
if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
|
if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
|
||||||
if (errno == ENXIO) /* Nothing bound, didn't do anything */
|
if (errno == ENXIO) /* Nothing bound, didn't do anything */
|
||||||
@ -440,43 +448,50 @@ static int delete_loopback(const char *device) {
|
|||||||
return -EBUSY; /* Nothing changed, the device is still attached, hence it apparently is still busy */
|
return -EBUSY; /* Nothing changed, the device is still attached, hence it apparently is still busy */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int delete_dm(dev_t devnum) {
|
static int delete_dm(MountPoint *m) {
|
||||||
|
|
||||||
struct dm_ioctl dm = {
|
|
||||||
.version = {
|
|
||||||
DM_VERSION_MAJOR,
|
|
||||||
DM_VERSION_MINOR,
|
|
||||||
DM_VERSION_PATCHLEVEL
|
|
||||||
},
|
|
||||||
.data_size = sizeof(dm),
|
|
||||||
.dev = devnum,
|
|
||||||
};
|
|
||||||
|
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(major(devnum) != 0);
|
assert(m);
|
||||||
|
assert(major(m->devnum) != 0);
|
||||||
|
assert(m->path);
|
||||||
|
|
||||||
fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC);
|
fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (ioctl(fd, DM_DEV_REMOVE, &dm) < 0)
|
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);
|
||||||
|
|
||||||
|
if (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,
|
||||||
|
}) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int delete_md(MountPoint *m) {
|
static int delete_md(MountPoint *m) {
|
||||||
|
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
assert(major(m->devnum) != 0);
|
assert(major(m->devnum) != 0);
|
||||||
assert(m->path != 0);
|
assert(m->path);
|
||||||
|
|
||||||
fd = open(m->path, O_RDONLY|O_CLOEXEC|O_EXCL);
|
fd = open(m->path, O_RDONLY|O_CLOEXEC|O_EXCL);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
if (fsync(fd) < 0)
|
||||||
|
log_debug_errno(errno, "Failed to sync MD block device %s, ignoring: %m", m->path);
|
||||||
|
|
||||||
if (ioctl(fd, STOP_ARRAY, NULL) < 0)
|
if (ioctl(fd, STOP_ARRAY, NULL) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
@ -692,7 +707,7 @@ static int dm_points_list_detach(MountPoint **head, bool *changed, int umount_lo
|
|||||||
}
|
}
|
||||||
|
|
||||||
log_info("Detaching DM %s (%u:%u).", m->path, major(m->devnum), minor(m->devnum));
|
log_info("Detaching DM %s (%u:%u).", m->path, major(m->devnum), minor(m->devnum));
|
||||||
r = delete_dm(m->devnum);
|
r = delete_dm(m);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_full_errno(umount_log_level, r, "Could not detach DM %s: %m", m->path);
|
log_full_errno(umount_log_level, r, "Could not detach DM %s: %m", m->path);
|
||||||
n_failed++;
|
n_failed++;
|
||||||
|
Loading…
Reference in New Issue
Block a user