<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Jul 18, 2013 at 9:47 AM, Lennart Poettering <span dir="ltr"><<a href="mailto:lennart@poettering.net" target="_blank">lennart@poettering.net</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><div class="h5">On Wed, 17.07.13 22:14, Tim Cuthbertson (<a href="mailto:tim@gfxmonk.net">tim@gfxmonk.net</a>) wrote:<br>


<br>
> Hi Folks,<br>
><br>
> I've posted a serverfault question [0], but it got no answers so I thought<br>
> I'd bring it to the mailing list:<br>
><br>
> I have some systemd units installed and running. Let's say I manually<br>
> uninstall foo.service by<br>
><br>
>  - removing its .service (and .socket) files<br>
>  - removing all symlinks (e.g from default.target.wants/)<br>
><br>
> I can run systemctl daemon-reload, and then I see:<br>
><br>
>     # systemctl status foo.service<br>
>     foo.service<br>
>        Loaded: error (Reason: No such file or directory)<br>
>        Active: active (running) since Mon 2013-07-08 13:50:29 EST; 48s ago<br>
>      Main PID: 1642 (node)<br>
><br>
> So systemd knows that it's not installed, and that it is running. Is there<br>
> some command I can use to stop all running services which no longer have a<br>
> unit file?<br>
><br>
> I do not want to have to somehow know what I've uninstalled, or for the<br>
> command to work only in some circumstances - I want something that I can<br>
> run at any point, with no additional knowledge, that will stop all units<br>
> not backed by a unit file.<br>
><br>
> I've currently got a hacky script that:<br>
>  - Runs `list-units` to get all unit names<br>
>  - Then `show -p ActiveState -p UnitFileState $unit` on each<br>
>  - It then runs `systemctl stop` on each unit with a UnitFileState of ""<br>
> (empty string), and ActiveState of anything but "failed".<br>
><br>
> This is almost certainly missing some edge case, as I couldn't really find<br>
> any documentation of these properties, it just seemed to be what occurred<br>
> with the examples I encountered.<br>
><br>
> I'm hoping there's a better way, can anyone point me in the right direction?<br>
><br>
> [0]:<br>
> <a href="http://serverfault.com/questions/521504/systemd-stop-all-uninstalled-units" target="_blank">http://serverfault.com/questions/521504/systemd-stop-all-uninstalled-units</a><br>
<br>
</div></div>So, the correct way to handle this is to make sure the packages in<br>
question contain the right scriplets that terminate all units they<br>
include before deinstallation. Of course, there'll always be broken<br>
packages like this I fear, hence I can totally see your usecase.<br>
<br>
There's currently no nice way to handle this, but what you can do is this:<br>
<br>
systemctl --all --type=not-found --type=error<br>
<br>
This will list you all units where the load state is either "error" or<br>
"not-found" (note that 'not-found' is available only in very recent<br>
versions, and in older systemd versions was just a special case of<br>
'error'. The command line above works for all versions). The --type=<br>
switch is used to filter unit types, but actually also can be used to<br>
filter for the load state.<br>
<br>
Then filter out the first column:<br>
<br>
systemctl --no-legend --all --type=not-found --type=error | awk '{ print $1 }'<br>
<br>
This will give you a list of unit files which got referenced or started<br>
but have no unit file installed. Then use this to stop the units:<br>
<br>
systemctl stop `systemctl --no-legend -all --type=not-found --type=error | awk '{ print $1}'`<br>
<br>
And there you go.<br>
<span class=""><font color="#888888"><br>
Lennart<br>
<br>
--<br>
Lennart Poettering - Red Hat, Inc.<br>
</font></span></blockquote></div><br></div><div class="gmail_extra" style>Thanks, Lennart (and Colin), that looks like a much better approach, although --type=not-found is rejected by old versions:</div><div class="gmail_extra" style>

<br></div><div class="gmail_extra" style><div class="gmail_extra">$ systemctl --all --type=not-found --type=error</div><div class="gmail_extra">Unknown unit type or load state 'not-found'.<br></div><div class="gmail_extra">

Use -t help to see a list of allowed values.</div><div class="gmail_extra">                                                                                                                                                                                                                   </div>

<div class="gmail_extra">$ systemctl --version<br></div><div class="gmail_extra">systemd 204</div><div class="gmail_extra">+PAM +LIBWRAP +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ</div><div class="gmail_extra">

<br></div><div class="gmail_extra" style>But I can probably try both, and fall back to just --error if not-found is denied.</div><div class="gmail_extra" style><br></div><div class="gmail_extra" style>I am not too concerned about systemd not knowing how best to kill the units - they don't contain any special stop actions, so it would be using the default action to kill the service anyway. But point taken, in the general case this is probably not advisable.<br>

</div></div><div class="gmail_extra" style><br></div><div class="gmail_extra" style>For background of why this might happen (if you or Colin are still curious), I'm installing systemd units not as part of any package - basically, the user has some application-specific config that they can change at any moment. They run:</div>

<div class="gmail_extra" style><br></div><div class="gmail_extra" style>$ foo install <my-config-file></div><div class="gmail_extra" style><br></div><div class="gmail_extra" style>And (regardless of any previous state), the units generated by that config file (and no units defined by previous invocations) should be installed / running. I put an X-Generated-By-MyApp=true in each of the generated unit files, so I can scan the /etc/systemd/system folder for previously installed units. This should mean that I can stop them immediately, but I wanted a failsafe way of doing it just in case things get left in an unknown state (because of bugs or unanticipated failure modes in my code).</div>

<div class="gmail_extra" style><br></div><div class="gmail_extra" style>I also had the notion if being able to affect a system from another with access to its filesystem, e.g. `foo install config-file --root=/srv/container1/etc/systemd/system` or by running the unit generation once and rsync'ing the installed units to multiple identical VMs, and then running a routine task in the container to "fix up" the state to reflect the installed units. But this is probably not worth the weirdness ;)</div>

<div class="gmail_extra" style><br></div><div class="gmail_extra" style>Cheers, and sorry for the double-post.</div><div class="gmail_extra" style> - Tim Cuthbertson.</div></div>