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
c4e7852b
Unverified
Commit
c4e7852b
authored
Nov 17, 2017
by
Serge Hallyn
Committed by
GitHub
Nov 17, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1925 from brauner/2017-11-14/console_config_keys
console: add lxc.console.buffer.size, lxc.console.buffer.logfile, lxc.console.rotate
parents
05e1745c
8a2404e9
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
395 additions
and
62 deletions
+395
-62
lxc.container.conf.sgml.in
doc/lxc.container.conf.sgml.in
+73
-2
commands.c
src/lxc/commands.c
+58
-5
conf.c
src/lxc/conf.c
+5
-2
conf.h
src/lxc/conf.h
+12
-1
confile.c
src/lxc/confile.c
+76
-14
console.c
src/lxc/console.c
+58
-22
console.h
src/lxc/console.h
+1
-0
console_log.c
src/tests/console_log.c
+112
-16
No files found.
doc/lxc.container.conf.sgml.in
View file @
c4e7852b
...
@@ -682,17 +682,88 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
...
@@ -682,17 +682,88 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
where the output of this console goes.
where the output of this console goes.
</para>
</para>
<variablelist>
<variablelist>
<varlistentry>
<term>
<option>lxc.console.buffer.size</option>
</term>
<listitem>
<para>
Setting this option instructs liblxc to allocate an in-memory
ringbuffer. The container's console output will be written to the
ringbuffer. Note that ringbuffer must be at least as big as a
standard page size. When passed a value smaller than a single page
size liblxc will allocate a ringbuffer of a single page size. A page
size is usually 4kB.
The keyword 'auto' will cause liblxc to allocate a ringbuffer of
128kB.
When manually specifying a size for the ringbuffer the value should
be a power of 2 when converted to bytes. Valid size prefixes are
'kB', 'MB', 'GB'. (Note that all conversions are based on multiples
of 1024. That means 'kb' == 'KiB', 'MB' == 'MiB', 'GB' == 'GiB'.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>lxc.console.buffer.logfile</option>
</term>
<listitem>
<para>
Setting this option instructs liblxc to write the in-memory
ringbuffer to disk. For performance reasons liblxc will only write
the in-memory ringbuffer to disk when requested. Note that the this
option is only used by liblxc when
<option>lxc.console.buffer.size</option> is set.
By default liblxc will dump the contents of the in-memory ringbuffer
to disk when the container terminates. This allows users to diagnose
boot failures when the container crashed before an API request to
retrieve the in-memory ringbuffer could be sent or handled.
</para>
</listitem>
</varlistentry>
<varlistentry>
<varlistentry>
<term>
<term>
<option>lxc.console.logfile</option>
<option>lxc.console.logfile</option>
</term>
</term>
<listitem>
<listitem>
<para>
<para>
Specify a path to a file where the console output will
Specify a path to a file where the console output will be written.
be written.
Note that in contrast to the on-disk ringbuffer logfile this file
will keep growing potentially filling up the users disks if not
rotated and deleted. This problem can also be avoided by using the
in-memory ringbuffer options
<option>lxc.console.buffer.size</option> and
<option>lxc.console.buffer.logfile</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>lxc.console.rotate</option>
</term>
<listitem>
<para>
Whether to rotate the console logfile specified in
<option>lxc.console.logfile</option>. Users can send an API
request to rotate the logfile. Note that the old logfile will have
the same name as the original with the suffix ".1" appended.
Users wishing to prevent the console log file from filling the
disk should rotate the logfile and delete it if unneeded. This
problem can also be avoided by using the in-memory ringbuffer
options <option>lxc.console.buffer.size</option> and
<option>lxc.console.buffer.logfile</option>.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term>
<term>
<option>lxc.console.path</option>
<option>lxc.console.path</option>
...
...
src/lxc/commands.c
View file @
c4e7852b
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#include "config.h"
#include "config.h"
#include <caps.h>
#include <errno.h>
#include <errno.h>
#include <fcntl.h>
#include <fcntl.h>
#include <malloc.h>
#include <malloc.h>
...
@@ -1026,7 +1027,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
...
@@ -1026,7 +1027,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
struct
lxc_handler
*
handler
)
struct
lxc_handler
*
handler
)
{
{
struct
lxc_cmd_rsp
rsp
;
struct
lxc_cmd_rsp
rsp
;
uint64_t
logsize
=
handler
->
conf
->
console
.
log
_size
;
uint64_t
buffer_size
=
handler
->
conf
->
console
.
buffer
_size
;
const
struct
lxc_cmd_console_log
*
log
=
req
->
data
;
const
struct
lxc_cmd_console_log
*
log
=
req
->
data
;
struct
lxc_console
*
console
=
&
handler
->
conf
->
console
;
struct
lxc_console
*
console
=
&
handler
->
conf
->
console
;
struct
lxc_ringbuf
*
buf
=
&
handler
->
conf
->
console
.
ringbuf
;
struct
lxc_ringbuf
*
buf
=
&
handler
->
conf
->
console
.
ringbuf
;
...
@@ -1034,10 +1035,12 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
...
@@ -1034,10 +1035,12 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
rsp
.
ret
=
-
EFAULT
;
rsp
.
ret
=
-
EFAULT
;
rsp
.
datalen
=
0
;
rsp
.
datalen
=
0
;
rsp
.
data
=
NULL
;
rsp
.
data
=
NULL
;
if
(
log
size
<=
0
)
if
(
buffer_
size
<=
0
)
goto
out
;
goto
out
;
if
(
log
->
read
||
log
->
write_logfile
)
rsp
.
datalen
=
lxc_ringbuf_used
(
buf
);
rsp
.
datalen
=
lxc_ringbuf_used
(
buf
);
if
(
log
->
read
)
if
(
log
->
read
)
rsp
.
data
=
lxc_ringbuf_get_read_addr
(
buf
);
rsp
.
data
=
lxc_ringbuf_get_read_addr
(
buf
);
...
@@ -1051,7 +1054,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
...
@@ -1051,7 +1054,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
if
(
log
->
write_logfile
&&
rsp
.
datalen
>
0
)
{
if
(
log
->
write_logfile
&&
rsp
.
datalen
>
0
)
{
rsp
.
ret
=
-
ENOENT
;
rsp
.
ret
=
-
ENOENT
;
if
(
!
console
->
log_path
)
if
(
!
console
->
buffer_log_file
)
goto
out
;
goto
out
;
rsp
.
ret
=
lxc_console_write_ringbuffer
(
console
);
rsp
.
ret
=
lxc_console_write_ringbuffer
(
console
);
...
@@ -1060,11 +1063,61 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
...
@@ -1060,11 +1063,61 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
}
}
rsp
.
ret
=
0
;
rsp
.
ret
=
0
;
if
(
log
->
clear
)
{
int
ret
;
size_t
len
;
char
*
tmp
;
if
(
log
->
clear
)
/* clear the ringbuffer */
lxc_ringbuf_clear
(
buf
);
lxc_ringbuf_clear
(
buf
);
else
if
(
rsp
.
datalen
>
0
)
/* truncate the ringbuffer log file */
if
(
console
->
buffer_log_file
)
{
rsp
.
ret
=
-
ENOENT
;
if
(
!
file_exists
(
console
->
buffer_log_file
))
goto
out
;
/* be very certain things are kosher */
rsp
.
ret
=
-
EBADF
;
if
(
console
->
buffer_log_file_fd
<
0
)
goto
out
;
rsp
.
ret
=
lxc_unpriv
(
ftruncate
(
console
->
buffer_log_file_fd
,
0
));
if
(
rsp
.
ret
<
0
)
{
ERROR
(
"%s - Failed to truncate console "
"ringbuffer log file
\"
%s
\"
"
,
strerror
(
errno
),
console
->
buffer_log_file
);
goto
out
;
}
}
/* rotate the console log file */
if
(
!
console
->
log_path
||
console
->
log_rotate
==
0
)
goto
out
;
/* be very certain things are kosher */
rsp
.
ret
=
-
EBADF
;
if
(
console
->
log_fd
<
0
)
goto
out
;
len
=
strlen
(
console
->
log_path
)
+
sizeof
(
".1"
);
tmp
=
alloca
(
len
);
rsp
.
ret
=
-
EFBIG
;
ret
=
snprintf
(
tmp
,
len
,
"%s.1"
,
console
->
log_path
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
len
)
goto
out
;
close
(
console
->
log_fd
);
console
->
log_fd
=
-
1
;
rsp
.
ret
=
lxc_unpriv
(
rename
(
console
->
log_path
,
tmp
));
if
(
rsp
.
ret
<
0
)
goto
out
;
rsp
.
ret
=
lxc_console_create_log_file
(
console
);
}
else
if
(
rsp
.
datalen
>
0
)
{
lxc_ringbuf_move_read_addr
(
buf
,
rsp
.
datalen
);
lxc_ringbuf_move_read_addr
(
buf
,
rsp
.
datalen
);
}
out:
out:
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
...
...
src/lxc/conf.c
View file @
c4e7852b
...
@@ -2430,9 +2430,11 @@ struct lxc_conf *lxc_conf_init(void)
...
@@ -2430,9 +2430,11 @@ struct lxc_conf *lxc_conf_init(void)
new
->
loglevel
=
LXC_LOG_LEVEL_NOTSET
;
new
->
loglevel
=
LXC_LOG_LEVEL_NOTSET
;
new
->
personality
=
-
1
;
new
->
personality
=
-
1
;
new
->
autodev
=
1
;
new
->
autodev
=
1
;
new
->
console
.
buffer_log_file
=
NULL
;
new
->
console
.
buffer_log_file_fd
=
-
1
;
new
->
console
.
buffer_size
=
0
;
new
->
console
.
log_path
=
NULL
;
new
->
console
.
log_path
=
NULL
;
new
->
console
.
log_fd
=
-
1
;
new
->
console
.
log_fd
=
-
1
;
new
->
console
.
log_size
=
0
;
new
->
console
.
path
=
NULL
;
new
->
console
.
path
=
NULL
;
new
->
console
.
peer
=
-
1
;
new
->
console
.
peer
=
-
1
;
new
->
console
.
peerpty
.
busy
=
-
1
;
new
->
console
.
peerpty
.
busy
=
-
1
;
...
@@ -3461,9 +3463,10 @@ void lxc_conf_free(struct lxc_conf *conf)
...
@@ -3461,9 +3463,10 @@ void lxc_conf_free(struct lxc_conf *conf)
return
;
return
;
if
(
current_config
==
conf
)
if
(
current_config
==
conf
)
current_config
=
NULL
;
current_config
=
NULL
;
free
(
conf
->
console
.
buffer_log_file
);
free
(
conf
->
console
.
log_path
);
free
(
conf
->
console
.
log_path
);
free
(
conf
->
console
.
path
);
free
(
conf
->
console
.
path
);
if
(
conf
->
console
.
log
_size
>
0
&&
conf
->
console
.
ringbuf
.
addr
)
if
(
conf
->
console
.
buffer
_size
>
0
&&
conf
->
console
.
ringbuf
.
addr
)
lxc_ringbuf_release
(
&
conf
->
console
.
ringbuf
);
lxc_ringbuf_release
(
&
conf
->
console
.
ringbuf
);
free
(
conf
->
rootfs
.
mount
);
free
(
conf
->
rootfs
.
mount
);
free
(
conf
->
rootfs
.
bdev_type
);
free
(
conf
->
rootfs
.
bdev_type
);
...
...
src/lxc/conf.h
View file @
c4e7852b
...
@@ -150,10 +150,21 @@ struct lxc_console {
...
@@ -150,10 +150,21 @@ struct lxc_console {
char
*
path
;
char
*
path
;
char
*
log_path
;
char
*
log_path
;
int
log_fd
;
int
log_fd
;
unsigned
int
log_rotate
;
char
name
[
MAXPATHLEN
];
char
name
[
MAXPATHLEN
];
struct
termios
*
tios
;
struct
termios
*
tios
;
struct
lxc_tty_state
*
tty_state
;
struct
lxc_tty_state
*
tty_state
;
uint64_t
log_size
;
/* size of the ringbuffer */
uint64_t
buffer_size
;
/* path to the log file for the ringbuffer */
char
*
buffer_log_file
;
/* fd to the log file for the ringbuffer */
int
buffer_log_file_fd
;
/* the in-memory ringbuffer */
struct
lxc_ringbuf
ringbuf
;
struct
lxc_ringbuf
ringbuf
;
};
};
...
...
src/lxc/confile.c
View file @
c4e7852b
...
@@ -83,7 +83,9 @@ lxc_config_define(cap_keep);
...
@@ -83,7 +83,9 @@ lxc_config_define(cap_keep);
lxc_config_define
(
cgroup_controller
);
lxc_config_define
(
cgroup_controller
);
lxc_config_define
(
cgroup_dir
);
lxc_config_define
(
cgroup_dir
);
lxc_config_define
(
console_logfile
);
lxc_config_define
(
console_logfile
);
lxc_config_define
(
console_logsize
);
lxc_config_define
(
console_rotate
);
lxc_config_define
(
console_buffer_logfile
);
lxc_config_define
(
console_buffer_size
);
lxc_config_define
(
console_path
);
lxc_config_define
(
console_path
);
lxc_config_define
(
environment
);
lxc_config_define
(
environment
);
lxc_config_define
(
ephemeral
);
lxc_config_define
(
ephemeral
);
...
@@ -149,9 +151,11 @@ static struct lxc_config_t config[] = {
...
@@ -149,9 +151,11 @@ static struct lxc_config_t config[] = {
{
"lxc.cap.keep"
,
false
,
set_config_cap_keep
,
get_config_cap_keep
,
clr_config_cap_keep
,
},
{
"lxc.cap.keep"
,
false
,
set_config_cap_keep
,
get_config_cap_keep
,
clr_config_cap_keep
,
},
{
"lxc.cgroup.dir"
,
false
,
set_config_cgroup_dir
,
get_config_cgroup_dir
,
clr_config_cgroup_dir
,
},
{
"lxc.cgroup.dir"
,
false
,
set_config_cgroup_dir
,
get_config_cgroup_dir
,
clr_config_cgroup_dir
,
},
{
"lxc.cgroup"
,
false
,
set_config_cgroup_controller
,
get_config_cgroup_controller
,
clr_config_cgroup_controller
,
},
{
"lxc.cgroup"
,
false
,
set_config_cgroup_controller
,
get_config_cgroup_controller
,
clr_config_cgroup_controller
,
},
{
"lxc.console.buffer.logfile"
,
false
,
set_config_console_buffer_logfile
,
get_config_console_buffer_logfile
,
clr_config_console_buffer_logfile
,
},
{
"lxc.console.buffer.size"
,
false
,
set_config_console_buffer_size
,
get_config_console_buffer_size
,
clr_config_console_buffer_size
,
},
{
"lxc.console.logfile"
,
false
,
set_config_console_logfile
,
get_config_console_logfile
,
clr_config_console_logfile
,
},
{
"lxc.console.logfile"
,
false
,
set_config_console_logfile
,
get_config_console_logfile
,
clr_config_console_logfile
,
},
{
"lxc.console.logsize"
,
false
,
set_config_console_logsize
,
get_config_console_logsize
,
clr_config_console_logsize
,
},
{
"lxc.console.path"
,
false
,
set_config_console_path
,
get_config_console_path
,
clr_config_console_path
,
},
{
"lxc.console.path"
,
false
,
set_config_console_path
,
get_config_console_path
,
clr_config_console_path
,
},
{
"lxc.console.rotate"
,
false
,
set_config_console_rotate
,
get_config_console_rotate
,
clr_config_console_rotate
,
},
{
"lxc.environment"
,
false
,
set_config_environment
,
get_config_environment
,
clr_config_environment
,
},
{
"lxc.environment"
,
false
,
set_config_environment
,
get_config_environment
,
clr_config_environment
,
},
{
"lxc.ephemeral"
,
false
,
set_config_ephemeral
,
get_config_ephemeral
,
clr_config_ephemeral
,
},
{
"lxc.ephemeral"
,
false
,
set_config_ephemeral
,
get_config_ephemeral
,
clr_config_ephemeral
,
},
{
"lxc.execute.cmd"
,
false
,
set_config_execute_cmd
,
get_config_execute_cmd
,
clr_config_execute_cmd
,
},
{
"lxc.execute.cmd"
,
false
,
set_config_execute_cmd
,
get_config_execute_cmd
,
clr_config_execute_cmd
,
},
...
@@ -1788,27 +1792,47 @@ static int set_config_console_path(const char *key, const char *value,
...
@@ -1788,27 +1792,47 @@ static int set_config_console_path(const char *key, const char *value,
return
set_config_path_item
(
&
lxc_conf
->
console
.
path
,
value
);
return
set_config_path_item
(
&
lxc_conf
->
console
.
path
,
value
);
}
}
static
int
set_config_console_rotate
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
if
(
lxc_config_value_empty
(
value
))
{
lxc_conf
->
console
.
log_rotate
=
0
;
return
0
;
}
if
(
lxc_safe_uint
(
value
,
&
lxc_conf
->
console
.
log_rotate
)
<
0
)
return
-
1
;
if
(
lxc_conf
->
console
.
log_rotate
>
1
)
{
ERROR
(
"The
\"
lxc.console.rotate
\"
config key can only be set "
"to 0 or 1"
);
return
-
1
;
}
return
0
;
}
static
int
set_config_console_logfile
(
const
char
*
key
,
const
char
*
value
,
static
int
set_config_console_logfile
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
{
return
set_config_path_item
(
&
lxc_conf
->
console
.
log_path
,
value
);
return
set_config_path_item
(
&
lxc_conf
->
console
.
log_path
,
value
);
}
}
static
int
set_config_console_
log
size
(
const
char
*
key
,
const
char
*
value
,
static
int
set_config_console_
buffer_
size
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
{
int
ret
;
int
ret
;
int64_t
size
;
int64_t
size
;
uint64_t
log
size
,
pgsz
;
uint64_t
buffer_
size
,
pgsz
;
if
(
lxc_config_value_empty
(
value
))
{
if
(
lxc_config_value_empty
(
value
))
{
lxc_conf
->
console
.
log
_size
=
0
;
lxc_conf
->
console
.
buffer
_size
=
0
;
return
0
;
return
0
;
}
}
/* If the user specified "auto" the default log size is 2^17 = 128 Kib */
/* If the user specified "auto" the default log size is 2^17 = 128 Kib */
if
(
!
strcmp
(
value
,
"auto"
))
{
if
(
!
strcmp
(
value
,
"auto"
))
{
lxc_conf
->
console
.
log
_size
=
1
<<
17
;
lxc_conf
->
console
.
buffer
_size
=
1
<<
17
;
return
0
;
return
0
;
}
}
...
@@ -1829,18 +1853,25 @@ static int set_config_console_logsize(const char *key, const char *value,
...
@@ -1829,18 +1853,25 @@ static int set_config_console_logsize(const char *key, const char *value,
size
=
pgsz
;
size
=
pgsz
;
}
}
log
size
=
lxc_find_next_power2
((
uint64_t
)
size
);
buffer_
size
=
lxc_find_next_power2
((
uint64_t
)
size
);
if
(
log
size
==
0
)
if
(
buffer_
size
==
0
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
log
size
!=
size
)
if
(
buffer_
size
!=
size
)
NOTICE
(
"Passed size was not a power of 2. Rounding log size to "
NOTICE
(
"Passed size was not a power of 2. Rounding log size to "
"next power of two: %"
PRIu64
" bytes"
,
log
size
);
"next power of two: %"
PRIu64
" bytes"
,
buffer_
size
);
lxc_conf
->
console
.
log_size
=
log
size
;
lxc_conf
->
console
.
buffer_size
=
buffer_
size
;
return
0
;
return
0
;
}
}
static
int
set_config_console_buffer_logfile
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
return
set_config_path_item
(
&
lxc_conf
->
console
.
buffer_log_file
,
value
);
}
int
append_unexp_config_line
(
const
char
*
line
,
struct
lxc_conf
*
conf
)
int
append_unexp_config_line
(
const
char
*
line
,
struct
lxc_conf
*
conf
)
{
{
size_t
len
=
conf
->
unexpanded_len
,
linelen
=
strlen
(
line
);
size_t
len
=
conf
->
unexpanded_len
,
linelen
=
strlen
(
line
);
...
@@ -3091,12 +3122,27 @@ static int get_config_console_logfile(const char *key, char *retv, int inlen,
...
@@ -3091,12 +3122,27 @@ static int get_config_console_logfile(const char *key, char *retv, int inlen,
return
lxc_get_conf_str
(
retv
,
inlen
,
c
->
console
.
log_path
);
return
lxc_get_conf_str
(
retv
,
inlen
,
c
->
console
.
log_path
);
}
}
static
int
get_config_console_
logsiz
e
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
static
int
get_config_console_
rotat
e
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
struct
lxc_conf
*
c
,
void
*
data
)
{
{
return
lxc_get_conf_int
(
c
,
retv
,
inlen
,
c
->
console
.
log_rotate
);
}
static
int
get_config_console_buffer_size
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
{
return
lxc_get_conf_uint64
(
c
,
retv
,
inlen
,
c
->
autodev
);
return
lxc_get_conf_uint64
(
c
,
retv
,
inlen
,
c
->
autodev
);
}
}
static
int
get_config_console_buffer_logfile
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
{
return
lxc_get_conf_str
(
retv
,
inlen
,
c
->
console
.
buffer_log_file
);
}
static
int
get_config_seccomp_profile
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
static
int
get_config_seccomp_profile
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
struct
lxc_conf
*
c
,
void
*
data
)
{
{
...
@@ -3501,10 +3547,26 @@ static inline int clr_config_console_logfile(const char *key,
...
@@ -3501,10 +3547,26 @@ static inline int clr_config_console_logfile(const char *key,
return
0
;
return
0
;
}
}
static
inline
int
clr_config_console_logsize
(
const
char
*
key
,
static
inline
int
clr_config_console_rotate
(
const
char
*
key
,
struct
lxc_conf
*
c
,
void
*
data
)
{
c
->
console
.
log_rotate
=
0
;
return
0
;
}
static
inline
int
clr_config_console_buffer_size
(
const
char
*
key
,
struct
lxc_conf
*
c
,
void
*
data
)
struct
lxc_conf
*
c
,
void
*
data
)
{
{
c
->
console
.
log_size
=
0
;
c
->
console
.
buffer_size
=
0
;
return
0
;
}
static
inline
int
clr_config_console_buffer_logfile
(
const
char
*
key
,
struct
lxc_conf
*
c
,
void
*
data
)
{
free
(
c
->
console
.
buffer_log_file
);
c
->
console
.
buffer_log_file
=
NULL
;
return
0
;
return
0
;
}
}
...
...
src/lxc/console.c
View file @
c4e7852b
...
@@ -238,7 +238,7 @@ static int lxc_console_cb_con(int fd, uint32_t events, void *data,
...
@@ -238,7 +238,7 @@ static int lxc_console_cb_con(int fd, uint32_t events, void *data,
w
=
lxc_write_nointr
(
console
->
peer
,
buf
,
r
);
w
=
lxc_write_nointr
(
console
->
peer
,
buf
,
r
);
/* write to console ringbuffer */
/* write to console ringbuffer */
if
(
console
->
log
_size
>
0
)
if
(
console
->
buffer
_size
>
0
)
w_rbuf
=
lxc_ringbuf_write
(
&
console
->
ringbuf
,
buf
,
r
);
w_rbuf
=
lxc_ringbuf_write
(
&
console
->
ringbuf
,
buf
,
r
);
/* write to console log */
/* write to console log */
...
@@ -552,29 +552,20 @@ out:
...
@@ -552,29 +552,20 @@ out:
int
lxc_console_write_ringbuffer
(
struct
lxc_console
*
console
)
int
lxc_console_write_ringbuffer
(
struct
lxc_console
*
console
)
{
{
int
fd
;
char
*
r_addr
;
char
*
r_addr
;
ssize_t
ret
;
ssize_t
ret
;
uint64_t
used
;
uint64_t
used
;
struct
lxc_ringbuf
*
buf
=
&
console
->
ringbuf
;
struct
lxc_ringbuf
*
buf
=
&
console
->
ringbuf
;
if
(
!
console
->
log_path
)
if
(
!
console
->
buffer_log_file
)
return
0
;
return
0
;
used
=
lxc_ringbuf_used
(
buf
);
used
=
lxc_ringbuf_used
(
buf
);
if
(
used
==
0
)
if
(
used
==
0
)
return
0
;
return
0
;
fd
=
lxc_unpriv
(
open
(
console
->
log_path
,
O_CLOEXEC
|
O_RDWR
|
O_CREAT
|
O_TRUNC
,
0600
));
if
(
fd
<
0
)
{
SYSERROR
(
"Failed to open console log file
\"
%s
\"
"
,
console
->
log_path
);
return
-
EIO
;
}
DEBUG
(
"Using
\"
%s
\"
as console log file"
,
console
->
log_path
);
r_addr
=
lxc_ringbuf_get_read_addr
(
buf
);
r_addr
=
lxc_ringbuf_get_read_addr
(
buf
);
ret
=
lxc_write_nointr
(
fd
,
r_addr
,
used
);
ret
=
lxc_write_nointr
(
console
->
buffer_log_file_fd
,
r_addr
,
used
);
close
(
fd
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
EIO
;
return
-
EIO
;
...
@@ -606,6 +597,30 @@ void lxc_console_delete(struct lxc_console *console)
...
@@ -606,6 +597,30 @@ void lxc_console_delete(struct lxc_console *console)
console
->
master
=
-
1
;
console
->
master
=
-
1
;
console
->
slave
=
-
1
;
console
->
slave
=
-
1
;
console
->
log_fd
=
-
1
;
console
->
log_fd
=
-
1
;
if
(
console
->
buffer_log_file_fd
>=
0
)
close
(
console
->
buffer_log_file_fd
);
console
->
buffer_log_file_fd
=
-
1
;
}
/* This is the console ringbuffer log file. Please note that the console
* ringbuffer log file is (implementation wise not content wise) independent of
* the console log file.
*/
static
int
lxc_console_create_ringbuf_log_file
(
struct
lxc_console
*
console
)
{
if
(
!
console
->
buffer_log_file
)
return
0
;
console
->
buffer_log_file_fd
=
lxc_unpriv
(
open
(
console
->
buffer_log_file
,
O_CLOEXEC
|
O_RDWR
|
O_CREAT
|
O_TRUNC
,
0600
));
if
(
console
->
buffer_log_file_fd
<
0
)
{
SYSERROR
(
"Failed to open console ringbuffer log file
\"
%s
\"
"
,
console
->
buffer_log_file
);
return
-
EIO
;
}
DEBUG
(
"Using
\"
%s
\"
as console ringbuffer log file"
,
console
->
buffer_log_file
);
return
0
;
}
}
/**
/**
...
@@ -613,11 +628,11 @@ void lxc_console_delete(struct lxc_console *console)
...
@@ -613,11 +628,11 @@ void lxc_console_delete(struct lxc_console *console)
* register a handler for the console's masterfd when we create the mainloop
* register a handler for the console's masterfd when we create the mainloop
* the console handler needs to see an allocated ringbuffer.
* the console handler needs to see an allocated ringbuffer.
*/
*/
static
int
lxc_
setup_consol
e_ringbuf
(
struct
lxc_console
*
console
)
static
int
lxc_
console_creat
e_ringbuf
(
struct
lxc_console
*
console
)
{
{
int
ret
;
int
ret
;
struct
lxc_ringbuf
*
buf
=
&
console
->
ringbuf
;
struct
lxc_ringbuf
*
buf
=
&
console
->
ringbuf
;
uint64_t
size
=
console
->
log
_size
;
uint64_t
size
=
console
->
buffer
_size
;
/* no ringbuffer previously allocated and no ringbuffer requested */
/* no ringbuffer previously allocated and no ringbuffer requested */
if
(
!
buf
->
addr
&&
size
<=
0
)
if
(
!
buf
->
addr
&&
size
<=
0
)
...
@@ -655,6 +670,25 @@ static int lxc_setup_console_ringbuf(struct lxc_console *console)
...
@@ -655,6 +670,25 @@ static int lxc_setup_console_ringbuf(struct lxc_console *console)
return
0
;
return
0
;
}
}
/**
* This is the console log file. Please note that the console log file is
* (implementation wise not content wise) independent of the console ringbuffer.
*/
int
lxc_console_create_log_file
(
struct
lxc_console
*
console
)
{
if
(
!
console
->
log_path
)
return
0
;
console
->
log_fd
=
lxc_unpriv
(
open
(
console
->
log_path
,
O_CLOEXEC
|
O_RDWR
|
O_CREAT
|
O_APPEND
,
0600
));
if
(
console
->
log_fd
<
0
)
{
SYSERROR
(
"Failed to open console log file
\"
%s
\"
"
,
console
->
log_path
);
return
-
1
;
}
DEBUG
(
"Using
\"
%s
\"
as console log file"
,
console
->
log_path
);
return
0
;
}
int
lxc_console_create
(
struct
lxc_conf
*
conf
)
int
lxc_console_create
(
struct
lxc_conf
*
conf
)
{
{
int
ret
,
saved_errno
;
int
ret
,
saved_errno
;
...
@@ -698,16 +732,18 @@ int lxc_console_create(struct lxc_conf *conf)
...
@@ -698,16 +732,18 @@ int lxc_console_create(struct lxc_conf *conf)
goto
err
;
goto
err
;
}
}
if
(
console
->
log_path
&&
console
->
log_size
<=
0
)
{
/* create console log file */
console
->
log_fd
=
lxc_unpriv
(
open
(
console
->
log_path
,
O_CLOEXEC
|
O_RDWR
|
O_CREAT
|
O_APPEND
,
0600
));
ret
=
lxc_console_create_log_file
(
console
);
if
(
console
->
log_fd
<
0
)
{
if
(
ret
<
0
)
SYSERROR
(
"Failed to open console log file
\"
%s
\"
"
,
console
->
log_path
);
goto
err
;
/* create console ringbuffer */
ret
=
lxc_console_create_ringbuf
(
console
);
if
(
ret
<
0
)
goto
err
;
goto
err
;
}
DEBUG
(
"Using
\"
%s
\"
as console log file"
,
console
->
log_path
);
}
ret
=
lxc_setup_console_ringbuf
(
console
);
/* create console ringbuffer log file */
ret
=
lxc_console_create_ringbuf_log_file
(
console
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
err
;
goto
err
;
...
...
src/lxc/console.h
View file @
c4e7852b
...
@@ -222,5 +222,6 @@ extern int lxc_console_cb_signal_fd(int fd, uint32_t events, void *cbdata,
...
@@ -222,5 +222,6 @@ extern int lxc_console_cb_signal_fd(int fd, uint32_t events, void *cbdata,
extern
void
lxc_console_signal_fini
(
struct
lxc_tty_state
*
ts
);
extern
void
lxc_console_signal_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
);
extern
int
lxc_console_create_log_file
(
struct
lxc_console
*
console
);
#endif
#endif
src/tests/console_log.c
View file @
c4e7852b
...
@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
...
@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
int
logfd
,
ret
;
int
logfd
,
ret
;
char
buf
[
4096
+
1
];
char
buf
[
4096
+
1
];
ssize_t
bytes
;
ssize_t
bytes
;
struct
stat
st
;
struct
stat
st
_buffer_log_file
,
st_log_file
,
st_log_file_old
;
struct
lxc_container
*
c
;
struct
lxc_container
*
c
;
struct
lxc_console_log
log
;
struct
lxc_console_log
log
;
bool
do_unlink
=
false
;
bool
do_unlink
=
false
;
...
@@ -57,12 +57,18 @@ int main(int argc, char *argv[])
...
@@ -57,12 +57,18 @@ int main(int argc, char *argv[])
}
}
/* Set console ringbuffer size. */
/* Set console ringbuffer size. */
if
(
!
c
->
set_config_item
(
c
,
"lxc.console.
log
size"
,
"4096"
))
{
if
(
!
c
->
set_config_item
(
c
,
"lxc.console.
buffer.
size"
,
"4096"
))
{
lxc_error
(
"%s
\n
"
,
"Failed to set config item
\"
lxc.console.
log
size
\"
"
);
lxc_error
(
"%s
\n
"
,
"Failed to set config item
\"
lxc.console.
buffer.
size
\"
"
);
goto
on_error_put
;
goto
on_error_put
;
}
}
/* Set on-disk logfile. */
/* Set ringbuffer log file. */
if
(
!
c
->
set_config_item
(
c
,
"lxc.console.buffer.logfile"
,
"/tmp/console-buffer-log.log"
))
{
lxc_error
(
"%s
\n
"
,
"Failed to set config item
\"
lxc.console.buffer.logfile
\"
"
);
goto
on_error_put
;
}
/* Set console log file. */
if
(
!
c
->
set_config_item
(
c
,
"lxc.console.logfile"
,
"/tmp/console-log.log"
))
{
if
(
!
c
->
set_config_item
(
c
,
"lxc.console.logfile"
,
"/tmp/console-log.log"
))
{
lxc_error
(
"%s
\n
"
,
"Failed to set config item
\"
lxc.console.logfile
\"
"
);
lxc_error
(
"%s
\n
"
,
"Failed to set config item
\"
lxc.console.logfile
\"
"
);
goto
on_error_put
;
goto
on_error_put
;
...
@@ -135,11 +141,17 @@ int main(int argc, char *argv[])
...
@@ -135,11 +141,17 @@ int main(int argc, char *argv[])
goto
on_error_stop
;
goto
on_error_stop
;
}
}
c
->
clear_config
(
c
);
if
(
!
c
->
load_config
(
c
,
NULL
))
{
lxc_error
(
"%s
\n
"
,
"Failed to load config for container
\"
console-log
\"
"
);
goto
on_error_stop
;
}
if
(
!
c
->
startl
(
c
,
0
,
NULL
))
{
if
(
!
c
->
startl
(
c
,
0
,
NULL
))
{
lxc_error
(
"%s
\n
"
,
"Failed to start container
\"
console-log
\"
daemonized"
);
lxc_error
(
"%s
\n
"
,
"Failed to start container
\"
console-log
\"
daemonized"
);
goto
on_error_destroy
;
goto
on_error_destroy
;
}
}
do_unlink
=
true
;
/* Leave some time for the container to write something to the log. */
/* Leave some time for the container to write something to the log. */
sleep
(
2
);
sleep
(
2
);
...
@@ -158,31 +170,31 @@ int main(int argc, char *argv[])
...
@@ -158,31 +170,31 @@ int main(int argc, char *argv[])
*
log
.
read_max
,
log
.
data
);
*
log
.
read_max
,
log
.
data
);
}
}
logfd
=
open
(
"/tmp/console-log.log"
,
O_RDONLY
);
logfd
=
open
(
"/tmp/console-
buffer-
log.log"
,
O_RDONLY
);
if
(
logfd
<
0
)
{
if
(
logfd
<
0
)
{
lxc_error
(
"%s - Failed to open console log file "
lxc_error
(
"%s - Failed to open console
ringbuffer
log file "
"
\"
/tmp/console-log.log
\"\n
"
,
strerror
(
errno
));
"
\"
/tmp/console-
buffer-
log.log
\"\n
"
,
strerror
(
errno
));
goto
on_error_stop
;
goto
on_error_stop
;
}
}
bytes
=
lxc_read_nointr
(
logfd
,
buf
,
4096
+
1
);
bytes
=
lxc_read_nointr
(
logfd
,
buf
,
4096
+
1
);
close
(
logfd
);
close
(
logfd
);
if
(
bytes
<
0
||
((
uint64_t
)
bytes
!=
*
log
.
read_max
))
{
if
(
bytes
<
0
||
((
uint64_t
)
bytes
!=
*
log
.
read_max
))
{
lxc_error
(
"%s - Failed to read console log file "
lxc_error
(
"%s - Failed to read console
ringbuffer
log file "
"
\"
/tmp/console-log.log
\"\n
"
,
strerror
(
errno
));
"
\"
/tmp/console-
buffer-
log.log
\"\n
"
,
strerror
(
errno
));
goto
on_error_stop
;
goto
on_error_stop
;
}
}
ret
=
stat
(
"/tmp/console-
log.log"
,
&
st
);
ret
=
stat
(
"/tmp/console-
buffer-log.log"
,
&
st_buffer_log_file
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
lxc_error
(
"%s - Failed to stat on-disk logfile
\n
"
,
strerror
(
errno
));
lxc_error
(
"%s - Failed to stat on-disk logfile
\n
"
,
strerror
(
errno
));
goto
on_error_stop
;
goto
on_error_stop
;
}
}
if
((
uint64_t
)
st
.
st_size
!=
*
log
.
read_max
)
{
if
((
uint64_t
)
st
_buffer_log_file
.
st_size
!=
*
log
.
read_max
)
{
lxc_error
(
"On-disk logfile size and used ringbuffer size do "
lxc_error
(
"On-disk logfile size and used ringbuffer size do "
"not match: %"
PRIu64
" != %"
PRIu64
"
\n
"
,
"not match: %"
PRIu64
" != %"
PRIu64
"
\n
"
,
(
uint64_t
)
st
.
st_size
,
*
log
.
read_max
);
(
uint64_t
)
st
_buffer_log_file
.
st_size
,
*
log
.
read_max
);
goto
on_error_stop
;
goto
on_error_stop
;
}
}
...
@@ -192,8 +204,86 @@ int main(int argc, char *argv[])
...
@@ -192,8 +204,86 @@ int main(int argc, char *argv[])
goto
on_error_stop
;
goto
on_error_stop
;
}
else
{
}
else
{
lxc_debug
(
"Retrieved %"
PRIu64
" bytes from console log and "
lxc_debug
(
"Retrieved %"
PRIu64
" bytes from console log and "
"console log file. Contents are:
\"
%s
\"
-
\"
%s
\"\n
"
,
"console ringbuffer log file. Contents are:
\"
%s
\"
- "
*
log
.
read_max
,
log
.
data
,
buf
);
"
\"
%s
\"\n
"
,
*
log
.
read_max
,
log
.
data
,
buf
);
}
ret
=
stat
(
"/tmp/console-log.log"
,
&
st_log_file
);
if
(
ret
<
0
)
{
lxc_error
(
"%s - Failed to stat on-disk logfile
\n
"
,
strerror
(
errno
));
goto
on_error_stop
;
}
/* Turn on rotation for the console log file. */
if
(
!
c
->
set_config_item
(
c
,
"lxc.console.rotate"
,
"1"
))
{
lxc_error
(
"%s
\n
"
,
"Failed to set config item
\"
lxc.console.rotate
\"
"
);
goto
on_error_put
;
}
if
(
!
c
->
stop
(
c
))
{
lxc_error
(
"%s
\n
"
,
"Failed to stop container
\"
console-log
\"
"
);
goto
on_error_stop
;
}
if
(
!
c
->
startl
(
c
,
0
,
NULL
))
{
lxc_error
(
"%s
\n
"
,
"Failed to start container
\"
console-log
\"
daemonized"
);
goto
on_error_destroy
;
}
/* Leave some time for the container to write something to the log. */
sleep
(
2
);
/* The console log file size must be greater than the console log file
* size since we append to the latter and we truncated the former
* already.
*/
if
(
st_log_file
.
st_size
<=
st_buffer_log_file
.
st_size
)
{
lxc_error
(
"%s - Console log file size was smaller than the "
"console buffer log file size: %zu < %zu
\n
"
,
strerror
(
errno
),
(
size_t
)
st_log_file
.
st_size
,
(
size_t
)
st_buffer_log_file
.
st_size
);
goto
on_error_stop
;
}
else
{
lxc_debug
(
"Console log file size is %zu bytes and console "
"buffer log file size is %zu bytes
\n
"
,
(
size_t
)
st_log_file
.
st_size
,
(
size_t
)
st_buffer_log_file
.
st_size
);
}
ret
=
stat
(
"/tmp/console-log.log"
,
&
st_log_file
);
if
(
ret
<
0
)
{
lxc_error
(
"%s - Failed to stat on-disk logfile
\n
"
,
strerror
(
errno
));
goto
on_error_stop
;
}
log
.
read_max
=
&
(
uint64_t
){
0
};
log
.
read
=
false
;
log
.
write_logfile
=
false
;
log
.
clear
=
true
;
ret
=
c
->
console_log
(
c
,
&
log
);
if
(
ret
<
0
)
{
lxc_error
(
"%s - Failed to retrieve console log
\n
"
,
strerror
(
-
ret
));
goto
on_error_stop
;
}
/* There should now be a rotated log file called
* "/tmp/console-log.log.1"
*/
ret
=
stat
(
"/tmp/console-log.log.1"
,
&
st_log_file_old
);
if
(
ret
<
0
)
{
lxc_error
(
"%s - Failed to stat on-disk logfile
\n
"
,
strerror
(
errno
));
goto
on_error_stop
;
}
/* The rotated log file should have the same size as before the
* rotation.
*/
if
(
st_log_file
.
st_size
!=
st_log_file_old
.
st_size
)
{
lxc_error
(
"%s - Console log file size changed during log "
"rotation: %zu != %zu
\n
"
,
strerror
(
errno
),
(
size_t
)
st_log_file
.
st_size
,
(
size_t
)
st_log_file_old
.
st_size
);
goto
on_error_stop
;
}
}
fret
=
0
;
fret
=
0
;
...
@@ -211,7 +301,13 @@ on_error_put:
...
@@ -211,7 +301,13 @@ on_error_put:
if
(
do_unlink
)
{
if
(
do_unlink
)
{
ret
=
unlink
(
"/tmp/console-log.log"
);
ret
=
unlink
(
"/tmp/console-log.log"
);
if
(
ret
<
0
)
if
(
ret
<
0
)
lxc_error
(
"%s - Failed to remove container log file
\n
"
,
strerror
(
errno
));
lxc_error
(
"%s - Failed to remove container log file
\n
"
,
strerror
(
errno
));
ret
=
unlink
(
"/tmp/console-log.log.1"
);
if
(
ret
<
0
)
lxc_error
(
"%s - Failed to remove container log file
\n
"
,
strerror
(
errno
));
}
}
exit
(
fret
);
exit
(
fret
);
}
}
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