1 |
commit: 05738bfce120114037d4f02c67ec740813f94b89 |
2 |
Author: William Hubbs <w.d.hubbs <AT> gmail <DOT> com> |
3 |
AuthorDate: Wed Apr 12 22:56:30 2017 +0000 |
4 |
Commit: William Hubbs <williamh <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Apr 12 22:56:36 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/openrc.git/commit/?id=05738bfc |
7 |
|
8 |
init: add re-exec capability |
9 |
|
10 |
This will allow the re-execution of the init process after upgrading |
11 |
OpenRC. |
12 |
|
13 |
man/openrc-shutdown.8 | 7 ++++++- |
14 |
src/rc/openrc-init.c | 22 +++++++++++++++++++--- |
15 |
src/rc/openrc-shutdown.c | 14 ++++++++++++-- |
16 |
3 files changed, 37 insertions(+), 6 deletions(-) |
17 |
|
18 |
diff --git a/man/openrc-shutdown.8 b/man/openrc-shutdown.8 |
19 |
index 98ec64a6..eae16ae8 100644 |
20 |
--- a/man/openrc-shutdown.8 |
21 |
+++ b/man/openrc-shutdown.8 |
22 |
@@ -19,11 +19,13 @@ |
23 |
.Op Fl H , -halt |
24 |
.Op Fl k , -kexec |
25 |
.Op Fl p , -poweroff |
26 |
+.Op Fl R , -reexec |
27 |
.Op Fl r , -reboot |
28 |
.Sh DESCRIPTION |
29 |
.Nm |
30 |
is the utility that communicates with openrc-init(8) to bring down the |
31 |
-system. The following options affect how the system is brought down: |
32 |
+system or instruct openrc-init to re-execute itself. It supports the |
33 |
+following options: |
34 |
.Bl -tag -width "poweroff" |
35 |
.It Fl H , -halt |
36 |
Stop all services, kill all remaining processes and halt the system. |
37 |
@@ -32,6 +34,9 @@ Stop all services, kill all processes and boot directly into a new |
38 |
kernel loaded via kexec(8). |
39 |
.It Fl p , -poweroff |
40 |
Stop all services, kill all processes and power off the system. |
41 |
+.It Fl R , -reexec |
42 |
+instruct openrc-init to re-exec itself. This should be used after an |
43 |
+upgrade of OpenRC if you are using openrc-init as your init process. |
44 |
.It Fl r , -reboot |
45 |
Stop all services, kill all processes and reboot the system. |
46 |
.El |
47 |
|
48 |
diff --git a/src/rc/openrc-init.c b/src/rc/openrc-init.c |
49 |
index fb3347a4..61052806 100644 |
50 |
--- a/src/rc/openrc-init.c |
51 |
+++ b/src/rc/openrc-init.c |
52 |
@@ -20,6 +20,7 @@ |
53 |
|
54 |
#include <errno.h> |
55 |
#include <signal.h> |
56 |
+#include <stdbool.h> |
57 |
#include <stdio.h> |
58 |
#include <stdlib.h> |
59 |
#include <string.h> |
60 |
@@ -79,6 +80,12 @@ static void init(const char *default_runlevel) |
61 |
waitpid(pid, NULL, 0); |
62 |
} |
63 |
|
64 |
+static void handle_reexec(char *my_name) |
65 |
+{ |
66 |
+ execl(my_name, my_name, "reexec", NULL); |
67 |
+ return; |
68 |
+} |
69 |
+ |
70 |
static void handle_shutdown(const char *runlevel, int cmd) |
71 |
{ |
72 |
pid_t pid; |
73 |
@@ -123,10 +130,11 @@ static void signal_handler(int sig) |
74 |
|
75 |
int main(int argc, char **argv) |
76 |
{ |
77 |
- char *default_runlevel = NULL; |
78 |
+ char *default_runlevel; |
79 |
char buf[2048]; |
80 |
int count; |
81 |
FILE *fifo; |
82 |
+ bool reexec = false; |
83 |
struct sigaction sa; |
84 |
|
85 |
if (getpid() != 1) |
86 |
@@ -134,16 +142,22 @@ int main(int argc, char **argv) |
87 |
|
88 |
if (argc > 1) |
89 |
default_runlevel = argv[1]; |
90 |
+ else |
91 |
+ default_runlevel = NULL; |
92 |
+ |
93 |
+ if (default_runlevel && strcmp(default_runlevel, "reexec") == 0) |
94 |
+ reexec = true; |
95 |
|
96 |
printf("OpenRC init version %s starting\n", VERSION); |
97 |
- init(default_runlevel); |
98 |
+ if (! reexec) |
99 |
+ init(default_runlevel); |
100 |
memset(&sa, 0, sizeof(sa)); |
101 |
sa.sa_handler = signal_handler; |
102 |
sigaction(SIGCHLD, &sa, NULL); |
103 |
sigaction(SIGINT, &sa, NULL); |
104 |
reboot(RB_DISABLE_CAD); |
105 |
|
106 |
- if (mkfifo(RC_INIT_FIFO, 0600) == -1) |
107 |
+ if (mkfifo(RC_INIT_FIFO, 0600) == -1 && errno != EEXIST) |
108 |
perror("mkfifo"); |
109 |
|
110 |
for (;;) { |
111 |
@@ -166,6 +180,8 @@ int main(int argc, char **argv) |
112 |
handle_shutdown("shutdown", RB_POWER_OFF); |
113 |
else if (strcmp(buf, "reboot") == 0) |
114 |
handle_shutdown("reboot", RB_AUTOBOOT); |
115 |
+ else if (strcmp(buf, "reexec") == 0) |
116 |
+ handle_reexec(argv[0]); |
117 |
} |
118 |
return 0; |
119 |
} |
120 |
|
121 |
diff --git a/src/rc/openrc-shutdown.c b/src/rc/openrc-shutdown.c |
122 |
index 978e8a68..8905d354 100644 |
123 |
--- a/src/rc/openrc-shutdown.c |
124 |
+++ b/src/rc/openrc-shutdown.c |
125 |
@@ -35,11 +35,12 @@ |
126 |
|
127 |
const char *applet = NULL; |
128 |
const char *extraopts = NULL; |
129 |
-const char *getoptstring = "kpr" getoptstring_COMMON; |
130 |
+const char *getoptstring = "HkpRr" getoptstring_COMMON; |
131 |
const struct option longopts[] = { |
132 |
{ "halt", no_argument, NULL, 'H'}, |
133 |
{ "kexec", no_argument, NULL, 'k'}, |
134 |
{ "poweroff", no_argument, NULL, 'p'}, |
135 |
+ { "reexec", no_argument, NULL, 'R'}, |
136 |
{ "reboot", no_argument, NULL, 'r'}, |
137 |
longopts_COMMON |
138 |
}; |
139 |
@@ -47,11 +48,13 @@ const char * const longopts_help[] = { |
140 |
"halt the system", |
141 |
"reboot the system using kexec", |
142 |
"power off the system", |
143 |
+ "re-execute init (use after upgrading)", |
144 |
"reboot the system", |
145 |
longopts_help_COMMON |
146 |
}; |
147 |
const char *usagestring = NULL; |
148 |
-const char *exclusive = "Select one of --halt, --kexec, --poweroff or --reboot"; |
149 |
+const char *exclusive = "Select one of " |
150 |
+"--halt, --kexec, --poweroff, --reexec or --reboot"; |
151 |
|
152 |
static void send_cmd(const char *cmd) |
153 |
{ |
154 |
@@ -79,6 +82,7 @@ int main(int argc, char **argv) |
155 |
bool do_kexec = false; |
156 |
bool do_poweroff = false; |
157 |
bool do_reboot = false; |
158 |
+ bool do_reexec = false; |
159 |
|
160 |
applet = basename_c(argv[0]); |
161 |
if (geteuid() != 0) |
162 |
@@ -99,6 +103,10 @@ if (geteuid() != 0) |
163 |
do_poweroff = true; |
164 |
cmd_count++; |
165 |
break; |
166 |
+ case 'R': |
167 |
+ do_reexec = true; |
168 |
+ cmd_count++; |
169 |
+ break; |
170 |
case 'r': |
171 |
do_reboot = true; |
172 |
cmd_count++; |
173 |
@@ -118,5 +126,7 @@ if (geteuid() != 0) |
174 |
send_cmd("poweroff"); |
175 |
else if (do_reboot) |
176 |
send_cmd("reboot"); |
177 |
+ else if (do_reexec) |
178 |
+ send_cmd("reexec"); |
179 |
return 0; |
180 |
} |