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
789ebbdb
Unverified
Commit
789ebbdb
authored
Oct 17, 2017
by
Stéphane Graber
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "init: rework dumb init"
Seems a bit invasive for a bugfix release. This reverts commit
f9d14b54
. Signed-off-by:
Stéphane Graber
<
stgraber@ubuntu.com
>
parent
49eb81b1
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
277 additions
and
306 deletions
+277
-306
Makefile.am
src/lxc/Makefile.am
+1
-2
execute.c
src/lxc/execute.c
+12
-15
initutils.c
src/lxc/initutils.c
+0
-106
initutils.h
src/lxc/initutils.h
+9
-34
lxccontainer.c
src/lxc/lxccontainer.c
+0
-1
lxc_init.c
src/lxc/tools/lxc_init.c
+125
-148
utils.c
src/lxc/utils.c
+129
-0
utils.h
src/lxc/utils.h
+1
-0
No files found.
src/lxc/Makefile.am
View file @
789ebbdb
...
...
@@ -298,8 +298,7 @@ endif
if
HAVE_STATIC_LIBCAP
sbin_PROGRAMS
+=
init.lxc.static
init_lxc_static_SOURCES
=
tools/lxc_init.c error.c log.c initutils.c caps.c
\
arguments.c
init_lxc_static_SOURCES
=
tools/lxc_init.c error.c log.c initutils.c caps.c
if
!HAVE_GETLINE
if
HAVE_FGETLN
...
...
src/lxc/execute.c
View file @
789ebbdb
...
...
@@ -64,36 +64,33 @@ static int execute_start(struct lxc_handler *handler, void* data)
initpath
=
choose_init
(
NULL
);
if
(
!
initpath
)
{
ERROR
(
"Failed to find an
init.lxc or init.lxc.stati
c"
);
ERROR
(
"Failed to find an
lxc-init or init.lx
c"
);
goto
out2
;
}
argv
[
i
++
]
=
initpath
;
argv
[
i
++
]
=
"-n"
;
argv
[
i
++
]
=
(
char
*
)
handler
->
name
;
if
(
lxc_log_has_valid_level
())
{
argv
[
i
++
]
=
"-l"
;
argv
[
i
++
]
=
(
char
*
)
lxc_log_priority_to_string
(
lxc_log_get_level
());
}
if
(
my_args
->
quiet
)
argv
[
i
++
]
=
"--quiet"
;
if
(
!
handler
->
conf
->
rootfs
.
path
)
{
argv
[
i
++
]
=
"-P"
;
argv
[
i
++
]
=
"--name"
;
argv
[
i
++
]
=
(
char
*
)
handler
->
name
;
argv
[
i
++
]
=
"--lxcpath"
;
argv
[
i
++
]
=
(
char
*
)
handler
->
lxcpath
;
}
if
(
lxc_log_has_valid_level
())
{
argv
[
i
++
]
=
"--logpriority"
;
argv
[
i
++
]
=
(
char
*
)
lxc_log_priority_to_string
(
lxc_log_get_level
());
}
}
argv
[
i
++
]
=
"--"
;
for
(
j
=
0
;
j
<
argc
;
j
++
)
argv
[
i
++
]
=
my_args
->
argv
[
j
];
argv
[
i
++
]
=
NULL
;
NOTICE
(
"
Exec'ing
\"
%s
\"
"
,
my_args
->
argv
[
0
]);
NOTICE
(
"
exec'ing '%s'
"
,
my_args
->
argv
[
0
]);
execvp
(
argv
[
0
],
argv
);
SYSERROR
(
"
F
ailed to exec %s"
,
argv
[
0
]);
SYSERROR
(
"
f
ailed to exec %s"
,
argv
[
0
]);
free
(
initpath
);
out2:
free
(
argv
);
...
...
src/lxc/initutils.c
View file @
789ebbdb
...
...
@@ -21,8 +21,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <sys/prctl.h>
#include "initutils.h"
#include "log.h"
...
...
@@ -298,107 +296,3 @@ FILE *fopen_cloexec(const char *path, const char *mode)
errno
=
saved_errno
;
return
ret
;
}
/*
* Sets the process title to the specified title. Note that this may fail if
* the kernel doesn't support PR_SET_MM_MAP (kernels <3.18).
*/
int
setproctitle
(
char
*
title
)
{
static
char
*
proctitle
=
NULL
;
char
buf
[
2048
],
*
tmp
;
FILE
*
f
;
int
i
,
len
,
ret
=
0
;
/* We don't really need to know all of this stuff, but unfortunately
* PR_SET_MM_MAP requires us to set it all at once, so we have to
* figure it out anyway.
*/
unsigned
long
start_data
,
end_data
,
start_brk
,
start_code
,
end_code
,
start_stack
,
arg_start
,
arg_end
,
env_start
,
env_end
,
brk_val
;
struct
prctl_mm_map
prctl_map
;
f
=
fopen_cloexec
(
"/proc/self/stat"
,
"r"
);
if
(
!
f
)
{
return
-
1
;
}
tmp
=
fgets
(
buf
,
sizeof
(
buf
),
f
);
fclose
(
f
);
if
(
!
tmp
)
{
return
-
1
;
}
/* Skip the first 25 fields, column 26-28 are start_code, end_code,
* and start_stack */
tmp
=
strchr
(
buf
,
' '
);
for
(
i
=
0
;
i
<
24
;
i
++
)
{
if
(
!
tmp
)
return
-
1
;
tmp
=
strchr
(
tmp
+
1
,
' '
);
}
if
(
!
tmp
)
return
-
1
;
i
=
sscanf
(
tmp
,
"%lu %lu %lu"
,
&
start_code
,
&
end_code
,
&
start_stack
);
if
(
i
!=
3
)
return
-
1
;
/* Skip the next 19 fields, column 45-51 are start_data to arg_end */
for
(
i
=
0
;
i
<
19
;
i
++
)
{
if
(
!
tmp
)
return
-
1
;
tmp
=
strchr
(
tmp
+
1
,
' '
);
}
if
(
!
tmp
)
return
-
1
;
i
=
sscanf
(
tmp
,
"%lu %lu %lu %*u %*u %lu %lu"
,
&
start_data
,
&
end_data
,
&
start_brk
,
&
env_start
,
&
env_end
);
if
(
i
!=
5
)
return
-
1
;
/* Include the null byte here, because in the calculations below we
* want to have room for it. */
len
=
strlen
(
title
)
+
1
;
proctitle
=
realloc
(
proctitle
,
len
);
if
(
!
proctitle
)
return
-
1
;
arg_start
=
(
unsigned
long
)
proctitle
;
arg_end
=
arg_start
+
len
;
brk_val
=
syscall
(
__NR_brk
,
0
);
prctl_map
=
(
struct
prctl_mm_map
)
{
.
start_code
=
start_code
,
.
end_code
=
end_code
,
.
start_stack
=
start_stack
,
.
start_data
=
start_data
,
.
end_data
=
end_data
,
.
start_brk
=
start_brk
,
.
brk
=
brk_val
,
.
arg_start
=
arg_start
,
.
arg_end
=
arg_end
,
.
env_start
=
env_start
,
.
env_end
=
env_end
,
.
auxv
=
NULL
,
.
auxv_size
=
0
,
.
exe_fd
=
-
1
,
};
ret
=
prctl
(
PR_SET_MM
,
PR_SET_MM_MAP
,
(
long
)
&
prctl_map
,
sizeof
(
prctl_map
),
0
);
if
(
ret
==
0
)
strcpy
((
char
*
)
arg_start
,
title
);
else
INFO
(
"setting cmdline failed - %s"
,
strerror
(
errno
));
return
ret
;
}
src/lxc/initutils.h
View file @
789ebbdb
...
...
@@ -25,16 +25,17 @@
#define __LXC_INITUTILS_H
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mount.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include "config.h"
...
...
@@ -43,37 +44,11 @@
#define DEFAULT_ZFSROOT "lxc"
#define DEFAULT_RBDPOOL "lxc"
#ifndef PR_SET_MM
#define PR_SET_MM 35
#endif
#ifndef PR_SET_MM_MAP
#define PR_SET_MM_MAP 14
struct
prctl_mm_map
{
uint64_t
start_code
;
uint64_t
end_code
;
uint64_t
start_data
;
uint64_t
end_data
;
uint64_t
start_brk
;
uint64_t
brk
;
uint64_t
start_stack
;
uint64_t
arg_start
;
uint64_t
arg_end
;
uint64_t
env_start
;
uint64_t
env_end
;
uint64_t
*
auxv
;
uint32_t
auxv_size
;
uint32_t
exe_fd
;
};
#endif
extern
void
lxc_setup_fs
(
void
);
extern
const
char
*
lxc_global_config_value
(
const
char
*
option_name
);
/* open a file with O_CLOEXEC */
extern
void
remove_trailing_slashes
(
char
*
p
);
extern
FILE
*
fopen_cloexec
(
const
char
*
path
,
const
char
*
mode
);
extern
int
setproctitle
(
char
*
title
);
FILE
*
fopen_cloexec
(
const
char
*
path
,
const
char
*
mode
);
#endif
/* __LXC_INITUTILS_H */
src/lxc/lxccontainer.c
View file @
789ebbdb
...
...
@@ -50,7 +50,6 @@
#include "confile_utils.h"
#include "console.h"
#include "criu.h"
#include "initutils.h"
#include "log.h"
#include "lxc.h"
#include "lxccontainer.h"
...
...
src/lxc/tools/lxc_init.c
View file @
789ebbdb
...
...
@@ -22,27 +22,35 @@
*/
#define _GNU_SOURCE
#include <errno.h>
#include <getopt.h>
#include <libgen.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <libgen.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <getopt.h>
#include <lxc/lxccontainer.h>
#include "
arguments
.h"
#include "
log
.h"
#include "error.h"
#include "initutils.h"
#include "log.h"
lxc_log_define
(
lxc_init
,
lxc
);
static
int
quiet
;
static
const
struct
option
options
[]
=
{
{
"name"
,
required_argument
,
NULL
,
'n'
},
{
"logpriority"
,
required_argument
,
NULL
,
'l'
},
{
"quiet"
,
no_argument
,
NULL
,
'q'
},
{
"lxcpath"
,
required_argument
,
NULL
,
'P'
},
{
0
,
0
,
0
,
0
},
};
static
sig_atomic_t
was_interrupted
=
0
;
static
void
interrupt_handler
(
int
sig
)
...
...
@@ -51,124 +59,114 @@ static void interrupt_handler(int sig)
was_interrupted
=
sig
;
}
static
const
struct
option
my_longopts
[]
=
{
LXC_COMMON_OPTIONS
};
static
int
my_parser
(
struct
lxc_arguments
*
args
,
int
c
,
char
*
arg
)
{
return
0
;
static
void
usage
(
void
)
{
fprintf
(
stderr
,
"Usage: lxc-init [OPTION]...
\n\n
"
"Common options :
\n
"
" -n, --name=NAME NAME of the container
\n
"
" -l, --logpriority=LEVEL Set log priority to LEVEL
\n
"
" -q, --quiet Don't produce any output
\n
"
" -P, --lxcpath=PATH Use specified container path
\n
"
" -?, --help Give this help list
\n
"
"
\n
"
"Mandatory or optional arguments to long options are also mandatory or optional
\n
"
"for any corresponding short options.
\n
"
"
\n
"
"NOTE: lxc-init is intended for use by lxc internally
\n
"
" and does not need to be run by hand
\n\n
"
);
}
static
struct
lxc_arguments
my_args
=
{
.
progname
=
"lxc-init"
,
.
help
=
"\
--name=NAME -- COMMAND
\n
\
\n
\
lxc-init start a COMMAND as PID 2 inside a container
\n
\
\n
\
Options :
\n
\
-n, --name=NAME NAME of the container
\n
\
"
,
.
options
=
my_longopts
,
.
parser
=
my_parser
,
};
int
main
(
int
argc
,
char
*
argv
[])
{
int
i
,
ret
;
pid_t
pid
,
sid
;
int
err
;
char
**
aargv
;
sigset_t
mask
,
omask
;
struct
sigaction
act
;
int
i
,
have_status
=
0
,
shutdown
=
0
;
int
opt
;
char
*
lxcpath
=
NULL
,
*
name
=
NULL
,
*
logpriority
=
NULL
;
struct
lxc_log
log
;
sigset_t
mask
,
omask
;
int
have_status
=
0
,
shutdown
=
0
;
if
(
lxc_arguments_parse
(
&
my_args
,
argc
,
argv
))
exit
(
EXIT_FAILURE
);
while
((
opt
=
getopt_long
(
argc
,
argv
,
"n:l:qP:"
,
options
,
NULL
))
!=
-
1
)
{
switch
(
opt
)
{
case
'n'
:
name
=
optarg
;
break
;
case
'l'
:
logpriority
=
optarg
;
break
;
case
'q'
:
quiet
=
1
;
break
;
case
'P'
:
lxcpath
=
optarg
;
break
;
default:
/* '?' */
usage
();
exit
(
EXIT_FAILURE
);
}
}
log
.
name
=
my_args
.
name
;
log
.
file
=
my_args
.
log_file
;
log
.
level
=
my_args
.
log_
priority
;
log
.
prefix
=
my_args
.
progname
;
log
.
quiet
=
my_args
.
quiet
;
log
.
lxcpath
=
my_args
.
lxcpath
[
0
]
;
log
.
name
=
name
;
log
.
file
=
name
?
NULL
:
"none"
;
log
.
level
=
log
priority
;
log
.
prefix
=
basename
(
argv
[
0
])
;
log
.
quiet
=
quiet
;
log
.
lxcpath
=
lxcpath
;
ret
=
lxc_log_init
(
&
log
);
if
(
ret
<
0
)
err
=
lxc_log_init
(
&
log
);
if
(
err
<
0
)
exit
(
EXIT_FAILURE
);
lxc_log_options_no_override
();
if
(
!
my_args
.
argc
)
{
ERROR
(
"
Please specify a command to execute
"
);
if
(
!
argv
[
optind
]
)
{
ERROR
(
"
Missing command to launch
"
);
exit
(
EXIT_FAILURE
);
}
/* Mask all the signals so we are safe to install a signal handler and
* to fork.
*/
ret
=
sigfillset
(
&
mask
);
if
(
ret
<
0
)
exit
(
EXIT_FAILURE
);
ret
=
sigdelset
(
&
mask
,
SIGILL
);
if
(
ret
<
0
)
exit
(
EXIT_FAILURE
);
ret
=
sigdelset
(
&
mask
,
SIGSEGV
);
if
(
ret
<
0
)
exit
(
EXIT_FAILURE
);
ret
=
sigdelset
(
&
mask
,
SIGBUS
);
if
(
ret
<
0
)
exit
(
EXIT_FAILURE
);
ret
=
sigprocmask
(
SIG_SETMASK
,
&
mask
,
&
omask
);
if
(
ret
<
0
)
exit
(
EXIT_FAILURE
);
ret
=
sigfillset
(
&
act
.
sa_mask
);
if
(
ret
<
0
)
exit
(
EXIT_FAILURE
);
ret
=
sigdelset
(
&
act
.
sa_mask
,
SIGILL
);
if
(
ret
<
0
)
exit
(
EXIT_FAILURE
);
ret
=
sigdelset
(
&
act
.
sa_mask
,
SIGSEGV
);
if
(
ret
<
0
)
exit
(
EXIT_FAILURE
);
aargv
=
&
argv
[
optind
];
ret
=
sigdelset
(
&
act
.
sa_mask
,
SIGBUS
);
if
(
ret
<
0
)
exit
(
EXIT_FAILURE
);
ret
=
sigdelset
(
&
act
.
sa_mask
,
SIGSTOP
);
if
(
ret
<
0
)
/*
* mask all the signals so we are safe to install a
* signal handler and to fork
*/
if
(
sigfillset
(
&
mask
)
||
sigdelset
(
&
mask
,
SIGILL
)
||
sigdelset
(
&
mask
,
SIGSEGV
)
||
sigdelset
(
&
mask
,
SIGBUS
)
||
sigprocmask
(
SIG_SETMASK
,
&
mask
,
&
omask
))
{
SYSERROR
(
"Failed to set signal mask"
);
exit
(
EXIT_FAILURE
);
}
ret
=
sigdelset
(
&
act
.
sa_mask
,
SIGKILL
);
if
(
ret
<
0
)
if
(
sigfillset
(
&
act
.
sa_mask
)
||
sigdelset
(
&
act
.
sa_mask
,
SIGILL
)
||
sigdelset
(
&
act
.
sa_mask
,
SIGSEGV
)
||
sigdelset
(
&
act
.
sa_mask
,
SIGBUS
)
||
sigdelset
(
&
act
.
sa_mask
,
SIGSTOP
)
||
sigdelset
(
&
act
.
sa_mask
,
SIGKILL
))
{
ERROR
(
"Failed to set signal"
);
exit
(
EXIT_FAILURE
);
}
act
.
sa_flags
=
0
;
act
.
sa_handler
=
interrupt_handler
;
for
(
i
=
1
;
i
<
NSIG
;
i
++
)
{
/* Exclude some signals: ILL, SEGV and BUS are likely to
reveal
*
a bug and we want a core. STOP and KILL cannot be handled
*
anyway: they're here for documentation. 32 and 33 are not
* defined.
/* Exclude some signals: ILL, SEGV and BUS are likely to
*
reveal a bug and we want a core. STOP and KILL cannot be
*
handled anyway: they're here for documentation. 32 and 33
*
are not
defined.
*/
if
(
i
==
SIGILL
||
i
==
SIGSEGV
||
i
==
SIGBUS
||
i
==
SIGSTOP
||
i
==
SIGKILL
||
i
==
32
||
i
==
33
)
if
(
i
==
SIGILL
||
i
==
SIGSEGV
||
i
==
SIGBUS
||
i
==
SIGSTOP
||
i
==
SIGKILL
||
i
==
32
||
i
==
33
)
continue
;
ret
=
sigaction
(
i
,
&
act
,
NULL
);
if
(
ret
<
0
)
{
if
(
errno
==
EINVAL
)
continue
;
SYSERROR
(
"Failed to change signal action"
);
if
(
sigaction
(
i
,
&
act
,
NULL
)
&&
errno
!=
EINVAL
)
{
SYSERROR
(
"Failed to sigaction"
);
exit
(
EXIT_FAILURE
);
}
}
...
...
@@ -180,19 +178,13 @@ int main(int argc, char *argv[])
exit
(
EXIT_FAILURE
);
if
(
!
pid
)
{
int
ret
;
/* restore default signal handlers */
for
(
i
=
1
;
i
<
NSIG
;
i
++
)
{
sighandler_t
sigerr
;
sigerr
=
signal
(
i
,
SIG_DFL
);
if
(
sigerr
==
SIG_ERR
)
{
DEBUG
(
"%s - Failed to reset to default action "
"for signal
\"
%d
\"
: %d"
,
strerror
(
errno
),
i
,
pid
);
}
}
for
(
i
=
1
;
i
<
NSIG
;
i
++
)
signal
(
i
,
SIG_DFL
);
ret
=
sigprocmask
(
SIG_SETMASK
,
&
omask
,
NULL
);
if
(
ret
<
0
)
{
if
(
sigprocmask
(
SIG_SETMASK
,
&
omask
,
NULL
))
{
SYSERROR
(
"Failed to set signal mask"
);
exit
(
EXIT_FAILURE
);
}
...
...
@@ -201,31 +193,25 @@ int main(int argc, char *argv[])
if
(
sid
<
0
)
DEBUG
(
"Failed to make child session leader"
);
NOTICE
(
"
Exec'ing
\"
%s
\"
"
,
my_args
.
argv
[
0
]);
NOTICE
(
"
About to exec '%s'"
,
a
argv
[
0
]);
ret
=
execvp
(
my_args
.
argv
[
0
],
my_args
.
argv
);
ERROR
(
"
%s - Failed to exec
\"
%s
\"
"
,
strerror
(
errno
),
my_args
.
argv
[
0
]
);
ret
=
execvp
(
aargv
[
0
],
a
argv
);
ERROR
(
"
Failed to exec: '%s' : %s"
,
aargv
[
0
],
strerror
(
errno
)
);
exit
(
ret
);
}
INFO
(
"Attempting to set proc title to
\"
init
\"
"
);
setproctitle
(
"init"
);
/* Let's process the signals now. */
ret
=
sigdelset
(
&
omask
,
SIGALRM
);
if
(
ret
<
0
)
exit
(
EXIT_FAILURE
);
ret
=
sigprocmask
(
SIG_SETMASK
,
&
omask
,
NULL
);
if
(
ret
<
0
)
{
/* let's process the signals now */
if
(
sigdelset
(
&
omask
,
SIGALRM
)
||
sigprocmask
(
SIG_SETMASK
,
&
omask
,
NULL
))
{
SYSERROR
(
"Failed to set signal mask"
);
exit
(
EXIT_FAILURE
);
}
/*
No need of other inherited fds but stderr.
*/
close
(
STDIN_FILENO
);
close
(
STDOUT_FILENO
);
/*
no need of other inherited fds but stderr
*/
close
(
fileno
(
stdin
)
);
close
(
fileno
(
stdout
)
);
err
=
EXIT_SUCCESS
;
for
(;;)
{
int
status
;
pid_t
waited_pid
;
...
...
@@ -237,56 +223,47 @@ int main(int argc, char *argv[])
case
SIGTERM
:
if
(
!
shutdown
)
{
shutdown
=
1
;
ret
=
kill
(
-
1
,
SIGTERM
);
if
(
ret
<
0
)
DEBUG
(
"%s - Failed to send SIGTERM to "
"all children"
,
strerror
(
errno
));
kill
(
-
1
,
SIGTERM
);
alarm
(
1
);
}
break
;
case
SIGALRM
:
ret
=
kill
(
-
1
,
SIGKILL
);
if
(
ret
<
0
)
DEBUG
(
"%s - Failed to send SIGKILL to all "
"children"
,
strerror
(
errno
));
kill
(
-
1
,
SIGKILL
);
break
;
default:
ret
=
kill
(
pid
,
was_interrupted
);
if
(
ret
<
0
)
DEBUG
(
"%s - Failed to send signal
\"
%d
\"
to "
"%d"
,
strerror
(
errno
),
was_interrupted
,
pid
);
kill
(
pid
,
was_interrupted
);
break
;
}
ret
=
EXIT_SUCCESS
;
was_interrupted
=
0
;
waited_pid
=
wait
(
&
status
);
if
(
waited_pid
<
0
)
{
if
(
errno
==
ECHILD
)
goto
out
;
if
(
errno
==
EINTR
)
continue
;
ERROR
(
"
%s - Failed to wait on child %d
"
,
strerror
(
errno
)
,
pid
);
ERROR
(
"
Failed to wait child : %s
"
,
strerror
(
errno
));
goto
out
;
}
/*
Reset timer each time a process exited.
*/
/*
reset timer each time a process exited
*/
if
(
shutdown
)
alarm
(
1
);
/* Keep the exit code of the started application (not wrapped
* pid) and continue to wait for the end of the orphan group.
/*
* keep the exit code of started application
* (not wrapped pid) and continue to wait for
* the end of the orphan group.
*/
if
(
waited_pid
==
pid
&&
!
have_status
)
{
ret
=
lxc_error_set_and_log
(
waited_pid
,
status
);
err
=
lxc_error_set_and_log
(
waited_pid
,
status
);
have_status
=
1
;
}
}
out:
if
(
ret
<
0
)
if
(
err
<
0
)
exit
(
EXIT_FAILURE
);
exit
(
ret
);
exit
(
err
);
}
src/lxc/utils.c
View file @
789ebbdb
...
...
@@ -49,6 +49,31 @@
#include "namespace.h"
#include "utils.h"
#ifndef PR_SET_MM
#define PR_SET_MM 35
#endif
#ifndef PR_SET_MM_MAP
#define PR_SET_MM_MAP 14
struct
prctl_mm_map
{
uint64_t
start_code
;
uint64_t
end_code
;
uint64_t
start_data
;
uint64_t
end_data
;
uint64_t
start_brk
;
uint64_t
brk
;
uint64_t
start_stack
;
uint64_t
arg_start
;
uint64_t
arg_end
;
uint64_t
env_start
;
uint64_t
env_end
;
uint64_t
*
auxv
;
uint32_t
auxv_size
;
uint32_t
exe_fd
;
};
#endif
#ifndef O_PATH
#define O_PATH 010000000
#endif
...
...
@@ -1346,6 +1371,110 @@ char *get_template_path(const char *t)
}
/*
* Sets the process title to the specified title. Note that this may fail if
* the kernel doesn't support PR_SET_MM_MAP (kernels <3.18).
*/
int
setproctitle
(
char
*
title
)
{
static
char
*
proctitle
=
NULL
;
char
buf
[
2048
],
*
tmp
;
FILE
*
f
;
int
i
,
len
,
ret
=
0
;
/* We don't really need to know all of this stuff, but unfortunately
* PR_SET_MM_MAP requires us to set it all at once, so we have to
* figure it out anyway.
*/
unsigned
long
start_data
,
end_data
,
start_brk
,
start_code
,
end_code
,
start_stack
,
arg_start
,
arg_end
,
env_start
,
env_end
,
brk_val
;
struct
prctl_mm_map
prctl_map
;
f
=
fopen_cloexec
(
"/proc/self/stat"
,
"r"
);
if
(
!
f
)
{
return
-
1
;
}
tmp
=
fgets
(
buf
,
sizeof
(
buf
),
f
);
fclose
(
f
);
if
(
!
tmp
)
{
return
-
1
;
}
/* Skip the first 25 fields, column 26-28 are start_code, end_code,
* and start_stack */
tmp
=
strchr
(
buf
,
' '
);
for
(
i
=
0
;
i
<
24
;
i
++
)
{
if
(
!
tmp
)
return
-
1
;
tmp
=
strchr
(
tmp
+
1
,
' '
);
}
if
(
!
tmp
)
return
-
1
;
i
=
sscanf
(
tmp
,
"%lu %lu %lu"
,
&
start_code
,
&
end_code
,
&
start_stack
);
if
(
i
!=
3
)
return
-
1
;
/* Skip the next 19 fields, column 45-51 are start_data to arg_end */
for
(
i
=
0
;
i
<
19
;
i
++
)
{
if
(
!
tmp
)
return
-
1
;
tmp
=
strchr
(
tmp
+
1
,
' '
);
}
if
(
!
tmp
)
return
-
1
;
i
=
sscanf
(
tmp
,
"%lu %lu %lu %*u %*u %lu %lu"
,
&
start_data
,
&
end_data
,
&
start_brk
,
&
env_start
,
&
env_end
);
if
(
i
!=
5
)
return
-
1
;
/* Include the null byte here, because in the calculations below we
* want to have room for it. */
len
=
strlen
(
title
)
+
1
;
proctitle
=
realloc
(
proctitle
,
len
);
if
(
!
proctitle
)
return
-
1
;
arg_start
=
(
unsigned
long
)
proctitle
;
arg_end
=
arg_start
+
len
;
brk_val
=
syscall
(
__NR_brk
,
0
);
prctl_map
=
(
struct
prctl_mm_map
)
{
.
start_code
=
start_code
,
.
end_code
=
end_code
,
.
start_stack
=
start_stack
,
.
start_data
=
start_data
,
.
end_data
=
end_data
,
.
start_brk
=
start_brk
,
.
brk
=
brk_val
,
.
arg_start
=
arg_start
,
.
arg_end
=
arg_end
,
.
env_start
=
env_start
,
.
env_end
=
env_end
,
.
auxv
=
NULL
,
.
auxv_size
=
0
,
.
exe_fd
=
-
1
,
};
ret
=
prctl
(
PR_SET_MM
,
PR_SET_MM_MAP
,
(
long
)
&
prctl_map
,
sizeof
(
prctl_map
),
0
);
if
(
ret
==
0
)
strcpy
((
char
*
)
arg_start
,
title
);
else
INFO
(
"setting cmdline failed - %s"
,
strerror
(
errno
));
return
ret
;
}
/*
* @path: a pathname where / replaced with '\0'.
* @offsetp: pointer to int showing which path segment was last seen.
* Updated on return to reflect the next segment.
...
...
src/lxc/utils.h
View file @
789ebbdb
...
...
@@ -339,6 +339,7 @@ extern int print_to_file(const char *file, const char *content);
extern
bool
switch_to_ns
(
pid_t
pid
,
const
char
*
ns
);
extern
int
is_dir
(
const
char
*
path
);
extern
char
*
get_template_path
(
const
char
*
t
);
extern
int
setproctitle
(
char
*
title
);
extern
int
safe_mount
(
const
char
*
src
,
const
char
*
dest
,
const
char
*
fstype
,
unsigned
long
flags
,
const
void
*
data
,
const
char
*
rootfs
);
...
...
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