diff --git a/src/liblxc/Makefile.am b/src/liblxc/Makefile.am index 46eb76e78..eeebd0864 100644 --- a/src/liblxc/Makefile.am +++ b/src/liblxc/Makefile.am @@ -1,5 +1,15 @@ lib_LIBRARIES = liblxc.a -pkginclude_HEADERS = lxc.h +pkginclude_HEADERS = \ + lxc.h \ + lxc_cgroup.h \ + lxc_conf.h \ + lxc_list.h \ + lxc_lock.h \ + lxc_log.h \ + lxc_namespace.h \ + lxc_state.h \ + lxc_utils.h + liblxc_a_SOURCES = \ create.c \ destroy.c \ @@ -8,19 +18,19 @@ liblxc_a_SOURCES = \ execute.c \ monitor.c \ kill.c \ - state.c \ freezer.c \ - cgroup.c cgroup.h \ + lxc_state.c lxc_state.h \ + lxc_cgroup.c lxc_cgroup.h \ lxc.h \ - utils.h \ - lock.c lock.h \ - namespace.h \ - network.c network.h \ - conf.c conf.h \ - list.h \ - state.c state.h \ - log.c log.h \ + lxc_utils.h \ + lxc_lock.c lxc_lock.h \ + lxc_namespace.h \ + lxc_conf.c lxc_conf.h \ + lxc_list.h \ + lxc_state.c lxc_state.h \ + lxc_log.c lxc_log.h \ \ + network.c network.h \ nl.c nl.h \ rtnl.c rtnl.h \ genl.c genl.h diff --git a/src/liblxc/create.c b/src/liblxc/create.c index 4c764c913..dc3b05faa 100644 --- a/src/liblxc/create.c +++ b/src/liblxc/create.c @@ -35,11 +35,6 @@ #include #include -#include -#include -#include -#include -#include static int dir_filter(const struct dirent *dirent) { diff --git a/src/liblxc/destroy.c b/src/liblxc/destroy.c index f8b4fc233..fb08da29b 100644 --- a/src/liblxc/destroy.c +++ b/src/liblxc/destroy.c @@ -37,11 +37,6 @@ #include #include -#include -#include -#include -#include -#include static int dir_filter(const struct dirent *dirent) { diff --git a/src/liblxc/execute.c b/src/liblxc/execute.c index 79008ed6e..207ad3005 100644 --- a/src/liblxc/execute.c +++ b/src/liblxc/execute.c @@ -39,15 +39,7 @@ #include #include -#include -#include -#include #include -#include -#include -#include -#include -#include LXC_TTY_HANDLER(SIGINT); LXC_TTY_HANDLER(SIGQUIT); diff --git a/src/liblxc/freezer.c b/src/liblxc/freezer.c index d941a4580..38332bdf6 100644 --- a/src/liblxc/freezer.c +++ b/src/liblxc/freezer.c @@ -36,8 +36,6 @@ #include #include -#include -#include static int freeze_unfreeze(const char *name, int freeze) { diff --git a/src/liblxc/kill.c b/src/liblxc/kill.c index 132b099e9..7af7f34f5 100644 --- a/src/liblxc/kill.c +++ b/src/liblxc/kill.c @@ -36,10 +36,6 @@ #include #include -#include -#include -#include -#include int lxc_kill(const char *name, int signum) { diff --git a/src/liblxc/lxc.h b/src/liblxc/lxc.h index 44709d30e..378da8d38 100644 --- a/src/liblxc/lxc.h +++ b/src/liblxc/lxc.h @@ -29,17 +29,21 @@ liblxc/lxc.h will contain exports of liblxc **/ +#include +#include +#include +#include +#include +#include +#include +#include + #define LXCPATH "/var/lxc" #define MAXPIDLEN 20 struct lxc_mem_stat; struct lxc_conf; -typedef enum { - STOPPED, STARTING, RUNNING, STOPPING, - ABORTING, FREEZING, FROZEN, MAX_STATE, -} lxc_state_t; - typedef int (*lxc_callback_t)(const char *name, int argc, char *argv[], void *data); diff --git a/src/liblxc/lxc_cgroup.c b/src/liblxc/lxc_cgroup.c new file mode 100644 index 000000000..bcc68a5dc --- /dev/null +++ b/src/liblxc/lxc_cgroup.c @@ -0,0 +1,188 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAXPRIOLEN 24 +#define MTAB "/etc/mtab" + +static int get_cgroup_mount(const char *mtab, char *mnt) +{ + struct mntent *mntent; + FILE *file = NULL; + int err = -1; + + file = setmntent(mtab, "r"); + if (!file) { + lxc_log_syserror("failed to open %s", mtab); + goto out; + } + + while ((mntent = getmntent(file))) { + if (strcmp(mntent->mnt_fsname, "cgroup")) + continue; + strcpy(mnt, mntent->mnt_dir); + err = 0; + break; + }; + + fclose(file); +out: + return err; +} + +int lxc_link_nsgroup(const char *name, pid_t pid) +{ + char *lxc, *nsgroup, cgroup[MAXPATHLEN]; + int ret; + + if (get_cgroup_mount(MTAB, cgroup)) { + lxc_log_info("cgroup is not mounted"); + return -1; + } + + asprintf(&lxc, LXCPATH "/%s/nsgroup", name); + asprintf(&nsgroup, "%s/%d", cgroup, pid); + + unlink(lxc); + ret = symlink(nsgroup, lxc); + if (ret) + lxc_log_syserror("failed to create symlink %s->%s", + nsgroup, lxc); + free(lxc); + free(nsgroup); + return ret; +} + +int lxc_unlink_nsgroup(const char *name) +{ + char *nsgroup; + int ret; + + asprintf(&nsgroup, LXCPATH "/%s/nsgroup", name); + ret = unlink(nsgroup); + free(nsgroup); + + return ret; +} + +int lxc_set_priority(const char *name, int priority) +{ + int fd; + char *path = NULL, *prio = NULL; + + asprintf(&path, LXCPATH "/%s/nsgroup/cpu.shares", name); + + fd = open(path, O_WRONLY); + if (fd < 0) { + lxc_log_syserror("failed to open '%s'", path); + goto out; + } + + asprintf(&prio, "%d", priority); + + if (write(fd, prio, strlen(prio) + 1) < 0) { + lxc_log_syserror("failed to write to '%s'", path); + close(fd); + goto out; + } + + close(fd); +out: + free(path); + free(prio); + return 0; +} + +int lxc_get_priority(const char *name, int *priority) +{ + int fd, ret = -1; + char *path, prio[MAXPRIOLEN]; + + asprintf(&path, LXCPATH "/%s/nsgroup/cpu.shares", name); + + fd = open(path, O_RDONLY); + if (fd < 0) { + lxc_log_syserror("failed to open '%s'", path); + goto out; + } + + if (read(fd, prio, MAXPRIOLEN) < 0) { + lxc_log_syserror("failed to read from '%s'", path); + close(fd); + goto out; + } + + close(fd); + *priority = atoi(prio); + + ret = 0; +out: + free(path); + return 0; +} + +int lxc_set_memory(const char *name, size_t memmax) +{ + return 0; +} + +int lxc_get_memory(const char *name, size_t *memmax) +{ + return 0; +} + +int lxc_get_memstat(const char *name, struct lxc_mem_stat *memstat) +{ + return 0; +} + +int lxc_set_cpuset(const char *name, long *cpumask, int len, int shared) +{ + return 0; +} + +int lxc_get_cpuset(const char *name, long *cpumask, int len, int *shared) +{ + return 0; +} + +int lxc_get_cpu_usage(const char *name, long long *usage) +{ + return 0; +} diff --git a/src/liblxc/lxc_cgroup.h b/src/liblxc/lxc_cgroup.h new file mode 100644 index 000000000..8060cdf43 --- /dev/null +++ b/src/liblxc/lxc_cgroup.h @@ -0,0 +1,30 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _cgroup_h +#define _cgroup_h + +int lxc_get_cgroup_mount(const char *mtab, char *mnt); +int lxc_link_nsgroup(const char *name, pid_t pid); +int lxc_unlink_nsgroup(const char *name); + +#endif diff --git a/src/liblxc/lxc_conf.c b/src/liblxc/lxc_conf.c new file mode 100644 index 000000000..8c06278ec --- /dev/null +++ b/src/liblxc/lxc_conf.c @@ -0,0 +1,1205 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define MAXHWLEN 18 +#define MAXINDEXLEN 20 +#define MAXLINELEN 128 + +typedef int (*instanciate_cb)(const char *dirname, + const char *file, pid_t pid); + +typedef int (*dir_cb)(const char *name, const char *dirname, + const char *file, void *data); + +typedef int (*file_cb)(void* buffer, void *data); + +struct netdev_conf { + const char *type; + instanciate_cb cb; + int count; +}; + +static int instanciate_veth(const char *, const char *, pid_t); +static int instanciate_macvlan(const char *, const char *, pid_t); +static int instanciate_phys(const char *, const char *, pid_t); + +static struct netdev_conf netdev_conf[] = { + { "veth", instanciate_veth, 0 }, + { "macvlan", instanciate_macvlan, 0, }, + { "phys", instanciate_phys, 0, }, +}; + +static int dir_filter(const struct dirent *dirent) +{ + if (!strcmp(dirent->d_name, ".") || + !strcmp(dirent->d_name, "..")) + return 0; + return 1; +} + +static int dir_for_each(const char *name, const char *dirname, + dir_cb callback, void *data) +{ + struct dirent **namelist; + int n; + + n = scandir(dirname, &namelist, dir_filter, alphasort); + if (n < 0) { + lxc_log_syserror("failed to scan %s directory", dirname); + return -1; + } + + while (n--) { + if (callback(name, dirname, namelist[n]->d_name, data)) { + lxc_log_error("callback failed"); + free(namelist[n]); + return -1; + } + free(namelist[n]); + } + + return 0; +} + +static int file_for_each_line(const char *file, file_cb callback, + void *buffer, size_t len, void* data) +{ + FILE *f; + int err = -1; + + f = fopen(file, "r"); + if (!f) { + lxc_log_syserror("failed to open %s", file); + return -1; + } + + while (fgets(buffer, len, f)) + if (callback(buffer, data)) + goto out; + err = 0; +out: + fclose(f); + return err; +} + +static int write_info(const char *path, const char *file, const char *info) +{ + int fd, err = -1; + char *f; + + asprintf(&f, "%s/%s", path, file); + fd = creat(f, 0755); + if (fd < 0) + goto out; + + if (write(fd, info, strlen(info)) < 0 || + write(fd, "\n", strlen("\n") + 1) < 0) + goto out_write; + err = 0; +out: + close(fd); + free(f); + return err; + +out_write: + unlink(f); + goto out; +} + +static int read_info(const char *path, const char *file, char *info, size_t len) +{ + int fd, ret = -1; + char *f, *token; + + asprintf(&f, "%s/%s", path, file); + fd = open(f, O_RDONLY); + if (fd < 0) { + if (errno == ENOENT) + ret = 1; + goto out; + } + + ret = read(fd, info, len); + if (ret < 0) + goto out; + + token = strstr(info, "\n"); + if (token) + *token = '\0'; + ret = 0; +out: + close(fd); + free(f); + return ret; +} + +static int delete_info(const char *path, const char *file) +{ + char *info; + int ret; + + asprintf(&info, "%s/%s", path, file); + ret = unlink(info); + free(info); + + return ret; +} + +static int configure_ip4addr(int fd, struct lxc_inetdev *in) +{ + char addr[INET6_ADDRSTRLEN]; + char bcast[INET_ADDRSTRLEN]; + char *line = NULL; + int err = -1; + + if (!inet_ntop(AF_INET, &in->addr, addr, sizeof(addr))) { + lxc_log_syserror("failed to convert ipv4 address"); + goto err; + } + + if (!inet_ntop(AF_INET, &in->bcast, bcast, sizeof(bcast))) { + lxc_log_syserror("failed to convert ipv4 broadcast"); + goto err; + } + + if (in->prefix) + asprintf(&line, "%s/%d %s\n", addr, in->prefix, bcast); + else + asprintf(&line, "%s %s\n", addr, bcast); + + if (write(fd, line, strlen(line)) < 0) { + lxc_log_syserror("failed to write address info"); + goto err; + } + + err = 0; +err: + free(line); + return err; +} + +static int configure_ip6addr(int fd, struct lxc_inet6dev *in6) +{ + char addr[INET6_ADDRSTRLEN]; + char *line = NULL; + int err = -1; + + if (!inet_ntop(AF_INET6, &in6->addr, addr, sizeof(addr))) { + lxc_log_syserror("failed to convert ipv4 address"); + goto err; + } + + asprintf(&line, "%s/%d\n", addr, in6->prefix?in6->prefix:64); + + if (write(fd, line, strlen(line)) < 0) { + lxc_log_syserror("failed to write address info"); + goto err; + } + + err = 0; +err: + free(line); + return err; +} + +static int configure_ip_address(const char *path, struct lxc_list *ip, int family) +{ + char file[MAXPATHLEN]; + struct lxc_list *iterator; + int fd, err = -1; + + if (mkdir(path, 0755)) { + lxc_log_syserror("failed to create directory %s", path); + return -1; + } + + snprintf(file, MAXPATHLEN, "%s/addresses", path); + fd = creat(file, 0755); + if (fd < 0) { + lxc_log_syserror("failed to create %s file", file); + goto err; + } + + lxc_list_for_each(iterator, ip) { + err = family == AF_INET? + configure_ip4addr(fd, iterator->elem): + configure_ip6addr(fd, iterator->elem); + if (err) + goto err; + } +out: + close(fd); + return err; +err: + unlink(file); + rmdir(path); + goto out; +} + +static int configure_netdev(const char *path, struct lxc_netdev *netdev) +{ + int err = -1; + char dir[MAXPATHLEN]; + + if (mkdir(path, 0755)) { + lxc_log_syserror("failed to create %s directory", path); + return -1; + } + + if (netdev->ifname) { + if (write_info(path, "link", netdev->ifname)) + goto out_link; + } + + if (netdev->newname) { + if (write_info(path, "name", netdev->newname)) + goto out_newname; + } + + if (netdev->hwaddr) { + if (write_info(path, "hwaddr", netdev->hwaddr)) + goto out_up; + } + + if (netdev->flags & IFF_UP) { + if (write_info(path, "up", "")) + goto out_hwaddr; + } + + if (!lxc_list_empty(&netdev->ipv4)) { + snprintf(dir, MAXPATHLEN, "%s/ipv4", path); + if (configure_ip_address(dir, &netdev->ipv4, AF_INET)) + goto out_ipv4; + } + + if (!lxc_list_empty(&netdev->ipv6)) { + snprintf(dir, MAXPATHLEN, "%s/ipv6", path); + if (configure_ip_address(dir, &netdev->ipv6, AF_INET6)) + goto out_ipv6; + } + err = 0; +out: + return err; +out_ipv6: + delete_info(path, "ipv4"); +out_ipv4: + delete_info(path, "up"); +out_hwaddr: + delete_info(path, "hwaddr"); +out_up: + delete_info(path, "name"); +out_newname: + delete_info(path, "link"); +out_link: + rmdir(path); + goto out; +} + +static int configure_utsname(const char *name, struct utsname *utsname) +{ + char path[MAXPATHLEN]; + + snprintf(path, MAXPATHLEN, LXCPATH "/%s", name); + + if (write_info(path, "utsname", utsname->nodename)) { + lxc_log_error("failed to write the utsname info"); + return -1; + } + + return 0; +} + +static int configure_network(const char *name, struct lxc_list *network) +{ + struct lxc_list *iterator; + struct lxc_network *n; + char networkpath[MAXPATHLEN]; + char path[MAXPATHLEN]; + int err = -1; + + if (lxc_list_empty(network)) + return 0; + + snprintf(networkpath, MAXPATHLEN, LXCPATH "/%s/network", name); + if (mkdir(networkpath, 0755)) { + lxc_log_syserror("failed to create %s directory", networkpath); + goto out; + } + + lxc_list_for_each(iterator, network) { + + n = iterator->elem; + + if (n->type < 0 || n->type > MAXCONFTYPE) { + lxc_log_error("invalid network configuration type %d", + n->type); + goto out; + } + + snprintf(path, MAXPATHLEN, "%s/%s%d", networkpath, + netdev_conf[n->type].type, + netdev_conf[n->type].count++); + + if (configure_netdev(path, lxc_list_first_elem(&n->netdev))) { + lxc_log_error("failed to configure network type %s", + netdev_conf[n->type].type); + goto out; + } + } + + err = 0; +out: + return err; +} + +static int configure_cgroup(const char *name, struct lxc_cgroup *cgroup) +{ + return 0; +} + +static int configure_chroot(const char *name, const char *chroot) +{ + char path[MAXPATHLEN]; + + snprintf(path, MAXPATHLEN, LXCPATH "/%s/chroot", name); + + return symlink(chroot, path); + +} + +static int configure_mount(const char *name, const char *fstab) +{ + char *path; + struct stat stat; + int infd, outfd; + void *src, *dst; + char c = '\0'; + int ret = -1; + + asprintf(&path, LXCPATH "/%s/fstab", name); + + outfd = open(path, O_RDWR|O_CREAT|O_EXCL, 0640); + if (outfd < 0) { + lxc_log_syserror("failed to creat '%s'", path); + goto out; + } + + infd = open(fstab, O_RDONLY); + if (infd < 0) { + lxc_log_syserror("failed to open '%s'", fstab); + goto out; + } + + if (fstat(infd, &stat)) { + lxc_log_syserror("failed to stat '%s'", fstab); + goto out; + } + + if (lseek(outfd, stat.st_size - 1, SEEK_SET) < 0) { + lxc_log_syserror("failed to seek dest file '%s'", path); + goto out; + } + + /* fixup length */ + if (write(outfd, &c, 1) < 0) { + lxc_log_syserror("failed to write to '%s'", path); + goto out; + } + + src = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, infd, 0L); + if (src == MAP_FAILED) { + lxc_log_syserror("failed to mmap '%s'", fstab); + goto out; + } + + dst = mmap(NULL, stat.st_size, PROT_WRITE, MAP_SHARED, outfd, 0L); + if (dst == MAP_FAILED) { + lxc_log_syserror("failed to mmap '%s'", path); + goto out; + } + + memcpy(dst, src, stat.st_size); + + munmap(src, stat.st_size); + munmap(dst, stat.st_size); + + ret = 0; +out: + free(path); + return ret; +} + +static int unconfigure_ip_addresses(const char *dirname) +{ + char path[MAXPATHLEN]; + + snprintf(path, MAXPATHLEN, "%s/ipv4", dirname); + delete_info(path, "addresses"); + rmdir(path); + + snprintf(path, MAXPATHLEN, "%s/ipv6", dirname); + delete_info(path, "addresses"); + rmdir(path); + + return 0; +} + +static int unconfigure_network_cb(const char *name, const char *dirname, + const char *file, void *data) +{ + char path[MAXPATHLEN]; + + snprintf(path, MAXPATHLEN, "%s/%s", dirname, file); + delete_info(path, "name"); + delete_info(path, "addr"); + delete_info(path, "link"); + delete_info(path, "hwaddr"); + delete_info(path, "up"); + unconfigure_ip_addresses(path); + rmdir(path); + + return 0; +} + +static int unconfigure_network(const char *name) +{ + char dirname[MAXPATHLEN]; + + snprintf(dirname, MAXPATHLEN, LXCPATH "/%s/network", name); + dir_for_each(name, dirname, unconfigure_network_cb, NULL); + rmdir(dirname); + + return 0; +} + +static int unconfigure_cgroup(const char *name) +{ + return 0; +} + +static int unconfigure_chroot(const char *name) +{ + char path[MAXPATHLEN]; + + snprintf(path, MAXPATHLEN, LXCPATH "/%s", name); + delete_info(path, "chroot"); + + return 0; +} + +static int unconfigure_mount(const char *name) +{ + char path[MAXPATHLEN]; + + snprintf(path, MAXPATHLEN, LXCPATH "/%s", name); + delete_info(path, "fstab"); + + return 0; +} + +static int unconfigure_utsname(const char *name) +{ + char path[MAXPATHLEN]; + + snprintf(path, MAXPATHLEN, LXCPATH "/%s", name); + delete_info(path, "utsname"); + + return 0; +} + +static int setup_utsname(const char *name) +{ + int ret; + char path[MAXPATHLEN]; + struct utsname utsname; + + snprintf(path, MAXPATHLEN, LXCPATH "/%s", name); + + ret = read_info(path, "utsname", utsname.nodename, + sizeof(utsname.nodename)); + if (ret < 0) { + lxc_log_syserror("failed to read utsname info"); + return -1; + } + + if (!ret && sethostname(utsname.nodename, strlen(utsname.nodename))) { + lxc_log_syserror("failed to set the hostname to '%s'", + utsname.nodename); + return -1; + } + + return 0; +} + +static int setup_chroot(const char *name) +{ + char path[MAXPATHLEN], chrt[MAXPATHLEN]; + + snprintf(path, MAXPATHLEN, LXCPATH "/%s/chroot", name); + + if (readlink(path, chrt, MAXPATHLEN) > 0) { + + if (chroot(chrt)) { + lxc_log_syserror("failed to set chroot %s", path); + return -1; + } + + if (chdir(getenv("HOME")) && chdir("/")) { + lxc_log_syserror("failed to change to home directory"); + return -1; + } + } + + return 0; +} + +static int setup_mount(const char *name) +{ + char path[MAXPATHLEN]; + struct mntent *mntent; + FILE *file; + int ret = -1; + + snprintf(path, MAXPATHLEN, LXCPATH "/%s/fstab", name); + + file = setmntent(path, "r"); + if (!file) { + if (errno == ENOENT) + return 0; + lxc_log_syserror("failed to open '%s'", path); + goto out; + } + + while((mntent = getmntent(file))) { + if (mount(mntent->mnt_fsname, mntent->mnt_dir, + mntent->mnt_type, 0, NULL)) { + lxc_log_syserror("failed to mount '%s' on '%s'", + mntent->mnt_fsname, mntent->mnt_dir); + goto out; + } + } + ret = 0; +out: + endmntent(file); + return ret; +} + +static int setup_ipv4_addr_cb(void *buffer, void *data) +{ + char *ifname = data; + char *cursor, *slash, *addr, *bcast = NULL, *prefix = NULL; + int p = 24; + + addr = buffer; + cursor = strstr(addr, " "); + if (cursor) { + *cursor = '\0'; + bcast = cursor + 1; + cursor = strstr(bcast, "\n"); + if (cursor) + *cursor = '\0'; + } + + slash = strstr(addr, "/"); + if (slash) { + *slash = '\0'; + prefix = slash + 1; + } + + if (prefix) + p = atoi(prefix); + + if (ip_addr_add(ifname, addr, p, bcast)) { + lxc_log_error("failed to set %s to addr %s/%d %s", ifname, + addr, p, bcast?bcast:""); + return -1; + } + + return 0; +} + +static int setup_ipv6_addr_cb(void *buffer, void *data) +{ + char *ifname = data; + char *cursor, *slash, *addr, *bcast = NULL, *prefix = NULL; + int p = 24; + + addr = buffer; + cursor = strstr(addr, " "); + if (cursor) { + *cursor = '\0'; + bcast = cursor + 1; + cursor = strstr(bcast, "\n"); + if (cursor) + *cursor = '\0'; + } + + slash = strstr(addr, "/"); + if (slash) { + *slash = '\0'; + prefix = slash + 1; + } + + if (prefix) + p = atoi(prefix); + + if (ip6_addr_add(ifname, addr, p, bcast)) { + lxc_log_error("failed to set %s to addr %s/%d %s", ifname, + addr, p, bcast?bcast:""); + return -1; + } + + return 0; +} + +static int setup_hw_addr(char *hwaddr, const char *ifname) +{ + struct sockaddr sockaddr; + struct ifreq ifr; + int ret, fd; + + if (lxc_convert_mac(hwaddr, &sockaddr)) { + fprintf(stderr, "conversion has failed\n"); + return -1; + } + + memcpy(ifr.ifr_name, ifname, IFNAMSIZ); + memcpy((char *) &ifr.ifr_hwaddr, (char *) &sockaddr, sizeof(sockaddr)); + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + perror("socket"); + return -1; + } + + ret = ioctl(fd, SIOCSIFHWADDR, &ifr); + close(fd); + if (ret) + perror("ioctl"); + + return ret; +} + +static int setup_ip_addr(const char *dirname, const char *ifname) +{ + char path[MAXPATHLEN], line[MAXLINELEN]; + struct stat s; + int ret = 0; + + snprintf(path, MAXPATHLEN, "%s/ipv4/addresses", dirname); + if (!stat(path, &s)) + ret = file_for_each_line(path, setup_ipv4_addr_cb, + line, MAXPATHLEN, (void*)ifname); + return ret; +} + +static int setup_ip6_addr(const char *dirname, const char *ifname) +{ + char path[MAXPATHLEN], line[MAXLINELEN]; + struct stat s; + int ret = 0; + + snprintf(path, MAXLINELEN, "%s/ipv6/addresses", dirname); + if (!stat(path, &s)) + ret = file_for_each_line(path, setup_ipv6_addr_cb, + line, MAXPATHLEN, (void*)ifname); + return ret; +} + +static int setup_network_cb(const char *name, const char *dirname, + const char *file, void *data) +{ + char path[MAXPATHLEN]; + char strindex[MAXINDEXLEN]; + char ifname[IFNAMSIZ]; + char newname[IFNAMSIZ]; + char hwaddr[MAXHWLEN]; + char *current_ifname = ifname; + int ifindex, ret = -1; + + snprintf(path, MAXPATHLEN, "%s/%s", dirname, file); + + if (read_info(path, "ifindex", strindex, sizeof(strindex))) { + lxc_log_error("failed to read ifindex info"); + goto out; + } + + ifindex = atoi(strindex); + if (!ifindex) { + lxc_log_error("bad index %s", strindex); + goto out; + } + + if (!if_indextoname(ifindex, current_ifname)) { + lxc_log_error("no interface corresponding to index '%d'", + ifindex); + goto out; + } + + if (!read_info(path, "name", newname, sizeof(newname))) { + if (device_rename(ifname, newname)) { + lxc_log_error("failed to rename %s->%s", + ifname, newname); + goto out; + } + current_ifname = newname; + } + + if (!read_info(path, "hwaddr", hwaddr, sizeof(hwaddr))) { + if (setup_hw_addr(hwaddr, current_ifname)) { + lxc_log_error("failed to setup hw address for '%s'", + current_ifname); + goto out; + } + } + + if (setup_ip_addr(path, current_ifname)) { + lxc_log_error("failed to setup ip addresses for '%s'", + ifname); + goto out; + } + + if (setup_ip6_addr(path, current_ifname)) { + lxc_log_error("failed to setup ipv6 addresses for '%s'", + ifname); + goto out; + } + + if (!read_info(path, "up", strindex, sizeof(strindex))) { + if (device_up(current_ifname)) { + lxc_log_error("failed to set '%s' up", current_ifname); + goto out; + } + + /* the network is up, make the loopback up too */ + if (device_up("lo")) { + lxc_log_error("failed to set the loopback up"); + goto out; + } + } + + ret = 0; +out: + return ret; +} + +static int setup_network(const char *name) +{ + char dirname[MAXPATHLEN]; + + snprintf(dirname, MAXPATHLEN, LXCPATH "/%s/network", name); + return dir_for_each(name, dirname, setup_network_cb, NULL); +} + +int conf_has(const char *name, const char *info) +{ + int ret; + char path[MAXPATHLEN]; + struct stat st; + + snprintf(path, MAXPATHLEN, LXCPATH "/%s/%s", name, info); + + ret = stat(path, &st); + if (!ret) { + ret = 1; + goto out; + } + + if (errno == ENOENT) { + ret = 0; + goto out; + } + + lxc_log_syserror("failed to stat %s info", info); +out: + return ret; +} + +int lxc_configure(const char *name, struct lxc_conf *conf) +{ + if (!conf) + return 0; + + if (conf->utsname && configure_utsname(name, conf->utsname)) { + lxc_log_error("failed to configure the utsname"); + return -1; + } + + if (configure_network(name, &conf->networks)) { + lxc_log_error("failed to configure the network"); + return -1; + } + + if (conf->cgroup && configure_cgroup(name, conf->cgroup)) { + lxc_log_error("failed to configure the control group"); + return -1; + } + + if (conf->chroot && configure_chroot(name, conf->chroot)) { + lxc_log_error("failed to configure the chroot"); + return -1; + } + + if (conf->fstab && configure_mount(name, conf->fstab)) { + lxc_log_error("failed to configure the mount points"); + return -1; + } + + return 0; +} + +int lxc_unconfigure(const char *name) +{ + if (conf_has_utsname(name) && unconfigure_utsname(name)) + lxc_log_error("failed to cleanup utsname"); + + if (conf_has_network(name) && unconfigure_network(name)) + lxc_log_error("failed to cleanup the network"); + + if (unconfigure_cgroup(name)) + lxc_log_error("failed to cleanup cgroup"); + + if (conf_has_chroot(name) && unconfigure_chroot(name)) + lxc_log_error("failed to cleanup chroot"); + + if (conf_has_fstab(name) && unconfigure_mount(name)) + lxc_log_error("failed to cleanup mount"); + + return 0; +} + +static int instanciate_veth(const char *dirname, const char *file, pid_t pid) +{ + char *path = NULL, *strindex = NULL, *veth1 = NULL, *veth2 = NULL; + char bridge[IFNAMSIZ]; + int ifindex, ret = -1; + + asprintf(&veth1, "%s_%d", file, pid); + asprintf(&veth2, "%s~%d", file, pid); + asprintf(&path, "%s/%s", dirname, file); + + if (read_info(path, "link", bridge, IFNAMSIZ)) { + lxc_log_error("failed to read bridge info"); + goto out; + } + + if (lxc_configure_veth(veth1, veth2, bridge)) { + lxc_log_error("failed to create %s-%s/%s", veth1, veth2, bridge); + goto out; + } + + ifindex = if_nametoindex(veth2); + if (!ifindex) { + lxc_log_error("failed to retrieve the index for %s", veth2); + goto out; + } + + asprintf(&strindex, "%d", ifindex); + if (write_info(path, "ifindex", strindex)) { + lxc_log_error("failed to write interface index to %s", path); + goto out; + } + + if (!read_info(path, "up", strindex, sizeof(strindex))) { + if (device_up(veth1)) { + lxc_log_error("failed to set %s up", veth1); + goto out; + } + } + + ret = 0; +out: + free(path); + free(strindex); + free(veth1); + free(veth2); + return ret; +} +static int instanciate_macvlan(const char *dirname, const char *file, pid_t pid) +{ + char *path = NULL, *strindex = NULL, *peer = NULL; + char link[IFNAMSIZ]; + int ifindex, ret = -1; + + asprintf(&peer, "%s~%d", file, pid); + asprintf(&path, "%s/%s", dirname, file); + if (read_info(path, "link", link, IFNAMSIZ)) { + lxc_log_error("failed to read bridge info"); + goto out; + } + + if (lxc_configure_macvlan(link, peer)) { + lxc_log_error("failed to create macvlan interface %s", peer); + goto out; + } + + ifindex = if_nametoindex(peer); + if (!ifindex) { + lxc_log_error("failed to retrieve the index for %s", peer); + goto out; + } + + asprintf(&strindex, "%d", ifindex); + if (write_info(path, "ifindex", strindex)) { + lxc_log_error("failed to write interface index to %s", path); + goto out; + } + + ret = 0; +out: + free(path); + free(strindex); + free(peer); + return ret; +} + +static int instanciate_phys(const char *dirname, const char *file, pid_t pid) +{ + char *path = NULL, *strindex = NULL; + char link[IFNAMSIZ]; + int ifindex, ret = -1; + + asprintf(&path, "%s/%s", dirname, file); + if (read_info(path, "link", link, IFNAMSIZ)) { + lxc_log_error("failed to read link info"); + goto out; + } + + ifindex = if_nametoindex(link); + if (!ifindex) { + lxc_log_error("failed to retrieve the index for %s", link); + goto out; + } + + asprintf(&strindex, "%d", ifindex); + if (write_info(path, "ifindex", strindex)) { + lxc_log_error("failed to write interface index to %s", path); + goto out; + } + + ret = 0; +out: + free(path); + free(strindex); + return ret; +} + +static int instanciate_netdev_cb(const char *name, const char *dirname, + const char *file, void *data) +{ + pid_t *pid = data; + + if (!strncmp("veth", file, strlen("veth"))) + return instanciate_veth(dirname, file, *pid); + else if (!strncmp("macvlan", file, strlen("macvlan"))) + return instanciate_macvlan(dirname, file, *pid); + else if (!strncmp("phys", file, strlen("phys"))) + return instanciate_phys(dirname, file, *pid); + + return -1; +} + +static int instanciate_netdev(const char *name, pid_t pid) +{ + char *dirname; + int ret; + + asprintf(&dirname, LXCPATH "/%s/network", name); + ret = dir_for_each(name, dirname, instanciate_netdev_cb, &pid); + free(dirname); + + return ret; +} + +static int move_netdev_cb(const char *name, const char *dirname, + const char *file, void *data) +{ + char *path, ifname[IFNAMSIZ], strindex[MAXINDEXLEN]; + pid_t *pid = data; + int ifindex, ret = -1; + + asprintf(&path, "%s/%s", dirname, file); + if (read_info(path, "ifindex", strindex, MAXINDEXLEN) < 0) { + lxc_log_error("failed to read index to from %s", path); + goto out; + } + + ifindex = atoi(strindex); + if (!if_indextoname(ifindex, ifname)) { + lxc_log_error("interface with index %d does not exist", + ifindex); + goto out; + } + + if (device_move(ifname, *pid)) { + lxc_log_error("failed to move %s to %d", ifname, *pid); + goto out; + } + + ret = 0; +out: + free(path); + return ret; +} + +static int move_netdev(const char *name, pid_t pid) +{ + char *dirname; + int ret; + + asprintf(&dirname, LXCPATH "/%s/network", name); + ret = dir_for_each(name, dirname, move_netdev_cb, &pid); + free(dirname); + + return ret; +} + +int conf_create_network(const char *name, pid_t pid) +{ + if (instanciate_netdev(name, pid)) { + lxc_log_error("failed to instantiate the network devices"); + return -1; + } + + if (move_netdev(name, pid)) { + lxc_log_error("failed to move the netdev to the container"); + return -1; + } + + return 0; +} + +static int delete_netdev_cb(const char *name, const char *dirname, + const char *file, void *data) +{ + char strindex[MAXINDEXLEN]; + char path[MAXPATHLEN]; + char ifname[IFNAMSIZ]; + int i, ifindex; + + snprintf(path, MAXPATHLEN, "%s/%s", dirname, file); + + if (read_info(path, "ifindex", strindex, MAXINDEXLEN)) { + lxc_log_error("failed to read ifindex info"); + return -1; + } + + ifindex = atoi(strindex); + if (!ifindex) { + lxc_log_error("bad index %s", strindex); + return -1; + } + + /* TODO : temporary code - needs wait on namespace */ + for (i = 0; i < 120; i++) { + if (if_indextoname(ifindex, ifname)) + break; + if (!i) + printf("waiting for interface #%d to come back\n", ifindex); + else + printf("."); fflush(stdout); + sleep(1); + } + + /* do not delete a physical network device */ + if (strncmp("phys", file, strlen("phys"))) + if (device_delete(ifname)) { + lxc_log_error("failed to remove the netdev %s", ifname); + } + + delete_info(path, "ifindex"); + + return 0; +} + +static int delete_netdev(const char *name) +{ + char *dirname; + int ret; + + asprintf(&dirname, LXCPATH "/%s/network", name); + ret = dir_for_each(name, dirname, delete_netdev_cb, NULL); + free(dirname); + + return ret; +} + +int conf_destroy_network(const char *name) +{ + if (delete_netdev(name)) { + lxc_log_error("failed to remove the network devices"); + return -1; + } + + return 0; +} + +int lxc_setup(const char *name) +{ + if (conf_has_utsname(name) && setup_utsname(name)) { + lxc_log_error("failed to setup the utsname for '%s'", name); + return -1; + } + + if (conf_has_network(name) && setup_network(name)) { + lxc_log_error("failed to setup the network for '%s'", name); + return -1; + } + + if (conf_has_fstab(name) && setup_mount(name)) { + lxc_log_error("failed to setup the mount points for '%s'", name); + return -1; + } + + if (conf_has_chroot(name) && setup_chroot(name)) { + lxc_log_error("failed to set chroot for '%s'", name); + return -1; + } + + return 0; +} diff --git a/src/liblxc/lxc_conf.h b/src/liblxc/lxc_conf.h new file mode 100644 index 000000000..ad8b8912f --- /dev/null +++ b/src/liblxc/lxc_conf.h @@ -0,0 +1,146 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _conf_h +#define _conf_h + +#include + +enum { + VETH, + MACVLAN, + PHYS, + MAXCONFTYPE, +}; + +/* + * Defines the structure to configure an ipv4 address + * @address : ipv4 address + * @broadcast : ipv4 broadcast address + * @mask : network mask + */ +struct lxc_inetdev { + struct in_addr addr; + struct in_addr bcast; + int prefix; +}; + +struct lxc_route { + struct in_addr addr; +}; + +/* + * Defines the structure to configure an ipv6 address + * @flags : set the address up + * @address : ipv6 address + * @broadcast : ipv6 broadcast address + * @mask : network mask + */ +struct lxc_inet6dev { + struct in6_addr addr; + struct in6_addr bcast; + struct in6_addr acast; + int prefix; +}; + +struct lxc_route6 { + struct in6_addr addr; +}; +/* + * Defines a structure to configure a network device + * @ifname : network device name + * @flags : flag of the network device (IFF_UP, ... ) + * @ipv4 : a list of ipv4 addresses to be set on the network device + * @ipv6 : a list of ipv6 addresses to be set on the network device + */ +struct lxc_netdev { + int flags; + char *ifname; + char *newname; + char *hwaddr; + struct lxc_list ipv4; + struct lxc_list ipv6; + struct lxc_list route4; + struct lxc_list route6; +}; + +/* + * Defines the kind of the network to use + * @type : the type of the network virtualization + * @phys : phys configuration type + * @veth : veth configuration type + * @macvlan : macvlan configuration type + */ +struct lxc_network { + int type; + struct lxc_list netdev; +}; + +/* + * Defines a structure to configure the control data and path + */ +struct lxc_cgroup { + ; +}; + +/* + * Defines the global container configuration + * @chroot : the root directory to run the container + * @mount : the list of mount points + * @network : the network configuration + * @utsname : the container utsname + */ +struct lxc_conf { + char *chroot; + char *fstab; + struct utsname *utsname; + struct lxc_cgroup *cgroup; + struct lxc_list networks; +}; + +/* + * Configure the external resources for the container + */ +extern int lxc_configure(const char *name, struct lxc_conf *conf); + +/* + * Remove the resources created by the configuration + */ +extern int lxc_unconfigure(const char *name); + +extern int conf_create_network(const char *name, pid_t pid); + +extern int conf_destroy_network(const char *name); + +/* + * Configure the container from inside + */ +extern int lxc_setup(const char *name); + +extern int conf_has(const char *name, const char *info); + +#define conf_has_fstab(__name) conf_has(__name, "fstab") +#define conf_has_chroot(__name) conf_has(__name, "chroot") +#define conf_has_utsname(__name) conf_has(__name, "utsname") +#define conf_has_network(__name) conf_has(__name, "network") + +#endif diff --git a/src/liblxc/lxc_list.c b/src/liblxc/lxc_list.c new file mode 100644 index 000000000..d588ae2e1 --- /dev/null +++ b/src/liblxc/lxc_list.c @@ -0,0 +1,23 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include diff --git a/src/liblxc/lxc_list.h b/src/liblxc/lxc_list.h new file mode 100644 index 000000000..c6727e95b --- /dev/null +++ b/src/liblxc/lxc_list.h @@ -0,0 +1,57 @@ +#ifndef _list_h +#define _list_h + +struct lxc_list { + void *elem; + struct lxc_list *next; + struct lxc_list *prev; +}; + +#define lxc_init_list(l) { .next = l, .prev = l, } + +#define lxc_list_for_each(__iterator, __list) \ + for (__iterator = (__list)->next; \ + __iterator != __list; \ + __iterator = __iterator->next) + +static inline void lxc_list_init(struct lxc_list *list) +{ + list->elem = NULL; + list->next = list->prev = list; +} + +static inline void lxc_list_add_elem(struct lxc_list *list, void *elem) +{ + list->elem = elem; +} + +static inline void *lxc_list_first_elem(struct lxc_list *list) +{ + return list->next->elem; +} + +static inline int lxc_list_empty(struct lxc_list *list) +{ + return list == list->next; +} + +static inline void lxc_list_add(struct lxc_list *list, struct lxc_list *new) +{ + struct lxc_list *next = list->next; + next->prev = new; + new->next = next; + new->prev = list; + list->next = new; +} + +static inline void lxc_list_del(struct lxc_list *list) +{ + struct lxc_list *next, *prev; + + next = list->next; + prev = list->prev; + next->prev = prev; + prev->next = next; +} + +#endif diff --git a/src/liblxc/lxc_lock.c b/src/liblxc/lxc_lock.c new file mode 100644 index 000000000..9f274aabc --- /dev/null +++ b/src/liblxc/lxc_lock.c @@ -0,0 +1,62 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include +#include +#include +#include + +#include + +int lxc_get_lock(const char *name) +{ + char *lock; + int fd, ret; + + asprintf(&lock, LXCPATH "/%s", name); + fd = open(lock, O_RDONLY|O_DIRECTORY, S_IRUSR|S_IWUSR); + if (fd < 0) { + ret = -errno; + goto out; + } + + if (flock(fd, LOCK_EX|LOCK_NB)) { + ret = errno == EWOULDBLOCK ? 0 : -errno; + close(fd); + goto out; + } + + ret = fd; +out: + free(lock); + return ret; +} + +void lxc_put_lock(int lock) +{ + flock(lock, LOCK_UN); + close(lock); +} diff --git a/src/liblxc/lxc_lock.h b/src/liblxc/lxc_lock.h new file mode 100644 index 000000000..ed72b0e5d --- /dev/null +++ b/src/liblxc/lxc_lock.h @@ -0,0 +1,30 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _lock_h +#define _lock_h + +extern int lxc_get_lock(const char *name); + +extern void lxc_put_lock(int lock); + +#endif diff --git a/src/liblxc/lxc_log.c b/src/liblxc/lxc_log.c new file mode 100644 index 000000000..7b962dcef --- /dev/null +++ b/src/liblxc/lxc_log.c @@ -0,0 +1,9 @@ +#include +#include +#include + +#include + +#define MAXTIMELEN 47; +#define ERRNO_FORMAT "%d (%s)" + diff --git a/src/liblxc/lxc_log.h b/src/liblxc/lxc_log.h new file mode 100644 index 000000000..370060f51 --- /dev/null +++ b/src/liblxc/lxc_log.h @@ -0,0 +1,20 @@ +#ifndef _log_h +#define _log_h + +#define lxc_log(format, level, ...) do { \ + fprintf(stderr, "[%s] \t%s:%d - " format "\n", \ + level, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +#define lxc_log_error(format, ...) lxc_log(format, "error", ##__VA_ARGS__); +#define lxc_log_warning(format, ...) lxc_log(format, "warning", ##__VA_ARGS__); +#define lxc_log_info(format, ...) lxc_log(format, "info", ##__VA_ARGS__); +#define lxc_log_debug(format, ...) lxc_log(format, "debug", ##__VA_ARGS__); +#define lxc_log_trace(format, ...) lxc_log(format, "trace", ##__VA_ARGS__); +#define lxc_log_syserror(format, ...) do { \ + fprintf(stderr, "[SYSERROR][%s] \t%s:%d - " format "\n", \ + strerror(errno),__FUNCTION__, __LINE__, \ + ##__VA_ARGS__); \ + } while (0) + +#endif diff --git a/src/liblxc/lxc_namespace.h b/src/liblxc/lxc_namespace.h new file mode 100644 index 000000000..405936864 --- /dev/null +++ b/src/liblxc/lxc_namespace.h @@ -0,0 +1,71 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __namespace_h +#define __namespace_h + +#include +#ifndef CLONE_FS +# define CLONE_FS 0x00000200 +#endif +#ifndef CLONE_NEWNS +# define CLONE_NEWNS 0x00020000 +#endif +#ifndef CLONE_NEWUTS +# define CLONE_NEWUTS 0x04000000 +#endif +#ifndef CLONE_NEWIPC +# define CLONE_NEWIPC 0x08000000 +#endif +#ifndef CLONE_NEWUSER +# define CLONE_NEWUSER 0x10000000 +#endif +#ifndef CLONE_NEWPID +# define CLONE_NEWPID 0x20000000 +#endif +#ifndef CLONE_NEWNET +# define CLONE_NEWNET 0x40000000 +#endif +#ifndef __NR_unshare +# ifdef __i386__ +# define __NR_unshare 310 +# elif __x86_64__ +# define __NR_unshare 272 +# elif __ia64__ +# define __NR_unshare 1296 +# elif __s390__ +# define __NR_unshare 303 +# elif __powerpc__ +# define __NR_unshare 282 +#else +# error "unsupported architecture" +# endif +#endif +#if __i386__ || __x86_64__ || __s390__ || __powerpc__ +# define fork_ns(flags) syscall(SYS_clone, flags|SIGCHLD, NULL); +#elif __ia64__ +# define fork_ns(flags) syscall(SYS_clone2, flags|SIGCHLD, NULL); +#else +# error "unsupported architecture" +#endif +#define unshare_ns(flags) syscall(__NR_unshare, flags, NULL); +#endif diff --git a/src/liblxc/lxc_state.c b/src/liblxc/lxc_state.c new file mode 100644 index 000000000..86e4d9f6b --- /dev/null +++ b/src/liblxc/lxc_state.c @@ -0,0 +1,191 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static char *strstate[] = { + "STOPPED", "STARTING", "RUNNING", "STOPPING", + "ABORTING", "FREEZING", "FROZEN", +}; + +const char *state2str(lxc_state_t state) +{ + if (state < STOPPED || state > MAX_STATE - 1) + return NULL; + return strstate[state]; +} + +lxc_state_t str2state(const char *state) +{ + int i, len; + len = sizeof(strstate)/sizeof(strstate[0]); + for (i = 0; i < len; i++) + if (!strcmp(strstate[i], state)) + return i; + return -1; +} + +int lxc_setstate(const char *name, lxc_state_t state) +{ + int fd, err; + char file[MAXPATHLEN]; + const char *str = state2str(state); + + if (!str) + return -1; + + snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name); + + fd = open(file, O_WRONLY); + if (fd < 0) { + lxc_log_syserror("failed to open %s file", file); + return -1; + } + + if (flock(fd, LOCK_EX)) { + lxc_log_syserror("failed to take the lock to %s", file); + goto out; + } + + if (ftruncate(fd, 0)) { + lxc_log_syserror("failed to truncate the file %s", file); + goto out; + } + + if (write(fd, str, strlen(str)) < 0) { + lxc_log_syserror("failed to write state to %s", file); + goto out; + } + + err = 0; +out: + close(fd); + + /* let the event to be propagated, crappy but that works, + * otherwise the events will be folded into only one event, + * and I want to have them to be one by one in order + * to follow the different states of the container. + */ + usleep(200000); + + return -err; +} + +int mkstate(const char *name) +{ + int fd; + char file[MAXPATHLEN]; + + snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name); + fd = creat(file, S_IRUSR|S_IWUSR); + if (fd < 0) { + lxc_log_syserror("failed to create file %s", file); + return -1; + } + close(fd); + return 0; +} + +int rmstate(const char *name) +{ + char file[MAXPATHLEN]; + snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name); + unlink(file); + return 0; +} + +lxc_state_t lxc_getstate(const char *name) +{ + int fd, err; + char file[MAXPATHLEN]; + + snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name); + + fd = open(file, O_RDONLY); + if (fd < 0) { + lxc_log_syserror("failed to open %s", file); + return -1; + } + + if (flock(fd, LOCK_SH)) { + lxc_log_syserror("failed to take the lock to %s", file); + close(fd); + return -1; + } + + err = read(fd, file, strlen(file)); + if (err < 0) { + lxc_log_syserror("failed to read file %s", file); + close(fd); + return -1; + } + file[err] = '\0'; + + close(fd); + return str2state(file); +} + +static int freezer_state(const char *name) +{ + char freezer[MAXPATHLEN]; + char status[MAXPATHLEN]; + FILE *file; + int err; + + snprintf(freezer, MAXPATHLEN, + LXCPATH "/%s/freezer.freeze", name); + + file = fopen(freezer, "r"); + if (file < 0) { + lxc_log_syserror("failed to open %s", freezer); + return -1; + } + + err = fscanf(file, "%s", status); + fclose(file); + + if (err == EOF) { + lxc_log_syserror("failed to read %s", freezer); + return -1; + } + + return str2state(status); +} + +lxc_state_t lxc_state(const char *name) +{ + int state = freezer_state(name); + if (state != FROZEN && state != FREEZING) + state = lxc_getstate(name); + return state; +} diff --git a/src/liblxc/lxc_state.h b/src/liblxc/lxc_state.h new file mode 100644 index 000000000..27f4f5e02 --- /dev/null +++ b/src/liblxc/lxc_state.h @@ -0,0 +1,38 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _state_h +#define _state_h + +typedef enum { + STOPPED, STARTING, RUNNING, STOPPING, + ABORTING, FREEZING, FROZEN, MAX_STATE, +} lxc_state_t; + +extern const char *state2str(lxc_state_t state); +extern lxc_state_t str2state(const char *state); +extern int mkstate(const char *name); +extern int rmstate(const char *name); +extern int lxc_setstate(const char *name, lxc_state_t state); +extern lxc_state_t lxc_getstate(const char *name); + +#endif diff --git a/src/liblxc/lxc_utils.h b/src/liblxc/lxc_utils.h new file mode 100644 index 000000000..5fc3946fb --- /dev/null +++ b/src/liblxc/lxc_utils.h @@ -0,0 +1,51 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _utils_h +#define _utils_h + +#define LXC_TTY_HANDLER(s) \ + static struct sigaction lxc_tty_sa_##s; \ + static void tty_##s##_handler(int sig, siginfo_t *info, void *ctx) \ + { \ + if (lxc_tty_sa_##s.sa_handler == SIG_DFL || \ + lxc_tty_sa_##s.sa_handler == SIG_IGN) \ + return; \ + (*lxc_tty_sa_##s.sa_sigaction)(sig, info, ctx); \ + } + +#define LXC_TTY_ADD_HANDLER(s) \ + do { \ + struct sigaction sa; \ + sa.sa_sigaction = tty_##s##_handler; \ + sa.sa_flags = SA_SIGINFO; \ + sigfillset(&sa.sa_mask); \ + /* No error expected with sigaction. */ \ + sigaction(s, &sa, &lxc_tty_sa_##s); \ + } while (0) + +#define LXC_TTY_DEL_HANDLER(s) \ + do { \ + sigaction(s, &lxc_tty_sa_##s, NULL); \ + } while (0) + +#endif diff --git a/src/liblxc/monitor.c b/src/liblxc/monitor.c index 0670c1c53..ce5fd19d2 100644 --- a/src/liblxc/monitor.c +++ b/src/liblxc/monitor.c @@ -33,8 +33,6 @@ #include #include -#include -#include int lxc_monitor(const char *name, int output_fd) { diff --git a/src/liblxc/start.c b/src/liblxc/start.c index 19b9b8c11..55526645c 100644 --- a/src/liblxc/start.c +++ b/src/liblxc/start.c @@ -41,15 +41,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include LXC_TTY_HANDLER(SIGINT); LXC_TTY_HANDLER(SIGQUIT); diff --git a/src/liblxc/stop.c b/src/liblxc/stop.c index 74372acd6..7428846ea 100644 --- a/src/liblxc/stop.c +++ b/src/liblxc/stop.c @@ -37,13 +37,10 @@ #include #include -#include -#include -#include int lxc_stop(const char *name) { - char *init; + char init[MAXPATHLEN]; char val[MAXPIDLEN]; int fd, lock, ret = -1; size_t pid; @@ -61,11 +58,11 @@ int lxc_stop(const char *name) return -1; } - asprintf(&init, LXCPATH "/%s/init", name); + snprintf(init, MAXPATHLEN, LXCPATH "/%s/init", name); fd = open(init, O_RDONLY); if (fd < 0) { lxc_log_syserror("failed to open init file for %s", name); - goto out_free; + goto out_unlock; } if (read(fd, val, sizeof(val)) < 0) { @@ -89,7 +86,7 @@ int lxc_stop(const char *name) out_close: close(fd); -out_free: - free(init); +out_unlock: + lxc_put_lock(lock); return ret; } diff --git a/src/lxc/config.c b/src/lxc/config.c index 16c53f4f3..45ec69637 100644 --- a/src/lxc/config.c +++ b/src/lxc/config.c @@ -33,10 +33,6 @@ #include #include -#include -#include -#include - typedef int (*file_cb)(char* buffer, void *data); typedef int (*config_cb)(char *value, struct lxc_conf *lxc_conf); @@ -128,11 +124,11 @@ static int char_right_gc(char *buffer, size_t len) static int config_network_type(char *value, struct lxc_conf *lxc_conf) { - struct list *networks = &lxc_conf->networks; - struct network *network; - struct netdev *netdev; - struct list *list; - struct list *ndlist; + struct lxc_list *networks = &lxc_conf->networks; + struct lxc_network *network; + struct lxc_netdev *netdev; + struct lxc_list *list; + struct lxc_list *ndlist; network = malloc(sizeof(*network)); if (!network) { @@ -140,7 +136,7 @@ static int config_network_type(char *value, struct lxc_conf *lxc_conf) return -1; } - list_init(&network->netdev); + lxc_list_init(&network->netdev); netdev = malloc(sizeof(*netdev)); if (!netdev) { @@ -148,10 +144,10 @@ static int config_network_type(char *value, struct lxc_conf *lxc_conf) return -1; } - list_init(&netdev->ipv4); - list_init(&netdev->ipv6); - list_init(&netdev->route4); - list_init(&netdev->route6); + lxc_list_init(&netdev->ipv4); + lxc_list_init(&netdev->ipv6); + lxc_list_init(&netdev->route4); + lxc_list_init(&netdev->route6); ndlist = malloc(sizeof(*ndlist)); if (!ndlist) { @@ -161,7 +157,7 @@ static int config_network_type(char *value, struct lxc_conf *lxc_conf) ndlist->elem = netdev; - list_add(&network->netdev, ndlist); + lxc_list_add(&network->netdev, ndlist); list = malloc(sizeof(*list)); if (!list) { @@ -169,10 +165,10 @@ static int config_network_type(char *value, struct lxc_conf *lxc_conf) return -1; } - list_init(list); + lxc_list_init(list); list->elem = network; - list_add(networks, list); + lxc_list_add(networks, list); if (!strcmp(value, "veth")) network->type = VETH; @@ -189,38 +185,38 @@ static int config_network_type(char *value, struct lxc_conf *lxc_conf) static int config_network_flags(char *value, struct lxc_conf *lxc_conf) { - struct list *networks = &lxc_conf->networks; - struct network *network; - struct netdev *netdev; + struct lxc_list *networks = &lxc_conf->networks; + struct lxc_network *network; + struct lxc_netdev *netdev; - if (list_empty(networks)) { + if (lxc_list_empty(networks)) { lxc_log_error("network is not created for '%s' option", value); return -1; } - network = list_first_elem(networks); + network = lxc_list_first_elem(networks); if (!network) { lxc_log_error("no network defined for '%s' option", value); return -1; } - netdev = list_first_elem(&network->netdev); + netdev = lxc_list_first_elem(&network->netdev); netdev->flags |= IFF_UP; return 0; } static int config_network_link(char *value, struct lxc_conf *lxc_conf) { - struct list *networks = &lxc_conf->networks; - struct network *network; - struct netdev *netdev; + struct lxc_list *networks = &lxc_conf->networks; + struct lxc_network *network; + struct lxc_netdev *netdev; - if (list_empty(networks)) { + if (lxc_list_empty(networks)) { lxc_log_error("network is not created for %s", value); return -1; } - network = list_first_elem(networks); + network = lxc_list_first_elem(networks); if (!network) { lxc_log_error("no network defined for %s", value); return -1; @@ -231,23 +227,23 @@ static int config_network_link(char *value, struct lxc_conf *lxc_conf) return -1; } - netdev = list_first_elem(&network->netdev); + netdev = lxc_list_first_elem(&network->netdev); netdev->ifname = strdup(value); return 0; } static int config_network_name(char *value, struct lxc_conf *lxc_conf) { - struct list *networks = &lxc_conf->networks; - struct network *network; - struct netdev *netdev; + struct lxc_list *networks = &lxc_conf->networks; + struct lxc_network *network; + struct lxc_netdev *netdev; - if (list_empty(networks)) { + if (lxc_list_empty(networks)) { lxc_log_error("network is not created for %s", value); return -1; } - network = list_first_elem(networks); + network = lxc_list_first_elem(networks); if (!network) { lxc_log_error("no network defined for %s", value); return -1; @@ -258,54 +254,54 @@ static int config_network_name(char *value, struct lxc_conf *lxc_conf) return -1; } - netdev = list_first_elem(&network->netdev); + netdev = lxc_list_first_elem(&network->netdev); netdev->newname = strdup(value); return 0; } static int config_network_hwaddr(char *value, struct lxc_conf *lxc_conf) { - struct list *networks = &lxc_conf->networks; - struct network *network; - struct netdev *netdev; + struct lxc_list *networks = &lxc_conf->networks; + struct lxc_network *network; + struct lxc_netdev *netdev; - if (list_empty(networks)) { + if (lxc_list_empty(networks)) { lxc_log_error("network is not created for %s", value); return -1; } - network = list_first_elem(networks); + network = lxc_list_first_elem(networks); if (!network) { lxc_log_error("no network defined for %s", value); return -1; } - netdev = list_first_elem(&network->netdev); + netdev = lxc_list_first_elem(&network->netdev); netdev->hwaddr = strdup(value); return 0; } static int config_network_ipv4(char *value, struct lxc_conf *lxc_conf) { - struct list *networks = &lxc_conf->networks; - struct network *network; - struct inetdev *inetdev; - struct netdev *netdev; - struct list *list; + struct lxc_list *networks = &lxc_conf->networks; + struct lxc_network *network; + struct lxc_inetdev *inetdev; + struct lxc_netdev *netdev; + struct lxc_list *list; char *cursor, *slash, *addr = NULL, *bcast = NULL, *prefix = NULL; - if (list_empty(networks)) { + if (lxc_list_empty(networks)) { lxc_log_error("network is not created for '%s'", value); return -1; } - network = list_first_elem(networks); + network = lxc_list_first_elem(networks); if (!network) { lxc_log_error("no network defined for '%s'", value); return -1; } - netdev = list_first_elem(&network->netdev); + netdev = lxc_list_first_elem(&network->netdev); if (!netdev) { lxc_log_error("no netdev defined for '%s'", value); } @@ -323,7 +319,7 @@ static int config_network_ipv4(char *value, struct lxc_conf *lxc_conf) return -1; } - list_init(list); + lxc_list_init(list); list->elem = inetdev; addr = value; @@ -359,27 +355,27 @@ static int config_network_ipv4(char *value, struct lxc_conf *lxc_conf) if (prefix) inetdev->prefix = atoi(prefix); - list_add(&netdev->ipv4, list); + lxc_list_add(&netdev->ipv4, list); return 0; } static int config_network_ipv6(char *value, struct lxc_conf *lxc_conf) { - struct list *networks = &lxc_conf->networks; - struct network *network; - struct netdev *netdev; - struct inet6dev *inet6dev; - struct list *list; + struct lxc_list *networks = &lxc_conf->networks; + struct lxc_network *network; + struct lxc_netdev *netdev; + struct lxc_inet6dev *inet6dev; + struct lxc_list *list; char *slash; char *netmask; - if (list_empty(networks)) { + if (lxc_list_empty(networks)) { lxc_log_error("network is not created for %s", value); return -1; } - network = list_first_elem(networks); + network = lxc_list_first_elem(networks); if (!network) { lxc_log_error("no network defined for %s", value); return -1; @@ -398,7 +394,7 @@ static int config_network_ipv6(char *value, struct lxc_conf *lxc_conf) return -1; } - list_init(list); + lxc_list_init(list); list->elem = inet6dev; slash = strstr(value, "/"); @@ -414,8 +410,8 @@ static int config_network_ipv6(char *value, struct lxc_conf *lxc_conf) } - netdev = list_first_elem(&network->netdev); - list_add(&netdev->ipv6, list); + netdev = lxc_list_first_elem(&network->netdev); + lxc_list_add(&netdev->ipv6, list); return 0; } @@ -545,6 +541,6 @@ int config_init(struct lxc_conf *conf) conf->fstab = NULL; conf->utsname = NULL; conf->cgroup = NULL; - list_init(&conf->networks); + lxc_list_init(&conf->networks); return 0; } diff --git a/src/lxc/lxc_create.c b/src/lxc/lxc_create.c index 389f4edf5..5f9f7205b 100644 --- a/src/lxc/lxc_create.c +++ b/src/lxc/lxc_create.c @@ -32,9 +32,6 @@ #include #include -#include -#include -#include #include "config.h" diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c index 8736885b6..b844f6124 100644 --- a/src/lxc/lxc_monitor.c +++ b/src/lxc/lxc_monitor.c @@ -26,7 +26,6 @@ #include #include -#include void usage(char *cmd) { diff --git a/src/lxc/lxc_state.c b/src/lxc/lxc_state.c index a173d19ad..abb6b3c92 100644 --- a/src/lxc/lxc_state.c +++ b/src/lxc/lxc_state.c @@ -26,7 +26,6 @@ #include #include -#include void usage(char *cmd) { diff --git a/test/conf.c b/test/conf.c index 419e4db54..ac1f929ba 100644 --- a/test/conf.c +++ b/test/conf.c @@ -27,8 +27,8 @@ #include #include -#include -#include +#include +#include /* * I want to setup a container with a veth attached on a bridge, diff --git a/test/confile.c b/test/confile.c index 5e9dbdd59..53a6f08ec 100644 --- a/test/confile.c +++ b/test/confile.c @@ -31,9 +31,6 @@ #include #include -#include -#include -#include #include "../src/lxc/config.h" diff --git a/test/lxc_create.c b/test/lxc_create.c index 9ee71b646..36761538e 100644 --- a/test/lxc_create.c +++ b/test/lxc_create.c @@ -31,9 +31,6 @@ #include #include -#include -#include -#include static void usage(const char *cmd) { @@ -50,7 +47,7 @@ int main(int argc, char *argv[]) /* struct list mclist2; */ /* struct list vethlist; */ /* struct list vethlist2; */ - struct list phylist; + struct lxc_list phylist; /* struct inetdev idev; */ /* struct list l1 = init_list(&l1); */ @@ -129,30 +126,30 @@ int main(int argc, char *argv[]) /* }; */ /* mclist2.elem = &macvlan2; */ - struct netdev nd = { + struct lxc_netdev nd = { .ifname = "dummy0", - .ipv4 = init_list(&nd.ipv4), - .ipv6 = init_list(&nd.ipv6), + .ipv4 = lxc_init_list(&nd.ipv4), + .ipv6 = lxc_init_list(&nd.ipv6), }; - struct list ndlist = init_list(&ndlist); + struct lxc_list ndlist = lxc_init_list(&ndlist); ndlist.elem = &nd; - struct network phys = { + struct lxc_network phys = { .type = PHYS, - .netdev = init_list(&phys.netdev), + .netdev = lxc_init_list(&phys.netdev), }; phylist.elem = &phys; struct lxc_conf lxc_conf = { - .networks = init_list(&lxc_conf.networks), + .networks = lxc_init_list(&lxc_conf.networks), .chroot = "/mnt/iso", }; - list_add(&phys.netdev, &ndlist); + lxc_list_add(&phys.netdev, &ndlist); /* list_add(&lxc_conf.networks, &vethlist); */ /* list_add(&lxc_conf.networks, &mclist); */ - list_add(&lxc_conf.networks, &phylist); + lxc_list_add(&lxc_conf.networks, &phylist); /* list_add(&lxc_conf.networks, &mclist); */ /* list_add(&lxc_conf.networks, &vethlist2); */ diff --git a/test/lxc_monitor.c b/test/lxc_monitor.c index 8f66d4ee6..cd297af53 100644 --- a/test/lxc_monitor.c +++ b/test/lxc_monitor.c @@ -26,7 +26,6 @@ #include #include -#include void usage(char *cmd) { diff --git a/test/lxc_start.c b/test/lxc_start.c index 2f551ec51..d1f2e93fc 100644 --- a/test/lxc_start.c +++ b/test/lxc_start.c @@ -34,9 +34,6 @@ #include #include -#include -#include -#include void usage(char *cmd) { diff --git a/test/lxc_state.c b/test/lxc_state.c index 2e5540873..2b4409130 100644 --- a/test/lxc_state.c +++ b/test/lxc_state.c @@ -26,7 +26,6 @@ #include #include -#include void usage(char *cmd) { diff --git a/test/tst_list.c b/test/tst_list.c index b4d062481..7bd8c58ab 100644 --- a/test/tst_list.c +++ b/test/tst_list.c @@ -1,15 +1,15 @@ #include #include -#include +#include int main(int argc, char *argv[]) { - struct list *iterator; - struct list head = init_list(&head); - struct list l1 = init_list(&l1); - struct list l2 = init_list(&l2); - struct list l3 = init_list(&l3); - struct list l4 = init_list(&l4); + struct lxc_list *iterator; + struct lxc_list head = lxc_init_list(&head); + struct lxc_list l1 = lxc_init_list(&l1); + struct lxc_list l2 = lxc_init_list(&l2); + struct lxc_list l3 = lxc_init_list(&l3); + struct lxc_list l4 = lxc_init_list(&l4); struct dummy { int a; @@ -21,7 +21,7 @@ int main(int argc, char *argv[]) struct dummy d3 = { .a = 3 }; struct dummy d4 = { .a = 4 }; - if (!list_empty(&head)) { + if (!lxc_list_empty(&head)) { fprintf(stderr, "expected empty list\n"); return -1; } @@ -31,33 +31,33 @@ int main(int argc, char *argv[]) l3.elem = &d3; l4.elem = &d4; - list_add(&head, &l1); - list_add(&head, &l2); - list_add(&head, &l3); - list_add(&head, &l4); + lxc_list_add(&head, &l1); + lxc_list_add(&head, &l2); + lxc_list_add(&head, &l3); + lxc_list_add(&head, &l4); - list_for_each(iterator, &head) { + lxc_list_for_each(iterator, &head) { elem = iterator->elem; printf("elem has %d\n", elem->a); } - list_del(&l3); + lxc_list_del(&l3); - list_for_each(iterator, &head) { + lxc_list_for_each(iterator, &head) { elem = iterator->elem; printf("elem has %d\n", elem->a); } - list_del(&l1); - list_del(&l2); - list_del(&l4); + lxc_list_del(&l1); + lxc_list_del(&l2); + lxc_list_del(&l4); - if (!list_empty(&head)) { + if (!lxc_list_empty(&head)) { fprintf(stderr, "expected empty list\n"); return -1; } - list_for_each(iterator, &head) { + lxc_list_for_each(iterator, &head) { fprintf(stderr, "should not loop\n"); return -1; }