/*
 * Copyright (C) 2012 Linux Test Project, 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.
 */

/*
 * use migrate_pages() and check that address is on correct node
 * 1. process A can migrate its non-shared mem with CAP_SYS_NICE
 * 2. process A can migrate its non-shared mem without CAP_SYS_NICE
 * 3. process A can migrate shared mem only with CAP_SYS_NICE
 * 4. process A can migrate non-shared mem in process B with same effective uid
 * 5. process A can migrate non-shared mem in process B with CAP_SYS_NICE
 */
#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <errno.h>
#if HAVE_NUMA_H
#include <numa.h>
#endif
#if HAVE_NUMAIF_H
#include <numaif.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include "config.h"
#include "test.h"
#include "safe_macros.h"
#include "linux_syscall_numbers.h"
#include "numa_helper.h"
#include "migrate_pages_common.h"

/*
 * This is an estimated minimum of free mem required to migrate this
 * process to another node as migrate_pages will fail if there is not
 * enough free space on node. While running this test on x86_64
 * it used ~2048 pages (total VM, not just RSS). Considering ia64 as
 * architecture with largest (non-huge) page size (16k), this limit
 * is set to 2048*16k == 32M.
 */
#define NODE_MIN_FREEMEM (32*1024*1024)

char *TCID = "migrate_pages02";
int TST_TOTAL = 1;

#if defined(__NR_migrate_pages) && HAVE_NUMA_H && HAVE_NUMAIF_H
static const char nobody_uid[] = "nobody";
static struct passwd *ltpuser;
static int *nodes, nodeA, nodeB;
static int num_nodes;

static void setup(void);
static void cleanup(void);

option_t options[] = {
	{NULL, NULL, NULL}
};

static void print_mem_stats(pid_t pid, int node)
{
	char s[64];
	long long node_size, freep;

	if (pid == 0)
		pid = getpid();

	tst_resm(TINFO, "mem_stats pid: %d, node: %d", pid, node);

	/* dump pid's VM info */
	sprintf(s, "cat /proc/%d/status", pid);
	system(s);
	sprintf(s, "cat /proc/%d/numa_maps", pid);
	system(s);

	/* dump node free mem */
	node_size = numa_node_size64(node, &freep);
	tst_resm(TINFO, "Node id: %d, size: %lld, free: %lld",
		 node, node_size, freep);
}

static int migrate_to_node(pid_t pid, int node)
{
	unsigned long nodemask_size, max_node;
	unsigned long *old_nodes, *new_nodes;
	int i;

	tst_resm(TINFO, "pid(%d) migrate pid %d to node -> %d",
		 getpid(), pid, node);
	max_node = LTP_ALIGN(get_max_node(), sizeof(unsigned long)*8);
	nodemask_size = max_node / 8;
	old_nodes = SAFE_MALLOC(NULL, nodemask_size);
	new_nodes = SAFE_MALLOC(NULL, nodemask_size);

	memset(old_nodes, 0, nodemask_size);
	memset(new_nodes, 0, nodemask_size);
	for (i = 0; i < num_nodes; i++)
		set_bit(old_nodes, nodes[i], 1);
	set_bit(new_nodes, node, 1);

	TEST(ltp_syscall(__NR_migrate_pages, pid, max_node, old_nodes,
		new_nodes));
	if (TEST_RETURN != 0) {
		if (TEST_RETURN < 0)
			tst_resm(TFAIL | TERRNO, "migrate_pages failed "
				 "ret: %ld, ", TEST_RETURN);
		else
			tst_resm(TWARN, "migrate_pages could not migrate all "
				 "pages, not migrated: %ld", TEST_RETURN);
		print_mem_stats(pid, node);
	}
	free(old_nodes);
	free(new_nodes);
	return TEST_RETURN;
}

static int addr_on_node(void *addr)
{
	int node;
	int ret;

	ret = ltp_syscall(__NR_get_mempolicy, &node, NULL, (unsigned long)0,
		      (unsigned long)addr, MPOL_F_NODE | MPOL_F_ADDR);
	if (ret == -1) {
		tst_resm(TBROK | TERRNO, "error getting memory policy "
			 "for page %p", addr);
	}
	return node;
}

static int check_addr_on_node(void *addr, int exp_node)
{
	int node;

	node = addr_on_node(addr);
	if (node == exp_node) {
		tst_resm(TPASS, "pid(%d) addr %p is on expected node: %d",
			 getpid(), addr, exp_node);
		return 0;
	} else {
		tst_resm(TFAIL, "pid(%d) addr %p not on expected node: %d "
			 ", expected %d", getpid(), addr, node, exp_node);
		print_mem_stats(0, exp_node);
		return 1;
	}
}

static void test_migrate_current_process(int node1, int node2, int cap_sys_nice)
{
	char *testp, *testp2;
	int ret, status;
	pid_t child;

	/* parent can migrate its non-shared memory */
	tst_resm(TINFO, "current_process, cap_sys_nice: %d", cap_sys_nice);
	testp = SAFE_MALLOC(NULL, getpagesize());
	testp[0] = 0;
	tst_resm(TINFO, "private anonymous: %p", testp);
	migrate_to_node(0, node2);
	check_addr_on_node(testp, node2);
	migrate_to_node(0, node1);
	check_addr_on_node(testp, node1);
	free(testp);

	/* parent can migrate shared memory with CAP_SYS_NICE */
	testp2 = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE,
		      MAP_ANONYMOUS | MAP_SHARED, 0, 0);
	if (testp2 == MAP_FAILED)
		tst_brkm(TBROK | TERRNO, cleanup, "mmap failed");
	testp2[0] = 1;
	tst_resm(TINFO, "shared anonymous: %p", testp2);
	migrate_to_node(0, node2);
	check_addr_on_node(testp2, node2);

	/* shared mem is on node2, try to migrate in child to node1 */
	fflush(stdout);
	child = fork();
	switch (child) {
	case -1:
		tst_brkm(TBROK | TERRNO, cleanup, "fork");
		break;
	case 0:
		tst_resm(TINFO, "child shared anonymous, cap_sys_nice: %d",
			 cap_sys_nice);
		testp = SAFE_MALLOC(NULL, getpagesize());
		testp[0] = 1;
		testp2[0] = 1;
		if (!cap_sys_nice)
			if (seteuid(ltpuser->pw_uid) == -1)
				tst_brkm(TBROK | TERRNO, NULL,
					 "seteuid failed");

		migrate_to_node(0, node1);
		/* child can migrate non-shared memory */
		ret = check_addr_on_node(testp, node1);

		free(testp);
		munmap(testp2, getpagesize());
		exit(ret);
	default:
		if (waitpid(child, &status, 0) == -1)
			tst_brkm(TBROK | TERRNO, cleanup, "waitpid");
		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
			tst_resm(TFAIL, "child returns %d", status);
		if (cap_sys_nice)
			/* child can migrate shared memory only
			 * with CAP_SYS_NICE */
			check_addr_on_node(testp2, node1);
		else
			check_addr_on_node(testp2, node2);
		munmap(testp2, getpagesize());
	}
}

static void test_migrate_other_process(int node1, int node2, int cap_sys_nice)
{
	char *testp;
	int status, ret, tmp;
	pid_t child;
	int child_ready[2];
	int pages_migrated[2];

	/* setup pipes to synchronize child/parent */
	if (pipe(child_ready) == -1)
		tst_resm(TBROK | TERRNO, "pipe #1 failed");
	if (pipe(pages_migrated) == -1)
		tst_resm(TBROK | TERRNO, "pipe #2 failed");

	tst_resm(TINFO, "other_process, cap_sys_nice: %d", cap_sys_nice);

	fflush(stdout);
	child = fork();
	switch (child) {
	case -1:
		tst_brkm(TBROK | TERRNO, cleanup, "fork");
		break;
	case 0:
		close(child_ready[0]);
		close(pages_migrated[1]);

		testp = SAFE_MALLOC(NULL, getpagesize());
		testp[0] = 0;

		/* make sure we are on node1 */
		migrate_to_node(0, node1);
		check_addr_on_node(testp, node1);

		if (seteuid(ltpuser->pw_uid) == -1)
			tst_brkm(TBROK | TERRNO, NULL, "seteuid failed");

		/* signal parent it's OK to migrate child and wait */
		if (write(child_ready[1], &tmp, 1) != 1)
			tst_brkm(TBROK | TERRNO, NULL, "write #1 failed");
		if (read(pages_migrated[0], &tmp, 1) != 1)
			tst_brkm(TBROK | TERRNO, NULL, "read #1 failed");

		/* parent can migrate child process with same euid */
		/* parent can migrate child process with CAP_SYS_NICE */
		ret = check_addr_on_node(testp, node2);

		free(testp);
		close(child_ready[1]);
		close(pages_migrated[0]);
		exit(ret);
	default:
		close(child_ready[1]);
		close(pages_migrated[0]);

		if (!cap_sys_nice)
			if (seteuid(ltpuser->pw_uid) == -1)
				tst_brkm(TBROK | TERRNO, NULL,
					 "seteuid failed");

		/* wait until child is ready on node1, then migrate and
		 * signal to check current node */
		if (read(child_ready[0], &tmp, 1) != 1)
			tst_brkm(TBROK | TERRNO, NULL, "read #2 failed");
		migrate_to_node(child, node2);
		if (write(pages_migrated[1], &tmp, 1) != 1)
			tst_brkm(TBROK | TERRNO, NULL, "write #2 failed");

		if (waitpid(child, &status, 0) == -1)
			tst_brkm(TBROK | TERRNO, cleanup, "waitpid");
		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
			tst_resm(TFAIL, "child returns %d", status);
		close(child_ready[0]);
		close(pages_migrated[1]);

		/* reset euid, so this testcase can be used in loop */
		if (!cap_sys_nice)
			if (seteuid(0) == -1)
				tst_brkm(TBROK | TERRNO, NULL,
					 "seteuid failed");
	}
}

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

	msg = parse_opts(argc, argv, options, NULL);
	if (msg != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;
		test_migrate_current_process(nodeA, nodeB, 1);
		test_migrate_current_process(nodeA, nodeB, 0);
		test_migrate_other_process(nodeA, nodeB, 1);
		test_migrate_other_process(nodeA, nodeB, 0);
	}
	cleanup();
	tst_exit();
}

static void setup(void)
{
	int ret, i, j;
	int pagesize = getpagesize();
	void *p;

	tst_require_root(NULL);
	TEST(ltp_syscall(__NR_migrate_pages, 0, 0, NULL, NULL));

	if (numa_available() == -1)
		tst_brkm(TCONF, NULL, "NUMA not available");

	ret = get_allowed_nodes_arr(NH_MEMS, &num_nodes, &nodes);
	if (ret < 0)
		tst_brkm(TBROK | TERRNO, NULL, "get_allowed_nodes(): %d", ret);

	if (num_nodes < 2)
		tst_brkm(TCONF, NULL, "at least 2 allowed NUMA nodes"
			 " are required");
	else if (tst_kvercmp(2, 6, 18) < 0)
		tst_brkm(TCONF, NULL, "2.6.18 or greater kernel required");

	/*
	 * find 2 nodes, which can hold NODE_MIN_FREEMEM bytes
	 * The reason is that:
	 * 1. migrate_pages() is expected to succeed
	 * 2. this test avoids hitting:
	 *    Bug 870326 - migrate_pages() reports success, but pages are
	 *                 not moved to desired node
	 *    https://bugzilla.redhat.com/show_bug.cgi?id=870326
	 */
	nodeA = nodeB = -1;
	for (i = 0; i < num_nodes; i++) {
		p = numa_alloc_onnode(NODE_MIN_FREEMEM, nodes[i]);
		if (p == NULL)
			break;
		memset(p, 0xff, NODE_MIN_FREEMEM);

		j = 0;
		while (j < NODE_MIN_FREEMEM) {
			if (addr_on_node(p + j) != nodes[i])
				break;
			j += pagesize;
		}
		numa_free(p, NODE_MIN_FREEMEM);

		if (j >= NODE_MIN_FREEMEM) {
			if (nodeA == -1)
				nodeA = nodes[i];
			else if (nodeB == -1)
				nodeB = nodes[i];
			else
				break;
		}
	}

	if (nodeA == -1 || nodeB == -1)
		tst_brkm(TCONF, NULL, "at least 2 NUMA nodes with "
			 "free mem > %d are needed", NODE_MIN_FREEMEM);
	tst_resm(TINFO, "Using nodes: %d %d", nodeA, nodeB);

	ltpuser = getpwnam(nobody_uid);
	if (ltpuser == NULL)
		tst_brkm(TBROK | TERRNO, NULL, "getpwnam failed");

	TEST_PAUSE;
}

static void cleanup(void)
{
	free(nodes);
}

#else /* __NR_migrate_pages */
int main(void)
{
	tst_brkm(TCONF, NULL, "System doesn't support __NR_migrate_pages"
		 " or libnuma is not available");
}
#endif
