You are not logged in.
I have been using OpenRC for some time on ASCII and on Beowulf in a VM and now on real hardware and it seems to run correctly. The default set-up, in fact, uses SysV init, which then runs OpenRC. As far as I can tell this works by init using /etc/inittab, which has the entry
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
while /etc/init.d/rcS contains
#!/bin/sh
# Wrapper of OpenRC called from inittab
set -e
exec /sbin/openrc sysinit
which refers to the entries in the directory /etc/runlevels/sysinit
This seems to work and I think that the entries are taken in the correct order.
As OpenRC 0.25 started to provide openrc-init and Beowulf is on 0.40, I thought that I should try it out.
There is some good documentation on Gentoo at
https://wiki.gentoo.org/wiki/OpenRC
The main task is to cover the setting up of the ttys which was covered by inittab. As this will no longer be
used entries are needed in the default runlevel. Gentoo recommend
ln -sr /etc/init.d/agetty /etc/init.d/agetty.tty1
rc-update add agetty.tty1 default
A quick check shows that on Beowulf getty is a link to agetty. This leave the question as to what should be in
/etc/init.d/getty. On the OpenRC git hub I found
https://github.com/OpenRC/openrc/blob/m … y-guide.md
https://raw.githubusercontent.com/OpenR … f.d/agetty
# Set the baud rate of the terminal line
#baud=""
# set the terminal type
#termtype="linux"
# extra options to pass to agetty for this port
#agetty_options=""
EDIT: this is an error. I had got the conf file and not the init.d file, see below.
So I tried
cat << EOF > /etc/init.d/getty
# Set the baud rate of the terminal line
baud="38400"
# set the terminal type
termtype="linux"
# extra options to pass to agetty for this port
getty_options="--noclear"
EOF
chmod a+x /etc/init.d/getty
ln -sr /etc/init.d/getty /etc/init.d/getty.hvc0
rc-update add getty.hvc0 default
I used hvc0 as this is in a VM under Xen and that is what was used in inittab.
I then went to /boot/grub and edited menu.lst and added init=/sbin/openrc-init to the kernel line of one
of the entries, leaving another entry as it was, so that I had an easy fall back to SysV init.
When I boot and select the entry with openrc-init it does indeed boot and I can log in. ps shows that PID 1 is /sbin/openrc-init. However not everything is runnning. Looking at /var/log/boot I can see that several services failed to start, complaining about Read-only file system. Comparing with a correct boot it seems that the services are not started in the correct order, with the filesystems not starting up early. With openrc-init several other services try to start and fail. If I take our friend dbus as an example of the failures, then /etc/init.d/dbus starts with
#!/bin/sh
### BEGIN INIT INFO
# Provides: dbus
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop:
# Short-Description: D-Bus systemwide message bus
# Description: D-Bus is a simple interprocess messaging system, used
# for sending messages between applications.
### END INIT INFO
My guess is that $remote_fs is not being set up correctly with openrc-init, whereas SysV init does set it up before handing over to openrc-init. Hence some of these services are being started too early.
I do not know where $remote_fs et al. are being set up and I do not know how to tell openrc-init about it.
Geoff
Last edited by Geoff 42 (2019-04-13 15:14:26)
Offline
Here is some info, maybe you already know these things.
$remote_fs, and similar entries in the LSB section of the init scripts comes from insserv. You can find $remote_fs in /etc/insserv.conf. When insserv is run (for example after an init script is changed), it generates the 3 hidden files in /etc/init.d: .depend.boot, .depend.start, .depend.stop. These are then used by OpenRC to populate its dependency tree in /run/openrc.
You can set OpenRC to created /var/rc.log file by changing /etc/rc.conf, its well documented. There is also a verbose log option. This generates a nice log of what OpenRC started.
Maybe running insserv is needed since you are changing the init process, not sure.
Offline
Thank you. I will investigate insserv in this context.
I have got rc.log being created.
Geoff
Offline
Something else I will just "throw out", I do not know this to be fact.
I wonder if using openrc-init would require the init scripts in /etc/init.d to use OpenRC's #!/sbin/openrc-run instead of #!/bin/sh? If so, then I believe all the init scripts would have to be rewritten to openrc-run specs.
EDIT:
Something else I thought of- is inittab part of init (/sbin/init)? Maybe openrc-init doesnt run inittab?
This is an interesting endeavor, please keep us posted, thanks.
Last edited by dxrobertson (2019-04-11 11:45:56)
Offline
I wonder if using openrc-init would require the init scripts in /etc/init.d to use OpenRC's #!/sbin/openrc-run instead of #!/bin/sh? If so, then I believe all the init scripts would have to be rewritten to openrc-run specs.
With Devuan's standard set up of OpenRC, nearly all of the init.d scripts are the same as for SysV init and in that setup it all seems to work nicely.
https://github.com/OpenRC/openrc/blob/m … t-guide.md reports, inter alia, :-
The interpreter for service scripts is #!/sbin/openrc-run.
Not using this interpreter will break the use of dependencies and is not supported.
(iow: if you insist on using #!/bin/sh you're on your own)
Although, I am not quite sure how to interpret that! If you read the above URL they also say that various shells work fine and as I mention OpenRC work correctly when triggered from inittab.
Something else I thought of- is inittab part of init (/sbin/init)? Maybe openrc-init doesnt run inittab?
That is correct. With the current Devuan setup OpenRC is triggered via init and inittab, but with openrc-init, inittab is not used.
Geoff
Offline
Looking at dependencies and insserv I can see that /run/openrc/deptree is freshly created, as it must be since /run is TMPFS.
The contents of deptree look reasonable, so that if I find our old 'friend' dbus :-
depinfo_17_service='dbus'
depinfo_17_iprovide_0='_all'
depinfo_17_iuse_0='mountall'
depinfo_17_iuse_1='mountall-bootclean'
depinfo_17_iuse_2='mountoverflowtmp'
depinfo_17_iuse_3='umountfs'
depinfo_17_iuse_4='mountnfs'
depinfo_17_iuse_5='mountnfs-bootclean'
depinfo_17_iuse_6='umountnfs'
depinfo_17_iuse_7='sendsigs'
depinfo_17_iuse_8='rsyslog'
depinfo_17_iuse_9='sysklogd'
depinfo_17_iuse_10='syslog-ng'
depinfo_17_iuse_11='dsyslog'
depinfo_17_iuse_12='inetutils-syslogd'
depinfo_17_needsme_0='avahi-daemon'
depinfo_17_needsme_1='bluetooth'
depinfo_17_needsme_2='connman'
depinfo_17_needsme_3='dundee'
depinfo_17_needsme_4='elogind'
depinfo_17_needsme_5='ofono'
depinfo_17_usesme_0='lightdm'
depinfo_17_usesme_1='lxdm'
depinfo_17_usesme_2='saned'
and yet I can see that dbus is actually being started before mountall.
I can also see the definitions for $remote_fs et al. in /etc/insserv.conf.
In /lib/rc/sh/gendepends.sh it says :-
# follow insserv to ignore alternatives generated by dpkg.
# Only generate dependencies for OpenRC and LSB scripts
This script seems to go through /etc/init.d and generate the dependencies from the LSB headers.
I think that OpenRC does not use the .depends files in init.d, as those files are based on the init runlevels 1 to 6,
while OpenRC uses /etc/runlevels/, which in my case are sysinit, boot and default. I am now wondering whether boot and default are starting up before sysinit has finished.
My VM console reports :-
...
/dev/xvda2: recovering journal
/dev/xvda2: clean, 254102/1310720 files, 2331768/5242880 blocks
done.
[ 3.237815] EXT4-fs (xvda2): mounted filesystem with ordered data mode. Opts: (null)
done.
Begin: Running /scripts/local-bottom ... done.
Begin: Running /scripts/init-bottom ... done.
OpenRC init version 0.40.3 starting
Starting sysinit runlevel
OpenRC 0.40.3 is starting up Linux 4.19.0-2-amd64 (x86_64) [XENU]
* /proc is already mounted
* /run/openrc: creating directory
* /run/lock: creating directory
* /run/lock: correcting owner
* Caching service dependencies ...
[ ok ]
* Executing: /lib/rc/sh/openrc-run.sh /lib/rc/sh/openrc-run.sh /etc/init.d/mountkernfs.sh start
* Executing: /lib/rc/sh/openrc-run.sh /lib/rc/sh/openrc-run.sh /etc/init.d/umountroot start
* Executing: /lib/rc/sh/openrc-run.sh /lib/rc/sh/openrc-run.sh /etc/init.d/eudev start
[....] Starting hot-plug events dispatcher: udevd[ 5.428353] udevd[601]: starting version 3.2.7
. ok
[ ok ] Synthesizing the initial hotplug events...done.
[....] Waiting for /dev to be fully populated...[ 5.514507] random: udevd: uninitialized urandom read (16 bytes read)
[ 5.528106] random: udevd: uninitialized urandom read (16 bytes read)
[ 5.528123] random: udevd: uninitialized urandom read (16 bytes read)
[ 5.908380] udevd[601]: starting eudev-3.2.7
Starting boot runlevel
Starting default runlevel
[ 6.029691] RAPL PMU: API unit is 2^-32 Joules, 4 fixed counters, 655360 ms ovfl timer
...
When OpenRC is started from SysV init, in /var/log/boot I can see that the sysinit stuff is started up and when that has finished there is the entry :-
Wed Apr 10 09:30:25 2019: INIT: Entering runlevel: 2
and then the default runlevel stuff starts up (the boot runlevel is empty, but is 'started').
Geoff
Offline
I can see where the default runlevel is run under SysV init. OpenRC has replaced /etc/init.d/rc with its own script, which for the different numeric run levels, runs openrc with its own runlevel, so from inittab rc 2 will
exec /sbin/openrc default
hence delaying default until sysinit has finished.
Geoff
Last edited by Geoff 42 (2019-04-12 10:07:02)
Offline
I think that OpenRC does not use the .depends files in init.d, as those files are based on the init runlevels 1 to 6,
while OpenRC uses /etc/runlevels/, which in my case are sysinit, boot and default. I am now wondering whether boot and default are starting up before sysinit has finished.
I thought OpenRC does use the .depend files, at each bootup to generate the /run/openrc directory. This is how the LSB code in the init scripts ends up being used by OpenRC, and the dependencies all work as expected. I played around with this some with some test scripts and it seemed thats the way it worked. But I may be mistaken, I will look into this further.
I think you are correct in that default may be starting up before sysinit has completed. As that was assured when running using inittab. I am starting to get a headache thinking about this on the surface, need to go a bit deeper. I am wondering without initab, how openrc "knows" sysinit has completed?
Offline
Researching...
In openrc-init, the sysint and boot runlevels are hard-coded. Default is also hard-coded, but can be overridded by 1st arguement on commandline of openrc-init.
waitpid is used to ensure the various runlevels are completed before the next one is run, I suppose this is how waitpid works (not familiar with it).
Thus openrc-init "should" run the runlevels correctly (started in proper order, waiting for each to complete).
static void init(const char *default_runlevel)
{
const char *runlevel = NULL;
pid_t pid;
pid = do_openrc("sysinit");
waitpid(pid, NULL, 0);
pid = do_openrc("boot");
waitpid(pid, NULL, 0);
if (default_runlevel)
runlevel = default_runlevel;
else
runlevel = rc_conf_value("rc_default_runlevel");
if (!runlevel)
runlevel = rc_default_runlevel;
if (!rc_runlevel_exists(runlevel)) {
printf("%s is an invalid runlevel\n", runlevel);
runlevel = rc_default_runlevel;
}
pid = do_openrc(runlevel);
waitpid(pid, NULL, 0);
log_wtmp("reboot", "~~", 0, RUN_LVL, "~~");
}
Offline
Away from the dependencies for a moment, I have found the "Official" getty init.d script :-
https://raw.githubusercontent.com/OpenR … /agetty.in
It includes supervision and is in the openrc-run style.
I have edited it a bit, to change the name to getty, for the #!/sbin path and to put in the options I like, the --noclear leaves the logging messages on the screen. I am not sure about the "keyword -prefix", which I think may be a Gentoo-ism.
cat << EOF > /etc/init.d/getty
#!/sbin/openrc-run
# Copyright (c) 2017 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
#
# This file is part of OpenRC. It is subject to the license terms in
# the LICENSE file found in the top-level directory of this
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
# This file may not be copied, modified, propagated, or distributed
# except according to the terms contained in the LICENSE file.
description="start getty on a terminal line"
supervisor=supervise-daemon
baud="38400"
port="${RC_SVCNAME#*.}"
respawn_period="${respawn_period:-60}"
term_type="${term_type:-linux}"
getty_options="--noclear"
command=/sbin/getty
command_args_foreground="${getty_options} ${port} ${baud} ${term_type}"
pidfile="/run/${RC_SVCNAME}.pid"
depend() {
after local
keyword -prefix
}
start_pre() {
if [ -z "$port" ]; then
eerror "${RC_SVCNAME} cannot be started directly. You must create"
eerror "symbolic links to it for the ports you want to start"
eerror "getty on and add those to the appropriate runlevels."
return 1
else
export EINFO_QUIET="${quiet:-yes}"
fi
}
stop_pre()
{
export EINFO_QUIET="${quiet:-yes}"
}
EOF
This now works correctly and I can see it on ps
$ ps axjf| grep getty
1 2011 664 664 ? -1 S 0 0:00 supervise-daemon getty.hvc0 --start --pidfile /run/getty.hvc0.pid --respawn-period 60 /sbin/getty -- --noclear hvc0 38400 linux
2011 2012 2012 2012 hvc0 2012 Ss+ 0 0:00 \_ /sbin/getty --noclear hvc0 38400 linux
I can also see it in /var/log/boot
Fri Apr 12 13:40:21 2019: * Executing: /lib/rc/sh/openrc-run.sh /lib/rc/sh/openrc-run.sh /etc/init.d/networking start
Fri Apr 12 13:40:21 2019: [....] Configuring network interfaces... exim4??7[ ok 8??.
Fri Apr 12 13:40:21 2019: * Executing: /lib/rc/sh/openrc-run.sh /lib/rc/sh/openrc-run.sh /etc/init.d/getty.hvc0 start
Fri Apr 12 13:40:21 2019: * supervise-daemon: fopen `/run/getty.hvc0.pid': No such file or directory
Fri Apr 12 13:40:21 2019: * Detaching to start `/sbin/getty'
Fri Apr 12 13:40:22 2019: * Executing: /lib/rc/sh/openrc-run.sh /lib/rc/sh/openrc-run.sh /etc/init.d/haveged start
Fri Apr 12 13:40:22 2019: * Executing: /lib/rc/sh/openrc-run.sh /lib/rc/sh/openrc-run.sh /etc/init.d/irqbalance start
Fri Apr 12 13:40:22 2019: Internet Systems Consortium DHCP Client 4.4.1
interestingly the PID file does exist from a similar time :-
-rw-r--r-- 1 root root 5 Apr 12 13:40 /run/getty.hvc0.pid
With this now running, I could log in on the console, as the prompt has now appeared.
Geoff
Last edited by Geoff 42 (2019-04-12 14:10:18)
Offline
On the question of dependencies, I thought that in /etc/rc.conf I should try :-
rc_depend_strict="YES"
to see if it made any difference and it didn't :-(
Geoff
Offline
I notice that the code you quote from openrc-init is a bit different from that on the github OpenRC.
https://github.com/OpenRC/openrc/blob/m … nrc-init.c
Their version does not obviously wait for do_openrc to finish and do_openrc itself appears to execlp the runlevel.
I am not an expert C coder so I may mis-understand what it is doing, but doesn't each level just get started asynchronously?
Geoff
Offline
I see that the changes are recent :-
https://github.com/OpenRC/openrc/commit … 65898b2411
and are to do with waiting for the child process.
Geoff
Edit: the bug report :-
https://github.com/OpenRC/openrc/pull/300
Last edited by Geoff 42 (2019-04-12 16:08:13)
Offline
I see that the changes are recent :-
https://github.com/OpenRC/openrc/commit … 65898b2411
and are to do with waiting for the child process.
Geoff
Edit: the bug report :-
The code I posted and was looking into was from Debian testing, most likely what you are running. And as you have found out, there seems to indeed be a problem with the child processes, and the github source is reflecting the current attempts being made to fix it. There is significant difference in the current Debian code, and the patches reflected in the github version; in the init as well as do_openrc functions.
Offline
Geoff 42 wrote:I think that OpenRC does not use the .depends files in init.d, as those files are based on the init runlevels 1 to 6,
while OpenRC uses /etc/runlevels/, which in my case are sysinit, boot and default. I am now wondering whether boot and default are starting up before sysinit has finished.I thought OpenRC does use the .depend files, at each bootup to generate the /run/openrc directory. This is how the LSB code in the init scripts ends up being used by OpenRC, and the dependencies all work as expected. I played around with this some with some test scripts and it seemed thats the way it worked. But I may be mistaken, I will look into this further.
It appears OpenRC does NOT use the .depend.* files in /etc/init.d. Instead directly using the LSB header info within the scripts. I ran some tests; changing the #Required-Start: in a particular script in /etc/init.d, and also manually changing the scripts entry in depend.boot to something different from that. The change to the script file was picked up on next boot, and the change to .depend.boot was not picked up at all. I then deleted the 3 .depend files, rebooted, and nobody complained.
The change I made to the script file was reflected in /run/openrc/deptree as well as the actual running of the script, at the next boot after the change.
Offline
The Beowulf version I am running is 0.40.3. The latest version on github is 0.41.2 and I see that Debian have noticed that the latest upstream version is 0.41.2. I don't know how quickly they are likely to pick it up.
Geoff
Offline
I checked Debian unstable, still at .40.3. Guess its best to wait until the update migrates up through to testing...
Offline
I notice that the code you quote from openrc-init is a bit different from that on the github OpenRC.
https://github.com/OpenRC/openrc/blob/m … nrc-init.c
Their version does not obviously wait for do_openrc to finish and do_openrc itself appears to execlp the runlevel.
I am not an expert C coder so I may mis-understand what it is doing, but doesn't each level just get started asynchronously?Geoff
Just to tidy up-
Yes, in effect; it would be "each level just get started asynchronously" from the code change in init(), but the new code moved the waitpid out of from init() down into do_openrc() at line 73:
while (waitpid(pid, NULL, 0) != pid)
Thus the return from do_openrc() wont happen until the "whatever we need to do to ensure all has started..." has actually started.
EDIT- To clarify; The transition of sysinit-boot-default will not be asynchronously. atleast in the intent of the coding.
Last edited by dxrobertson (2019-04-13 00:48:20)
Offline
I thought that it would be good to check that version 0.41.2 does actually work, so as a complete hack, I down loaded 0.41.2 from
https://github.com/OpenRC/openrc/releases
tar xvf openrc-0.41.2.tar.gz
cd openrc-0.41.2
make
then as root
cp src/rc/openrc-init /sbin/openrc-init.41
cd /boot/grub
nano menu.lst
where I changed the kernel line to init=openrc-init.41, remembering that I had another kernel which could boot SysV init if necessary!
When I booted up using the 0.41.2 openrc-init, it seems to work nicely and everything has come up without any errors.
I'm sure it is not good practice to mix version stuff like this, but openrc-init is quite simple and I seem to have got away with it ;-)
Geoff
Offline
Having got openrc-init working on a Xen Beowulf VM, the next thing to try was Beowulf on some real hardware.
As I had tried renaming the agetty to getty, I though this time I would leave it as agetty.
I had downloaded the 0.41.2 sources, as above, and run make, then :-
Either copy the files from your copy of the source tree or from their github at :-
https://github.com/OpenRC/openrc/blob/m … /agetty.in
https://github.com/OpenRC/openrc/blob/m … f.d/agetty
cp /home/user1/src/Devuan/openrc-0.41.2/src/rc/openrc-init /sbin/openrc-init.41
cd /etc/init.d/
cp /home/user1/src/Devuan/openrc-0.41.2/init.d/agetty .
chmod a+x agetty
cd ../conf.d/
cp /home/user1/src/Devuan/openrc-0.41.2/conf.d/agetty .
I think the idea is that you leave init.d/agetty as is and put your edits in conf.d/agetty
ln -sr /etc/init.d/agetty /etc/init.d/agetty.tty1
rc-update add agetty.tty1 default
cd /boot/grub
nano grub.cfg
add to the linux line in a spare entry init=/sbin/openrc-init.41
Then rebooted and selected the OpenRC-init option and it all seemed to work nicely.
The next step was to set up grub 'properly' so edited /etc/default/grub and added
init=/sbin/openrc-init.41
thus to
GRUB_CMDLINE_LINUX_DEFAULT="earlyprintk=vga,keep net.ifnames=0 init=/sbin/openrc-init.41"
followed by update-grub.
Geoff
Offline
I should mention that once you have openrc-init working, that instead of using shutdown you will need to use openrc-shutdown which sends the correct signals to openrc-init. openrc-shutdown takes -r for reboot and -p for poweroff and -H for halt and also needs the time do do it, which can be 'now'. I just need to remember where I can plug this into LXQt!
Geoff
Offline
To document my findings.
Debians implementation of openrc init uses /sbin/init (obviously). /etc/inittab, /etc/init.d/rcS, and /etc/rc are used to run openrc runlevel sysinit (until completion) and then runlevel default. Note runlevel boot is not used in Debians implementation. "running" these runlevels is executing /sbin/openrc with the runlevel as the commandline arg.
When running openrc-init (as demonstrated by @Geoff42), /sbin/init, initab, rcS, rc are not used. Instead openrc-init has hard-coded (in openrc-init.c) the running of runlevel sysinit, followed by runlevel boot, followed by runlevel default. "default" can be overridden with a commandline arg to openrc-init.
Also, it appears that Debian has added patches to openrc for the LSB and insserv support. This support is not included in vanilla openrc. This modification provides the ability for openrc to use stock sysvinit init scripts (via LSB) and thus not requiring all init scripts to be rewritten to openrc-run interpretive specs (/bin/sh can be used). This is good in that it allows openrc to be run with minimal changes, from sysvinit. Debians process for using LSB and insserv does not use the 3 hidden .depend.* files in /etc/init.d, instead processes the LSB headers directly (thus the 3 .depend.* files are not used).
Thanks @Geoff42 for your persistent work in getting openrc-init to boot!
Last edited by dxrobertson (2019-04-21 00:11:26)
Offline
This may be a good point to ask about the benefits of running OpenRC and openrc-init.
As mentioned, OpenRC can use the existing init scripts as is, but if you re-do a script, you can set it up to do supervision, as in the above example of agetty, although SysV init already supervises getty! The other feature that OpenRC brings is that you can start services in parallel, although it does tend to make the logs a bit untidy. With OpenRC being started from SysV init, things seem to work very nicely and with little impact on the running of the machine. Once you replace SysV init with openrc-init, then the shutdown behaviour is changed as openrc-init uses different signals, so you tend to end up using openrc-shutdown. With openrc-init running the logging in rc.log is tidier, compared when started from SysV init, when I was seeing duplicates of the different phases.
Geoff
Offline
I have also had a look at getting a newer version of OpenRC running. I have reported on
this under the DIY thread :-
https://dev1galaxy.org/viewtopic.php?id=3371
A newer version is now available in Ceres, although there remains a bug related to openrc-init during shutdown.
Geoff
Offline