/*
 * 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 "usctest.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 = get_max_node();
	nodemask_size = max_node / 8 + 1;
	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;
	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);
	TEST_CLEANUP;
}

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