Commit e043236e by Michel Normand Committed by Daniel Lezcano

lxc-start to report exit code of started application

The exit code of the application as reported by lxc-start is: 0-126 exit code of the application itself 128+n signal n received by the application 255 lxc error Signed-off-by: 's avatarMichel Normand <normand@fr.ibm.com> Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent 41cfbac9
...@@ -23,7 +23,11 @@ ...@@ -23,7 +23,11 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/wait.h>
#include "error.h" #include "error.h"
#include "log.h"
lxc_log_define(lxc_error, lxc);
static const char *const catalogue[] = { static const char *const catalogue[] = {
...@@ -67,3 +71,32 @@ const char *const lxc_strerror(int error) ...@@ -67,3 +71,32 @@ const char *const lxc_strerror(int error)
return catalogue[error]; return catalogue[error];
} }
/*---------------------------------------------------------------------------*/
/* lxc_error_set_and_log
* function is here to convert
* the reported status to an exit code as detailed here:
*
* 0-126 exit code of the application
* 128+n signal n received by the application
* 255 lxc error
*/
extern int lxc_error_set_and_log(int pid, int status)
{
int ret = 0;
if (WIFEXITED(status)) {
ret = WEXITSTATUS(status);
if (ret)
INFO("child <%d> ended on error (%d)", pid, ret);
}
if (WIFSIGNALED(status)) {
int signal = WTERMSIG(status);
ret = ret + 128 + signal;
INFO("child <%d> ended on signal (%d)", pid, signal);
}
return ret;
}
...@@ -59,4 +59,5 @@ typedef enum { ...@@ -59,4 +59,5 @@ typedef enum {
LXC_LAST_ERROR, LXC_LAST_ERROR,
} lxc_error_t; } lxc_error_t;
extern int lxc_error_set_and_log(int pid, int status);
#endif #endif
...@@ -61,7 +61,7 @@ Options :\n\ ...@@ -61,7 +61,7 @@ Options :\n\
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *const *args; char *const *args;
int err; int err = -1;
struct termios tios; struct termios tios;
char *const default_args[] = { char *const default_args[] = {
...@@ -69,9 +69,8 @@ int main(int argc, char *argv[]) ...@@ -69,9 +69,8 @@ int main(int argc, char *argv[])
'\0', '\0',
}; };
err = lxc_arguments_parse(&my_args, argc, argv); if (lxc_arguments_parse(&my_args, argc, argv))
if (err) return err;
return 1;
if (!my_args.argc) if (!my_args.argc)
args = default_args; args = default_args;
...@@ -80,19 +79,15 @@ int main(int argc, char *argv[]) ...@@ -80,19 +79,15 @@ int main(int argc, char *argv[])
if (lxc_log_init(my_args.log_file, my_args.log_priority, if (lxc_log_init(my_args.log_file, my_args.log_priority,
my_args.progname, my_args.quiet)) my_args.progname, my_args.quiet))
return 1; return err;
if (tcgetattr(0, &tios)) { if (tcgetattr(0, &tios)) {
ERROR("failed to get current terminal settings : %s", ERROR("failed to get current terminal settings : %s",
strerror(errno)); strerror(errno));
return 1; return err;
} }
err = lxc_start(my_args.name, args); err = lxc_start(my_args.name, args);
if (err) {
ERROR("failed to start '%s'", my_args.name);
err = 1;
}
if (tcsetattr(0, TCSAFLUSH, &tios)) if (tcsetattr(0, TCSAFLUSH, &tios))
ERROR("failed to restore terminal settings : %s", ERROR("failed to restore terminal settings : %s",
......
...@@ -439,7 +439,7 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) ...@@ -439,7 +439,7 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[])
if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) { if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) {
SYSERROR("failed to set sigprocmask"); SYSERROR("failed to set sigprocmask");
return -1; goto out_child;
} }
close(sv[1]); close(sv[1]);
...@@ -460,12 +460,9 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) ...@@ -460,12 +460,9 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[])
} }
/* Setup the container, ip, names, utsname, ... */ /* Setup the container, ip, names, utsname, ... */
err = lxc_setup(name, handler->tty, &handler->tty_info); if (lxc_setup(name, handler->tty, &handler->tty_info)) {
if (err) {
ERROR("failed to setup the container"); ERROR("failed to setup the container");
if (write(sv[0], &err, sizeof(err)) < 0) goto out_warn_father;
SYSERROR("failed to write the socket");
goto out_child;
} }
if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) { if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) {
...@@ -476,11 +473,10 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) ...@@ -476,11 +473,10 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[])
execvp(argv[0], argv); execvp(argv[0], argv);
SYSERROR("failed to exec %s", argv[0]); SYSERROR("failed to exec %s", argv[0]);
err = LXC_ERROR_WRONG_COMMAND; out_warn_father:
/* If the exec fails, tell that to our father */ /* If the exec fails, tell that to our father */
if (write(sv[0], &err, sizeof(err)) < 0) if (write(sv[0], &err, sizeof(err)) < 0)
SYSERROR("failed to write the socket"); SYSERROR("failed to write the socket");
out_child: out_child:
exit(err); exit(err);
} }
...@@ -509,8 +505,7 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) ...@@ -509,8 +505,7 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[])
} }
/* Wait for the child to exec or returning an error */ /* Wait for the child to exec or returning an error */
err = read(sv[1], &sync, sizeof(sync)); if (read(sv[1], &sync, sizeof(sync)) < 0) {
if (err < 0) {
ERROR("failed to read the socket"); ERROR("failed to read the socket");
goto out_abort; goto out_abort;
} }
...@@ -542,7 +537,7 @@ out_abort: ...@@ -542,7 +537,7 @@ out_abort:
int lxc_start(const char *name, char *const argv[]) int lxc_start(const char *name, char *const argv[])
{ {
struct lxc_handler handler = { 0 }; struct lxc_handler handler = { 0 };
int err = -LXC_ERROR_INTERNAL; int err = -1;
int status; int status;
if (lxc_init(name, &handler)) { if (lxc_init(name, &handler)) {
...@@ -556,14 +551,16 @@ int lxc_start(const char *name, char *const argv[]) ...@@ -556,14 +551,16 @@ int lxc_start(const char *name, char *const argv[])
goto out; goto out;
} }
if (lxc_poll(name, &handler)) { err = lxc_poll(name, &handler);
if (err) {
ERROR("mainloop exited with an error"); ERROR("mainloop exited with an error");
goto out_abort; goto out_abort;
} }
while (waitpid(handler.pid, &status, 0) < 0 && errno == EINTR) while (waitpid(handler.pid, &status, 0) < 0 && errno == EINTR)
continue; continue;
err = 0;
err = lxc_error_set_and_log(handler.pid, status);
out: out:
lxc_fini(name, &handler); lxc_fini(name, &handler);
return err; return err;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment