/*
 * 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.
 */

/*
 * errno tests for migrate_pages() syscall
 */
#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 <string.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"

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

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

#if defined(__NR_migrate_pages) && HAVE_NUMA_H && HAVE_NUMAIF_H
static unsigned long *sane_old_nodes;
static unsigned long *sane_new_nodes;
static int sane_nodemask_size;
static int sane_max_node;

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

static void test_sane_nodes(void)
{
	tst_resm(TINFO, "test_empty_mask");
	TEST(ltp_syscall(__NR_migrate_pages, 0, sane_max_node,
		     sane_old_nodes, sane_new_nodes));
	check_ret(0);
}

static void test_invalid_pid(void)
{
	const char pid_max[] = "/proc/sys/kernel/pid_max";
	FILE *fp;
	char buff[512];
	pid_t invalid_pid = -1;

	tst_resm(TINFO, "test_invalid_pid -1");
	TEST(ltp_syscall(__NR_migrate_pages, invalid_pid, sane_max_node,
		     sane_old_nodes, sane_new_nodes));
	check_ret(-1);
	check_errno(ESRCH);

	tst_resm(TINFO, "test_invalid_pid pid_max+1");
	fp = fopen(pid_max, "r");
	if (fp == NULL)
		tst_brkm(TBROK, cleanup, "Could not open %s", pid_max);
	if (!fgets(buff, sizeof(buff), fp))
		tst_brkm(TBROK, cleanup, "Could not read %s", pid_max);
	fclose(fp);
	invalid_pid = atol(buff) + 1;
	TEST(ltp_syscall(__NR_migrate_pages, invalid_pid, sane_max_node,
		     sane_old_nodes, sane_new_nodes));
	check_ret(-1);
	check_errno(ESRCH);
}

static void test_invalid_masksize(void)
{
	tst_resm(TINFO, "test_invalid_masksize");
	TEST(ltp_syscall(__NR_migrate_pages, 0, -1, sane_old_nodes,
		     sane_new_nodes));
	check_ret(-1);
	check_errno(EINVAL);
}

static void test_invalid_mem(void)
{
	unsigned long *p;

	tst_resm(TINFO, "test_invalid_mem -1");
	TEST(ltp_syscall(__NR_migrate_pages, 0, sane_max_node, -1, -1));
	check_ret(-1);
	check_errno(EFAULT);

	tst_resm(TINFO, "test_invalid_mem invalid prot");
	p = mmap(NULL, getpagesize(), PROT_NONE,
		 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
	if (p == MAP_FAILED)
		tst_brkm(TBROK | TERRNO, cleanup, "mmap");
	TEST(ltp_syscall(__NR_migrate_pages, 0, sane_max_node, p, p));
	check_ret(-1);
	check_errno(EFAULT);

	if (munmap(p, getpagesize()) < 0)
		tst_brkm(TBROK | TERRNO, cleanup, "munmap");
	tst_resm(TINFO, "test_invalid_mem unmmaped");
	TEST(ltp_syscall(__NR_migrate_pages, 0, sane_max_node, p, p));
	check_ret(-1);
	check_errno(EFAULT);
}

static void test_invalid_nodes(void)
{
	int *nodes;
	int num_nodes, ret, i;
	int invalid_node = 0;
	unsigned long *old_nodes, *new_nodes;

	tst_resm(TINFO, "test_invalid_nodes");
	ret = get_allowed_nodes_arr(NH_MEMS, &num_nodes, &nodes);
	if (ret < 0)
		tst_brkm(TBROK | TERRNO, cleanup,
			 "get_allowed_nodes_arr: %d", ret);

	/* get first node which is not in nodes */
	for (i = 0; i < num_nodes; i++, invalid_node++)
		if (invalid_node != nodes[i])
			break;
	if (invalid_node < sane_max_node) {
		old_nodes = SAFE_MALLOC(NULL, sane_nodemask_size);
		new_nodes = SAFE_MALLOC(NULL, sane_nodemask_size);
		memcpy(old_nodes, sane_old_nodes, sane_nodemask_size);
		memset(new_nodes, 0, sane_nodemask_size);
		set_bit(new_nodes, invalid_node, 1);

		TEST(ltp_syscall(__NR_migrate_pages, 0, sane_max_node,
			     old_nodes, new_nodes));
		check_ret(-1);
		check_errno(EINVAL);
		free(old_nodes);
		free(new_nodes);
	} else {
		tst_resm(TCONF, "All possible nodes are present");
	}

	free(nodes);
}

static void test_invalid_perm(void)
{
	char nobody_uid[] = "nobody";
	struct passwd *ltpuser;
	int status;
	pid_t child_pid;
	pid_t parent_pid;
	int ret = 0;

	tst_resm(TINFO, "test_invalid_perm");
	parent_pid = getpid();
	fflush(stdout);
	child_pid = fork();
	switch (child_pid) {
	case -1:
		tst_brkm(TBROK | TERRNO, cleanup, "fork");
		break;
	case 0:
		ltpuser = getpwnam(nobody_uid);
		if (ltpuser == NULL)
			tst_brkm(TBROK | TERRNO, NULL, "getpwnam failed");
		if (setuid(ltpuser->pw_uid) == -1)
			tst_brkm(TBROK | TERRNO, NULL,
				 "setuid(%u) failed", ltpuser->pw_uid);
		TEST(ltp_syscall(__NR_migrate_pages, parent_pid,
			     sane_max_node, sane_old_nodes, sane_new_nodes));
		ret |= check_ret(-1);
		ret |= check_errno(EPERM);
		exit(ret);
	default:
		if (waitpid(child_pid, &status, 0) == -1)
			tst_brkm(TBROK | TERRNO, cleanup, "waitpid");
		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
			tst_resm(TFAIL, "child returns %d", status);
	}
}

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_sane_nodes();
		test_invalid_pid();
		test_invalid_masksize();
		test_invalid_mem();
		test_invalid_nodes();
		test_invalid_perm();
	}
	cleanup();
	tst_exit();
}

static void setup(void)
{
	int node, ret;

	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(NH_MEMS, 1, &node);
	if (ret < 0)
		tst_brkm(TBROK | TERRNO, NULL, "get_allowed_nodes_arr: %d",
			 ret);

	sane_max_node = get_max_node();
	sane_nodemask_size = sane_max_node / 8 + 1;
	sane_old_nodes = SAFE_MALLOC(NULL, sane_nodemask_size);
	sane_new_nodes = SAFE_MALLOC(NULL, sane_nodemask_size);
	memset(sane_old_nodes, 0, sane_nodemask_size);
	memset(sane_new_nodes, 0, sane_nodemask_size);

	set_bit(sane_old_nodes, node, 1);
	set_bit(sane_new_nodes, node, 1);

	TEST_PAUSE;
}

static void cleanup(void)
{
	free(sane_old_nodes);
	free(sane_new_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
