swap.c revision e99e38bbdcca3fe5956823bdb3d38544ccf93221
/*-*- Mode: C; c-basic-offset: 8 -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include "unit.h"
#include "swap.h"
#include "load-fragment.h"
#include "load-dropin.h"
#include "unit-name.h"
#include "dbus-swap.h"
[SWAP_DEAD] = UNIT_INACTIVE,
[SWAP_ACTIVE] = UNIT_ACTIVE,
};
assert(s);
s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
}
assert(s);
}
int r;
assert(s);
assert(m);
return 0;
if (is_device_path(s->what))
return 0;
return 0;
return r;
return r;
return 0;
}
static int swap_add_mount_links(Swap *s) {
int r;
assert(s);
return r;
return 0;
}
static int swap_add_target_links(Swap *s) {
SwapParameters *p;
int r;
assert(s);
if (s->from_fragment)
p = &s->parameters_fragment;
else if (s->from_etc_fstab)
p = &s->parameters_etc_fstab;
else
return 0;
return r;
return r;
}
static int swap_verify(Swap *s) {
bool b;
char *e;
return 0;
return -ENOMEM;
b = unit_has_name(UNIT(s), e);
free(e);
if (!b) {
return -EINVAL;
}
return 0;
}
int r;
assert(s);
/* Load a .swap file */
if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
return r;
if (s->meta.fragment_path)
s->from_fragment = true;
if (!s->what) {
if (s->parameters_fragment.what)
else if (s->parameters_etc_fstab.what)
else if (s->parameters_proc_swaps.what)
else
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,
return r;
if ((r = swap_add_mount_links(s)) < 0)
return r;
if ((r = swap_add_target_links(s)) < 0)
return r;
}
return swap_verify(s);
}
Unit *u;
char *e;
assert(m);
* 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 */
return -ENOMEM;
u = manager_get_unit(m, e);
free(e);
if (u) {
Iterator i;
const char *d;
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;
}
}
}
return 0;
}
int swap_add_one(
Manager *m,
const char *what,
int priority,
bool noauto,
bool handle,
bool from_proc_swaps) {
bool delete;
int r;
SwapParameters *p;
assert(m);
return -ENOMEM;
if (!(u = manager_get_unit(m, e)))
goto fail;
if (!u) {
delete = true;
if (!(u = unit_new(m))) {
free(e);
return -ENOMEM;
}
} else
delete = false;
if ((r = unit_add_name(u, e)) < 0)
goto fail;
r = -ENOMEM;
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;
}
p->what = w;
if (delete)
free(e);
return 0;
fail:
free(w);
free(e);
if (delete && u)
unit_free(u);
return r;
}
assert(s);
log_debug("%s changed %s -> %s",
}
static int swap_coldplug(Unit *u) {
assert(s);
if (s->deserialized_state != s->state)
new_state = s->deserialized_state;
else if (s->from_proc_swaps)
swap_set_state(s, new_state);
return 0;
}
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,
"%sSwap State: %s\n"
"%sWhat: %s\n"
"%sPriority: %i\n"
"%sNoAuto: %s\n"
"%sHandle: %s\n"
"%sFrom fragment: %s\n",
}
assert(s);
}
static int swap_start(Unit *u) {
int priority = -1;
int r;
assert(s);
if (s->from_fragment)
else if (s->from_etc_fstab)
r = -errno;
swap_enter_dead(s, false);
return r;
}
return 0;
}
int r;
assert(s);
return 0;
}
assert(s);
assert(f);
return 0;
}
assert(s);
else
s->deserialized_state = state;
} else
return 0;
}
assert(u);
}
static const char *swap_sub_state_to_string(Unit *u) {
assert(u);
}
static bool swap_check_gc(Unit *u) {
assert(s);
return s->from_etc_fstab || s->from_proc_swaps;
}
static int swap_load_proc_swaps(Manager *m) {
rewind(m->proc_swaps);
for (;;) {
int prio = 0, k;
if ((k = fscanf(m->proc_swaps,
"%*s " /* type of swap */
"%*s " /* swap size */
"%*s " /* used */
"%i\n", /* priority */
if (k == EOF)
break;
return -EBADMSG;
}
if (!d)
return -ENOMEM;
k = swap_add_one(m, d, prio, false, false, true);
free(d);
if (k < 0)
return k;
}
return 0;
}
static void swap_shutdown(Manager *m) {
assert(m);
if (m->proc_swaps) {
fclose(m->proc_swaps);
m->proc_swaps = NULL;
}
}
static const char* const swap_state_table[_SWAP_STATE_MAX] = {
[SWAP_DEAD] = "dead",
[SWAP_ACTIVE] = "active",
[SWAP_MAINTAINANCE] = "maintainance"
};
static int swap_enumerate(Manager *m) {
int r;
assert(m);
if (!m->proc_swaps)
return -errno;
if ((r = swap_load_proc_swaps(m)) < 0)
swap_shutdown(m);
return r;
}
const UnitVTable swap_vtable = {
.suffix = ".swap",
.no_instances = true,
.no_isolate = true,
.start = swap_start,
};