]>
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>
41 lxc_log_define(lxc_confile
, lxc
);
43 static int config_pts(const char *, char *, struct lxc_conf
*);
44 static int config_tty(const char *, char *, struct lxc_conf
*);
45 static int config_cgroup(const char *, char *, struct lxc_conf
*);
46 static int config_mount(const char *, char *, struct lxc_conf
*);
47 static int config_rootfs(const char *, char *, struct lxc_conf
*);
48 static int config_utsname(const char *, char *, struct lxc_conf
*);
49 static int config_network_type(const char *, char *, struct lxc_conf
*);
50 static int config_network_flags(const char *, char *, struct lxc_conf
*);
51 static int config_network_link(const char *, char *, struct lxc_conf
*);
52 static int config_network_name(const char *, char *, struct lxc_conf
*);
53 static int config_network_pair(const char *, char *, struct lxc_conf
*);
54 static int config_network_hwaddr(const char *, char *, struct lxc_conf
*);
55 static int config_network_vlanid(const char *, char *, struct lxc_conf
*);
56 static int config_network_mtu(const char *, char *, struct lxc_conf
*);
57 static int config_network_ipv4(const char *, char *, struct lxc_conf
*);
58 static int config_network_ipv6(const char *, char *, struct lxc_conf
*);
60 typedef int (*config_cb
)(const char *, char *, struct lxc_conf
*);
67 static struct config config
[] = {
69 { "lxc.pts", config_pts
},
70 { "lxc.tty", config_tty
},
71 { "lxc.cgroup", config_cgroup
},
72 { "lxc.mount", config_mount
},
73 { "lxc.rootfs", config_rootfs
},
74 { "lxc.utsname", config_utsname
},
75 { "lxc.network.type", config_network_type
},
76 { "lxc.network.flags", config_network_flags
},
77 { "lxc.network.link", config_network_link
},
78 { "lxc.network.name", config_network_name
},
79 { "lxc.network.pair", config_network_pair
},
80 { "lxc.network.hwaddr", config_network_hwaddr
},
81 { "lxc.network.mtu", config_network_mtu
},
82 { "lxc.network.vlanid", config_network_vlanid
},
83 { "lxc.network.ipv4", config_network_ipv4
},
84 { "lxc.network.ipv6", config_network_ipv6
},
87 static const size_t config_size
= sizeof(config
)/sizeof(struct config
);
89 static struct config
*getconfig(const char *key
)
93 for (i
= 0; i
< config_size
; i
++)
94 if (!strncmp(config
[i
].name
, key
,
95 strlen(config
[i
].name
)))
100 static int config_network_type(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
102 struct lxc_list
*network
= &lxc_conf
->network
;
103 struct lxc_netdev
*netdev
;
104 struct lxc_list
*list
;
106 netdev
= malloc(sizeof(*netdev
));
108 SYSERROR("failed to allocate memory");
112 memset(netdev
, 0, sizeof(*netdev
));
113 lxc_list_init(&netdev
->ipv4
);
114 lxc_list_init(&netdev
->ipv6
);
116 list
= malloc(sizeof(*list
));
118 SYSERROR("failed to allocate memory");
125 lxc_list_add(network
, list
);
127 if (!strcmp(value
, "veth"))
129 else if (!strcmp(value
, "macvlan"))
130 netdev
->type
= MACVLAN
;
131 else if (!strcmp(value
, "vlan"))
133 else if (!strcmp(value
, "phys"))
135 else if (!strcmp(value
, "empty"))
136 netdev
->type
= EMPTY
;
138 ERROR("invalid network type %s", value
);
144 static int config_ip_prefix(struct in_addr
*addr
)
146 if (IN_CLASSA(addr
->s_addr
))
147 return 32 - IN_CLASSA_NSHIFT
;
148 if (IN_CLASSB(addr
->s_addr
))
149 return 32 - IN_CLASSB_NSHIFT
;
150 if (IN_CLASSC(addr
->s_addr
))
151 return 32 - IN_CLASSC_NSHIFT
;
156 static struct lxc_netdev
*network_netdev(const char *key
, const char *value
,
157 struct lxc_list
*network
)
159 struct lxc_netdev
*netdev
;
161 if (lxc_list_empty(network
)) {
162 ERROR("network is not created for '%s' = '%s' option",
167 netdev
= lxc_list_first_elem(network
);
169 ERROR("no network device defined for '%s' = '%s' option",
177 static int network_ifname(char **valuep
, char *value
)
179 if (strlen(value
) > IFNAMSIZ
) {
180 ERROR("invalid interface name: %s", value
);
184 *valuep
= strdup(value
);
186 ERROR("failed to dup string '%s'", value
);
193 static int config_network_flags(const char *key
, char *value
,
194 struct lxc_conf
*lxc_conf
)
196 struct lxc_netdev
*netdev
;
198 netdev
= network_netdev(key
, value
, &lxc_conf
->network
);
202 netdev
->flags
|= IFF_UP
;
207 static int config_network_link(const char *key
, char *value
,
208 struct lxc_conf
*lxc_conf
)
210 struct lxc_netdev
*netdev
;
212 netdev
= network_netdev(key
, value
, &lxc_conf
->network
);
216 return network_ifname(&netdev
->link
, value
);
219 static int config_network_name(const char *key
, char *value
,
220 struct lxc_conf
*lxc_conf
)
222 struct lxc_netdev
*netdev
;
224 netdev
= network_netdev(key
, value
, &lxc_conf
->network
);
228 return network_ifname(&netdev
->name
, value
);
231 static int config_network_pair(const char *key
, char *value
,
232 struct lxc_conf
*lxc_conf
)
234 struct lxc_netdev
*netdev
;
236 netdev
= network_netdev(key
, value
, &lxc_conf
->network
);
240 return network_ifname(&netdev
->pair
, value
);
243 static int config_network_hwaddr(const char *key
, char *value
,
244 struct lxc_conf
*lxc_conf
)
246 struct lxc_netdev
*netdev
;
248 netdev
= network_netdev(key
, value
, &lxc_conf
->network
);
252 netdev
->hwaddr
= strdup(value
);
253 if (!netdev
->hwaddr
) {
254 SYSERROR("failed to dup string '%s'", value
);
261 static int config_network_vlanid(const char *key
, char *value
,
262 struct lxc_conf
*lxc_conf
)
264 struct lxc_netdev
*netdev
;
266 netdev
= network_netdev(key
, value
, &lxc_conf
->network
);
270 if (get_u16(&netdev
->vlan_attr
.vid
, value
, 0))
276 static int config_network_mtu(const char *key
, char *value
,
277 struct lxc_conf
*lxc_conf
)
279 struct lxc_netdev
*netdev
;
281 netdev
= network_netdev(key
, value
, &lxc_conf
->network
);
285 netdev
->mtu
= strdup(value
);
287 SYSERROR("failed to dup string '%s'", value
);
294 static int config_network_ipv4(const char *key
, char *value
,
295 struct lxc_conf
*lxc_conf
)
297 struct lxc_netdev
*netdev
;
298 struct lxc_inetdev
*inetdev
;
299 struct lxc_list
*list
;
300 char *cursor
, *slash
, *addr
= NULL
, *bcast
= NULL
, *prefix
= NULL
;
302 netdev
= network_netdev(key
, value
, &lxc_conf
->network
);
306 inetdev
= malloc(sizeof(*inetdev
));
308 SYSERROR("failed to allocate ipv4 address");
311 memset(inetdev
, 0, sizeof(*inetdev
));
313 list
= malloc(sizeof(*list
));
315 SYSERROR("failed to allocate memory");
320 list
->elem
= inetdev
;
324 cursor
= strstr(addr
, " ");
330 slash
= strstr(addr
, "/");
337 ERROR("no address specified");
341 if (!inet_pton(AF_INET
, addr
, &inetdev
->addr
)) {
342 SYSERROR("invalid ipv4 address: %s", value
);
347 if (!inet_pton(AF_INET
, bcast
, &inetdev
->bcast
)) {
348 SYSERROR("invalid ipv4 address: %s", value
);
352 /* no prefix specified, determine it from the network class */
353 inetdev
->prefix
= prefix
? atoi(prefix
) :
354 config_ip_prefix(&inetdev
->addr
);
357 lxc_list_add(&netdev
->ipv4
, list
);
362 static int config_network_ipv6(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
364 struct lxc_netdev
*netdev
;
365 struct lxc_inet6dev
*inet6dev
;
366 struct lxc_list
*list
;
370 netdev
= network_netdev(key
, value
, &lxc_conf
->network
);
374 inet6dev
= malloc(sizeof(*inet6dev
));
376 SYSERROR("failed to allocate ipv6 address");
379 memset(inet6dev
, 0, sizeof(*inet6dev
));
381 list
= malloc(sizeof(*list
));
383 SYSERROR("failed to allocate memory");
388 list
->elem
= inet6dev
;
390 inet6dev
->prefix
= 64;
391 slash
= strstr(value
, "/");
395 inet6dev
->prefix
= atoi(netmask
);
398 if (!inet_pton(AF_INET6
, value
, &inet6dev
->addr
)) {
399 SYSERROR("invalid ipv6 address: %s", value
);
403 lxc_list_add(&netdev
->ipv6
, list
);
408 static int config_pts(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
410 int maxpts
= atoi(value
);
412 lxc_conf
->pts
= maxpts
;
417 static int config_tty(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
419 int nbtty
= atoi(value
);
421 lxc_conf
->tty
= nbtty
;
426 static int config_cgroup(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
428 char *token
= "lxc.cgroup.";
430 struct lxc_list
*cglist
;
431 struct lxc_cgroup
*cgelem
;
433 subkey
= strstr(key
, token
);
441 if (strlen(subkey
) == strlen(token
))
444 subkey
+= strlen(token
);
446 cglist
= malloc(sizeof(*cglist
));
450 cgelem
= malloc(sizeof(*cgelem
));
456 cgelem
->subsystem
= strdup(subkey
);
457 cgelem
->value
= strdup(value
);
458 cglist
->elem
= cgelem
;
460 lxc_list_add_tail(&lxc_conf
->cgroup
, cglist
);
465 static int config_fstab(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
467 if (strlen(value
) >= MAXPATHLEN
) {
468 ERROR("%s path is too long", value
);
472 lxc_conf
->fstab
= strdup(value
);
473 if (!lxc_conf
->fstab
) {
474 SYSERROR("failed to duplicate string %s", value
);
481 static int config_mount(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
483 char *fstab_token
= "lxc.mount";
484 char *token
= "lxc.mount.entry";
487 struct lxc_list
*mntlist
;
489 subkey
= strstr(key
, token
);
492 subkey
= strstr(key
, fstab_token
);
497 return config_fstab(key
, value
, lxc_conf
);
503 mntlist
= malloc(sizeof(*mntlist
));
507 mntelem
= strdup(value
);
508 mntlist
->elem
= mntelem
;
510 lxc_list_add_tail(&lxc_conf
->mount_list
, mntlist
);
515 static int config_rootfs(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
517 if (strlen(value
) >= MAXPATHLEN
) {
518 ERROR("%s path is too long", value
);
522 lxc_conf
->rootfs
= strdup(value
);
523 if (!lxc_conf
->rootfs
) {
524 SYSERROR("failed to duplicate string %s", value
);
531 static int config_utsname(const char *key
, char *value
, struct lxc_conf
*lxc_conf
)
533 struct utsname
*utsname
;
535 utsname
= malloc(sizeof(*utsname
));
537 SYSERROR("failed to allocate memory");
541 if (strlen(value
) >= sizeof(utsname
->nodename
)) {
542 ERROR("node name '%s' is too long",
547 strcpy(utsname
->nodename
, value
);
548 lxc_conf
->utsname
= utsname
;
553 static int parse_line(void *buffer
, void *data
)
555 struct config
*config
;
561 if (lxc_is_line_empty(line
))
564 line
+= lxc_char_left_gc(line
, strlen(line
));
568 dot
= strstr(line
, "=");
570 ERROR("invalid configuration line: %s", line
);
578 key
[lxc_char_right_gc(key
, strlen(key
))] = '\0';
580 value
+= lxc_char_left_gc(value
, strlen(value
));
581 value
[lxc_char_right_gc(value
, strlen(value
))] = '\0';
583 config
= getconfig(key
);
585 ERROR("unknow key %s", key
);
589 return config
->cb(key
, value
, data
);
592 int lxc_config_read(const char *file
, struct lxc_conf
*conf
)
594 char buffer
[MAXPATHLEN
];
596 return lxc_file_for_each_line(file
, parse_line
, buffer
,
597 sizeof(buffer
), conf
);