chiark / gitweb /
core: fix assertion failure in checking a transaction with a JOB_NOP
authorMichal Schmidt <mschmidt@redhat.com>
Wed, 26 Nov 2014 15:33:43 +0000 (16:33 +0100)
committerMichal Schmidt <mschmidt@redhat.com>
Wed, 26 Nov 2014 15:33:43 +0000 (16:33 +0100)
Several functions called from transaction_activate() need to correctly
handle the case where a JOB_NOP job is being checked against a unit's
pending job. The assumption that JOB_NOP never merges with other job
types was correct, but since the job_type_is_*() functions are
implemented using the merge lookup, they need to special-case JOB_NOP
to avoid hitting assertion failures.

src/core/job.c
src/core/job.h

index 51d1581..1411603 100644 (file)
@@ -352,6 +352,9 @@ bool job_type_is_redundant(JobType a, UnitActiveState b) {
                 return
                         b == UNIT_ACTIVATING;
 
+        case JOB_NOP:
+                return true;
+
         default:
                 assert_not_reached("Invalid job type");
         }
index b7ebd8d..223ff9c 100644 (file)
@@ -49,9 +49,11 @@ enum JobType {
         _JOB_TYPE_MAX_MERGING,
 
         /* JOB_NOP can enter into a transaction, but as it won't pull in
-         * any dependencies, it won't have to merge with anything.
-         * job_install() avoids the problem of merging JOB_NOP too (it's
-         * special-cased, only merges with other JOB_NOPs). */
+         * any dependencies and it uses the special 'nop_job' slot in Unit,
+         * it won't have to merge with anything (except possibly into another
+         * JOB_NOP, previously installed). JOB_NOP is special-cased in
+         * job_type_is_*() functions so that the transaction can be
+         * activated. */
         JOB_NOP = _JOB_TYPE_MAX_MERGING, /* do nothing */
 
         _JOB_TYPE_MAX_IN_TRANSACTION,
@@ -191,11 +193,15 @@ _pure_ static inline bool job_type_is_mergeable(JobType a, JobType b) {
 }
 
 _pure_ static inline bool job_type_is_conflicting(JobType a, JobType b) {
-        return !job_type_is_mergeable(a, 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);
 }