Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable service activation from dbus-broker while dbus-broker.service is deactivating #26799

Closed
Geass-LL opened this issue Mar 14, 2023 · 2 comments · Fixed by #27579
Closed
Labels
pid1 RFE 🎁 Request for Enhancement, i.e. a feature request

Comments

@Geass-LL
Copy link
Contributor

Component

systemd

Is your feature request related to a problem? Please describe

I'm using systemctl isolate reboot.target to reboot the system. But since I changed the default D-Bus daemon from dbus-daemon to dbus-broker, the reboot process is always terminated. This is because NetworkManager.service will activate NetworkManager-dispatcher.service when it is stopped, and this start job makes many stop jobs canceled.

I'm curious why this NetworkManager-dispatcher.service start job was not generated when I use dbus-daemon, and find systemd will refuse this job when dbus-daemon is shutting down in signal_activation_request(). But this doesn't work on dbus-broker, because dbus-broker uses StartUnit methon_call directly instead of ActivationRequest signal. See https://github.com/bus1/dbus-broker/blame/main/NEWS.md#L693. systemd seems doesn't have similar code for dbus-broker.

Describe the solution you'd like

I want systemd to refuse the service activation while dbus-broker.service is deactivating.

Describe alternatives you've considered

I have considered 2 alternatives:

  1. Broadcasting signal DBusDeactivating so dbus-broker knows it will be stopped, and dbus-broker can refuse the StartUnit message.

  2. Check the state of dbus-broker and the the type of service waitting to be activated, if dbus-broker is deactivating, systemd refuses to activate Type=dbus services.

The systemd version you checked that didn't have the feature you are asking for

No response

@Geass-LL Geass-LL added the RFE 🎁 Request for Enhancement, i.e. a feature request label Mar 14, 2023
@github-actions github-actions bot added the pid1 label Mar 14, 2023
@poettering
Copy link
Member

This is because NetworkManager.service will activate NetworkManager-dispatcher.service when it is stopped, and this start job makes many stop jobs canceled.

Hmm? it does what? it starts new services during shutdown? it really shouldn't do that. This is what should be fixed.

@poettering
Copy link
Member

2. Check the state of dbus-broker and the the type of service waitting to be activated, if dbus-broker is deactivating, systemd refuses to activate Type=dbus services.

this sounds better to me actually. but yuck, nm shouldn't do what it is doing. starting up a lot of infra when shutting down, reversing the shutdown transaction is just a bad idea.

YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 8, 2023
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 8, 2023
dbus-broker issues StartUnit directly for activation requests,
so let's add a check on bus state in bus_unit_queue_job to refuse
that if dbus is not running.

Replaces systemd#27570
Closes systemd#26799
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 8, 2023
dbus-broker issues StartUnit directly for activation requests,
so let's add a check on bus state in bus_unit_queue_job to refuse
that if dbus is not running.

Replaces systemd#27570
Closes systemd#26799
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 8, 2023
dbus-broker issues StartUnit directly for activation requests,
so let's add a check on bus state in bus_unit_queue_job to refuse
that if dbus is not running.

Replaces systemd#27570
Closes systemd#26799
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 8, 2023
dbus-broker issues StartUnit directly for activation requests,
so let's add a check on bus state in bus_unit_queue_job to refuse
that if dbus is not running.

Replaces systemd#27570
Closes systemd#26799
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 8, 2023
dbus-broker issues StartUnit directly for activation requests,
so let's add a check on bus state in bus_unit_queue_job to refuse
that if dbus is not running.

Replaces systemd#27570
Closes systemd#26799
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 8, 2023
dbus-broker issues StartUnit directly for activation requests,
so let's add a check on bus state in bus_unit_queue_job to refuse
that if dbus is not running.

Replaces systemd#27570
Closes systemd#26799
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 8, 2023
dbus-broker issues StartUnit directly for activation requests,
so let's add a check on bus state in bus_unit_queue_job to refuse
that if dbus is not running.

Replaces systemd#27570
Closes systemd#26799
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 11, 2023
Follow-up for systemd#27579

In systemd#27579 we refused all StartUnit requests for Type=dbus units
if dbus is not running, which means if dbus is manually stopped,
user can't use systemctl to start Type=dbus units again, which
is incorrect.

The culprit that leads to the cancellation of the whole transaction
mentioned in systemd#26799 is job type conflict on dbus. On the other hand,
if the stop job is already running, or dbus is already inactive,
everything should be fine. So let's relax the restriction and only
refuse job enqueue if dbus has a pending stop job.

To summerize, the case we want to avoid is:

1. dbus has a pending stop job
2. StartUnit/ActivationRequest is received
3. Type=dbus service gets started, which has Requires=dbus.socket
4. dbus is pulled in again, resulting in job type conflict

What we can support is:

1. dbus is already stopping (in UNIT_DEACTIVATING)
2. StartUnit is received (possibly through systemctl, i.e. private bus)
3. Type=dbus service gets started, and will wait for running jobs for
   dbus to complete
4. dbus is started again, and Type=dbus service follows

Fixes systemd#27588
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 11, 2023
Follow-up for systemd#27579

In systemd#27579 we refused all StartUnit requests for Type=dbus units
if dbus is not running, which means if dbus is manually stopped,
user can't use systemctl to start Type=dbus units again, which
is incorrect.

The only culprit that leads to the cancellation of the whole
transaction mentioned in systemd#26799 is job type conflict on dbus.
In other words, if the stop job is already running, or dbus
is already inactive, everything should be fine. So let's relax
the restriction and only refuse job enqueuing if dbus has
a *pending* stop job.

To summarize, the case we want to avoid is:

1. dbus has a pending stop job
2. StartUnit/ActivationRequest is received
3. Type=dbus service gets started, which has Requires=dbus.socket
4. dbus is pulled in again, resulting in job type conflict

What we can support is:

1. dbus is already stopping (in UNIT_DEACTIVATING)
2. StartUnit is received (possibly through systemctl, i.e. on private bus)
3. Type=dbus service gets started, and will wait for running jobs for
   dbus to complete
4. dbus is started again, thus the Type=dbus service

Fixes systemd#27588
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 11, 2023
Follow-up for systemd#27579

In systemd#27579 we refused all StartUnit requests for Type=dbus units
if dbus is not running, which means if dbus is manually stopped,
user can't use systemctl to start Type=dbus units again, which
is incorrect.

The only culprit that leads to the cancellation of the whole
transaction mentioned in systemd#26799 is job type conflict on dbus.
In other words, if the stop job is already running, or dbus
is already inactive, everything should be fine. So let's relax
the restriction and only refuse job enqueuing if dbus has
a *pending* stop job.

To summarize, the case we want to avoid is:

1. dbus has a pending stop job
2. StartUnit/ActivationRequest is received
3. Type=dbus service gets started, which has Requires=dbus.socket
4. dbus is pulled in again, resulting in job type conflict

What we can support is:

1. dbus is already stopping (in UNIT_DEACTIVATING)
2. StartUnit is received (possibly through systemctl, i.e. on private bus)
3. Type=dbus service gets started, and will wait for running jobs for
   dbus to complete
4. dbus is started again, thus the Type=dbus service

Fixes systemd#27588
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 11, 2023
Follow-up for systemd#27579

In systemd#27579 we refused all StartUnit requests for Type=dbus units
if dbus is not running, which means if dbus is manually stopped,
user can't use systemctl to start Type=dbus units again, which
is incorrect.

The only culprit that leads to the cancellation of the whole
transaction mentioned in systemd#26799 is job type conflict on dbus.
So let's relax the restriction and only refuse job enqueuing
if dbus has a stop job.

To summarize, the case we want to avoid is:

1. dbus has a stop job installed
2. StartUnit/ActivationRequest is received
3. Type=dbus service gets started, which has Requires=dbus.socket
4. dbus is pulled in again, resulting in job type conflict

What we can support is:

1. dbus is already stopped
2. StartUnit is received (possibly through systemctl, i.e. on private bus)
3. Type=dbus service gets started
4. dbus is started again, thus the Type=dbus service

Replaces systemd#27590
Fixes systemd#27588
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 11, 2023
Follow-up for systemd#27579

In systemd#27579 we refused all StartUnit requests for Type=dbus units
if dbus is not running, which means if dbus is manually stopped,
user can't use systemctl to start Type=dbus units again, which
is incorrect.

The only culprit that leads to the cancellation of the whole
transaction mentioned in systemd#26799 is job type conflict on dbus.
So let's relax the restriction and only refuse job enqueuing
if dbus has a stop job.

To summarize, the case we want to avoid is:

1. dbus has a stop job installed
2. StartUnit/ActivationRequest is received
3. Type=dbus service gets started, which has Requires=dbus.socket
4. dbus is pulled in again, resulting in job type conflict

What we can support is:

1. dbus is already stopped
2. StartUnit is received (possibly through systemctl, i.e. on private bus)
3. Type=dbus service gets started, which will wait for dbus to start
4. dbus is started again, thus the job for Type=dbus service

Replaces systemd#27590
Fixes systemd#27588
YHNdnzj added a commit to YHNdnzj/systemd that referenced this issue May 12, 2023
Follow-up for systemd#27579

In systemd#27579 we refused all StartUnit requests for Type=dbus units
if dbus is not running, which means if dbus is manually stopped,
user can't use systemctl to start Type=dbus units again, which
is incorrect.

The only culprit that leads to the cancellation of the whole
transaction mentioned in systemd#26799 is job type conflict on dbus.
So let's relax the restriction and only refuse job enqueuing
if dbus has a stop job.

To summarize, the case we want to avoid is:

1. dbus has a stop job installed
2. StartUnit/ActivationRequest is received
3. Type=dbus service gets started, which has Requires=dbus.socket
4. dbus is pulled in again, resulting in job type conflict

What we can support is:

1. dbus is already stopped
2. StartUnit is received (possibly through systemctl, i.e. on private bus)
3. Type=dbus service gets started, which will wait for dbus to start
4. dbus is started again, thus the job for Type=dbus service

Replaces systemd#27590
Fixes systemd#27588
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pid1 RFE 🎁 Request for Enhancement, i.e. a feature request
2 participants