***/
#include <errno.h>
-#include <limits.h>
#include <unistd.h>
-#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/stat.h>
-#include <sys/swap.h>
#include <libudev.h>
#include "unit.h"
#include "swap.h"
-#include "load-fragment.h"
-#include "load-dropin.h"
#include "unit-name.h"
#include "dbus-swap.h"
#include "special.h"
-#include "bus-common-errors.h"
#include "exit-status.h"
-#include "def.h"
#include "path-util.h"
#include "virt.h"
#include "udev-util.h"
static void swap_set_state(Swap *s, SwapState state) {
SwapState old_state;
+ Swap *other;
assert(s);
swap_state_to_string(state));
unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
+
+ /* If there other units for the same device node have a job
+ queued it might be worth checking again if it is runnable
+ now. This is necessary, since swap_start() refuses
+ operation with EAGAIN if there's already another job for
+ the same device node queued. */
+ LIST_FOREACH_OTHERS(same_devnode, other, s)
+ if (UNIT(other)->job)
+ job_add_to_run_queue(UNIT(other)->job);
}
static int swap_coldplug(Unit *u) {
fail:
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
-
return r;
}
return;
fail:
- log_unit_warning(UNIT(s)->id,
- "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
-
+ log_unit_warning_errno(UNIT(s)->id, r, "%s failed to kill processes: %m", UNIT(s)->id);
swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
}
if (streq(discard, "all"))
discard_arg = "--discard";
else
- discard_arg = strappenda("--discard=", discard);
+ discard_arg = strjoina("--discard=", discard);
r = exec_command_append(s->control_command, discard_arg, NULL);
if (r < 0)
return;
fail:
- log_unit_warning(UNIT(s)->id,
- "%s failed to run 'swapon' task: %s",
- UNIT(s)->id, strerror(-r));
+ log_unit_warning_errno(UNIT(s)->id, r, "%s failed to run 'swapon' task: %m", UNIT(s)->id);
swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
}
return;
fail:
- log_unit_warning(UNIT(s)->id,
- "%s failed to run 'swapoff' task: %s",
- UNIT(s)->id, strerror(-r));
+ log_unit_warning_errno(UNIT(s)->id, r, "%s failed to run 'swapoff' task: %m", UNIT(s)->id);
swap_enter_active(s, SWAP_FAILURE_RESOURCES);
}
static int swap_start(Unit *u) {
- Swap *s = SWAP(u);
+ Swap *s = SWAP(u), *other;
assert(s);
if (detect_container(NULL) > 0)
return -EPERM;
+ /* If there's a job for another swap unit for the same node
+ * running, then let's not dispatch this one for now, and wait
+ * until that other job has finished. */
+ LIST_FOREACH_OTHERS(same_devnode, other, s)
+ if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING)
+ return -EAGAIN;
+
s->result = SWAP_SUCCESS;
swap_enter_activating(s);
- return 0;
+ return 1;
}
static int swap_stop(Unit *u) {
return -EPERM;
swap_enter_deactivating(s);
- return 0;
+ return 1;
}
static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
if (s->from_fragment)
return NULL;
- LIST_FOREACH_AFTER(same_devnode, other, s)
- if (other->from_fragment)
- return UNIT(other);
-
- LIST_FOREACH_BEFORE(same_devnode, other, s)
+ LIST_FOREACH_OTHERS(same_devnode, other, s)
if (other->from_fragment)
return UNIT(other);
if (!set)
return -ENOMEM;
- LIST_FOREACH_AFTER(same_devnode, other, s) {
- r = set_put(set, other);
- if (r < 0)
- goto fail;
- }
-
- LIST_FOREACH_BEFORE(same_devnode, other, s) {
+ LIST_FOREACH_OTHERS(same_devnode, other, s) {
r = set_put(set, other);
if (r < 0)
goto fail;