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 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 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 // clear misc
82 (void)UpdateMiscMessage(NULL, "reboot", NULL, NULL);
83 return DoRoot_("reboot", RB_POWER_OFF);
84 }
85
DoRebootUpdater(int id,const char * name,int argc,const char ** argv)86 static int DoRebootUpdater(int id, const char *name, int argc, const char **argv)
87 {
88 UNUSED(id);
89 PLUGIN_LOGI("DoRebootUpdater argc %d %s", argc, name);
90 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
91 PLUGIN_LOGI("DoRebootUpdater argv %s", argv[0]);
92 int ret = UpdateMiscMessage(argv[0], "updater", "updater:", "boot_updater");
93 if (ret == 0) {
94 return DoRoot_("reboot", RB_AUTOBOOT);
95 }
96 return ret;
97 }
98
DoRebootFlashed(int id,const char * name,int argc,const char ** argv)99 static int DoRebootFlashed(int id, const char *name, int argc, const char **argv)
100 {
101 UNUSED(id);
102 PLUGIN_LOGI("DoRebootFlashed argc %d %s", argc, name);
103 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
104 PLUGIN_LOGI("DoRebootFlashd argv %s", argv[0]);
105 int ret = UpdateMiscMessage(argv[0], "flash", "flash:", "boot_flash");
106 if (ret == 0) {
107 return DoRoot_("reboot", RB_AUTOBOOT);
108 }
109 return ret;
110 }
111
DoRebootCharge(int id,const char * name,int argc,const char ** argv)112 static int DoRebootCharge(int id, const char *name, int argc, const char **argv)
113 {
114 UNUSED(id);
115 UNUSED(name);
116 UNUSED(argc);
117 UNUSED(argv);
118 int ret = UpdateMiscMessage(NULL, "charge", "charge:", "boot_charge");
119 if (ret == 0) {
120 return DoRoot_("reboot", RB_AUTOBOOT);
121 }
122 return ret;
123 }
124
DoRebootSuspend(int id,const char * name,int argc,const char ** argv)125 static int DoRebootSuspend(int id, const char *name, int argc, const char **argv)
126 {
127 UNUSED(id);
128 UNUSED(name);
129 UNUSED(argc);
130 UNUSED(argv);
131 return DoRoot_("suspend", RB_AUTOBOOT);
132 }
133
DoRebootOther(int id,const char * name,int argc,const char ** argv)134 static int DoRebootOther(int id, const char *name, int argc, const char **argv)
135 {
136 UNUSED(id);
137 UNUSED(name);
138 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter argc %d", argc);
139 const char *cmd = strstr(argv[0], "reboot,");
140 PLUGIN_CHECK(cmd != NULL, return -1, "Invalid parameter argc %s", argv[0]);
141 PLUGIN_LOGI("DoRebootOther argv %s", argv[0]);
142 return syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
143 LINUX_REBOOT_CMD_RESTART2, cmd + strlen("reboot,"));
144 }
145
RebootAdpInit(void)146 static void RebootAdpInit(void)
147 {
148 // add default reboot cmd
149 (void)AddCmdExecutor("reboot", DoReboot);
150 (void)AddCmdExecutor("reboot.other", DoRebootOther);
151 AddRebootCmdExecutor("shutdown", DoRebootShutdown);
152 AddRebootCmdExecutor("flashd", DoRebootFlashed);
153 AddRebootCmdExecutor("updater", DoRebootUpdater);
154 AddRebootCmdExecutor("charge", DoRebootCharge);
155 AddRebootCmdExecutor("suspend", DoRebootSuspend);
156 AddRebootCmdExecutor("panic", DoRebootPanic);
157 (void)AddCmdExecutor("panic", DoRebootPanic);
158 }
159
MODULE_CONSTRUCTOR(void)160 MODULE_CONSTRUCTOR(void)
161 {
162 PLUGIN_LOGI("Reboot adapter plug-in init now ...");
163 RebootAdpInit();
164 }
165
MODULE_DESTRUCTOR(void)166 MODULE_DESTRUCTOR(void)
167 {
168 PLUGIN_LOGI("Reboot adapter plug-in exit now ...");
169 }
170