55

With init scripts (or with openrc) I alway could run services from a different installation root.
but when I run chroot /somepath/to_root /usr/bin/systemctl start someservice I got:

Running in chroot, ignoring request.

Is there a way to force systemd run the service?

Update:
I forgot to say my host system run init scripts or openrc, but never systemd, and that I use chroot to troubleshot Unix systems which can't even launch a minimal shell.

user2284570
  • 1,799
  • 7
  • 35
  • 62

8 Answers8

41

A well-known problem in systemd distros (Arch Linux, OpenSUSE, Fedora).

Systemd replaces sysvinit, and provides one great advantage over this. In sysvinit, when you ask a service to start, it inherits the execution context of the person invoking the script, which includes environment variables, ulimits, and so on. Systemd improves on this at the contrary by notifying a daemon, which will start the service in a well-defined, healthy, constant environment, where of course the performances of the services are much easier to predict, since the environment is always the same.

This implies that, when I call systemctl from within the chroot, it is irrelevant that I am inside chroot, the environment that will be inherited is still that of PID 1, not my current one. But it gets worse than this: since communication sockets are placed inside /run/systemd, a process in a chroot will not even be able to talk to the init system!

So how do you go about chroot'ing in systemd distros?

  1. If all you want to do is have a Linux container, this Arch Wiki page will tell you how to set up a Linux container in less than 30 seconds, thanks to systemd-nspawn.

  2. If instead you really want a chroot environment, this beautiful and crystal clear Web page will provide you with two working solutions (the second one is a modified version of the one offered at point #1).

Evan Carroll
  • 8,863
  • 17
  • 76
  • 129
MariusMatutiae
  • 46,990
  • 12
  • 80
  • 129
  • I've looked for `systemd-nspawn` but I can't run it. And No this is not for a container since the service need to be used by both the host and the target architecture. – user2284570 Dec 15 '13 at 17:57
  • @user2284570 What do you mean exactly by `I can't run it?` – MariusMatutiae Dec 15 '13 at 19:48
  • 3
    That I never use systemd in my host system root. In my case I can't mix systemd with openrc. – user2284570 Dec 16 '13 at 18:05
  • It should be located right next to systemctl and the other systemd binaries (from your host: `/somepath/to_root/usr/bin/systemd-nspawn`) – TwoD Jun 13 '14 at 06:00
  • 2
    @TwoD That won't work. Running `systemd-nspawn` fails with "Not running on a systemd system." unless the host is using systemd as well. – hvd Jul 15 '15 at 11:59
  • @hvd See the other answers for actually having systemd itself run in the chroot. I was just answering where to find the binary as it sounded to me like user2284570 was looking for it. – TwoD Jul 15 '15 at 12:40
  • 1
    @TwoD And I responded because it doesn't sound like that at all to me. :) "I can't run it" is an odd thing to say if you're having trouble finding the executable, which is why I suspect that the problem is what I put in my comment: running it gives that error message and doesn't do anything useful. But even if it turns out the problem really was where to find `systemd-nspawn`, then pointing into the new root won't help. Either the host already has it (because it's running systemd), in which case the host version can be used, or the host doesn't have it, but the new root's version won't work. – hvd Jul 15 '15 at 12:45
  • @hvd I probably missed the "run" part and saw no mentioned of an error in this answer before writing that comment. – TwoD Jul 15 '15 at 13:16
  • 1
    `systemd` will refuse to be run in `chroot` – Erkin Alp Güney Mar 11 '17 at 14:30
  • Part of the problem is I sometimes need for the chroot services to ineract with those of the main root, so jailing based solutions cannot work. – user2284570 Jul 31 '17 at 07:11
  • After setting up with `debootstrap` and `schroot`ing into the directory to `apt install` things (specifically `postgresql`) I had the same problem as the OP. But following the web page link to pid eins, installing `systemd-container` both outside and inside the target directory, and finally invoking `systemd-spawn -b -D ` success was achieved. – Craig Hicks Jul 03 '18 at 18:24
  • It should be possible to use `systemd-nspawn` in a traditional init system. If you would read the whole arch wiki article posted in this answer, you'll come across this link: https://wiki.archlinux.org/index.php/Init#systemd-nspawn. – Tim Jul 28 '18 at 17:20
  • 1
    @CraigHicks Except since you set up a jail, you can’t do things like connecting wayland apps to the host’s compositing. Plain chroot isn’t a jail, but a way to change access search paths for the binaires. – user2284570 Aug 08 '20 at 10:02
11

systemd only ignores "services", so I just run the daemon commands manually.

So instead of

service sshd start

I use

/usr/sbin/sshd -D &
DavidPostill
  • 153,128
  • 77
  • 353
  • 394
johnP
  • 161
  • 2
  • 3
11

Several years later I must admit there is only one solution to most Systemd practical problems. Because the error is Systemd itself

I am really fed up with Systemd as I had problems that I never faced with things like Upstart or Openrc :

  • The enforcing of a kernel requiring cgroups support (instead of being made optional but enabled by default inside a config file) even for embedded systems with only 24Mb of ram and no writable storage.
    While proponents argue that not being able to use it in such case is the wanted behavior since it wasn’t designed for such case, the reality is the other init systems also don’t care while in systemd such feature isn’t a separate project which highlights once again the consequences of not following kiss.
  • Despite the claim of being modular, at runtime the dependency hell makes it a strong god object : want to boot over a single reiser4 rootfs ? It’s not possible because many programs requires systemd-udevd which requires systemd-init which requires the systemd-boot package which can’t be installed at the same time than grub2 nor can read kernel images from a reiser4 partition.
  • Want to connect to the internet through Bluetooth dialup ? If it doesn’t work with your Samsung java me phone, then you aren’t able to run the scripts and command line software that previously worked manually because of networkd.
  • Though I recognize the biggest problem is if you are building and maintaining your own Linux distribution : the systemd init module itself has so many dependencies that you can’t propose to choose another init system through different install packages.
  • The default use of Google dns for systemd if no resolver is defined in terms of privacy and censorship through the example to prevent Tornado Cash domains to resolve.
  • The inability to launch a background non service process and log out as there are no simple ways to do it in a new systemd scope.
  • Good luck for viewing logs if you can’t chroot in your system or if you upgraded from libdb4.8 (whereas at least, in worst case Microsoft has it’s log files in xml format).

The only solution :

Systemd is unnecessary complex for solving problems : like alsa instead of ossv4. So if you have something that uses systemd just wipe all the data :

dd if=/dev/urandom of=/dev/dm−0 bs=1M count=1

and install something that doesn’t use it at all while solving problems of SysV Init like Gentoo with Openrc.
Concerning my question systemd makes things like the Windows® registry : if a part of it gets screwed up, then it’s over.

user2284570
  • 1,799
  • 7
  • 35
  • 62
  • 11
    **Please recognize that the design of something can really prevent from getting an answer so that the answer is to switch to something which works**. And that this is a real answer. – user2284570 Nov 18 '18 at 21:47
  • 3
    I had the same opinion, now I am on a little bit more balanced view. Systemd has the super-big advantage that *it can really kill what should be killed*. It is because it tracks all the forked sub-processes with the kernel cgroup feature. None of the older tools can do that. Furthermore, do you remember the crap of the scripts in /etc/init/*.sh?I too, but it is only a bad memory to me today. The systemd service files are clear and around 10 lines long *configs*. Not 200 line long *scripts*. These huge advantages has the systemd, I agree that its all other features are disadvantage. – peterh Mar 25 '19 at 12:53
  • Btw, I voted your answer up because, beside its advantages, exactly this type of critics, exactly in this tone is what the systemd development requires to improve. For example, I've just tried to start a postgresql in a chroot and I had to crap my root system to do that. Many, *many* crappy thing is still there, right. – peterh Mar 25 '19 at 12:57
  • 1
    @peterh : unfortunately [not everyone share it](https://superuser.com/a/1208366/282033) I mean to the point of deleting post. This is not about SysV init against Systemd but more against things like Openrc or even Upstart (which allows for short startup scripts as well as parallel service start). At least I learned one thing : Darwin is mostly the ᴏꜱ of Apple™ Windows is the ᴏꜱ of Microsoft and Linux design is mostly run by red hat. Though SysV init while being slower doesn’t restrict you at what you can do at runtime. – user2284570 Mar 26 '19 at 13:08
  • @peterh Services scripts are also very clear when you use Openrc. The problem with cgroup on Systemd is this is not an option which by the prevent Systemd running things like Darwin or NetBSD. – user2284570 Sep 29 '19 at 07:11
  • 1
    After many years and at least in Debian I've found the easiest solution is to simply, in the chroot, ``apt purge systemd`` and then ``apt install sysvinit-core``. Since in a chroot systemd is not really "running" even if it's started, uninstalling it won't cripple the chroot, and then you can operate with sysv just as you do in the outside machine. (Unfortunately, in Debian I've found no way to debootstrap chroots with sysvinit preinstalled) – Luis Machuca Apr 28 '20 at 20:05
  • 1
    @LuisMachuca which is the problem of this question (but apt-get can work without Systemd). How do you manage to not have `pid 1` based on a systemd binary because of packages dependencies? This is for that impossibility that devuan was started. Are you still running Jessie or older? – user2284570 Apr 28 '20 at 22:12
  • I'm running Buster with Antix's ``nosystemd`` repo substituting all things that could depend on systemd. This is the setup I have for all production systems I manage. Have been using this setup since Antix started the repo back in Debian Jessie and so far the only software that has ever caused me issues with it is Samba. – Luis Machuca Apr 30 '20 at 18:05
  • @LuisMachuca so much like Devuan. I know many peoples would get angry seeing things like this in production environments. – user2284570 Apr 30 '20 at 19:29
  • Oh they do, but they are definitively, *quantifiably* less angry than back when the servers migrated to systemd and a bunch of stuff wouldn't start, including entire servers with remote mountpoints. When it's time to get paid, "it works again and just as well as before" means a lot. – Luis Machuca Apr 30 '20 at 21:07
  • @LuisMachuca no I’m meaning mixing repositories of different distributions. Even if 1 of them is for that purpose. What’s can be accepted is starting from a clean way with a distrib no designed for Systemd. – user2284570 May 01 '20 at 11:56
  • I'm no such zealot and I don't know any reasonable person who is. In the end, some people broke Debian and some other people decided to help fix it; I prefer to work with the latter than with the former. Most of the contributions Antix has done with that repo are things that can and do go well with a current Debian, if the Debian repo masters were willing to give the greenlight. For example, they provide a ``libpam-elogind-compat`` package without which a de-systemdified Buster frequently slows down or freezes because of DBus issues. – Luis Machuca May 01 '20 at 21:57
  • If anything, when we asked between the Production handlers if they preferred to reformat all servers and switch to learn different distros *or* to work with the proven-to-work, ongoing efforts that a community is doing... one of those solutions requires exponentially less downtime and headaches than the other. – Luis Machuca May 01 '20 at 22:02
  • @LuisMachuca `I'm no such zealot and I don't know any reasonable person who is.` My main teacher at my Master degree is one proof of the contrary among others. Though he is pro Systemd. – user2284570 May 01 '20 at 22:13
  • OpenRC/SysVinit go against the Unix philosophy by making each program/daemon not only take care of itself, but also handle all logging, log rotation, forking, startup sequence, permissions, and failures. Systemd simplifies this by having one tool that handles the common job of running programs in a consistent and unified way. When writing a program, I'd rather not deal with startup/daemonizing/logging/failure issues. That's the OS's job. – Cameron Tacklind Dec 27 '22 at 20:54
  • @CameronTacklind, for writing scripts, previously, I can tell you you re wrong. It s rather that it is taken care of by separate systems like eudev or evdev or rsyslog. **Systemd doesn t simplify but require you to use their tools even if they don t feet your needs like the impossibility to connect through dial up or not being able to boot on reiser4**. And in the case of Openrc startup sequence which has to be called once is put in the `init()` function. – user2284570 Dec 28 '22 at 10:57
3

No. Services are executed by systemd (pid 1), not by systemctl directly (which only sends a start request), and since systemd runs outside the chroot, so will the service.

Although technically it could be possible to implement this (by making systemctl somehow pass its root to systemd), it is somewhat unlikely to happen since there already is a tool for creating full containers (systemd-nspawn /somepath/to_root). You could always contact the mailing list though.

u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
  • 1
    Nice, But I need to use systemctl since My host system use oepnrc. I want full independent solution – user2284570 Dec 15 '13 at 17:55
  • 3
    I'll muddy the waters yet further by saying: Psst! Mention [`RootDirectory=`](http://freedesktop.org/software/systemd/man/systemd.exec.html#RootDirectory=) as well since you are so dangerously short of upvotes. (-: – JdeBP Dec 16 '13 at 19:56
  • @JdeBP : What is the difference (in term of results) beetween the variable `RootDirectory`and the `chroot`command? – user2284570 Dec 17 '13 at 21:35
  • @grawity : So What append if the `pid 1` is init? – user2284570 Dec 21 '13 at 09:41
2

Faced this problem once tried to bring up network in rescue mode using network configuration from chroot. Finally this works for me:

service --skip-redirect <service> restart

or:

SYSTEMCTL_SKIP_REDIRECT=_ /etc/init.d/<service> restart
reddot
  • 398
  • 3
  • 7
  • Nice. But it works only with legacy Init compatible services *(won’t work for networking in Fedora rawhide)*. As I said in my answer, the real solution is to screw up anything that use systemd. – user2284570 Dec 12 '17 at 14:59
1

Define a service file outside chroot that execute the service inside the chroot with the options RootDirectory=/path/to/chroot in conjunction with MountAPIVFS=on, the link above contains the magic.

Run systemd script in chroot from outside the chroot

-2

If you are launching an inetd-style service with socket activation, consider launching stunnel instead with a configuration file that specifies both a chroot and your binary as an inetd-style launch target.

Note that you may have SELINUX issues. On an Oracle Linux 7.1 system, I had to "chcon -v --type=stunnel_etc_t" on all files that stunnel needed to read.

You will need to use TLS encryption on the client side of the socket (i.e., another stunnel with "client=yes" in the config). Let me know if you want more details on this.

chas
  • 1
-3

You can use nohup command to start services in chroot. To start httpdservice for example, I do it like this.

nohup httpd /dev/null &

to stop it pkill httpd

ellooku
  • 7
  • 5