]>
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_cgroup(const char *, char *, struct lxc_conf
*);
41 static int config_mount(const char *, char *, struct lxc_conf
*);
42 static int config_rootfs(const char *, char *, struct lxc_conf
*);
43 static int config_utsname(const char *, char *, struct lxc_conf
*);
44 static int config_network_type(const char *, char *, struct lxc_conf
*);
45 static int config_network_flags(const char *, char *, struct lxc_conf
*);
46 static int config_network_link(const char *, char *, struct lxc_conf
*);
47 static int config_network_name(const char *, char *, struct lxc_conf
*);
48 static int config_network_hwaddr(const char *, char *, struct lxc_conf
*);
49 static int config_network_ipv4(const char *, char *, struct lxc_conf
*);
50 static int config_network_ipv6(const char *, char *, struct lxc_conf
*);
57 static struct config config
[] = {
59 { "lxc.cgroup", config_cgroup
},
60 { "lxc.mount", config_mount
},
61 { "lxc.rootfs", config_rootfs
},
62 { "lxc.utsname", config_utsname
},
63 { "lxc.network.type", config_network_type
},
64 { "lxc.network.flags", config_network_flags
},
65 { "lxc.network.link", config_network_link
},
66 { "lxc.network.name", config_network_name
},
67 { "lxc.network.hwaddr", config_network_hwaddr
},
68 { "lxc.network.ipv4", config_network_ipv4
},
69 { "lxc.network.ipv6", config_network_ipv6
},
72 static const size_t config_size
= sizeof(config
)/sizeof(struct config
);
74 static struct config
*getconfig(const char *key
)
78 for (i
= 0; i
< config_size
; i
++)
79 if (!strncmp(config
[i
].name
, key
,
80 strlen(config
[i
].name
)))
85 static int is_line_empty(char *line
)
88 size_t len
= strlen(line
);
90 for (i
= 0; i
< len
; i
++)
91 if (line
[i
] != ' ' && line
[i
] != '\t' &&
92 line
[i
] != '\n' && line
[i
] != '\r' &&
93 line
[i
] != '\f' && line
[i
] != '\0')
98 static int char_left_gc(char *buffer
, size_t len
)
101 for (i
= 0; i
< len
; i
++) {
102 if (buffer
[i
] == ' ' ||
110 static int char_right_gc(char *buffer
, size_t len
)
113 for (i
= len
- 1; i
>= 0; i
--) {
114 if (buffer
[i
] == ' ' ||
124 static int config_network_type(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
126 struct lxc_list
*networks
= &lxc_conf
->networks
;
127 struct lxc_network
*network
;
128 struct lxc_netdev
*netdev
;
129 struct lxc_list
*list
;
130 struct lxc_list
*ndlist
;
132 network
= malloc(sizeof(*network
));
134 lxc_log_syserror("failed to allocate memory");
138 lxc_list_init(&network
->netdev
);
140 netdev
= malloc(sizeof(*netdev
));
142 lxc_log_syserror("failed to allocate memory");
146 lxc_list_init(&netdev
->ipv4
);
147 lxc_list_init(&netdev
->ipv6
);
148 lxc_list_init(&netdev
->route4
);
149 lxc_list_init(&netdev
->route6
);
151 ndlist
= malloc(sizeof(*ndlist
));
153 lxc_log_syserror("failed to allocate memory");
157 ndlist
->elem
= netdev
;
159 lxc_list_add(&network
->netdev
, ndlist
);
161 list
= malloc(sizeof(*list
));
163 lxc_log_syserror("failed to allocate memory");
168 list
->elem
= network
;
170 lxc_list_add(networks
, list
);
172 if (!strcmp(value
, "veth"))
173 network
->type
= VETH
;
174 else if (!strcmp(value
, "macvlan"))
175 network
->type
= MACVLAN
;
176 else if (!strcmp(value
, "phys"))
177 network
->type
= PHYS
;
178 else if (!strcmp(value
, "empty"))
179 network
->type
= EMPTY
;
181 lxc_log_error("invalid network type %s", value
);
187 static int config_network_flags(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
189 struct lxc_list
*networks
= &lxc_conf
->networks
;
190 struct lxc_network
*network
;
191 struct lxc_netdev
*netdev
;
193 if (lxc_list_empty(networks
)) {
194 lxc_log_error("network is not created for '%s' option", value
);
198 network
= lxc_list_first_elem(networks
);
200 lxc_log_error("no network defined for '%s' option", value
);
204 netdev
= lxc_list_first_elem(&network
->netdev
);
205 netdev
->flags
|= IFF_UP
;
209 static int config_network_link(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
211 struct lxc_list
*networks
= &lxc_conf
->networks
;
212 struct lxc_network
*network
;
213 struct lxc_netdev
*netdev
;
215 if (lxc_list_empty(networks
)) {
216 lxc_log_error("network is not created for %s", value
);
220 network
= lxc_list_first_elem(networks
);
222 lxc_log_error("no network defined for %s", value
);
226 if (strlen(value
) > IFNAMSIZ
) {
227 lxc_log_error("invalid interface name: %s", value
);
231 netdev
= lxc_list_first_elem(&network
->netdev
);
232 netdev
->ifname
= strdup(value
);
236 static int config_network_name(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
238 struct lxc_list
*networks
= &lxc_conf
->networks
;
239 struct lxc_network
*network
;
240 struct lxc_netdev
*netdev
;
242 if (lxc_list_empty(networks
)) {
243 lxc_log_error("network is not created for %s", value
);
247 network
= lxc_list_first_elem(networks
);
249 lxc_log_error("no network defined for %s", value
);
253 if (strlen(value
) > IFNAMSIZ
) {
254 lxc_log_error("invalid interface name: %s", value
);
258 netdev
= lxc_list_first_elem(&network
->netdev
);
259 netdev
->newname
= strdup(value
);
263 static int config_network_hwaddr(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
265 struct lxc_list
*networks
= &lxc_conf
->networks
;
266 struct lxc_network
*network
;
267 struct lxc_netdev
*netdev
;
269 if (lxc_list_empty(networks
)) {
270 lxc_log_error("network is not created for %s", value
);
274 network
= lxc_list_first_elem(networks
);
276 lxc_log_error("no network defined for %s", value
);
280 netdev
= lxc_list_first_elem(&network
->netdev
);
281 netdev
->hwaddr
= strdup(value
);
285 static int config_network_ipv4(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
287 struct lxc_list
*networks
= &lxc_conf
->networks
;
288 struct lxc_network
*network
;
289 struct lxc_inetdev
*inetdev
;
290 struct lxc_netdev
*netdev
;
291 struct lxc_list
*list
;
292 char *cursor
, *slash
, *addr
= NULL
, *bcast
= NULL
, *prefix
= NULL
;
294 if (lxc_list_empty(networks
)) {
295 lxc_log_error("network is not created for '%s'", value
);
299 network
= lxc_list_first_elem(networks
);
301 lxc_log_error("no network defined for '%s'", value
);
305 netdev
= lxc_list_first_elem(&network
->netdev
);
307 lxc_log_error("no netdev defined for '%s'", value
);
310 inetdev
= malloc(sizeof(*inetdev
));
312 lxc_log_syserror("failed to allocate ipv4 address");
315 memset(inetdev
, 0, sizeof(*inetdev
));
317 list
= malloc(sizeof(*list
));
319 lxc_log_syserror("failed to allocate memory");
324 list
->elem
= inetdev
;
328 cursor
= strstr(addr
, " ");
334 slash
= strstr(addr
, "/");
341 lxc_log_error("no address specified");
345 if (!inet_pton(AF_INET
, addr
, &inetdev
->addr
)) {
346 lxc_log_syserror("invalid ipv4 address: %s", value
);
351 if (!inet_pton(AF_INET
, bcast
, &inetdev
->bcast
)) {
352 lxc_log_syserror("invalid ipv4 address: %s", value
);
357 inetdev
->prefix
= atoi(prefix
);
359 lxc_list_add(&netdev
->ipv4
, list
);
364 static int config_network_ipv6(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
366 struct lxc_list
*networks
= &lxc_conf
->networks
;
367 struct lxc_network
*network
;
368 struct lxc_netdev
*netdev
;
369 struct lxc_inet6dev
*inet6dev
;
370 struct lxc_list
*list
;
374 if (lxc_list_empty(networks
)) {
375 lxc_log_error("network is not created for %s", value
);
379 network
= lxc_list_first_elem(networks
);
381 lxc_log_error("no network defined for %s", value
);
385 inet6dev
= malloc(sizeof(*inet6dev
));
387 lxc_log_syserror("failed to allocate ipv6 address");
390 memset(inet6dev
, 0, sizeof(*inet6dev
));
392 list
= malloc(sizeof(*list
));
394 lxc_log_syserror("failed to allocate memory");
399 list
->elem
= inet6dev
;
401 slash
= strstr(value
, "/");
405 inet6dev
->prefix
= atoi(netmask
);
408 if (!inet_pton(AF_INET6
, value
, &inet6dev
->addr
)) {
409 lxc_log_syserror("invalid ipv6 address: %s", value
);
414 netdev
= lxc_list_first_elem(&network
->netdev
);
415 lxc_list_add(&netdev
->ipv6
, list
);
420 static int config_cgroup(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
422 char *token
= "lxc.cgroup.";
424 struct lxc_list
*cglist
;
425 struct lxc_cgroup
*cgelem
;
427 subkey
= strstr(key
, token
);
435 if (strlen(subkey
) == strlen(token
))
438 subkey
+= strlen(token
);
440 cglist
= malloc(sizeof(*cglist
));
444 cgelem
= malloc(sizeof(*cgelem
));
450 cgelem
->subsystem
= strdup(subkey
);
451 cgelem
->value
= strdup(value
);
452 cglist
->elem
= cgelem
;
454 lxc_list_add(&lxc_conf
->cgroup
, cglist
);
459 static int config_mount(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
461 if (strlen(value
) >= MAXPATHLEN
) {
462 lxc_log_error("%s path is too long", value
);
466 lxc_conf
->fstab
= strdup(value
);
467 if (!lxc_conf
->fstab
) {
468 lxc_log_syserror("failed to duplicate string %s", value
);
475 static int config_rootfs(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
477 if (strlen(value
) >= MAXPATHLEN
) {
478 lxc_log_error("%s path is too long", value
);
482 lxc_conf
->rootfs
= strdup(value
);
483 if (!lxc_conf
->rootfs
) {
484 lxc_log_syserror("failed to duplicate string %s", value
);
491 static int config_utsname(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
493 struct utsname
*utsname
;
495 utsname
= malloc(sizeof(*utsname
));
497 lxc_log_syserror("failed to allocate memory");
501 if (strlen(value
) >= sizeof(utsname
->nodename
)) {
502 lxc_log_error("node name '%s' is too long",
507 strcpy(utsname
->nodename
, value
);
508 lxc_conf
->utsname
= utsname
;
513 static int parse_line(char *buffer
, void *data
)
515 struct config
*config
;
520 if (is_line_empty(buffer
))
523 buffer
+= char_left_gc(buffer
, strlen(buffer
));
524 if (buffer
[0] == '#')
527 dot
= strstr(buffer
, "=");
529 lxc_log_error("invalid configuration line: %s", buffer
);
537 key
[char_right_gc(key
, strlen(key
))] = '\0';
539 value
+= char_left_gc(value
, strlen(value
));
540 value
[char_right_gc(value
, strlen(value
))] = '\0';
542 config
= getconfig(key
);
544 lxc_log_error("unknow key %s", key
);
548 return config
->cb(key
, value
, data
);
551 static int file_for_each_line(const char *file
, file_cb callback
, void *data
)
553 char buffer
[MAXPATHLEN
];
554 size_t len
= sizeof(buffer
);
558 f
= fopen(file
, "r");
560 lxc_log_syserror("failed to open %s", file
);
564 while (fgets(buffer
, len
, f
))
565 if (callback(buffer
, data
))
573 int lxc_config_read(const char *file
, struct lxc_conf
*conf
)
575 return file_for_each_line(file
, parse_line
, conf
);
578 int lxc_config_init(struct lxc_conf
*conf
)
582 conf
->utsname
= NULL
;
583 lxc_list_init(&conf
->cgroup
);
584 lxc_list_init(&conf
->networks
);