Using init.rc to start and restart a Linux daemon

786 views
Skip to first unread message

rsg

unread,
Jun 4, 2014, 12:11:30 AM6/4/14
to android...@googlegroups.com
I need to write a Linuxland daemon that talks to our custom hardware.  I would like to use the /init process to start, and if necessary, restart it.  I have made this entry into the init.<hardware>.rc file that looks like this:

  service rsgd /system/bin/rsgd
    class main
    user system

Here is my daemon (just a skeleton now, but it runs):

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>

          #define DAEMONIZE
 
int main(void)
{
#ifdef DAEMONIZE 
  pid_t pid, sid;
  
  /* Fork off the parent process */
  pid = fork();
  if (pid < 0) {
    exit(EXIT_FAILURE);
  }
  /* Exit the parent process. */
  if (pid > 0) {
    exit(EXIT_SUCCESS);
  }
#endif
 
  /* Change the file mode mask */
  umask(0);
          
#ifdef DAEMONIZE 
  /* Create a new SID for the child process */
  sid = setsid();
  if (sid < 0) {
    /* Log the failure */
    exit(EXIT_FAILURE);
  }
#endif
 
 
  /* Change the current working directory */
  if ((chdir("/")) < 0) {
    /* Log the failure */
    exit(EXIT_FAILURE);
  }
  
  /* Close out the standard file descriptors */
  close(STDIN_FILENO);
  close(STDOUT_FILENO);
  close(STDERR_FILENO);
  
  /* Daemon-specific initialization goes here */
  
  /* The Big Loop */
  while (1) {
    /* Do some task here ... */

    usleep(100000); /* wait 100 milliseconds */
  }
  exit(EXIT_SUCCESS);
}

Nothing fancy.  When I build the system, the daemon gets created properly, and lives in /system/bin, as expected.  When I boot the system, however, /init continually starts my daemon, many times, until the system eventually runs out of memory!

Is there something my daemon needs to do so /init doesn't think it has died and needs to restart? 

Well, as I wrote this originally, I had an "Aha!" moment - /init must be acting on the exit of the parent process!  That would explain why it starts another instance, even though the prior one is still around.  So I got rid of the code with the DAEMONIZE conditionals, but that just hangs the system immediately after print this message:

Freeing init memory: 248K

So, what is the proper way to write a Linux daemon that /init can manage for me?  Any ideas welcome!

Thanks!

trevd

unread,
Jun 6, 2014, 11:16:03 AM6/6/14
to android...@googlegroups.com
Hi there

I don't think you need to "daemonize" the process manually as the native service infrastructure handles that for you. IIRC you can sit in the loop on the Main thread.
Here's an example of a USB Device hotplug listener I wrote a while back which ran as a system service.


However if you actually do want to daemonize the process you can add oneshot to the service declaration which will tell init to only start the service once, e.g

 service rsgd /system/bin/rsgd
    oneshot
    class main
    user system


Hope that helps!
trevd

rsg

unread,
Jun 6, 2014, 1:29:24 PM6/6/14
to android...@googlegroups.com
Hi trevd,

Yeah, you are right.  What I discovered is that I had a faulty Android.mk file that was driving the build of my daemon, such that it sometimes worked, but usually didn't.  So many of my changes weren't actually taking effect!  Then, the hang, which was simply a mistake on my part when creating the bootable SD Card (don't ask, too embarrassing!), really had me confused.

I sorted those issues out last night, and my code (with DAEMONIZE not defined) works correctly.

Thanks for confirming my understanding, and for the example daemon - seems the right balance between contrived (for ease in understanding) and the usual "real-world" (too complicated to understand); it's likely to serve as a useful reference going forward!

Regards,
Bob

trevd

unread,
Jun 6, 2014, 9:38:41 PM6/6/14
to android...@googlegroups.com
Hi Bob

Ay there's definitely plenty of room for error. For reference the init "language" is "documented" here https://android.googlesource.com/platform/system/core/+/master/init/readme.txt. However it's a mixture of fact and fiction as some of the functionality was never implemented. the "on device-" triggers only ever existed in the mind of author ( although I believe intel eventually implemented it 4 years down the line :\ ). It was this functionality which the hotplug service was developed to implement. 

I can only apologise for "contrived" nature of my code. I was just picking up C and Linux at the time after spending a decade on .Net, so I can definitely say it's not the finest piece of code I've ever hacked together but it did the job. :)
 
trevd

Glenn Kasten

unread,
Jun 7, 2014, 2:40:46 PM6/7/14
to android...@googlegroups.com
Quality improvements to the documentation would be welcome;
Reply all
Reply to author
Forward
0 new messages