Commit 329414e0 by Stéphane Graber Committed by GitHub

Merge pull request #1810 from brauner/2017-09-12/start_move_env_setup

start: pass LXC_LOG_LEVEL to hooks
parents dbac6c02 8bd8018e
...@@ -1446,6 +1446,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ...@@ -1446,6 +1446,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<listitem><para> LXC_CONFIG_FILE: the path to the container configuration file. </para></listitem> <listitem><para> LXC_CONFIG_FILE: the path to the container configuration file. </para></listitem>
<listitem><para> LXC_SRC_NAME: in the case of the clone hook, this is the original container's name. </para></listitem> <listitem><para> LXC_SRC_NAME: in the case of the clone hook, this is the original container's name. </para></listitem>
<listitem><para> LXC_ROOTFS_PATH: this is the lxc.rootfs.path entry for the container. Note this is likely not where the mounted rootfs is to be found, use LXC_ROOTFS_MOUNT for that. </para></listitem> <listitem><para> LXC_ROOTFS_PATH: this is the lxc.rootfs.path entry for the container. Note this is likely not where the mounted rootfs is to be found, use LXC_ROOTFS_MOUNT for that. </para></listitem>
<listitem><para> LXC_CGNS_AWARE: indicated whether the container is cgroup namespace aware. </para></listitem>
<listitem><para> LXC_LOG_LEVEL: the container's log level. </para></listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para> <para>
......
...@@ -631,6 +631,9 @@ int lxc_init(const char *name, struct lxc_handler *handler) ...@@ -631,6 +631,9 @@ int lxc_init(const char *name, struct lxc_handler *handler)
if (setenv("LXC_CGNS_AWARE", "1", 1)) if (setenv("LXC_CGNS_AWARE", "1", 1))
SYSERROR("Failed to set environment variable LXC_CGNS_AWARE=1."); SYSERROR("Failed to set environment variable LXC_CGNS_AWARE=1.");
if (setenv("LXC_LOG_LEVEL", lxc_log_priority_to_string(handler->conf->loglevel), 1))
SYSERROR("Failed to set environment variable LXC_CGNS_AWARE=1.");
/* End of environment variable setup for hooks. */ /* End of environment variable setup for hooks. */
TRACE("set environment variables"); TRACE("set environment variables");
......
...@@ -470,135 +470,105 @@ const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip) ...@@ -470,135 +470,105 @@ const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip)
return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0); return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0);
} }
extern struct lxc_popen_FILE *lxc_popen(const char *command) struct lxc_popen_FILE *lxc_popen(const char *command)
{ {
struct lxc_popen_FILE *fp = NULL; int ret;
int parent_end = -1, child_end = -1;
int pipe_fds[2]; int pipe_fds[2];
pid_t child_pid; pid_t child_pid;
struct lxc_popen_FILE *fp = NULL;
int r = pipe2(pipe_fds, O_CLOEXEC); ret = pipe2(pipe_fds, O_CLOEXEC);
if (ret < 0)
if (r < 0) {
ERROR("pipe2 failure");
return NULL; return NULL;
}
parent_end = pipe_fds[0];
child_end = pipe_fds[1];
child_pid = fork(); child_pid = fork();
if (child_pid < 0)
goto on_error;
if (child_pid == 0) { if (!child_pid) {
/* child */ sigset_t mask;
int child_std_end = STDOUT_FILENO;
close(parent_end);
if (child_end != child_std_end) { close(pipe_fds[0]);
/* dup2() doesn't dup close-on-exec flag */
dup2(child_end, child_std_end);
/* it's safe not to close child_end here /* duplicate stdout */
* as it's marked close-on-exec anyway if (pipe_fds[1] != STDOUT_FILENO)
*/ ret = dup2(pipe_fds[1], STDOUT_FILENO);
} else { else
/* ret = fcntl(pipe_fds[1], F_SETFD, 0);
* The descriptor is already the one we will use. if (ret < 0) {
* But it must not be marked close-on-exec. close(pipe_fds[1]);
* Undo the effects. exit(EXIT_FAILURE);
*/
if (fcntl(child_end, F_SETFD, 0) != 0) {
SYSERROR("Failed to remove FD_CLOEXEC from fd.");
exit(127);
}
}
/*
* Unblock signals.
* This is the main/only reason
* why we do our lousy popen() emulation.
*/
{
sigset_t mask;
sigfillset(&mask);
sigprocmask(SIG_UNBLOCK, &mask, NULL);
} }
execl("/bin/sh", "sh", "-c", command, (char *) NULL); /* duplicate stderr */
exit(127); if (pipe_fds[1] != STDERR_FILENO)
} ret = dup2(pipe_fds[1], STDERR_FILENO);
else
ret = fcntl(pipe_fds[1], F_SETFD, 0);
close(pipe_fds[1]);
if (ret < 0)
exit(EXIT_FAILURE);
/* parent */ /* unblock all signals */
ret = sigfillset(&mask);
if (ret < 0)
exit(EXIT_FAILURE);
close(child_end); ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
if (ret < 0)
exit(EXIT_FAILURE);
if (child_pid < 0) { execl("/bin/sh", "sh", "-c", command, (char *)NULL);
ERROR("fork failure"); exit(127);
goto error;
} }
fp = calloc(1, sizeof(*fp)); close(pipe_fds[1]);
if (!fp) { pipe_fds[1] = -1;
ERROR("failed to allocate memory");
goto error;
}
fp->f = fdopen(parent_end, "r"); fp = malloc(sizeof(*fp));
if (!fp->f) { if (!fp)
ERROR("fdopen failure"); goto on_error;
goto error;
}
fp->child_pid = child_pid; fp->child_pid = child_pid;
fp->pipe = pipe_fds[0];
return fp; fp->f = fdopen(pipe_fds[0], "r");
if (!fp->f)
error: goto on_error;
if (fp) { return fp;
if (fp->f) {
fclose(fp->f);
parent_end = -1; /* so we do not close it second time */
}
on_error:
if (fp)
free(fp); free(fp);
}
if (parent_end != -1) if (pipe_fds[0] >= 0)
close(parent_end); close(pipe_fds[0]);
if (pipe_fds[1] >= 0)
close(pipe_fds[1]);
return NULL; return NULL;
} }
extern int lxc_pclose(struct lxc_popen_FILE *fp) int lxc_pclose(struct lxc_popen_FILE *fp)
{ {
FILE *f = NULL;
pid_t child_pid = 0;
int wstatus = 0;
pid_t wait_pid; pid_t wait_pid;
int wstatus = 0;
if (fp) { if (!fp)
f = fp->f;
child_pid = fp->child_pid;
/* free memory (we still need to close file stream) */
free(fp);
fp = NULL;
}
if (!f || fclose(f)) {
ERROR("fclose failure");
return -1; return -1;
}
do { do {
wait_pid = waitpid(child_pid, &wstatus, 0); wait_pid = waitpid(fp->child_pid, &wstatus, 0);
} while (wait_pid == -1 && errno == EINTR); } while (wait_pid < 0 && errno == EINTR);
if (wait_pid == -1) { close(fp->pipe);
ERROR("waitpid failure"); fclose(fp->f);
free(fp);
if (wait_pid < 0)
return -1; return -1;
}
return wstatus; return wstatus;
} }
......
...@@ -190,6 +190,7 @@ static inline int signalfd(int fd, const sigset_t *mask, int flags) ...@@ -190,6 +190,7 @@ static inline int signalfd(int fd, const sigset_t *mask, int flags)
* without additional wrappers. * without additional wrappers.
*/ */
struct lxc_popen_FILE { struct lxc_popen_FILE {
int pipe;
FILE *f; FILE *f;
pid_t child_pid; pid_t child_pid;
}; };
......
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