'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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list