[libvirt PATCH 2/2] build: teach run script how to temporarily stop systemd units

Daniel P. Berrangé berrange at redhat.com
Wed Mar 24 16:44:25 UTC 2021


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.



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 :|




More information about the libvir-list mailing list