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
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) {
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;
#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"
#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);
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 */