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
ba2be1a8
Unverified
Commit
ba2be1a8
authored
Dec 24, 2017
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
attach: move pty allocation into api
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
79bd7662
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
274 additions
and
242 deletions
+274
-242
lxc-attach.sgml.in
doc/lxc-attach.sgml.in
+0
-17
attach.c
src/lxc/attach.c
+192
-35
attach_options.h
src/lxc/attach_options.h
+1
-0
lxc_attach.c
src/lxc/tools/lxc_attach.c
+27
-168
attach.c
src/tests/attach.c
+54
-11
lxc-test-lxc-attach
src/tests/lxc-test-lxc-attach
+0
-11
No files found.
doc/lxc-attach.sgml.in
View file @
ba2be1a8
...
...
@@ -58,7 +58,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<arg choice="opt">-R, --remount-sys-proc</arg>
<arg choice="opt">--keep-env</arg>
<arg choice="opt">--clear-env</arg>
<arg choice="opt">-L, --pty-log <replaceable>file</replaceable></arg>
<arg choice="opt">-v, --set-var <replaceable>variable</replaceable></arg>
<arg choice="opt">--keep-var <replaceable>variable</replaceable></arg>
<arg choice="opt">-- <replaceable>command</replaceable></arg>
...
...
@@ -258,22 +257,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<varlistentry>
<term>
<option>-L, --pty-log <replaceable>file</replaceable></option>
</term>
<listitem>
<para>
Specify a file where the output of <command>lxc-attach</command> will be
logged.
</para>
<para>
<emphasis>Important:</emphasis> When a standard file descriptor
does not refer to a pty output produced on it will not be logged.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-v, --set-var <replaceable>variable</replaceable></option>
</term>
<listitem>
...
...
src/lxc/attach.c
View file @
ba2be1a8
This diff is collapsed.
Click to expand it.
src/lxc/attach_options.h
View file @
ba2be1a8
...
...
@@ -51,6 +51,7 @@ enum {
LXC_ATTACH_LSM_NOW
=
0x00020000
,
/*!< FIXME: unknown */
/* Set PR_SET_NO_NEW_PRIVS to block execve() gainable privileges. */
LXC_ATTACH_NO_NEW_PRIVS
=
0x00040000
,
/*!< PR_SET_NO_NEW_PRIVS */
LXC_ATTACH_ALLOCATE_PTY
=
0x00080000
,
/*!< Allocate new pty for attached process. */
/* We have 16 bits for things that are on by default and 16 bits that
* are off by default, that should be sufficient to keep binary
...
...
src/lxc/tools/lxc_attach.c
View file @
ba2be1a8
...
...
@@ -27,11 +27,12 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <lxc/lxccontainer.h>
...
...
@@ -46,12 +47,6 @@
#include "mainloop.h"
#include "utils.h"
#if HAVE_PTY_H
#include <pty.h>
#else
#include <../include/openpty.h>
#endif
static
const
struct
option
my_longopts
[]
=
{
{
"elevated-privileges"
,
optional_argument
,
0
,
'e'
},
{
"arch"
,
required_argument
,
0
,
'a'
},
...
...
@@ -241,155 +236,29 @@ Options :\n\
.
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
)
static
bool
stdfd_is_pty
(
void
)
{
struct
wrapargs
*
wrap
=
p
;
close
(
wrap
->
console
->
master
);
if
(
login_pty
(
wrap
->
console
->
slave
)
<
0
)
return
-
1
;
if
(
isatty
(
STDIN_FILENO
))
return
true
;
if
(
isatty
(
STDOUT_FILENO
))
return
true
;
if
(
isatty
(
STDERR_FILENO
))
return
true
;
if
(
wrap
->
command
->
program
)
lxc_attach_run_command
(
wrap
->
command
);
else
lxc_attach_run_shell
(
NULL
);
return
-
1
;
return
false
;
}
static
int
get_pty_on_host
(
struct
lxc_container
*
c
,
struct
wrapargs
*
wrap
,
int
*
pid
)
int
lxc_attach_create_log_file
(
const
char
*
log_file
)
{
struct
lxc_epoll_descr
descr
;
struct
lxc_conf
*
conf
;
struct
lxc_tty_state
*
ts
;
int
ret
=
-
1
;
struct
wrapargs
*
args
=
wrap
;
if
(
!
isatty
(
args
->
ptyfd
))
{
fprintf
(
stderr
,
"Standard file descriptor does not refer to a pty
\n
"
);
return
-
1
;
}
if
(
c
->
lxc_conf
)
{
conf
=
c
->
lxc_conf
;
}
else
{
/* If the container is not defined and the user didn't specify a
* config file to load we will simply init a dummy config here.
*/
conf
=
lxc_conf_init
();
if
(
!
conf
)
{
fprintf
(
stderr
,
"Failed to allocate dummy config file for the container
\n
"
);
return
-
1
;
}
int
fd
;
/* We also need a dummy rootfs path otherwise
* lxc_console_create() will not let us create a console. Note,
* I don't want this change to make it into
* lxc_console_create()'s since this function will only be
* responsible for proper /dev/{console,tty<n>} devices.
* lxc-attach is just abusing it to also handle the pty case
* because it is very similar. However, with LXC 3.0 lxc-attach
* will need to move away from using lxc_console_create() since
* this is actually an internal symbol and we only want the
* tools to use the API with LXC 3.0.
*/
conf
->
rootfs
.
path
=
strdup
(
"dummy"
);
if
(
!
conf
->
rootfs
.
path
)
return
-
1
;
}
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 NULL. lxc_console_peer_default()
* will then try to open /dev/tty. If the process doesn't have a
* controlling terminal we should still proceed.
*/
free
(
conf
->
console
.
path
);
conf
->
console
.
path
=
NULL
;
/* Create pty on the host. */
if
(
lxc_console_create
(
conf
)
<
0
)
fd
=
open
(
log_file
,
O_CLOEXEC
|
O_RDWR
|
O_CREAT
|
O_APPEND
,
0600
);
if
(
fd
<
0
)
{
fprintf
(
stderr
,
"Failed to open log file
\"
%s
\"\n
"
,
log_file
);
return
-
1
;
ts
=
conf
->
console
.
tty_state
;
conf
->
console
.
descr
=
&
descr
;
/* Shift ttys to container. */
ret
=
lxc_pty_map_ids
(
conf
,
&
conf
->
console
);
if
(
ret
<
0
)
{
fprintf
(
stderr
,
"Failed to shift tty into container
\n
"
);
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. */
conf
->
console
.
slave
=
-
1
;
ret
=
lxc_mainloop_open
(
&
descr
);
if
(
ret
)
{
fprintf
(
stderr
,
"failed to create mainloop
\n
"
);
goto
err2
;
}
if
(
lxc_console_mainloop_add
(
&
descr
,
&
conf
->
console
)
<
0
)
{
fprintf
(
stderr
,
"Failed to add handlers to lxc mainloop.
\n
"
);
goto
err3
;
}
ret
=
lxc_mainloop
(
&
descr
,
-
1
);
if
(
ret
)
{
fprintf
(
stderr
,
"mainloop returned an error
\n
"
);
goto
err3
;
}
ret
=
0
;
err3:
lxc_mainloop_close
(
&
descr
);
err2:
if
(
ts
&&
ts
->
sigfd
!=
-
1
)
lxc_console_signal_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
;
return
fd
;
}
int
main
(
int
argc
,
char
*
argv
[])
...
...
@@ -463,6 +332,8 @@ int main(int argc, char *argv[])
attach_options
.
attach_flags
|=
LXC_ATTACH_REMOUNT_PROC_SYS
;
if
(
elevated_privileges
)
attach_options
.
attach_flags
&=
~
(
elevated_privileges
);
if
(
stdfd_is_pty
())
attach_options
.
attach_flags
|=
LXC_ATTACH_ALLOCATE_PTY
;
attach_options
.
namespaces
=
namespace_flags
;
attach_options
.
personality
=
new_personality
;
attach_options
.
env_policy
=
env_policy
;
...
...
@@ -474,29 +345,17 @@ int main(int argc, char *argv[])
command
.
argv
=
(
char
**
)
my_args
.
argv
;
}
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
{
if
(
my_args
.
console_log
)
{
fprintf
(
stderr
,
"-L/--pty-log can only be used when stdout and stderr refer to a pty.
\n
"
);
if
(
my_args
.
console_log
)
{
attach_options
.
log_fd
=
lxc_attach_create_log_file
(
my_args
.
console_log
);
if
(
attach_options
.
log_fd
<
0
)
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
(
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
)
goto
out
;
...
...
src/tests/attach.c
View file @
ba2be1a8
...
...
@@ -19,16 +19,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <lxc/lxccontainer.h>
#include "lxc/utils.h"
#include "lxc/lsm/lsm.h"
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <errno.h>
#include <sys/types.h>
#include "lxctest.h"
#include "utils.h"
#include "lsm/lsm.h"
#include <lxc/lxccontainer.h>
#define TSTNAME "lxc-attach-test"
#define TSTOUT(fmt, ...) do { \
...
...
@@ -392,19 +394,60 @@ err1:
int
main
(
int
argc
,
char
*
argv
[])
{
int
ret
;
int
i
,
ret
;
struct
lxc_log
log
;
char
template
[
sizeof
(
P_tmpdir
"/attach_XXXXXX"
)];
int
fret
=
EXIT_FAILURE
;
strcpy
(
template
,
P_tmpdir
"/attach_XXXXXX"
);
i
=
lxc_make_tmpfile
(
template
,
false
);
if
(
i
<
0
)
{
lxc_error
(
"Failed to create temporary log file for container %s
\n
"
,
TSTNAME
);
exit
(
EXIT_FAILURE
);
}
else
{
lxc_debug
(
"Using
\"
%s
\"
as temporary log file for container %s
\n
"
,
template
,
TSTNAME
);
close
(
i
);
}
log
.
name
=
TSTNAME
;
log
.
file
=
template
;
log
.
level
=
"TRACE"
;
log
.
prefix
=
"attach"
;
log
.
quiet
=
false
;
log
.
lxcpath
=
NULL
;
if
(
lxc_log_init
(
&
log
))
goto
on_error
;
test_lsm_detect
();
ret
=
test_attach
(
NULL
,
TSTNAME
,
"busybox"
);
if
(
ret
<
0
)
return
EXIT_FAILURE
;
goto
on_error
;
TSTOUT
(
"
\n
"
);
ret
=
test_attach
(
LXCPATH
"/alternate-path-test"
,
TSTNAME
,
"busybox"
);
if
(
ret
<
0
)
return
EXIT_FAILURE
;
goto
on_error
;
(
void
)
rmdir
(
LXCPATH
"/alternate-path-test"
);
TSTOUT
(
"All tests passed
\n
"
);
return
EXIT_SUCCESS
;
fret
=
EXIT_SUCCESS
;
on_error:
if
(
fret
!=
EXIT_SUCCESS
)
{
int
fd
;
fd
=
open
(
template
,
O_RDONLY
);
if
(
fd
>=
0
)
{
char
buf
[
4096
];
ssize_t
buflen
;
while
((
buflen
=
read
(
fd
,
buf
,
1024
))
>
0
)
{
buflen
=
write
(
STDERR_FILENO
,
buf
,
buflen
);
if
(
buflen
<=
0
)
break
;
}
close
(
fd
);
}
}
(
void
)
rmdir
(
LXCPATH
"/alternate-path-test"
);
(
void
)
unlink
(
template
);
exit
(
fret
);
}
src/tests/lxc-test-lxc-attach
View file @
ba2be1a8
...
...
@@ -190,17 +190,6 @@ fi
rm
-f
$out
$err
if
[
$allocate_pty
=
"pty"
]
;
then
# Test whether logging pty output to a file works.
trap
"rm -f /tmp/ptylog"
EXIT INT QUIT PIPE
lxc-attach
-n
busy
-L
/tmp/ptylog
--
hostname
||
FAIL
"to allocate or setup pty"
if
[
!
-s
/tmp/ptylog
]
;
then
FAIL
"lxc-attach -n busy -L /tmp/ptylog -- hostname"
fi
rm
-f
/tmp/ptylog
fi
lxc-destroy
-n
busy
-f
exit
0
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