EBC systemd

From eLinux.org
Jump to: navigation, search

thumb‎ Embedded Linux Class by Mark A. Yoder


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.<anonymous> (/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 /etc/systemd/system and then looks in /lib/systemd/system. 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.




thumb‎ Embedded Linux Class by Mark A. Yoder