[libvirt] [PATCH] lxc: do not require 'ifconfig' or 'ipconfig' in container
Daniel P. Berrange
berrange at redhat.com
Thu Sep 1 09:02:55 UTC 2011
On Wed, Aug 31, 2011 at 02:02:10PM -0500, Serge Hallyn wrote:
> Quoting Scott Moser (smoser at ubuntu.com):
> > Currently, the lxc implementation invokes 'ip' and 'ifconfig' commands
> > inside a container using 'virRun'. That has the side effect of requiring
> > those commands to be present and to function in a manner consistent with
> > the usage. Some small roots (such as ttylinux) may not have 'ip' or
> > 'ifconfig'.
> >
> > This patch replaces the use of these commands with usage of
> > netdevice. The result is that lxc containers do not have to implement
> > those commands, and lxc in libvirt is only dependent on the netdevice
> > interface.
>
> Requiring fewer tools in the container seems like a very good thing,
> especially when trying to create a tiny busybox-based container.
Yep, and we already directly do this kind of thing elsewhere in
libvirt without external tools, so there is precedent.
> > I've tested this patch locally against the ubuntu libvirt version enough
> > to verify its generally sane. I attempted to build upstream today, but
> > failed with:
> > /usr/bin/ld:
> > ../src/.libs/libvirt_driver_qemu.a(libvirt_driver_qemu_la-qemu_domain.o):
> > undefined reference to symbol 'xmlXPathRegisterNs@@LIBXML2_2.4.30
> >
> > Thats probably a local issue only, but I wanted to get this patch up and
> > see what others thought of it. This is ubuntu bug
> > https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/828211 .
> >
> > diff --git a/src/lxc/veth.c b/src/lxc/veth.c
> > index 34cb804..c24df91 100644
> > --- a/src/lxc/veth.c
> > +++ b/src/lxc/veth.c
> > @@ -12,8 +12,11 @@
> >
> > #include <config.h>
> >
> > +#include <linux/sockios.h>
> > +#include <net/if.h>
> > #include <string.h>
> > #include <stdio.h>
> > +#include <sys/ioctl.h>
> > #include <sys/types.h>
> > #include <sys/wait.h>
> >
> > @@ -186,41 +189,49 @@ int vethDelete(const char *veth)
> > * @veth: name of veth device
> > * @upOrDown: 0 => down, 1 => up
> > *
> > - * Enables a veth device using the ifconfig command. A NULL inetAddress
> > - * will cause it to be left off the command line.
> > + * Enables a veth device using SIOCSIFFLAGS
> > *
> > - * Returns 0 on success or -1 in case of error
> > + * Returns 0 on success, -1 on failure, with errno set
> > */
> > int vethInterfaceUpOrDown(const char* veth, int upOrDown)
> > {
> > - int rc;
> > - const char *argv[] = {"ifconfig", veth, NULL, NULL};
> > - int cmdResult = 0;
> > + struct ifreq ifr;
> > + int fd, ret;
> >
> > - if (0 == upOrDown)
> > - argv[2] = "down";
> > - else
> > - argv[2] = "up";
> > + if ((fd = socket(PF_PACKET, SOCK_DGRAM, 0)) == -1)
> > + return(-1);
> >
> > - rc = virRun(argv, &cmdResult);
> > + memset(&ifr, 0, sizeof(struct ifreq));
> >
> > - if (rc != 0 ||
> > - (WIFEXITED(cmdResult) && WEXITSTATUS(cmdResult) != 0)) {
> > - if (0 == upOrDown)
> > + if (virStrcpyStatic(ifr.ifr_name, veth) == NULL) {
> > + errno = EINVAL;
> > + return -1;
> > + }
> > +
> > + if ((ret = ioctl(fd, SIOCGIFFLAGS, &ifr)) == 0) {
> > + if (upOrDown)
> > + ifr.ifr_flags |= IFF_UP;
> > + else
> > + ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
> > +
> > + ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
> > + }
> > +
> > + close(fd);
> > + if (ret == -1)
> > + if (upOrDown == 0)
> > /*
> > * Prevent overwriting an error log which may be set
> > * where an actual failure occurs.
> > */
> > - VIR_DEBUG("Failed to disable '%s' (%d)",
> > - veth, WEXITSTATUS(cmdResult));
> > + VIR_DEBUG("Failed to disable '%s'", veth);
> > else
> > vethError(VIR_ERR_INTERNAL_ERROR,
> > - _("Failed to enable '%s' (%d)"),
> > - veth, WEXITSTATUS(cmdResult));
> > - rc = -1;
> > - }
> > + _("Failed to enable '%s'"), veth);
> > + else
> > + ret = 0;
> >
> > - return rc;
> > + return(ret);
> > }
> >
> > /**
> > @@ -279,17 +290,29 @@ int setMacAddr(const char* iface, const char* macaddr)
> > * @iface: name of device
> > * @new: new name of @iface
> > *
> > - * Changes the name of the given device with the
> > - * given new name using this command:
> > - * ip link set @iface name @new
> > + * Changes the name of the given device.
> > *
> > - * Returns 0 on success or -1 in case of error
> > + * Returns 0 on success, -1 on failure with errno set.
> > */
> > int setInterfaceName(const char* iface, const char* new)
> > {
> > - const char *argv[] = {
> > - "ip", "link", "set", iface, "name", new, NULL
> > - };
> > + struct ifreq ifr;
> > + int fd = socket(PF_PACKET, SOCK_DGRAM, 0);
> >
> > - return virRun(argv, NULL);
> > + memset(&ifr, 0, sizeof(struct ifreq));
> > +
> > + if (virStrcpyStatic(ifr.ifr_name, iface) == NULL) {
> > + errno = EINVAL;
> > + return -1;
> > + }
> > +
> > + if (virStrcpyStatic(ifr.ifr_newname, new) == NULL) {
> > + errno = EINVAL;
> > + return -1;
> > + }
> > +
> > + if (ioctl(fd, SIOCSIFNAME, &ifr))
> > + return -1;
> > +
> > + return 0;
> > }
> >
ACK
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list