Merge pull request #8847 from poettering/transient-once
enforce that scope units are started at most once
This commit is contained in:
commit
2ff04e5b7f
9
TODO
9
TODO
|
@ -52,8 +52,6 @@ Features:
|
|||
|
||||
* add --vacuum-xyz options to coredumpctl, matching those journalctl already has.
|
||||
|
||||
* enforce that transient units are started exactly once only
|
||||
|
||||
* list the exit codes from the BSD/glibc <sysexits.h> in our own
|
||||
exit-codes.[ch] tables.
|
||||
|
||||
|
@ -517,7 +515,6 @@ Features:
|
|||
|
||||
* transient units:
|
||||
- add field to transient units that indicate whether systemd or somebody else saves/restores its settings, for integration with libvirt
|
||||
- ensure scope units may be started only a single time
|
||||
|
||||
* Automatically configure swap partition to use for hibernation by looking for largest swap partition on the root disk?
|
||||
|
||||
|
@ -640,10 +637,6 @@ Features:
|
|||
logout dialog. If it is pressed for 1s, do the usual
|
||||
shutdown. Inspiration are Macs here.
|
||||
- expose "Locked" property on logind sesison objects
|
||||
- given that logind now lets PID 1 do all nasty work, we can
|
||||
probably reduce the capability set it retains substantially.
|
||||
(we need CAP_SYS_ADMIN for drmSetMaster(), so maybe not worth it)
|
||||
- expose orientation sensors and tablet mode through logind
|
||||
- maybe allow configuration of the StopTimeout for session scopes
|
||||
- rename session scope so that it includes the UID. THat way
|
||||
the session scope can be arranged freely in slices and we don't have
|
||||
|
@ -700,8 +693,6 @@ Features:
|
|||
lazily. Encode just enough information in the file name, so that we
|
||||
do not have to open it to know that it is not interesting for us, for
|
||||
the most common operations.
|
||||
- journal-or-kmsg is currently broken? See reverted
|
||||
commit 4a01181e460686d8b4a543b1dfa7f77c9e3c5ab8.
|
||||
- man: document that corrupted journal files is nothing to act on
|
||||
- rework journald sigbus stuff to use mutex
|
||||
- Set RLIMIT_NPROC for systemd-journal-xyz, and all other of our
|
||||
|
|
|
@ -612,6 +612,8 @@ int job_run_and_invalidate(Job *j) {
|
|||
r = job_finish_and_invalidate(j, JOB_UNSUPPORTED, true, false);
|
||||
else if (r == -ENOLINK)
|
||||
r = job_finish_and_invalidate(j, JOB_DEPENDENCY, true, false);
|
||||
else if (r == -ESTALE)
|
||||
r = job_finish_and_invalidate(j, JOB_ONCE, true, false);
|
||||
else if (r == -EAGAIN)
|
||||
job_set_state(j, JOB_WAITING);
|
||||
else if (r < 0)
|
||||
|
@ -631,6 +633,7 @@ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobR
|
|||
[JOB_ASSERT] = "Assertion failed for %s.",
|
||||
[JOB_UNSUPPORTED] = "Starting of %s not supported.",
|
||||
[JOB_COLLECTED] = "Unnecessary job for %s was removed.",
|
||||
[JOB_ONCE] = "Unit %s has been started before and cannot be started again."
|
||||
};
|
||||
static const char *const generic_finished_stop_job[_JOB_RESULT_MAX] = {
|
||||
[JOB_DONE] = "Stopped %s.",
|
||||
|
@ -690,6 +693,7 @@ static const struct {
|
|||
[JOB_ASSERT] = { ANSI_HIGHLIGHT_YELLOW, "ASSERT" },
|
||||
[JOB_UNSUPPORTED] = { ANSI_HIGHLIGHT_YELLOW, "UNSUPP" },
|
||||
/* JOB_COLLECTED */
|
||||
[JOB_ONCE] = { ANSI_HIGHLIGHT_RED, " ONCE " },
|
||||
};
|
||||
|
||||
static void job_print_status_message(Unit *u, JobType t, JobResult result) {
|
||||
|
@ -747,6 +751,7 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
|
|||
[JOB_ASSERT] = LOG_WARNING,
|
||||
[JOB_UNSUPPORTED] = LOG_WARNING,
|
||||
[JOB_COLLECTED] = LOG_INFO,
|
||||
[JOB_ONCE] = LOG_ERR,
|
||||
};
|
||||
|
||||
assert(u);
|
||||
|
@ -1523,6 +1528,7 @@ static const char* const job_result_table[_JOB_RESULT_MAX] = {
|
|||
[JOB_ASSERT] = "assert",
|
||||
[JOB_UNSUPPORTED] = "unsupported",
|
||||
[JOB_COLLECTED] = "collected",
|
||||
[JOB_ONCE] = "once",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);
|
||||
|
|
|
@ -96,6 +96,7 @@ enum JobResult {
|
|||
JOB_ASSERT, /* Couldn't start a unit, because an assert didn't hold */
|
||||
JOB_UNSUPPORTED, /* Couldn't start a unit, because the unit type is not supported on the system */
|
||||
JOB_COLLECTED, /* Job was garbage collected, since nothing needed it anymore */
|
||||
JOB_ONCE, /* Unit was started before, and hence can't be started again */
|
||||
_JOB_RESULT_MAX,
|
||||
_JOB_RESULT_INVALID = -1
|
||||
};
|
||||
|
|
|
@ -587,6 +587,7 @@ const UnitVTable scope_vtable = {
|
|||
|
||||
.can_transient = true,
|
||||
.can_delegate = true,
|
||||
.once_only = true,
|
||||
|
||||
.init = scope_init,
|
||||
.load = scope_load,
|
||||
|
|
|
@ -1753,6 +1753,7 @@ static bool unit_verify_deps(Unit *u) {
|
|||
* -EINVAL: Unit not loaded
|
||||
* -EOPNOTSUPP: Unit type not supported
|
||||
* -ENOLINK: The necessary dependencies are not fulfilled.
|
||||
* -ESTALE: This unit has been started before and can't be started a second time
|
||||
*/
|
||||
int unit_start(Unit *u) {
|
||||
UnitActiveState state;
|
||||
|
@ -1772,6 +1773,10 @@ int unit_start(Unit *u) {
|
|||
if (u->load_state != UNIT_LOADED)
|
||||
return -EINVAL;
|
||||
|
||||
/* Refuse starting scope units more than once */
|
||||
if (UNIT_VTABLE(u)->once_only && dual_timestamp_is_set(&u->inactive_enter_timestamp))
|
||||
return -ESTALE;
|
||||
|
||||
/* If the conditions failed, don't do anything at all. If we
|
||||
* already are activating this call might still be useful to
|
||||
* speed up activation in case there is some hold-off time,
|
||||
|
@ -1835,6 +1840,10 @@ bool unit_can_start(Unit *u) {
|
|||
if (!unit_supported(u))
|
||||
return false;
|
||||
|
||||
/* Scope units may be started only once */
|
||||
if (UNIT_VTABLE(u)->once_only && dual_timestamp_is_set(&u->inactive_exit_timestamp))
|
||||
return false;
|
||||
|
||||
return !!UNIT_VTABLE(u)->start;
|
||||
}
|
||||
|
||||
|
|
|
@ -561,6 +561,9 @@ struct UnitVTable {
|
|||
/* True if cgroup delegation is permissible */
|
||||
bool can_delegate:1;
|
||||
|
||||
/* True if units of this type shall be startable only once and then never again */
|
||||
bool once_only:1;
|
||||
|
||||
/* True if queued jobs of this type should be GC'ed if no other job needs them anymore */
|
||||
bool gc_jobs:1;
|
||||
};
|
||||
|
|
|
@ -1900,8 +1900,6 @@ finish:
|
|||
}
|
||||
|
||||
static int check_wait_response(BusWaitForJobs *d, bool quiet, const char* const* extra_args) {
|
||||
int r = 0;
|
||||
|
||||
assert(d->result);
|
||||
|
||||
if (!quiet) {
|
||||
|
@ -1919,6 +1917,8 @@ static int check_wait_response(BusWaitForJobs *d, bool quiet, const char* const*
|
|||
log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
|
||||
else if (streq(d->result, "collected"))
|
||||
log_error("Queued job for %s was garbage collected.", strna(d->name));
|
||||
else if (streq(d->result, "once"))
|
||||
log_error("Unit %s was started already once and can't be started again.", strna(d->name));
|
||||
else if (!STR_IN_SET(d->result, "done", "skipped")) {
|
||||
if (d->name) {
|
||||
_cleanup_free_ char *result = NULL;
|
||||
|
@ -1935,21 +1935,24 @@ static int check_wait_response(BusWaitForJobs *d, bool quiet, const char* const*
|
|||
}
|
||||
|
||||
if (STR_IN_SET(d->result, "canceled", "collected"))
|
||||
r = -ECANCELED;
|
||||
return -ECANCELED;
|
||||
else if (streq(d->result, "timeout"))
|
||||
r = -ETIME;
|
||||
return -ETIME;
|
||||
else if (streq(d->result, "dependency"))
|
||||
r = -EIO;
|
||||
return -EIO;
|
||||
else if (streq(d->result, "invalid"))
|
||||
r = -ENOEXEC;
|
||||
return -ENOEXEC;
|
||||
else if (streq(d->result, "assert"))
|
||||
r = -EPROTO;
|
||||
return -EPROTO;
|
||||
else if (streq(d->result, "unsupported"))
|
||||
r = -EOPNOTSUPP;
|
||||
else if (!STR_IN_SET(d->result, "done", "skipped"))
|
||||
r = -EIO;
|
||||
return -EOPNOTSUPP;
|
||||
else if (streq(d->result, "once"))
|
||||
return -ESTALE;
|
||||
else if (STR_IN_SET(d->result, "done", "skipped"))
|
||||
return 0;
|
||||
|
||||
return r;
|
||||
log_debug("Unexpected job result, assuming server side newer than us: %s", d->result);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet, const char* const* extra_args) {
|
||||
|
|
Loading…
Reference in a new issue