1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-28 20:25:38 +03:00

umount: split out swap detachment code too

This commit is contained in:
Lennart Poettering 2023-06-02 10:46:17 +02:00
parent 2e2c472b1c
commit 82a1d6d096
7 changed files with 111 additions and 86 deletions

View File

@ -0,0 +1,93 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/***
Copyright © 2010 ProFUSION embedded systems
***/
#include <sys/swap.h>
#include "alloc-util.h"
#include "detach-swap.h"
#include "libmount-util.h"
int swap_list_get(const char *swaps, MountPoint **head) {
_cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
int r;
assert(head);
t = mnt_new_table();
i = mnt_new_iter(MNT_ITER_FORWARD);
if (!t || !i)
return log_oom();
r = mnt_table_parse_swaps(t, swaps);
if (r == -ENOENT) /* no /proc/swaps is fine */
return 0;
if (r < 0)
return log_error_errno(r, "Failed to parse %s: %m", swaps ?: "/proc/swaps");
for (;;) {
struct libmnt_fs *fs;
_cleanup_free_ MountPoint *swap = NULL;
const char *source;
r = mnt_table_next_fs(t, i, &fs);
if (r == 1) /* EOF */
break;
if (r < 0)
return log_error_errno(r, "Failed to get next entry from %s: %m", swaps ?: "/proc/swaps");
source = mnt_fs_get_source(fs);
if (!source)
continue;
swap = new0(MountPoint, 1);
if (!swap)
return log_oom();
swap->path = strdup(source);
if (!swap->path)
return log_oom();
LIST_PREPEND(mount_point, *head, TAKE_PTR(swap));
}
return 0;
}
static int swap_points_list_off(MountPoint **head, bool *changed) {
int n_failed = 0;
assert(head);
assert(changed);
LIST_FOREACH(mount_point, m, *head) {
log_info("Deactivating swap %s.", m->path);
if (swapoff(m->path) < 0) {
log_warning_errno(errno, "Could not deactivate swap %s: %m", m->path);
n_failed++;
continue;
}
*changed = true;
mount_point_free(head, m);
}
return n_failed;
}
int swapoff_all(bool *changed) {
_cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, swap_list_head);
int r;
assert(changed);
LIST_HEAD_INIT(swap_list_head);
r = swap_list_get(NULL, &swap_list_head);
if (r < 0)
return r;
return swap_points_list_off(&swap_list_head, changed);
}

View File

@ -0,0 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/***
Copyright © 2010 ProFUSION embedded systems
***/
#include <stdbool.h>
#include "umount.h"
int swapoff_all(bool *changed);
int swap_list_get(const char *swaps, MountPoint **head);

View File

@ -4,6 +4,7 @@ systemd_shutdown_sources = files(
'detach-dm.c',
'detach-loopback.c',
'detach-md.c',
'detach-swap.c',
'shutdown.c',
'umount.c',
)
@ -11,6 +12,7 @@ systemd_shutdown_sources = files(
tests += [
{
'sources' : files(
'detach-swap.c',
'test-umount.c',
'umount.c',
),

View File

@ -26,6 +26,7 @@
#include "detach-dm.h"
#include "detach-loopback.h"
#include "detach-md.h"
#include "detach-swap.h"
#include "errno-util.h"
#include "exec-util.h"
#include "fd-util.h"

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "alloc-util.h"
#include "detach-swap.h"
#include "errno-util.h"
#include "log.h"
#include "path-util.h"

View File

@ -7,7 +7,6 @@
#include <fcntl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/swap.h>
#include <sys/types.h>
#include <unistd.h>
@ -168,53 +167,6 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) {
return 0;
}
int swap_list_get(const char *swaps, MountPoint **head) {
_cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
int r;
assert(head);
t = mnt_new_table();
i = mnt_new_iter(MNT_ITER_FORWARD);
if (!t || !i)
return log_oom();
r = mnt_table_parse_swaps(t, swaps);
if (r == -ENOENT) /* no /proc/swaps is fine */
return 0;
if (r < 0)
return log_error_errno(r, "Failed to parse %s: %m", swaps ?: "/proc/swaps");
for (;;) {
struct libmnt_fs *fs;
_cleanup_free_ MountPoint *swap = NULL;
const char *source;
r = mnt_table_next_fs(t, i, &fs);
if (r == 1) /* EOF */
break;
if (r < 0)
return log_error_errno(r, "Failed to get next entry from %s: %m", swaps ?: "/proc/swaps");
source = mnt_fs_get_source(fs);
if (!source)
continue;
swap = new0(MountPoint, 1);
if (!swap)
return log_oom();
swap->path = strdup(source);
if (!swap->path)
return log_oom();
LIST_PREPEND(mount_point, *head, TAKE_PTR(swap));
}
return 0;
}
static bool nonunmountable_path(const char *path) {
return path_equal(path, "/")
#if ! HAVE_SPLIT_USR
@ -509,27 +461,6 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool last_
return n_failed;
}
static int swap_points_list_off(MountPoint **head, bool *changed) {
int n_failed = 0;
assert(head);
assert(changed);
LIST_FOREACH(mount_point, m, *head) {
log_info("Deactivating swap %s.", m->path);
if (swapoff(m->path) < 0) {
log_warning_errno(errno, "Could not deactivate swap %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;
@ -562,18 +493,3 @@ int umount_all(bool *changed, bool last_try) {
return r;
}
int swapoff_all(bool *changed) {
_cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, swap_list_head);
int r;
assert(changed);
LIST_HEAD_INIT(swap_list_head);
r = swap_list_get(NULL, &swap_list_head);
if (r < 0)
return r;
return swap_points_list_off(&swap_list_head, changed);
}

View File

@ -8,7 +8,6 @@
#include "list.h"
int umount_all(bool *changed, bool last_try);
int swapoff_all(bool *changed);
/* This is exported just for testing */
typedef struct MountPoint {
@ -25,4 +24,3 @@ typedef struct MountPoint {
int mount_points_list_get(const char *mountinfo, MountPoint **head);
void mount_point_free(MountPoint **head, MountPoint *m);
void mount_points_list_free(MountPoint **head);
int swap_list_get(const char *swaps, MountPoint **head);