/*
 * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * 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.  See the
 * GNU General Public License for more details.
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Author:
 * Alexey Kodanev <alexey.kodanev@oracle.com>
 *
 * Test checks following preconditions:
 * since Linux kernel 3.7 it is possible to set extended attributes
 * to cgroup files.
 */

#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include "test.h"
#include "safe_macros.h"

char *TCID = "cgroup_xattr";

static const char subdir_name[]	= "test";

#define MAX_SUBSYS		16
#define MAX_OPTIONS_LEN		256
#define MAX_DIR_NAME		64

/* struct to store available mount options */
struct cgrp_option {
	char str[MAX_OPTIONS_LEN];
	char dir[MAX_DIR_NAME];
	int hier;
	int mounted;
	int subdir;
};
static struct cgrp_option cgrp_opt[MAX_SUBSYS];
static int cgrp_opt_num;

struct tst_key {
	const char *name;
	int good;
};

/* only security.* & trusted.* are valid key names */
static const struct tst_key tkeys[] = {
	{ .name = "trusted.test",	.good = 1,	},
	{ .name = "security.",		.good = 1,	},
	{ .name = "user.",		.good = 0,	},
	{ .name = "system.",		.good = 0,	},
};

#define DEFAULT_VALUE_SIZE	8

/* struct to store key's value */
struct tst_val {
	char *buf;
	size_t size;
};
static struct tst_val val;

/* it fills value's buffer */
static char id;

/*
 * When test breaks, all open dirs should be closed
 * otherwise umount won't succeed
 */
#define MAX_OPEN_DIR		32
static DIR *odir[MAX_OPEN_DIR];
static int odir_num;

/* test options */
static char *narg;
static int nflag;
static int skip_cleanup;
static int verbose;
static const option_t options[] = {
	{"n:", &nflag, &narg},
	{"s", &skip_cleanup, NULL},
	{"v", &verbose, NULL},
	{NULL, NULL, NULL}
};

static void help(void);
static void setup(int argc, char *argv[]);
static void test_run(void);
static void cleanup(void);

static int mount_cgroup(void);
static int set_xattrs(const char *file);
static int get_xattrs(const char *file);
/*
 * set or get xattr recursively
 *
 * @path: start directory
 * @xattr_operation: can be set_xattrs() or get_xattrs()
 */
static int cgrp_files_walking(const char *path,
	int (*xattr_operation)(const char *));

int main(int argc, char *argv[])
{
	setup(argc, argv);

	test_run();

	cleanup();

	tst_exit();
}

static void help(void)
{
	printf("  -n x    Write x bytes to xattr value, default is %d\n",
		DEFAULT_VALUE_SIZE);
	printf("  -s      Skip cleanup\n");
	printf("  -v      Verbose\n");
}

void setup(int argc, char *argv[])
{
	const char *msg;
	msg = parse_opts(argc, argv, options, help);
	if (msg != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	tst_require_root(NULL);

	if (access("/proc/cgroups", F_OK) == -1)
		tst_brkm(TCONF, NULL, "Kernel doesn't support cgroups");

	if (tst_kvercmp(3, 7, 0) < 0) {
		tst_brkm(TCONF, NULL,
			"Test must be run with kernel 3.7 or newer");
	}

	int value_size = DEFAULT_VALUE_SIZE;
	if (nflag) {
		if (sscanf(narg, "%i", &value_size) != 1)
			tst_brkm(TBROK, NULL, "-n option arg is not a number");
		if (value_size <= 0)
			tst_brkm(TBROK, NULL, "-n option arg is less than 1");
	}

	/* initialize test value */
	val.size = value_size;
	val.buf = SAFE_MALLOC(NULL, value_size);

	tst_sig(FORK, DEF_HANDLER, cleanup);

	tst_tmpdir();

	if (!mount_cgroup())
		tst_brkm(TCONF, cleanup, "Nothing  mounted");
}

static void test_run(void)
{
	int i, set_res = 0, get_res = 0;

	for (i = 0; i < cgrp_opt_num; ++i) {
		if (!cgrp_opt[i].mounted)
			continue;

		SAFE_CHDIR(cleanup, cgrp_opt[i].dir);
		/* reset value */
		id = 0;
		/* set xattr to each file in cgroup fs */
		set_res |= cgrp_files_walking(".", set_xattrs);

		id = 0;
		/* get & check xattr */
		get_res |= cgrp_files_walking(".", get_xattrs);
		SAFE_CHDIR(cleanup, "..");
	}

	/* final results */
	tst_resm(TINFO, "All test-cases have been completed, summary:");
	tst_resm(TINFO, "Set tests result: %s", (set_res) ? "FAIL" : "PASS");
	tst_resm(TINFO, "Get tests result: %s", (get_res) ? "FAIL" : "PASS");
}

static void cleanup(void)
{
	if (val.buf != NULL)
		free(val.buf);

	if (skip_cleanup)
		return;

	/*
	 * Kernels 3.7 can crash while unmounting cgroups with xattr,
	 * call tst_flush() to make sure all buffered data written
	 * before it happens
	 */
	tst_flush();

	int i;
	for (i = 0; i < odir_num; ++i) {
		if (closedir(odir[i]) == -1)
			tst_brkm(TBROK, NULL, "Failed to close dir\n");
	}

	char *cwd = tst_get_tmpdir();
	SAFE_CHDIR(NULL, cwd);
	free(cwd);

	for (i = 0; i < cgrp_opt_num; ++i) {
		if (cgrp_opt[i].subdir) {
			SAFE_CHDIR(NULL, cgrp_opt[i].dir);
			if (rmdir(subdir_name) == -1) {
				tst_brkm(TBROK | TERRNO, NULL,
					"Can't remove dir");
			}
			SAFE_CHDIR(NULL, "..");
		}
		if (cgrp_opt[i].mounted) {
			if (umount(cgrp_opt[i].dir) == -1) {
				tst_brkm(TBROK | TERRNO, NULL,
					"Can't unmount: %s", cgrp_opt[i].dir);
			}
		}
	}

	tst_rmdir();
}

int mount_cgroup(void)
{
	FILE *fd = fopen("/proc/cgroups", "r");
	if (fd == NULL)
		tst_brkm(TBROK, cleanup, "Failed to read /proc/cgroups");
	char str[MAX_DIR_NAME], name[MAX_DIR_NAME];
	int hier = 0, num = 0, enabled = 0, first = 1;
	/* make mount options */
	while ((fgets(str, MAX_DIR_NAME, fd)) != NULL) {
		/* skip first line */
		if (first) {
			first = 0;
			continue;
		}
		if (sscanf(str, "%s\t%d\t%d\t%d",
			name, &hier, &num, &enabled) != 4)
			tst_brkm(TBROK, cleanup, "Can't parse /proc/cgroups");
		if (!enabled)
			continue;

		/* BUG WORKAROUND
		 * Only mount those subsystems, which are not mounted yet.
		 * It's a workaround to a bug when mount doesn't return any err
		 * code while mounting already mounted subsystems, but with
		 * additional "xattr" option. In that case, mount will succeed,
		 * but xattr won't be supported in the new mount anyway.
		 * Should be removed as soon as a fix committed to upstream.
		 */
		if (hier != 0)
			continue;

		int i, found = 0;
		for (i = 0; i < cgrp_opt_num; ++i) {
			if (cgrp_opt[i].hier == hier) {
				found = 1;
				break;
			}
		}
		if (!found) {
			i = cgrp_opt_num++;
			cgrp_opt[i].hier = hier;
		}
		char *str = cgrp_opt[i].str;
		if (str[0] == '\0')
			strcpy(str, "xattr");
		snprintf(str + strlen(str), MAX_OPTIONS_LEN - strlen(str),
			",%s", name);
	}
	fclose(fd);

	int i, any_mounted = 0;
	for (i = 0; i < cgrp_opt_num; ++i) {
		char dir[MAX_DIR_NAME];
		struct cgrp_option *opt = &cgrp_opt[i];
		tst_resm(TINFO, "mount options %d: %s (hier = %d)",
			i, opt->str, opt->hier);
		snprintf(opt->dir, MAX_DIR_NAME, "cgx_%d", opt->hier);
		SAFE_MKDIR(cleanup, opt->dir, 0755);

		if (mount(opt->dir, opt->dir, "cgroup", 0, opt->str) == -1) {
			tst_resm(TINFO, "Can't mount: %s", dir);
			continue;
		}

		any_mounted = 1;
		opt->mounted = 1;

		/* create new hierarchy */
		SAFE_CHDIR(cleanup, opt->dir);
		SAFE_MKDIR(cleanup, subdir_name, 0755);
		opt->subdir = 1;
		SAFE_CHDIR(cleanup, "..");
	}
	return any_mounted;
}

static int set_xattrs(const char *file)
{
	int i, err, fail, res = 0;

	for (i = 0; i < ARRAY_SIZE(tkeys); ++i) {
		err = setxattr(file, tkeys[i].name,
			(const void *)val.buf, val.size, 0) == -1;

		fail = err && tkeys[i].good;
		res |= fail;

		tst_resm((fail) ? TFAIL : TPASS,
			"Expect: %s set xattr key '%s' to file '%s'",
			(tkeys[i].good) ? "can" : "can't",
			tkeys[i].name, file);

		if (verbose && tkeys[i].good)
			tst_resm_hexd(TINFO, val.buf, val.size, "value:");
	}
	return res;
}

static int get_xattrs(const char *file)
{
	int i, fail, res = 0;

	for (i = 0; i < ARRAY_SIZE(tkeys); ++i) {
		/* get value size */
		ssize_t size = getxattr(file, tkeys[i].name, NULL, 0);
		fail = (size == -1 && tkeys[i].good);
		res |= fail;

		tst_resm((fail) ? TFAIL : TPASS,
			"Expect: %s read xattr %s of file '%s'",
			(tkeys[i].good) ? "can" : "can't",
			tkeys[i].name, file);

		if (fail || size == -1)
			continue;

		/* get xattr value */
		char xval[size];
		if (getxattr(file, tkeys[i].name, xval, size) == -1) {
			tst_brkm(TBROK, cleanup,
				"Can't get buffer of key %s",
				tkeys[i].name);
		}
		fail = val.size != size ||
			strncmp(val.buf, xval, val.size) != 0;
		res |= fail;

		tst_resm((fail) ? TFAIL : TPASS, "Expect: values equal");

		if (verbose && fail) {
			tst_resm_hexd(TINFO, xval, size,
				"Read  xattr  value:");
			tst_resm_hexd(TINFO, val.buf, val.size,
				"Expect xattr value:");
		}
	}
	return res;
}

static int cgrp_files_walking(const char *path,
	int (*xattr_operation)(const char *))
{
	int res = 0;
	struct dirent *entry;
	DIR *dir = opendir(path);

	odir[odir_num] = dir;
	if (++odir_num >= MAX_OPEN_DIR) {
		tst_brkm(TBROK, cleanup,
			"Unexpected num of open dirs, max: %d", MAX_OPEN_DIR);
	}

	SAFE_CHDIR(cleanup, path);

	tst_resm(TINFO, "In dir %s", path);

	errno = 0;
	while ((entry = readdir(dir)) != NULL) {
		const char *file = entry->d_name;
		/* skip current and up directories */
		if (!strcmp(file, "..") || !strcmp(file, "."))
			continue;
		struct stat stat_buf;
		TEST(lstat(file, &stat_buf));
		if (TEST_RETURN != -1 && S_ISDIR(stat_buf.st_mode)) {
			/* proceed to subdir */
			res |= cgrp_files_walking(file, xattr_operation);
			tst_resm(TINFO, "In dir %s", path);
		}
		memset(val.buf, id++, val.size);
		res |= xattr_operation(file);
		errno = 0;
	}
	if (errno && !entry) {
		tst_brkm(TWARN | TERRNO, cleanup,
			"Error while reading dir '%s'", path);
	}
	if (closedir(dir) == -1)
		tst_brkm(TWARN, cleanup, "Failed to close dir '%s'", path);
	else
		odir[--odir_num] = NULL;

	if (strcmp(path, "."))
		SAFE_CHDIR(cleanup, "..");
	return res;
}
