_cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
+ (void) serialize_item_format(f, "last-transaction-id", "%" PRIu64, m->last_transaction_id);
+
(void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id);
(void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs);
(void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs);
if (r == 0) /* eof or end marker */
break;
- if ((val = startswith(l, "current-job-id="))) {
+ if ((val = startswith(l, "last-transaction-id="))) {
+ uint64_t id;
+
+ if (safe_atou64(val, &id) < 0)
+ log_notice("Failed to parse last transaction id value '%s', ignoring.", val);
+ else
+ m->last_transaction_id = MAX(m->last_transaction_id, id);
+
+ } else if ((val = startswith(l, "current-job-id="))) {
uint32_t id;
if (safe_atou32(val, &id) < 0)
if (mode == JOB_RESTART_DEPENDENCIES && type != JOB_START)
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "--job-mode=restart-dependencies is only valid for start.");
+ tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY, ++m->last_transaction_id);
+ if (!tr)
+ return -ENOMEM;
+
+ LOG_CONTEXT_PUSHF("TRANSACTION_ID=%" PRIu64, tr->id);
+
log_unit_debug(unit, "Trying to enqueue job %s/%s/%s", unit->id, job_type_to_string(type), job_mode_to_string(mode));
type = job_type_collapse(type, unit);
- tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
- if (!tr)
- return -ENOMEM;
-
r = transaction_add_job_and_dependencies(
tr,
type,
}
int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error *e) {
- int r;
_cleanup_(transaction_abort_and_freep) Transaction *tr = NULL;
+ int r;
assert(m);
assert(unit);
assert(mode < _JOB_MODE_MAX);
assert(mode != JOB_ISOLATE); /* Isolate is only valid for start */
- tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
+ tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY, ++m->last_transaction_id);
if (!tr)
return -ENOMEM;
+ LOG_CONTEXT_PUSHF("TRANSACTION_ID=%" PRIu64, tr->id);
+
/* We need an anchor job */
r = transaction_add_job_and_dependencies(tr, JOB_NOP, unit, NULL, TRANSACTION_IGNORE_REQUIREMENTS|TRANSACTION_IGNORE_ORDER, e);
if (r < 0)
/* A set which contains all currently failed units */
Set *failed_units;
+ uint64_t last_transaction_id;
+
sd_event_source *run_queue_event_source;
char *notify_socket;
return 0;
}
-Transaction* transaction_new(bool irreversible) {
- Transaction *tr;
+Transaction* transaction_new(bool irreversible, uint64_t id) {
+ _cleanup_free_ Transaction *tr = NULL;
- tr = new0(Transaction, 1);
+ assert(id != 0);
+
+ tr = new(Transaction, 1);
if (!tr)
return NULL;
- tr->jobs = hashmap_new(NULL);
+ *tr = (Transaction) {
+ .jobs = hashmap_new(NULL),
+ .irreversible = irreversible,
+ .id = id,
+ };
if (!tr->jobs)
- return mfree(tr);
-
- tr->irreversible = irreversible;
+ return NULL;
- return tr;
+ return TAKE_PTR(tr);
}
Transaction* transaction_free(Transaction *tr) {
Hashmap *jobs; /* Unit object => Job object list 1:1 */
Job *anchor_job; /* The job the user asked for */
bool irreversible;
+
+ uint64_t id;
} Transaction;
-Transaction* transaction_new(bool irreversible);
+Transaction* transaction_new(bool irreversible, uint64_t id);
Transaction* transaction_free(Transaction *tr);
Transaction* transaction_abort_and_free(Transaction *tr);
DEFINE_TRIVIAL_CLEANUP_FUNC(Transaction*, transaction_abort_and_free);