'virsh lxc-enter-namespace' does not have a way to reflect exit
status to the caller in single-command mode, but we might as well
at least report the exit status. Prior to this patch,
$ virsh -c lxc:/// lxc-enter-namespace shell /bin/sh 'exit 3'; echo $?
1
now it gives some details:
$ virsh -c lxc:/// lxc-enter-namespace shell /bin/sh -c 'exit 3'; echo $?
error: internal error: Child process (31557) unexpected exit status 3
1
Also useful:
$ virsh -c lxc:/// lxc-enter-namespace shell /bin/sh -c 'kill $$'; echo $?
error: internal error: Child process (31585) unexpected fatal signal 15
1
* tools/virsh-domain.c (cmdLxcEnterNamespace): Avoid magic numbers.
Dispatch any error.
* tools/virsh.pod: Document that non-zero exit status is collapsed.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
tools/virsh-domain.c | 27 +++++++++++++++++++--------
tools/virsh.pod | 3 ++-
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index d9b542e..4dc6410 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -8140,12 +8140,14 @@ cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd)
if ((pid = virFork()) < 0)
goto cleanup;
if (pid == 0) {
+ int status;
+
if (setlabel &&
virDomainLxcEnterSecurityLabel(secmodel,
seclabel,
NULL,
0) < 0)
- _exit(255);
+ _exit(EXIT_CANCELED);
if (virDomainLxcEnterNamespace(dom,
nfdlist,
@@ -8153,27 +8155,36 @@ cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd)
NULL,
NULL,
0) < 0)
- _exit(255);
+ _exit(EXIT_CANCELED);
/* Fork a second time because entering the
* pid namespace only takes effect after fork
*/
if ((pid = virFork()) < 0)
- _exit(255);
+ _exit(EXIT_CANCELED);
if (pid == 0) {
execv(cmdargv[0], cmdargv);
- _exit(255);
+ _exit(errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
+ }
+ if (virProcessWait(pid, &status) < 0)
+ _exit(EXIT_CANNOT_INVOKE);
+ if (WIFSIGNALED(status)) {
+ raise(WTERMSIG(status));
+ status = WTERMSIG(status) + 128;
+ } else if (WIFEXITED(status)) {
+ status = WEXITSTATUS(status);
} else {
- if (virProcessWait(pid, NULL) < 0)
- _exit(255);
+ status = EXIT_CANNOT_INVOKE;
}
- _exit(0);
+ _exit(status);
} else {
for (i = 0; i < nfdlist; i++)
VIR_FORCE_CLOSE(fdlist[i]);
VIR_FREE(fdlist);
- if (virProcessWait(pid, NULL) < 0)
+ if (virProcessWait(pid, NULL) < 0) {
+ vshReportError(ctl);
goto cleanup;
+ }
}
ret = true;
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 3534b54..9b24a69 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -3284,7 +3284,8 @@ Enter the namespace of I<domain> and execute the command
C</path/to/binary>
passing the requested args. The binary path is relative to the container
root filesystem, not the host root filesystem. The binary will inherit the
environment variables / console visible to virsh. This command only works
-when connected to the LXC hypervisor driver.
+when connected to the LXC hypervisor driver. This command succeeds only
+if C</path/to/binary> has 0 exit status.
=back
--
1.8.4.2