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
0519b5cc
Unverified
Commit
0519b5cc
authored
Nov 12, 2017
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
console: prepare for generic signal handler
Non-functional changes to enable handling more signals. Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
af73a0bf
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
71 additions
and
50 deletions
+71
-50
console.c
src/lxc/console.c
+43
-28
console.h
src/lxc/console.h
+27
-21
lxc_attach.c
src/lxc/tools/lxc_attach.c
+1
-1
No files found.
src/lxc/console.c
View file @
0519b5cc
...
@@ -59,25 +59,39 @@ static struct lxc_list lxc_ttys;
...
@@ -59,25 +59,39 @@ static struct lxc_list lxc_ttys;
typedef
void
(
*
sighandler_t
)(
int
);
typedef
void
(
*
sighandler_t
)(
int
);
__attribute__
((
constructor
))
__attribute__
((
constructor
))
void
lxc_console_init
(
void
)
void
lxc_console_init
(
void
)
{
{
lxc_list_init
(
&
lxc_ttys
);
lxc_list_init
(
&
lxc_ttys
);
}
}
void
lxc_console_winsz
(
int
srcfd
,
int
dstfd
)
void
lxc_console_winsz
(
int
srcfd
,
int
dstfd
)
{
{
int
ret
;
struct
winsize
wsz
;
struct
winsize
wsz
;
if
(
isatty
(
srcfd
)
&&
ioctl
(
srcfd
,
TIOCGWINSZ
,
&
wsz
)
==
0
)
{
DEBUG
(
"set winsz dstfd:%d cols:%d rows:%d"
,
dstfd
,
if
(
!
isatty
(
srcfd
))
wsz
.
ws_col
,
wsz
.
ws_row
);
return
;
ioctl
(
dstfd
,
TIOCSWINSZ
,
&
wsz
);
ret
=
ioctl
(
srcfd
,
TIOCGWINSZ
,
&
wsz
);
if
(
ret
<
0
)
{
WARN
(
"Failed to get window size"
);
return
;
}
}
ret
=
ioctl
(
dstfd
,
TIOCSWINSZ
,
&
wsz
);
if
(
ret
<
0
)
WARN
(
"Failed to set window size"
);
else
DEBUG
(
"Set window size to %d columns and %d rows"
,
wsz
.
ws_col
,
wsz
.
ws_row
);
return
;
}
}
static
void
lxc_console_winch
(
struct
lxc_tty_state
*
ts
)
static
void
lxc_console_winch
(
struct
lxc_tty_state
*
ts
)
{
{
lxc_console_winsz
(
ts
->
stdinfd
,
ts
->
masterfd
);
lxc_console_winsz
(
ts
->
stdinfd
,
ts
->
masterfd
);
if
(
ts
->
winch_proxy
)
if
(
ts
->
winch_proxy
)
lxc_cmd_console_winch
(
ts
->
winch_proxy
,
ts
->
winch_proxy_lxcpath
);
lxc_cmd_console_winch
(
ts
->
winch_proxy
,
ts
->
winch_proxy_lxcpath
);
}
}
...
@@ -93,15 +107,15 @@ void lxc_console_sigwinch(int sig)
...
@@ -93,15 +107,15 @@ void lxc_console_sigwinch(int sig)
}
}
}
}
int
lxc_console_cb_sig
winch
_fd
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
int
lxc_console_cb_sig
nal
_fd
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
)
struct
lxc_epoll_descr
*
descr
)
{
{
struct
signalfd_siginfo
siginfo
;
struct
signalfd_siginfo
siginfo
;
struct
lxc_tty_state
*
ts
=
cbdata
;
struct
lxc_tty_state
*
ts
=
cbdata
;
ssize_t
ret
=
read
(
fd
,
&
siginfo
,
sizeof
(
siginfo
));
ssize_t
ret
=
read
(
fd
,
&
siginfo
,
sizeof
(
siginfo
));
if
(
ret
<
0
||
(
size_t
)
ret
<
sizeof
(
siginfo
))
{
if
(
ret
<
0
||
(
size_t
)
ret
<
sizeof
(
siginfo
))
{
ERROR
(
"
f
ailed to read signal info"
);
ERROR
(
"
F
ailed to read signal info"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -109,8 +123,9 @@ int lxc_console_cb_sigwinch_fd(int fd, uint32_t events, void *cbdata,
...
@@ -109,8 +123,9 @@ int lxc_console_cb_sigwinch_fd(int fd, uint32_t events, void *cbdata,
return
0
;
return
0
;
}
}
struct
lxc_tty_state
*
lxc_console_sig
winch
_init
(
int
srcfd
,
int
dstfd
)
struct
lxc_tty_state
*
lxc_console_sig
nal
_init
(
int
srcfd
,
int
dstfd
)
{
{
bool
istty
;
sigset_t
mask
;
sigset_t
mask
;
struct
lxc_tty_state
*
ts
;
struct
lxc_tty_state
*
ts
;
...
@@ -123,7 +138,8 @@ struct lxc_tty_state *lxc_console_sigwinch_init(int srcfd, int dstfd)
...
@@ -123,7 +138,8 @@ struct lxc_tty_state *lxc_console_sigwinch_init(int srcfd, int dstfd)
ts
->
masterfd
=
dstfd
;
ts
->
masterfd
=
dstfd
;
ts
->
sigfd
=
-
1
;
ts
->
sigfd
=
-
1
;
if
(
!
isatty
(
srcfd
))
{
istty
=
isatty
(
srcfd
)
==
1
;
if
(
!
istty
)
{
INFO
(
"fd %d does not refer to a tty device"
,
srcfd
);
INFO
(
"fd %d does not refer to a tty device"
,
srcfd
);
return
ts
;
return
ts
;
}
}
...
@@ -135,7 +151,7 @@ struct lxc_tty_state *lxc_console_sigwinch_init(int srcfd, int dstfd)
...
@@ -135,7 +151,7 @@ struct lxc_tty_state *lxc_console_sigwinch_init(int srcfd, int dstfd)
sigemptyset
(
&
mask
);
sigemptyset
(
&
mask
);
sigaddset
(
&
mask
,
SIGWINCH
);
sigaddset
(
&
mask
,
SIGWINCH
);
if
(
sigprocmask
(
SIG_BLOCK
,
&
mask
,
&
ts
->
oldmask
))
{
if
(
sigprocmask
(
SIG_BLOCK
,
&
mask
,
&
ts
->
oldmask
))
{
SYSERROR
(
"
failed to block SIGWINCH
"
);
SYSERROR
(
"
Failed to block SIGWINCH signal
"
);
ts
->
sigfd
=
-
1
;
ts
->
sigfd
=
-
1
;
lxc_list_del
(
&
ts
->
node
);
lxc_list_del
(
&
ts
->
node
);
return
ts
;
return
ts
;
...
@@ -143,18 +159,18 @@ struct lxc_tty_state *lxc_console_sigwinch_init(int srcfd, int dstfd)
...
@@ -143,18 +159,18 @@ struct lxc_tty_state *lxc_console_sigwinch_init(int srcfd, int dstfd)
ts
->
sigfd
=
signalfd
(
-
1
,
&
mask
,
0
);
ts
->
sigfd
=
signalfd
(
-
1
,
&
mask
,
0
);
if
(
ts
->
sigfd
<
0
)
{
if
(
ts
->
sigfd
<
0
)
{
SYSERROR
(
"
f
ailed to create signal fd"
);
SYSERROR
(
"
F
ailed to create signal fd"
);
sigprocmask
(
SIG_SETMASK
,
&
ts
->
oldmask
,
NULL
);
sigprocmask
(
SIG_SETMASK
,
&
ts
->
oldmask
,
NULL
);
ts
->
sigfd
=
-
1
;
ts
->
sigfd
=
-
1
;
lxc_list_del
(
&
ts
->
node
);
lxc_list_del
(
&
ts
->
node
);
return
ts
;
return
ts
;
}
}
DEBUG
(
"
process %d created signal fd %d to handle SIGWINCH events
"
,
getpid
(),
ts
->
sigfd
);
DEBUG
(
"
Process %d created signal fd %d
"
,
getpid
(),
ts
->
sigfd
);
return
ts
;
return
ts
;
}
}
void
lxc_console_sig
winch
_fini
(
struct
lxc_tty_state
*
ts
)
void
lxc_console_sig
nal
_fini
(
struct
lxc_tty_state
*
ts
)
{
{
if
(
ts
->
sigfd
>=
0
)
{
if
(
ts
->
sigfd
>=
0
)
{
close
(
ts
->
sigfd
);
close
(
ts
->
sigfd
);
...
@@ -178,7 +194,7 @@ static int lxc_console_cb_con(int fd, uint32_t events, void *data,
...
@@ -178,7 +194,7 @@ static int lxc_console_cb_con(int fd, uint32_t events, void *data,
lxc_mainloop_del_handler
(
descr
,
fd
);
lxc_mainloop_del_handler
(
descr
,
fd
);
if
(
fd
==
console
->
peer
)
{
if
(
fd
==
console
->
peer
)
{
if
(
console
->
tty_state
)
{
if
(
console
->
tty_state
)
{
lxc_console_sig
winch
_fini
(
console
->
tty_state
);
lxc_console_sig
nal
_fini
(
console
->
tty_state
);
console
->
tty_state
=
NULL
;
console
->
tty_state
=
NULL
;
}
}
console
->
peer
=
-
1
;
console
->
peer
=
-
1
;
...
@@ -225,16 +241,15 @@ static void lxc_console_mainloop_add_peer(struct lxc_console *console)
...
@@ -225,16 +241,15 @@ static void lxc_console_mainloop_add_peer(struct lxc_console *console)
if
(
console
->
peer
>=
0
)
{
if
(
console
->
peer
>=
0
)
{
if
(
lxc_mainloop_add_handler
(
console
->
descr
,
console
->
peer
,
if
(
lxc_mainloop_add_handler
(
console
->
descr
,
console
->
peer
,
lxc_console_cb_con
,
console
))
lxc_console_cb_con
,
console
))
WARN
(
"
console peer not added
to mainloop"
);
WARN
(
"
Failed to add console peer handler
to mainloop"
);
}
}
if
(
console
->
tty_state
&&
console
->
tty_state
->
sigfd
!=
-
1
)
{
if
(
console
->
tty_state
&&
console
->
tty_state
->
sigfd
!=
-
1
)
{
if
(
lxc_mainloop_add_handler
(
console
->
descr
,
if
(
lxc_mainloop_add_handler
(
console
->
descr
,
console
->
tty_state
->
sigfd
,
console
->
tty_state
->
sigfd
,
lxc_console_cb_sig
winch
_fd
,
lxc_console_cb_sig
nal
_fd
,
console
->
tty_state
))
{
console
->
tty_state
))
{
WARN
(
"failed to add to mainloop SIGWINCH handler for '%d'"
,
WARN
(
"Failed to add signal handler to mainloop"
);
console
->
tty_state
->
sigfd
);
}
}
}
}
}
}
...
@@ -321,7 +336,7 @@ int lxc_setup_tios(int fd, struct termios *oldtios)
...
@@ -321,7 +336,7 @@ int lxc_setup_tios(int fd, struct termios *oldtios)
static
void
lxc_console_peer_proxy_free
(
struct
lxc_console
*
console
)
static
void
lxc_console_peer_proxy_free
(
struct
lxc_console
*
console
)
{
{
if
(
console
->
tty_state
)
{
if
(
console
->
tty_state
)
{
lxc_console_sig
winch
_fini
(
console
->
tty_state
);
lxc_console_sig
nal
_fini
(
console
->
tty_state
);
console
->
tty_state
=
NULL
;
console
->
tty_state
=
NULL
;
}
}
close
(
console
->
peerpty
.
master
);
close
(
console
->
peerpty
.
master
);
...
@@ -367,7 +382,7 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd)
...
@@ -367,7 +382,7 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd)
if
(
lxc_setup_tios
(
console
->
peerpty
.
slave
,
&
oldtermio
)
<
0
)
if
(
lxc_setup_tios
(
console
->
peerpty
.
slave
,
&
oldtermio
)
<
0
)
goto
err1
;
goto
err1
;
ts
=
lxc_console_sig
winch
_init
(
console
->
peerpty
.
master
,
console
->
master
);
ts
=
lxc_console_sig
nal
_init
(
console
->
peerpty
.
master
,
console
->
master
);
if
(
!
ts
)
if
(
!
ts
)
goto
err1
;
goto
err1
;
...
@@ -479,10 +494,10 @@ static int lxc_console_peer_default(struct lxc_console *console)
...
@@ -479,10 +494,10 @@ static int lxc_console_peer_default(struct lxc_console *console)
goto
on_error1
;
goto
on_error1
;
}
}
ts
=
lxc_console_sig
winch
_init
(
console
->
peer
,
console
->
master
);
ts
=
lxc_console_sig
nal
_init
(
console
->
peer
,
console
->
master
);
console
->
tty_state
=
ts
;
console
->
tty_state
=
ts
;
if
(
!
ts
)
{
if
(
!
ts
)
{
WARN
(
"
unable to install SIGWINCH
handler"
);
WARN
(
"
Failed to install signal
handler"
);
goto
on_error1
;
goto
on_error1
;
}
}
...
@@ -785,7 +800,7 @@ int lxc_console(struct lxc_container *c, int ttynum,
...
@@ -785,7 +800,7 @@ int lxc_console(struct lxc_container *c, int ttynum,
if
(
ret
<
0
)
if
(
ret
<
0
)
TRACE
(
"Process is already group leader"
);
TRACE
(
"Process is already group leader"
);
ts
=
lxc_console_sig
winch
_init
(
stdinfd
,
masterfd
);
ts
=
lxc_console_sig
nal
_init
(
stdinfd
,
masterfd
);
if
(
!
ts
)
{
if
(
!
ts
)
{
ret
=
-
1
;
ret
=
-
1
;
goto
close_fds
;
goto
close_fds
;
...
@@ -811,9 +826,9 @@ int lxc_console(struct lxc_container *c, int ttynum,
...
@@ -811,9 +826,9 @@ int lxc_console(struct lxc_container *c, int ttynum,
if
(
ts
->
sigfd
!=
-
1
)
{
if
(
ts
->
sigfd
!=
-
1
)
{
ret
=
lxc_mainloop_add_handler
(
&
descr
,
ts
->
sigfd
,
ret
=
lxc_mainloop_add_handler
(
&
descr
,
ts
->
sigfd
,
lxc_console_cb_sig
winch
_fd
,
ts
);
lxc_console_cb_sig
nal
_fd
,
ts
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"Failed to add
SIGWINCH handler
"
);
ERROR
(
"Failed to add
signal handler to mainloop
"
);
goto
close_mainloop
;
goto
close_mainloop
;
}
}
}
}
...
@@ -867,7 +882,7 @@ close_mainloop:
...
@@ -867,7 +882,7 @@ close_mainloop:
lxc_mainloop_close
(
&
descr
);
lxc_mainloop_close
(
&
descr
);
sigwinch_fini
:
sigwinch_fini
:
lxc_console_sig
winch
_fini
(
ts
);
lxc_console_sig
nal
_fini
(
ts
);
close_fds
:
close_fds
:
close
(
masterfd
);
close
(
masterfd
);
...
...
src/lxc/console.h
View file @
0519b5cc
...
@@ -24,6 +24,9 @@
...
@@ -24,6 +24,9 @@
#ifndef __LXC_CONSOLE_H
#ifndef __LXC_CONSOLE_H
#define __LXC_CONSOLE_H
#define __LXC_CONSOLE_H
#include <signal.h>
#include <stdio.h>
#include "conf.h"
#include "conf.h"
#include "list.h"
#include "list.h"
...
@@ -38,18 +41,21 @@ struct lxc_tty_state
...
@@ -38,18 +41,21 @@ struct lxc_tty_state
/* Escape sequence to use for exiting the pty. A single char can be
/* 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.
* 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
* This field is checked by lxc_console_cb_tty_stdin(). Set to -1 to
* disable exiting the pty via a escape sequence. */
* disable exiting the pty via a escape sequence.
*/
int
escape
;
int
escape
;
/* Used internally by lxc_console_cb_tty_stdin() to check whether an
/* Used internally by lxc_console_cb_tty_stdin() to check whether an
* escape sequence has been received. */
* escape sequence has been received.
*/
int
saw_escape
;
int
saw_escape
;
/* Name of the container to forward the SIGWINCH event to. */
/* Name of the container to forward the SIGWINCH event to. */
const
char
*
winch_proxy
;
const
char
*
winch_proxy
;
/* Path of the container to forward the SIGWINCH event to. */
/* Path of the container to forward the SIGWINCH event to. */
const
char
*
winch_proxy_lxcpath
;
const
char
*
winch_proxy_lxcpath
;
/* File descriptor that accepts SIGWINCH signals. If set to -1 no
/* File descriptor that accepts signals. If set to -1 no signal handler
* SIGWINCH handler could be installed. This also means that
* could be installed. This also means that the sigset_t oldmask member
* the sigset_t oldmask member is meaningless. */
* is meaningless.
*/
int
sigfd
;
int
sigfd
;
sigset_t
oldmask
;
sigset_t
oldmask
;
};
};
...
@@ -172,48 +178,48 @@ extern int lxc_setup_tios(int fd, struct termios *oldtios);
...
@@ -172,48 +178,48 @@ extern int lxc_setup_tios(int fd, struct termios *oldtios);
extern
void
lxc_console_winsz
(
int
srcfd
,
int
dstfd
);
extern
void
lxc_console_winsz
(
int
srcfd
,
int
dstfd
);
/*
/*
* lxc_console_sig
winch_init: install SIGWINCH
handler
* lxc_console_sig
nal_init: install signal
handler
*
*
* @srcfd : src for winsz in SIGWINCH handler
* @srcfd : src for winsz in SIGWINCH handler
* @dstfd : dst 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
* 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
* member of the returned lxc_tty_state can be select()/poll()ed/epoll()ed
* on (ie added to a mainloop) for
SIGWINCH
.
* on (ie added to a mainloop) for
signals
.
*
*
* Must be called with process_lock held to protect the lxc_ttys list, or
* Must be called with process_lock held to protect the lxc_ttys list, or
* from a non-threaded context.
* from a non-threaded context.
*
*
* Note that
SIGWINCH isn't installed as a classic asychronous handler,
* Note that
the signal handler isn't installed as a classic asychronous
*
rather signalfd(2) is used so that we can handle the signal when we're
*
handler, rather signalfd(2) is used so that we can handle the signal when
*
ready for it. This avoids deadlocks since a signal handler
*
we're ready for it. This avoids deadlocks since a signal handler (ie
*
(ie lxc_console_sigwinch()) would need to take the thread mutex to
*
lxc_console_sigwinch()) would need to take the thread mutex to prevent
*
prevent lxc_ttys list corruption, but using the fd we can provide th
e
*
lxc_ttys list corruption, but using the fd we can provide the tty_stat
e
*
tty_state needed to the callback (lxc_console_cb_sigwinch
_fd()).
*
needed to the callback (lxc_console_cb_signal
_fd()).
*
*
* This function allocates memory. It is up to the caller to free it.
* This function allocates memory. It is up to the caller to free it.
*/
*/
extern
struct
lxc_tty_state
*
lxc_console_sig
winch
_init
(
int
srcfd
,
int
dstfd
);
extern
struct
lxc_tty_state
*
lxc_console_sig
nal
_init
(
int
srcfd
,
int
dstfd
);
/*
/*
* Handler for
SIGWINCH
events. To be registered via the corresponding functions
* Handler for
signal
events. To be registered via the corresponding functions
* declared and defined in mainloop.{c,h} or lxc_console_mainloop_add().
* declared and defined in mainloop.{c,h} or lxc_console_mainloop_add().
*/
*/
extern
int
lxc_console_cb_sig
winch
_fd
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
extern
int
lxc_console_cb_sig
nal
_fd
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
);
struct
lxc_epoll_descr
*
descr
);
/*
/*
* lxc_console_sig
winch_fini: uninstall SIGWINCH
handler
* lxc_console_sig
nal_fini: uninstall signal
handler
*
*
* @ts : the lxc_tty_state returned by lxc_console_sig
winch
_init
* @ts : the lxc_tty_state returned by lxc_console_sig
nal
_init
*
*
* Restore the saved signal handler that was in effect at the time
* Restore the saved signal handler that was in effect at the time
* lxc_console_sig
winch
_init() was called.
* lxc_console_sig
nal
_init() was called.
*
*
* Must be called with process_lock held to protect the lxc_ttys list, or
* Must be called with process_lock held to protect the lxc_ttys list, or
* from a non-threaded context.
* from a non-threaded context.
*/
*/
extern
void
lxc_console_sig
winch
_fini
(
struct
lxc_tty_state
*
ts
);
extern
void
lxc_console_sig
nal
_fini
(
struct
lxc_tty_state
*
ts
);
extern
int
lxc_console_write_ringbuffer
(
struct
lxc_console
*
console
);
extern
int
lxc_console_write_ringbuffer
(
struct
lxc_console
*
console
);
...
...
src/lxc/tools/lxc_attach.c
View file @
0519b5cc
...
@@ -371,7 +371,7 @@ err3:
...
@@ -371,7 +371,7 @@ err3:
lxc_mainloop_close
(
&
descr
);
lxc_mainloop_close
(
&
descr
);
err2:
err2:
if
(
ts
&&
ts
->
sigfd
!=
-
1
)
if
(
ts
&&
ts
->
sigfd
!=
-
1
)
lxc_console_sig
winch
_fini
(
ts
);
lxc_console_sig
nal
_fini
(
ts
);
err1:
err1:
lxc_console_delete
(
&
conf
->
console
);
lxc_console_delete
(
&
conf
->
console
);
...
...
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