From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Add a 'lxc-enter-namespace' command which accepts a domain name and then a command + args to run, attached to the container eg virsh -c lxc:/// lxc-enter-namespace demo -- /bin/ps -auxf Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- tools/Makefile.am | 1 + tools/virsh-domain.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/tools/Makefile.am b/tools/Makefile.am index 605bf3b..698db43 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -133,6 +133,7 @@ virsh_LDADD = \ $(STATIC_BINARIES) \ $(WARN_CFLAGS) \ ../src/libvirt.la \ + ../src/libvirt-lxc.la \ ../src/libvirt-qemu.la \ ../gnulib/lib/libgnu.la \ $(LIBXML_LIBS) \ diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index e91939c..cc79fd4 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -43,11 +43,13 @@ #include "conf/domain_conf.h" #include "console.h" #include "viralloc.h" +#include "vircommand.h" #include "virutil.h" #include "virfile.h" #include "virjson.h" #include "virkeycode.h" #include "virmacaddr.h" +#include "virprocess.h" #include "virstring.h" #include "virsh-domain-monitor.h" #include "virerror.h" @@ -6771,6 +6773,103 @@ cleanup: } /* + * "lxc-enter-namespace" namespace + */ +static const vshCmdInfo info_lxc_enter_namespace[] = { + {"help", N_("LXC Guest Enter Namespace")}, + {"desc", N_("Run an arbitrary lxc guest enter namespace; use at your own risk")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_lxc_enter_namespace[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"timeout", VSH_OT_INT, VSH_OFLAG_REQ_OPT, N_("timeout seconds. must be positive.")}, + {"async", VSH_OT_BOOL, 0, N_("execute namespace without waiting for timeout")}, + {"block", VSH_OT_BOOL, 0, N_("execute namespace without timeout")}, + {"cmd", VSH_OT_ARGV, VSH_OFLAG_REQ, N_("namespace")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdLxcEnterNamespace(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom = NULL; + bool ret = false; + const vshCmdOpt *opt = NULL; + char **cmdargv = NULL; + size_t ncmdargv = 0; + pid_t pid; + int nfdlist; + int *fdlist; + size_t i; + + dom = vshCommandOptDomain(ctl, cmd, NULL); + if (dom == NULL) + goto cleanup; + + while ((opt = vshCommandOptArgv(cmd, opt))) { + if (VIR_EXPAND_N(cmdargv, ncmdargv, 1) < 0) { + vshError(ctl, _("%s: %d: failed to allocate argv"), + __FILE__, __LINE__); + exit(EXIT_FAILURE); + } + cmdargv[ncmdargv-1] = opt->data; + } + if (VIR_EXPAND_N(cmdargv, ncmdargv, 1) < 0) { + vshError(ctl, _("%s: %d: failed to allocate argv"), + __FILE__, __LINE__); + exit(EXIT_FAILURE); + } + cmdargv[ncmdargv-1] = NULL; + + if ((nfdlist = virDomainLxcOpenNamespace(dom, &fdlist, 0)) < 0) + goto cleanup; + + /* Fork once because we don't want to affect + * virsh's namespace itself + */ + if (virFork(&pid) < 0) + goto cleanup; + if (pid == 0) { + if (virDomainLxcEnterNamespace(dom, + nfdlist, + fdlist, + NULL, + NULL, + 0) < 0) + _exit(255); + + /* Fork a second time because entering the + * pid namespace only takes effect after fork + */ + if (virFork(&pid) < 0) + _exit(255); + if (pid == 0) { + execv(cmdargv[0], cmdargv); + _exit(255); + } else { + if (virProcessWait(pid, NULL) < 0) + _exit(255); + } + _exit(0); + } else { + for (i = 0 ; i < nfdlist ; i++) + VIR_FORCE_CLOSE(fdlist[i]); + VIR_FREE(fdlist); + if (virProcessWait(pid, NULL) < 0) + goto cleanup; + } + + ret = true; + +cleanup: + if (dom) + virDomainFree(dom); + VIR_FREE(cmdargv); + return ret; +} + +/* * "dumpxml" command */ static const vshCmdInfo info_dumpxml[] = { @@ -8760,6 +8859,7 @@ const vshCmdDef domManagementCmds[] = { {"inject-nmi", cmdInjectNMI, opts_inject_nmi, info_inject_nmi, 0}, {"send-key", cmdSendKey, opts_send_key, info_send_key, 0}, {"send-process-signal", cmdSendProcessSignal, opts_send_process_signal, info_send_process_signal, 0}, + {"lxc-enter-namespace", cmdLxcEnterNamespace, opts_lxc_enter_namespace, info_lxc_enter_namespace, 0}, {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave, 0}, {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, info_managedsaveremove, 0}, -- 1.7.11.7 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list