[libvirt PATCH 2/2] build: teach run script how to temporarily stop systemd units
Martin Kletzander
mkletzan at redhat.com
Thu Mar 25 13:49:25 UTC 2021
On Wed, Mar 24, 2021 at 04:44:25PM +0000, Daniel P. Berrangé wrote:
>On Wed, Mar 24, 2021 at 05:35:06PM +0100, Martin Kletzander wrote:
>> On Thu, Mar 18, 2021 at 06:30:27PM +0000, Daniel P. Berrangé wrote:
>> > When testing locally built daemons on a systemd host there can be quite
>> > a few systemd units that need temporarily stopping, and ideally
>> > restarting after the test is complete. This becomes a massive burden
>> > when modular daemons are running and you want to test libvirtd, as a
>> > huge number of units need stopping.
>> >
>> > The run script can facilitate this usage by looking at what units are
>> > running and automatically stopping any that are known to conflict with
>> > the daemon that is about to be run.
>> >
>>
>> It might be worth noting that this only affects running it as root.
>
>Good point.
>
>One day we might start using systemd for session daemons too[1].
>
>[1] https://gitlab.com/libvirt/libvirt/-/issues/21
>
>but for now this is root only.
>
>>
>> > Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
>> > ---
>> > run.in | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>> > 1 file changed, 84 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/run.in b/run.in
>> > index 99c67c586a..72d299dc4a 100644
>> > --- a/run.in
>> > +++ b/run.in
>> > @@ -44,6 +44,7 @@ import os
>> > import os.path
>> > import random
>> > import sys
>> > +import subprocess
>> >
>> > # Function to intelligently prepend a path to an environment variable.
>> > # See https://stackoverflow.com/a/9631350
>> > @@ -77,5 +78,86 @@ env["LIBVIRT_DIR_OVERRIDE"] = "1"
>> > # read problems when using glibc.
>> > env["MALLOC_PERTURB_"] = "%d" % random.randint(1, 255)
>> >
>> > -# Run the program.
>> > -os.execve(prog, args, env)
>> > +modular_daemons = [
>> > + "virtinterfaced",
>> > + "virtlxcd",
>> > + "virtnetworkd",
>> > + "virtnodedevd",
>> > + "virtnwfilterd",
>> > + "virtproxyd",
>> > + "virtqemud",
>> > + "virtsecretd",
>> > + "virtstoraged",
>> > + "virtvboxd",
>> > + "virtvzd",
>> > + "virtxend",
>> > +]
>> > +
>> > +def is_modular_daemon(name):
>> > + return name in modular_daemons
>> > +
>> > +def is_monolithic_daemon(name):
>> > + return name == "libvirtd"
>> > +
>> > +def is_systemd_host():
>> > + if os.getuid() != 0:
>> > + return False
>> > + return os.path.exists("/run/systemd/system")
>> > +
>> > +def daemon_units(name):
>> > + return [name + suffix for suffix in [
>> > + ".service", ".socket", "-ro.socket", "-admin.socket"]]
>> > +
>> > +def is_unit_active(name):
>> > + ret = subprocess.call(["systemctl", "is-active", "-q", name])
>> > + return ret == 0
>> > +
>> > +def change_unit(name, action):
>> > + ret = subprocess.call(["systemctl", action, "-q", name])
>> > + return ret == 0
>> > +
>> > +try_stop_units = []
>> > +if is_systemd_host():
>> > + name = os.path.basename(prog)
>> > +
>> > + maybe_stopped_units = []
>> > + if is_modular_daemon(name):
>> > + # Only need to stop libvirtd or this specific modular unit
>> > + maybe_stopped_units += daemon_units("libvirtd")
>> > + maybe_stopped_units += daemon_units(name)
>> > + elif is_monolithic_daemon(name):
>> > + # Need to stop libvirtd and/or all modular units
>> > + maybe_stopped_units += daemon_units("libvirtd")
>> > + for entry in modular_daemons:
>> > + maybe_stopped_units += daemon_units(entry)
>> > +
>> > + for unit in maybe_stopped_units:
>> > + if is_unit_active(unit):
>> > + try_stop_units.append(unit)
>> > +
>> > +if len(try_stop_units) == 0:
>> > + # Run the program directly, replacing ourselves
>> > + os.execve(prog, args, env)
>> > +else:
>> > + print("Temporarily stopping systemd units...")
>> > + stopped_units = []
>> > +
>> > + try:
>> > + for unit in try_stop_units:
>> > + print(" > %s" % unit)
>> > + if not change_unit(unit, "stop"):
>> > + raise Exception("Unable to stop '%s'" % unit)
>> > +
>> > + stopped_units.append(unit)
>> > +
>> > + print("Running %s..." % prog)
>> > + ret = subprocess.call(prog, env=env)
>>
>> You are not passing any possible parameters here, I think you meant something
>> like the following:
>>
>> subprocess.call([prog] + args)
>>
>> no?
>
>Yes, you're right.
>
OK, then I get it correctly, so
Reviewed-by: Martin Kletzander <mkletzan at redhat.com>
>
>
>Regards,
>Daniel
>--
>|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
>|: https://libvirt.org -o- https://fstop138.berrange.com :|
>|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20210325/34dc0373/attachment-0001.sig>
More information about the libvir-list
mailing list