Factor out some code

From: Daniel Lezcano <daniel.lezcano@free.fr>

Factor out some code and especially the parsing of text file functions.

Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
This commit is contained in:
dlezcano 2009-02-16 10:22:49 +00:00
parent 78ae2fcca0
commit b2718c72a7
4 changed files with 46 additions and 187 deletions

View File

@ -25,6 +25,7 @@ liblxc_la_SOURCES = \
restart.c \ restart.c \
version.c \ version.c \
error.h error.c \ error.h error.c \
parse.c parse.h \
cgroup.c cgroup.h \ cgroup.c cgroup.h \
lxc.h \ lxc.h \
lxc_utils.h \ lxc_utils.h \

View File

@ -47,6 +47,7 @@
#include "network.h" #include "network.h"
#include "error.h" #include "error.h"
#include "parse.h"
#include <lxc/lxc.h> #include <lxc/lxc.h>
@ -58,11 +59,6 @@
typedef int (*instanciate_cb)(const char *directory, typedef int (*instanciate_cb)(const char *directory,
const char *file, pid_t pid); const char *file, pid_t pid);
typedef int (*dir_cb)(const char *name, const char *directory,
const char *file, void *data);
typedef int (*file_cb)(void* buffer, void *data);
struct netdev_conf { struct netdev_conf {
const char *type; const char *type;
instanciate_cb cb; instanciate_cb cb;
@ -82,86 +78,6 @@ static struct netdev_conf netdev_conf[MAXCONFTYPE + 1] = {
[EMPTY] = { "empty", instanciate_empty, 0, }, [EMPTY] = { "empty", instanciate_empty, 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 *directory,
dir_cb callback, void *data)
{
struct dirent **namelist;
int n;
n = scandir(directory, &namelist, dir_filter, alphasort);
if (n < 0) {
lxc_log_syserror("failed to scan %s directory", directory);
return -1;
}
while (n--) {
if (callback(name, directory, 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)) {
err = callback(buffer, data);
if (err)
goto out;
}
out:
fclose(f);
return err;
}
static int char_left_gc(char *buffer, size_t len)
{
int i;
for (i = 0; i < len; i++) {
if (buffer[i] == ' ' ||
buffer[i] == '\t')
continue;
return i;
}
return 0;
}
static int char_right_gc(char *buffer, size_t len)
{
int i;
for (i = len - 1; i >= 0; i--) {
if (buffer[i] == ' ' ||
buffer[i] == '\t' ||
buffer[i] == '\n' ||
buffer[i] == '\0')
continue;
return i + 1;
}
return 0;
}
static int write_info(const char *path, const char *file, const char *info) static int write_info(const char *path, const char *file, const char *info)
{ {
int fd, err = -1; int fd, err = -1;
@ -493,8 +409,8 @@ static int configure_find_fstype_cb(void* buffer, void *data)
return 0; return 0;
fstype = buffer; fstype = buffer;
fstype += char_left_gc(fstype, strlen(fstype)); fstype += lxc_char_left_gc(fstype, strlen(fstype));
fstype[char_right_gc(fstype, strlen(fstype))] = '\0'; fstype[lxc_char_right_gc(fstype, strlen(fstype))] = '\0';
if (mount(cbarg->rootfs, cbarg->testdir, fstype, cbarg->mntopt, NULL)) if (mount(cbarg->rootfs, cbarg->testdir, fstype, cbarg->mntopt, NULL))
return 0; return 0;
@ -544,7 +460,7 @@ static int configure_find_fstype(const char *rootfs, char *fstype, int mntopt)
for (i = 0; i < sizeof(fsfile)/sizeof(fsfile[0]); i++) { for (i = 0; i < sizeof(fsfile)/sizeof(fsfile[0]); i++) {
found = file_for_each_line(fsfile[i], found = lxc_file_for_each_line(fsfile[i],
configure_find_fstype_cb, configure_find_fstype_cb,
buffer, sizeof(buffer), &cbarg); buffer, sizeof(buffer), &cbarg);
@ -789,7 +705,7 @@ static int unconfigure_network(const char *name)
char directory[MAXPATHLEN]; char directory[MAXPATHLEN];
snprintf(directory, MAXPATHLEN, LXCPATH "/%s/network", name); snprintf(directory, MAXPATHLEN, LXCPATH "/%s/network", name);
dir_for_each(name, directory, unconfigure_network_cb, NULL); lxc_dir_for_each(name, directory, unconfigure_network_cb, NULL);
rmdir(directory); rmdir(directory);
return 0; return 0;
@ -815,7 +731,7 @@ static int unconfigure_cgroup(const char *name)
if (S_ISDIR(s.st_mode)) { if (S_ISDIR(s.st_mode)) {
/* old cgroup configuration */ /* old cgroup configuration */
dir_for_each(name, filename, unconfigure_cgroup_cb, NULL); lxc_dir_for_each(name, filename, unconfigure_cgroup_cb, NULL);
rmdir(filename); rmdir(filename);
} else { } else {
unlink(filename); unlink(filename);
@ -1054,7 +970,7 @@ static int setup_convert_cgroup(const char *name, char *directory)
if (!file) if (!file)
return -1; return -1;
ret = dir_for_each(name, directory, setup_convert_cgroup_cb, file); ret = lxc_dir_for_each(name, directory, setup_convert_cgroup_cb, file);
if (ret) if (ret)
goto out_error; goto out_error;
@ -1094,7 +1010,7 @@ static int setup_cgroup(const char *name)
} }
} }
return file_for_each_line(filename, setup_cgroup_cb, return lxc_file_for_each_line(filename, setup_cgroup_cb,
line, MAXPATHLEN, (void *)name); line, MAXPATHLEN, (void *)name);
} }
@ -1242,7 +1158,7 @@ static int setup_ip_addr(const char *directory, const char *ifname)
snprintf(path, MAXPATHLEN, "%s/ipv4/addresses", directory); snprintf(path, MAXPATHLEN, "%s/ipv4/addresses", directory);
if (!stat(path, &s)) if (!stat(path, &s))
ret = file_for_each_line(path, setup_ipv4_addr_cb, ret = lxc_file_for_each_line(path, setup_ipv4_addr_cb,
line, MAXPATHLEN, (void*)ifname); line, MAXPATHLEN, (void*)ifname);
return ret; return ret;
} }
@ -1255,7 +1171,7 @@ static int setup_ip6_addr(const char *directory, const char *ifname)
snprintf(path, MAXLINELEN, "%s/ipv6/addresses", directory); snprintf(path, MAXLINELEN, "%s/ipv6/addresses", directory);
if (!stat(path, &s)) if (!stat(path, &s))
ret = file_for_each_line(path, setup_ipv6_addr_cb, ret = lxc_file_for_each_line(path, setup_ipv6_addr_cb,
line, MAXPATHLEN, (void*)ifname); line, MAXPATHLEN, (void*)ifname);
return ret; return ret;
} }
@ -1344,7 +1260,7 @@ static int setup_network(const char *name)
char directory[MAXPATHLEN]; char directory[MAXPATHLEN];
snprintf(directory, MAXPATHLEN, LXCPATH "/%s/network", name); snprintf(directory, MAXPATHLEN, LXCPATH "/%s/network", name);
return dir_for_each(name, directory, setup_network_cb, NULL); return lxc_dir_for_each(name, directory, setup_network_cb, NULL);
} }
int conf_has(const char *name, const char *info) int conf_has(const char *name, const char *info)
@ -1616,7 +1532,7 @@ static int instanciate_netdev(const char *name, pid_t pid)
char directory[MAXPATHLEN]; char directory[MAXPATHLEN];
snprintf(directory, MAXPATHLEN, LXCPATH "/%s/network", name); snprintf(directory, MAXPATHLEN, LXCPATH "/%s/network", name);
return dir_for_each(name, directory, instanciate_netdev_cb, &pid); return lxc_dir_for_each(name, directory, instanciate_netdev_cb, &pid);
} }
static int move_netdev_cb(const char *name, const char *directory, static int move_netdev_cb(const char *name, const char *directory,
@ -1654,7 +1570,7 @@ static int move_netdev(const char *name, pid_t pid)
{ {
char directory[MAXPATHLEN]; char directory[MAXPATHLEN];
snprintf(directory, MAXPATHLEN, LXCPATH "/%s/network", name); snprintf(directory, MAXPATHLEN, LXCPATH "/%s/network", name);
return dir_for_each(name, directory, move_netdev_cb, &pid); return lxc_dir_for_each(name, directory, move_netdev_cb, &pid);
} }
int conf_create_network(const char *name, pid_t pid) int conf_create_network(const char *name, pid_t pid)
@ -1672,6 +1588,7 @@ int conf_create_network(const char *name, pid_t pid)
return 0; return 0;
} }
#ifdef NETWORK_DESTROY
static int delete_netdev_cb(const char *name, const char *directory, static int delete_netdev_cb(const char *name, const char *directory,
const char *file, void *data) const char *file, void *data)
{ {
@ -1712,19 +1629,16 @@ static int delete_netdev_cb(const char *name, const char *directory,
return 0; return 0;
} }
#endif
static int delete_netdev(const char *name)
{
char directory[MAXPATHLEN];
snprintf(directory, MAXPATHLEN, LXCPATH "/%s/network", name);
return dir_for_each(name, directory, delete_netdev_cb, NULL);
}
int conf_destroy_network(const char *name) int conf_destroy_network(const char *name)
{ {
#ifdef NETWORK_DESTROY #ifdef NETWORK_DESTROY
if (delete_netdev(name)) { char directory[MAXPATHLEN];
snprintf(directory, MAXPATHLEN, LXCPATH "/%s/network", name);
if (lxc_dir_for_each(name, directory, delete_netdev_cb, NULL)) {
lxc_log_error("failed to remove the network devices"); lxc_log_error("failed to remove the network devices");
return -1; return -1;
} }

View File

@ -32,10 +32,9 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <net/if.h> #include <net/if.h>
#include <lxc/lxc.h> #include "parse.h"
typedef int (*file_cb)(char* buffer, void *data); #include <lxc/lxc.h>
typedef int (*config_cb)(const char *, char *, struct lxc_conf *);
static int config_pts(const char *, char *, struct lxc_conf *); static int config_pts(const char *, char *, struct lxc_conf *);
static int config_tty(const char *, char *, struct lxc_conf *); static int config_tty(const char *, char *, struct lxc_conf *);
@ -51,6 +50,8 @@ static int config_network_hwaddr(const char *, char *, struct lxc_conf *);
static int config_network_ipv4(const char *, char *, struct lxc_conf *); static int config_network_ipv4(const char *, char *, struct lxc_conf *);
static int config_network_ipv6(const char *, char *, struct lxc_conf *); static int config_network_ipv6(const char *, char *, struct lxc_conf *);
typedef int (*config_cb)(const char *, char *, struct lxc_conf *);
struct config { struct config {
char *name; char *name;
config_cb cb; config_cb cb;
@ -86,45 +87,6 @@ static struct config *getconfig(const char *key)
return NULL; return NULL;
} }
static int is_line_empty(char *line)
{
int i;
size_t len = strlen(line);
for (i = 0; i < len; i++)
if (line[i] != ' ' && line[i] != '\t' &&
line[i] != '\n' && line[i] != '\r' &&
line[i] != '\f' && line[i] != '\0')
return 0;
return 1;
}
static int char_left_gc(char *buffer, size_t len)
{
int i;
for (i = 0; i < len; i++) {
if (buffer[i] == ' ' ||
buffer[i] == '\t')
continue;
return i;
}
return 0;
}
static int char_right_gc(char *buffer, size_t len)
{
int i;
for (i = len - 1; i >= 0; i--) {
if (buffer[i] == ' ' ||
buffer[i] == '\t' ||
buffer[i] == '\n' ||
buffer[i] == '\0')
continue;
return i + 1;
}
return 0;
}
static int config_network_type(const char *key, char *value, struct lxc_conf *lxc_conf) static int config_network_type(const char *key, char *value, struct lxc_conf *lxc_conf)
{ {
struct lxc_list *networks = &lxc_conf->networks; struct lxc_list *networks = &lxc_conf->networks;
@ -532,34 +494,35 @@ static int config_utsname(const char *key, char *value, struct lxc_conf *lxc_con
return 0; return 0;
} }
static int parse_line(char *buffer, void *data) static int parse_line(void *buffer, void *data)
{ {
struct config *config; struct config *config;
char *line = buffer;
char *dot; char *dot;
char *key; char *key;
char *value; char *value;
if (is_line_empty(buffer)) if (lxc_is_line_empty(line))
return 0; return 0;
buffer += char_left_gc(buffer, strlen(buffer)); line += lxc_char_left_gc(line, strlen(line));
if (buffer[0] == '#') if (line[0] == '#')
return 0; return 0;
dot = strstr(buffer, "="); dot = strstr(line, "=");
if (!dot) { if (!dot) {
lxc_log_error("invalid configuration line: %s", buffer); lxc_log_error("invalid configuration line: %s", line);
return -1; return -1;
} }
*dot = '\0'; *dot = '\0';
value = dot + 1; value = dot + 1;
key = buffer; key = line;
key[char_right_gc(key, strlen(key))] = '\0'; key[lxc_char_right_gc(key, strlen(key))] = '\0';
value += char_left_gc(value, strlen(value)); value += lxc_char_left_gc(value, strlen(value));
value[char_right_gc(value, strlen(value))] = '\0'; value[lxc_char_right_gc(value, strlen(value))] = '\0';
config = getconfig(key); config = getconfig(key);
if (!config) { if (!config) {
@ -570,31 +533,12 @@ static int parse_line(char *buffer, void *data)
return config->cb(key, value, data); return config->cb(key, value, data);
} }
static int file_for_each_line(const char *file, file_cb callback, void *data)
{
char buffer[MAXPATHLEN];
size_t len = sizeof(buffer);
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;
}
int lxc_config_read(const char *file, struct lxc_conf *conf) int lxc_config_read(const char *file, struct lxc_conf *conf)
{ {
return file_for_each_line(file, parse_line, conf); char buffer[MAXPATHLEN];
return lxc_file_for_each_line(file, parse_line, buffer,
sizeof(buffer), conf);
} }
int lxc_config_init(struct lxc_conf *conf) int lxc_config_init(struct lxc_conf *conf)

View File

@ -53,7 +53,7 @@ int main(int argc, char *argv[])
int opt, nbargs = 0, status = 1, hastofork = 0; int opt, nbargs = 0, status = 1, hastofork = 0;
char **args; char **args;
long flags = 0; long flags = 0;
uid_t uid; uid_t uid = 0;
pid_t pid; pid_t pid;
while ((opt = getopt(argc, argv, "fmphiu:n")) != -1) { while ((opt = getopt(argc, argv, "fmphiu:n")) != -1) {