chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
main: try a bit harder to find an init process to execute after reexec/switch-root
[elogind.git]
/
src
/
core
/
main.c
diff --git
a/src/core/main.c
b/src/core/main.c
index d7ce8abdac895e907ceed40f9cdc75b603239668..a51d1be45bc3de8794fa5e1d13cb70f85d085bf4 100644
(file)
--- a/
src/core/main.c
+++ b/
src/core/main.c
@@
-1185,7
+1185,7
@@
static int do_switch_root(const char *switch_root) {
}
if (chroot(".") < 0)
}
if (chroot(".") < 0)
- log_warning("Failed to change root, ignoring: %
s", strerror(-r)
);
+ log_warning("Failed to change root, ignoring: %
m"
);
/* FIXME: remove old root */
/* FIXME: remove old root */
@@
-1640,7
+1640,7
@@
finish:
if (reexecute) {
const char **args;
if (reexecute) {
const char **args;
- unsigned i;
+ unsigned i
, args_size
;
/* Close and disarm the watchdog, so that the new
* instance can reinitialize it, but doesn't get
/* Close and disarm the watchdog, so that the new
* instance can reinitialize it, but doesn't get
@@
-1650,7
+1650,8
@@
finish:
if (switch_root)
do_switch_root(switch_root);
if (switch_root)
do_switch_root(switch_root);
- args = newa(const char*, MAX(5, argc+1));
+ args_size = MAX(5, argc+1);
+ args = newa(const char*, args_size);
if (!switch_root_init) {
char sfd[16];
if (!switch_root_init) {
char sfd[16];
@@
-1673,7
+1674,7
@@
finish:
args[i++] = sfd;
args[i++] = NULL;
args[i++] = sfd;
args[i++] = NULL;
- assert(i <=
ELEMENTSOF(args)
);
+ assert(i <=
args_size
);
execv(args[0], (char* const*) args);
}
execv(args[0], (char* const*) args);
}
@@
-1683,22
+1684,36
@@
finish:
* getopt() in argv[], and some cleanups in envp[],
* but let's hope that doesn't matter.) */
* getopt() in argv[], and some cleanups in envp[],
* but let's hope that doesn't matter.) */
- if (serialization)
+ if (serialization)
{
fclose(serialization);
fclose(serialization);
+ serialization = NULL;
+ }
- if (fds)
+ if (fds)
{
fdset_free(fds);
fdset_free(fds);
+ fds = NULL;
+ }
- i = 0;
- args[i++] = switch_root_init ? switch_root_init : "/sbin/init";
- for (j = 1; j < argc; j++)
+ for (j = 1, i = 1; j < argc; j++)
args[i++] = argv[j];
args[i++] = NULL;
args[i++] = argv[j];
args[i++] = NULL;
+ assert(i <= args_size);
+
+ if (switch_root_init) {
+ args[0] = switch_root_init;
+ execv(args[0], (char* const*) args);
+ log_warning("Failed to execute configured init, trying fallback: %m");
+ }
- a
ssert(i <= ELEMENTSOF(args))
;
+ a
rgs[0] = "/sbin/init"
;
execv(args[0], (char* const*) args);
execv(args[0], (char* const*) args);
- log_error("Failed to reexecute: %m");
+ log_warning("Failed to execute /sbin/init, trying fallback: %m");
+
+ args[0] = "/bin/sh";
+ args[1] = NULL;
+ execv(args[0], (char* const*) args);
+ log_error("Failed to execute /bin/sh, giving up: %m");
}
if (serialization)
}
if (serialization)