mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +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%
|
Support: %SUPPORT_URL%
|
||||||
Documentation: man:systemd(1)
|
Documentation: man:systemd(1)
|
||||||
|
|
||||||
A unit transaction was initiated that contains an ordering cycle, i.e. some
|
A unit transaction (with ID @TRANSACTION_ID@) was initiated that contains
|
||||||
unit that was requested to be started (either directly, or indirectly due to a
|
an ordering cycle, i.e. some unit that was requested to be started
|
||||||
requirement dependency such as Wants= or Requires=) is ordered before some
|
(either directly, or indirectly due to a requirement dependency such as
|
||||||
other unit (via After=/Before=), but that latter unit is also ordered before
|
Wants= or Requires=) is ordered before some other unit (via After=/Before=),
|
||||||
the former by some dependency (either directly or indirectly).
|
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
|
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
|
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_running_jobs = 0;
|
||||||
m->n_installed_jobs = 0;
|
m->n_installed_jobs = 0;
|
||||||
m->n_failed_jobs = 0;
|
m->n_failed_jobs = 0;
|
||||||
|
|
||||||
|
m->transactions_with_cycle = set_free(m->transactions_with_cycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager* manager_free(Manager *m) {
|
Manager* manager_free(Manager *m) {
|
||||||
|
|||||||
@@ -238,6 +238,9 @@ typedef struct Manager {
|
|||||||
|
|
||||||
uint64_t last_transaction_id;
|
uint64_t last_transaction_id;
|
||||||
|
|
||||||
|
/* IDs of transactions that once encountered ordering cycle */
|
||||||
|
Set *transactions_with_cycle;
|
||||||
|
|
||||||
sd_event_source *run_queue_event_source;
|
sd_event_source *run_queue_event_source;
|
||||||
|
|
||||||
char *notify_socket;
|
char *notify_socket;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "bus-common-errors.h"
|
#include "bus-common-errors.h"
|
||||||
#include "bus-error.h"
|
#include "bus-error.h"
|
||||||
#include "dbus-unit.h"
|
#include "dbus-unit.h"
|
||||||
|
#include "hash-funcs.h"
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
#include "slice.h"
|
#include "slice.h"
|
||||||
@@ -15,6 +16,8 @@
|
|||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "transaction.h"
|
#include "transaction.h"
|
||||||
|
|
||||||
|
#define CYCLIC_TRANSACTIONS_MAX 4096U
|
||||||
|
|
||||||
static bool job_matters_to_anchor(Job *job);
|
static bool job_matters_to_anchor(Job *job);
|
||||||
static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies);
|
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_MESSAGE_ID(SD_MESSAGE_UNIT_ORDERING_CYCLE_STR),
|
||||||
LOG_ITEM("%s", strempty(unit_ids)));
|
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) {
|
if (delete) {
|
||||||
const char *status;
|
const char *status;
|
||||||
/* logging for j not k here to provide a consistent narrative */
|
/* logging for j not k here to provide a consistent narrative */
|
||||||
|
|||||||
Reference in New Issue
Block a user