You were right, @tomp. Running the above command gave me nothing when I activated suspend. I believe I’ve figured this out now. I’ve confirmed that resolvectl commands do not survive suspend cycles, as systemd-resolved seems to go down during the sleep event.
Just to verify, I also tried to change the per-link dns settings for a virbr0 bridge I had laying around from the dark times before I installed lxd. This confirmed that the resolved service loses those per-link settings regardless of the bridge.
sudo resolvectl dns 1.1.1.1 virbr0
sudo resolvectl status virbr0 # confirms it was set
sudo resolvectl dns lxdbr0 1.1.1.1
sudo resolvectl status lxdbr0 # also confirms it was set
sudo systemctl suspend
# both of the devices have lost their dns settings
sudo resolvectl status lxdbr0
sudo resolvectl status virbr0
Then I turned on debugging for resolved and found that the recommended systemd unit was getting activated just moments before systemd-resolved did its reinitialization process after wakeup.
Turning on debugging:
# I followed wiki.ubuntu.com/DebuggingSystemd
sudo systemctl edit --runtime systemd-resolved
# Added the following to turn on debugging:
# [Service]
# Environment=SYSTEMD_LOG_LEVEL=debug
sudo systemctl daemon-reload
sudo systemctl restart systemd-resolved
Here’s the race condition in the logs:
Jun 28 10:51:55 $hostname systemd[1]: systemd-suspend.service: Succeeded.
Jun 28 10:51:55 $hostname systemd[1]: Finished Suspend.
Jun 28 10:51:55 $hostname systemd[1]: Stopped target Sleep.
Jun 28 10:51:55 $hostname systemd[1]: Reached target Suspend.
Jun 28 10:51:55 $hostname systemd[1]: Starting LXD per-link DNS configuration for lxdbr0...
Jun 28 10:51:55 $hostname kernel: [ 2935.503384] audit: type=1107 audit(1656427915.699:173): pid=1974 uid=103 auid=4294967295 ses=4294967295 subj=unconfined msg='apparmor="DENIED" operation="dbus_signal" bus="system" path="/org/freedesktop/login1"
Jun 28 10:51:55 $hostname kernel: [ 2935.503384] exe="/usr/bin/dbus-daemon" sauid=103 hostname=? addr=? terminal=?'
Jun 28 10:51:55 $hostname systemd[1]: Stopped target Suspend.
Jun 28 10:51:55 $hostname ModemManager[2076]: <info> [sleep-monitor] system is resuming
Jun 28 10:51:55 $hostname systemd-resolved[10667]: Got message type=signal sender=:1.25 destination=n/a path=/org/freedesktop/login1 interface=org.freedesktop.login1.Manager member=PrepareForSleep cookie=427 reply_cookie=0 signature=b error-name=n/a error-message=n/a
Jun 28 10:51:55 $hostname systemd-resolved[10667]: Coming back from suspend, verifying all RRs...
So now I’ve just added a healthy buffer to the unit to avoid this race condition:
[Unit]
Description=LXD per-link DNS configuration for lxdbr0
BindsTo=sys-subsystem-net-devices-lxdbr0.device
After=sys-subsystem-net-devices-lxdbr0.device suspend.target
[Service]
Type=oneshot
ExecStart=/usr/bin/sleep 15
ExecStart=/usr/bin/resolvectl dns lxdbr0 10.0.10.1
ExecStart=/usr/bin/resolvectl domain lxdbr0 '~lxd'
[Install]
WantedBy=sys-subsystem-net-devices-lxdbr0.device suspend.target
You may want to mention this on the page for systemd integration. E.g. something like:
Hibernate and Suspend Behavior
When running LXD in a desktop environment, it may be common to suspend or hibernate the system. The previous configuration will not survive the wake from sleep, but adding suspend.target, hibernate.target, hybrid-sleep.target, and/or suspend-then-hibernate.target in the After=
field will re-run the script as the system comes back online.
During the resume process, it is possible that the unit will run before the systemd-resolved service completes its post-wake initialization. One simple way to avoid this is by adding a small wait before the resolvectl commands are run, e.g.
[Service]
Type=oneshot
ExecStart=/usr/bin/sleep 5
ExecStart=/usr/bin/resolvectl dns lxdbr0 10.0.10.1
ExecStart=/usr/bin/resolvectl domain lxdbr0 '~lxd'