tags:

views:

421

answers:

4

I need to reboot a Linux box from a user space process. I want to have the following behavior:

  1. sync file systems
  2. not attempt to gracefully stop processes, go to runlevel 5/6, etc., for I assume things are bad and that would fail

Can those requirements be achieved together at all?

I was planning to write a 'b' into proc/sysrq-trigger. Is there a better way? (No, that won't give me sync.)

Thanks!

+3  A: 

I'm assuming you have root.

  • the sysrq-trigger thing is fine, you just have to echo 's' a couple times into it first, which is an "Emergency Sync".
  • You can also check out the '-n' option to shutdown(8). That's a canned way to do what you want. It just sends SIGTERM, SIGKILL, syncs and shuts down or reboots (-h or -r option.)

Hope that helps.

Josh K
I was thinking about that, but how do I know when 's' has been processed?
n-alexander
Not sure. I would look at the behavior of sysrq-trigger (does it block until the operation completes?) You may well get it for free.If it is problematic, I would let shutdown -n do the job for you. Again, it bypasses init and does pretty much what you want without you having to call the shots manually.
Josh K
if it blocks that's another problem, for sync may actually hang on me. But thanks anyway
n-alexander
Now that I think about it, yes, sync() is by definition synchronous! It *may* hang on you. How about fork()ing, and then syncing?
Josh K
yes, I guess sync() being synchronous makes sense :)It seems like I'm not so much looking for a solution here, but defining my problem. You're right, I either need to wait or I don't.
n-alexander
No, sync() is *not* defined to be synchronous. It may be on some platforms, but it's not required by the POSIX standards, and it definitely is asynchronous on some other platforms. See `man 2 sync`: "According to the standard specification (e.g., POSIX.1-2001), sync() schedules the writes, but may return before the actual writing is done."
ephemient
+1  A: 

Well, do sync(1), kill -1, sync again, kill -9 -1, sync, poweroff -f.

That should do the trick, I guess!

alamar
what's the second sync for?
n-alexander
the processes killed by the first 'kill' command may have written something to disk.
Banengusk
+1  A: 

This directly from sys/reboot.h :

#ifndef _SYS_REBOOT_H
#define _SYS_REBOOT_H   1

#include <features.h>

/* Perform a hard reset now.  */
#define RB_AUTOBOOT     0x01234567

/* Halt the system.  */
#define RB_HALT_SYSTEM  0xcdef0123

/* Enable reboot using Ctrl-Alt-Delete keystroke.  */
#define RB_ENABLE_CAD   0x89abcdef

/* Disable reboot using Ctrl-Alt-Delete keystroke.  */
#define RB_DISABLE_CAD  0

/* Stop system and switch power off if possible.  */
#define RB_POWER_OFF    0x4321fedc

__BEGIN_DECLS

/* Reboot or halt the system.  */
extern int reboot (int __howto) __THROW;

__END_DECLS

#endif  /* _SYS_REBOOT_H */

I believe RB_HALT_SYSTEM will handle all sync()s , etc. I usually do that myself, and finally trigger the reboot with RB_AUTOBOOT.

Tim Post
A: 

On an ordinary distro, the simplest way to do this is:

system("/sbin/reboot -f");

This will sync all filesystems, then reboot immediately. Note that sysrq b will NOT sync.

bdonlan