]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/tools/lxc_device.c
2 * lxc: linux Container library
5 * Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <sys/types.h>
28 #include <lxc/lxccontainer.h>
34 #include "arguments.h"
39 #include <../include/ifaddrs.h>
42 lxc_log_define(lxc_device
, lxc
);
44 static const struct option my_longopts
[] = {
48 static struct lxc_arguments my_args
= {
49 .progname
= "lxc-device",
51 --name=NAME -- add|del DEV\n\
53 lxc-device attach or detach DEV to or from container.\n\
56 -n, --name=NAME NAME of the container\n\
57 --rcfile=FILE Load configuration file FILE\n",
58 .options
= my_longopts
,
63 static bool is_interface(const char* dev_name
, pid_t pid
)
68 SYSERROR("failed to fork task.");
73 struct ifaddrs
*interfaceArray
= NULL
, *tempIfAddr
= NULL
;
75 if (!switch_to_ns(pid
, "net")) {
76 ERROR("failed to enter netns of container.");
80 /* Grab the list of interfaces */
81 if (getifaddrs(&interfaceArray
)) {
82 ERROR("failed to get interfaces list");
86 /* Iterate through the interfaces */
87 for (tempIfAddr
= interfaceArray
; tempIfAddr
!= NULL
; tempIfAddr
= tempIfAddr
->ifa_next
) {
88 if (strcmp(tempIfAddr
->ifa_name
, dev_name
) == 0) {
95 if (wait_for_pid(p
) == 0) {
101 int main(int argc
, char *argv
[])
103 struct lxc_container
*c
;
104 char *cmd
, *dev_name
, *dst_name
;
107 if (geteuid() != 0) {
108 ERROR("%s must be run as root", argv
[0]);
112 if (lxc_arguments_parse(&my_args
, argc
, argv
))
115 if (!my_args
.log_file
)
116 my_args
.log_file
= "none";
118 if (lxc_log_init(my_args
.name
, my_args
.log_file
, my_args
.log_priority
,
119 my_args
.progname
, my_args
.quiet
, my_args
.lxcpath
[0]))
121 lxc_log_options_no_override();
123 c
= lxc_container_new(my_args
.name
, my_args
.lxcpath
[0]);
125 ERROR("%s doesn't exist", my_args
.name
);
129 if (my_args
.rcfile
) {
131 if (!c
->load_config(c
, my_args
.rcfile
)) {
132 ERROR("Failed to load rcfile");
135 c
->configfile
= strdup(my_args
.rcfile
);
136 if (!c
->configfile
) {
137 ERROR("Out of memory setting new config filename");
142 if (!c
->is_running(c
)) {
143 ERROR("Container %s is not running.", c
->name
);
147 if (my_args
.argc
< 2) {
148 ERROR("Error: no command given (Please see --help output)");
152 cmd
= my_args
.argv
[0];
153 dev_name
= my_args
.argv
[1];
154 if (my_args
.argc
< 3)
157 dst_name
= my_args
.argv
[2];
159 if (strcmp(cmd
, "add") == 0) {
160 if (is_interface(dev_name
, 1)) {
161 ret
= c
->attach_interface(c
, dev_name
, dst_name
);
163 ret
= c
->add_device_node(c
, dev_name
, dst_name
);
166 ERROR("Failed to add %s to %s.", dev_name
, c
->name
);
170 INFO("Add %s to %s.", dev_name
, c
->name
);
171 } else if (strcmp(cmd
, "del") == 0) {
172 if (is_interface(dev_name
, c
->init_pid(c
))) {
173 ret
= c
->detach_interface(c
, dev_name
, dst_name
);
175 ret
= c
->remove_device_node(c
, dev_name
, dst_name
);
178 ERROR("Failed to del %s from %s.", dev_name
, c
->name
);
182 INFO("Delete %s from %s.", dev_name
, c
->name
);
184 ERROR("Error: Please use add or del (Please see --help output)");
189 lxc_container_put(c
);