Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
3196b9ac
Commit
3196b9ac
authored
Apr 04, 2017
by
Stéphane Graber
Committed by
GitHub
Apr 04, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1386 from brauner/2017-01-16/fix_CVE-2016-10124_stable-1.0
stable-1.0: backport fixes for CVE-2016-10124
parents
b2ed6cc2
6aae6d02
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
431 additions
and
36 deletions
+431
-36
console.c
src/lxc/console.c
+0
-0
console.h
src/lxc/console.h
+178
-4
lxc_attach.c
src/lxc/lxc_attach.c
+250
-29
start.c
src/lxc/start.c
+3
-3
No files found.
src/lxc/console.c
View file @
3196b9ac
This diff is collapsed.
Click to expand it.
src/lxc/console.h
View file @
3196b9ac
...
@@ -24,21 +24,195 @@
...
@@ -24,21 +24,195 @@
#ifndef __LXC_CONSOLE_H
#ifndef __LXC_CONSOLE_H
#define __LXC_CONSOLE_H
#define __LXC_CONSOLE_H
struct
lxc_epoll_descr
;
#include "conf.h"
struct
lxc_container
;
#include "list.h"
struct
lxc_epoll_descr
;
/* defined in mainloop.h */
struct
lxc_container
;
/* defined in lxccontainer.h */
struct
lxc_tty_state
{
struct
lxc_list
node
;
int
stdinfd
;
int
stdoutfd
;
int
masterfd
;
/* Escape sequence to use for exiting the pty. A single char can be
* specified. The pty can then exited by doing: Ctrl + specified_char + q.
* This field is checked by lxc_console_cb_tty_stdin(). Set to -1 to
* disable exiting the pty via a escape sequence. */
int
escape
;
/* Used internally by lxc_console_cb_tty_stdin() to check whether an
* escape sequence has been received. */
int
saw_escape
;
/* Name of the container to forward the SIGWINCH event to. */
const
char
*
winch_proxy
;
/* Path of the container to forward the SIGWINCH event to. */
const
char
*
winch_proxy_lxcpath
;
/* File descriptor that accepts SIGWINCH signals. If set to -1 no
* SIGWINCH handler could be installed. This also means that
* the sigset_t oldmask member is meaningless. */
int
sigfd
;
sigset_t
oldmask
;
};
/*
* lxc_console_allocate: allocate the console or a tty
*
* @conf : the configuration of the container to allocate from
* @sockfd : the socket fd whose remote side when closed, will be an
* indication that the console or tty is no longer in use
* @ttyreq : the tty requested to be opened, -1 for any, 0 for the console
*/
extern
int
lxc_console_allocate
(
struct
lxc_conf
*
conf
,
int
sockfd
,
int
*
ttynum
);
extern
int
lxc_console_allocate
(
struct
lxc_conf
*
conf
,
int
sockfd
,
int
*
ttynum
);
/*
* Create a new pty:
* - calls openpty() to allocate a master/slave pty pair
* - sets the FD_CLOEXEC flag on the master/slave fds
* - allocates either the current controlling pty (default) or a user specified
* pty as peer pty for the newly created master/slave pair
* - sets up SIGWINCH handler, winsz, and new terminal settings
* (Handlers for SIGWINCH and I/O are not registered in a mainloop.)
* (For an unprivileged container the created pty on the host is not
* automatically chowned to the uid/gid of the unprivileged user. For this
* ttys_shift_ids() can be called.)
*/
extern
int
lxc_console_create
(
struct
lxc_conf
*
);
extern
int
lxc_console_create
(
struct
lxc_conf
*
);
/*
* Delete a pty created via lxc_console_create():
* - set old terminal settings
* - memory allocated via lxc_console_create() is free()ed.
* - close master/slave pty pair and allocated fd for the peer (usually
* /dev/tty)
* Registered handlers in a mainloop are not automatically deleted.
*/
extern
void
lxc_console_delete
(
struct
lxc_console
*
);
extern
void
lxc_console_delete
(
struct
lxc_console
*
);
/*
* lxc_console_free: mark the console or a tty as unallocated, free any
* resources allocated by lxc_console_allocate().
*
* @conf : the configuration of the container whose tty was closed
* @fd : the socket fd whose remote side was closed, which indicated
* the console or tty is no longer in use. this is used to match
* which console/tty is being freed.
*/
extern
void
lxc_console_free
(
struct
lxc_conf
*
conf
,
int
fd
);
extern
void
lxc_console_free
(
struct
lxc_conf
*
conf
,
int
fd
);
extern
int
lxc_console_mainloop_add
(
struct
lxc_epoll_descr
*
,
struct
lxc_handler
*
);
/*
* Register pty event handlers in an open mainloop
*/
extern
int
lxc_console_mainloop_add
(
struct
lxc_epoll_descr
*
,
struct
lxc_conf
*
);
/*
* Handle SIGWINCH events on the allocated ptys.
*/
extern
void
lxc_console_sigwinch
(
int
sig
);
extern
void
lxc_console_sigwinch
(
int
sig
);
/*
* Connect to one of the ptys given to the container via lxc.tty.
* - allocates either the current controlling pty (default) or a user specified
* pty as peer pty for the containers tty
* - sets up SIGWINCH handler, winsz, and new terminal settings
* - opens mainloop
* - registers SIGWINCH, I/O handlers in the mainloop
* - performs all necessary cleanup operations
*/
extern
int
lxc_console
(
struct
lxc_container
*
c
,
int
ttynum
,
extern
int
lxc_console
(
struct
lxc_container
*
c
,
int
ttynum
,
int
stdinfd
,
int
stdoutfd
,
int
stderrfd
,
int
stdinfd
,
int
stdoutfd
,
int
stderrfd
,
int
escape
);
int
escape
);
/*
* Allocate one of the ptys given to the container via lxc.tty. Returns an open
* fd to the allocated pty.
* Set ttynum to -1 to allocate the first available pty, or to a value within
* the range specified by lxc.tty to allocate a specific pty.
*/
extern
int
lxc_console_getfd
(
struct
lxc_container
*
c
,
int
*
ttynum
,
extern
int
lxc_console_getfd
(
struct
lxc_container
*
c
,
int
*
ttynum
,
int
*
masterfd
);
int
*
masterfd
);
extern
int
lxc_console_set_stdfds
(
struct
lxc_handler
*
);
/*
* Make fd a duplicate of the standard file descriptors:
* fd is made a duplicate of a specific standard file descriptor iff the
* standard file descriptor refers to a pty.
*/
extern
int
lxc_console_set_stdfds
(
int
fd
);
/*
* Handler for events on the stdin fd of the pty. To be registered via the
* corresponding functions declared and defined in mainloop.{c,h} or
* lxc_console_mainloop_add().
* This function exits the loop cleanly when an EPOLLHUP event is received.
*/
extern
int
lxc_console_cb_tty_stdin
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
);
/*
* Handler for events on the master fd of the pty. To be registered via the
* corresponding functions declared and defined in mainloop.{c,h} or
* lxc_console_mainloop_add().
* This function exits the loop cleanly when an EPOLLHUP event is received.
*/
extern
int
lxc_console_cb_tty_master
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
);
/*
* Setup new terminal properties. The old terminal settings are stored in
* oldtios.
*/
extern
int
lxc_setup_tios
(
int
fd
,
struct
termios
*
oldtios
);
/*
* lxc_console_winsz: propagte winsz from one terminal to another
*
* @srcfd : terminal to get size from (typically a slave pty)
* @dstfd : terminal to set size on (typically a master pty)
*/
extern
void
lxc_console_winsz
(
int
srcfd
,
int
dstfd
);
/*
* lxc_console_sigwinch_init: install SIGWINCH handler
*
* @srcfd : src for winsz in SIGWINCH handler
* @dstfd : dst for winsz in SIGWINCH handler
*
* Returns lxc_tty_state structure on success or NULL on failure. The sigfd
* member of the returned lxc_tty_state can be select()/poll()ed/epoll()ed
* on (ie added to a mainloop) for SIGWINCH.
*
* Must be called with process_lock held to protect the lxc_ttys list, or
* from a non-threaded context.
*
* Note that SIGWINCH isn't installed as a classic asychronous handler,
* rather signalfd(2) is used so that we can handle the signal when we're
* ready for it. This avoids deadlocks since a signal handler
* (ie lxc_console_sigwinch()) would need to take the thread mutex to
* prevent lxc_ttys list corruption, but using the fd we can provide the
* tty_state needed to the callback (lxc_console_cb_sigwinch_fd()).
*
* This function allocates memory. It is up to the caller to free it.
*/
extern
struct
lxc_tty_state
*
lxc_console_sigwinch_init
(
int
srcfd
,
int
dstfd
);
/*
* Handler for SIGWINCH events. To be registered via the corresponding functions
* declared and defined in mainloop.{c,h} or lxc_console_mainloop_add().
*/
extern
int
lxc_console_cb_sigwinch_fd
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
);
/*
* lxc_console_sigwinch_fini: uninstall SIGWINCH handler
*
* @ts : the lxc_tty_state returned by lxc_console_sigwinch_init
*
* Restore the saved signal handler that was in effect at the time
* lxc_console_sigwinch_init() was called.
*
* Must be called with process_lock held to protect the lxc_ttys list, or
* from a non-threaded context.
*/
extern
void
lxc_console_sigwinch_fini
(
struct
lxc_tty_state
*
ts
);
#endif
#endif
src/lxc/lxc_attach.c
View file @
3196b9ac
...
@@ -21,21 +21,36 @@
...
@@ -21,21 +21,36 @@
* 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
#include "config.h"
#include <assert.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <lxc/lxccontainer.h>
#include "attach.h"
#include "attach.h"
#include "arguments.h"
#include "arguments.h"
#include "config.h"
#include "confile.h"
#include "namespace.h"
#include "caps.h"
#include "caps.h"
#include "confile.h"
#include "console.h"
#include "log.h"
#include "log.h"
#include "list.h"
#include "mainloop.h"
#include "utils.h"
#include "utils.h"
#if HAVE_PTY_H
#include <pty.h>
#else
#include <../include/openpty.h>
#endif
lxc_log_define
(
lxc_attach_ui
,
lxc
);
lxc_log_define
(
lxc_attach_ui
,
lxc
);
static
const
struct
option
my_longopts
[]
=
{
static
const
struct
option
my_longopts
[]
=
{
...
@@ -48,6 +63,8 @@ static const struct option my_longopts[] = {
...
@@ -48,6 +63,8 @@ static const struct option my_longopts[] = {
{
"keep-env"
,
no_argument
,
0
,
501
},
{
"keep-env"
,
no_argument
,
0
,
501
},
{
"keep-var"
,
required_argument
,
0
,
502
},
{
"keep-var"
,
required_argument
,
0
,
502
},
{
"set-var"
,
required_argument
,
0
,
'v'
},
{
"set-var"
,
required_argument
,
0
,
'v'
},
{
"pty-log"
,
required_argument
,
0
,
'L'
},
{
"rcfile"
,
required_argument
,
0
,
'f'
},
LXC_COMMON_OPTIONS
LXC_COMMON_OPTIONS
};
};
...
@@ -65,7 +82,8 @@ static int add_to_simple_array(char ***array, ssize_t *capacity, char *value)
...
@@ -65,7 +82,8 @@ static int add_to_simple_array(char ***array, ssize_t *capacity, char *value)
{
{
ssize_t
count
=
0
;
ssize_t
count
=
0
;
assert
(
array
);
if
(
!
array
)
return
-
1
;
if
(
*
array
)
if
(
*
array
)
for
(;
(
*
array
)[
count
];
count
++
);
for
(;
(
*
array
)[
count
];
count
++
);
...
@@ -81,7 +99,8 @@ static int add_to_simple_array(char ***array, ssize_t *capacity, char *value)
...
@@ -81,7 +99,8 @@ static int add_to_simple_array(char ***array, ssize_t *capacity, char *value)
*
capacity
=
new_capacity
;
*
capacity
=
new_capacity
;
}
}
assert
(
*
array
);
if
(
!
(
*
array
))
return
-
1
;
(
*
array
)[
count
]
=
value
;
(
*
array
)[
count
]
=
value
;
return
0
;
return
0
;
...
@@ -133,6 +152,12 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg)
...
@@ -133,6 +152,12 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg)
return
-
1
;
return
-
1
;
}
}
break
;
break
;
case
'L'
:
args
->
console_log
=
arg
;
break
;
case
'f'
:
args
->
rcfile
=
arg
;
break
;
}
}
return
0
;
return
0
;
...
@@ -175,41 +200,214 @@ Options :\n\
...
@@ -175,41 +200,214 @@ Options :\n\
--keep-env Keep all current environment variables. This
\n
\
--keep-env Keep all current environment variables. This
\n
\
is the current default behaviour, but is likely to
\n
\
is the current default behaviour, but is likely to
\n
\
change in the future.
\n
\
change in the future.
\n
\
-L, --pty-log=FILE
\n
\
Log pty output to FILE
\n
\
-v, --set-var Set an additional variable that is seen by the
\n
\
-v, --set-var Set an additional variable that is seen by the
\n
\
attached program in the container. May be specified
\n
\
attached program in the container. May be specified
\n
\
multiple times.
\n
\
multiple times.
\n
\
--keep-var Keep an additional environment variable. Only
\n
\
--keep-var Keep an additional environment variable. Only
\n
\
applicable if --clear-env is specified. May be used
\n
\
applicable if --clear-env is specified. May be used
\n
\
multiple times.
\n
"
,
multiple times.
\n
\
-f, --rcfile=FILE
\n
\
Load configuration file FILE
\n
\
"
,
.
options
=
my_longopts
,
.
options
=
my_longopts
,
.
parser
=
my_parser
,
.
parser
=
my_parser
,
.
checker
=
NULL
,
.
checker
=
NULL
,
};
};
struct
wrapargs
{
lxc_attach_options_t
*
options
;
lxc_attach_command_t
*
command
;
struct
lxc_console
*
console
;
int
ptyfd
;
};
/* Minimalistic login_tty() implementation. */
static
int
login_pty
(
int
fd
)
{
setsid
();
if
(
ioctl
(
fd
,
TIOCSCTTY
,
NULL
)
<
0
)
return
-
1
;
if
(
lxc_console_set_stdfds
(
fd
)
<
0
)
return
-
1
;
if
(
fd
>
STDERR_FILENO
)
close
(
fd
);
return
0
;
}
static
int
get_pty_on_host_callback
(
void
*
p
)
{
struct
wrapargs
*
wrap
=
p
;
close
(
wrap
->
console
->
master
);
if
(
login_pty
(
wrap
->
console
->
slave
)
<
0
)
return
-
1
;
if
(
wrap
->
command
->
program
)
lxc_attach_run_command
(
wrap
->
command
);
else
lxc_attach_run_shell
(
NULL
);
return
-
1
;
}
static
int
get_pty_on_host
(
struct
lxc_container
*
c
,
struct
wrapargs
*
wrap
,
int
*
pid
)
{
int
ret
=
-
1
;
struct
wrapargs
*
args
=
wrap
;
struct
lxc_epoll_descr
descr
;
struct
lxc_conf
*
conf
;
struct
lxc_tty_state
*
ts
;
INFO
(
"Trying to allocate a pty on the host"
);
if
(
!
isatty
(
args
->
ptyfd
))
{
ERROR
(
"Standard file descriptor does not refer to a pty
\n
."
);
return
-
1
;
}
conf
=
c
->
lxc_conf
;
free
(
conf
->
console
.
log_path
);
if
(
my_args
.
console_log
)
conf
->
console
.
log_path
=
strdup
(
my_args
.
console_log
);
else
conf
->
console
.
log_path
=
NULL
;
/* In the case of lxc-attach our peer pty will always be the current
* controlling terminal. We clear whatever was set by the user for
* lxc.console.path here and set it to "/dev/tty". Doing this will (a)
* prevent segfaults when the container has been setup with
* lxc.console = none and (b) provide an easy way to ensure that we
* always do the correct thing. strdup() must be used since console.path
* is free()ed when we call lxc_container_put(). */
free
(
conf
->
console
.
path
);
conf
->
console
.
path
=
strdup
(
"/dev/tty"
);
if
(
!
conf
->
console
.
path
)
return
-
1
;
/* Create pty on the host. */
if
(
lxc_console_create
(
conf
)
<
0
)
return
-
1
;
ts
=
conf
->
console
.
tty_state
;
conf
->
console
.
descr
=
&
descr
;
/* Shift ttys to container. */
if
(
ttys_shift_ids
(
conf
)
<
0
)
{
ERROR
(
"Failed to shift tty into container"
);
goto
err1
;
}
/* Send wrapper function on its way. */
wrap
->
console
=
&
conf
->
console
;
if
(
c
->
attach
(
c
,
get_pty_on_host_callback
,
wrap
,
wrap
->
options
,
pid
)
<
0
)
goto
err1
;
close
(
conf
->
console
.
slave
);
/* Close slave side. */
ret
=
lxc_mainloop_open
(
&
descr
);
if
(
ret
)
{
ERROR
(
"failed to create mainloop"
);
goto
err2
;
}
if
(
lxc_console_mainloop_add
(
&
descr
,
conf
)
<
0
)
{
ERROR
(
"Failed to add handlers to lxc mainloop."
);
goto
err3
;
}
ret
=
lxc_mainloop
(
&
descr
,
-
1
);
if
(
ret
)
{
ERROR
(
"mainloop returned an error"
);
goto
err3
;
}
ret
=
0
;
err3:
lxc_mainloop_close
(
&
descr
);
err2:
if
(
ts
&&
ts
->
sigfd
!=
-
1
)
lxc_console_sigwinch_fini
(
ts
);
err1:
lxc_console_delete
(
&
conf
->
console
);
return
ret
;
}
static
int
stdfd_is_pty
(
void
)
{
if
(
isatty
(
STDIN_FILENO
))
return
STDIN_FILENO
;
if
(
isatty
(
STDOUT_FILENO
))
return
STDOUT_FILENO
;
if
(
isatty
(
STDERR_FILENO
))
return
STDERR_FILENO
;
return
-
1
;
}
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
int
ret
;
int
ret
=
-
1
,
r
;
int
wexit
=
0
;
pid_t
pid
;
pid_t
pid
;
lxc_attach_options_t
attach_options
=
LXC_ATTACH_OPTIONS_DEFAULT
;
lxc_attach_options_t
attach_options
=
LXC_ATTACH_OPTIONS_DEFAULT
;
lxc_attach_command_t
command
;
lxc_attach_command_t
command
=
(
lxc_attach_command_t
){.
program
=
NULL
}
;
r
et
=
lxc_caps_init
();
r
=
lxc_caps_init
();
if
(
r
et
)
if
(
r
)
return
1
;
exit
(
EXIT_FAILURE
)
;
r
et
=
lxc_arguments_parse
(
&
my_args
,
argc
,
argv
);
r
=
lxc_arguments_parse
(
&
my_args
,
argc
,
argv
);
if
(
r
et
)
if
(
r
)
return
1
;
exit
(
EXIT_FAILURE
)
;
if
(
!
my_args
.
log_file
)
if
(
!
my_args
.
log_file
)
my_args
.
log_file
=
"none"
;
my_args
.
log_file
=
"none"
;
r
et
=
lxc_log_init
(
my_args
.
name
,
my_args
.
log_file
,
my_args
.
log_priority
,
r
=
lxc_log_init
(
my_args
.
name
,
my_args
.
log_file
,
my_args
.
log_priority
,
my_args
.
progname
,
my_args
.
quiet
,
my_args
.
lxcpath
[
0
]);
my_args
.
progname
,
my_args
.
quiet
,
my_args
.
lxcpath
[
0
]);
if
(
r
et
)
if
(
r
)
return
1
;
exit
(
EXIT_FAILURE
)
;
lxc_log_options_no_override
();
lxc_log_options_no_override
();
if
(
geteuid
())
{
if
(
access
(
my_args
.
lxcpath
[
0
],
O_RDONLY
)
<
0
)
{
if
(
!
my_args
.
quiet
)
fprintf
(
stderr
,
"You lack access to %s
\n
"
,
my_args
.
lxcpath
[
0
]);
exit
(
EXIT_FAILURE
);
}
}
struct
lxc_container
*
c
=
lxc_container_new
(
my_args
.
name
,
my_args
.
lxcpath
[
0
]);
if
(
!
c
)
exit
(
EXIT_FAILURE
);
if
(
my_args
.
rcfile
)
{
c
->
clear_config
(
c
);
if
(
!
c
->
load_config
(
c
,
my_args
.
rcfile
))
{
ERROR
(
"Failed to load rcfile"
);
lxc_container_put
(
c
);
exit
(
EXIT_FAILURE
);
}
c
->
configfile
=
strdup
(
my_args
.
rcfile
);
if
(
!
c
->
configfile
)
{
ERROR
(
"Out of memory setting new config filename"
);
lxc_container_put
(
c
);
exit
(
EXIT_FAILURE
);
}
}
if
(
!
c
->
may_control
(
c
))
{
fprintf
(
stderr
,
"Insufficent privileges to control %s
\n
"
,
c
->
name
);
lxc_container_put
(
c
);
exit
(
EXIT_FAILURE
);
}
if
(
!
c
->
is_defined
(
c
))
{
fprintf
(
stderr
,
"Error: container %s is not defined
\n
"
,
c
->
name
);
lxc_container_put
(
c
);
exit
(
EXIT_FAILURE
);
}
if
(
remount_sys_proc
)
if
(
remount_sys_proc
)
attach_options
.
attach_flags
|=
LXC_ATTACH_REMOUNT_PROC_SYS
;
attach_options
.
attach_flags
|=
LXC_ATTACH_REMOUNT_PROC_SYS
;
if
(
elevated_privileges
)
if
(
elevated_privileges
)
...
@@ -220,23 +418,46 @@ int main(int argc, char *argv[])
...
@@ -220,23 +418,46 @@ int main(int argc, char *argv[])
attach_options
.
extra_env_vars
=
extra_env
;
attach_options
.
extra_env_vars
=
extra_env
;
attach_options
.
extra_keep_env
=
extra_keep
;
attach_options
.
extra_keep_env
=
extra_keep
;
if
(
my_args
.
argc
)
{
if
(
my_args
.
argc
>
0
)
{
command
.
program
=
my_args
.
argv
[
0
];
command
.
program
=
my_args
.
argv
[
0
];
command
.
argv
=
(
char
**
)
my_args
.
argv
;
command
.
argv
=
(
char
**
)
my_args
.
argv
;
ret
=
lxc_attach
(
my_args
.
name
,
my_args
.
lxcpath
[
0
],
lxc_attach_run_command
,
&
command
,
&
attach_options
,
&
pid
);
}
struct
wrapargs
wrap
=
(
struct
wrapargs
){
.
command
=
&
command
,
.
options
=
&
attach_options
};
wrap
.
ptyfd
=
stdfd_is_pty
();
if
(
wrap
.
ptyfd
>=
0
)
{
if
((
!
isatty
(
STDOUT_FILENO
)
||
!
isatty
(
STDERR_FILENO
))
&&
my_args
.
console_log
)
{
fprintf
(
stderr
,
"-L/--pty-log can only be used when stdout and stderr refer to a pty.
\n
"
);
goto
out
;
}
ret
=
get_pty_on_host
(
c
,
&
wrap
,
&
pid
);
}
else
{
}
else
{
ret
=
lxc_attach
(
my_args
.
name
,
my_args
.
lxcpath
[
0
],
lxc_attach_run_shell
,
NULL
,
&
attach_options
,
&
pid
);
if
(
my_args
.
console_log
)
{
fprintf
(
stderr
,
"-L/--pty-log can only be used when stdout and stderr refer to a pty.
\n
"
);
goto
out
;
}
if
(
command
.
program
)
ret
=
c
->
attach
(
c
,
lxc_attach_run_command
,
&
command
,
&
attach_options
,
&
pid
);
else
ret
=
c
->
attach
(
c
,
lxc_attach_run_shell
,
NULL
,
&
attach_options
,
&
pid
);
}
}
if
(
ret
<
0
)
if
(
ret
<
0
)
return
1
;
goto
out
;
ret
=
lxc_wait_for_pid_status
(
pid
);
ret
=
lxc_wait_for_pid_status
(
pid
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
1
;
goto
out
;
if
(
WIFEXITED
(
ret
))
if
(
WIFEXITED
(
ret
))
return
WEXITSTATUS
(
ret
);
wexit
=
WEXITSTATUS
(
ret
);
out:
return
1
;
lxc_container_put
(
c
);
if
(
ret
>=
0
)
exit
(
wexit
);
exit
(
EXIT_FAILURE
);
}
}
src/lxc/start.c
View file @
3196b9ac
...
@@ -339,7 +339,7 @@ static int lxc_poll(const char *name, struct lxc_handler *handler)
...
@@ -339,7 +339,7 @@ static int lxc_poll(const char *name, struct lxc_handler *handler)
goto
out_mainloop_open
;
goto
out_mainloop_open
;
}
}
if
(
lxc_console_mainloop_add
(
&
descr
,
handler
))
{
if
(
lxc_console_mainloop_add
(
&
descr
,
handler
->
conf
))
{
ERROR
(
"failed to add console handler to mainloop"
);
ERROR
(
"failed to add console handler to mainloop"
);
goto
out_mainloop_open
;
goto
out_mainloop_open
;
}
}
...
@@ -751,7 +751,7 @@ static int do_start(void *data)
...
@@ -751,7 +751,7 @@ static int do_start(void *data)
* setup on its console ie. the pty allocated in lxc_console_create()
* setup on its console ie. the pty allocated in lxc_console_create()
* so make sure that that pty is stdin,stdout,stderr.
* so make sure that that pty is stdin,stdout,stderr.
*/
*/
if
(
lxc_console_set_stdfds
(
handler
)
<
0
)
if
(
lxc_console_set_stdfds
(
handler
->
conf
->
console
.
slave
)
<
0
)
goto
out_warn_father
;
goto
out_warn_father
;
/* If we mounted a temporary proc, then unmount it now */
/* If we mounted a temporary proc, then unmount it now */
...
@@ -800,7 +800,7 @@ static int save_phys_nics(struct lxc_conf *conf)
...
@@ -800,7 +800,7 @@ static int save_phys_nics(struct lxc_conf *conf)
if
(
!
am_root
)
if
(
!
am_root
)
return
0
;
return
0
;
lxc_list_for_each
(
iterator
,
&
conf
->
network
)
{
lxc_list_for_each
(
iterator
,
&
conf
->
network
)
{
struct
lxc_netdev
*
netdev
=
iterator
->
elem
;
struct
lxc_netdev
*
netdev
=
iterator
->
elem
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment