]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/lxc_config.c
2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <dlezcano at fr.ibm.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <sys/types.h>
29 #include <sys/param.h>
30 #include <sys/utsname.h>
31 #include <arpa/inet.h>
32 #include <netinet/in.h>
37 typedef int (*file_cb
)(char* buffer
, void *data
);
38 typedef int (*config_cb
)(const char *, char *, struct lxc_conf
*);
40 static int config_tty(const char *, char *, struct lxc_conf
*);
41 static int config_cgroup(const char *, char *, struct lxc_conf
*);
42 static int config_mount(const char *, char *, struct lxc_conf
*);
43 static int config_rootfs(const char *, char *, struct lxc_conf
*);
44 static int config_utsname(const char *, char *, struct lxc_conf
*);
45 static int config_network_type(const char *, char *, struct lxc_conf
*);
46 static int config_network_flags(const char *, char *, struct lxc_conf
*);
47 static int config_network_link(const char *, char *, struct lxc_conf
*);
48 static int config_network_name(const char *, char *, struct lxc_conf
*);
49 static int config_network_hwaddr(const char *, char *, struct lxc_conf
*);
50 static int config_network_ipv4(const char *, char *, struct lxc_conf
*);
51 static int config_network_ipv6(const char *, char *, struct lxc_conf
*);
58 static struct config config
[] = {
60 { "lxc.tty", config_tty
},
61 { "lxc.cgroup", config_cgroup
},
62 { "lxc.mount", config_mount
},
63 { "lxc.rootfs", config_rootfs
},
64 { "lxc.utsname", config_utsname
},
65 { "lxc.network.type", config_network_type
},
66 { "lxc.network.flags", config_network_flags
},
67 { "lxc.network.link", config_network_link
},
68 { "lxc.network.name", config_network_name
},
69 { "lxc.network.hwaddr", config_network_hwaddr
},
70 { "lxc.network.ipv4", config_network_ipv4
},
71 { "lxc.network.ipv6", config_network_ipv6
},
74 static const size_t config_size
= sizeof(config
)/sizeof(struct config
);
76 static struct config
*getconfig(const char *key
)
80 for (i
= 0; i
< config_size
; i
++)
81 if (!strncmp(config
[i
].name
, key
,
82 strlen(config
[i
].name
)))
87 static int is_line_empty(char *line
)
90 size_t len
= strlen(line
);
92 for (i
= 0; i
< len
; i
++)
93 if (line
[i
] != ' ' && line
[i
] != '\t' &&
94 line
[i
] != '\n' && line
[i
] != '\r' &&
95 line
[i
] != '\f' && line
[i
] != '\0')
100 static int char_left_gc(char *buffer
, size_t len
)
103 for (i
= 0; i
< len
; i
++) {
104 if (buffer
[i
] == ' ' ||
112 static int char_right_gc(char *buffer
, size_t len
)
115 for (i
= len
- 1; i
>= 0; i
--) {
116 if (buffer
[i
] == ' ' ||
126 static int config_network_type(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
128 struct lxc_list
*networks
= &lxc_conf
->networks
;
129 struct lxc_network
*network
;
130 struct lxc_netdev
*netdev
;
131 struct lxc_list
*list
;
132 struct lxc_list
*ndlist
;
134 network
= malloc(sizeof(*network
));
136 lxc_log_syserror("failed to allocate memory");
140 lxc_list_init(&network
->netdev
);
142 netdev
= malloc(sizeof(*netdev
));
144 lxc_log_syserror("failed to allocate memory");
148 lxc_list_init(&netdev
->ipv4
);
149 lxc_list_init(&netdev
->ipv6
);
150 lxc_list_init(&netdev
->route4
);
151 lxc_list_init(&netdev
->route6
);
153 ndlist
= malloc(sizeof(*ndlist
));
155 lxc_log_syserror("failed to allocate memory");
159 ndlist
->elem
= netdev
;
161 lxc_list_add(&network
->netdev
, ndlist
);
163 list
= malloc(sizeof(*list
));
165 lxc_log_syserror("failed to allocate memory");
170 list
->elem
= network
;
172 lxc_list_add(networks
, list
);
174 if (!strcmp(value
, "veth"))
175 network
->type
= VETH
;
176 else if (!strcmp(value
, "macvlan"))
177 network
->type
= MACVLAN
;
178 else if (!strcmp(value
, "phys"))
179 network
->type
= PHYS
;
180 else if (!strcmp(value
, "empty"))
181 network
->type
= EMPTY
;
183 lxc_log_error("invalid network type %s", value
);
189 static int config_network_flags(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
191 struct lxc_list
*networks
= &lxc_conf
->networks
;
192 struct lxc_network
*network
;
193 struct lxc_netdev
*netdev
;
195 if (lxc_list_empty(networks
)) {
196 lxc_log_error("network is not created for '%s' option", value
);
200 network
= lxc_list_first_elem(networks
);
202 lxc_log_error("no network defined for '%s' option", value
);
206 netdev
= lxc_list_first_elem(&network
->netdev
);
207 netdev
->flags
|= IFF_UP
;
211 static int config_network_link(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
213 struct lxc_list
*networks
= &lxc_conf
->networks
;
214 struct lxc_network
*network
;
215 struct lxc_netdev
*netdev
;
217 if (lxc_list_empty(networks
)) {
218 lxc_log_error("network is not created for %s", value
);
222 network
= lxc_list_first_elem(networks
);
224 lxc_log_error("no network defined for %s", value
);
228 if (strlen(value
) > IFNAMSIZ
) {
229 lxc_log_error("invalid interface name: %s", value
);
233 netdev
= lxc_list_first_elem(&network
->netdev
);
234 netdev
->ifname
= strdup(value
);
238 static int config_network_name(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
240 struct lxc_list
*networks
= &lxc_conf
->networks
;
241 struct lxc_network
*network
;
242 struct lxc_netdev
*netdev
;
244 if (lxc_list_empty(networks
)) {
245 lxc_log_error("network is not created for %s", value
);
249 network
= lxc_list_first_elem(networks
);
251 lxc_log_error("no network defined for %s", value
);
255 if (strlen(value
) > IFNAMSIZ
) {
256 lxc_log_error("invalid interface name: %s", value
);
260 netdev
= lxc_list_first_elem(&network
->netdev
);
261 netdev
->newname
= strdup(value
);
265 static int config_network_hwaddr(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
267 struct lxc_list
*networks
= &lxc_conf
->networks
;
268 struct lxc_network
*network
;
269 struct lxc_netdev
*netdev
;
271 if (lxc_list_empty(networks
)) {
272 lxc_log_error("network is not created for %s", value
);
276 network
= lxc_list_first_elem(networks
);
278 lxc_log_error("no network defined for %s", value
);
282 netdev
= lxc_list_first_elem(&network
->netdev
);
283 netdev
->hwaddr
= strdup(value
);
287 static int config_network_ipv4(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
289 struct lxc_list
*networks
= &lxc_conf
->networks
;
290 struct lxc_network
*network
;
291 struct lxc_inetdev
*inetdev
;
292 struct lxc_netdev
*netdev
;
293 struct lxc_list
*list
;
294 char *cursor
, *slash
, *addr
= NULL
, *bcast
= NULL
, *prefix
= NULL
;
296 if (lxc_list_empty(networks
)) {
297 lxc_log_error("network is not created for '%s'", value
);
301 network
= lxc_list_first_elem(networks
);
303 lxc_log_error("no network defined for '%s'", value
);
307 netdev
= lxc_list_first_elem(&network
->netdev
);
309 lxc_log_error("no netdev defined for '%s'", value
);
312 inetdev
= malloc(sizeof(*inetdev
));
314 lxc_log_syserror("failed to allocate ipv4 address");
317 memset(inetdev
, 0, sizeof(*inetdev
));
319 list
= malloc(sizeof(*list
));
321 lxc_log_syserror("failed to allocate memory");
326 list
->elem
= inetdev
;
330 cursor
= strstr(addr
, " ");
336 slash
= strstr(addr
, "/");
343 lxc_log_error("no address specified");
347 if (!inet_pton(AF_INET
, addr
, &inetdev
->addr
)) {
348 lxc_log_syserror("invalid ipv4 address: %s", value
);
353 if (!inet_pton(AF_INET
, bcast
, &inetdev
->bcast
)) {
354 lxc_log_syserror("invalid ipv4 address: %s", value
);
359 inetdev
->prefix
= atoi(prefix
);
361 lxc_list_add(&netdev
->ipv4
, list
);
366 static int config_network_ipv6(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
368 struct lxc_list
*networks
= &lxc_conf
->networks
;
369 struct lxc_network
*network
;
370 struct lxc_netdev
*netdev
;
371 struct lxc_inet6dev
*inet6dev
;
372 struct lxc_list
*list
;
376 if (lxc_list_empty(networks
)) {
377 lxc_log_error("network is not created for %s", value
);
381 network
= lxc_list_first_elem(networks
);
383 lxc_log_error("no network defined for %s", value
);
387 inet6dev
= malloc(sizeof(*inet6dev
));
389 lxc_log_syserror("failed to allocate ipv6 address");
392 memset(inet6dev
, 0, sizeof(*inet6dev
));
394 list
= malloc(sizeof(*list
));
396 lxc_log_syserror("failed to allocate memory");
401 list
->elem
= inet6dev
;
403 slash
= strstr(value
, "/");
407 inet6dev
->prefix
= atoi(netmask
);
410 if (!inet_pton(AF_INET6
, value
, &inet6dev
->addr
)) {
411 lxc_log_syserror("invalid ipv6 address: %s", value
);
416 netdev
= lxc_list_first_elem(&network
->netdev
);
417 lxc_list_add(&netdev
->ipv6
, list
);
422 static int config_tty(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
424 int nbtty
= atoi(value
);
426 lxc_conf
->tty
= nbtty
;
431 static int config_cgroup(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
433 char *token
= "lxc.cgroup.";
435 struct lxc_list
*cglist
;
436 struct lxc_cgroup
*cgelem
;
438 subkey
= strstr(key
, token
);
446 if (strlen(subkey
) == strlen(token
))
449 subkey
+= strlen(token
);
451 cglist
= malloc(sizeof(*cglist
));
455 cgelem
= malloc(sizeof(*cgelem
));
461 cgelem
->subsystem
= strdup(subkey
);
462 cgelem
->value
= strdup(value
);
463 cglist
->elem
= cgelem
;
465 lxc_list_add_tail(&lxc_conf
->cgroup
, cglist
);
470 static int config_mount(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
472 if (strlen(value
) >= MAXPATHLEN
) {
473 lxc_log_error("%s path is too long", value
);
477 lxc_conf
->fstab
= strdup(value
);
478 if (!lxc_conf
->fstab
) {
479 lxc_log_syserror("failed to duplicate string %s", value
);
486 static int config_rootfs(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
488 if (strlen(value
) >= MAXPATHLEN
) {
489 lxc_log_error("%s path is too long", value
);
493 lxc_conf
->rootfs
= strdup(value
);
494 if (!lxc_conf
->rootfs
) {
495 lxc_log_syserror("failed to duplicate string %s", value
);
502 static int config_utsname(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
504 struct utsname
*utsname
;
506 utsname
= malloc(sizeof(*utsname
));
508 lxc_log_syserror("failed to allocate memory");
512 if (strlen(value
) >= sizeof(utsname
->nodename
)) {
513 lxc_log_error("node name '%s' is too long",
518 strcpy(utsname
->nodename
, value
);
519 lxc_conf
->utsname
= utsname
;
524 static int parse_line(char *buffer
, void *data
)
526 struct config
*config
;
531 if (is_line_empty(buffer
))
534 buffer
+= char_left_gc(buffer
, strlen(buffer
));
535 if (buffer
[0] == '#')
538 dot
= strstr(buffer
, "=");
540 lxc_log_error("invalid configuration line: %s", buffer
);
548 key
[char_right_gc(key
, strlen(key
))] = '\0';
550 value
+= char_left_gc(value
, strlen(value
));
551 value
[char_right_gc(value
, strlen(value
))] = '\0';
553 config
= getconfig(key
);
555 lxc_log_error("unknow key %s", key
);
559 return config
->cb(key
, value
, data
);
562 static int file_for_each_line(const char *file
, file_cb callback
, void *data
)
564 char buffer
[MAXPATHLEN
];
565 size_t len
= sizeof(buffer
);
569 f
= fopen(file
, "r");
571 lxc_log_syserror("failed to open %s", file
);
575 while (fgets(buffer
, len
, f
))
576 if (callback(buffer
, data
))
584 int lxc_config_read(const char *file
, struct lxc_conf
*conf
)
586 return file_for_each_line(file
, parse_line
, conf
);
589 int lxc_config_init(struct lxc_conf
*conf
)
593 conf
->utsname
= NULL
;
595 lxc_list_init(&conf
->cgroup
);
596 lxc_list_init(&conf
->networks
);