Modern Linux versions (2010) may have difficulty running atop of some of the aging host containers employed by VPS companies.
In particular many VPS host containers provider Kernel facilities first implemented in 2007, with more modern features missing.
Testing if your Kernel supports signalfd():
If you are fairly certain that your VPS supports modern Linux (provides Kernel 2.6.26 to your container), then the Linux Test Project (described at end of article) will be enough to confirm things.
It is perhaps more likely that you do not know if you have signalfd() support, and want to do a test function call.
The signalfd() manpage provides a good summary and some test code:
signalfd() is available on Linux since kernel 2.6.22. Working support is
provided in glibc since version 2.8. The signalfd4() system call (see NOTES) is available on Linux since kernel 2.6.27.
Extract from the test code:
for (;;) {
s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo))
handle_error("read");
if (fdsi.ssi_signo == SIGINT) {
printf("Got SIGINT\n");
} else if (fdsi.ssi_signo == SIGQUIT) {
printf("Got SIGQUIT\n");
exit(EXIT_SUCCESS);
} else {
printf("Read unexpected signal\n");
}
}
The full code is available in the manpage on kernel.org, and for convenience there is also a copy in this directory.
In the above loop, pay particular attention to the item
fdsi.ssi_signo
, as some outdated manpages may have an old reference.( I describe this in detail in README.txt )
Examples of running signalfd_demo32bit on VPS:
The example above shows a failure message, as this VPS does not have access to
a host kernel which implements signalfd()
Another failure giving the same message 'function not implemented'
Now here I show a working example on a local Debian Squeeze install:
If signalfd() is supported by the running Kernel then you running signalfd_demo should make your system wait for input.
Pressing Ctrl+C should say 'Got SIGINT'
and Pressing Ctrl+\ should say 'Got SIGQUIT'
Warning: If you have redefined Ctrl+\ to be intercepted by screen or some graphical tool, then you are going to have difficulty getting out of the test!
Summary of expected responses:
- Your Kernel is 2.6.18 and/or does not support signalfd()
'Function not implemented' - Your Kernel supports signalfd()
Your system should enter a 'wait' state until
you press Ctrl+C or Ctrl+\ after which
it should respond with 'Got SIGINT' or 'Got SIGQUIT' as appropriate
'Function not implemented' and again below another 'signalfd: Function not implemented':
and now a success for OpenVZ running a patched Kernel 2.6.18:
Ignore the echo statement which is just a way of me highlighting this surprising result.
Patching 2.6.18 to give signalfd() support - pros and cons:
Arguing the thing both ways...
Pros:
- Hundreds of thousands of VPS containers may be able to successfully deploy Debian Squeeze and the latest Ubuntu (if signalfd() support is patched in)
Cons:
- Confusion. Wholescale backporting of features to a Kernel tree that is over 3 years old seems like a mistake to me. ( Upgrading the underlying container software to RedHat 6 or CentOS 6 really feels to me to be a better solution )
- Lack of easily scriptable tests. Already there are scripts out there that check for Kernel 2.6.26 or newer (see ltp below for example). If patching 2.6.18 becomes widespread, then scripts that test the Kernel version number to determine signalfd() support will become less useful.
Linux Test Project and signalfd():
When I was searching around for a way of testing for signalfd() support, I read about the Linux Test Project, and installed some software:
apt-get --no-install-recommends install ltp-kernel-test
You can leave out the --no-install-recommends but be warned that you will pull down a lot of packages if you decide to go that way.
Here are ltp tests running on a local 32 bit desktop install of Debian Squeeze:
and this result is less successful:
signalfd4() versus signalfd():
Newer Kernels of the ( 2.6.2x and 2.6.3x series ) implement signalfd4().
I quote directly from the manpage to explain their relationship:
Starting with glibc 2.9, the signalfd() wrapper function will use signalfd4() where it is available.
If you feel that there is merit in adapting the signalfd_demo.c code, to use signalfd4() instead, then there is perhaps some work to do there - feel free to take this on as an exercise in C.
Further reading and links:
- Linux Test Project News (sourceforge.net)
- signalfd() manpage ( kernel.org )
- Python library for signalfd() ( bazaar.launchpad.net )
- Python eventfs libraries ( bazaar.launchpad.net )
- VPS example illustrating precisely the problem discussed in this article
- signalfd4() manpage ( debian.net ) same as kernel.org manpage right now.