[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