@@ -412,6 +412,8 @@ ifdef BR2_INIT_SYSV
BR2_INIT = initscripts
else ifdef BR2_INIT_BUSYBOX
BR2_INIT = initscripts
+else ifdef BR2_INIT_BUSYBOX_BARE
+BR2_INIT = inittab
else ifdef BR2_INIT_SYSTEMD
BR2_INIT = systemd
else
@@ -172,6 +172,48 @@ def initscripts():
# ------------------------------------------------------------------------------
+# Inittab is almost the same as initscripts, except all services
+# are listed directly instead of running rcS and rcK
+def inittab():
+ writeto('output/target/etc/inittab')
+ pipefile('support/init/sysv.init')
+ wnl()
+
+ sysv_mount()
+ sysv_net()
+ # These are started *before* anything else, in particular before
+ # any system initialization, to catch possible messages and
+ # to give a chance to peek at the system state if something hangs.
+ sysv_syslog()
+ sysv_getty()
+ inittab_udev()
+
+ # This follows initscript idea of priority, with mixed
+ # w-type and s-type entries. Makes little sense actually,
+ # but the code is a bit shorter this way, and install-init
+ # already kinda splits w/s-type with its default prio settings.
+ lines = readlines('output/parts/inittab/')
+ lines = map(sysv_line, sorted(lines, key=sysv_prio))
+ if lines:
+ wnl()
+ for l in lines: w('%s', l.rstrip())
+
+ wnl()
+ pipefile('support/init/sysv.fini')
+
+def inittab_udev():
+ if BR2.ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV:
+ copyfile('support/init/rc.sys/udev', 'output/target/etc/rc/sys/udev')
+ w('null:2345:respawn:/sbin/udevd')
+ w('null:2345:wait:/etc/rc/sys/udev')
+ elif BR2.ROOTFS_DEVICE_CREATION_DYNAMIC_MDEV:
+ # mdev is not a deamon
+ copyfile('support/init/rc.sys/mdev', 'output/target/etc/rc/sys/mdev')
+ copyfile('support/init/mdev.conf', 'output/target/etc/mdev.conf')
+ w('null:2345:wait:/etc/rc/sys/mdev')
+
+# ------------------------------------------------------------------------------
+
# Installed service files must be linked to relevant *.wants directories.
# Other than that, there is nothing to do with systemd configuration.
def systemd():
@@ -191,7 +233,7 @@ def systemd():
# ------------------------------------------------------------------------------
output = None
-inits = [ 'initscripts', 'systemd' ]
+inits = [ 'inittab', 'initscripts', 'systemd' ]
BR2 = Br2('.config')
if len(argv) > 1 and argv[1] == '-':
@@ -23,7 +23,7 @@ from os import open as osopen
from os import read as osread
from os import write as oswrite
-inits = ['initscripts', 'systemd']
+inits = ['inittab', 'initscripts', 'systemd']
output = None
nopath = False
@@ -37,7 +37,7 @@ class Run:
# accepting unadorned commands for pre/post groups.
for k in ['description', 'user', 'group', 'umask',
- 'pidfile', 'priority',
+ 'pidfile', 'priority', 'short',
'after', 'requires', 'wantedby',
'busname', 'conflicts', 'killwith', 'restart']:
setattr(self, k, None)
@@ -219,6 +219,81 @@ def maybesu(r, cmd):
else:
return cmd
+# return either cmd, sh cmd or su cmd; the caller can *not* handle
+# shell commands, so anything unusual must be escaped with sh -c
+def maybesush(r, cmd):
+ # everything below assumes the caller uses execvp even with no sh
+ # which is ok for all init systemd that use su
+ shneeded = match(r'^.*[<>&|$"()]', cmd)
+
+ if r.user:
+ if shneeded:
+ return "su - %s -c '%s'" % (r.user, cmd)
+ else:
+ return "su - %s %s" % (r.user, cmd)
+ else:
+ if shneeded:
+ return "sh -c '%s'" % (r.user, cmd)
+ else:
+ return cmd
+
+# ------------------------------------------------------------------------------
+
+def inittab(r):
+ short = r.short if r.short else r.name
+ rlvls = '345' # BR does not use runlevels
+ writeto('output/parts/inittab/%s.line' % r.name, 0o644)
+ script = None
+ r.substcmds()
+
+ if r.umask:
+ r.pre.insert(0, "umask %s" % r.umask)
+
+ if r.exec:
+ action, cmd = 'respawn', r.exec
+ elif r.start:
+ action, cmd = 'wait', r.start
+ elif len(r.pre) == 1:
+ action, cmd = 'wait', r.pre[0]
+ else:
+ action, cmd = 'wait', None
+ if ((r.exec or r.start) and r.pre) or (len(r.pre) > 1):
+ sdir = 'rc' if r.start or r.exec else 'rc/sys'
+ script = '/etc/%s/%s' % (sdir, r.name)
+ cmd = script
+
+ if not script:
+ cmd = maybesush(r, cmd)
+
+ # let tty be null for all anything intalled from .run files
+ w("%02d:%s:%s:%s:%s", int(r.priority), 'null', rlvls, action, cmd)
+
+ if not script:
+ return
+
+ writeto('output/target%s' % script, 0o755)
+ w("#!/bin/sh")
+ if r.description:
+ w("# %s", r.description)
+ wnl
+
+ for c in r.pre:
+ # this may result in profoundly ugly code, but luckily
+ # the only service that uses it atm has exactly one line pre
+ w("%s", maybesu(r, c))
+
+ if r.exec:
+ w("exec %s", maybesu(r, r.exec))
+ elif r.start:
+ w("%s", maybesu(r, r.start))
+
+ # TODO: handle pre-post scripts
+ # This should result in *two* lines, not one, with the second
+ # line being probably :06: with relevant setup in finalize-init
+ # to make sysvinit switch to those runlevels on reboot/poweroff
+ # XXX: would that be a natural solution for sysv?
+ # XXX: bb init does not support runlevels
+
# ------------------------------------------------------------------------------
def initscripts(r):
@@ -381,6 +456,10 @@ def systemd(r):
# bypass inittab -
bypasstable = {
+ 'inittab': [
+ ('*.line', 'output/parts/inittab/*'),
+ ('sys:*', 'output/target/etc/rc/sys/*'),
+ ('*', 'output/target/etc/rc/*') ],
'initscripts': [
('*:*.init', 'output/target/etc/init.d/S$1$2'),
('*.init', 'output/target/etc/init.d/S50$1'),
new file mode 100755
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+echo /sbin/mdev >/proc/sys/kernel/hotplug
+exec /sbin/mdev -s
new file mode 100755
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# udevd must be running by this point!
+
+printf '\000\000\000\000' > /proc/sys/kernel/hotplug
+udevadm trigger --type=subsystems --action=add
+udevadm trigger --type=devices --action=add
+udevadm settle --timeout=30
@@ -86,8 +86,20 @@ choice
There are several possible configurations providing
varying degrees of control over the spawned processes.
+config BR2_INIT_BUSYBOX_BARE
+ bool "BusyBox / inittab"
+ select BR2_PACKAGE_BUSYBOX
+ help
+ Minimalistic init implementation from busybox.
+ Daemons are written directly to /etc/inittab.
+
+ No runlevel support.
+ No runtime control over processes.
+ Daemons are started in foreground mode,
+ failed processes are respawned.
+
config BR2_INIT_BUSYBOX
- bool "BusyBox"
+ bool "BusyBox / initscripts"
select BR2_PACKAGE_BUSYBOX
help
Minimalistic init implementation from busybox
@@ -100,7 +112,7 @@ config BR2_INIT_BUSYBOX
Failed processes are not respawned.
config BR2_INIT_SYSV
- bool "systemV"
+ bool "sysvinit / initscripts"
select BR2_PACKAGE_BUSYBOX_SHOW_OTHERS # sysvinit
select BR2_PACKAGE_SYSVINIT
help