Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

On Fedora 17, I put a file into /etc/cron.daily with the following contents:

cd /
su dstahlke /home/dstahlke/bin/anacron-daily.sh
exit 0

For some reason, I get a mail every day that just says

/etc/cron.daily/dstahlke-daily:

 ...killed.

I tried with and without the exit 0 line above (I noticed that some system scripts have that and others don't, I'm not sure of the purpose). Running /etc/cron.daily/dstahlke-daily from the command line as root produces no ...killed message. Other than the message, everything seems to work fine. Putting set -x in the above script, as well as in the /home/dstahlke/bin/anacron-daily.sh script shows that the ...killed message happens just after the latter script terminates (or perhaps just after the su command finishes).

What causes the ...killed message?

Or, is there a more acceptable way to have anacron run a user script daily? I figured that putting this in /etc/cron.daily would help the system coordinate all of the daily tasks rather than potentially running my task concurrently with the system tasks.

share|improve this question
    
This question has long since disappeared into the tumbleweeds, but I would like to give a hint. I get the "...killed" message regardless of what su runs. So, even "su dstahlke ls" gives the message. I tried using sudo instead of su, but it won't run without a terminal. –  Dan Stahlke Oct 18 '12 at 15:51
    
I also get this message, and I would very much like to know what the reason is. –  hlovdal Dec 25 '12 at 19:31

1 Answer 1

up vote 2 down vote accepted

I did some further investigation, and found that ...killed is indeed printed by the su program, although the print does not come from the upstream coreutils project, it is introduced by coreutils-8.5-pam.patch in the source rpm. There is some history about the origins for adding this on bugzilla (622700, 597928 and 240117).

The relevant part of the code is

static sig_atomic_t volatile caught_signal = false;
...
/* Signal handler for parent process.  */
static void
su_catch_sig (int sig)
{
  caught_signal = true;
}

...

static void
create_watching_parent (void)
{
  ...
  sigfillset (&ourset);
  if (sigprocmask (SIG_BLOCK, &ourset, NULL))
    {
      error (0, errno, _("cannot block signals"));
      caught_signal = true;
    }
  if (!caught_signal)
    {
       ...
       action.sa_handler = su_catch_sig;
       ...
         || sigaction (SIGTERM, &action, NULL)
 ...
  if (caught_signal)
    {
      fprintf (stderr, _("\nSession terminated, killing shell..."));
      kill (child, SIGTERM);
    }

  cleanup_pam (PAM_SUCCESS);

  if (caught_signal)
    {
      sleep (2);
      kill (child, SIGKILL);
      fprintf (stderr, _(" ...killed.\n"));
    }
  exit (status);
}

So in some way (either directly/indirectly related to cleanup_pam or unrelated) the parent process receives SIGTERM between the second last and the last if tests, and thus only prints the ...killed message that obviously should have been a continuation of the fprintf above.

All in all that double use of caught_signal as both a asynchronous signal handler means and as a local flow control variable inside the function feels like a really dirty hack and I did not like the code. I tested by splitting that up and introduced a kill_child boolean variable to use in the body of the function and then having

  if (caught_signal)
    {
kill_child:
      kill_child = true;
      status = 1;
    }

  if (kill_child) {
    {
      fprintf (stderr, _("\nSession terminated, killing shell..."));
      kill (child, SIGTERM);
    }

  cleanup_pam (PAM_SUCCESS);

  if (kill_child)
    {
      sleep (2);
      kill (child, SIGKILL);
      fprintf (stderr, _(" ...killed.\n"));
    }
  exit (status);
}

at the end of the function. With that modification I do not get any ....killed spam from anacron any longer.


So a long explanation, and possibly more information than you need. However. I also found out some more, which is good news for you since you do not have to make local modifications to the coreutils package. For cases like running su from cron you are supposed to run the program runuser instead. It is sort of "bad" news for me since it makes my findings above less important, but well well :).

share|improve this answer
    
Excellent, thank you very much! Using runuser works perfectly and saves me from a cron email every morning. –  Dan Stahlke Dec 27 '12 at 15:00
    
Wow. Thanks. Upvotes for effort. –  Jonathan Hartley Jan 22 at 7:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.