Skip to content

varlink: add varlink interface for syncing fwupd capsule updates across ESPs - #1138

Open
Rolv-Apneseth wants to merge 1 commit into
coreos:mainfrom
Rolv-Apneseth:varlink
Open

varlink: add varlink interface for syncing fwupd capsule updates across ESPs#1138
Rolv-Apneseth wants to merge 1 commit into
coreos:mainfrom
Rolv-Apneseth:varlink

Conversation

@Rolv-Apneseth

Copy link
Copy Markdown
Member

This is related to coreos/fedora-coreos-tracker#1623, and adds a varlink interface that fwupd can use to tell bootupd to sync firmware capsule updates to other co-located ESPs for our RAID setups (redundant ESPs).

There is already a related fwupd PR, which @hughsie built against a copr project I created. The tests included here should confirm we're working as intended though.

The way it works is it accepts a partuuid of the device the update was written to, and a capsule_dir with the relative path to the update dir on the device, and syncs those updates across co-located ESPs by mounting each in turn. On my system, I can interact with the interface like this:

sudo dnf copr enable rapneset/bootupd-varlink
sudo dnf install bootupd-0.3d32bdb --repo 'copr:copr.fedorainfracloud.org:rapneset:bootupd-varlink'
sudo systemctl start bootupd-varlink.socket
sudo varlinkctl call /run/bootupd/org.coreos.bootupd1 \
  org.coreos.bootupd1.SyncFwupdUpdates \
  '{"partuuid": "2e126947-2730-49df-af3f-012de73bccfd", "capsule_dir": "EFI/fedora/fw"}'

Couple notes:

  • Put the varlink subcommand under bootupd since it shouldn't be user-facing
  • Implemented a simple service first, but now I'm leaning mostly towards socket-activated (both currently implemented)
  • Socket will need to be enabled in fedora-coreos-config. We'll also need to have udisks2 for fwupd to work as intended.
  • I haven't made any updates to the readme just yet - waiting to see if we want to make any changes to the approach here
  • RAID tests are divided by architecture just like the raid1-boot tests
  • Since zlink required an async runtime, I chose smol as a lightweight option

@Rolv-Apneseth

Copy link
Copy Markdown
Member Author

CI failures related to coreos/fedora-coreos-config#4261

@Rolv-Apneseth

Copy link
Copy Markdown
Member Author

I'll include a quick note on why we even need this:

Typical RAID setups only have a single ESP, but CoreOS duplicates the ESP as plain vfat partitions across all disks, which are all updated by bootupd (and hence kept in "sync"). If fwupd places capsule updates on one ESP, the firmware will only process them from the ESP on the boot disk. By syncing capsules to all co-located ESPs, we ensure the firmware update applies regardless of which disk the system boots from.

%{_prefix}/lib/bootupd/grub2-static/
%{_unitdir}/bootloader-update.service
%{_unitdir}/bootupd-varlink.socket
%{_unitdir}/bootupd-varlink.service

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it'd be nice to have systemd units enforce locking.

So we have a single bootupd.service and change bootloader-update.service to actually call into the varlink API too, which would activate that service in the same way.

Alternatively, do we actually need a .socket unit? What we did in e.g. varlink for https://github.com/bootc-dev/bcvk/ is that it remains a CLI that has an interface one forks that enables varlink.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Current state should work without a socket unit actually, so just bootupd varlink will run it's own daemon. I don't quite understand the suggestion for a single bootupd.service though, would you mind clarifying? If we're gonna have a service anyway why not let systemd handle the socket? I don't have a strong opinion on this and initially leaned towards a simple service at first but the PR over on fwupd assumed it was socket-activated so I shifted that direction.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks for taking a look by the way @cgwalters

Comment thread src/varlink.rs
bootupd::list_dev_current_root, efi::Efi, freezethaw::fsfreeze_thaw_cycle, model::SavedState,
};

const SOCKET_PATH: &str = "/run/bootupd/org.coreos.bootupd1";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See above re the socket

Comment thread src/varlink.rs

#[zlink::service(interface = "org.coreos.bootupd1")]
impl BootupdVarlinkService {
/// Sync capsule update files from a "primary" ESP to all colocated ESPs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this really be specific to capsules? Isn't the general use case here "I am some software that touched one of the ESPs, please sync the others"?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That's what I assumed at first, but @travier wanted just the "fwupd folder" in coreos/fedora-coreos-tracker#1623 (comment)

Type=simple
# It doesn't make sense to sync ESP updates in "Live" environments.
# https://github.com/coreos/fedora-coreos-tracker/issues/2136
ExecCondition=/bin/bash -c '[[ ! $(findmnt -n -o FSTYPE /sysroot) =~ ^(erofs|squashfs)$ ]]'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See above, if we changed bootloader-update.service then we could avoid copy-pasta this

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.

2 participants