LCOV - code coverage report
Current view: top level - core - job.h (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 4 10 40.0 %
Date: 2015-07-29 18:47:03 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : #pragma once
       4             : 
       5             : /***
       6             :   This file is part of systemd.
       7             : 
       8             :   Copyright 2010 Lennart Poettering
       9             : 
      10             :   systemd is free software; you can redistribute it and/or modify it
      11             :   under the terms of the GNU Lesser General Public License as published by
      12             :   the Free Software Foundation; either version 2.1 of the License, or
      13             :   (at your option) any later version.
      14             : 
      15             :   systemd is distributed in the hope that it will be useful, but
      16             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      18             :   Lesser General Public License for more details.
      19             : 
      20             :   You should have received a copy of the GNU Lesser General Public License
      21             :   along with systemd; If not, see <http://www.gnu.org/licenses/>.
      22             : ***/
      23             : 
      24             : #include <stdbool.h>
      25             : 
      26             : typedef struct Job Job;
      27             : typedef struct JobDependency JobDependency;
      28             : typedef enum JobType JobType;
      29             : typedef enum JobState JobState;
      30             : typedef enum JobMode JobMode;
      31             : typedef enum JobResult JobResult;
      32             : 
      33             : /* Be careful when changing the job types! Adjust job_merging_table[] accordingly! */
      34             : enum JobType {
      35             :         JOB_START,                  /* if a unit does not support being started, we'll just wait until it becomes active */
      36             :         JOB_VERIFY_ACTIVE,
      37             : 
      38             :         JOB_STOP,
      39             : 
      40             :         JOB_RELOAD,                 /* if running, reload */
      41             : 
      42             :         /* Note that restarts are first treated like JOB_STOP, but
      43             :          * then instead of finishing are patched to become
      44             :          * JOB_START. */
      45             :         JOB_RESTART,                /* If running, stop. Then start unconditionally. */
      46             : 
      47             :         _JOB_TYPE_MAX_MERGING,
      48             : 
      49             :         /* JOB_NOP can enter into a transaction, but as it won't pull in
      50             :          * any dependencies and it uses the special 'nop_job' slot in Unit,
      51             :          * it won't have to merge with anything (except possibly into another
      52             :          * JOB_NOP, previously installed). JOB_NOP is special-cased in
      53             :          * job_type_is_*() functions so that the transaction can be
      54             :          * activated. */
      55             :         JOB_NOP = _JOB_TYPE_MAX_MERGING, /* do nothing */
      56             : 
      57             :         _JOB_TYPE_MAX_IN_TRANSACTION,
      58             : 
      59             :         /* JOB_TRY_RESTART can never appear in a transaction, because
      60             :          * it always collapses into JOB_RESTART or JOB_NOP before entering.
      61             :          * Thus we never need to merge it with anything. */
      62             :         JOB_TRY_RESTART = _JOB_TYPE_MAX_IN_TRANSACTION, /* if running, stop and then start */
      63             : 
      64             :         /* JOB_RELOAD_OR_START won't enter into a transaction and cannot result
      65             :          * from transaction merging (there's no way for JOB_RELOAD and
      66             :          * JOB_START to meet in one transaction). It can result from a merge
      67             :          * during job installation, but then it will immediately collapse into
      68             :          * one of the two simpler types. */
      69             :         JOB_RELOAD_OR_START,        /* if running, reload, otherwise start */
      70             : 
      71             :         _JOB_TYPE_MAX,
      72             :         _JOB_TYPE_INVALID = -1
      73             : };
      74             : 
      75             : enum JobState {
      76             :         JOB_WAITING,
      77             :         JOB_RUNNING,
      78             :         _JOB_STATE_MAX,
      79             :         _JOB_STATE_INVALID = -1
      80             : };
      81             : 
      82             : enum JobMode {
      83             :         JOB_FAIL,                /* Fail if a conflicting job is already queued */
      84             :         JOB_REPLACE,             /* Replace an existing conflicting job */
      85             :         JOB_REPLACE_IRREVERSIBLY,/* Like JOB_REPLACE + produce irreversible jobs */
      86             :         JOB_ISOLATE,             /* Start a unit, and stop all others */
      87             :         JOB_FLUSH,               /* Flush out all other queued jobs when queing this one */
      88             :         JOB_IGNORE_DEPENDENCIES, /* Ignore both requirement and ordering dependencies */
      89             :         JOB_IGNORE_REQUIREMENTS, /* Ignore requirement dependencies */
      90             :         _JOB_MODE_MAX,
      91             :         _JOB_MODE_INVALID = -1
      92             : };
      93             : 
      94             : enum JobResult {
      95             :         JOB_DONE,                /* Job completed successfully */
      96             :         JOB_CANCELED,            /* Job canceled by a conflicting job installation or by explicit cancel request */
      97             :         JOB_TIMEOUT,             /* Job timeout elapsed */
      98             :         JOB_FAILED,              /* Job failed */
      99             :         JOB_DEPENDENCY,          /* A required dependency job did not result in JOB_DONE */
     100             :         JOB_SKIPPED,             /* Negative result of JOB_VERIFY_ACTIVE */
     101             :         JOB_INVALID,             /* JOB_RELOAD of inactive unit */
     102             :         JOB_ASSERT,              /* Couldn't start a unit, because an assert didn't hold */
     103             :         JOB_UNSUPPORTED,         /* Couldn't start a unit, because the unit type is not supported on the system */
     104             :         _JOB_RESULT_MAX,
     105             :         _JOB_RESULT_INVALID = -1
     106             : };
     107             : 
     108             : #include "sd-event.h"
     109             : #include "unit.h"
     110             : #include "list.h"
     111             : 
     112             : struct JobDependency {
     113             :         /* Encodes that the 'subject' job needs the 'object' job in
     114             :          * some way. This structure is used only while building a transaction. */
     115             :         Job *subject;
     116             :         Job *object;
     117             : 
     118             :         LIST_FIELDS(JobDependency, subject);
     119             :         LIST_FIELDS(JobDependency, object);
     120             : 
     121             :         bool matters;
     122             :         bool conflicts;
     123             : };
     124             : 
     125             : struct Job {
     126             :         Manager *manager;
     127             :         Unit *unit;
     128             : 
     129             :         LIST_FIELDS(Job, transaction);
     130             :         LIST_FIELDS(Job, run_queue);
     131             :         LIST_FIELDS(Job, dbus_queue);
     132             : 
     133             :         LIST_HEAD(JobDependency, subject_list);
     134             :         LIST_HEAD(JobDependency, object_list);
     135             : 
     136             :         /* Used for graph algs as a "I have been here" marker */
     137             :         Job* marker;
     138             :         unsigned generation;
     139             : 
     140             :         uint32_t id;
     141             : 
     142             :         JobType type;
     143             :         JobState state;
     144             : 
     145             :         sd_event_source *timer_event_source;
     146             :         usec_t begin_usec;
     147             : 
     148             :         /*
     149             :          * This tracks where to send signals, and also which clients
     150             :          * are allowed to call DBus methods on the job (other than
     151             :          * root).
     152             :          *
     153             :          * There can be more than one client, because of job merging.
     154             :          */
     155             :         sd_bus_track *clients;
     156             :         char **deserialized_clients;
     157             : 
     158             :         JobResult result;
     159             : 
     160             :         bool installed:1;
     161             :         bool in_run_queue:1;
     162             :         bool matters_to_anchor:1;
     163             :         bool override:1;
     164             :         bool in_dbus_queue:1;
     165             :         bool sent_dbus_new_signal:1;
     166             :         bool ignore_order:1;
     167             :         bool irreversible:1;
     168             : };
     169             : 
     170             : Job* job_new(Unit *unit, JobType type);
     171             : Job* job_new_raw(Unit *unit);
     172             : void job_free(Job *job);
     173             : Job* job_install(Job *j);
     174             : int job_install_deserialized(Job *j);
     175             : void job_uninstall(Job *j);
     176             : void job_dump(Job *j, FILE*f, const char *prefix);
     177             : int job_serialize(Job *j, FILE *f, FDSet *fds);
     178             : int job_deserialize(Job *j, FILE *f, FDSet *fds);
     179             : int job_coldplug(Job *j);
     180             : 
     181             : JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts);
     182             : void job_dependency_free(JobDependency *l);
     183             : 
     184             : int job_merge(Job *j, Job *other);
     185             : 
     186             : JobType job_type_lookup_merge(JobType a, JobType b) _pure_;
     187             : 
     188        1413 : _pure_ static inline bool job_type_is_mergeable(JobType a, JobType b) {
     189        1413 :         return job_type_lookup_merge(a, b) >= 0;
     190             : }
     191             : 
     192          83 : _pure_ static inline bool job_type_is_conflicting(JobType a, JobType b) {
     193          83 :         return a != JOB_NOP && b != JOB_NOP && !job_type_is_mergeable(a, b);
     194             : }
     195             : 
     196           0 : _pure_ static inline bool job_type_is_superset(JobType a, JobType b) {
     197             :         /* Checks whether operation a is a "superset" of b in its actions */
     198           0 :         if (b == JOB_NOP)
     199           0 :                 return true;
     200           0 :         if (a == JOB_NOP)
     201           0 :                 return false;
     202           0 :         return a == job_type_lookup_merge(a, b);
     203             : }
     204             : 
     205             : bool job_type_is_redundant(JobType a, UnitActiveState b) _pure_;
     206             : 
     207             : /* Collapses a state-dependent job type into a simpler type by observing
     208             :  * the state of the unit which it is going to be applied to. */
     209             : JobType job_type_collapse(JobType t, Unit *u);
     210             : 
     211             : int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u);
     212             : 
     213             : void job_add_to_run_queue(Job *j);
     214             : void job_add_to_dbus_queue(Job *j);
     215             : 
     216             : int job_start_timer(Job *j);
     217             : 
     218             : int job_run_and_invalidate(Job *j);
     219             : int job_finish_and_invalidate(Job *j, JobResult result, bool recursive);
     220             : 
     221             : char *job_dbus_path(Job *j);
     222             : 
     223             : void job_shutdown_magic(Job *j);
     224             : 
     225             : const char* job_type_to_string(JobType t) _const_;
     226             : JobType job_type_from_string(const char *s) _pure_;
     227             : 
     228             : const char* job_state_to_string(JobState t) _const_;
     229             : JobState job_state_from_string(const char *s) _pure_;
     230             : 
     231             : const char* job_mode_to_string(JobMode t) _const_;
     232             : JobMode job_mode_from_string(const char *s) _pure_;
     233             : 
     234             : const char* job_result_to_string(JobResult t) _const_;
     235             : JobResult job_result_from_string(const char *s) _pure_;
     236             : 
     237             : int job_get_timeout(Job *j, uint64_t *timeout) _pure_;

Generated by: LCOV version 1.11