job.h revision b26fa1a2fbcfee7d03b0c8fd15ec3aa64ae70b9f
f82c66a0f006e0f7bbe420e055fef560c6898126nd#pragma once
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd/***
f82c66a0f006e0f7bbe420e055fef560c6898126nd This file is part of systemd.
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd Copyright 2010 Lennart Poettering
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd systemd is free software; you can redistribute it and/or modify it
f82c66a0f006e0f7bbe420e055fef560c6898126nd under the terms of the GNU Lesser General Public License as published by
f82c66a0f006e0f7bbe420e055fef560c6898126nd the Free Software Foundation; either version 2.1 of the License, or
f82c66a0f006e0f7bbe420e055fef560c6898126nd (at your option) any later version.
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd systemd is distributed in the hope that it will be useful, but
f82c66a0f006e0f7bbe420e055fef560c6898126nd WITHOUT ANY WARRANTY; without even the implied warranty of
f82c66a0f006e0f7bbe420e055fef560c6898126nd MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
f82c66a0f006e0f7bbe420e055fef560c6898126nd Lesser General Public License for more details.
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd You should have received a copy of the GNU Lesser General Public License
f82c66a0f006e0f7bbe420e055fef560c6898126nd along with systemd; If not, see <http://www.gnu.org/licenses/>.
f82c66a0f006e0f7bbe420e055fef560c6898126nd***/
f82c66a0f006e0f7bbe420e055fef560c6898126nd
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin#include <stdbool.h>
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd#include "sd-event.h"
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd#include "list.h"
f82c66a0f006e0f7bbe420e055fef560c6898126nd#include "unit-name.h"
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126ndtypedef struct Job Job;
b6529ec5115d80b7dedcfd0935746015b2096084minfrintypedef struct JobDependency JobDependency;
f82c66a0f006e0f7bbe420e055fef560c6898126ndtypedef enum JobType JobType;
f82c66a0f006e0f7bbe420e055fef560c6898126ndtypedef enum JobState JobState;
b6529ec5115d80b7dedcfd0935746015b2096084minfrintypedef enum JobMode JobMode;
f82c66a0f006e0f7bbe420e055fef560c6898126ndtypedef enum JobResult JobResult;
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin/* Be careful when changing the job types! Adjust job_merging_table[] accordingly! */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrinenum JobType {
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrin JOB_START, /* if a unit does not support being started, we'll just wait until it becomes active */
5da7a94d6237c66b561dfa4add47a3f954ed39e5minfrin JOB_VERIFY_ACTIVE,
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrin
f82c66a0f006e0f7bbe420e055fef560c6898126nd JOB_STOP,
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd JOB_RELOAD, /* if running, reload */
f82c66a0f006e0f7bbe420e055fef560c6898126nd
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin /* Note that restarts are first treated like JOB_STOP, but
f82c66a0f006e0f7bbe420e055fef560c6898126nd * then instead of finishing are patched to become
f82c66a0f006e0f7bbe420e055fef560c6898126nd * JOB_START. */
f82c66a0f006e0f7bbe420e055fef560c6898126nd JOB_RESTART, /* If running, stop. Then start unconditionally. */
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd _JOB_TYPE_MAX_MERGING,
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd /* JOB_NOP can enter into a transaction, but as it won't pull in
f82c66a0f006e0f7bbe420e055fef560c6898126nd * any dependencies and it uses the special 'nop_job' slot in Unit,
f82c66a0f006e0f7bbe420e055fef560c6898126nd * it won't have to merge with anything (except possibly into another
f82c66a0f006e0f7bbe420e055fef560c6898126nd * JOB_NOP, previously installed). JOB_NOP is special-cased in
b6529ec5115d80b7dedcfd0935746015b2096084minfrin * job_type_is_*() functions so that the transaction can be
f82c66a0f006e0f7bbe420e055fef560c6898126nd * activated. */
f82c66a0f006e0f7bbe420e055fef560c6898126nd JOB_NOP = _JOB_TYPE_MAX_MERGING, /* do nothing */
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd _JOB_TYPE_MAX_IN_TRANSACTION,
f82c66a0f006e0f7bbe420e055fef560c6898126nd
663c339c8a4663cf1977f890481f8b7e251d3221jerenkrantz /* JOB_TRY_RESTART can never appear in a transaction, because
f82c66a0f006e0f7bbe420e055fef560c6898126nd * it always collapses into JOB_RESTART or JOB_NOP before entering.
f82c66a0f006e0f7bbe420e055fef560c6898126nd * Thus we never need to merge it with anything. */
f82c66a0f006e0f7bbe420e055fef560c6898126nd JOB_TRY_RESTART = _JOB_TYPE_MAX_IN_TRANSACTION, /* if running, stop and then start */
f82c66a0f006e0f7bbe420e055fef560c6898126nd
663c339c8a4663cf1977f890481f8b7e251d3221jerenkrantz /* Similar to JOB_TRY_RESTART but collapses to JOB_RELOAD or JOB_NOP */
663c339c8a4663cf1977f890481f8b7e251d3221jerenkrantz JOB_TRY_RELOAD,
663c339c8a4663cf1977f890481f8b7e251d3221jerenkrantz
f82c66a0f006e0f7bbe420e055fef560c6898126nd /* JOB_RELOAD_OR_START won't enter into a transaction and cannot result
f82c66a0f006e0f7bbe420e055fef560c6898126nd * from transaction merging (there's no way for JOB_RELOAD and
f82c66a0f006e0f7bbe420e055fef560c6898126nd * JOB_START to meet in one transaction). It can result from a merge
03f4b8dc5610480df8539053b96b568a9f29ee13minfrin * during job installation, but then it will immediately collapse into
03f4b8dc5610480df8539053b96b568a9f29ee13minfrin * one of the two simpler types. */
03f4b8dc5610480df8539053b96b568a9f29ee13minfrin JOB_RELOAD_OR_START, /* if running, reload, otherwise start */
5da7a94d6237c66b561dfa4add47a3f954ed39e5minfrin
5da7a94d6237c66b561dfa4add47a3f954ed39e5minfrin _JOB_TYPE_MAX,
5da7a94d6237c66b561dfa4add47a3f954ed39e5minfrin _JOB_TYPE_INVALID = -1
f82c66a0f006e0f7bbe420e055fef560c6898126nd};
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126ndenum JobState {
b6529ec5115d80b7dedcfd0935746015b2096084minfrin JOB_WAITING,
b6529ec5115d80b7dedcfd0935746015b2096084minfrin JOB_RUNNING,
b6529ec5115d80b7dedcfd0935746015b2096084minfrin _JOB_STATE_MAX,
f82c66a0f006e0f7bbe420e055fef560c6898126nd _JOB_STATE_INVALID = -1
f82c66a0f006e0f7bbe420e055fef560c6898126nd};
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrinenum JobMode {
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_FAIL, /* Fail if a conflicting job is already queued */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_REPLACE, /* Replace an existing conflicting job */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_REPLACE_IRREVERSIBLY,/* Like JOB_REPLACE + produce irreversible jobs */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_ISOLATE, /* Start a unit, and stop all others */
f82c66a0f006e0f7bbe420e055fef560c6898126nd JOB_FLUSH, /* Flush out all other queued jobs when queing this one */
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrin JOB_IGNORE_DEPENDENCIES, /* Ignore both requirement and ordering dependencies */
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrin JOB_IGNORE_REQUIREMENTS, /* Ignore requirement dependencies */
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrin _JOB_MODE_MAX,
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrin _JOB_MODE_INVALID = -1
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrin};
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrin
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrinenum JobResult {
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrin JOB_DONE, /* Job completed successfully */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_CANCELED, /* Job canceled by a conflicting job installation or by explicit cancel request */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_TIMEOUT, /* Job timeout elapsed */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_FAILED, /* Job failed */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_DEPENDENCY, /* A required dependency job did not result in JOB_DONE */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_SKIPPED, /* Negative result of JOB_VERIFY_ACTIVE */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_INVALID, /* JOB_RELOAD of inactive unit */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_ASSERT, /* Couldn't start a unit, because an assert didn't hold */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin JOB_UNSUPPORTED, /* Couldn't start a unit, because the unit type is not supported on the system */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin _JOB_RESULT_MAX,
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin _JOB_RESULT_INVALID = -1
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin};
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin#include "unit.h"
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrinstruct JobDependency {
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin /* Encodes that the 'subject' job needs the 'object' job in
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin * some way. This structure is used only while building a transaction. */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin Job *subject;
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin Job *object;
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin LIST_FIELDS(JobDependency, subject);
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin LIST_FIELDS(JobDependency, object);
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin bool matters;
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin bool conflicts;
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin};
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrinstruct Job {
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin Manager *manager;
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin Unit *unit;
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin LIST_FIELDS(Job, transaction);
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin LIST_FIELDS(Job, run_queue);
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin LIST_FIELDS(Job, dbus_queue);
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin LIST_HEAD(JobDependency, subject_list);
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin LIST_HEAD(JobDependency, object_list);
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin /* Used for graph algs as a "I have been here" marker */
8310cf661acfe5224adb2f1d62e67e929fb5b60bminfrin Job* marker;
f82c66a0f006e0f7bbe420e055fef560c6898126nd unsigned generation;
f82c66a0f006e0f7bbe420e055fef560c6898126nd
f82c66a0f006e0f7bbe420e055fef560c6898126nd uint32_t id;
cd75115baac4df586f9a346dc1c2c9d9bd3d58aaminfrin
f82c66a0f006e0f7bbe420e055fef560c6898126nd JobType type;
JobState state;
sd_event_source *timer_event_source;
usec_t begin_usec;
/*
* This tracks where to send signals, and also which clients
* are allowed to call DBus methods on the job (other than
* root).
*
* There can be more than one client, because of job merging.
*/
sd_bus_track *clients;
char **deserialized_clients;
JobResult result;
bool installed:1;
bool in_run_queue:1;
bool matters_to_anchor:1;
bool in_dbus_queue:1;
bool sent_dbus_new_signal:1;
bool ignore_order:1;
bool irreversible:1;
};
Job* job_new(Unit *unit, JobType type);
Job* job_new_raw(Unit *unit);
void job_free(Job *job);
Job* job_install(Job *j);
int job_install_deserialized(Job *j);
void job_uninstall(Job *j);
void job_dump(Job *j, FILE*f, const char *prefix);
int job_serialize(Job *j, FILE *f, FDSet *fds);
int job_deserialize(Job *j, FILE *f, FDSet *fds);
int job_coldplug(Job *j);
JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts);
void job_dependency_free(JobDependency *l);
int job_merge(Job *j, Job *other);
JobType job_type_lookup_merge(JobType a, JobType b) _pure_;
_pure_ static inline bool job_type_is_mergeable(JobType a, JobType b) {
return job_type_lookup_merge(a, b) >= 0;
}
_pure_ static inline bool job_type_is_conflicting(JobType a, JobType b) {
return a != JOB_NOP && b != JOB_NOP && !job_type_is_mergeable(a, b);
}
_pure_ static inline bool job_type_is_superset(JobType a, JobType b) {
/* Checks whether operation a is a "superset" of b in its actions */
if (b == JOB_NOP)
return true;
if (a == JOB_NOP)
return false;
return a == job_type_lookup_merge(a, b);
}
bool job_type_is_redundant(JobType a, UnitActiveState b) _pure_;
/* Collapses a state-dependent job type into a simpler type by observing
* the state of the unit which it is going to be applied to. */
JobType job_type_collapse(JobType t, Unit *u);
int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u);
void job_add_to_run_queue(Job *j);
void job_add_to_dbus_queue(Job *j);
int job_start_timer(Job *j);
int job_run_and_invalidate(Job *j);
int job_finish_and_invalidate(Job *j, JobResult result, bool recursive);
char *job_dbus_path(Job *j);
void job_shutdown_magic(Job *j);
int job_get_timeout(Job *j, usec_t *timeout) _pure_;
const char* job_type_to_string(JobType t) _const_;
JobType job_type_from_string(const char *s) _pure_;
const char* job_state_to_string(JobState t) _const_;
JobState job_state_from_string(const char *s) _pure_;
const char* job_mode_to_string(JobMode t) _const_;
JobMode job_mode_from_string(const char *s) _pure_;
const char* job_result_to_string(JobResult t) _const_;
JobResult job_result_from_string(const char *s) _pure_;
const char* job_type_to_access_method(JobType t);