EBC systemd

Traditionally user space initialization has been done using init.d, however recently many distributions have been switching to systemd

systemd is a system and service manager for Linux, compatible with SysV and LSB init scripts. systemd provides aggressive parallelization capabilities, uses socket and D-Bus activation for starting services, offers on-demand starting of daemons, keeps track of processes using Linux control groups, supports snapshotting and restoring of the system state, maintains mount and automount points and implements an elaborate transactional dependency-based service control logic.

Here we'll see how to use systemd as an administration and how to create a simple service.

Administration
There are a few simple commands that show what's running under systemd and how to stop and start them. The examples here were inspired by the twenty part series on systemd administration and the three part intro by Carla Schroder

To see what's running, run bone$ systemctl UNIT                       LOAD   ACTIVE SUB       DESCRIPTION proc-sys...t_misc.automount loaded active waiting  Arbitrary Executable File Fo sys-devi...tty-ttyO0.device loaded active plugged   /sys/devices/ocp.2/44e09000. sys-devi...ty-ttyGS0.device loaded active plugged  /sys/devices/ocp.2/47400000. sys-devi...-net-eth0.device loaded active plugged  /sys/devices/ocp.2/4a100000. sys-devi...blk0boot0.device loaded active plugged  /sys/devices/ocp.2/mmc.10/mm sys-devi...blk0boot1.device loaded active plugged  /sys/devices/ocp.2/mmc.10/mm sys-devi...mmcblk0p1.device loaded active plugged  /sys/devices/ocp.2/mmc.10/mm sys-devi...mmcblk0p2.device loaded active plugged  /sys/devices/ocp.2/mmc.10/mm sys-devi...k-mmcblk0.device loaded active plugged  /sys/devices/ocp.2/mmc.10/mm sys-devi...tty-ttyS0.device loaded active plugged  /sys/devices/platform/serial sys-devi...tty-ttyS1.device loaded active plugged  /sys/devices/platform/serial sys-devi...tty-ttyS2.device loaded active plugged  /sys/devices/platform/serial sys-devi...tty-ttyS3.device loaded active plugged  /sys/devices/platform/serial sys-module-fuse.device     loaded active plugged   /sys/module/fuse sys-subs...ices-eth0.device loaded active plugged  /sys/subsystem/net/devices/e -.mount                    loaded active mounted   / dev-mqueue.mount           loaded active mounted   POSIX Message Queue File Sys sys-fs-f...onnections.mount loaded active mounted  FUSE Control File System sys-kernel-debug.mount     loaded active mounted   Debug File System tmp.mount                  loaded active mounted   /tmp systemd-...ord-console.path loaded active waiting  Dispatch Password Requests t systemd-...ssword-wall.path loaded active waiting   Forward Password Requests to avahi-daemon.service        loaded active running   Avahi mDNS/DNS-SD Stack bonescript-autorun.service loaded active running   Bonescript autorun bonescript.service         loaded active running   Bonescript server and so on. Look through the list and see what you recognize. If you make your window bigger you will see more information. Here's how to find more details about a given process. bone$ systemctl status bonescript.service bonescript.service - Bonescript server Loaded: loaded (/lib/systemd/system/bonescript.service; static) Active: active (running) since Tue 2013-10-08 15:30:10 EDT; 1 day 20h ago Main PID: 346 (node) CGroup: name=systemd:/system/bonescript.service `-346 /usr/bin/node server.js Oct 08 15:30:10 yoder-black-bone systemd[1]: Started Bonescript server. Oct 08 15:30:16 yoder-black-bone bonescript[346]: [35B blob data] Oct 08 15:30:16 yoder-black-bone bonescript[346]: - - - [Tue, 08 Oct 2013 19:... Oct 08 15:30:17 yoder-black-bone bonescript[346]: - - - [Tue, 08 Oct 2013 19:... Oct 08 15:30:17 yoder-black-bone bonescript[346]: - - - [Tue, 08 Oct 2013 19:...

Stopping and Starting
You can stop a process with bone$ systemctl | grep cloud cloud9.service             loaded active running   Cloud9 IDE bone$ systemctl status cloud9 cloud9.service - Cloud9 IDE Loaded: loaded (/lib/systemd/system/cloud9.service; enabled) Active: active (running) since Fri 2000-01-07 17:46:06 EST; 13 years 9 months ago Main PID: 130 (node4) CGroup: name=systemd:/system/cloud9.service `-130 /usr/bin/node4 /usr/share/cloud9/bin/cloud9.js -l 0.0... Oct 08 15:30:15 yoder-black-bone node4[130]: publish state{"type":"state","p...} Oct 10 10:51:10 yoder-black-bone node4[130]: uncaught exception: Oct 10 10:51:10 yoder-black-bone node4[130]: Error: ENOENT, No such file or ...' Oct 10 10:51:10 yoder-black-bone node4[130]: at Object.statSync (fs.js:400:18) Oct 10 10:51:10 yoder-black-bone node4[130]: at /usr/share/cloud9/server/clo...7 Oct 10 10:51:10 yoder-black-bone node4[130]: at Array.forEach (native) Oct 10 10:51:10 yoder-black-bone node4[130]: at StatWatcher. (/us...) bone$ systemctl stop cloud9 Now try accessing cloud9 from a web browser (192.168.7.2:3000). It isn't there. You can start it with bone$ systemctl start cloud9 bone$ systemctl status cloud9 cloud9.service - Cloud9 IDE          Loaded: loaded (/lib/systemd/system/cloud9.service; enabled)          Active: active (running) since Thu 2013-10-10 11:53:25 EDT; 14s ago Main PID: 1470 (node4) CGroup: name=systemd:/system/cloud9.service `-1470 /usr/bin/node4 /usr/share/cloud9/bin/cloud9.js -l 0.... Oct 10 11:53:29 yoder-black-bone node4[1470]: .){2ooooonnnnvnvnvvvvvIIIIIIll...` Oct 10 11:53:29 yoder-black-bone node4[1470]: -{2oooonnnnnvvvvvvvlIIlllllil=...- Oct 10 11:53:29 yoder-black-bone node4[1470]: . -."11oonnvvvnvvIIlIlliliiiii.... Oct 10 11:53:29 yoder-black-bone node4[1470]: . -+~!lvvnvIvIIllliiiii|i|||i|.... Oct 10 11:53:29 yoder-black-bone node4[1470]: . ..--~++++++++~+~+~+~+-+-+~+~.... Oct 10 11:53:29 yoder-black-bone node4[1470]: . . . . .... . . .... .. ... .... Oct 10 11:53:29 yoder-black-bone node4[1470]: Ajax.org Cloud9 IDE Oct 10 11:53:29 yoder-black-bone node4[1470]: version 0.6 Oct 10 11:53:29 yoder-black-bone node4[1470]: Project root is: /var/lib/cloud9 Oct 10 11:53:29 yoder-black-bone node4[1470]: Point your browser to http://l...0 Notice the log messages have changed.

Autostart at boot time
You can use enable and disable to make a service start (or not start) at boot time. bone$ systemctl disable cloud9 rm '/etc/systemd/system/multi-user.target.wants/cloud9.service' bone$ systemctl enable cloud9 ln -s '/lib/systemd/system/cloud9.service' '/etc/systemd/system/multi-user.target.wants/cloud9.service' Watch out though, if some other service needs the service you disabled, it will start anyway.

Stopping no matter what
If you want to stop a service NO MATTER WHAT. bone$ ln -s /dev/null /etc/systemd/system/servicename.service bone$ systemctl daemon-reload systemd first looks in  and then looks in. The command above places an empty file in /etc/systemd/system, so the real file in /lib/systemd/system is never seen.

Analyzing Boot Time
You can see how look booting take by running bone$ systemd-analyze Startup finished in 1079ms (kernel) + 15007ms (userspace) = 16086ms You can also see how much time each program is taking bone$ systemd-analyze blame 10735ms wicd.service 6505ms apache2.service 6023ms bootlogs.service 5979ms console-kit-daemon.service 5040ms xrdp.service 4744ms ssh.service 4067ms cron.service 2271ms loadcpufreq.service 1968ms polkitd.service 1739ms avahi-daemon.service 1712ms wpa_supplicant.service 1666ms systemd-logind.service 1634ms upower.service 1612ms console-setup.service 1551ms networking.service 1328ms lightdm.service 1246ms generic-boot-script.service 1238ms capemgr.service 981ms keyboard-setup.service 963ms rc.local.service 920ms udev-trigger.service 827ms udhcpd.service 751ms motd.service 659ms console-kit-log-system-start.service 652ms alsa-utils.service 529ms udev.service 505ms kbd.service 365ms screen-cleanup.service 364ms systemd-user-sessions.service 318ms saned.service 307ms bluetooth.service 303ms systemd-modules-load.service 299ms hostapd.service 280ms hdparm.service 254ms systemd-sysctl.service 238ms run-lock.mount 231ms sys-kernel-security.mount 223ms systemd-tmpfiles-setup.service 197ms sys-kernel-debug.mount 194ms pppd-dns.service 172ms dev-mqueue.mount 170ms run-user.mount 118ms systemd-remount-api-vfs.service 95ms cpufrequtils.service 62ms sys-fs-fuse-connections.mount 42ms remount-rootfs.service It looks like apache and wicd are taking the most time. If you aren't using them, try disabling them and seeing what impact it has on boot time.

Running your own service
If you check in exercises/realtime you find boneServer.js a server for some demos. You run it with: bone$ cd exercises/realtime bone$ ./boneServer.js Listening on 8080 info - socket.io started Now point a browser to 192.168.7.2:8080. You'll see a list of demos served up by boneServer.js. Suppose you want the boneServer to automatically start every time the the Beagle boots. Here is how to do it.

We need to create a service file and the quickest way is to find one that does similar things. bone$ systemctl | grep bone bonescript-autorun.service loaded active running   Bonescript autorun bonescript.service         loaded active running   Bonescript server bonescript.socket          loaded active running   bonescript.socket I see a couple of bonescript servers that look promising. bone$ systemctl status bonescript bonescript.service - Bonescript server Loaded: loaded (/lib/systemd/system/bonescript.service; static) Active: active (running) since Sun 2000-01-09 15:07:55 EST; 13 years 9 months ago Main PID: 357 (node) CGroup: name=systemd:/system/bonescript.service `-357 /usr/bin/node server.js Jan 09 15:07:55 yoder-black-bone systemd[1]: Starting Bonescript server... Jan 09 15:08:04 yoder-black-bone bonescript[357]: [35B blob data] Jan 09 15:08:05 yoder-black-bone bonescript[357]: - - - [Sun, 09 Jan 2000 20:... Looks like the file is in /lib/systemd/system/bonescript.service copy it to a handy place and take a look. bone$ cp /lib/systemd/system/bonescript.service boneServer.service bone$ cat boneServer.service [Unit] Description=Bonescript server [Service] WorkingDirectory=/usr/lib/node_modules/bonescript ExecStart=/usr/bin/node server.js SyslogIdentifier=bonescript [Install] WantedBy=multi-user.target I copied the last two line from /lib/systemd/system/cloud9.service since they are needed to start at boot time. Modify the file so it will work for your server. Make sure to modify 'Description' as well or your service will confuse itself with the original bonescript.service.

There is one other thing you have to add to the file. When node.js runs it needs to know where to find its modules. There is an environment variable that says where bone$ echo $NODE_PATH /usr/lib/node_modules You need to add a line to the service file that set this environment variable. Look at the other files in /lib/systemd/system to see how this is done. (Hint: grep Env *).

Once your BoneServer.service file is ready, copy it to the right place bone$ cp boneServer.service /lib/systemd/system and start the server bone$ systemctl start boneServer Point your browser to 192.168.7.2:8080 and see if it works.

To make it work after rebooting bone$ systemctl enable boneServer ln -s '/lib/systemd/system/boneServer.service' '/etc/systemd/system/multi-user.target.wants/boneServer.service' Notice it copies your file to another place. Try rebooting and see if it works.