Unverified Commit c8a5adcd by Stéphane Graber Committed by GitHub

Merge pull request #2186 from brauner/2018-02-22/make_confile_reading_thread_safe

tree-wide: thread-safety improvements
parents 1401329e 106f1f38
...@@ -278,7 +278,7 @@ lxc_checkpoint_SOURCES = tools/lxc_checkpoint.c tools/arguments.c tools/tool_uti ...@@ -278,7 +278,7 @@ lxc_checkpoint_SOURCES = tools/lxc_checkpoint.c tools/arguments.c tools/tool_uti
# Binaries shipping with liblxc # Binaries shipping with liblxc
init_lxc_SOURCES = cmd/lxc_init.c init_lxc_SOURCES = cmd/lxc_init.c
lxc_monitord_SOURCES = cmd/lxc_monitord.c lxc_monitord_SOURCES = cmd/lxc_monitord.c
lxc_user_nic_SOURCES = cmd/lxc_user_nic.c namespace.c network.c lxc_user_nic_SOURCES = cmd/lxc_user_nic.c namespace.c network.c parse.c
lxc_usernsexec_SOURCES = cmd/lxc_usernsexec.c lxc_usernsexec_SOURCES = cmd/lxc_usernsexec.c
if ENABLE_DEPRECATED if ENABLE_DEPRECATED
......
...@@ -327,7 +327,7 @@ struct hierarchy *get_hierarchy(const char *c) ...@@ -327,7 +327,7 @@ struct hierarchy *get_hierarchy(const char *c)
!hierarchies[i]->controllers[0]) !hierarchies[i]->controllers[0])
return hierarchies[i]; return hierarchies[i];
return NULL; continue;
} }
if (string_in_list(hierarchies[i]->controllers, c)) if (string_in_list(hierarchies[i]->controllers, c))
...@@ -1306,8 +1306,11 @@ static bool cg_hybrid_init(void) ...@@ -1306,8 +1306,11 @@ static bool cg_hybrid_init(void)
controller_list = cg_unified_get_controllers(cgv2_ctrl_path); controller_list = cg_unified_get_controllers(cgv2_ctrl_path);
free(cgv2_ctrl_path); free(cgv2_ctrl_path);
if (!controller_list) if (!controller_list) {
controller_list = cg_unified_make_empty_controller(); controller_list = cg_unified_make_empty_controller();
CGFSNG_DEBUG("No controllers are enabled for "
"delegation in the unified hierarchy\n");
}
} }
new = add_hierarchy(controller_list, mountpoint, base_cgroup, type); new = add_hierarchy(controller_list, mountpoint, base_cgroup, type);
...@@ -2365,13 +2368,16 @@ static bool cgfsng_unfreeze(void *hdata) ...@@ -2365,13 +2368,16 @@ static bool cgfsng_unfreeze(void *hdata)
return true; return true;
} }
static const char *cgfsng_get_cgroup(void *hdata, const char *subsystem) static const char *cgfsng_get_cgroup(void *hdata, const char *controller)
{ {
struct hierarchy *h; struct hierarchy *h;
h = get_hierarchy(subsystem); h = get_hierarchy(controller);
if (!h) if (!h) {
SYSERROR("Failed to find hierarchy for controller \"%s\"",
controller ? controller : "(null)");
return NULL; return NULL;
}
return h->fullcgpath ? h->fullcgpath + strlen(h->mountpoint) : NULL; return h->fullcgpath ? h->fullcgpath + strlen(h->mountpoint) : NULL;
} }
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "config.h" #include "config.h"
#include "namespace.h" #include "namespace.h"
#include "network.h" #include "network.h"
#include "parse.h"
#include "utils.h" #include "utils.h"
#define usernic_debug_stream(stream, format, ...) \ #define usernic_debug_stream(stream, format, ...) \
......
...@@ -2334,7 +2334,7 @@ int lxc_config_read(const char *file, struct lxc_conf *conf, bool from_include) ...@@ -2334,7 +2334,7 @@ int lxc_config_read(const char *file, struct lxc_conf *conf, bool from_include)
if (!conf->rcfile) if (!conf->rcfile)
conf->rcfile = strdup(file); conf->rcfile = strdup(file);
return lxc_file_for_each_line(file, parse_line, &c); return lxc_file_for_each_line_mmap(file, parse_line, &c);
} }
int lxc_config_define_add(struct lxc_list *defines, char *arg) int lxc_config_define_add(struct lxc_list *defines, char *arg)
...@@ -2417,17 +2417,21 @@ signed long lxc_config_parse_arch(const char *arch) ...@@ -2417,17 +2417,21 @@ signed long lxc_config_parse_arch(const char *arch)
} }
/* Write out a configuration file. */ /* Write out a configuration file. */
void write_config(FILE *fout, struct lxc_conf *c) int write_config(int fd, const struct lxc_conf *conf)
{ {
int ret; int ret;
size_t len = c->unexpanded_len; size_t len = conf->unexpanded_len;
if (!len) if (len == 0)
return; return 0;
ret = fwrite(c->unexpanded_config, 1, len, fout); ret = lxc_write_nointr(fd, conf->unexpanded_config, len);
if (ret != len) if (ret < 0) {
SYSERROR("Failed to write configuration file"); SYSERROR("Failed to write configuration file");
return -1;
}
return 0;
} }
bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key, bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key,
......
...@@ -93,7 +93,7 @@ extern signed long lxc_config_parse_arch(const char *arch); ...@@ -93,7 +93,7 @@ extern signed long lxc_config_parse_arch(const char *arch);
extern int lxc_clear_config_item(struct lxc_conf *c, const char *key); extern int lxc_clear_config_item(struct lxc_conf *c, const char *key);
extern void write_config(FILE *fout, struct lxc_conf *c); extern int write_config(int fd, const struct lxc_conf *conf);
extern bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key, extern bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key,
const char *v); const char *v);
......
...@@ -717,13 +717,13 @@ bool __criu_check_feature(uint64_t *features_to_check) ...@@ -717,13 +717,13 @@ bool __criu_check_feature(uint64_t *features_to_check)
* LXC checking only for 'uffd' makes not much sense. */ * LXC checking only for 'uffd' makes not much sense. */
args[3] = "uffd-noncoop"; args[3] = "uffd-noncoop";
else else
exit(1); _exit(EXIT_FAILURE);
null_stdfds(); null_stdfds();
execvp("criu", args); execvp("criu", args);
SYSERROR("Failed to exec \"criu\""); SYSERROR("Failed to exec \"criu\"");
exit(1); _exit(EXIT_FAILURE);
} }
ret = wait_for_pid(pid); ret = wait_for_pid(pid);
...@@ -785,14 +785,14 @@ static bool criu_version_ok(char **version) ...@@ -785,14 +785,14 @@ static bool criu_version_ok(char **version)
close(STDERR_FILENO); close(STDERR_FILENO);
if (dup2(pipes[1], STDOUT_FILENO) < 0) if (dup2(pipes[1], STDOUT_FILENO) < 0)
exit(1); _exit(EXIT_FAILURE);
path = on_path("criu", NULL); path = on_path("criu", NULL);
if (!path) if (!path)
exit(1); _exit(EXIT_FAILURE);
execv(path, args); execv(path, args);
exit(1); _exit(EXIT_FAILURE);
} else { } else {
FILE *f; FILE *f;
char *tmp; char *tmp;
...@@ -923,7 +923,7 @@ out_unlock: ...@@ -923,7 +923,7 @@ out_unlock:
} }
/* do_restore never returns, the calling process is used as the monitor process. /* do_restore never returns, the calling process is used as the monitor process.
* do_restore calls exit() if it fails. * do_restore calls _exit() if it fails.
*/ */
static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_opts *opts, char *criu_version) static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_opts *opts, char *criu_version)
{ {
...@@ -1140,7 +1140,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ ...@@ -1140,7 +1140,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
if (ret) if (ret)
lxc_abort(c->name, handler); lxc_abort(c->name, handler);
lxc_fini(c->name, handler); lxc_fini(c->name, handler);
exit(ret); _exit(ret);
} }
out_fini_handler: out_fini_handler:
...@@ -1165,7 +1165,7 @@ out: ...@@ -1165,7 +1165,7 @@ out:
close(status_pipe); close(status_pipe);
} }
exit(1); _exit(EXIT_FAILURE);
} }
static int save_tty_major_minor(char *directory, struct lxc_container *c, char *tty_id, int len) static int save_tty_major_minor(char *directory, struct lxc_container *c, char *tty_id, int len)
...@@ -1256,7 +1256,7 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op ...@@ -1256,7 +1256,7 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
h.name = c->name; h.name = c->name;
if (!cgroup_init(&h)) { if (!cgroup_init(&h)) {
ERROR("failed to cgroup_init()"); ERROR("failed to cgroup_init()");
exit(1); _exit(EXIT_FAILURE);
} }
os.pipefd = criuout[1]; os.pipefd = criuout[1];
...@@ -1269,13 +1269,13 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op ...@@ -1269,13 +1269,13 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
ret = save_tty_major_minor(opts->directory, c, os.tty_id, sizeof(os.tty_id)); ret = save_tty_major_minor(opts->directory, c, os.tty_id, sizeof(os.tty_id));
if (ret < 0) { if (ret < 0) {
free(criu_version); free(criu_version);
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
/* exec_criu() returning is an error */ /* exec_criu() returning is an error */
exec_criu(&os); exec_criu(&os);
free(criu_version); free(criu_version);
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} else { } else {
int status; int status;
ssize_t n; ssize_t n;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define __LXC_ERROR_H #define __LXC_ERROR_H
#define LXC_CLONE_ERROR "Failed to clone a new set of namespaces" #define LXC_CLONE_ERROR "Failed to clone a new set of namespaces"
#define LXC_UNPRIV_EOPNOTSUPP "the requested function %s is not currently supported with unprivileged containers"
extern int lxc_error_set_and_log(int pid, int status); extern int lxc_error_set_and_log(int pid, int status);
......
...@@ -72,10 +72,11 @@ static void lock_mutex(pthread_mutex_t *l) ...@@ -72,10 +72,11 @@ static void lock_mutex(pthread_mutex_t *l)
{ {
int ret; int ret;
if ((ret = pthread_mutex_lock(l)) != 0) { ret = pthread_mutex_lock(l);
fprintf(stderr, "pthread_mutex_lock returned:%d %s\n", ret, strerror(ret)); if (ret != 0) {
fprintf(stderr, "%s - Failed acquire mutex", strerror(ret));
dump_stacktrace(); dump_stacktrace();
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
} }
...@@ -83,11 +84,11 @@ static void unlock_mutex(pthread_mutex_t *l) ...@@ -83,11 +84,11 @@ static void unlock_mutex(pthread_mutex_t *l)
{ {
int ret; int ret;
if ((ret = pthread_mutex_unlock(l)) != 0) { ret = pthread_mutex_unlock(l);
fprintf(stderr, "%s: pthread_mutex_unlock returned:%d %s\n", if (ret != 0) {
__FILE__, ret, strerror(ret)); fprintf(stderr, "%s - Failed to release mutex", strerror(ret));
dump_stacktrace(); dump_stacktrace();
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
} }
......
...@@ -635,7 +635,7 @@ static int lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old, ...@@ -635,7 +635,7 @@ static int lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old,
if (!switch_to_ns(pid, "net")) if (!switch_to_ns(pid, "net"))
return -1; return -1;
exit(lxc_netdev_rename_by_name(old, new)); _exit(lxc_netdev_rename_by_name(old, new));
} }
static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
...@@ -663,7 +663,7 @@ static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, ...@@ -663,7 +663,7 @@ static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
sprintf(pidstr, "%d", pid); sprintf(pidstr, "%d", pid);
execlp("iw", "iw", "phy", physname, "set", "netns", pidstr, execlp("iw", "iw", "phy", physname, "set", "netns", pidstr,
(char *)NULL); (char *)NULL);
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
if (wait_for_pid(fpid)) if (wait_for_pid(fpid))
...@@ -2126,7 +2126,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna ...@@ -2126,7 +2126,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
close(pipefd[1]); close(pipefd[1]);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to duplicate std{err,out} file descriptor"); SYSERROR("Failed to duplicate std{err,out} file descriptor");
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
if (netdev->link[0] != '\0') if (netdev->link[0] != '\0')
...@@ -2136,7 +2136,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna ...@@ -2136,7 +2136,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
ret = snprintf(pidstr, LXC_NUMSTRLEN64, "%d", pid); ret = snprintf(pidstr, LXC_NUMSTRLEN64, "%d", pid);
if (ret < 0 || ret >= LXC_NUMSTRLEN64) if (ret < 0 || ret >= LXC_NUMSTRLEN64)
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
pidstr[LXC_NUMSTRLEN64 - 1] = '\0'; pidstr[LXC_NUMSTRLEN64 - 1] = '\0';
INFO("Execing lxc-user-nic create %s %s %s veth %s %s", lxcpath, INFO("Execing lxc-user-nic create %s %s %s veth %s %s", lxcpath,
...@@ -2151,7 +2151,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna ...@@ -2151,7 +2151,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
lxcpath, lxcname, pidstr, "veth", netdev_link, lxcpath, lxcname, pidstr, "veth", netdev_link,
(char *)NULL); (char *)NULL);
SYSERROR("Failed to execute lxc-user-nic"); SYSERROR("Failed to execute lxc-user-nic");
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
/* close the write-end of the pipe */ /* close the write-end of the pipe */
...@@ -2269,7 +2269,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna ...@@ -2269,7 +2269,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
close(pipefd[1]); close(pipefd[1]);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to duplicate std{err,out} file descriptor"); SYSERROR("Failed to duplicate std{err,out} file descriptor");
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
if (netdev->priv.veth_attr.pair[0] != '\0') if (netdev->priv.veth_attr.pair[0] != '\0')
...@@ -2278,13 +2278,13 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna ...@@ -2278,13 +2278,13 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
hostveth = netdev->priv.veth_attr.veth1; hostveth = netdev->priv.veth_attr.veth1;
if (hostveth[0] == '\0') { if (hostveth[0] == '\0') {
SYSERROR("Host side veth device name is missing"); SYSERROR("Host side veth device name is missing");
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
if (netdev->link[0] == '\0') { if (netdev->link[0] == '\0') {
SYSERROR("Network link for network device \"%s\" is " SYSERROR("Network link for network device \"%s\" is "
"missing", netdev->priv.veth_attr.veth1); "missing", netdev->priv.veth_attr.veth1);
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
INFO("Execing lxc-user-nic delete %s %s %s veth %s %s", lxcpath, INFO("Execing lxc-user-nic delete %s %s %s veth %s %s", lxcpath,
...@@ -2293,7 +2293,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna ...@@ -2293,7 +2293,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
lxcname, netns_path, "veth", netdev->link, hostveth, lxcname, netns_path, "veth", netdev->link, hostveth,
(char *)NULL); (char *)NULL);
SYSERROR("Failed to exec lxc-user-nic."); SYSERROR("Failed to exec lxc-user-nic.");
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
close(pipefd[1]); close(pipefd[1]);
......
...@@ -20,13 +20,15 @@ ...@@ -20,13 +20,15 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#undef _GNU_SOURCE #undef _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include "parse.h" #include "parse.h"
#include "config.h" #include "config.h"
...@@ -35,6 +37,77 @@ ...@@ -35,6 +37,77 @@
lxc_log_define(lxc_parse, lxc); lxc_log_define(lxc_parse, lxc);
void *lxc_strmmap(void *addr, size_t length, int prot, int flags, int fd,
off_t offset)
{
void *tmp = NULL, *overlap = NULL;
/* We establish an anonymous mapping that is one byte larger than the
* underlying file. The pages handed to us are zero filled. */
tmp = mmap(addr, length + 1, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (tmp == MAP_FAILED)
return tmp;
/* Now we establish a fixed-address mapping starting at the address we
* received from our anonymous mapping and replace all bytes excluding
* the additional \0-byte with the file. This allows us to use normal
* string-handling functions. */
overlap = mmap(tmp, length, prot, MAP_FIXED | flags, fd, offset);
if (overlap == MAP_FAILED)
munmap(tmp, length + 1);
return overlap;
}
int lxc_strmunmap(void *addr, size_t length)
{
return munmap(addr, length + 1);
}
int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback,
void *data)
{
int fd, ret;
char *buf, *line;
struct stat st;
char *saveptr = NULL;
fd = open(file, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return -1;
ret = fstat(fd, &st);
if (ret < 0) {
close(fd);
return -1;
}
if (st.st_size == 0)
return 0;
buf = lxc_strmmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (buf == MAP_FAILED) {
close(fd);
return -1;
}
for (; (line = strtok_r(buf, "\n\0", &saveptr)); buf = NULL) {
ret = callback(line, data);
if (ret) {
/* Callback rv > 0 means stop here callback rv < 0 means
* error.
*/
if (ret < 0)
ERROR("Failed to parse config: %s", line);
break;
}
}
lxc_strmunmap(buf, st.st_size);
close(fd);
return 0;
}
int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data) int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data)
{ {
FILE *f; FILE *f;
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
#ifndef __LXC_PARSE_H #ifndef __LXC_PARSE_H
#define __LXC_PARSE_H #define __LXC_PARSE_H
#include <stdio.h>
#include <sys/types.h>
typedef int (*lxc_dir_cb)(const char *name, const char *directory, typedef int (*lxc_dir_cb)(const char *name, const char *directory,
const char *file, void *data); const char *file, void *data);
...@@ -31,10 +34,20 @@ typedef int (*lxc_file_cb)(char *buffer, void *data); ...@@ -31,10 +34,20 @@ typedef int (*lxc_file_cb)(char *buffer, void *data);
extern int lxc_file_for_each_line(const char *file, lxc_file_cb callback, extern int lxc_file_for_each_line(const char *file, lxc_file_cb callback,
void* data); void* data);
extern int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback,
void *data);
extern int lxc_char_left_gc(const char *buffer, size_t len); extern int lxc_char_left_gc(const char *buffer, size_t len);
extern int lxc_char_right_gc(const char *buffer, size_t len); extern int lxc_char_right_gc(const char *buffer, size_t len);
extern int lxc_is_line_empty(const char *line); extern int lxc_is_line_empty(const char *line);
/* mmap() wrapper. lxc_strmmap() will take care to \0-terminate files so that
* normal string-handling functions can be used on the buffer. */
extern void *lxc_strmmap(void *addr, size_t length, int prot, int flags, int fd,
off_t offset);
/* munmap() wrapper. Use it to free memory mmap()ed with lxc_strmmap(). */
extern int lxc_strmunmap(void *addr, size_t length);
#endif #endif
...@@ -478,7 +478,7 @@ struct lxc_popen_FILE *lxc_popen(const char *command) ...@@ -478,7 +478,7 @@ struct lxc_popen_FILE *lxc_popen(const char *command)
ret = fcntl(pipe_fds[1], F_SETFD, 0); ret = fcntl(pipe_fds[1], F_SETFD, 0);
if (ret < 0) { if (ret < 0) {
close(pipe_fds[1]); close(pipe_fds[1]);
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
/* duplicate stderr */ /* duplicate stderr */
...@@ -488,19 +488,19 @@ struct lxc_popen_FILE *lxc_popen(const char *command) ...@@ -488,19 +488,19 @@ struct lxc_popen_FILE *lxc_popen(const char *command)
ret = fcntl(pipe_fds[1], F_SETFD, 0); ret = fcntl(pipe_fds[1], F_SETFD, 0);
close(pipe_fds[1]); close(pipe_fds[1]);
if (ret < 0) if (ret < 0)
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
/* unblock all signals */ /* unblock all signals */
ret = sigfillset(&mask); ret = sigfillset(&mask);
if (ret < 0) if (ret < 0)
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
ret = sigprocmask(SIG_UNBLOCK, &mask, NULL); ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
if (ret < 0) if (ret < 0)
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
execl("/bin/sh", "sh", "-c", command, (char *)NULL); execl("/bin/sh", "sh", "-c", command, (char *)NULL);
exit(127); _exit(127);
} }
close(pipe_fds[1]); close(pipe_fds[1]);
...@@ -1810,33 +1810,6 @@ int lxc_count_file_lines(const char *fn) ...@@ -1810,33 +1810,6 @@ int lxc_count_file_lines(const char *fn)
return n; return n;
} }
void *lxc_strmmap(void *addr, size_t length, int prot, int flags, int fd,
off_t offset)
{
void *tmp = NULL, *overlap = NULL;
/* We establish an anonymous mapping that is one byte larger than the
* underlying file. The pages handed to us are zero filled. */
tmp = mmap(addr, length + 1, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (tmp == MAP_FAILED)
return tmp;
/* Now we establish a fixed-address mapping starting at the address we
* received from our anonymous mapping and replace all bytes excluding
* the additional \0-byte with the file. This allows us to use normal
* string-handling functions. */
overlap = mmap(tmp, length, prot, MAP_FIXED | flags, fd, offset);
if (overlap == MAP_FAILED)
munmap(tmp, length + 1);
return overlap;
}
int lxc_strmunmap(void *addr, size_t length)
{
return munmap(addr, length + 1);
}
/* Check whether a signal is blocked by a process. */ /* Check whether a signal is blocked by a process. */
/* /proc/pid-to-str/status\0 = (5 + 21 + 7 + 1) */ /* /proc/pid-to-str/status\0 = (5 + 21 + 7 + 1) */
#define __PROC_STATUS_LEN (5 + (LXC_NUMSTRLEN64) + 7 + 1) #define __PROC_STATUS_LEN (5 + (LXC_NUMSTRLEN64) + 7 + 1)
...@@ -2269,13 +2242,13 @@ int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args) ...@@ -2269,13 +2242,13 @@ int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
if (ret < 0) { if (ret < 0) {
SYSERROR("failed to duplicate std{err,out} file descriptor"); SYSERROR("failed to duplicate std{err,out} file descriptor");
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
/* Does not return. */ /* Does not return. */
child_fn(args); child_fn(args);
ERROR("failed to exec command"); ERROR("failed to exec command");
exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
/* close the write-end of the pipe */ /* close the write-end of the pipe */
......
...@@ -100,6 +100,7 @@ ...@@ -100,6 +100,7 @@
#define LXC_NUMSTRLEN64 21 #define LXC_NUMSTRLEN64 21
#define LXC_LINELEN 4096 #define LXC_LINELEN 4096
#define LXC_IDMAPLEN 4096 #define LXC_IDMAPLEN 4096
#define LXC_MAX_BUFFER 4096
/* returns 1 on success, 0 if there were any failures */ /* returns 1 on success, 0 if there were any failures */
extern int lxc_rmdir_onedev(const char *path, const char *exclude); extern int lxc_rmdir_onedev(const char *path, const char *exclude);
...@@ -426,13 +427,6 @@ extern size_t lxc_array_len(void **array); ...@@ -426,13 +427,6 @@ extern size_t lxc_array_len(void **array);
extern void **lxc_append_null_to_array(void **array, size_t count); extern void **lxc_append_null_to_array(void **array, size_t count);
/* mmap() wrapper. lxc_strmmap() will take care to \0-terminate files so that
* normal string-handling functions can be used on the buffer. */
extern void *lxc_strmmap(void *addr, size_t length, int prot, int flags, int fd,
off_t offset);
/* munmap() wrapper. Use it to free memory mmap()ed with lxc_strmmap(). */
extern int lxc_strmunmap(void *addr, size_t length);
/* initialize rand with urandom */ /* initialize rand with urandom */
extern int randseed(bool); extern int randseed(bool);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment