Skip to content

Commit

Permalink
lxc_init: add custom argument parser
Browse files Browse the repository at this point in the history
lxc_init.c should not depend on tools/arguments.{c,h}, thus it needs its own custom argument parser

Signed-off-by: RicardoSanchezA <ricardo.sanchez@utexas.edu>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
  • Loading branch information
RicardoSanchezA authored and Christian Brauner committed Dec 15, 2017
1 parent 09d14a7 commit 5fb5c04
Show file tree
Hide file tree
Showing 6 changed files with 446 additions and 269 deletions.
5 changes: 2 additions & 3 deletions src/lxc/Makefile.am
Expand Up @@ -275,7 +275,7 @@ lxc_device_SOURCES = tools/lxc_device.c tools/arguments.c
lxc_execute_SOURCES = tools/lxc_execute.c tools/arguments.c
lxc_freeze_SOURCES = tools/lxc_freeze.c tools/arguments.c
lxc_info_SOURCES = tools/lxc_info.c tools/arguments.c
init_lxc_SOURCES = lxc_init.c tools/arguments.c
init_lxc_SOURCES = lxc_init.c
lxc_monitor_SOURCES = tools/lxc_monitor.c tools/arguments.c
lxc_ls_SOURCES = tools/lxc_ls.c tools/arguments.c
lxc_copy_SOURCES = tools/lxc_copy.c tools/arguments.c
Expand Down Expand Up @@ -303,8 +303,7 @@ endif
if HAVE_STATIC_LIBCAP
sbin_PROGRAMS += init.lxc.static

init_lxc_static_SOURCES = lxc_init.c error.c log.c initutils.c caps.c \
tools/arguments.c
init_lxc_static_SOURCES = lxc_init.c error.c log.c initutils.c caps.c

if !HAVE_GETLINE
if HAVE_FGETLN
Expand Down
106 changes: 106 additions & 0 deletions src/lxc/initutils.c
Expand Up @@ -21,6 +21,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <sys/prctl.h>

#include "initutils.h"
#include "log.h"

Expand Down Expand Up @@ -296,3 +298,107 @@ 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;
}
43 changes: 34 additions & 9 deletions src/lxc/initutils.h
Expand Up @@ -25,17 +25,16 @@
#define __LXC_INITUTILS_H

#include <errno.h>
#include <stdio.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 <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"

Expand All @@ -44,11 +43,37 @@
#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);
FILE *fopen_cloexec(const char *path, const char *mode);
extern FILE *fopen_cloexec(const char *path, const char *mode);
extern int setproctitle(char *title);

#endif /* __LXC_INITUTILS_H */

0 comments on commit 5fb5c04

Please sign in to comment.