]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/confile.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>
40 lxc_log_define(lxc_confile
, lxc
);
42 static int config_pts(const char *, char *, struct lxc_conf
*);
43 static int config_tty(const char *, char *, struct lxc_conf
*);
44 static int config_cgroup(const char *, char *, struct lxc_conf
*);
45 static int config_mount(const char *, char *, struct lxc_conf
*);
46 static int config_rootfs(const char *, char *, struct lxc_conf
*);
47 static int config_utsname(const char *, char *, struct lxc_conf
*);
48 static int config_network_type(const char *, char *, struct lxc_conf
*);
49 static int config_network_flags(const char *, char *, struct lxc_conf
*);
50 static int config_network_link(const char *, char *, struct lxc_conf
*);
51 static int config_network_name(const char *, char *, struct lxc_conf
*);
52 static int config_network_hwaddr(const char *, char *, struct lxc_conf
*);
53 static int config_network_mtu(const char *, char *, struct lxc_conf
*);
54 static int config_network_ipv4(const char *, char *, struct lxc_conf
*);
55 static int config_network_ipv6(const char *, char *, struct lxc_conf
*);
57 typedef int (*config_cb
)(const char *, char *, struct lxc_conf
*);
64 static struct config config
[] = {
66 { "lxc.pts", config_pts
},
67 { "lxc.tty", config_tty
},
68 { "lxc.cgroup", config_cgroup
},
69 { "lxc.mount", config_mount
},
70 { "lxc.rootfs", config_rootfs
},
71 { "lxc.utsname", config_utsname
},
72 { "lxc.network.type", config_network_type
},
73 { "lxc.network.flags", config_network_flags
},
74 { "lxc.network.link", config_network_link
},
75 { "lxc.network.name", config_network_name
},
76 { "lxc.network.hwaddr", config_network_hwaddr
},
77 { "lxc.network.mtu", config_network_mtu
},
78 { "lxc.network.ipv4", config_network_ipv4
},
79 { "lxc.network.ipv6", config_network_ipv6
},
82 static const size_t config_size
= sizeof(config
)/sizeof(struct config
);
84 static struct config
*getconfig(const char *key
)
88 for (i
= 0; i
< config_size
; i
++)
89 if (!strncmp(config
[i
].name
, key
,
90 strlen(config
[i
].name
)))
95 static int config_network_type(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
97 struct lxc_list
*network
= &lxc_conf
->network
;
98 struct lxc_netdev
*netdev
;
99 struct lxc_list
*list
;
101 netdev
= malloc(sizeof(*netdev
));
103 SYSERROR("failed to allocate memory");
107 memset(netdev
, 0, sizeof(*netdev
));
108 lxc_list_init(&netdev
->ipv4
);
109 lxc_list_init(&netdev
->ipv6
);
111 list
= malloc(sizeof(*list
));
113 SYSERROR("failed to allocate memory");
120 lxc_list_add(network
, list
);
122 if (!strcmp(value
, "veth"))
124 else if (!strcmp(value
, "macvlan"))
125 netdev
->type
= MACVLAN
;
126 else if (!strcmp(value
, "phys"))
128 else if (!strcmp(value
, "empty"))
129 netdev
->type
= EMPTY
;
131 ERROR("invalid network type %s", value
);
137 static int config_ip_prefix(struct in_addr
*addr
)
139 if (IN_CLASSA(addr
->s_addr
))
140 return 32 - IN_CLASSA_NSHIFT
;
141 if (IN_CLASSB(addr
->s_addr
))
142 return 32 - IN_CLASSB_NSHIFT
;
143 if (IN_CLASSC(addr
->s_addr
))
144 return 32 - IN_CLASSC_NSHIFT
;
149 static struct lxc_netdev
*network_netdev(const char *key
, char *value
,
150 struct lxc_conf
*lxc_conf
)
152 struct lxc_list
*network
= &lxc_conf
->network
;
153 struct lxc_netdev
*netdev
;
155 if (lxc_list_empty(network
)) {
156 ERROR("network is not created for '%s' option", value
);
160 netdev
= lxc_list_first_elem(network
);
162 ERROR("no network defined for '%s' option", value
);
169 static int network_ifname(char **valuep
, char *value
)
171 if (strlen(value
) > IFNAMSIZ
) {
172 ERROR("invalid interface name: %s", value
);
176 *valuep
= strdup(value
);
181 static int config_network_flags(const char *key
, char *value
,
182 struct lxc_conf
*lxc_conf
)
184 struct lxc_netdev
*netdev
;
186 netdev
= network_netdev(key
, value
, lxc_conf
);
190 netdev
->flags
|= IFF_UP
;
195 static int config_network_link(const char *key
, char *value
,
196 struct lxc_conf
*lxc_conf
)
198 struct lxc_netdev
*netdev
;
200 netdev
= network_netdev(key
, value
, lxc_conf
);
204 return network_ifname(&netdev
->link
, value
);
207 static int config_network_name(const char *key
, char *value
,
208 struct lxc_conf
*lxc_conf
)
210 struct lxc_netdev
*netdev
;
212 netdev
= network_netdev(key
, value
, lxc_conf
);
216 return network_ifname(&netdev
->name
, value
);
219 static int config_network_hwaddr(const char *key
, char *value
,
220 struct lxc_conf
*lxc_conf
)
222 struct lxc_netdev
*netdev
;
224 netdev
= network_netdev(key
, value
, lxc_conf
);
228 netdev
->hwaddr
= strdup(value
);
233 static int config_network_mtu(const char *key
, char *value
,
234 struct lxc_conf
*lxc_conf
)
236 struct lxc_netdev
*netdev
;
238 netdev
= network_netdev(key
, value
, lxc_conf
);
242 netdev
->mtu
= strdup(value
);
247 static int config_network_ipv4(const char *key
, char *value
,
248 struct lxc_conf
*lxc_conf
)
250 struct lxc_netdev
*netdev
;
251 struct lxc_inetdev
*inetdev
;
252 struct lxc_list
*list
;
253 char *cursor
, *slash
, *addr
= NULL
, *bcast
= NULL
, *prefix
= NULL
;
255 netdev
= network_netdev(key
, value
, lxc_conf
);
259 inetdev
= malloc(sizeof(*inetdev
));
261 SYSERROR("failed to allocate ipv4 address");
264 memset(inetdev
, 0, sizeof(*inetdev
));
266 list
= malloc(sizeof(*list
));
268 SYSERROR("failed to allocate memory");
273 list
->elem
= inetdev
;
277 cursor
= strstr(addr
, " ");
283 slash
= strstr(addr
, "/");
290 ERROR("no address specified");
294 if (!inet_pton(AF_INET
, addr
, &inetdev
->addr
)) {
295 SYSERROR("invalid ipv4 address: %s", value
);
300 if (!inet_pton(AF_INET
, bcast
, &inetdev
->bcast
)) {
301 SYSERROR("invalid ipv4 address: %s", value
);
305 /* no prefix specified, determine it from the network class */
306 inetdev
->prefix
= prefix
? atoi(prefix
) :
307 config_ip_prefix(&inetdev
->addr
);
310 lxc_list_add(&netdev
->ipv4
, list
);
315 static int config_network_ipv6(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
317 struct lxc_netdev
*netdev
;
318 struct lxc_inet6dev
*inet6dev
;
319 struct lxc_list
*list
;
323 netdev
= network_netdev(key
, value
, lxc_conf
);
327 inet6dev
= malloc(sizeof(*inet6dev
));
329 SYSERROR("failed to allocate ipv6 address");
332 memset(inet6dev
, 0, sizeof(*inet6dev
));
334 list
= malloc(sizeof(*list
));
336 SYSERROR("failed to allocate memory");
341 list
->elem
= inet6dev
;
343 inet6dev
->prefix
= 64;
344 slash
= strstr(value
, "/");
348 inet6dev
->prefix
= atoi(netmask
);
351 if (!inet_pton(AF_INET6
, value
, &inet6dev
->addr
)) {
352 SYSERROR("invalid ipv6 address: %s", value
);
356 lxc_list_add(&netdev
->ipv6
, list
);
361 static int config_pts(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
363 int maxpts
= atoi(value
);
365 lxc_conf
->pts
= maxpts
;
370 static int config_tty(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
372 int nbtty
= atoi(value
);
374 lxc_conf
->tty
= nbtty
;
379 static int config_cgroup(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
381 char *token
= "lxc.cgroup.";
383 struct lxc_list
*cglist
;
384 struct lxc_cgroup
*cgelem
;
386 subkey
= strstr(key
, token
);
394 if (strlen(subkey
) == strlen(token
))
397 subkey
+= strlen(token
);
399 cglist
= malloc(sizeof(*cglist
));
403 cgelem
= malloc(sizeof(*cgelem
));
409 cgelem
->subsystem
= strdup(subkey
);
410 cgelem
->value
= strdup(value
);
411 cglist
->elem
= cgelem
;
413 lxc_list_add_tail(&lxc_conf
->cgroup
, cglist
);
418 static int config_fstab(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
420 if (strlen(value
) >= MAXPATHLEN
) {
421 ERROR("%s path is too long", value
);
425 lxc_conf
->fstab
= strdup(value
);
426 if (!lxc_conf
->fstab
) {
427 SYSERROR("failed to duplicate string %s", value
);
434 static int config_mount(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
436 char *fstab_token
= "lxc.mount";
437 char *token
= "lxc.mount.entry";
440 struct lxc_list
*mntlist
;
442 subkey
= strstr(key
, token
);
445 subkey
= strstr(key
, fstab_token
);
450 return config_fstab(key
, value
, lxc_conf
);
456 mntlist
= malloc(sizeof(*mntlist
));
460 mntelem
= strdup(value
);
461 mntlist
->elem
= mntelem
;
463 lxc_list_add_tail(&lxc_conf
->mount_list
, mntlist
);
468 static int config_rootfs(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
470 if (strlen(value
) >= MAXPATHLEN
) {
471 ERROR("%s path is too long", value
);
475 lxc_conf
->rootfs
= strdup(value
);
476 if (!lxc_conf
->rootfs
) {
477 SYSERROR("failed to duplicate string %s", value
);
484 static int config_utsname(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
486 struct utsname
*utsname
;
488 utsname
= malloc(sizeof(*utsname
));
490 SYSERROR("failed to allocate memory");
494 if (strlen(value
) >= sizeof(utsname
->nodename
)) {
495 ERROR("node name '%s' is too long",
500 strcpy(utsname
->nodename
, value
);
501 lxc_conf
->utsname
= utsname
;
506 static int parse_line(void *buffer
, void *data
)
508 struct config
*config
;
514 if (lxc_is_line_empty(line
))
517 line
+= lxc_char_left_gc(line
, strlen(line
));
521 dot
= strstr(line
, "=");
523 ERROR("invalid configuration line: %s", line
);
531 key
[lxc_char_right_gc(key
, strlen(key
))] = '\0';
533 value
+= lxc_char_left_gc(value
, strlen(value
));
534 value
[lxc_char_right_gc(value
, strlen(value
))] = '\0';
536 config
= getconfig(key
);
538 ERROR("unknow key %s", key
);
542 return config
->cb(key
, value
, data
);
545 int lxc_config_read(const char *file
, struct lxc_conf
*conf
)
547 char buffer
[MAXPATHLEN
];
549 return lxc_file_for_each_line(file
, parse_line
, buffer
,
550 sizeof(buffer
), conf
);