1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <unistd.h>
17 #include <linux/reboot.h>
18 #include <sys/reboot.h>
19 #include <sys/syscall.h>
20
21 #include "reboot_adp.h"
22 #include "init_cmdexecutor.h"
23 #include "init_module_engine.h"
24 #include "plugin_adapter.h"
25 #include "securec.h"
26
DoRoot_(const char * jobName,int type)27 PLUGIN_STATIC int DoRoot_(const char *jobName, int type)
28 {
29 // by job to stop service and unmount
30 if (jobName != NULL) {
31 DoJobNow(jobName);
32 }
33 #ifndef STARTUP_INIT_TEST
34 return reboot(type);
35 #else
36 return 0;
37 #endif
38 }
39
DoReboot(int id,const char * name,int argc,const char ** argv)40 static int DoReboot(int id, const char *name, int argc, const char **argv)
41 {
42 UNUSED(id);
43 UNUSED(name);
44 UNUSED(argc);
45 UNUSED(argv);
46 // clear misc
47 (void)UpdateMiscMessage(NULL, "reboot", NULL, NULL);
48 return DoRoot_("reboot", RB_AUTOBOOT);
49 }
50
DoRebootPanic(int id,const char * name,int argc,const char ** argv)51 static int DoRebootPanic(int id, const char *name, int argc, const char **argv)
52 {
53 UNUSED(id);
54 UNUSED(name);
55 UNUSED(argc);
56 UNUSED(argv);
57 // clear misc
58 (void)UpdateMiscMessage(NULL, "reboot", NULL, NULL);
59 DoJobNow("reboot");
60 #ifndef STARTUP_INIT_TEST
61 FILE *panic = fopen("/proc/sysrq-trigger", "wb");
62 if (panic == NULL) {
63 return reboot(RB_AUTOBOOT);
64 }
65 if (fwrite((void *)"c", 1, 1, panic) != 1) {
66 (void)fclose(panic);
67 PLUGIN_LOGI("fwrite to panic failed");
68 return -1;
69 }
70 (void)fclose(panic);
71 #endif
72 return 0;
73 }
74
DoRebootShutdown(int id,const char * name,int argc,const char ** argv)75 PLUGIN_STATIC int DoRebootShutdown(int id, const char *name, int argc, const char **argv)
76 {
77 UNUSED(id);
78 UNUSED(name);
79 UNUSED(argc);
80 UNUSED(argv);
81 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
82 // clear misc
83 (void)UpdateMiscMessage(NULL, "reboot", NULL, NULL);
84 const size_t len = strlen("reboot,");
85 const char *cmd = strstr(argv[0], "reboot,");
86 if (cmd != NULL && strlen(cmd) > len) {
87 PLUGIN_LOGI("DoRebootShutdown argv %s", cmd + len);
88 // by job to stop service and unmount
89 DoJobNow("reboot");
90 #ifndef STARTUP_INIT_TEST
91 return syscall(__NR_reboot,
92 LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_POWER_OFF, cmd + len);
93 #else
94 return 0;
95 #endif
96 }
97 return DoRoot_("reboot", RB_POWER_OFF);
98 }
99
DoRebootUpdater(int id,const char * name,int argc,const char ** argv)100 static int DoRebootUpdater(int id, const char *name, int argc, const char **argv)
101 {
102 UNUSED(id);
103 PLUGIN_LOGI("DoRebootUpdater argc %d %s", argc, name);
104 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
105 PLUGIN_LOGI("DoRebootUpdater argv %s", argv[0]);
106 int ret = UpdateMiscMessage(argv[0], "updater", "updater:", "boot_updater");
107 if (ret == 0) {
108 return DoRoot_("reboot", RB_AUTOBOOT);
109 }
110 return ret;
111 }
112
DoRebootFlashed(int id,const char * name,int argc,const char ** argv)113 PLUGIN_STATIC int DoRebootFlashed(int id, const char *name, int argc, const char **argv)
114 {
115 UNUSED(id);
116 PLUGIN_LOGI("DoRebootFlashed argc %d %s", argc, name);
117 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
118 PLUGIN_LOGI("DoRebootFlashd argv %s", argv[0]);
119 int ret = UpdateMiscMessage(argv[0], "flash", "flash:", "boot_flash");
120 if (ret == 0) {
121 return DoRoot_("reboot", RB_AUTOBOOT);
122 }
123 return ret;
124 }
125
DoRebootCharge(int id,const char * name,int argc,const char ** argv)126 PLUGIN_STATIC int DoRebootCharge(int id, const char *name, int argc, const char **argv)
127 {
128 UNUSED(id);
129 UNUSED(name);
130 UNUSED(argc);
131 UNUSED(argv);
132 int ret = UpdateMiscMessage(NULL, "charge", "charge:", "boot_charge");
133 if (ret == 0) {
134 return DoRoot_("reboot", RB_AUTOBOOT);
135 }
136 return ret;
137 }
138
DoRebootSuspend(int id,const char * name,int argc,const char ** argv)139 static int DoRebootSuspend(int id, const char *name, int argc, const char **argv)
140 {
141 UNUSED(id);
142 UNUSED(name);
143 UNUSED(argc);
144 UNUSED(argv);
145 return DoRoot_("suspend", RB_AUTOBOOT);
146 }
147
DoRebootOther(int id,const char * name,int argc,const char ** argv)148 PLUGIN_STATIC int DoRebootOther(int id, const char *name, int argc, const char **argv)
149 {
150 UNUSED(id);
151 UNUSED(name);
152 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter argc %d", argc);
153 const char *cmd = strstr(argv[0], "reboot,");
154 PLUGIN_CHECK(cmd != NULL, return -1, "Invalid parameter argc %s", argv[0]);
155 PLUGIN_LOGI("DoRebootOther argv %s", argv[0]);
156 #ifndef STARTUP_INIT_TEST
157 return syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
158 LINUX_REBOOT_CMD_RESTART2, cmd + strlen("reboot,"));
159 #else
160 return 0;
161 #endif
162 }
163
RebootAdpInit(void)164 static void RebootAdpInit(void)
165 {
166 // add default reboot cmd
167 (void)AddCmdExecutor("reboot", DoReboot);
168 (void)AddCmdExecutor("reboot.other", DoRebootOther);
169 AddRebootCmdExecutor("shutdown", DoRebootShutdown);
170 AddRebootCmdExecutor("flashd", DoRebootFlashed);
171 AddRebootCmdExecutor("updater", DoRebootUpdater);
172 AddRebootCmdExecutor("charge", DoRebootCharge);
173 AddRebootCmdExecutor("suspend", DoRebootSuspend);
174 AddRebootCmdExecutor("panic", DoRebootPanic);
175 (void)AddCmdExecutor("panic", DoRebootPanic);
176 }
177
MODULE_CONSTRUCTOR(void)178 MODULE_CONSTRUCTOR(void)
179 {
180 PLUGIN_LOGI("Reboot adapter plug-in init now ...");
181 RebootAdpInit();
182 }
183
MODULE_DESTRUCTOR(void)184 MODULE_DESTRUCTOR(void)
185 {
186 PLUGIN_LOGI("Reboot adapter plug-in exit now ...");
187 }
188