]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/tools/lxc_device.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
10 #include <sys/types.h>
13 #include <lxc/lxccontainer.h>
15 #include "netns_ifaddrs.h"
16 #include "arguments.h"
21 lxc_log_define(lxc_device
, lxc
);
23 static bool is_interface(const char *dev_name
, pid_t pid
);
25 static const struct option my_longopts
[] = {
29 static struct lxc_arguments my_args
= {
30 .progname
= "lxc-device",
32 --name=NAME -- add|del DEV\n\
34 lxc-device attach or detach DEV to or from container.\n\
37 -n, --name=NAME NAME of the container\n\
38 --rcfile=FILE Load configuration file FILE\n",
39 .options
= my_longopts
,
42 .log_priority
= "ERROR",
46 static bool is_interface(const char *dev_name
, pid_t pid
)
50 ERROR("Failed to fork task");
55 struct netns_ifaddrs
*interfaceArray
= NULL
, *tempIfAddr
= NULL
;
57 if (!switch_to_ns(pid
, "net")) {
58 ERROR("Failed to enter netns of container");
62 /* Grab the list of interfaces */
63 if (netns_getifaddrs(&interfaceArray
, -1, &(bool){false})) {
64 ERROR("Failed to get interfaces list");
68 /* Iterate through the interfaces */
69 for (tempIfAddr
= interfaceArray
; tempIfAddr
!= NULL
; tempIfAddr
= tempIfAddr
->ifa_next
) {
70 if (strncmp(tempIfAddr
->ifa_name
, dev_name
, strlen(tempIfAddr
->ifa_name
)) == 0)
77 if (wait_for_pid(p
) == 0)
83 int main(int argc
, char *argv
[])
85 struct lxc_container
*c
;
87 char *cmd
, *dev_name
, *dst_name
;
91 ERROR("%s must be run as root", argv
[0]);
95 if (lxc_arguments_parse(&my_args
, argc
, argv
))
98 log
.name
= my_args
.name
;
99 log
.file
= my_args
.log_file
;
100 log
.level
= my_args
.log_priority
;
101 log
.prefix
= my_args
.progname
;
102 log
.quiet
= my_args
.quiet
;
103 log
.lxcpath
= my_args
.lxcpath
[0];
105 if (lxc_log_init(&log
))
108 c
= lxc_container_new(my_args
.name
, my_args
.lxcpath
[0]);
110 ERROR("%s doesn't exist", my_args
.name
);
114 if (my_args
.rcfile
) {
117 if (!c
->load_config(c
, my_args
.rcfile
)) {
118 ERROR("Failed to load rcfile");
122 c
->configfile
= strdup(my_args
.rcfile
);
123 if (!c
->configfile
) {
124 ERROR("Out of memory setting new config filename");
129 if (!c
->is_running(c
)) {
130 ERROR("Container %s is not running", c
->name
);
134 if (my_args
.argc
< 2) {
135 ERROR("Error: no command given (Please see --help output)");
139 cmd
= my_args
.argv
[0];
140 dev_name
= my_args
.argv
[1];
142 if (my_args
.argc
< 3)
145 dst_name
= my_args
.argv
[2];
147 if (strncmp(cmd
, "add", strlen(cmd
)) == 0) {
148 if (is_interface(dev_name
, 1))
149 ret
= c
->attach_interface(c
, dev_name
, dst_name
);
151 ret
= c
->add_device_node(c
, dev_name
, dst_name
);
153 ERROR("Failed to add %s to %s", dev_name
, c
->name
);
156 } else if (strncmp(cmd
, "del", strlen(cmd
)) == 0) {
157 if (is_interface(dev_name
, c
->init_pid(c
)))
158 ret
= c
->detach_interface(c
, dev_name
, dst_name
);
160 ret
= c
->remove_device_node(c
, dev_name
, dst_name
);
162 ERROR("Failed to del %s from %s", dev_name
, c
->name
);
166 ERROR("Error: Please use add or del (Please see --help output)");
173 lxc_container_put(c
);