X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fswap.c;h=1ef672f7e9e7a3ce565b57ce9597bd7ff60d3ff3;hb=b57b06258e0b1894edb6d1fc52a80b3c33164892;hp=b97f102d643b7815f135e678bcddc7300353a3b0;hpb=caac2704d57ef6d95f7053456479353bae3638de;p=elogind.git diff --git a/src/core/swap.c b/src/core/swap.c index b97f102d6..1ef672f7e 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -473,6 +473,7 @@ static int swap_process_new_swap(Manager *m, const char *device, int prio, bool static void swap_set_state(Swap *s, SwapState state) { SwapState old_state; + Swap *other; assert(s); @@ -500,6 +501,15 @@ static void swap_set_state(Swap *s, SwapState state) { 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) { @@ -796,7 +806,7 @@ fail: } static int swap_start(Unit *u) { - Swap *s = SWAP(u); + Swap *s = SWAP(u), *other; assert(s); @@ -818,6 +828,13 @@ static int swap_start(Unit *u) { 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;