1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/* 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"
static void swap_device_free(SwapDevice **head, SwapDevice *m) {
assert(head);
assert(m);
LIST_REMOVE(swap_device, *head, m);
free(m->path);
free(m);
}
void swap_devices_list_free(SwapDevice **head) {
assert(head);
while (*head)
swap_device_free(head, *head);
}
int swap_list_get(const char *swaps, SwapDevice **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_ SwapDevice *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(SwapDevice, 1);
if (!swap)
return log_oom();
swap->path = strdup(source);
if (!swap->path)
return log_oom();
LIST_PREPEND(swap_device, *head, TAKE_PTR(swap));
}
return 0;
}
static int swap_points_list_off(SwapDevice **head, bool *changed) {
int n_failed = 0;
assert(head);
assert(changed);
LIST_FOREACH(swap_device, 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;
swap_device_free(head, m);
}
return n_failed;
}
int swapoff_all(bool *changed) {
_cleanup_(swap_devices_list_free) LIST_HEAD(SwapDevice, 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);
}
|