2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 ///////////////////////////////////////////////////////////////////////////////
18 /// \ingroup tag_SystemManager
19 /// \brief This file provides support for process launching and termination.
21 ///////////////////////////////////////////////////////////////////////////////
22 #include <native_service/frameworkunified_framework_if.h>
23 #include <native_service/frameworkunified_multithreading.h>
24 #include <system_service/ss_templates.h>
25 #include <system_service/ss_string_maps.h>
26 #include <native_service/ns_plogger_if.h>
29 #include "ProcessLauncher.h"
30 #include "ss_sm_process_launcher_protocol.h"
31 #include "ss_sm_process_launcher.h"
32 #include "ss_sm_systemmanagerlog.h"
33 #include "ss_sm_signals.h"
35 CProcessLauncher::CProcessLauncher() { // LCOV_EXCL_START 8: dead code
36 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
40 CProcessLauncher::CProcessLauncher(void *) {
43 CProcessLauncher::~CProcessLauncher() { // LCOV_EXCL_START 14: resident process end
44 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
45 m_mapOfProcesses.clear();
49 EFrameworkunifiedStatus CProcessLauncher::PLTerminateModule(
51 T_ProcessLauncherTerminationResp *f_pTerminateRespData) {
52 EFrameworkunifiedStatus l_eStatus;
53 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
55 T_ProcessLauncherTerminationReq l_ModuleTerminateReq;
57 // LCOV_EXCL_BR_START 4:NSFW error case
58 if (eFrameworkunifiedStatusOK
59 != (l_eStatus = ReadMsg < T_ProcessLauncherTerminationReq > (hThread, l_ModuleTerminateReq, eSMRRetain))) {
61 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
62 LOG_ERROR("ReadMsg()"); // LCOV_EXCL_LINE 4:NSFW error case
64 // get pointer to the process object launched earlier
65 Process * l_pProcessPtr = m_mapOfProcesses[l_ModuleTerminateReq.path]; // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
67 // Confirm that the process pointer for the module exists in the map
68 if (NULL != l_pProcessPtr) { // LCOV_EXCL_BR_LINE 200: l_pProcessPtr must not be null
69 // check if process still exists
70 if (l_pProcessPtr->DoesProcessExist()) {
71 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__,
72 " Terminating %s, PID: %d.", l_ModuleTerminateReq.path, l_pProcessPtr->GetProcessId());
73 // kill unresponsive process
74 l_pProcessPtr->KillProcess(SS_SM_ABORT_SIGNAL);
76 if (NULL != f_pTerminateRespData) { // LCOV_EXCL_BR_LINE 200: f_pTerminateRespData must not be null
77 std::strcpy(f_pTerminateRespData->name, // NOLINT
78 l_ModuleTerminateReq.name);
79 std::strcpy(f_pTerminateRespData->path, // NOLINT
80 l_ModuleTerminateReq.path);
81 std::strcpy(f_pTerminateRespData->args, // NOLINT
82 l_ModuleTerminateReq.args);
83 f_pTerminateRespData->moduleIterator =
84 l_ModuleTerminateReq.moduleIterator;
85 f_pTerminateRespData->groupIterator =
86 l_ModuleTerminateReq.groupIterator;
89 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Info: %s has already terminated.", l_ModuleTerminateReq.path);
91 l_eStatus = eFrameworkunifiedStatusServNotFound;
93 // remove process entry
94 m_mapOfProcesses.erase(l_ModuleTerminateReq.path);
95 // delete process object
96 delete l_pProcessPtr; // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
97 } else { // LCOV_EXCL_BR_LINE 200: l_pProcessPtr will not be null
98 // LCOV_EXCL_START 200: l_pProcessPtr will not be null
99 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
100 l_eStatus = eFrameworkunifiedStatusDbRecNotFound;
101 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error: %s not in m_mapOfProcesses", l_ModuleTerminateReq.path);
105 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
109 EFrameworkunifiedStatus CProcessLauncher::PLOnCmdTerminateModule(HANDLE hThread) {
110 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
111 EFrameworkunifiedStatus l_eStatus;
113 T_ProcessLauncherTerminationResp l_TerminateRespData;
114 if (eFrameworkunifiedStatusOK == (l_eStatus = PLTerminateModule(hThread, &l_TerminateRespData))) {
115 // reply to System Manager about successful module termination
116 l_eStatus = FrameworkunifiedSendParent(hThread,
117 ePLThrdCmd_TERMINATE_MODULE_RESP,
118 sizeof(l_TerminateRespData),
119 &l_TerminateRespData);
120 LOG_STATUS(l_eStatus, "FrameworkunifiedSendParent(ePLThrdCmd_TERMINATE_MODULE_RESP"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length)
121 } else if (eFrameworkunifiedStatusServNotFound == l_eStatus) { // Already terminated
122 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Info. Module already terminated.");
124 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
125 " Error: PLTerminateModule(%s) errored: %d/'%s'",
126 l_TerminateRespData.name, l_eStatus, GetStr(l_eStatus).c_str());
128 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
132 EFrameworkunifiedStatus CProcessLauncher::PLOnCmdModuleStatus(HANDLE hThread) {
133 return eFrameworkunifiedStatusOK;
136 VOID buildArgList(StringList& arg_list, PSTR args) { // NOLINT
139 pch = std::strtok(args, " ");
140 while (pch != NULL) {
141 arg_list.push_back(pch);
142 pch = std::strtok(NULL, " ");
146 EFrameworkunifiedStatus CProcessLauncher::PLLaunchModule(HANDLE hThread, T_ProcessLaunchResp &f_LaunchRespData) {
147 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
148 EFrameworkunifiedStatus l_eStatus;
149 Process *l_pProcessPtr = NULL;
150 T_ProcessLauncherLaunchReq l_ModuleLaunchReq;
152 // LCOV_EXCL_BR_START 4:NSFW error case
153 if (eFrameworkunifiedStatusOK
154 != (l_eStatus = ReadMsg < T_ProcessLauncherLaunchReq > (hThread, l_ModuleLaunchReq))) {
156 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
157 LOG_ERROR("ReadMsg()"); // LCOV_EXCL_LINE 4:NSFW error case
159 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__,
160 "Sending to Launcher name: %s, path: %s, args: %s, lmsk: %s, "
161 "prio: %d ", l_ModuleLaunchReq.name,
162 l_ModuleLaunchReq.path, l_ModuleLaunchReq.args,
163 l_ModuleLaunchReq.logging_mask, l_ModuleLaunchReq.priority);
166 buildArgList(args, l_ModuleLaunchReq.args); // LCOV_EXCL_BR_LINE 15: marco defined in ns_logger_if.h // NOLINT(whitespace/line_length)
168 int log_mask_str_len = static_cast<int>(std::strlen(l_ModuleLaunchReq.logging_mask));
169 if (log_mask_str_len > 0) {
170 // Create mask argument to be passed to application.
171 // The argument must be of the form "-m 0x00000000,0x00000000,...", assuming n 32-bit mask values.
172 // The storage size of the argument must include one byte for the NULL termination character.
173 args.push_back("-m");
174 args.push_back(l_ModuleLaunchReq.logging_mask);
175 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " %s args: logging_mask: %s",
176 l_ModuleLaunchReq.path, l_ModuleLaunchReq.logging_mask);
178 FRAMEWORKUNIFIEDLOG(ZONE_PROC_LAUNCH_INFO, __FUNCTION__,
179 " '%s' has no logging_mask specified. Using compile time defaults.",
180 l_ModuleLaunchReq.path);
183 std::strcpy(f_LaunchRespData.name, l_ModuleLaunchReq.name); // NOLINT Module queue name
184 std::strcpy(f_LaunchRespData.path, l_ModuleLaunchReq.path); // NOLINT Module path and file name
185 std::strcpy(f_LaunchRespData.args, l_ModuleLaunchReq.args); // NOLINT
186 f_LaunchRespData.moduleIterator = l_ModuleLaunchReq.moduleIterator;
187 f_LaunchRespData.groupIterator = l_ModuleLaunchReq.groupIterator;
189 // Process exists? If not, re-launch the process and create a new map entry.
190 l_pProcessPtr = m_mapOfProcesses[l_ModuleLaunchReq.path]; // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
191 if (NULL == l_pProcessPtr) { // LCOV_EXCL_BR_LINE 200: l_pProcessPtr must not be null
192 FRAMEWORKUNIFIEDLOG(ZONE_PROC_LAUNCH_INFO, __FUNCTION__,
193 " '%s' is not in the module map. Creating new process.",
194 l_ModuleLaunchReq.name);
196 SS_String sPathAndFileName = l_ModuleLaunchReq.path; // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
197 l_pProcessPtr = new (std::nothrow) Process(l_ModuleLaunchReq.cpu_assign); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
199 if (NULL == l_pProcessPtr) { // LCOV_EXCL_BR_LINE 11::new operation failed
200 // LCOV_EXCL_START 11::new operation failed
201 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
202 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error: Process() returned NULL");
203 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
204 return eFrameworkunifiedStatusThreadNotExist;
205 // LCOV_EXCL_STOP 11::new operation failed
209 ('\0' == f_LaunchRespData.moduleIterator->unix_user_name[0]) ?
210 NULL : &f_LaunchRespData.moduleIterator->unix_user_name[0]; // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
212 l_pProcessPtr->CreateProcess(sPathAndFileName, "", l_ModuleLaunchReq.priority, args, uname); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
214 FRAMEWORKUNIFIEDLOG(ZONE_PROC_LAUNCH_INFO, __FUNCTION__,
215 " Process Name: %s Process File: %s Pid: %d Is Alive: %s\n",
216 l_pProcessPtr->GetProcessName().data(),
217 l_pProcessPtr->GetExecutableFileName(),
218 l_pProcessPtr->GetProcessId(),
219 (l_pProcessPtr->DoesProcessExist() == FALSE) ? "No" : "Yes");
221 // Add the process in the map
222 m_mapOfProcesses[l_ModuleLaunchReq.path] = l_pProcessPtr; // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
225 f_LaunchRespData.pid = l_pProcessPtr->GetProcessId();
226 f_LaunchRespData.priority = l_pProcessPtr->GetPriority(); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
227 l_eStatus = eFrameworkunifiedStatusOK;
229 // LCOV_EXCL_START 200: l_pProcessPtr must not be null
230 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
231 FRAMEWORKUNIFIEDLOG(ZONE_PROC_LAUNCH_INFO, __FUNCTION__,
232 " %s already in Process Map", l_ModuleLaunchReq.name);
233 // the module is already in the list. Send the response to system manager with PID 0x7FFFFFFF
234 f_LaunchRespData.pid = 0x7FFFFFFF;
235 f_LaunchRespData.priority = l_ModuleLaunchReq.priority;
236 l_eStatus = eFrameworkunifiedStatusOK;
241 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
245 EFrameworkunifiedStatus CProcessLauncher::PLOnCmdLaunchModule(HANDLE hThread) {
246 EFrameworkunifiedStatus l_eStatus;
247 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
249 l_eStatus = PLCmdLaunchModule(hThread, ePLThrdCmd_LAUNCH_MODULE_RESP, "ePLThrdCmd_LAUNCH_MODULE_RESP"); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
250 LOG_STATUS_IF_ERRORED(l_eStatus, " PLCmdLaunchModule(ePLThrdCmd_LAUNCH_MODULE_RESP)"); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
252 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
256 EFrameworkunifiedStatus CProcessLauncher::PLOnCmdRelaunchModule(HANDLE hThread) {
257 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
258 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
260 // Terminate unresponsive module
261 CALL_AND_LOG_STATUS(PLTerminateModule(hThread)); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length)
263 l_eStatus = PLCmdLaunchModule(hThread, ePLThrdCmd_RELAUNCH_MODULE_RESP, "ePLThrdCmd_RELAUNCH_MODULE_RESP"); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
264 LOG_STATUS_IF_ERRORED(l_eStatus, "PLCmdLaunchModule(ePLThrdCmd_RELAUNCH_MODULE_RESP)"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length)
266 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
270 EFrameworkunifiedStatus CProcessLauncher::PLCmdLaunchModule(HANDLE hThread, UI_32 f_protocol_ID, std::string f_protocol_str) {
271 EFrameworkunifiedStatus l_eStatus;
272 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
274 T_ProcessLaunchResp l_LaunchRespData;
275 l_LaunchRespData.pid = 0;
276 if (eFrameworkunifiedStatusOK != (l_eStatus = PLLaunchModule(hThread, l_LaunchRespData))) { // LCOV_EXCL_BR_LINE 4:NSFW error case
277 // LCOV_EXCL_START 4:NSFW error case
278 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
279 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
280 " Error: PLLaunchModule(%s, %s) errored: %d/'%s'",
281 l_LaunchRespData.name, f_protocol_str.c_str(), l_eStatus,
282 GetStr(l_eStatus).c_str());
283 // LCOV_EXCL_STOP 4:NSFW error case
285 l_eStatus = FrameworkunifiedSendParent(hThread, f_protocol_ID,
286 sizeof(T_ProcessLaunchResp), &l_LaunchRespData);
288 if (eFrameworkunifiedStatusOK != l_eStatus) { // LCOV_EXCL_BR_LINE 4:NSFW error case
289 // LCOV_EXCL_START 4:NSFW error case
290 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
291 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
292 " Error: FrameworkunifiedSendParent( %s, %s ) errored: %d/'%s'",
293 l_LaunchRespData.name, f_protocol_str.c_str(), l_eStatus,
294 GetStr(l_eStatus).c_str());
295 // LCOV_EXCL_STOP 4:NSFW
299 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
303 EFrameworkunifiedStatus CProcessLauncher::PLOnCmdStop(HANDLE hThread) { // LCOV_EXCL_START 14: resident process end
304 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
305 return eFrameworkunifiedStatusOK;
309 EFrameworkunifiedStatus CProcessLauncher::PLOnCmdStart(HANDLE hThread) {
310 return eFrameworkunifiedStatusOK;
313 EFrameworkunifiedStatus CProcessLauncher::PLOnCmdHeartbeatStatusReq(HANDLE hThread) {
314 FrameworkunifiedSendParent(hThread, ePLThrdCmd_THREAD_STATUS_RESP, 0, NULL);
315 return eFrameworkunifiedStatusOK;