[lxc-devel] [PATCH 9/9] lxc-device: rewrite lxc-device.
Serge Hallyn
serge.hallyn at ubuntu.com
Thu Oct 9 18:12:06 UTC 2014
I'm sorry, I confused myself in that thread, especially as I'd acked some
of your v1 patches, but I can't clearly tell from my mbox which are v2.
Could you please resend (keeping my acks) or send me a github url?
Quoting Dongsheng Yang (yangds.fnst at cn.fujitsu.com):
> Hi Serge, Any more comments on this patchset?
>
> Thanx :)
>
> On 09/29/2014 03:13 PM, Dongsheng Yang wrote:
> >As there is a function named attach_interface to pass
> >a interface to container now, we do not need to relay on
> >python impolementation for lxc-device any more.
> >
> >Signed-off-by: Dongsheng Yang <yangds.fnst at cn.fujitsu.com>
> >---
> > src/lxc/Makefile.am | 4 +-
> > src/lxc/lxc-device | 97 -----------------------------
> > src/lxc/lxc_device.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 175 insertions(+), 99 deletions(-)
> > delete mode 100644 src/lxc/lxc-device
> > create mode 100644 src/lxc/lxc_device.c
> >
> >diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
> >index 8322e62..dab5350 100644
> >--- a/src/lxc/Makefile.am
> >+++ b/src/lxc/Makefile.am
> >@@ -163,14 +163,12 @@ endif
> > bin_SCRIPTS = lxc-checkconfig
> > EXTRA_DIST = \
> >- lxc-device \
> > lxc-ls \
> > lxc-top \
> > lxc.net \
> > lxc-restore-net
> > if ENABLE_PYTHON
> >-bin_SCRIPTS += lxc-device
> > bin_SCRIPTS += lxc-ls
> > bin_SCRIPTS += lxc-start-ephemeral
> > else
> >@@ -191,6 +189,7 @@ bin_PROGRAMS = \
> > lxc-console \
> > lxc-create \
> > lxc-destroy \
> >+ lxc-device \
> > lxc-execute \
> > lxc-freeze \
> > lxc-info \
> >@@ -222,6 +221,7 @@ lxc_cgroup_SOURCES = lxc_cgroup.c
> > lxc_config_SOURCES = lxc_config.c
> > lxc_console_SOURCES = lxc_console.c
> > lxc_destroy_SOURCES = lxc_destroy.c
> >+lxc_device_SOURCES = lxc_device.c
> > lxc_execute_SOURCES = lxc_execute.c
> > lxc_freeze_SOURCES = lxc_freeze.c
> > lxc_info_SOURCES = lxc_info.c
> >diff --git a/src/lxc/lxc-device b/src/lxc/lxc-device
> >deleted file mode 100644
> >index dca161e..0000000
> >--- a/src/lxc/lxc-device
> >+++ /dev/null
> >@@ -1,97 +0,0 @@
> >-#!/usr/bin/python3
> >-#
> >-# lxc-device: Add devices to a running container
> >-#
> >-# This python implementation is based on the work done in the original
> >-# shell implementation done by Serge Hallyn in Ubuntu (and other contributors)
> >-#
> >-# (C) Copyright Canonical Ltd. 2012
> >-#
> >-# Authors:
> >-# St?(c)phane Graber <stgraber at ubuntu.com>
> >-#
> >-# This library is free software; you can redistribute it and/or
> >-# modify it under the terms of the GNU Lesser General Public
> >-# License as published by the Free Software Foundation; either
> >-# version 2.1 of the License, or (at your option) any later version.
> >-#
> >-# This library is distributed in the hope that it will be useful,
> >-# but WITHOUT ANY WARRANTY; without even the implied warranty of
> >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> >-# Lesser General Public License for more details.
> >-#
> >-# You should have received a copy of the GNU Lesser General Public
> >-# License along with this library; if not, write to the Free Software
> >-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> >-#
> >-
> >-import argparse
> >-import gettext
> >-import lxc
> >-import os
> >-
> >-_ = gettext.gettext
> >-gettext.textdomain("lxc-device")
> >-
> >-# Begin parsing the command line
> >-parser = argparse.ArgumentParser(description=_("LXC: Manage devices"),
> >- formatter_class=argparse.RawTextHelpFormatter)
> >-
> >-# Global arguments
> >-parser.add_argument("-n", dest="container", metavar="CONTAINER",
> >- help=_("Name of the container to add the device to"),
> >- required=True)
> >-
> >-parser.add_argument("-P", "--lxcpath", dest="lxcpath", metavar="PATH",
> >- help=_("Use specified container path"), default=None)
> >-
> >-parser.add_argument("--version", action="version", version=lxc.version)
> >-
> >-# Commands
> >-subparsers = parser.add_subparsers()
> >-subparser_add = subparsers.add_parser('add', help=_('Add a device'))
> >-subparser_add.set_defaults(action="add")
> >-
> >-subparser_add.add_argument(dest="device", metavar="DEVICE",
> >- help=_("Add a device "
> >- "(path to a node or interface name)"))
> >-
> >-subparser_add.add_argument(dest="name", metavar="NAME", nargs="?",
> >- help=_("Use an alternative path or name "
> >- "in the container"))
> >-
> >-args = parser.parse_args()
> >-
> >-# Some basic checks
> >-## Check for valid action
> >-if not hasattr(args, "action"):
> >- parser.error(_("You must specify an action."))
> >-
> >-## Don't rename if no alternative name
> >-if not args.name:
> >- args.name = args.device
> >-
> >-## Check that the container is ready
> >-container = lxc.Container(args.container, args.lxcpath)
> >-
> >-## Check that we have control over the container
> >-if not container.controllable:
> >- parser.error("Insufficent privileges to control: %s" % container.name)
> >-
> >-## Check that the container is running
> >-if not container.running:
> >- parser.error("The container must be running.")
> >-
> >-# Do the work
> >-if args.action == "add":
> >- if os.path.exists("/sys/class/net/%s/" % args.device):
> >- ret = container.add_device_net(args.device, args.name)
> >- else:
> >- ret = container.add_device_node(args.device, args.name)
> >-
> >- if ret:
> >- print("Added '%s' to '%s' as '%s'." %
> >- (args.device, container.name, args.name))
> >- else:
> >- print("Failed to add '%s' to '%s' as '%s'." %
> >- (args.device, container.name, args.name))
> >diff --git a/src/lxc/lxc_device.c b/src/lxc/lxc_device.c
> >new file mode 100644
> >index 0000000..68c4802
> >--- /dev/null
> >+++ b/src/lxc/lxc_device.c
> >@@ -0,0 +1,173 @@
> >+/*
> >+ * lxc: linux Container library
> >+ *
> >+ * Authors:
> >+ * Dongsheng Yang <yangds.fnst at cn.fujitsu.com>
> >+ *
> >+ * This library is free software; you can redistribute it and/or
> >+ * modify it under the terms of the GNU Lesser General Public
> >+ * License as published by the Free Software Foundation; either
> >+ * version 2.1 of the License, or (at your option) any later version.
> >+ *
> >+ * This library is distributed in the hope that it will be useful,
> >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> >+ * Lesser General Public License for more details.
> >+ *
> >+ * You should have received a copy of the GNU Lesser General Public
> >+ * License along with this library; if not, write to the Free Software
> >+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> >+ */
> >+#include <stdio.h>
> >+#include <unistd.h>
> >+#include <sys/types.h>
> >+#include <libgen.h>
> >+#include <string.h>
> >+#include <limits.h>
> >+
> >+#include <lxc/lxccontainer.h>
> >+
> >+#include "utils.h"
> >+#include "lxc.h"
> >+#include "log.h"
> >+
> >+#include "arguments.h"
> >+
> >+#if HAVE_IFADDRS_H
> >+#include <ifaddrs.h>
> >+#else
> >+#include <../include/ifaddrs.h>
> >+#endif
> >+
> >+lxc_log_define(lxc_device, lxc);
> >+
> >+static const struct option my_longopts[] = {
> >+ LXC_COMMON_OPTIONS
> >+};
> >+
> >+static struct lxc_arguments my_args = {
> >+ .progname = "lxc-device",
> >+ .help = "\
> >+--name=NAME -- add|del DEV\n\
> >+\n\
> >+lxc-device attach or detach DEV to or from container.\n\
> >+\n\
> >+Options :\n\
> >+ -n, --name=NAME NAME for name of the container",
> >+ .options = my_longopts,
> >+ .parser = NULL,
> >+ .checker = NULL,
> >+};
> >+
> >+static bool is_interface(const char* dev_name, pid_t pid)
> >+{
> >+ pid_t p = fork();
> >+
> >+ if (p < 0) {
> >+ SYSERROR("failed to fork task.");
> >+ exit(1);
> >+ }
> >+
> >+ if (p == 0) {
> >+ struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
> >+
> >+ if (!switch_to_ns(pid, "net")) {
> >+ ERROR("failed to enter netns of container.");
> >+ exit(-1);
> >+ }
> >+
> >+ /* Grab the list of interfaces */
> >+ if (getifaddrs(&interfaceArray)) {
> >+ ERROR("failed to get interfaces list");
> >+ exit(-1);
> >+ }
> >+
> >+ /* Iterate through the interfaces */
> >+ for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next) {
> >+ if (strcmp(tempIfAddr->ifa_name, dev_name) == 0) {
> >+ exit(0);
> >+ }
> >+ }
> >+ exit(1);
> >+ }
> >+
> >+ if (wait_for_pid(p) == 0) {
> >+ return true;
> >+ }
> >+ return false;
> >+}
> >+
> >+int main(int argc, char *argv[])
> >+{
> >+ struct lxc_container *c;
> >+ char *cmd, *dev_name, *dst_name;
> >+ int ret = 1;
> >+
> >+ if (lxc_arguments_parse(&my_args, argc, argv))
> >+ goto err;
> >+
> >+ if (!my_args.log_file)
> >+ my_args.log_file = "none";
> >+
> >+ if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
> >+ my_args.progname, my_args.quiet, my_args.lxcpath[0]))
> >+ goto err;
> >+ lxc_log_options_no_override();
> >+
> >+ c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
> >+ if (!c) {
> >+ ERROR("%s doesn't exist", my_args.name);
> >+ goto err;
> >+ }
> >+
> >+ if (!c->is_running(c)) {
> >+ ERROR("Container %s is not running.", c->name);
> >+ goto err1;
> >+ }
> >+
> >+ if (my_args.argc < 2) {
> >+ ERROR(my_args.help);
> >+ goto err1;
> >+ }
> >+
> >+ cmd = my_args.argv[0];
> >+ dev_name = my_args.argv[1];
> >+ if (my_args.argc < 3)
> >+ dst_name = dev_name;
> >+ else
> >+ dst_name = my_args.argv[2];
> >+
> >+ if (strcmp(cmd, "add") == 0) {
> >+ if (is_interface(dev_name, 1)) {
> >+ ret = c->attach_interface(c, dev_name, dst_name);
> >+ } else {
> >+ ret = c->add_device_node(c, dev_name, dst_name);
> >+ }
> >+ if (ret != true) {
> >+ ERROR("Failed to add %s to %s.", dev_name, c->name);
> >+ ret = 1;
> >+ goto err1;
> >+ }
> >+ INFO("Add %s to %s.", dev_name, c->name);
> >+ } else if (strcmp(cmd, "del") == 0) {
> >+ if (is_interface(dev_name, c->init_pid(c))) {
> >+ ret = c->detach_interface(c, dev_name, dst_name);
> >+ } else {
> >+ ret = c->remove_device_node(c, dev_name, dst_name);
> >+ }
> >+ if (ret != true) {
> >+ ERROR("Failed to del %s from %s.", dev_name, c->name);
> >+ ret = 1;
> >+ goto err1;
> >+ }
> >+ INFO("Delete %s from %s.", dev_name, c->name);
> >+ } else {
> >+ ERROR(my_args.help);
> >+ goto err1;
> >+ }
> >+ exit(0);
> >+err1:
> >+ lxc_container_put(c);
> >+err:
> >+ exit(ret);
> >+}
>
More information about the lxc-devel
mailing list