/* * This file is part of activationd. * * Copyright © 2019 Samsung Electronics * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "action.h" #include "action_executor.h" #include "decision_made_event.h" #include "log.h" #include "systemd_dbus.h" #include "common.h" static int unit_action_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { struct action_executed_event *exe_info = userdata; int ret; if (!exe_info) return -EINVAL; exe_info->result = 0; ret = event_processor_report_event(&exe_info->event); epc_event_unref(&exe_info->event); return ret; } static int start_unit(struct epc_action *action, struct action_executed_event *exe_info) { struct epc_event *ev = pop_epc_event(&action->execution_queue); struct decision_made_event *dm_ev = to_decision_made_event(ev); char *unit_name = NULL; char *unit_action = NULL; int ret; /* * We are passing an event to exe_info, so there is no need to unref it * in this function */ exe_info->reason = ev; ret = epc_object_get_string(dm_ev->action_data, EPC_AD_UNIT_NAME, &unit_name); if (!unit_name) { epc_object_append_string(exe_info->action_log, "error", "Unit name not specified"); exe_info->result = -EINVAL; return 0; } epc_object_get_string(dm_ev->action_data, EPC_AD_UNIT_ACTION, &unit_action); if (!unit_action) { epc_object_append_string(exe_info->action_log, "error", "Unit action not specified"); exe_info->result = -EINVAL; return 0; } if (strcmp(unit_action, "StartUnit") && strcmp(unit_action, "StopUnit") && strcmp(unit_action, "RestartUnit")) { epc_object_append_string(exe_info->action_log, "error", "Unit action is not one of \"StartUnit\", " "\"StopUnit\" or \"RestartUnit\""); exe_info->result = -EINVAL; return 0; } ret = epc_dbus_call_systemd_simple_async(SYSTEMD_OBJ, SYSTEMD_MANAGER_INTERFACE, unit_action, unit_action_handler, exe_info, "ss", unit_name, "replace"); if (ret < 0) epc_object_append_string(exe_info->action_log, "error", "Failed to call systemd"); else log_kmsg("Starting unit: %s", unit_name); exe_info->result = -EPROBE_DEFER; epc_event_ref(&exe_info->event); return 0; } static struct epc_action unit_start_action = { .action_id = EPC_ACTION_UNIT_START_ID, .impl_name = EPC_DEFAULT_ACTION_IMPL, .execute = start_unit, .node = LIST_HEAD_INIT(unit_start_action.node), }; EPC_ACTION_REGISTER_SIMPLE(unit_start_action);