[PATCH] spec: Do not disable some systemd units of newly split package

Andrea Bolognani abologna at redhat.com
Tue Jun 27 16:21:55 UTC 2023


On Mon, Jun 26, 2023 at 04:16:33PM -0600, Jim Fehlig wrote:
> On 6/26/23 10:06, Andrea Bolognani wrote:
> > The current logic in all packages' %post scriptlet basically
> > translates to: if installing the package from scratch, apply the
> > systemd presets; if upgrading, leave things well alone.
> >
> > What I would want the witness file to indicate would be:
> > libvirt-daemon is being upgraded, so when running the %post for
> > libvirt-daemon-proxy behave as in the upgrade scenario as opposed to
> > the install-from-scratch scenario.
>
> Is it enough to know that libvirt-daemon is being upgraded? Do we also need
> to know if libvirtd.service and any of the sockets are enabled? I think
> Martin already suggested a solution along these lines
>
> https://listman.redhat.com/archives/libvir-list/2023-June/240312.html

If we can detect this upgrade scenario reliably and behave
accordingly, I don't think looking at whether any specific service is
enabled or running would be necessary and, as I mentioned below, I
think this would make for an overall more solid approach. I'm just
still unclear on whether that's actually feasible :)

> > Detecting whether the monolithic libvirtd and its sockets are enabled
> > could also work, but feels more fragile. Specifically, it would not
> > cover the scenario described by Martin, where the deployment is a
> > split daemon one but with some units that are disabled by default
> > based on presets have been manually enabled by the admin.
>
> Nod. I even apologized to Martin in another response for getting bogged down
> on your issue :-).

I believe the two are actually one and the same, since they're both a
consequence of the package manager being convinced that virtproxyd
needs to be handled as a newly installed service when it's in fact
simply being upgraded.

> > I'm not sure this is entirely relevant, but just for completeness'
> > sake: in a monolithic daemon deployment, you want libvirtd.service in
> > addition to its sockets to be enabled. This is needed to make sure
> > domain autostart works as intended.
>
> Thanks for the reminder! BTW, does the same apply for virtnetworkd and
> virtstoraged, which also have resources that can be autostarted?

I'm actually not sure. The Fedora presets seem to indicate it does
not, but I can't really rule out that simply being a bug :)

> > > After updating to packages containing commit b1da03b5b3, virtproxyd.socket
> > > was still disabled and libvirt.socket was enabled. No problem connecting to
> > > libvirtd, even after the service timeout.
> >
> > I'll try to reproduce this myself later this week, but what you're
> > describing doesn't match my expectations: virtproxyd.socket should
> > have been enabled during installation.
>
> I would have thought so too and was surprised by the results. That test was
> done in a VM. I just did the same test on the host (freshly updated
> Tumbleweed) with the same results.

I have managed to reproduce the issue on Fedora 38, with the
following steps:

  * build the libvirt 9.0.0 RPMs from upstream sources and use them
    to create a very minimal QEMU installation consisting of just

      libvirt-client
      libvirt-daemon
      libvirt-daemon-driver-qemu
      libvirt-libs

  * reboot the machine, verify that a basic VM can be started;

  * turn the deployment into a monolithic one by running

      # systemctl disable --now virtqemud virtqemud{,-ro,-admin}.socket
      # systemctl mask virtqemud virtqemud{,-ro,-admin}.socket
      # systemctl disable --now virtproxyd virtproxyd{,-ro,-admin}.socket
      # systemctl mask virtproxyd virtproxyd{,-ro,-admin}.socket
      # systemctl unmask libvirtd libvirtd{,-ro,-admin}.socket
      # systemctl enable libvirtd libvirtd{,-ro,-admin}.socket

  * reboot the machine again and repeat the smoke test;

  * build the libvirt 9.1.0 RPMs from upstream sources and upgrade.
    As expected, this will result in a few new packages being added
    to the system:

      libvirt-client
      libvirt-daemon
      libvirt-daemon-common
      libvirt-daemon-driver-qemu
      libvirt-daemon-lock
      libvirt-daemon-log
      libvirt-daemon-plugin-lockd
      libvirt-daemon-proxy
      libvirt-libs

  * reboot the machine and try again.

Things will actually still work! But there's a somewhat subtle reason
for that ;)

During the upgrade, the following was printed:

    Running scriptlet: libvirt-daemon-proxy-9.1.0-1.fc38.x86_64
    Installing       : libvirt-daemon-proxy-9.1.0-1.fc38.x86_64
    Running scriptlet: libvirt-daemon-proxy-9.1.0-1.fc38.x86_64
  Failed to preset unit: Unit file
/etc/systemd/system/virtproxyd.socket is masked.

That's because I had *masked* all the split daemons in addition to
disabling them, as suggested on [1]. If I take a more naive approach
and simply disable the units, then I get

    Running scriptlet: libvirt-daemon-proxy-9.1.0-1.fc38.x86_64
    Installing       : libvirt-daemon-proxy-9.1.0-1.fc38.x86_64
    Running scriptlet: libvirt-daemon-proxy-9.1.0-1.fc38.x86_64
  Created symlink
/etc/systemd/system/sockets.target.wants/virtproxyd.socket →
/usr/lib/systemd/system/virtproxyd.socket.

during upgrade and after a reboot libvirtd is unusable, manifesting
the issue I was talking about.

Now, we could simply tell users that they need to disable things
properly O:-) but that's clearly not very helpful. It also wouldn't
do anything to solve Martin's issue.

Interestingly, I also get

    Running scriptlet: libvirt-daemon-log-9.1.0-1.fc38.x86_64
    Installing       : libvirt-daemon-log-9.1.0-1.fc38.x86_64
    Running scriptlet: libvirt-daemon-log-9.1.0-1.fc38.x86_64
  Removed "/etc/systemd/system/sockets.target.wants/virtlogd.socket".

    Running scriptlet: libvirt-daemon-lock-9.1.0-1.fc38.x86_64
    Installing       : libvirt-daemon-lock-9.1.0-1.fc38.x86_64
    Running scriptlet: libvirt-daemon-lock-9.1.0-1.fc38.x86_64
  Removed "/etc/systemd/system/sockets.target.wants/virtlockd.socket".

because, just as is the case for virtproxyd, the package manager is
convinced that these are completely new services and so it applies
the presets for them. However, libvirtd.service and virtqemud.service
both contain

  [Unit]
  Requires=virtlogd.socket
  Wants=virtlockd.socket

  [Install]
  Also=virtlogd.socket
  Also=virtlockd.socket

which I guess ultimately takes precedence over the preset, and the
sockets end up remaining enabled after all. Regardless, it would be
probably a good idea to apply whatever approach we end up taking for
virtproxyd to these two services too.

> > Are the packages you're using for testing a direct rebuild of the
> > spec file shipped upstream? Or have you integrated the changes into
> > the openSUSE spec file somehow?
>
> I've made the changes to the openSUSE Factory spec file, which closely
> tracks the upstream one.
>
> > Note that the scriptlets in the upstream spec file call out to some
> > standard macros, and it's also possible that the implementation of
> > said macros is not the same across Fedora and openSUSE.
>
> The openSUSE scriptlets use the 'service_add_pre' macro from the
> systemd-rpm-macros package
>
> https://build.opensuse.org/package/view_file/Base:System/systemd-rpm-macros/macros.systemd?expand=1
>
> In the end, something like 'systemctl --no-reload preset $unit' is called.

There might be some additional nuance that we're missing. I will try
to play around with openSUSE and understand the situation better
tomorrow.


[1] https://libvirt.org/daemons.html#switching-to-modular-daemons
-- 
Andrea Bolognani / Red Hat / Virtualization



More information about the libvir-list mailing list