* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <sys/types.h>
-#include <sys/stat.h>
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
#include <errno.h>
-#include <unistd.h>
+#include <stdio.h>
#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "conf.h"
+#include "config.h"
#include "log.h"
#include "start.h"
+#include "raw_syscalls.h"
#include "utils.h"
-lxc_log_define(lxc_execute, lxc_start);
+lxc_log_define(execute, start);
static int execute_start(struct lxc_handler *handler, void* data)
{
- int j, i = 0;
- struct execute_args *my_args = data;
+ int argc_add, j;
char **argv;
- int argc = 0, argc_add;
+ int argc = 0, i = 0, logfd = -1;
+ struct execute_args *my_args = data;
+ char logfile[LXC_PROC_PID_FD_LEN];
+ bool is_privileged = lxc_list_empty(&handler->conf->id_map);
while (my_args->argv[argc++]);
argc_add = 5;
if (my_args->quiet)
argc_add++;
+
if (!handler->conf->rootfs.path)
argc_add += 2;
- if (lxc_log_has_valid_level())
- argc_add += 2;
+
+ if (is_privileged) {
+ if (lxc_log_has_valid_level())
+ argc_add += 2;
+
+ if (current_config->logfd != -1 || lxc_log_fd != -1)
+ argc_add += 2;
+ }
argv = malloc((argc + argc_add) * sizeof(*argv));
- if (!argv)
+ if (!argv) {
+ SYSERROR("Allocating init args failed");
goto out1;
+ }
- if (!my_args->init_path)
- goto out2;
-
- argv[i++] = my_args->init_path;
+ if (my_args->init_path)
+ argv[i++] = my_args->init_path;
+ else
+ argv[i++] = "lxc-init";
argv[i++] = "-n";
argv[i++] = (char *)handler->name;
argv[i++] = (char *)lxc_log_priority_to_string(lxc_log_get_level());
}
- if (handler->conf->logfile) {
+ if (is_privileged && (current_config->logfd != -1 || lxc_log_fd != -1)) {
+ int ret;
+ int to_dup = current_config->logfd;
+
+ if (current_config->logfd == -1)
+ to_dup = lxc_log_fd;
+
+ logfd = dup(to_dup);
+ if (logfd < 0) {
+ SYSERROR("Failed to duplicate log file descriptor");
+ goto out2;
+ }
+
+ ret = snprintf(logfile, sizeof(logfile), "/proc/self/fd/%d", logfd);
+ if (ret < 0 || (size_t)ret >= sizeof(logfile))
+ goto out3;
+
argv[i++] = "-o";
- argv[i++] = (char *)handler->conf->logfile;
+ argv[i++] = logfile;
}
if (my_args->quiet)
NOTICE("Exec'ing \"%s\"", my_args->argv[0]);
- execvp(argv[0], argv);
+ if (my_args->init_fd >= 0)
+ lxc_raw_execveat(my_args->init_fd, "", argv, environ, AT_EMPTY_PATH);
+ else
+ execvp(argv[0], argv);
SYSERROR("Failed to exec %s", argv[0]);
+out3:
+ close(logfd);
out2:
free(argv);
out1:
int lxc_execute(const char *name, char *const argv[], int quiet,
struct lxc_handler *handler, const char *lxcpath,
- bool backgrounded, int *error_num)
+ bool daemonize, int *error_num)
{
struct execute_args args = {.argv = argv, .quiet = quiet};
- if (lxc_check_inherited(handler->conf, false, &handler->conf->maincmd_fd, 1))
- return -1;
-
- handler->conf->is_execute = 1;
+ TRACE("Doing lxc_execute");
+ handler->conf->is_execute = true;
return __lxc_start(name, handler, &execute_start_ops, &args, lxcpath,
- backgrounded, error_num);
+ daemonize, error_num);
}