1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/*
* 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);
|