mirror of
https://github.com/systemd/systemd.git
synced 2025-03-21 02:50:18 +03:00
execute: fix bad jump
This commit is contained in:
parent
c0b52914d2
commit
4e85aff465
81
dbus-mount.c
81
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),
|
||||
|
30
dbus-swap.c
30
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 }
|
||||
};
|
||||
|
||||
|
5
device.c
5
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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 }
|
||||
};
|
||||
|
73
mount.c
73
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);
|
||||
|
311
swap.c
311
swap.c
@ -40,32 +40,24 @@ static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
|
||||
[SWAP_MAINTAINANCE] = UNIT_INACTIVE
|
||||
};
|
||||
|
||||
static void swap_init(Unit *u) {
|
||||
Swap *s = SWAP(u);
|
||||
|
||||
assert(s);
|
||||
assert(s->meta.load_state == UNIT_STUB);
|
||||
|
||||
s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
|
||||
}
|
||||
|
||||
static void swap_done(Unit *u) {
|
||||
Swap *s = SWAP(u);
|
||||
|
||||
assert(s);
|
||||
|
||||
free(s->what);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
r = unit_add_name(u, e);
|
||||
free(e);
|
||||
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
if (!(SWAP(u)->what = strdup(what))) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((r = unit_set_description(u, what)) < 0)
|
||||
goto fail;
|
||||
|
||||
unit_add_to_load_queue(u);
|
||||
|
||||
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;
|
||||
|
||||
} else
|
||||
delete = false;
|
||||
free(e);
|
||||
|
||||
if ((r = unit_add_name(u, e)) < 0)
|
||||
goto fail;
|
||||
|
||||
if (!(w = strdup(what))) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!from_proc_swaps)
|
||||
SWAP(u)->no_auto = no_auto;
|
||||
else
|
||||
SWAP(u)->found_in_proc_swaps = true;
|
||||
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;
|
||||
}
|
||||
|
||||
SWAP(u)->priority = prio;
|
||||
free(p->what);
|
||||
p->what = w;
|
||||
|
||||
p->priority = priority;
|
||||
p->noauto = noauto;
|
||||
p->handle = handle;
|
||||
|
||||
if (delete)
|
||||
unit_add_to_load_queue(u);
|
||||
|
||||
unit_add_to_dbus_queue(u);
|
||||
|
||||
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,
|
||||
|
||||
|
22
swap.h
22
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;
|
||||
|
||||
SwapParameters parameters_etc_fstab;
|
||||
SwapParameters parameters_proc_swaps;
|
||||
SwapParameters parameters_fragment;
|
||||
|
||||
char *what;
|
||||
|
||||
int priority;
|
||||
|
||||
bool no_auto;
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user