static int device_add_udev_wants(Unit *u, struct udev_device *dev) { const char *wants, *property, *p; int r; assert(u); assert(dev); property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS"; wants = udev_device_get_property_value(dev, property); for (p = wants;;) { _cleanup_free_ char *word = NULL, *k = NULL; r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); if (r == 0) return 0; if (r == -ENOMEM) return log_oom(); if (r < 0) return log_unit_error_errno(u, r, "Failed to add parse %s: %m", property); r = unit_name_mangle(word, UNIT_NAME_NOGLOB, &k); if (r < 0) return log_unit_error_errno(u, r, "Failed to mangle unit name \"%s\": %m", word); r = unit_add_dependency_by_name(u, UNIT_WANTS, k, NULL, true); if (r < 0) return log_unit_error_errno(u, r, "Failed to add wants dependency: %m"); } }
int emergency_action( Manager *m, EmergencyAction action, EmergencyActionFlags options, const char *reboot_arg, int exit_status, const char *reason) { assert(m); assert(action >= 0); assert(action < _EMERGENCY_ACTION_MAX); if (action == EMERGENCY_ACTION_NONE) return -ECANCELED; if (FLAGS_SET(options, EMERGENCY_ACTION_IS_WATCHDOG) && !m->service_watchdogs) { log_warning("Watchdog disabled! Not acting on: %s", reason); return -ECANCELED; } bool warn = FLAGS_SET(options, EMERGENCY_ACTION_WARN); switch (action) { case EMERGENCY_ACTION_REBOOT: log_and_status(m, warn, "Rebooting", reason); (void) update_reboot_parameter_and_warn(reboot_arg); (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL); break; case EMERGENCY_ACTION_REBOOT_FORCE: log_and_status(m, warn, "Forcibly rebooting", reason); (void) update_reboot_parameter_and_warn(reboot_arg); m->objective = MANAGER_REBOOT; break; case EMERGENCY_ACTION_REBOOT_IMMEDIATE: log_and_status(m, warn, "Rebooting immediately", reason); sync(); if (!isempty(reboot_arg)) { log_info("Rebooting with argument '%s'.", reboot_arg); (void) raw_reboot(LINUX_REBOOT_CMD_RESTART2, reboot_arg); log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m"); } log_info("Rebooting."); (void) reboot(RB_AUTOBOOT); break; case EMERGENCY_ACTION_EXIT: if (exit_status >= 0) m->return_value = exit_status; if (MANAGER_IS_USER(m) || detect_container() > 0) { log_and_status(m, warn, "Exiting", reason); (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL); break; } log_notice("Doing \"poweroff\" action instead of an \"exit\" emergency action."); _fallthrough_; case EMERGENCY_ACTION_POWEROFF: log_and_status(m, warn, "Powering off", reason); (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL); break; case EMERGENCY_ACTION_EXIT_FORCE: if (exit_status >= 0) m->return_value = exit_status; if (MANAGER_IS_USER(m) || detect_container() > 0) { log_and_status(m, warn, "Exiting immediately", reason); m->objective = MANAGER_EXIT; break; } log_notice("Doing \"poweroff-force\" action instead of an \"exit-force\" emergency action."); _fallthrough_; case EMERGENCY_ACTION_POWEROFF_FORCE: log_and_status(m, warn, "Forcibly powering off", reason); m->objective = MANAGER_POWEROFF; break; case EMERGENCY_ACTION_POWEROFF_IMMEDIATE: log_and_status(m, warn, "Powering off immediately", reason); sync(); log_info("Powering off."); (void) reboot(RB_POWER_OFF); break; default: assert_not_reached("Unknown emergency action"); } return -ECANCELED; }