[lxc-devel] [PATCH 9/9] lxc-device: rewrite lxc-device.
Dongsheng Yang
yangds.fnst at cn.fujitsu.com
Fri Sep 26 02:27:14 UTC 2014
Thanx Hallyn and Graber,
Sorry for the delay. It is too busy this week. I will address all your
comments maybe next week.
Thanx
Yang
On 09/20/2014 07:56 AM, Serge Hallyn wrote:
> Quoting Stéphane Graber (stgraber at ubuntu.com):
>> On Fri, Sep 19, 2014 at 09:57:57PM +0000, Serge Hallyn wrote:
>>> Quoting Dongsheng Yang (yangds.fnst at cn.fujitsu.com):
>>>> 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.
>>> Don't we still need it for non-network device node?
>> That new lxc_device does that too.
> D'oh.
>
>>>> Signed-off-by: Dongsheng Yang <yangds.fnst at cn.fujitsu.com>
> Thanks, I added a few more notes below, but with all of those
> fixed
>
> Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
>
>>>> ---
>>>> src/lxc/Makefile.am | 4 +-
>>>> src/lxc/lxc-device | 97 ------------------------------
>>>> src/lxc/lxc_device.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>>> 3 files changed, 168 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é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..963f934
>>>> --- /dev/null
>>>> +++ b/src/lxc/lxc_device.c
>>>> @@ -0,0 +1,166 @@
>>>> +/*
>>>> + * 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-devicee",
>> Type above.
>>
>>>> + .help = "\
>>>> +--name=NAME -- COMMAND\n\
>>>> +\n\
>>>> +lxc-device attach or detach device to container.\n\
>>>> +lxc-device -n name add|del ifname.\n\
>>>> +\n\
>>>> +Options :\n\
>>>> + -n, --name=NAME NAME for name of the container",
>> Could be updated to ressemble the output from the other C programs a bit more.
>>
>>>> + .options = my_longopts,
>>>> + .parser = NULL,
>>>> + .checker = NULL,
>>>> +};
>>>> +
>>>> +static bool is_interface(const char* dev_name, pid_t pid)
>>>> +{
>>>> + pid_t p = fork();
> Please do check for fork failure.
>
>>>> + if (p == 0) {
>>>> + struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
>>>> +
>>>> + switch_to_newnet(pid);
> Check for failure.
>
>>>> + /* 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("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
>> The standard error message for that is "%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("Added %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("Deled %s from %s.", dev_name, c->name);
>> Typo
>>
>>>> + } else {
>>>> + ERROR(my_args.help);
>>>> + goto err1;
>>>> + }
>>>> + exit(0);
>>>> +err1:
>>>> + lxc_container_put(c);
>>>> +err:
>>>> + exit(ret);
>>>> +}
>>>> --
>>>> 1.8.4.2
>>>>
>> --
>> Stéphane Graber
>> Ubuntu developer
>> http://www.ubuntu.com
>
> .
>
More information about the lxc-devel
mailing list