Blame hugectl.c

Packit 2d622a
/***************************************************************************
Packit 2d622a
 *   User front end for using huge pages Copyright (C) 2008, IBM           *
Packit 2d622a
 *                                                                         *
Packit 2d622a
 *   This program is free software; you can redistribute it and/or modify  *
Packit 2d622a
 *   it under the terms of the Lesser GNU General Public License as        *
Packit 2d622a
 *   published by the Free Software Foundation; either version 2.1 of the  *
Packit 2d622a
 *   License, or at your option) any later version.                        *
Packit 2d622a
 *                                                                         *
Packit 2d622a
 *   This program is distributed in the hope that it will be useful,       *
Packit 2d622a
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
Packit 2d622a
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
Packit 2d622a
 *   GNU Lesser General Public License for more details.                   *
Packit 2d622a
 *                                                                         *
Packit 2d622a
 *   You should have received a copy of the Lesser GNU General Public      *
Packit 2d622a
 *   License along with this program; if not, write to the                 *
Packit 2d622a
 *   Free Software Foundation, Inc.,                                       *
Packit 2d622a
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
Packit 2d622a
 ***************************************************************************/
Packit 2d622a
Packit 2d622a
/*
Packit 2d622a
 * hugectl is inspired by numactl as a single front end to a large number of
Packit 2d622a
 * options for controlling a very specific environment.  Eventually it will
Packit 2d622a
 * have support for controlling the all of the environment variables for
Packit 2d622a
 * libhugetlbfs, but options will only be added after they have been in the
Packit 2d622a
 * library for some time and are throughly tested and stable.
Packit 2d622a
 *
Packit 2d622a
 * This program should be treated as an ABI for using libhugetlbfs.
Packit 2d622a
 */
Packit 2d622a
Packit 2d622a
#include <stdlib.h>
Packit 2d622a
#include <stdio.h>
Packit 2d622a
#include <errno.h>
Packit 2d622a
#include <string.h>
Packit 2d622a
#include <limits.h>
Packit 2d622a
Packit 2d622a
#define _GNU_SOURCE /* for getopt_long */
Packit 2d622a
#include <unistd.h>
Packit 2d622a
#include <getopt.h>
Packit 2d622a
Packit 2d622a
#define REPORT(level, prefix, format, ...)				      \
Packit 2d622a
	do {								      \
Packit 2d622a
		if (verbose_level >= level)				      \
Packit 2d622a
			fprintf(stderr, "hugectl: " prefix ": " format,	      \
Packit 2d622a
				##__VA_ARGS__);				      \
Packit 2d622a
	} while (0);
Packit 2d622a
Packit 2d622a
#include "libhugetlbfs_debug.h"
Packit 2d622a
Packit 2d622a
extern int errno;
Packit 2d622a
extern int optind;
Packit 2d622a
extern char *optarg;
Packit 2d622a
Packit 2d622a
#define OPTION(opts, text)	fprintf(stderr, " %-25s  %s\n", opts, text)
Packit 2d622a
#define CONT(text) 		fprintf(stderr, " %-25s  %s\n", "", text)
Packit 2d622a
Packit 2d622a
void print_usage()
Packit 2d622a
{
Packit 2d622a
	fprintf(stderr, "hugectl [options] target\n");
Packit 2d622a
	fprintf(stderr, "options:\n");
Packit 2d622a
Packit 2d622a
	OPTION("--help, -h", "Prints this message");
Packit 2d622a
	OPTION("--verbose <level>, -v", "Increases/sets tracing levels");
Packit 2d622a
Packit 2d622a
	OPTION("--text[=<size>]", "Requests remapping of the program text");
Packit 2d622a
	OPTION("--data[=<size>]", "Requests remapping of the program data");
Packit 2d622a
	OPTION("--bss[=<size>]", "Requests remapping of the program bss");
Packit 2d622a
	OPTION("--heap[=<size>]", "Requests remapping of the program heap");
Packit 2d622a
	CONT("(malloc space)");
Packit 2d622a
	OPTION("--shm", "Requests remapping of shared memory segments");
Packit 2d622a
	OPTION("--thp", "Setup the heap space to be aligned for merging");
Packit 2d622a
	CONT("by khugepaged into huge pages.  This requires");
Packit 2d622a
	CONT("kernel support for transparent huge pages to be");
Packit 2d622a
	CONT("enabled");
Packit 2d622a
Packit 2d622a
	OPTION("--no-preload", "Disable preloading the libhugetlbfs library");
Packit 2d622a
	OPTION("--no-reserve", "Disable huge page reservation for segments");
Packit 2d622a
	OPTION("--force-preload", "Force preloading the libhugetlbfs library");
Packit 2d622a
Packit 2d622a
	OPTION("--dry-run", "describe what would be done without doing it");
Packit 2d622a
Packit 2d622a
	OPTION("--library-use-path", "Use the system library path");
Packit 2d622a
	OPTION("--share-text", "Share text segments between multiple");
Packit 2d622a
	CONT("application instances");
Packit 2d622a
	OPTION("--library-path <path>", "Select a library prefix");
Packit 2d622a
	CONT("(Default: "
Packit 2d622a
#ifdef LIBDIR32
Packit 2d622a
		LIBDIR32 ":"
Packit 2d622a
#endif
Packit 2d622a
#ifdef LIBDIR32
Packit 2d622a
		LIBDIR32 ":"
Packit 2d622a
#endif
Packit 2d622a
		")");
Packit 2d622a
}
Packit 2d622a
Packit 2d622a
int opt_dry_run = 0;
Packit 2d622a
int opt_force_preload = 0;
Packit 2d622a
int verbose_level = VERBOSITY_DEFAULT;
Packit 2d622a
Packit 2d622a
void verbose_init(void)
Packit 2d622a
{
Packit 2d622a
	char *env;
Packit 2d622a
Packit 2d622a
	env = getenv("HUGETLB_VERBOSE");
Packit 2d622a
	if (env)
Packit 2d622a
		verbose_level = atoi(env);
Packit 2d622a
	env = getenv("HUGETLB_DEBUG");
Packit 2d622a
	if (env)
Packit 2d622a
		verbose_level = VERBOSITY_MAX;
Packit 2d622a
}
Packit 2d622a
Packit 2d622a
void verbose(char *which)
Packit 2d622a
{
Packit 2d622a
	int new_level;
Packit 2d622a
Packit 2d622a
	if (which) {
Packit 2d622a
		new_level = atoi(which);
Packit 2d622a
		if (new_level < 0 || new_level > 99) {
Packit 2d622a
			ERROR("%d: verbosity out of range 0-99\n",
Packit 2d622a
				new_level);
Packit 2d622a
			exit(EXIT_FAILURE);
Packit 2d622a
		}
Packit 2d622a
	} else {
Packit 2d622a
		new_level = verbose_level + 1;
Packit 2d622a
		if (new_level == 100) {
Packit 2d622a
			WARNING("verbosity limited to 99\n");
Packit 2d622a
			new_level--;
Packit 2d622a
		}
Packit 2d622a
	}
Packit 2d622a
	verbose_level = new_level;
Packit 2d622a
}
Packit 2d622a
Packit 2d622a
void quiet(void)
Packit 2d622a
{
Packit 2d622a
	int new_level = verbose_level - 1;
Packit 2d622a
	if (new_level < 0) {
Packit 2d622a
		WARNING("verbosity must be at least 0\n");
Packit 2d622a
		new_level = 0;
Packit 2d622a
	}
Packit 2d622a
	verbose_level = new_level;
Packit 2d622a
}
Packit 2d622a
Packit 2d622a
void setup_environment(char *var, char *val)
Packit 2d622a
{
Packit 2d622a
	setenv(var, val, 1);
Packit 2d622a
	INFO("%s='%s'\n", var, val);
Packit 2d622a
Packit 2d622a
	if (opt_dry_run)
Packit 2d622a
		printf("%s='%s'\n", var, val);
Packit 2d622a
}
Packit 2d622a
Packit 2d622a
void verbose_expose(void)
Packit 2d622a
{
Packit 2d622a
	char level[3];
Packit 2d622a
Packit 2d622a
	if (verbose_level == 99) {
Packit 2d622a
		setup_environment("HUGETLB_DEBUG", "yes");
Packit 2d622a
	}
Packit 2d622a
	snprintf(level, sizeof(level), "%d", verbose_level);
Packit 2d622a
	setup_environment("HUGETLB_VERBOSE", level);
Packit 2d622a
}
Packit 2d622a
Packit 2d622a
/*
Packit 2d622a
 * getopts return values for options which are long only.
Packit 2d622a
 */
Packit 2d622a
#define MAP_BASE	0x1000
Packit 2d622a
#define LONG_BASE	0x2000
Packit 2d622a
Packit 2d622a
#define LONG_NO_PRELOAD		(LONG_BASE | 'p')
Packit 2d622a
#define LONG_NO_RESERVE		(LONG_BASE | 'r')
Packit 2d622a
#define LONG_FORCE_PRELOAD	(LONG_BASE | 'F')
Packit 2d622a
Packit 2d622a
#define LONG_DRY_RUN		(LONG_BASE | 'd')
Packit 2d622a
Packit 2d622a
#define LONG_SHARE		(LONG_BASE | 's')
Packit 2d622a
#define LONG_NO_LIBRARY		(LONG_BASE | 'L')
Packit 2d622a
#define LONG_LIBRARY		(LONG_BASE | 'l')
Packit 2d622a
Packit 2d622a
#define LONG_THP_HEAP		('t')
Packit 2d622a
Packit 2d622a
/*
Packit 2d622a
 * Mapping selectors, one per remappable/backable area as requested
Packit 2d622a
 * by the user.  These are also used as returns from getopts where they
Packit 2d622a
 * are offset from MAP_BASE, which must be removed before they are compared.
Packit 2d622a
 */
Packit 2d622a
enum {
Packit 2d622a
	MAP_TEXT,
Packit 2d622a
	MAP_DATA,
Packit 2d622a
	MAP_BSS,
Packit 2d622a
	MAP_HEAP,
Packit 2d622a
	MAP_SHM,
Packit 2d622a
	MAP_DISABLE,
Packit 2d622a
Packit 2d622a
	MAP_COUNT,
Packit 2d622a
};
Packit 2d622a
char *map_size[MAP_COUNT];
Packit 2d622a
Packit 2d622a
char default_size[] = "the default hugepage size";
Packit 2d622a
#define DEFAULT_SIZE default_size
Packit 2d622a
Packit 2d622a
#define available(buf, ptr) ((int)(sizeof(buf) - (ptr - buf)))
Packit 2d622a
void setup_mappings(int count)
Packit 2d622a
{
Packit 2d622a
	char value[128];
Packit 2d622a
	char *ptr = value;
Packit 2d622a
	int needed;
Packit 2d622a
Packit 2d622a
	/*
Packit 2d622a
	 * HUGETLB_ELFMAP should be set to either a combination of 'R' and 'W'
Packit 2d622a
	 * which indicate which segments should be remapped.  Each may take
Packit 2d622a
	 * an optional page size.  It may also be set to 'no' to prevent
Packit 2d622a
	 * remapping.
Packit 2d622a
	 */
Packit 2d622a
Packit 2d622a
	/*
Packit 2d622a
	 * Accumulate sections each with a ':' prefix to simplify later
Packit 2d622a
	 * handling.  We will elide the initial ':' before use.
Packit 2d622a
	 */
Packit 2d622a
	if (map_size[MAP_TEXT]) {
Packit 2d622a
		if (map_size[MAP_TEXT] == DEFAULT_SIZE)
Packit 2d622a
			needed = snprintf(ptr, available(value, ptr), ":R");
Packit 2d622a
		else
Packit 2d622a
			needed = snprintf(ptr, available(value, ptr),
Packit 2d622a
						":R=%s", map_size[MAP_TEXT]);
Packit 2d622a
		ptr += needed;
Packit 2d622a
		if (needed < 0 || available(value, ptr) < 0) {
Packit 2d622a
			ERROR("%s: bad size specification\n", map_size[MAP_TEXT]);
Packit 2d622a
			exit(EXIT_FAILURE);
Packit 2d622a
		}
Packit 2d622a
	}
Packit 2d622a
	if (map_size[MAP_DATA] != 0 || map_size[MAP_BSS] != 0) {
Packit 2d622a
		char *size = map_size[MAP_BSS];
Packit 2d622a
		if (map_size[MAP_DATA])
Packit 2d622a
			size = map_size[MAP_DATA];
Packit 2d622a
		if (map_size[MAP_DATA] != map_size[MAP_BSS])
Packit 2d622a
			WARNING("data and bss remapped together in %s\n", size);
Packit 2d622a
Packit 2d622a
		if (size == DEFAULT_SIZE)
Packit 2d622a
			needed = snprintf(ptr, available(value, ptr), ":W");
Packit 2d622a
		else
Packit 2d622a
			needed = snprintf(ptr, available(value, ptr),
Packit 2d622a
						":W=%s", size);
Packit 2d622a
		ptr += needed;
Packit 2d622a
		if (needed < 0 || available(value, ptr) < 0) {
Packit 2d622a
			ERROR("%s: bad size specification\n", size);
Packit 2d622a
			exit(EXIT_FAILURE);
Packit 2d622a
		}
Packit 2d622a
	}
Packit 2d622a
	*ptr = '\0';
Packit 2d622a
	if (ptr != value)
Packit 2d622a
		setup_environment("HUGETLB_ELFMAP", &value[1]);
Packit 2d622a
Packit 2d622a
	if (map_size[MAP_DISABLE]) {
Packit 2d622a
		if (ptr != value)
Packit 2d622a
			WARNING("--disable masks requested remap\n");
Packit 2d622a
		setup_environment("HUGETLB_ELFMAP", "no");
Packit 2d622a
	}
Packit 2d622a
Packit 2d622a
	if (map_size[MAP_HEAP] == DEFAULT_SIZE)
Packit 2d622a
		setup_environment("HUGETLB_MORECORE", "yes");
Packit 2d622a
	else if (map_size[MAP_HEAP])
Packit 2d622a
		setup_environment("HUGETLB_MORECORE", map_size[MAP_HEAP]);
Packit 2d622a
Packit 2d622a
	if (map_size[MAP_SHM] && map_size[MAP_SHM] != DEFAULT_SIZE)
Packit 2d622a
		WARNING("shm segments may only be mapped in the "
Packit 2d622a
			"default hugepage size\n");
Packit 2d622a
	if (map_size[MAP_SHM])
Packit 2d622a
		setup_environment("HUGETLB_SHM", "yes");
Packit 2d622a
}
Packit 2d622a
Packit 2d622a
#define LIBRARY_DISABLE ((void *)-1)
Packit 2d622a
Packit 2d622a
void library_path(char *path)
Packit 2d622a
{
Packit 2d622a
	char val[PATH_MAX] = "";
Packit 2d622a
	char *env;
Packit 2d622a
Packit 2d622a
	env = getenv("LD_LIBRARY_PATH");
Packit 2d622a
Packit 2d622a
	/*
Packit 2d622a
	 * Select which libraries we wish to use.  If the path is NULL
Packit 2d622a
	 * use the libraries included with hugectl.  If the path is valid
Packit 2d622a
	 * and points to a directory including a libhugetlbfs.so use it
Packit 2d622a
	 * directly.  Else path is assumed to be a prefix to the 32/64 bit
Packit 2d622a
	 * directories both of which are added, where available.
Packit 2d622a
	 */
Packit 2d622a
	if (path) {
Packit 2d622a
		snprintf(val, sizeof(val), "%s/libhugetlbfs.so", path);
Packit 2d622a
		if (access(val, F_OK) == 0) {
Packit 2d622a
			/* $PATH */
Packit 2d622a
			snprintf(val, sizeof(val), "%s:%s",
Packit 2d622a
				path, env ? env : "");
Packit 2d622a
Packit 2d622a
		} else {
Packit 2d622a
			/* [$PATH/LIB32:][$PATH/LIB64:]$LD_LIBRARY_PATH */
Packit 2d622a
			snprintf(val, sizeof(val), ""
Packit 2d622a
#ifdef LIBDIR32
Packit 2d622a
				"%s/" LIB32 ":"
Packit 2d622a
#endif
Packit 2d622a
#ifdef LIBDIR64
Packit 2d622a
				"%s/" LIB64 ":"
Packit 2d622a
#endif
Packit 2d622a
				"%s",
Packit 2d622a
#ifdef LIBDIR32
Packit 2d622a
				path,
Packit 2d622a
#endif
Packit 2d622a
#ifdef LIBDIR64
Packit 2d622a
				path,
Packit 2d622a
#endif
Packit 2d622a
				env ? env : "");
Packit 2d622a
		}
Packit 2d622a
Packit 2d622a
	} else {
Packit 2d622a
		/* [LIBDIR32:][LIBDIR64:]$LD_LIBRARY_PATH */
Packit 2d622a
		snprintf(val, sizeof(val), ""
Packit 2d622a
#ifdef LIBDIR32
Packit 2d622a
			LIBDIR32 ":"
Packit 2d622a
#endif
Packit 2d622a
#ifdef LIBDIR64
Packit 2d622a
			LIBDIR64 ":"
Packit 2d622a
#endif
Packit 2d622a
			"%s", env ? env : "");
Packit 2d622a
	}
Packit 2d622a
	setup_environment("LD_LIBRARY_PATH", val);
Packit 2d622a
}
Packit 2d622a
Packit 2d622a
void ldpreload(int count)
Packit 2d622a
{
Packit 2d622a
	int allowed = 0;
Packit 2d622a
Packit 2d622a
	if (map_size[MAP_HEAP])
Packit 2d622a
		allowed++;
Packit 2d622a
	if (map_size[MAP_SHM])
Packit 2d622a
		allowed++;
Packit 2d622a
Packit 2d622a
	if ((allowed == count) || opt_force_preload) {
Packit 2d622a
		setup_environment("LD_PRELOAD", "libhugetlbfs.so");
Packit 2d622a
		if (allowed == count)
Packit 2d622a
			INFO("LD_PRELOAD in use for lone --heap/--shm\n");
Packit 2d622a
	} else {
Packit 2d622a
		WARNING("LD_PRELOAD not appropriate for this map combination\n");
Packit 2d622a
	}
Packit 2d622a
}
Packit 2d622a
Packit 2d622a
int main(int argc, char** argv)
Packit 2d622a
{
Packit 2d622a
	int opt_mappings = 0;
Packit 2d622a
	int opt_preload = 1;
Packit 2d622a
	int opt_no_reserve = 0;
Packit 2d622a
	int opt_share = 0;
Packit 2d622a
	int opt_thp_heap = 0;
Packit 2d622a
	char *opt_library = NULL;
Packit 2d622a
Packit 2d622a
	char opts[] = "+hvq";
Packit 2d622a
	int ret = 0, index = 0;
Packit 2d622a
	struct option long_opts[] = {
Packit 2d622a
		{"help",       no_argument, NULL, 'h'},
Packit 2d622a
		{"verbose",    required_argument, NULL, 'v' },
Packit 2d622a
		{"no-preload", no_argument, NULL, LONG_NO_PRELOAD},
Packit 2d622a
		{"no-reserve", no_argument, NULL, LONG_NO_RESERVE},
Packit 2d622a
		{"force-preload",
Packit 2d622a
			       no_argument, NULL, LONG_FORCE_PRELOAD},
Packit 2d622a
		{"dry-run",    no_argument, NULL, LONG_DRY_RUN},
Packit 2d622a
		{"library-path",
Packit 2d622a
			       required_argument, NULL, LONG_LIBRARY},
Packit 2d622a
		{"library-use-path",
Packit 2d622a
			       no_argument, NULL, LONG_NO_LIBRARY},
Packit 2d622a
		{"share-text", no_argument, NULL, LONG_SHARE},
Packit 2d622a
Packit 2d622a
		{"disable",    optional_argument, NULL, MAP_BASE|MAP_DISABLE},
Packit 2d622a
		{"text",       optional_argument, NULL, MAP_BASE|MAP_TEXT},
Packit 2d622a
		{"data",       optional_argument, NULL, MAP_BASE|MAP_DATA},
Packit 2d622a
		{"bss",        optional_argument, NULL, MAP_BASE|MAP_BSS},
Packit 2d622a
		{"heap",       optional_argument, NULL, MAP_BASE|MAP_HEAP},
Packit 2d622a
		{"shm",        optional_argument, NULL, MAP_BASE|MAP_SHM},
Packit 2d622a
		{"thp",        no_argument, NULL, LONG_THP_HEAP},
Packit 2d622a
		{0},
Packit 2d622a
	};
Packit 2d622a
Packit 2d622a
	verbose_init();
Packit 2d622a
Packit 2d622a
	while (ret != -1) {
Packit 2d622a
		ret = getopt_long(argc, argv, opts, long_opts, &index);
Packit 2d622a
		if (ret > 0 && (ret & MAP_BASE)) {
Packit 2d622a
			if (optarg)
Packit 2d622a
				map_size[ret & ~MAP_BASE] = optarg;
Packit 2d622a
			else
Packit 2d622a
				map_size[ret & ~MAP_BASE] = DEFAULT_SIZE;
Packit 2d622a
			opt_mappings++;
Packit 2d622a
			continue;
Packit 2d622a
		}
Packit 2d622a
		switch (ret) {
Packit 2d622a
		case '?':
Packit 2d622a
			print_usage();
Packit 2d622a
			exit(EXIT_FAILURE);
Packit 2d622a
Packit 2d622a
		case 'h':
Packit 2d622a
			print_usage();
Packit 2d622a
			exit(EXIT_SUCCESS);
Packit 2d622a
Packit 2d622a
		case 'v':
Packit 2d622a
			verbose(optarg);
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		case 'q':
Packit 2d622a
			quiet();
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		case LONG_THP_HEAP:
Packit 2d622a
			opt_thp_heap = 1;
Packit 2d622a
			INFO("Aligning heap for use with THP\n");
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		case LONG_NO_PRELOAD:
Packit 2d622a
			opt_preload = 0;
Packit 2d622a
			INFO("LD_PRELOAD disabled\n");
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		case LONG_NO_RESERVE:
Packit 2d622a
			opt_no_reserve = 1;
Packit 2d622a
			INFO("MAP_NORESERVE used for huge page mappings\n");
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		case LONG_FORCE_PRELOAD:
Packit 2d622a
			opt_preload = 1;
Packit 2d622a
			opt_force_preload = 1;
Packit 2d622a
			INFO("Forcing ld preload\n");
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		case LONG_DRY_RUN:
Packit 2d622a
			opt_dry_run = 1;
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		case LONG_NO_LIBRARY:
Packit 2d622a
			opt_library = LIBRARY_DISABLE;
Packit 2d622a
			INFO("using LD_LIBRARY_PATH to find library\n");
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		case LONG_LIBRARY:
Packit 2d622a
			opt_library = optarg;
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		case LONG_SHARE:
Packit 2d622a
			opt_share = 1;
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		case -1:
Packit 2d622a
			break;
Packit 2d622a
Packit 2d622a
		default:
Packit 2d622a
			WARNING("unparsed option %08x\n", ret);
Packit 2d622a
			ret = -1;
Packit 2d622a
			break;
Packit 2d622a
		}
Packit 2d622a
	}
Packit 2d622a
	index = optind;
Packit 2d622a
Packit 2d622a
	if (!opt_dry_run && (argc - index) < 1) {
Packit 2d622a
		print_usage();
Packit 2d622a
		exit(EXIT_FAILURE);
Packit 2d622a
	}
Packit 2d622a
Packit 2d622a
	verbose_expose();
Packit 2d622a
Packit 2d622a
	if (opt_library != LIBRARY_DISABLE)
Packit 2d622a
		library_path(opt_library);
Packit 2d622a
Packit 2d622a
	if (opt_mappings)
Packit 2d622a
		setup_mappings(opt_mappings);
Packit 2d622a
Packit 2d622a
	if (opt_preload)
Packit 2d622a
		ldpreload(opt_mappings);
Packit 2d622a
Packit 2d622a
	if (opt_no_reserve)
Packit 2d622a
		setup_environment("HUGETLB_NO_RESERVE", "yes");
Packit 2d622a
Packit 2d622a
	if (opt_share)
Packit 2d622a
		setup_environment("HUGETLB_SHARE", "1");
Packit 2d622a
Packit 2d622a
	if (opt_thp_heap)
Packit 2d622a
		setup_environment("HUGETLB_MORECORE", "thp");
Packit 2d622a
Packit 2d622a
	if (opt_dry_run)
Packit 2d622a
		exit(EXIT_SUCCESS);
Packit 2d622a
Packit 2d622a
	execvp(argv[index], &argv[index]);
Packit 2d622a
	ERROR("exec failed: %s\n", strerror(errno));
Packit 2d622a
	exit(EXIT_FAILURE);
Packit 2d622a
}