]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/tools/lxc_device.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
14 #include "netns_ifaddrs.h"
15 #include "arguments.h"
19 lxc_log_define(lxc_device
, lxc
);
21 static bool is_interface(const char *dev_name
, pid_t pid
);
23 static const struct option my_longopts
[] = {
27 static struct lxc_arguments my_args
= {
28 .progname
= "lxc-device",
30 --name=NAME -- add|del DEV\n\
32 lxc-device attach or detach DEV to or from container.\n\
35 -n, --name=NAME NAME of the container\n\
36 --rcfile=FILE Load configuration file FILE\n",
37 .options
= my_longopts
,
40 .log_priority
= "ERROR",
44 static bool is_interface(const char *dev_name
, pid_t pid
)
48 ERROR("Failed to fork task");
53 struct netns_ifaddrs
*interfaceArray
= NULL
, *tempIfAddr
= NULL
;
55 if (!switch_to_ns(pid
, "net")) {
56 ERROR("Failed to enter netns of container");
60 /* Grab the list of interfaces */
61 if (netns_getifaddrs(&interfaceArray
, -1, &(bool){false})) {
62 ERROR("Failed to get interfaces list");
66 /* Iterate through the interfaces */
67 for (tempIfAddr
= interfaceArray
; tempIfAddr
!= NULL
; tempIfAddr
= tempIfAddr
->ifa_next
) {
68 if (strncmp(tempIfAddr
->ifa_name
, dev_name
, strlen(tempIfAddr
->ifa_name
)) == 0)
75 if (wait_for_pid(p
) == 0)
81 int main(int argc
, char *argv
[])
83 struct lxc_container
*c
;
85 char *cmd
, *dev_name
, *dst_name
;
89 ERROR("%s must be run as root", argv
[0]);
93 if (lxc_arguments_parse(&my_args
, argc
, argv
))
96 log
.name
= my_args
.name
;
97 log
.file
= my_args
.log_file
;
98 log
.level
= my_args
.log_priority
;
99 log
.prefix
= my_args
.progname
;
100 log
.quiet
= my_args
.quiet
;
101 log
.lxcpath
= my_args
.lxcpath
[0];
103 if (lxc_log_init(&log
))
106 c
= lxc_container_new(my_args
.name
, my_args
.lxcpath
[0]);
108 ERROR("%s doesn't exist", my_args
.name
);
112 if (my_args
.rcfile
) {
115 if (!c
->load_config(c
, my_args
.rcfile
)) {
116 ERROR("Failed to load rcfile");
120 c
->configfile
= strdup(my_args
.rcfile
);
121 if (!c
->configfile
) {
122 ERROR("Out of memory setting new config filename");
127 if (!c
->is_running(c
)) {
128 ERROR("Container %s is not running", c
->name
);
132 if (my_args
.argc
< 2) {
133 ERROR("Error: no command given (Please see --help output)");
137 cmd
= my_args
.argv
[0];
138 dev_name
= my_args
.argv
[1];
140 if (my_args
.argc
< 3)
143 dst_name
= my_args
.argv
[2];
145 if (strncmp(cmd
, "add", strlen(cmd
)) == 0) {
146 if (is_interface(dev_name
, 1))
147 ret
= c
->attach_interface(c
, dev_name
, dst_name
);
149 ret
= c
->add_device_node(c
, dev_name
, dst_name
);
151 ERROR("Failed to add %s to %s", dev_name
, c
->name
);
154 } else if (strncmp(cmd
, "del", strlen(cmd
)) == 0) {
155 if (is_interface(dev_name
, c
->init_pid(c
)))
156 ret
= c
->detach_interface(c
, dev_name
, dst_name
);
158 ret
= c
->remove_device_node(c
, dev_name
, dst_name
);
160 ERROR("Failed to del %s from %s", dev_name
, c
->name
);
164 ERROR("Error: Please use add or del (Please see --help output)");
171 lxc_container_put(c
);