job.h revision 94bd732348535de399f8f003e3a1cbc8a81ab839
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#pragma once
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2010 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <stdbool.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "sd-event.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "list.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "unit-name.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringtypedef struct Job Job;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringtypedef struct JobDependency JobDependency;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringtypedef enum JobType JobType;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringtypedef enum JobState JobState;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringtypedef enum JobMode JobMode;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringtypedef enum JobResult JobResult;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/* Be careful when changing the job types! Adjust job_merging_table[] accordingly! */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringenum JobType {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering JOB_START, /* if a unit does not support being started, we'll just wait until it becomes active */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering JOB_VERIFY_ACTIVE,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering JOB_STOP,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering JOB_RELOAD, /* if running, reload */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
d3152a09ac5804ec8603daee12f98cf03523cce0Lennart Poettering /* Note that restarts are first treated like JOB_STOP, but
d3152a09ac5804ec8603daee12f98cf03523cce0Lennart Poettering * then instead of finishing are patched to become
e70bc43cdf75b36e7ad3d29e9a6f8ee1461e7d5eLennart Poettering * JOB_START. */
d3152a09ac5804ec8603daee12f98cf03523cce0Lennart Poettering JOB_RESTART, /* If running, stop. Then start unconditionally. */
97e67f1e52ddc0c21a88cfbcab57e83c59ee627dLennart Poettering
97e67f1e52ddc0c21a88cfbcab57e83c59ee627dLennart Poettering _JOB_TYPE_MAX_MERGING,
e70bc43cdf75b36e7ad3d29e9a6f8ee1461e7d5eLennart Poettering
97e67f1e52ddc0c21a88cfbcab57e83c59ee627dLennart Poettering /* JOB_NOP can enter into a transaction, but as it won't pull in
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering * any dependencies and it uses the special 'nop_job' slot in Unit,
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering * it won't have to merge with anything (except possibly into another
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering * JOB_NOP, previously installed). JOB_NOP is special-cased in
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering * job_type_is_*() functions so that the transaction can be
adacb9575a09981fcf11279f2f661e3fc21e58ffLennart Poettering * activated. */
adacb9575a09981fcf11279f2f661e3fc21e58ffLennart Poettering JOB_NOP = _JOB_TYPE_MAX_MERGING, /* do nothing */
e70bc43cdf75b36e7ad3d29e9a6f8ee1461e7d5eLennart Poettering
e70bc43cdf75b36e7ad3d29e9a6f8ee1461e7d5eLennart Poettering _JOB_TYPE_MAX_IN_TRANSACTION,
e70bc43cdf75b36e7ad3d29e9a6f8ee1461e7d5eLennart Poettering
e70bc43cdf75b36e7ad3d29e9a6f8ee1461e7d5eLennart Poettering /* JOB_TRY_RESTART can never appear in a transaction, because
e70bc43cdf75b36e7ad3d29e9a6f8ee1461e7d5eLennart Poettering * it always collapses into JOB_RESTART or JOB_NOP before entering.
adacb9575a09981fcf11279f2f661e3fc21e58ffLennart Poettering * Thus we never need to merge it with anything. */
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering JOB_TRY_RESTART = _JOB_TYPE_MAX_IN_TRANSACTION, /* if running, stop and then start */
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering /* Similar to JOB_TRY_RESTART but collapses to JOB_RELOAD or JOB_NOP */
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering JOB_TRY_RELOAD,
49af9e1368571f4e423cde0fd45ee284451434d1Lennart Poettering
49af9e1368571f4e423cde0fd45ee284451434d1Lennart Poettering /* JOB_RELOAD_OR_START won't enter into a transaction and cannot result
49af9e1368571f4e423cde0fd45ee284451434d1Lennart Poettering * from transaction merging (there's no way for JOB_RELOAD and
49af9e1368571f4e423cde0fd45ee284451434d1Lennart Poettering * JOB_START to meet in one transaction). It can result from a merge
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering * during job installation, but then it will immediately collapse into
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering * one of the two simpler types. */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_RELOAD_OR_START, /* if running, reload, otherwise start */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering _JOB_TYPE_MAX,
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering _JOB_TYPE_INVALID = -1
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering};
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poetteringenum JobState {
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_WAITING,
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_RUNNING,
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering _JOB_STATE_MAX,
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering _JOB_STATE_INVALID = -1
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering};
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poetteringenum JobMode {
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_FAIL, /* Fail if a conflicting job is already queued */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_REPLACE, /* Replace an existing conflicting job */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_REPLACE_IRREVERSIBLY,/* Like JOB_REPLACE + produce irreversible jobs */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_ISOLATE, /* Start a unit, and stop all others */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_FLUSH, /* Flush out all other queued jobs when queing this one */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_IGNORE_DEPENDENCIES, /* Ignore both requirement and ordering dependencies */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_IGNORE_REQUIREMENTS, /* Ignore requirement dependencies */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering _JOB_MODE_MAX,
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering _JOB_MODE_INVALID = -1
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering};
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poetteringenum JobResult {
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_DONE, /* Job completed successfully */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_CANCELED, /* Job canceled by a conflicting job installation or by explicit cancel request */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_TIMEOUT, /* Job timeout elapsed */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_FAILED, /* Job failed */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_DEPENDENCY, /* A required dependency job did not result in JOB_DONE */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_SKIPPED, /* Negative result of JOB_VERIFY_ACTIVE */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_INVALID, /* JOB_RELOAD of inactive unit */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JOB_ASSERT, /* Couldn't start a unit, because an assert didn't hold */
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering JOB_UNSUPPORTED, /* Couldn't start a unit, because the unit type is not supported on the system */
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering _JOB_RESULT_MAX,
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering _JOB_RESULT_INVALID = -1
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering};
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering#include "unit.h"
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poetteringstruct JobDependency {
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering /* Encodes that the 'subject' job needs the 'object' job in
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering * some way. This structure is used only while building a transaction. */
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering Job *subject;
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering Job *object;
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering LIST_FIELDS(JobDependency, subject);
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering LIST_FIELDS(JobDependency, object);
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering bool matters;
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering bool conflicts;
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering};
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poetteringstruct Job {
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering Manager *manager;
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering Unit *unit;
c01ff965b48bb9693dcd77cbc748b5d8676766b0Lennart Poettering
d3152a09ac5804ec8603daee12f98cf03523cce0Lennart Poettering LIST_FIELDS(Job, transaction);
d3152a09ac5804ec8603daee12f98cf03523cce0Lennart Poettering LIST_FIELDS(Job, run_queue);
d3152a09ac5804ec8603daee12f98cf03523cce0Lennart Poettering LIST_FIELDS(Job, dbus_queue);
d3152a09ac5804ec8603daee12f98cf03523cce0Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering LIST_HEAD(JobDependency, subject_list);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering LIST_HEAD(JobDependency, object_list);
e70bc43cdf75b36e7ad3d29e9a6f8ee1461e7d5eLennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering /* Used for graph algs as a "I have been here" marker */
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering Job* marker;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering unsigned generation;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering uint32_t id;
49af9e1368571f4e423cde0fd45ee284451434d1Lennart Poettering
49af9e1368571f4e423cde0fd45ee284451434d1Lennart Poettering JobType type;
49af9e1368571f4e423cde0fd45ee284451434d1Lennart Poettering JobState state;
49af9e1368571f4e423cde0fd45ee284451434d1Lennart Poettering
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering sd_event_source *timer_event_source;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering usec_t begin_usec;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering /*
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering * This tracks where to send signals, and also which clients
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering * are allowed to call DBus methods on the job (other than
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering * root).
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering *
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering * There can be more than one client, because of job merging.
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering */
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering sd_bus_track *clients;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering char **deserialized_clients;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering JobResult result;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering bool installed:1;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering bool in_run_queue:1;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering bool matters_to_anchor:1;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering bool in_dbus_queue:1;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering bool sent_dbus_new_signal:1;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering bool ignore_order:1;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering bool irreversible:1;
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering};
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering
72c3897f77a7352618ea76b880a6764f52d6327bLennart PoetteringJob* job_new(Unit *unit, JobType type);
72c3897f77a7352618ea76b880a6764f52d6327bLennart PoetteringJob* job_new_raw(Unit *unit);
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poetteringvoid job_free(Job *job);
72c3897f77a7352618ea76b880a6764f52d6327bLennart PoetteringJob* job_install(Job *j);
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poetteringint job_install_deserialized(Job *j);
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poetteringvoid job_uninstall(Job *j);
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poetteringvoid job_dump(Job *j, FILE*f, const char *prefix);
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poetteringint job_serialize(Job *j, FILE *f, FDSet *fds);
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poetteringint job_deserialize(Job *j, FILE *f, FDSet *fds);
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poetteringint job_coldplug(Job *j);
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart PoetteringJobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts);
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poetteringvoid job_dependency_free(JobDependency *l);
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poetteringint job_merge(Job *j, Job *other);
72c3897f77a7352618ea76b880a6764f52d6327bLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart PoetteringJobType job_type_lookup_merge(JobType a, JobType b) _pure_;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering_pure_ static inline bool job_type_is_mergeable(JobType a, JobType b) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 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);
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_;
int job_get_timeout(Job *j, uint64_t *timeout) _pure_;
const char* job_type_to_access_method(JobType t);