/*
 * overcommit hugetlbfs and check the statistics.
 *
 * hugetlbfs allows to overcommit hugepages and there are tunables in
 * sysfs and procfs. The test here want to ensure it is possible to
 * overcommit by either mmap or shared memory. Also ensure those
 * reservation can be read/write, and several statistics work correctly.
 *
 * First, it resets nr_hugepages and nr_overcommit_hugepages. Then, set
 * both to a specify value - N, and allocate N + %50 x N hugepages.
 * Finally, it reads and writes every page. There are command options to
 * choose either to manage hugepages from sysfs or procfs, and reserve
 * them by mmap or shmget.
 *
 * Copyright (C) 2010  Red Hat, Inc.
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it
 * is free of the rightful claim of any third person regarding
 * infringement or the like.  Any license provided herein, whether
 * implied or otherwise, applies only to this software file.  Patent
 * licenses, if any, provided herein do not apply to combinations of
 * this program with other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include "test.h"

#define PROTECTION		(PROT_READ | PROT_WRITE)
#define PATH_MEMINFO		"/proc/meminfo"

char path_sys_sz[BUFSIZ];
char path_sys_sz_over[BUFSIZ];
char path_sys_sz_free[BUFSIZ];
char path_sys_sz_resv[BUFSIZ];
char path_sys_sz_surp[BUFSIZ];
char path_sys_sz_huge[BUFSIZ];

#define PATH_PROC_VM		"/proc/sys/vm/"
#define PATH_PROC_OVER		PATH_PROC_VM "nr_overcommit_hugepages"
#define PATH_PROC_HUGE		PATH_PROC_VM "nr_hugepages"
#define PATH_SHMMAX		"/proc/sys/kernel/shmmax"

/* Only ia64 requires this */
#ifdef __ia64__
#define ADDR (void *)(0x8000000000000000UL)
#define FLAGS (MAP_SHARED | MAP_FIXED)
#define SHMAT_FLAGS (SHM_RND)
#else
#define ADDR (void *)(0x0UL)
#define FLAGS (MAP_SHARED)
#define SHMAT_FLAGS (0)
#endif

#ifndef SHM_HUGETLB
#define SHM_HUGETLB 04000
#endif

char *TCID = "hugemmap05";
int TST_TOTAL = 1, tst_count;
static char nr_hugepages[BUFSIZ], nr_overcommit_hugepages[BUFSIZ];
static char buf[BUFSIZ], line[BUFSIZ], path[BUFSIZ], pathover[BUFSIZ];
static char shmmax[BUFSIZ];
static char *opt_allocstr;
static int hugepagesize;	/* in Bytes */
static int opt_sysfs, opt_alloc;
static int shmid = -1;
static int restore_shmmax;
static size_t size = 128, length = 384;
static option_t options[] = {
	{"s", &opt_sysfs, NULL},
	{"m", &shmid, NULL},
	{"a:", &opt_alloc, &opt_allocstr},
	{NULL, NULL, NULL}
};

static void setup(void);
static void cleanup(void);
static void overcommit(void);
static void write_bytes(void *addr);
static void read_bytes(void *addr);
static int lookup(char *line, char *pattern);
static void usage(void);
static int checkproc(FILE * fp, char *string, int value);
static int checksys(char *path, char *pattern, int value);
static void init_hugepagesize(void);
static void init_sys_sz_paths(void);

int main(int argc, char *argv[])
{
	int lc;
	const char *msg;

	init_hugepagesize();
	init_sys_sz_paths();

	msg = parse_opts(argc, argv, options, usage);
	if (msg != NULL)
		tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
	if (opt_sysfs) {
		strncpy(path, path_sys_sz_huge, strlen(path_sys_sz_huge) + 1);
		strncpy(pathover, path_sys_sz_over,
			strlen(path_sys_sz_over) + 1);
	} else {
		strncpy(path, PATH_PROC_HUGE, strlen(PATH_PROC_HUGE) + 1);
		strncpy(pathover, PATH_PROC_OVER, strlen(PATH_PROC_OVER) + 1);
	}
	if (opt_alloc) {
		size = atoi(opt_allocstr);
		length = (int)(size + size * 0.5) * 2;
	}
	setup();
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;
		overcommit();
	}
	cleanup();
	tst_exit();
}

static void overcommit(void)
{
	void *addr = NULL, *shmaddr = NULL;
	int fd = -1, key = -1;
	char s[BUFSIZ];
	FILE *fp;

	if (shmid != -1) {
		/* Use /proc/meminfo to generate an IPC key. */
		key = ftok(PATH_MEMINFO, strlen(PATH_MEMINFO));
		if (key == -1)
			tst_brkm(TBROK | TERRNO, cleanup, "ftok");
		shmid = shmget(key, (long)(length / 2 * hugepagesize),
			       SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
		if (shmid == -1)
			tst_brkm(TBROK | TERRNO, cleanup, "shmget");
	} else {
		/* XXX (garrcoop): memory leak. */
		snprintf(s, BUFSIZ, "%s/hugemmap05/file", tst_get_tmpdir());
		fd = open(s, O_CREAT | O_RDWR, 0755);
		if (fd == -1)
			tst_brkm(TBROK | TERRNO, cleanup, "open");
		addr = mmap(ADDR, (long)(length / 2 * hugepagesize), PROTECTION,
			    FLAGS, fd, 0);
		if (addr == MAP_FAILED)
			tst_brkm(TBROK | TERRNO, cleanup, "mmap");
	}

	if (opt_sysfs) {
		tst_resm(TINFO, "check sysfs before allocation.");
		if (checksys(path_sys_sz_huge, "HugePages_Total",
			     length / 2) != 0)
			return;
		if (checksys(path_sys_sz_free, "HugePages_Free",
			     length / 2) != 0)
			return;
		if (checksys(path_sys_sz_surp, "HugePages_Surp",
			     length / 2 - size) != 0)
			return;
		if (checksys(path_sys_sz_resv, "HugePages_Rsvd",
			     length / 2) != 0)
			return;
	} else {
		tst_resm(TINFO, "check /proc/meminfo before allocation.");
		fp = fopen(PATH_MEMINFO, "r");
		if (fp == NULL)
			tst_brkm(TBROK | TERRNO, cleanup, "fopen");
		if (checkproc(fp, "HugePages_Total", length / 2) != 0)
			return;
		if (checkproc(fp, "HugePages_Free", length / 2) != 0)
			return;
		if (checkproc(fp, "HugePages_Surp", length / 2 - size) != 0)
			return;
		if (checkproc(fp, "HugePages_Rsvd", length / 2) != 0)
			return;
		fclose(fp);
	}
	if (shmid != -1) {
		tst_resm(TINFO, "shmid: 0x%x", shmid);
		shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
		if (shmaddr == (void *)-1)
			tst_brkm(TBROK | TERRNO, cleanup, "shmat");
		write_bytes(shmaddr);
		read_bytes(shmaddr);
	} else {
		write_bytes(addr);
		read_bytes(addr);
	}
	if (opt_sysfs) {
		tst_resm(TINFO, "check sysfs.");
		if (checksys(path_sys_sz_huge, "HugePages_Total",
			     length / 2) != 0)
			return;
		if (checksys(path_sys_sz_free, "HugePages_Free", 0)
		    != 0)
			return;
		if (checksys(path_sys_sz_surp, "HugePages_Surp",
			     length / 2 - size) != 0)
			return;
		if (checksys(path_sys_sz_resv, "HugePages_Rsvd", 0)
		    != 0)
			return;
	} else {
		tst_resm(TINFO, "check /proc/meminfo.");
		fp = fopen(PATH_MEMINFO, "r");
		if (fp == NULL)
			tst_brkm(TBROK | TERRNO, cleanup, "fopen");
		if (checkproc(fp, "HugePages_Total", length / 2) != 0)
			return;
		if (checkproc(fp, "HugePages_Free", 0) != 0)
			return;
		if (checkproc(fp, "HugePages_Surp", length / 2 - size) != 0)
			return;
		if (checkproc(fp, "HugePages_Rsvd", 0) != 0)
			return;
		fclose(fp);
	}
	if (shmid != -1) {
		if (shmdt(shmaddr) != 0)
			tst_brkm(TBROK | TERRNO, cleanup, "shmdt");
	} else {
		munmap(addr, (long)(length / 2 * hugepagesize));
		close(fd);
		unlink(s);
	}
}

static void cleanup(void)
{
	int fd;

	if (restore_shmmax) {
		fd = open(PATH_SHMMAX, O_WRONLY);
		if (fd == -1)
			tst_resm(TWARN | TERRNO, "open");
		if (write(fd, shmmax, strlen(shmmax)) != strlen(shmmax))
			tst_resm(TWARN | TERRNO, "write");
		close(fd);
	}
	fd = open(path, O_WRONLY);
	if (fd == -1)
		tst_resm(TWARN | TERRNO, "open");
	tst_resm(TINFO, "restore nr_hugepages to %s.", nr_hugepages);
	if (write(fd, nr_hugepages,
		  strlen(nr_hugepages)) != strlen(nr_hugepages))
		tst_resm(TWARN | TERRNO, "write");
	close(fd);

	fd = open(pathover, O_WRONLY);
	if (fd == -1)
		tst_resm(TWARN | TERRNO, "open");
	tst_resm(TINFO, "restore nr_overcommit_hugepages to %s.",
		 nr_overcommit_hugepages);
	if (write(fd, nr_overcommit_hugepages, strlen(nr_overcommit_hugepages))
	    != strlen(nr_overcommit_hugepages))
		tst_resm(TWARN | TERRNO, "write");
	close(fd);

	/* XXX (garrcoop): memory leak. */
	snprintf(buf, BUFSIZ, "%s/hugemmap05", tst_get_tmpdir());
	if (umount(buf) == -1)
		tst_resm(TWARN | TERRNO, "umount");
	if (shmid != -1) {
		tst_resm(TINFO, "shmdt cleaning");
		shmctl(shmid, IPC_RMID, NULL);
	}
	tst_rmdir();
}

static void setup(void)
{
	FILE *fp;
	int fd;
	struct stat stat_buf;

	tst_require_root(NULL);

	if (stat(pathover, &stat_buf) == -1) {
		if (errno == ENOENT || errno == ENOTDIR)
			tst_brkm(TCONF, NULL,
				 "file %s does not exist in the system",
				 pathover);
	}

	tst_sig(FORK, DEF_HANDLER, cleanup);
	TEST_PAUSE;
	tst_tmpdir();

	if (shmid != -1) {
		fp = fopen(PATH_SHMMAX, "r");
		if (fp == NULL)
			tst_brkm(TBROK | TERRNO, cleanup, "fopen");
		if (fgets(shmmax, BUFSIZ, fp) == NULL)
			tst_brkm(TBROK | TERRNO, cleanup, "fgets");
		fclose(fp);

		if (atol(shmmax) < (long)(length / 2 * hugepagesize)) {
			restore_shmmax = 1;
			fd = open(PATH_SHMMAX, O_RDWR);
			if (fd == -1)
				tst_brkm(TBROK | TERRNO, cleanup, "open");
			snprintf(buf, BUFSIZ, "%ld",
				 (long)(length / 2 * hugepagesize));
			if (write(fd, buf, strlen(buf)) != strlen(buf))
				tst_brkm(TBROK | TERRNO, cleanup,
					 "failed to change shmmax.");
		}
	}
	fp = fopen(path, "r+");
	if (fp == NULL)
		tst_brkm(TBROK | TERRNO, cleanup, "fopen");
	if (fgets(nr_hugepages, BUFSIZ, fp) == NULL)
		tst_brkm(TBROK | TERRNO, cleanup, "fgets");
	fclose(fp);
	/* Remove trailing newline. */
	nr_hugepages[strlen(nr_hugepages) - 1] = '\0';
	tst_resm(TINFO, "original nr_hugepages is %s", nr_hugepages);

	fd = open(path, O_RDWR);
	if (fd == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "open");
	/* Reset. */
	if (write(fd, "0", 1) != 1)
		tst_brkm(TBROK | TERRNO, cleanup, "write");
	if (lseek(fd, 0, SEEK_SET) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "lseek");
	snprintf(buf, BUFSIZ, "%zd", size);
	if (write(fd, buf, strlen(buf)) != strlen(buf))
		tst_brkm(TBROK | TERRNO, cleanup,
			 "failed to change nr_hugepages.");
	close(fd);

	fp = fopen(pathover, "r+");
	if (fp == NULL)
		tst_brkm(TBROK | TERRNO, cleanup, "fopen");
	if (fgets(nr_overcommit_hugepages, BUFSIZ, fp) == NULL)
		tst_brkm(TBROK | TERRNO, cleanup, "fgets");
	fclose(fp);
	nr_overcommit_hugepages[strlen(nr_overcommit_hugepages) - 1] = '\0';
	tst_resm(TINFO, "original nr_overcommit_hugepages is %s",
		 nr_overcommit_hugepages);

	fd = open(pathover, O_RDWR);
	if (fd == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "open");
	/* Reset. */
	if (write(fd, "0", 1) != 1)
		tst_brkm(TBROK | TERRNO, cleanup, "write");
	if (lseek(fd, 0, SEEK_SET) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "lseek");
	snprintf(buf, BUFSIZ, "%zd", size);
	if (write(fd, buf, strlen(buf)) != strlen(buf))
		tst_brkm(TBROK | TERRNO, cleanup,
			 "failed to change nr_hugepages.");
	close(fd);

	/* XXX (garrcoop): memory leak. */
	snprintf(buf, BUFSIZ, "%s/hugemmap05", tst_get_tmpdir());
	if (mkdir(buf, 0700) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "mkdir");
	if (mount(NULL, buf, "hugetlbfs", 0, NULL) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "mount");
}

static void write_bytes(void *addr)
{
	long i;

	for (i = 0; i < (long)(length / 2 * hugepagesize); i++)
		((char *)addr)[i] = '\a';
}

static void read_bytes(void *addr)
{
	long i;

	tst_resm(TINFO, "First hex is %x", *((unsigned int *)addr));
	for (i = 0; i < (long)(length / 2 * hugepagesize); i++) {
		if (((char *)addr)[i] != '\a') {
			tst_resm(TFAIL, "mismatch at %ld", i);
			break;
		}
	}
}

/* Lookup a pattern and get the value from file */
static int lookup(char *line, char *pattern)
{
	char buf2[BUFSIZ];

	/* empty line */
	if (line[0] == '\0')
		return 0;

	snprintf(buf2, BUFSIZ, "%s: %%s", pattern);
	if (sscanf(line, buf2, buf) != 1)
		return 0;

	return 1;
}

static void usage(void)
{
	printf("  -s      Setup hugepages from sysfs\n");
	printf("  -m      Reserve hugepages by shmget\n");
	printf("  -a      Number of overcommint hugepages\n");
}

static int checksys(char *path, char *string, int value)
{
	FILE *fp;

	fp = fopen(path, "r");
	if (fp == NULL)
		tst_brkm(TBROK | TERRNO, cleanup, "fopen");
	if (fgets(buf, BUFSIZ, fp) == NULL)
		tst_brkm(TBROK | TERRNO, cleanup, "fgets");
	tst_resm(TINFO, "%s is %d.", string, atoi(buf));
	if (atoi(buf) != value) {
		tst_resm(TFAIL, "%s is not %d but %d.", string, value,
			 atoi(buf));
		return 1;
	}
	fclose(fp);
	return 0;
}

static int checkproc(FILE * fp, char *pattern, int value)
{
	memset(buf, -1, BUFSIZ);
	rewind(fp);
	while (fgets(line, BUFSIZ, fp) != NULL)
		if (lookup(line, pattern))
			break;

	tst_resm(TINFO, "%s is %d.", pattern, atoi(buf));
	if (atoi(buf) != value) {
		tst_resm(TFAIL, "%s is not %d but %d.", pattern, value,
			 atoi(buf));
		return 1;
	}
	return 0;
}

static void init_hugepagesize(void)
{
	FILE *fp;

	memset(buf, -1, BUFSIZ);
	fp = fopen(PATH_MEMINFO, "r");
	if (fp == NULL)
		tst_brkm(TBROK, NULL, "can't open %s", PATH_MEMINFO);
	while (fgets(line, BUFSIZ, fp) != NULL) {
		if (lookup(line, "Hugepagesize")) {
			tst_resm(TINFO, "Hugepagesize is %s kB", buf);
			hugepagesize = atoi(buf) * 1024;
			return;
		}
	}
	tst_brkm(TBROK, NULL, "get Hugepagesize failed.");
}

/*
 * It's not easy to #define tunable file paths via sysfs,
 * use function init_hugepagesize and global variable instead.
 */
static void init_sys_sz_paths(void)
{
	sprintf(path_sys_sz, "/sys/kernel/mm/hugepages/hugepages-%dkB",
		hugepagesize / 1024);
	sprintf(path_sys_sz_over, "%s/nr_overcommit_hugepages", path_sys_sz);
	sprintf(path_sys_sz_free, "%s/free_hugepages", path_sys_sz);
	sprintf(path_sys_sz_resv, "%s/resv_hugepages", path_sys_sz);
	sprintf(path_sys_sz_surp, "%s/surplus_hugepages", path_sys_sz);
	sprintf(path_sys_sz_huge, "%s/nr_hugepages", path_sys_sz);
}
