virsh: report exit status of failed lxc-enter-namespace

'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@redhat.com>
This commit is contained in:
Eric Blake 2013-12-23 09:32:45 -07:00
parent 730fc9622b
commit 2ebf593a05
2 changed files with 15 additions and 11 deletions

View File

@ -8183,12 +8183,14 @@ cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd)
if ((pid = virFork()) < 0) if ((pid = virFork()) < 0)
goto cleanup; goto cleanup;
if (pid == 0) { if (pid == 0) {
int status;
if (setlabel && if (setlabel &&
virDomainLxcEnterSecurityLabel(secmodel, virDomainLxcEnterSecurityLabel(secmodel,
seclabel, seclabel,
NULL, NULL,
0) < 0) 0) < 0)
_exit(255); _exit(EXIT_CANCELED);
if (virDomainLxcEnterNamespace(dom, if (virDomainLxcEnterNamespace(dom,
nfdlist, nfdlist,
@ -8196,28 +8198,29 @@ cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd)
NULL, NULL,
NULL, NULL,
0) < 0) 0) < 0)
_exit(255); _exit(EXIT_CANCELED);
/* Fork a second time because entering the /* Fork a second time because entering the
* pid namespace only takes effect after fork * pid namespace only takes effect after fork
*/ */
if ((pid = virFork()) < 0) if ((pid = virFork()) < 0)
_exit(255); _exit(EXIT_CANCELED);
if (pid == 0) { if (pid == 0) {
execv(cmdargv[0], cmdargv); execv(cmdargv[0], cmdargv);
_exit(255); _exit(errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
} else {
if (virProcessWait(pid, NULL, false) < 0)
_exit(255);
} }
_exit(0); if (virProcessWait(pid, &status, true) < 0)
_exit(EXIT_CANNOT_INVOKE);
virProcessExitWithStatus(status);
} else { } else {
for (i = 0; i < nfdlist; i++) for (i = 0; i < nfdlist; i++)
VIR_FORCE_CLOSE(fdlist[i]); VIR_FORCE_CLOSE(fdlist[i]);
VIR_FREE(fdlist); VIR_FREE(fdlist);
if (virProcessWait(pid, NULL, false) < 0) if (virProcessWait(pid, NULL, false) < 0) {
vshReportError(ctl);
goto cleanup; goto cleanup;
} }
}
ret = true; ret = true;

View File

@ -3371,7 +3371,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 passing the requested args. The binary path is relative to the container
root filesystem, not the host root filesystem. The binary will inherit the root filesystem, not the host root filesystem. The binary will inherit the
environment variables / console visible to virsh. This command only works 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 =back
@ -3486,7 +3487,7 @@ Alternatively report bugs to your software distributor / vendor.
=head1 COPYRIGHT =head1 COPYRIGHT
Copyright (C) 2005, 2007-2010 Red Hat, Inc., and the authors listed in the Copyright (C) 2005, 2007-2014 Red Hat, Inc., and the authors listed in the
libvirt AUTHORS file. libvirt AUTHORS file.
=head1 LICENSE =head1 LICENSE