11

After removing most of the services that I don't need, it still takes about 28 seconds to boot, take a picture and shut down. I would like to lower this even more, and I did a systemd-analyze blame and got the following:

7.476s disableusb.service
1.736s keyboard-setup.service
958ms kbd.service
789ms systemd-fsck-root.service
737ms systemd-setup-dgram-qlen.service
722ms fake-hwclock.service
580ms kmod-static-nodes.service
565ms console-setup.service
534ms dev-mqueue.mount
518ms systemd-udev-trigger.service
498ms networking.service
489ms raspi-config.service
449ms hdparm.service
444ms systemd-journal-flush.service
376ms systemd-tmpfiles-setup.service
375ms dhcpcd.service
345ms systemd-logind.service
332ms ntp.service
317ms systemd-modules-load.service
281ms tmp.mount
272ms triggerhappy.service
269ms sys-kernel-debug.mount
265ms systemd-fsck@dev-mmcblk0p6.service
223ms rsyslog.service
221ms sys-kernel-config.mount
212ms systemd-tmpfiles-setup-dev.service
200ms systemd-remount-fs.service
198ms systemd-sysctl.service
184ms boot.mount
173ms systemd-random-seed.service
168ms rc-local.service
167ms user@1000.service
165ms var-log.mount
141ms udev-finish.service
130ms sys-fs-fuse-connections.mount
111ms systemd-user-sessions.service
94ms systemd-update-utmp.service
94ms alsa-restore.service
93ms systemd-update-utmp-runlevel.service
77ms systemd-udevd.service
55ms takepicture.service

disableusb.service is mine, and unlike what the name implies it does other things as well. I doubt I can improve the time there.

My system is running headless, by serial. I only need networking via wifi (wifi doesn't start because I disable the usb power, but sometimes I won't disable it, so that it can start).

Looking at this list, I see things such as: 1.736s keyboard-setup.service and 958ms kbd.service. They take almost 3 seconds. Do I need them if I am not using a keyboard? If not, how do I disable them?

What else can I safely disable from here?

Ok, there is something really strange going here. I disabled some more services, and it still takes that long in total, only that now some services that took less time before take much longer...

7.468s disableusb.service
1.676s console-setup.service
768ms systemd-logind.service
768ms systemd-fsck-root.service
726ms systemd-setup-dgram-qlen.service
714ms fake-hwclock.service
689ms networking.service
530ms systemd-journal-flush.service
524ms systemd-udev-trigger.service
509ms dev-mqueue.mount
509ms ntp.service
508ms kmod-static-nodes.service
439ms dhcpcd.service
334ms systemd-random-seed.service
331ms hdparm.service
318ms systemd-modules-load.service
281ms systemd-tmpfiles-setup.service
279ms systemd-fsck@dev-mmcblk0p6.service
279ms rsyslog.service
269ms systemd-remount-fs.service
265ms sys-kernel-config.mount
254ms systemd-tmpfiles-setup-dev.service
250ms systemd-sysctl.service
238ms rc-local.service
234ms systemd-udevd.service
232ms sys-kernel-debug.mount
224ms user@1000.service
187ms tmp.mount
176ms sys-fs-fuse-connections.mount
175ms var-log.mount
133ms systemd-update-utmp.service
122ms systemd-update-utmp-runlevel.service
122ms systemd-user-sessions.service
119ms alsa-restore.service
91ms boot.mount
88ms udev-finish.service
76ms takepicture.service

Service file: (no idea why the code syntax doesn't work)

[Unit]
Description=Disable USB power
Before=networking.service
After=local-fs.target
DefaultDependencies=no

[Service]
Type=oneshot
ExecStart=/sbin/usb_down

[Install]

Here is the plot: http://www.eternal-lands.com/plot.svg

enter image description here

Aurora0001
  • 6,308
  • 3
  • 23
  • 38
Radu
  • 480
  • 2
  • 4
  • 12
  • 1
    Perhaps it might be clearer what the problem is if you run systemd-analyze plot and include the image here (that should produce a nice SVG chart showing the timings and maybe will clear things up). – Aurora0001 Jan 21 '18 at 17:26
  • 1
    Thanks for the suggestion, I edited the post to add the plot. – Radu Jan 21 '18 at 17:36
  • You should paste in the service file for disableusb.service. BTW, you can quickly convert plog.svg plog.jpg if you install the imagemagick package/ – goldilocks Jan 21 '18 at 18:58
  • I edited the question to add the service file. – Radu Jan 21 '18 at 19:26
  • Question: What kind of SD card do you have? A faster SD card may provide faster boot times than any of these optimizations. Is it rated for at least 60mb/s? – cybernard Jan 22 '18 at 02:20
  • I have a 80mb/s SD card and my boot time are way faster. You fake-hwclock 722ms me 118ms. kmod-static 580ms me 63ms console-setup 565ms vs 63ms. I have a Pi 3 an OP does say if its a 2 or 3. – cybernard Jan 22 '18 at 02:33
  • It's a class 10 card, and it's a pi Zero, which is the slowest of all. The last services that load are always going to appear slower, because they run in parallel with my time consuming service. – Radu Jan 22 '18 at 07:48

3 Answers3

7
7.476s disableusb.service

This implies you are running something in the foreground because it is not persistent so you feel there is no point in backgrounding it. However, if it takes that long to do its thing, perhaps you should fork it to background as soon as it starts instead.

The issue here is simply that it is more likely to benefit your boot time than leaving it in the foreground is, although it may not make any difference either way. However, if something else depends upon it completing (as opposed to simply completing initialization successfully, which is more applicable to a persistent service), then you should leave it as.

I see things such as: 1.736s keyboard-setup.service and 958ms kbd.service. They take almost 3 seconds.

I've never looked into it because it does not matter much to me, but I believe there is something wrong about the way the "keyboard setup" is handled on Raspbian. I've seen it run 90 seconds before being killed by systemd.

Do I need them if I am not using a keyboard? If not, how do I disable them?

I suppose not, but this may create a hassle for you if you suddenly do need a keyboard...or it might make no difference at all -- part of my suspicion is that it actually isn't accomplishing anything, since the "keyboard setup" is something that is static configuration and can be manually changed as required.

To disable a service, sudo systemd disable ....

raspi-config.service

Odd this is still there since it is supposed to disable itself after it is run -- but that might not happen if you ignored it. That might relate to the keyboard thing. If possible you should plug in a monitor and see if it pops up post boot. In any case this is something else you might as well disable.

Here is the plot: http://www.eternal-lands.com/plot.svg

I think you should make disableusb.service After=sysinit.target.

goldilocks
  • 58,859
  • 17
  • 112
  • 227
  • I did a: pi@raspberrypi:~$ sudo systemd disable raspi-config.service and got Excess arguments.. Also, many of those services do not appear listed in systemctl list-unit-files. – Radu Jan 21 '18 at 16:17
  • What is the benefit of forking my service to the background? Ideally, everything should stop after my service is being ran (I also have a shutdown now in it, which is usually disable while I test things). – Radu Jan 21 '18 at 16:18
  • I've edited in a bit about that in the second paragraph. Based on what you are saying though, you might as well leave it foregrounded -- although if it doesn't make any difference, you could try it going straight to background and see if that speeds anything up. – goldilocks Jan 21 '18 at 16:34
  • I edited my post as well. I disabled some services, and it still takes as long to boot (some services take longer than before). – Radu Jan 21 '18 at 17:25
  • I think you should make disableusb.service After=sysinit.target. – goldilocks Jan 21 '18 at 18:52
  • Well I guess I can split ti in two, right now it's a hack, it was supposed to just shut down the usb, and take a pic in the takepicture.service I guess I can try to see if making this change would do anything. – Radu Jan 21 '18 at 19:18
  • Ok, did that, the takepicture service is After=local-fs.target sysinit.target and it takes about a second more to boot now. So the old way was better, since I think there was some parallelization of things on the CPU while the CPU waited for the camera data. – Radu Jan 21 '18 at 19:22
  • 1
    What about the relationship to networking.service? I'm presuming that wasn't intentional, which is why I recommended to start after sysinit (which waits for networking to initialize). Anyway, keep in mind that if 28 seconds includes your disableusb, it is a pretty reasonable boot time for any model of Pi. None of them are fast. – goldilocks Jan 21 '18 at 19:28
  • The networking.service is intentional. It is important for the USB power to be off so the wifi doesn't start, or else it spends a lot of time doing wifi startup things :) Yes, 28 seconds is not bad, but the thing is, this system will run on batteries, and will have to boot a few thousand times. So each second it's on it will be the equivalent of maybe 1 hour in total. Trimming even half a second can make a difference. Btw, it's a Pi Zero, so yeah, it's not the fastest PI :) – Radu Jan 21 '18 at 19:38
  • This is beginning to sound like a somewhat zany XY problem. >_< Disabling USB to prevent wifi from starting is ridiculous. You should just disable wifi via your networking configuration. – goldilocks Jan 21 '18 at 19:42
  • 1
    Disabling usb has the role to conserve power, not just to prevent the wifi from starting. The idea is that wifi SHOULD start sometimes, and the script will not disable the power in that case. – Radu Jan 21 '18 at 19:47
  • 2
    You're wasting your time trying to optimize if you want to insist disableusb has to finish before networking starts because this is how you want to ensure wifi doesn't start. That's just dumb, to be frank; you're playing have my cake and eat too. If you want to disable USB to conserve power, great, but you should deal with the wifi issue separately. If you can't be bothered, then don't waste your time trying to squeeze seconds out of your boot time either. – goldilocks Jan 21 '18 at 19:51
  • 1
    I don't think I understand what you are saying. I told you that I moved the bulk of the script as you suggested, and the boot time increased with almost 2 seconds... – Radu Jan 21 '18 at 19:52
4

I am running a head-less raspberrypi Zero and I could shave some seconds from it like so:

Systemd

# Don't start the Light Display Manager on headless
sudo systemctl disable lightdm.service

# In a headless environment you don't need the keyboard setup.
sudo systemctl disable keyboard-setup.service

# Checks if the country is set in the WIFI config. This is likely a regulatory precaution.
sudo systemctl disable wifi-country.service

# Unless you have an external joystick or something that uses `/dev/input/`
sudo systemctl disable triggerhappy.service 

# I read that the swap file actually slows the PI down and decreases SD card lifetime. 
sudo systemctl disable dphys-swapfile.service

# Disable Bluetooth unless you need it
sudo systemctl disable hciuart.service

# Unless you have a hardware button to disable the WIFI you won't need this
sudo systemctl mask systemd-rfkill.service # disabling won't work


# Open GL should be obsolete on a headless machine
sudo systemctl disable gldriver-test.service

# Only disable this one if you're not using `/etc/rc.local`
sudo systemctl mask rc-local

# You might to re-enable this service when making changes using `sudo raspi-config`
sudo systemctl disable raspi-config.service

Please note that systemd-analyze outputs the boot time:

Startup finished in 1.532s (kernel) + 20.862s (userspace) = 22.395s

Minimal boot output

In boot/cmdline.txt change tty1 to tty3 and append loglevel=3 quiet logo.nologo at the end after rootwait

This saved another second for me.

Misc

This guy achieves a raspberrypi boot of 3 seconds: https://www.samplerbox.org/article/fastbootrpi

This is a good blog with some steps to reduce the boot time: http://himeshp.blogspot.com/2018/08/fast-boot-with-raspberry-pi.html

DougieLawson explains some of the raspberrpi services https://www.raspberrypi.org/forums/viewtopic.php?t=195692

In-depth tutorial as PDF

Besi
  • 874
  • 4
  • 11
  • 24
3

Looking at the graph, it seems clear that disabling console-setup.service won't actually speed anything up anyway. As you can see networking.service is waiting until disableusb.service completes, so a 1.6 second load time for console-setup.service run in parallel won't affect the overall boot time at all.

There's an idea in scheduling of a critical path which, when any activity in this path is delayed, causes delays to the entire project. The other activities have 'float', i.e. they are not critical, and can be delayed without affecting the final finish time.

It is this critical path which you must save time on, not the non-critical activities. systemd-analyze critical-chain will help you identify the critical activities, although you can pretty much spot them on the plot. Any marginal gain in disableusb.service would help your boot time significantly.

It might also help to understand why your services take so long. For this, Bootchart2 might be useful. It can be installed with:

apt-get install systemd-bootchart

To actually enable it, edit /boot/cmdline.txt and set:

init=/lib/systemd/systemd-bootchart

After booting is complete, you'll find the chart saved in /run/log as an SVG file. Then, revert init=... to its initial setting (or delete it if it wasn't there before).

See also the man page for systemd-bootchart.

Aurora0001
  • 6,308
  • 3
  • 23
  • 38
  • The only cpu expensive thing my disableusb.service does it raspistill -o /home/pi/test_boot.jpg. This is just a test, I might modify the parameters a bit more and save some time, but in the future I also want to enable raw output which will mean another ~10 MB or so for each pic, which will probably take an extra second to write. I will try the bootchart thing, I hope it doesn't require a monitor :) – Radu Jan 21 '18 at 18:07
  • I think a PNG is produced too; it should be noted in the documentation where it saves in Raspbian. – Aurora0001 Jan 21 '18 at 18:08
  • Unfortunately, it doesn't work. Setting up bootchart2 (0.14.4-3) ... update-rc.d: warning: start and stop actions are no longer supported; falling back to defaults update-rc.d: warning: stop runlevel arguments (6 0) do not match bootchart-done Default-Stop values (none). When I start pybootchartgui -i I get a: warning: path '/var/log/bootchart.tgz' does not exist, ignoring. Parse error: empty state: '/var/log/bootchart.tgz' does not contain a valid bootchart – Radu Jan 21 '18 at 19:05
  • 2
    Oh, it turns out bootchart is now called systemd-bootchart in Stretch and is integrated more closely with systemd. I've edited, @Radu, with the appropriate steps. – Aurora0001 Jan 21 '18 at 20:36
  • I have Jessie, not Stretch. I am getting a E: Unable to locate package systemd-bootchart :/ – Radu Jan 21 '18 at 20:59
  • In that case, it doesn't sound like you'll be able to use Bootchart on your system if the packages aren't working. That's a bit of a shame, but I suppose you'll probably be able to manage without it and try other optimisations. – Aurora0001 Jan 21 '18 at 21:02
  • Yes, thanks for trying thought. I will see what other services I can remove. Even if I don't speed up time, I will save a bit of battery by keeping the CPU/file system less busy. – Radu Jan 21 '18 at 21:09
  • 1
    So, I found out that the camera app has a 5 seconds delay, just because. I used --timeout 1 and it reduced the boot time to 15.389s :) – Radu Jan 21 '18 at 22:26