]>
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 static const struct option my_longopts
[] = {
46 static struct lxc_arguments my_args
= {
47 .progname
= "lxc-device",
49 --name=NAME -- add|del DEV\n\
51 lxc-device attach or detach DEV to or from container.\n\
54 -n, --name=NAME NAME of the container\n\
55 --rcfile=FILE Load configuration file FILE\n",
56 .options
= my_longopts
,
61 static bool is_interface(const char* dev_name
, pid_t pid
)
66 fprintf(stderr
, "failed to fork task.\n");
71 struct ifaddrs
*interfaceArray
= NULL
, *tempIfAddr
= NULL
;
73 if (!switch_to_ns(pid
, "net")) {
74 fprintf(stderr
, "failed to enter netns of container.\n");
78 /* Grab the list of interfaces */
79 if (getifaddrs(&interfaceArray
)) {
80 fprintf(stderr
, "failed to get interfaces list\n");
84 /* Iterate through the interfaces */
85 for (tempIfAddr
= interfaceArray
; tempIfAddr
!= NULL
; tempIfAddr
= tempIfAddr
->ifa_next
) {
86 if (strcmp(tempIfAddr
->ifa_name
, dev_name
) == 0) {
93 if (wait_for_pid(p
) == 0) {
99 int main(int argc
, char *argv
[])
101 struct lxc_container
*c
;
103 char *cmd
, *dev_name
, *dst_name
;
106 if (geteuid() != 0) {
107 fprintf(stderr
, "%s must be run as root\n", argv
[0]);
111 if (lxc_arguments_parse(&my_args
, argc
, argv
))
114 if (!my_args
.log_file
)
115 my_args
.log_file
= "none";
117 log
.name
= my_args
.name
;
118 log
.file
= my_args
.log_file
;
119 log
.level
= my_args
.log_priority
;
120 log
.prefix
= my_args
.progname
;
121 log
.quiet
= my_args
.quiet
;
122 log
.lxcpath
= my_args
.lxcpath
[0];
124 if (lxc_log_init(&log
))
126 lxc_log_options_no_override();
128 /* REMOVE IN LXC 3.0 */
129 setenv("LXC_UPDATE_CONFIG_FORMAT", "1", 0);
131 c
= lxc_container_new(my_args
.name
, my_args
.lxcpath
[0]);
133 fprintf(stderr
, "%s doesn't exist\n", my_args
.name
);
137 if (my_args
.rcfile
) {
139 if (!c
->load_config(c
, my_args
.rcfile
)) {
140 fprintf(stderr
, "Failed to load rcfile\n");
143 c
->configfile
= strdup(my_args
.rcfile
);
144 if (!c
->configfile
) {
145 fprintf(stderr
, "Out of memory setting new config filename\n");
150 if (!c
->is_running(c
)) {
151 fprintf(stderr
, "Container %s is not running.\n", c
->name
);
155 if (my_args
.argc
< 2) {
156 fprintf(stderr
, "Error: no command given (Please see --help output)\n");
160 cmd
= my_args
.argv
[0];
161 dev_name
= my_args
.argv
[1];
162 if (my_args
.argc
< 3)
165 dst_name
= my_args
.argv
[2];
167 if (strcmp(cmd
, "add") == 0) {
168 if (is_interface(dev_name
, 1)) {
169 ret
= c
->attach_interface(c
, dev_name
, dst_name
);
171 ret
= c
->add_device_node(c
, dev_name
, dst_name
);
174 fprintf(stderr
, "Failed to add %s to %s.\n", dev_name
, c
->name
);
177 } else if (strcmp(cmd
, "del") == 0) {
178 if (is_interface(dev_name
, c
->init_pid(c
))) {
179 ret
= c
->detach_interface(c
, dev_name
, dst_name
);
181 ret
= c
->remove_device_node(c
, dev_name
, dst_name
);
184 fprintf(stderr
, "Failed to del %s from %s.\n", dev_name
, c
->name
);
188 fprintf(stderr
, "Error: Please use add or del (Please see --help output)\n");
193 lxc_container_put(c
);