static void power_down(suspend_disk_method_t mode) { unsigned long flags; int error = 0; local_irq_save(flags); switch(mode) { case PM_DISK_PLATFORM: device_power_down(PM_SUSPEND_DISK); error = pm_ops->enter(PM_SUSPEND_DISK); break; case PM_DISK_SHUTDOWN: printk("Powering off system\n"); device_shutdown(); machine_power_off(); break; case PM_DISK_REBOOT: device_shutdown(); machine_restart(NULL); break; } machine_halt(); /* Valid image is on the disk, if we continue we risk serious data corruption after resume. */ printk(KERN_CRIT "Please power me down manually\n"); while(1); }
static void kernel_shutdown_prepare(enum system_states state) { blocking_notifier_call_chain(&reboot_notifier_list, (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL); system_state = state; device_shutdown(); }
static void kernel_restart_prepare(char *cmd) { blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); system_state = SYSTEM_RESTART; device_shutdown(); sysdev_shutdown(); }
void kernel_restart_prepare(char *cmd) { blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); system_state = SYSTEM_RESTART; usermodehelper_disable(); device_shutdown(); }
/** * Helper function for implementing DEVICE_SHUTDOWN(). * * This function can be used to implement DEVICE_SHUTDOWN() for bhnd(4) * bus implementations. It calls device_shutdown() for each * of the device's children, in reverse order, terminating if * any call to device_shutdown() fails. */ int bhnd_generic_shutdown(device_t dev) { device_t *devs; int ndevs; int error; if (!device_is_attached(dev)) return (EBUSY); if ((error = device_get_children(dev, &devs, &ndevs))) return (error); /* Shutdown in the reverse of attach order */ qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); for (int i = 0; i < ndevs; i++) { device_t child = devs[i]; /* Terminate on first error */ if ((error = device_shutdown(child))) goto cleanup; } cleanup: free(devs, M_TEMP); return (error); }
void kernel_restart_prepare(char *cmd) { register_reboot_notifier(&dummy_notifier_reboot); notifier_head.head=dummy_notifier_reboot.next; unregister_reboot_notifier(&dummy_notifier_reboot); blocking_notifier_call_chain(¬ifier_head, SYS_RESTART, cmd); system_state = SYSTEM_RESTART; device_shutdown(); sysdev_shutdown(); }
static int siba_bwn_shutdown(device_t dev) { device_t *devlistp; int devcnt, error = 0, i; error = device_get_children(dev, &devlistp, &devcnt); if (error != 0) return (error); for (i = 0 ; i < devcnt ; i++) device_shutdown(devlistp[i]); kfree(devlistp, M_TEMP); return (0); }
static void suspend_power_down(void) { extern int C_A_D; C_A_D = 0; printk(KERN_EMERG "%s%s Trying to power down.\n", name_suspend, TEST_SWSUSP ? "Disable TEST_SWSUSP. NOT ": ""); #ifdef CONFIG_VT PRINTK(KERN_EMERG "shift_state: %04x\n", shift_state); mdelay(1000); if (TEST_SWSUSP ^ (!!(shift_state & (1 << KG_CTRL)))) machine_restart(NULL); else #endif { device_shutdown(); machine_power_off(); } printk(KERN_EMERG "%sProbably not capable for powerdown. System halted.\n", name_suspend); machine_halt(); while (1); /* NOTREACHED */ }
int main(int argc, char *argv[]) { int listenfd; int res = 0; int lfd; struct flock lock; char pids[10]; parse_opts(argc, argv); argc -= optind; argv += optind; if (!foreground) { verbose += LL_WARNING; log_enable_syslog(); } else { verbose += LL_NOTICE; } /* set log level to specified verbosity */ log_level = verbose; usbmuxd_log(LL_NOTICE, "usbmuxd v%s starting up", PACKAGE_VERSION); should_exit = 0; should_discover = 0; set_signal_handlers(); signal(SIGPIPE, SIG_IGN); res = lfd = open(lockfile, O_WRONLY|O_CREAT, 0644); if(res == -1) { usbmuxd_log(LL_FATAL, "Could not open lockfile"); goto terminate; } lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; lock.l_pid = 0; fcntl(lfd, F_GETLK, &lock); close(lfd); if (lock.l_type != F_UNLCK) { if (opt_exit) { if (lock.l_pid && !kill(lock.l_pid, 0)) { usbmuxd_log(LL_NOTICE, "Sending signal %d to instance with pid %d", exit_signal, lock.l_pid); res = 0; if (kill(lock.l_pid, exit_signal) < 0) { usbmuxd_log(LL_FATAL, "Could not deliver signal %d to pid %d", exit_signal, lock.l_pid); res = -1; } goto terminate; } else { usbmuxd_log(LL_ERROR, "Could not determine pid of the other running instance!"); res = -1; goto terminate; } } else { if (!opt_disable_hotplug) { usbmuxd_log(LL_ERROR, "Another instance is already running (pid %d). exiting.", lock.l_pid); res = -1; } else { usbmuxd_log(LL_NOTICE, "Another instance is already running (pid %d). Telling it to check for devices.", lock.l_pid); if (lock.l_pid && !kill(lock.l_pid, 0)) { usbmuxd_log(LL_NOTICE, "Sending signal SIGUSR2 to instance with pid %d", lock.l_pid); res = 0; if (kill(lock.l_pid, SIGUSR2) < 0) { usbmuxd_log(LL_FATAL, "Could not deliver SIGUSR2 to pid %d", lock.l_pid); res = -1; } } else { usbmuxd_log(LL_ERROR, "Could not determine pid of the other running instance!"); res = -1; } } goto terminate; } } unlink(lockfile); if (opt_exit) { usbmuxd_log(LL_NOTICE, "No running instance found, none killed. Exiting."); goto terminate; } if (!foreground) { if ((res = daemonize()) < 0) { fprintf(stderr, "usbmuxd: FATAL: Could not daemonize!\n"); usbmuxd_log(LL_FATAL, "Could not daemonize!"); goto terminate; } } // now open the lockfile and place the lock res = lfd = open(lockfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644); if(res < 0) { usbmuxd_log(LL_FATAL, "Could not open lockfile"); goto terminate; } lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; if ((res = fcntl(lfd, F_SETLK, &lock)) < 0) { usbmuxd_log(LL_FATAL, "Lockfile locking failed!"); goto terminate; } sprintf(pids, "%d", getpid()); if ((size_t)(res = write(lfd, pids, strlen(pids))) != strlen(pids)) { usbmuxd_log(LL_FATAL, "Could not write pidfile!"); if(res >= 0) res = -2; goto terminate; } // set number of file descriptors to higher value struct rlimit rlim; getrlimit(RLIMIT_NOFILE, &rlim); rlim.rlim_max = 65536; setrlimit(RLIMIT_NOFILE, (const struct rlimit*)&rlim); usbmuxd_log(LL_INFO, "Creating socket"); res = listenfd = create_socket(); if(listenfd < 0) goto terminate; #ifdef HAVE_LIBIMOBILEDEVICE const char* userprefdir = config_get_config_dir(); struct stat fst; memset(&fst, '\0', sizeof(struct stat)); if (stat(userprefdir, &fst) < 0) { if (mkdir(userprefdir, 0775) < 0) { usbmuxd_log(LL_FATAL, "Failed to create required directory '%s': %s", userprefdir, strerror(errno)); res = -1; goto terminate; } if (stat(userprefdir, &fst) < 0) { usbmuxd_log(LL_FATAL, "stat() failed after creating directory '%s': %s", userprefdir, strerror(errno)); res = -1; goto terminate; } } // make sure permission bits are set correctly if (fst.st_mode != 02775) { if (chmod(userprefdir, 02775) < 0) { usbmuxd_log(LL_WARNING, "chmod(%s, 02775) failed: %s", userprefdir, strerror(errno)); } } #endif // drop elevated privileges if (drop_privileges && (getuid() == 0 || geteuid() == 0)) { struct passwd *pw; if (!drop_user) { usbmuxd_log(LL_FATAL, "No user to drop privileges to?"); res = -1; goto terminate; } pw = getpwnam(drop_user); if (!pw) { usbmuxd_log(LL_FATAL, "Dropping privileges failed, check if user '%s' exists!", drop_user); res = -1; goto terminate; } if (pw->pw_uid == 0) { usbmuxd_log(LL_INFO, "Not dropping privileges to root"); } else { #ifdef HAVE_LIBIMOBILEDEVICE /* make sure the non-privileged user has proper access to the config directory */ if ((fst.st_uid != pw->pw_uid) || (fst.st_gid != pw->pw_gid)) { if (chown(userprefdir, pw->pw_uid, pw->pw_gid) < 0) { usbmuxd_log(LL_WARNING, "chown(%s, %d, %d) failed: %s", userprefdir, pw->pw_uid, pw->pw_gid, strerror(errno)); } } #endif if ((res = initgroups(drop_user, pw->pw_gid)) < 0) { usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set supplementary groups)"); goto terminate; } if ((res = setgid(pw->pw_gid)) < 0) { usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set group ID to %d)", pw->pw_gid); goto terminate; } if ((res = setuid(pw->pw_uid)) < 0) { usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set user ID to %d)", pw->pw_uid); goto terminate; } // security check if (setuid(0) != -1) { usbmuxd_log(LL_FATAL, "Failed to drop privileges properly!"); res = -1; goto terminate; } if (getuid() != pw->pw_uid || getgid() != pw->pw_gid) { usbmuxd_log(LL_FATAL, "Failed to drop privileges properly!"); res = -1; goto terminate; } usbmuxd_log(LL_NOTICE, "Successfully dropped privileges to '%s'", drop_user); } } client_init(); device_init(); usbmuxd_log(LL_INFO, "Initializing USB"); if((res = usb_init()) < 0) goto terminate; usbmuxd_log(LL_INFO, "%d device%s detected", res, (res==1)?"":"s"); usbmuxd_log(LL_NOTICE, "Initialization complete"); if (report_to_parent) if((res = notify_parent(0)) < 0) goto terminate; if(opt_disable_hotplug) { usbmuxd_log(LL_NOTICE, "Automatic device discovery on hotplug disabled."); usb_autodiscover(0); // discovery to be triggered by new instance } if (opt_enable_exit) { usbmuxd_log(LL_NOTICE, "Enabled exit on SIGUSR1 if no devices are attached. Start a new instance with \"--exit\" to trigger."); } res = main_loop(listenfd); if(res < 0) usbmuxd_log(LL_FATAL, "main_loop failed"); usbmuxd_log(LL_NOTICE, "usbmuxd shutting down"); device_kill_connections(); usb_shutdown(); device_shutdown(); client_shutdown(); usbmuxd_log(LL_NOTICE, "Shutdown complete"); terminate: log_disable_syslog(); if (res < 0) res = -res; else res = 0; if (report_to_parent) notify_parent(res); return res; }
/* * Reboot system call: for obvious reasons only root may call it, * and even root needs to set up some magic numbers in the registers * so that some mistake won't make this reboot the whole machine. * You can also set the meaning of the ctrl-alt-del-key here. * * reboot doesn't sync: do that yourself before calling this. */ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg) { char buffer[256]; /* We only trust the superuser with rebooting the system. */ if (!capable(CAP_SYS_BOOT)) return -EPERM; /* For safety, we require "magic" arguments. */ if (magic1 != LINUX_REBOOT_MAGIC1 || (magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A && magic2 != LINUX_REBOOT_MAGIC2B && magic2 != LINUX_REBOOT_MAGIC2C)) return -EINVAL; lock_kernel(); switch (cmd) { case LINUX_REBOOT_CMD_RESTART: notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); system_state = SYSTEM_RESTART; device_shutdown(); printk(KERN_EMERG "Restarting system.\n"); machine_restart(NULL); break; case LINUX_REBOOT_CMD_CAD_ON: C_A_D = 1; break; case LINUX_REBOOT_CMD_CAD_OFF: C_A_D = 0; break; case LINUX_REBOOT_CMD_HALT: notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); system_state = SYSTEM_HALT; device_shutdown(); printk(KERN_EMERG "System halted.\n"); machine_halt(); unlock_kernel(); do_exit(0); break; case LINUX_REBOOT_CMD_POWER_OFF: notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); system_state = SYSTEM_POWER_OFF; device_shutdown(); printk(KERN_EMERG "Power down.\n"); machine_power_off(); unlock_kernel(); do_exit(0); break; case LINUX_REBOOT_CMD_RESTART2: if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) { unlock_kernel(); return -EFAULT; } buffer[sizeof(buffer) - 1] = '\0'; notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer); system_state = SYSTEM_RESTART; device_shutdown(); printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer); machine_restart(buffer); break; #ifdef CONFIG_SOFTWARE_SUSPEND case LINUX_REBOOT_CMD_SW_SUSPEND: { int ret = software_suspend(); unlock_kernel(); return ret; } #endif default: unlock_kernel(); return -EINVAL; } unlock_kernel(); return 0; }
/** * kernel_power_off - power_off the system * * Shutdown everything and perform a clean system power_off. */ void kernel_power_off_prepare(void) { notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); system_state = SYSTEM_POWER_OFF; device_shutdown(); }
/** * kernel_halt - halt the system * * Shutdown everything and perform a clean system halt. */ void kernel_halt_prepare(void) { notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); system_state = SYSTEM_HALT; device_shutdown(); }