Skip to content

Conversation

jlebon
Copy link
Member

@jlebon jlebon commented Mar 7, 2025

This effectively reverts ac1a919 ("boot: Add
ostree-finalize-staged.path").

A bug came in on the OCP side that demonstrates that the way things are setup right now is racy. If a reboot is triggered quickly after staging a deployment, the whole pipeline of:

  • ostree-finalize-staged.path, which triggers
  • ostree-finalize-staged.service, which triggers
  • ostree-finalize-staged-hold.service,

may not fully have happened before systemd isolates to reboot.target which will want to kill all pending jobs.

Just directly starting the systemd unit is less elegant but much more explicit and gets rid of any possible race because it's directly part of the staging operation.

Fixes: https://issues.redhat.com/browse/OCPBUGS-51150

Copy link

openshift-ci bot commented Mar 7, 2025

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@jlebon
Copy link
Member Author

jlebon commented Mar 7, 2025

Haven't really tested this yet. We should reproduce the race in that bug and sanity-check it fixes it before we do this.

@jlebon
Copy link
Member Author

jlebon commented Mar 7, 2025

Of course, there's an argument to be made here that rebooting right after staging is silly since you could just as well have not used staging. But we also shouldn't be prone to races in the default deployment path.

This effectively reverts ac1a919 ("boot: Add
ostree-finalize-staged.path").

A bug came in on the OCP side that demonstrates that the way things are
setup right now is racy. If a reboot is triggered quickly after staging
a deployment, the whole pipeline of:

- ostree-finalize-staged.path, which triggers
- ostree-finalize-staged.service, which triggers
- ostree-finalize-staged-hold.service,

may not fully have happened before systemd isolates to `reboot.target`
which will want to kill all pending jobs.

Just directly starting the systemd unit is less elegant but much more
explicit and gets rid of any possible race because it's directly part of
the staging operation.

Fixes: https://issues.redhat.com/browse/OCPBUGS-51150
@jlebon jlebon force-pushed the pr/drop-finalize-staged-path branch from 1f10145 to 2b9912e Compare March 7, 2025 22:11
Copy link
Member

@cgwalters cgwalters left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's less risky if we only have the change in sysroot-deploy to synchronously start -finalize-staged.service. It shouldn't hurt to still have the .path unit attempting to also queue the start, right?

But, I dunno, I'm fine with this too, it is perhaps clearer to only have one way it's done.

@cgwalters
Copy link
Member

Of course, there's an argument to be made here that rebooting right after staging is silly since you could just as well have not used staging.

I wouldn't want to recommend that because it re-introduces the possibility of races if there's anything else running at the time that wants to serialize state to /etc (not that there should generally be such things, but still).

@cgwalters
Copy link
Member

But we also shouldn't be prone to races in the default deployment path.

IOW yes this - I think we should always use staging, and we should definitely fix this race.

(That said there is a longer term thing I think we talked about at some point by moving the finalization into the initramfs, i.e. pivoting back to the initramfs at shutdown, which would also have avoided any race like this)

@dbnicholson
Copy link
Member

I have nothing against this change, but how does it fix the race? Whether you trigger via a path systemd is monitoring or you call systemctl (which makes a dbus call), there's still a window between creating the staged deployment and enqueuing ostree-finalize-staged.service, isn't there?

I'd think that the only way to truly fix this issue would be to inhibit shutdown during the staging process.

@jlebon
Copy link
Member Author

jlebon commented Mar 8, 2025

I have nothing against this change, but how does it fix the race? Whether you trigger via a path systemd is monitoring or you call systemctl (which makes a dbus call), there's still a window between creating the staged deployment and enqueuing ostree-finalize-staged.service, isn't there?

We invoke systemctl start ostree-finalize-staged.service before we do the staging. The invocation will not return until the unit is active. So there's no longer a window during which we staged something and the service isn't already active.

(The more important fix in here though isn't really that we do it before, but just that we do it at all synchronously as part of the staging API call. That forces the client calling into it to not move on to initiating a reboot -- since it's likely the same software -- until we're guaranteed the service is active instead of relying on the path unit and its dependency tree to have kicked in.)

@jlebon
Copy link
Member Author

jlebon commented Mar 8, 2025

I think it's less risky if we only have the change in sysroot-deploy to synchronously start -finalize-staged.service. It shouldn't hurt to still have the .path unit attempting to also queue the start, right?

But, I dunno, I'm fine with this too, it is perhaps clearer to only have one way it's done.

Could go either way on this. I guess if we were to backport, I would agree it'd be less risky to just backport the systemctl start bit. Maybe I split this commit in two to make that easier? OTOH, I'm not sure it's worth backporting either. The workaround for the specific client affected here doesn't seem too painful.

@jlebon jlebon marked this pull request as ready for review March 10, 2025 19:22
@jlebon
Copy link
Member Author

jlebon commented Mar 10, 2025

OK, this is trivial to reproduce actually by just adding a dropin for ostree-finalize-staged.service with

[Service]
ExecStart=sleep 10

And indeed, this patch fixes the issue.

@cgwalters cgwalters enabled auto-merge March 10, 2025 19:29
@cgwalters cgwalters merged commit 8df797d into ostreedev:main Mar 10, 2025
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants