core/transaction: assign unique ids to transactions and encode them in log
Preparation for later commits, but I think this one makes a ton of sense on its own. When debug logging is enabled it's otherwise difficult to dig up the portion of journal for transaction construction.
This commit is contained in:
@@ -92,6 +92,8 @@ int manager_serialize(
|
||||
|
||||
_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);
|
||||
@@ -325,7 +327,15 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
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)
|
||||
|
||||
+10
-6
@@ -2153,14 +2153,16 @@ int manager_add_job_full(
|
||||
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,
|
||||
@@ -2247,18 +2249,20 @@ int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name,
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@@ -236,6 +236,8 @@ typedef struct Manager {
|
||||
/* 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;
|
||||
|
||||
+12
-8
@@ -1235,20 +1235,24 @@ int transaction_add_triggering_jobs(Transaction *tr, Unit *u) {
|
||||
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);
|
||||
return NULL;
|
||||
|
||||
tr->irreversible = irreversible;
|
||||
|
||||
return tr;
|
||||
return TAKE_PTR(tr);
|
||||
}
|
||||
|
||||
Transaction* transaction_free(Transaction *tr) {
|
||||
|
||||
@@ -8,9 +8,11 @@ typedef struct Transaction {
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user