summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dbus-mount.c81
-rw-r--r--dbus-swap.c30
-rw-r--r--device.c5
-rw-r--r--execute.c7
-rw-r--r--load-fragment.c5
-rw-r--r--mount.c73
-rw-r--r--swap.c299
-rw-r--r--swap.h22
8 files changed, 372 insertions, 150 deletions
diff --git a/dbus-mount.c b/dbus-mount.c
index cbdb300f2c..500b773bf6 100644
--- a/dbus-mount.c
+++ b/dbus-mount.c
@@ -19,6 +19,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <errno.h>
+
#include "dbus-unit.h"
#include "dbus-mount.h"
#include "dbus-execute.h"
@@ -30,6 +32,9 @@ static const char introspection[] =
BUS_PROPERTIES_INTERFACE
" <interface name=\"org.freedesktop.systemd1.Mount\">"
" <property name=\"Where\" type=\"s\" access=\"read\"/>"
+ " <property name=\"What\" type=\"s\" access=\"read\"/>"
+ " <property name=\"Options\" type=\"s\" access=\"read\"/>"
+ " <property name=\"Type\" type=\"s\" access=\"read\"/>"
" <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>"
BUS_EXEC_CONTEXT_INTERFACE
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>"
@@ -38,11 +43,85 @@ static const char introspection[] =
BUS_INTROSPECTABLE_INTERFACE
"</node>";
+static int bus_mount_append_what(Manager *n, DBusMessageIter *i, const char *property, void *data) {
+ Mount *m = data;
+ const char *d;
+
+ assert(n);
+ assert(i);
+ assert(property);
+ assert(m);
+
+ if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
+ d = m->parameters_proc_self_mountinfo.what;
+ else if (m->from_fragment && m->parameters_fragment.what)
+ d = m->parameters_fragment.what;
+ else if (m->from_etc_fstab && m->parameters_etc_fstab.what)
+ d = m->parameters_etc_fstab.what;
+ else
+ d = "";
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int bus_mount_append_options(Manager *n, DBusMessageIter *i, const char *property, void *data) {
+ Mount *m = data;
+ const char *d;
+
+ assert(n);
+ assert(i);
+ assert(property);
+ assert(m);
+
+ if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
+ d = m->parameters_proc_self_mountinfo.options;
+ else if (m->from_fragment && m->parameters_fragment.options)
+ d = m->parameters_fragment.options;
+ else if (m->from_etc_fstab && m->parameters_etc_fstab.options)
+ d = m->parameters_etc_fstab.options;
+ else
+ d = "";
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int bus_mount_append_type(Manager *n, DBusMessageIter *i, const char *property, void *data) {
+ Mount *m = data;
+ const char *d;
+
+ assert(n);
+ assert(i);
+ assert(property);
+ assert(m);
+
+ if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
+ d = m->parameters_proc_self_mountinfo.fstype;
+ else if (m->from_fragment && m->parameters_fragment.fstype)
+ d = m->parameters_fragment.fstype;
+ else if (m->from_etc_fstab && m->parameters_etc_fstab.fstype)
+ d = m->parameters_etc_fstab.fstype;
+ else
+ d = "";
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
+ return -ENOMEM;
+
+ return 0;
+}
+
DBusHandlerResult bus_mount_message_handler(Unit *u, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
{ "org.freedesktop.systemd1.Mount", "Where", bus_property_append_string, "s", u->mount.where },
- /* Where, Options, fstype */
+ { "org.freedesktop.systemd1.Mount", "What", bus_mount_append_what, "s", u },
+ { "org.freedesktop.systemd1.Mount", "Options", bus_mount_append_options, "s", u },
+ { "org.freedesktop.systemd1.Mount", "Type", bus_mount_append_type, "s", u },
{ "org.freedesktop.systemd1.Mount", "TimeoutUSec", bus_property_append_usec, "t", &u->mount.timeout_usec },
/* ExecCommand */
BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Mount", u->mount.exec_context),
diff --git a/dbus-swap.c b/dbus-swap.c
index 6939ae29c7..e935e09bf2 100644
--- a/dbus-swap.c
+++ b/dbus-swap.c
@@ -20,6 +20,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <errno.h>
+
#include "dbus-unit.h"
#include "dbus-swap.h"
@@ -35,11 +37,35 @@ static const char introspection[] =
BUS_INTROSPECTABLE_INTERFACE
"</node>";
+static int bus_swap_append_priority(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ Swap *s = data;
+ dbus_int32_t j;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(s);
+
+ if (s->from_proc_swaps)
+ j = s->parameters_proc_swaps.priority;
+ else if (s->from_fragment)
+ j = s->parameters_fragment.priority;
+ else if (s->from_etc_fstab)
+ j = s->parameters_etc_fstab.priority;
+ else
+ j = -1;
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &j))
+ return -ENOMEM;
+
+ return 0;
+}
+
DBusHandlerResult bus_swap_message_handler(Unit *u, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
- { "org.freedesktop.systemd1.Swap", "What", bus_property_append_string, "s", u->swap.what },
- { "org.freedesktop.systemd1.Swap", "Priority", bus_property_append_int32, "i", &u->swap.priority },
+ { "org.freedesktop.systemd1.Swap", "What", bus_property_append_string, "s", u->swap.what },
+ { "org.freedesktop.systemd1.Swap", "Priority", bus_swap_append_priority, "i", u },
{ NULL, NULL, NULL, NULL, NULL }
};
diff --git a/device.c b/device.c
index 70936808be..e67d0a6c2d 100644
--- a/device.c
+++ b/device.c
@@ -248,9 +248,12 @@ static int device_process_new_device(Manager *m, struct udev_device *dev, bool u
(model = udev_device_get_property_value(dev, "ID_MODEL"))) {
if ((r = unit_set_description(u, model)) < 0)
goto fail;
- } else if (dn)
+ } else if (dn) {
if ((r = unit_set_description(u, dn)) < 0)
goto fail;
+ } else
+ if ((r = unit_set_description(u, sysfs)) < 0)
+ goto fail;
if (wants) {
FOREACH_WORD(w, l, wants, state) {
diff --git a/execute.c b/execute.c
index ef24f71a25..a36e52b345 100644
--- a/execute.c
+++ b/execute.c
@@ -1035,6 +1035,8 @@ int exec_spawn(ExecCommand *command,
goto fail;
}
+ assert(n_env <= 6);
+
if (!(final_env = strv_env_merge(environment, our_env, context->environment, NULL))) {
r = EXIT_MEMORY;
goto fail;
@@ -1062,10 +1064,7 @@ int exec_spawn(ExecCommand *command,
* sure that when we kill the cgroup the process will be
* killed too). */
if (cgroup_bondings)
- if ((r = cgroup_bonding_install_list(cgroup_bondings, pid)) < 0) {
- r = EXIT_CGROUP;
- goto fail;
- }
+ cgroup_bonding_install_list(cgroup_bondings, pid);
log_debug("Forked %s as %llu", command->path, (unsigned long long) pid);
diff --git a/load-fragment.c b/load-fragment.c
index b4e0c76009..deebba3e82 100644
--- a/load-fragment.c
+++ b/load-fragment.c
@@ -1287,9 +1287,8 @@ static int load_from_path(Unit *u, const char *path) {
{ "Where", config_parse_path, &u->automount.where, "Automount" },
- { "What", config_parse_path, &u->swap.what, "Swap" },
- { "Priority", config_parse_unsigned, &u->swap.priority, "Swap" },
- { "NoAuto", config_parse_bool, &u->swap.no_auto, "Swap" },
+ { "What", config_parse_path, &u->swap.parameters_fragment.what, "Swap" },
+ { "Priority", config_parse_int, &u->swap.parameters_fragment.priority, "Swap" },
{ NULL, NULL, NULL, NULL }
};
diff --git a/mount.c b/mount.c
index adb3a084a8..b53c7c0d8a 100644
--- a/mount.c
+++ b/mount.c
@@ -230,9 +230,6 @@ static int mount_add_target_links(Mount *m) {
handle = !!mount_test_option(p->options, "comment=systemd.mount");
automount = !!mount_test_option(p->options, "comment=systemd.automount");
- if (noauto && !handle && !automount)
- return 0;
-
if (mount_test_option(p->options, "_netdev") ||
fstype_is_network(p->fstype))
target = SPECIAL_REMOTE_FS_TARGET;
@@ -255,7 +252,7 @@ static int mount_add_target_links(Mount *m) {
} else {
- if (handle)
+ if (!noauto && handle)
if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(m), true)) < 0)
return r;
@@ -282,6 +279,11 @@ static int mount_verify(Mount *m) {
return -EINVAL;
}
+ if (m->meta.fragment_path && !m->parameters_fragment.what) {
+ log_error("%s's What setting is missing. Refusing.", UNIT(m)->meta.id);
+ return -EBADMSG;
+ }
+
return 0;
}
@@ -297,10 +299,10 @@ static int mount_load(Unit *u) {
/* This is a new unit? Then let's add in some extras */
if (u->meta.load_state == UNIT_LOADED) {
- const char *what = m->parameters_fragment.what;
+ const char *what = NULL;
- if (!what)
- what = m->parameters_etc_fstab.what;
+ if (m->meta.fragment_path)
+ m->from_fragment = true;
if (!m->where)
if (!(m->where = unit_name_to_path(u->meta.id)))
@@ -308,17 +310,22 @@ static int mount_load(Unit *u) {
path_kill_slashes(m->where);
- /* Minor validity checking */
- if ((m->parameters_fragment.options || m->parameters_fragment.fstype) && !m->parameters_fragment.what)
- return -EBADMSG;
+ if (!m->meta.description)
+ if ((r = unit_set_description(u, m->where)) < 0)
+ return r;
- if (m->parameters_fragment.what)
- m->from_fragment = true;
+ if (m->from_fragment && m->parameters_fragment.what)
+ what = m->parameters_fragment.what;
+ else if (m->from_etc_fstab && m->parameters_etc_fstab.what)
+ what = m->parameters_etc_fstab.what;
+ else if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
+ what = m->parameters_proc_self_mountinfo.what;
- if ((r = unit_add_node_link(u, what,
- (u->meta.manager->running_as == MANAGER_INIT ||
- u->meta.manager->running_as == MANAGER_SYSTEM))) < 0)
- return r;
+ if (what)
+ if ((r = unit_add_node_link(u, what,
+ (u->meta.manager->running_as == MANAGER_INIT ||
+ u->meta.manager->running_as == MANAGER_SYSTEM))) < 0)
+ return r;
if ((r = mount_add_mount_links(m)) < 0)
return r;
@@ -1017,7 +1024,7 @@ static int mount_add_one(
Unit *u;
bool delete;
char *e, *w = NULL, *o = NULL, *f = NULL;
- MountParameters *mp;
+ MountParameters *p;
assert(m);
assert(what);
@@ -1035,8 +1042,8 @@ static int mount_add_one(
if (streq(fstype, "autofs"))
return 0;
- /* probably some kind of swap, which we don't cover for now */
- if (where[0] != '/')
+ /* probably some kind of swap, ignore */
+ if (!is_path(where))
return 0;
if (!(e = unit_name_from_path(where, ".mount")))
@@ -1061,9 +1068,6 @@ static int mount_add_one(
goto fail;
}
- if ((r = unit_set_description(u, where)) < 0)
- goto fail;
-
unit_add_to_load_queue(u);
} else {
delete = false;
@@ -1078,30 +1082,28 @@ static int mount_add_one(
}
if (from_proc_self_mountinfo) {
- mp = &MOUNT(u)->parameters_proc_self_mountinfo;
+ p = &MOUNT(u)->parameters_proc_self_mountinfo;
if (set_flags) {
MOUNT(u)->is_mounted = true;
MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
- MOUNT(u)->just_changed = !streq_ptr(MOUNT(u)->parameters_proc_self_mountinfo.options, o);
+ MOUNT(u)->just_changed = !streq_ptr(p->options, o);
}
MOUNT(u)->from_proc_self_mountinfo = true;
-
} else {
- mp = &MOUNT(u)->parameters_etc_fstab;
-
+ p = &MOUNT(u)->parameters_etc_fstab;
MOUNT(u)->from_etc_fstab = true;
}
- free(mp->what);
- mp->what = w;
+ free(p->what);
+ p->what = w;
- free(mp->options);
- mp->options = o;
+ free(p->options);
+ p->options = o;
- free(mp->fstype);
- mp->fstype = f;
+ free(p->fstype);
+ p->fstype = f;
unit_add_to_dbus_queue(u);
@@ -1115,7 +1117,7 @@ fail:
if (delete && u)
unit_free(u);
- return 0;
+ return r;
}
static char *fstab_node_to_udev_node(char *p) {
@@ -1216,8 +1218,9 @@ static int mount_load_etc_fstab(Manager *m) {
else
r = swap_add_one(m,
what,
- !!mount_test_option(me->mnt_opts, MNTOPT_NOAUTO),
pri,
+ !!mount_test_option(me->mnt_opts, MNTOPT_NOAUTO),
+ !!mount_test_option(me->mnt_opts, "comment=systemd.swapon"),
false);
} else
r = mount_add_one(m, what, where, me->mnt_opts, me->mnt_type, false, false);
diff --git a/swap.c b/swap.c
index 275f1d4a9f..174ce1dc0e 100644
--- a/swap.c
+++ b/swap.c
@@ -40,32 +40,24 @@ static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
[SWAP_MAINTAINANCE] = UNIT_INACTIVE
};
-static void swap_done(Unit *u) {
+static void swap_init(Unit *u) {
Swap *s = SWAP(u);
assert(s);
+ assert(s->meta.load_state == UNIT_STUB);
- free(s->what);
+ s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
}
-static int swap_verify(Swap *s) {
- bool b;
- char *e;
-
- if (UNIT(s)->meta.load_state != UNIT_LOADED)
- return 0;
-
- if (!(e = unit_name_from_path(s->what, ".swap")))
- return -ENOMEM;
+static void swap_done(Unit *u) {
+ Swap *s = SWAP(u);
- b = unit_has_name(UNIT(s), e);
- free(e);
+ assert(s);
- if (!b) {
- log_error("%s: Value of \"What\" and unit name do not match, not loading.\n", UNIT(s)->meta.id);
- return -EINVAL;
- }
- return 0;
+ free(s->what);
+ free(s->parameters_etc_fstab.what);
+ free(s->parameters_proc_swaps.what);
+ free(s->parameters_fragment.what);
}
int swap_add_one_mount_link(Swap *s, Mount *m) {
@@ -104,20 +96,50 @@ static int swap_add_mount_links(Swap *s) {
}
static int swap_add_target_links(Swap *s) {
- Manager *m = s->meta.manager;
Unit *tu;
+ SwapParameters *p;
int r;
- if ((r = manager_load_unit(m, SPECIAL_SWAP_TARGET, NULL, &tu)) < 0)
+ assert(s);
+
+ if (s->from_fragment)
+ p = &s->parameters_fragment;
+ else if (s->from_etc_fstab)
+ p = &s->parameters_etc_fstab;
+ else
+ return 0;
+
+ if ((r = manager_load_unit(s->meta.manager, SPECIAL_SWAP_TARGET, NULL, &tu)) < 0)
return r;
- if (!s->no_auto)
+ if (!p->noauto && p->handle)
if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(s), true)) < 0)
return r;
return unit_add_dependency(UNIT(s), UNIT_BEFORE, tu, true);
}
+static int swap_verify(Swap *s) {
+ bool b;
+ char *e;
+
+ if (UNIT(s)->meta.load_state != UNIT_LOADED)
+ return 0;
+
+ if (!(e = unit_name_from_path(s->what, ".swap")))
+ return -ENOMEM;
+
+ b = unit_has_name(UNIT(s), e);
+ free(e);
+
+ if (!b) {
+ log_error("%s: Value of \"What\" and unit name do not match, not loading.\n", UNIT(s)->meta.id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int swap_load(Unit *u) {
int r;
Swap *s = SWAP(u);
@@ -130,12 +152,30 @@ static int swap_load(Unit *u) {
return r;
if (u->meta.load_state == UNIT_LOADED) {
- if (!s->what)
- if (!(s->what = unit_name_to_path(u->meta.id)))
+
+ if (s->meta.fragment_path)
+ s->from_fragment = true;
+
+ if (!s->what) {
+ if (s->parameters_fragment.what)
+ s->what = strdup(s->parameters_fragment.what);
+ else if (s->parameters_etc_fstab.what)
+ s->what = strdup(s->parameters_etc_fstab.what);
+ else if (s->parameters_proc_swaps.what)
+ s->what = strdup(s->parameters_proc_swaps.what);
+ else
+ s->what = unit_name_to_path(u->meta.id);
+
+ if (!s->what)
return -ENOMEM;
+ }
path_kill_slashes(s->what);
+ if (!s->meta.description)
+ if ((r = unit_set_description(u, s->what)) < 0)
+ return r;
+
if ((r = unit_add_node_link(u, s->what,
(u->meta.manager->running_as == MANAGER_INIT ||
u->meta.manager->running_as == MANAGER_SYSTEM))) < 0)
@@ -151,62 +191,122 @@ static int swap_load(Unit *u) {
return swap_verify(s);
}
-int swap_add_one(Manager *m, const char *what, bool no_auto, int prio, bool from_proc_swaps) {
+static int swap_find(Manager *m, const char *what, Unit **_u) {
Unit *u;
char *e;
+
+ assert(m);
+ assert(what);
+ assert(_u);
+
+ /* /proc/swaps and /etc/fstab might refer to this device by
+ * different names (e.g. one by uuid, the other by the kernel
+ * name), we hence need to look for all aliases we are aware
+ * of for this device */
+
+ if (!(e = unit_name_from_path(what, ".device")))
+ return -ENOMEM;
+
+ u = manager_get_unit(m, e);
+ free(e);
+
+ if (u) {
+ Iterator i;
+ const char *d;
+
+ SET_FOREACH(d, u->meta.names, i) {
+ Unit *k;
+
+ if (!(e = unit_name_change_suffix(d, ".swap")))
+ return -ENOMEM;
+
+ k = manager_get_unit(m, e);
+ free(e);
+
+ if (k) {
+ *_u = k;
+ return 0;
+ }
+ }
+ }
+
+ *_u = NULL;
+ return 0;
+}
+
+int swap_add_one(
+ Manager *m,
+ const char *what,
+ int priority,
+ bool noauto,
+ bool handle,
+ bool from_proc_swaps) {
+ Unit *u = NULL;
+ char *e = NULL, *w = NULL;
bool delete;
int r;
+ SwapParameters *p;
+
+ assert(m);
+ assert(what);
if (!(e = unit_name_from_path(what, ".swap")))
return -ENOMEM;
- if (!(u = manager_get_unit(m, e))) {
+ if (!(u = manager_get_unit(m, e)))
+ if ((r = swap_find(m, what, &u)) < 0)
+ goto fail;
+
+ if (!u) {
delete = true;
if (!(u = unit_new(m))) {
free(e);
return -ENOMEM;
}
+ } else
+ delete = false;
- r = unit_add_name(u, e);
- free(e);
-
- if (r < 0)
- goto fail;
+ if ((r = unit_add_name(u, e)) < 0)
+ goto fail;
- if (!(SWAP(u)->what = strdup(what))) {
- r = -ENOMEM;
- goto fail;
- }
+ if (!(w = strdup(what))) {
+ r = -ENOMEM;
+ goto fail;
+ }
- if ((r = unit_set_description(u, what)) < 0)
- goto fail;
+ if (from_proc_swaps) {
+ p = &SWAP(u)->parameters_proc_swaps;
+ SWAP(u)->from_proc_swaps = true;
+ } else {
+ p = &SWAP(u)->parameters_etc_fstab;
+ SWAP(u)->from_etc_fstab = true;
+ }
- unit_add_to_load_queue(u);
+ free(p->what);
+ p->what = w;
- SWAP(u)->from_proc_swaps_only = from_proc_swaps;
- } else {
- if (SWAP(u)->from_proc_swaps_only && !from_proc_swaps)
- SWAP(u)->from_proc_swaps_only = false;
+ p->priority = priority;
+ p->noauto = noauto;
+ p->handle = handle;
- delete = false;
- free(e);
- }
+ if (delete)
+ unit_add_to_load_queue(u);
- if (!from_proc_swaps)
- SWAP(u)->no_auto = no_auto;
- else
- SWAP(u)->found_in_proc_swaps = true;
+ unit_add_to_dbus_queue(u);
- SWAP(u)->priority = prio;
+ free(e);
return 0;
fail:
- if (delete)
+ free(w);
+ free(e);
+
+ if (delete && u)
unit_free(u);
- return 0;
+ return r;
}
static void swap_set_state(Swap *s, SwapState state) {
@@ -234,29 +334,46 @@ static int swap_coldplug(Unit *u) {
if (s->deserialized_state != s->state)
new_state = s->deserialized_state;
- else if (s->found_in_proc_swaps)
+ else if (s->from_proc_swaps)
new_state = SWAP_ACTIVE;
if (new_state != s->state)
- swap_set_state(s, s->deserialized_state);
+ swap_set_state(s, new_state);
return 0;
}
static void swap_dump(Unit *u, FILE *f, const char *prefix) {
Swap *s = SWAP(u);
+ SwapParameters *p;
assert(s);
+ assert(f);
+
+ if (s->from_proc_swaps)
+ p = &s->parameters_proc_swaps;
+ else if (s->from_fragment)
+ p = &s->parameters_fragment;
+ else
+ p = &s->parameters_etc_fstab;
fprintf(f,
- "%sAutomount State: %s\n"
+ "%sSwap State: %s\n"
"%sWhat: %s\n"
"%sPriority: %i\n"
- "%sNoAuto: %s\n",
+ "%sNoAuto: %s\n"
+ "%sHandle: %s\n"
+ "%sFrom /etc/fstab: %s\n"
+ "%sFrom /proc/swaps: %s\n"
+ "%sFrom fragment: %s\n",
prefix, swap_state_to_string(s->state),
prefix, s->what,
- prefix, s->priority,
- prefix, yes_no(s->no_auto));
+ prefix, p->priority,
+ prefix, yes_no(p->noauto),
+ prefix, yes_no(p->handle),
+ prefix, yes_no(s->from_etc_fstab),
+ prefix, yes_no(s->from_proc_swaps),
+ prefix, yes_no(s->from_fragment));
}
static void swap_enter_dead(Swap *s, bool success) {
@@ -267,13 +384,18 @@ static void swap_enter_dead(Swap *s, bool success) {
static int swap_start(Unit *u) {
Swap *s = SWAP(u);
+ int priority = -1;
int r;
assert(s);
-
assert(s->state == SWAP_DEAD || s->state == SWAP_MAINTAINANCE);
- r = swapon(s->what, (s->priority << SWAP_FLAG_PRIO_SHIFT) & SWAP_FLAG_PRIO_MASK);
+ if (s->from_fragment)
+ priority = s->parameters_fragment.priority;
+ else if (s->from_etc_fstab)
+ priority = s->parameters_etc_fstab.priority;
+
+ r = swapon(s->what, (priority << SWAP_FLAG_PRIO_SHIFT) & SWAP_FLAG_PRIO_MASK);
if (r < 0 && errno != EBUSY) {
r = -errno;
@@ -347,64 +469,47 @@ static bool swap_check_gc(Unit *u) {
assert(s);
- return !s->from_proc_swaps_only || s->found_in_proc_swaps;
+ return s->from_etc_fstab || s->from_proc_swaps;
}
static int swap_load_proc_swaps(Manager *m) {
- Meta *meta;
-
rewind(m->proc_swaps);
- (void) fscanf(m->proc_self_mountinfo, "%*s %*s %*s %*s %*s\n");
+ (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
for (;;) {
char *dev = NULL, *d;
int prio = 0, k;
- k = fscanf(m->proc_self_mountinfo,
- "%ms " /* device/file */
- "%*s " /* type of swap */
- "%*s " /* swap size */
- "%*s " /* used */
- "%d\n", /* priority */
- &dev, &prio);
+ if ((k = fscanf(m->proc_swaps,
+ "%ms " /* device/file */
+ "%*s " /* type of swap */
+ "%*s " /* swap size */
+ "%*s " /* used */
+ "%i\n", /* priority */
+ &dev, &prio)) != 2) {
- if (k != 2) {
if (k == EOF)
- k = 0;
+ break;
free(dev);
return -EBADMSG;
}
- if (!(d = cunescape(dev))) {
- free(dev);
- k = -ENOMEM;
- return k;
- }
- k = swap_add_one(m, d, false, prio, true);
+ d = cunescape(dev);
free(dev);
+
+ if (!d)
+ return -ENOMEM;
+
+ k = swap_add_one(m, d, prio, false, false, true);
free(d);
if (k < 0)
return k;
}
- LIST_FOREACH(units_per_type, meta, m->units_per_type[UNIT_SWAP]) {
- Swap *s = (Swap*) meta;
-
- if (s->state != SWAP_DEAD && s->state != SWAP_ACTIVE)
- continue;
-
- if ((s->state == SWAP_DEAD && !s->found_in_proc_swaps) ||
- (s->state == SWAP_ACTIVE && s->found_in_proc_swaps))
- continue;
-
- swap_set_state(s, s->found_in_proc_swaps ? SWAP_ACTIVE : SWAP_DEAD);
-
- /* Reset the flags for later calls */
- s->found_in_proc_swaps = false;
- }
+ return 0;
}
static void swap_shutdown(Manager *m) {
@@ -428,9 +533,9 @@ static int swap_enumerate(Manager *m) {
int r;
assert(m);
- if (!m->proc_swaps &&
- !(m->proc_swaps = fopen("/proc/swaps", "er")))
- return -errno;
+ if (!m->proc_swaps)
+ if (!(m->proc_swaps = fopen("/proc/swaps", "re")))
+ return -errno;
if ((r = swap_load_proc_swaps(m)) < 0)
swap_shutdown(m);
@@ -441,10 +546,10 @@ static int swap_enumerate(Manager *m) {
const UnitVTable swap_vtable = {
.suffix = ".swap",
- .no_alias = true,
.no_instances = true,
.no_isolate = true,
+ .init = swap_init,
.load = swap_load,
.done = swap_done,
diff --git a/swap.h b/swap.h
index 758cdbd31d..f54a9ee434 100644
--- a/swap.h
+++ b/swap.h
@@ -35,24 +35,32 @@ typedef enum SwapState {
_SWAP_STATE_INVALID = -1
} SwapState;
+typedef struct SwapParameters {
+ char *what;
+ int priority;
+ bool noauto:1;
+ bool handle:1;
+} SwapParameters;
+
struct Swap {
Meta meta;
- char *what;
+ SwapParameters parameters_etc_fstab;
+ SwapParameters parameters_proc_swaps;
+ SwapParameters parameters_fragment;
- int priority;
-
- bool no_auto;
+ char *what;
- bool from_proc_swaps_only:1;
- bool found_in_proc_swaps:1;
+ bool from_etc_fstab:1;
+ bool from_proc_swaps:1;
+ bool from_fragment:1;
SwapState state, deserialized_state;
};
extern const UnitVTable swap_vtable;
-int swap_add_one(Manager *m, const char *what, bool no_auto, int prio, bool from_proc_swap);
+int swap_add_one(Manager *m, const char *what, int prio, bool no_auto, bool handle, bool from_proc_swap);
int swap_add_one_mount_link(Swap *s, Mount *m);