I have been investigating code for a UPS for a Raspberry Pi that is using sysv init rather than systemd (personal preference and familiarity). I was looking into how a privileged script - possibly part of or run from /etc/rc.local - would tell init that there was a shortage of electrons in the power supply system. The init(8) man page tells me about writing a single capital letter ('F'ailing,'O'k or critically 'L'ow) into formerly /etc/powerstatus but now /var/run/powerstatus and then sending init a SIGPWR signal; but there is the warning that:

Usage of SIGPWR and /etc/powerstatus is discouraged. Someone wanting to interact with init should use the /run/initctl control channel - see the source code of the sysvinit package for more documentation about this.

I've looked at the source hosted by gnu.org but I've not seen any examples of anything using this new fangled interface to tell init things.

Interestingly, the hydra that is systemd does try to replicate this interface as I think somethings do not like it not being around but I have not found something that actually uses it. Is there such a thing? I'd expect some UPS related software to, e.g. nut but I don't think it does...

This question, although it mentions "Raspberry Pi" is not intended to be specific to that platform or the distributions like Raspbian that run on it.

These questions and their answers were quite enlightening on filling in some related details:

Edit: at least one of the above Q&A also indicated why some people have /dev/initctl and others /run/initctl - which was something I didn't realise (it was a Debian thing).

2 Answers 2


I believe reboot uses it. Do an strace of reboot:

# strace -s 128 -f reboot

Somewhere towards the bottom I see:

open("/dev/initctl", O_WRONLY)          = 3
write(3, "i\31\t\3\6\0\0\0\0\0\0\0\0\0\0\0INIT_HALT\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 384) = 384


open("/dev/initctl", O_WRONLY)          = 3
write(3, "i\31\t\3\1\0\0\0006\0\0\0\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 384) = 384

On Debian the following packages use /run/initctl: systemd, libvirt, sysvinit, refpolicy, gradm2. (from https://codesearch.debian.net/ ).

I think it is the normal way to tell init to change runlevel.

  • That codesearch link does look useful for Debian users. I am not altogether convinced that all of those use it - I think some (systemd ?) just make sure that the FIFO exists (for compatibility purposes!)- I recall somewhere that bad things happen if it isn't around (though that could just be that init itself gets really uptight if the thing does not exist and cannot be created by it) - guess I have some code reading to do...
    – SlySven
    Commented Feb 13, 2016 at 16:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .