mirror of
https://github.com/morgan9e/systemd
synced 2026-04-13 16:04:28 +09:00
core: record transactions that have seen ordering cycles
This commit is contained in:
@@ -938,11 +938,12 @@ Defined-By: systemd
|
||||
Support: %SUPPORT_URL%
|
||||
Documentation: man:systemd(1)
|
||||
|
||||
A unit transaction was initiated that contains an ordering cycle, i.e. some
|
||||
unit that was requested to be started (either directly, or indirectly due to a
|
||||
requirement dependency such as Wants= or Requires=) is ordered before some
|
||||
other unit (via After=/Before=), but that latter unit is also ordered before
|
||||
the former by some dependency (either directly or indirectly).
|
||||
A unit transaction (with ID @TRANSACTION_ID@) was initiated that contains
|
||||
an ordering cycle, i.e. some unit that was requested to be started
|
||||
(either directly, or indirectly due to a requirement dependency such as
|
||||
Wants= or Requires=) is ordered before some other unit (via After=/Before=),
|
||||
but that latter unit is also ordered before the former by some dependency
|
||||
(either directly or indirectly).
|
||||
|
||||
Ordering cycles consist of at least two units, but might involve many
|
||||
more. They generally indicate a bug in the unit definitions, as a unit
|
||||
|
||||
@@ -1659,6 +1659,8 @@ static void manager_clear_jobs_and_units(Manager *m) {
|
||||
m->n_running_jobs = 0;
|
||||
m->n_installed_jobs = 0;
|
||||
m->n_failed_jobs = 0;
|
||||
|
||||
m->transactions_with_cycle = set_free(m->transactions_with_cycle);
|
||||
}
|
||||
|
||||
Manager* manager_free(Manager *m) {
|
||||
|
||||
@@ -238,6 +238,9 @@ typedef struct Manager {
|
||||
|
||||
uint64_t last_transaction_id;
|
||||
|
||||
/* IDs of transactions that once encountered ordering cycle */
|
||||
Set *transactions_with_cycle;
|
||||
|
||||
sd_event_source *run_queue_event_source;
|
||||
|
||||
char *notify_socket;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "bus-common-errors.h"
|
||||
#include "bus-error.h"
|
||||
#include "dbus-unit.h"
|
||||
#include "hash-funcs.h"
|
||||
#include "manager.h"
|
||||
#include "set.h"
|
||||
#include "slice.h"
|
||||
@@ -15,6 +16,8 @@
|
||||
#include "strv.h"
|
||||
#include "transaction.h"
|
||||
|
||||
#define CYCLIC_TRANSACTIONS_MAX 4096U
|
||||
|
||||
static bool job_matters_to_anchor(Job *job);
|
||||
static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies);
|
||||
|
||||
@@ -399,6 +402,16 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
|
||||
LOG_MESSAGE_ID(SD_MESSAGE_UNIT_ORDERING_CYCLE_STR),
|
||||
LOG_ITEM("%s", strempty(unit_ids)));
|
||||
|
||||
if (set_size(j->manager->transactions_with_cycle) >= CYCLIC_TRANSACTIONS_MAX)
|
||||
log_warning("Too many transactions with ordering cycle, suppressing record.");
|
||||
else {
|
||||
uint64_t *id_buf = newdup(uint64_t, &tr->id, 1);
|
||||
if (!id_buf)
|
||||
log_oom_warning();
|
||||
else
|
||||
(void) set_ensure_consume(&j->manager->transactions_with_cycle, &uint64_hash_ops_value_free, id_buf);
|
||||
}
|
||||
|
||||
if (delete) {
|
||||
const char *status;
|
||||
/* logging for j not k here to provide a consistent narrative */
|
||||
|
||||
Reference in New Issue
Block a user