]>
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 int config_network_flags(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
151 struct lxc_list
*network
= &lxc_conf
->network
;
152 struct lxc_netdev
*netdev
;
154 if (lxc_list_empty(network
)) {
155 ERROR("network is not created for '%s' option", value
);
159 netdev
= lxc_list_first_elem(network
);
161 ERROR("no network defined for '%s' option", value
);
165 netdev
->flags
|= IFF_UP
;
169 static int config_network_link(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
171 struct lxc_list
*network
= &lxc_conf
->network
;
172 struct lxc_netdev
*netdev
;
174 if (lxc_list_empty(network
)) {
175 ERROR("network is not created for %s", value
);
179 netdev
= lxc_list_first_elem(network
);
181 ERROR("no network defined for %s", value
);
185 if (strlen(value
) > IFNAMSIZ
) {
186 ERROR("invalid interface name: %s", value
);
190 netdev
->ifname
= strdup(value
);
194 static int config_network_name(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
196 struct lxc_list
*network
= &lxc_conf
->network
;
197 struct lxc_netdev
*netdev
;
199 if (lxc_list_empty(network
)) {
200 ERROR("network is not created for %s", value
);
204 netdev
= lxc_list_first_elem(network
);
206 ERROR("no network defined for %s", value
);
210 if (strlen(value
) > IFNAMSIZ
) {
211 ERROR("invalid interface name: %s", value
);
215 netdev
->newname
= strdup(value
);
219 static int config_network_hwaddr(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
221 struct lxc_list
*network
= &lxc_conf
->network
;
222 struct lxc_netdev
*netdev
;
224 if (lxc_list_empty(network
)) {
225 ERROR("network is not created for %s", value
);
229 netdev
= lxc_list_first_elem(network
);
231 ERROR("no network defined for %s", value
);
235 netdev
->hwaddr
= strdup(value
);
239 static int config_network_mtu(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
241 struct lxc_list
*network
= &lxc_conf
->network
;
242 struct lxc_netdev
*netdev
;
244 if (lxc_list_empty(network
)) {
245 ERROR("network is not created for %s", value
);
249 netdev
= lxc_list_first_elem(network
);
251 ERROR("no network defined for %s", value
);
255 netdev
->mtu
= strdup(value
);
259 static int config_network_ipv4(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
261 struct lxc_list
*network
= &lxc_conf
->network
;
262 struct lxc_inetdev
*inetdev
;
263 struct lxc_netdev
*netdev
;
264 struct lxc_list
*list
;
265 char *cursor
, *slash
, *addr
= NULL
, *bcast
= NULL
, *prefix
= NULL
;
267 if (lxc_list_empty(network
)) {
268 ERROR("network is not created for '%s'", value
);
272 netdev
= lxc_list_first_elem(network
);
274 ERROR("no netdev defined for '%s'", value
);
277 inetdev
= malloc(sizeof(*inetdev
));
279 SYSERROR("failed to allocate ipv4 address");
282 memset(inetdev
, 0, sizeof(*inetdev
));
284 list
= malloc(sizeof(*list
));
286 SYSERROR("failed to allocate memory");
291 list
->elem
= inetdev
;
295 cursor
= strstr(addr
, " ");
301 slash
= strstr(addr
, "/");
308 ERROR("no address specified");
312 if (!inet_pton(AF_INET
, addr
, &inetdev
->addr
)) {
313 SYSERROR("invalid ipv4 address: %s", value
);
318 if (!inet_pton(AF_INET
, bcast
, &inetdev
->bcast
)) {
319 SYSERROR("invalid ipv4 address: %s", value
);
323 /* no prefix specified, determine it from the network class */
324 inetdev
->prefix
= prefix
? atoi(prefix
) :
325 config_ip_prefix(&inetdev
->addr
);
328 lxc_list_add(&netdev
->ipv4
, list
);
333 static int config_network_ipv6(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
335 struct lxc_list
*network
= &lxc_conf
->network
;
336 struct lxc_netdev
*netdev
;
337 struct lxc_inet6dev
*inet6dev
;
338 struct lxc_list
*list
;
342 if (lxc_list_empty(network
)) {
343 ERROR("network is not created for %s", value
);
347 netdev
= lxc_list_first_elem(network
);
349 ERROR("no network defined for %s", value
);
353 inet6dev
= malloc(sizeof(*inet6dev
));
355 SYSERROR("failed to allocate ipv6 address");
358 memset(inet6dev
, 0, sizeof(*inet6dev
));
360 list
= malloc(sizeof(*list
));
362 SYSERROR("failed to allocate memory");
367 list
->elem
= inet6dev
;
369 inet6dev
->prefix
= 64;
370 slash
= strstr(value
, "/");
374 inet6dev
->prefix
= atoi(netmask
);
377 if (!inet_pton(AF_INET6
, value
, &inet6dev
->addr
)) {
378 SYSERROR("invalid ipv6 address: %s", value
);
382 lxc_list_add(&netdev
->ipv6
, list
);
387 static int config_pts(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
389 int maxpts
= atoi(value
);
391 lxc_conf
->pts
= maxpts
;
396 static int config_tty(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
398 int nbtty
= atoi(value
);
400 lxc_conf
->tty
= nbtty
;
405 static int config_cgroup(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
407 char *token
= "lxc.cgroup.";
409 struct lxc_list
*cglist
;
410 struct lxc_cgroup
*cgelem
;
412 subkey
= strstr(key
, token
);
420 if (strlen(subkey
) == strlen(token
))
423 subkey
+= strlen(token
);
425 cglist
= malloc(sizeof(*cglist
));
429 cgelem
= malloc(sizeof(*cgelem
));
435 cgelem
->subsystem
= strdup(subkey
);
436 cgelem
->value
= strdup(value
);
437 cglist
->elem
= cgelem
;
439 lxc_list_add_tail(&lxc_conf
->cgroup
, cglist
);
444 static int config_fstab(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
446 if (strlen(value
) >= MAXPATHLEN
) {
447 ERROR("%s path is too long", value
);
451 lxc_conf
->fstab
= strdup(value
);
452 if (!lxc_conf
->fstab
) {
453 SYSERROR("failed to duplicate string %s", value
);
460 static int config_mount(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
462 char *fstab_token
= "lxc.mount";
463 char *token
= "lxc.mount.entry";
466 struct lxc_list
*mntlist
;
468 subkey
= strstr(key
, token
);
471 subkey
= strstr(key
, fstab_token
);
476 return config_fstab(key
, value
, lxc_conf
);
482 mntlist
= malloc(sizeof(*mntlist
));
486 mntelem
= strdup(value
);
487 mntlist
->elem
= mntelem
;
489 lxc_list_add_tail(&lxc_conf
->mount_list
, mntlist
);
494 static int config_rootfs(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
496 if (strlen(value
) >= MAXPATHLEN
) {
497 ERROR("%s path is too long", value
);
501 lxc_conf
->rootfs
= strdup(value
);
502 if (!lxc_conf
->rootfs
) {
503 SYSERROR("failed to duplicate string %s", value
);
510 static int config_utsname(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
512 struct utsname
*utsname
;
514 utsname
= malloc(sizeof(*utsname
));
516 SYSERROR("failed to allocate memory");
520 if (strlen(value
) >= sizeof(utsname
->nodename
)) {
521 ERROR("node name '%s' is too long",
526 strcpy(utsname
->nodename
, value
);
527 lxc_conf
->utsname
= utsname
;
532 static int parse_line(void *buffer
, void *data
)
534 struct config
*config
;
540 if (lxc_is_line_empty(line
))
543 line
+= lxc_char_left_gc(line
, strlen(line
));
547 dot
= strstr(line
, "=");
549 ERROR("invalid configuration line: %s", line
);
557 key
[lxc_char_right_gc(key
, strlen(key
))] = '\0';
559 value
+= lxc_char_left_gc(value
, strlen(value
));
560 value
[lxc_char_right_gc(value
, strlen(value
))] = '\0';
562 config
= getconfig(key
);
564 ERROR("unknow key %s", key
);
568 return config
->cb(key
, value
, data
);
571 int lxc_config_read(const char *file
, struct lxc_conf
*conf
)
573 char buffer
[MAXPATHLEN
];
575 return lxc_file_for_each_line(file
, parse_line
, buffer
,
576 sizeof(buffer
), conf
);