/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*
 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
 */

#include <libintl.h>
#include <libuutil.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <thread_pool.h>

#include <libzfs.h>
#include <libzutil.h>
#include <sys/zfs_context.h>
#include <sys/wait.h>

#include "zpool_util.h"

/*
 * Private interface for iterating over pools specified on the command line.
 * Most consumers will call for_each_pool, but in order to support iostat, we
 * allow fined grained control through the zpool_list_t interface.
 */

typedef struct zpool_node {
	zpool_handle_t	*zn_handle;
	uu_avl_node_t	zn_avlnode;
	int		zn_mark;
} zpool_node_t;

struct zpool_list {
	boolean_t	zl_findall;
	uu_avl_t	*zl_avl;
	uu_avl_pool_t	*zl_pool;
	zprop_list_t	**zl_proplist;
};

/* ARGSUSED */
static int
zpool_compare(const void *larg, const void *rarg, void *unused)
{
	zpool_handle_t *l = ((zpool_node_t *)larg)->zn_handle;
	zpool_handle_t *r = ((zpool_node_t *)rarg)->zn_handle;
	const char *lname = zpool_get_name(l);
	const char *rname = zpool_get_name(r);

	return (strcmp(lname, rname));
}

/*
 * Callback function for pool_list_get().  Adds the given pool to the AVL tree
 * of known pools.
 */
static int
add_pool(zpool_handle_t *zhp, void *data)
{
	zpool_list_t *zlp = data;
	zpool_node_t *node = safe_malloc(sizeof (zpool_node_t));
	uu_avl_index_t idx;

	node->zn_handle = zhp;
	uu_avl_node_init(node, &node->zn_avlnode, zlp->zl_pool);
	if (uu_avl_find(zlp->zl_avl, node, NULL, &idx) == NULL) {
		if (zlp->zl_proplist &&
		    zpool_expand_proplist(zhp, zlp->zl_proplist) != 0) {
			zpool_close(zhp);
			free(node);
			return (-1);
		}
		uu_avl_insert(zlp->zl_avl, node, idx);
	} else {
		zpool_close(zhp);
		free(node);
		return (-1);
	}

	return (0);
}

/*
 * Create a list of pools based on the given arguments.  If we're given no
 * arguments, then iterate over all pools in the system and add them to the AVL
 * tree.  Otherwise, add only those pool explicitly specified on the command
 * line.
 */
zpool_list_t *
pool_list_get(int argc, char **argv, zprop_list_t **proplist, int *err)
{
	zpool_list_t *zlp;

	zlp = safe_malloc(sizeof (zpool_list_t));

	zlp->zl_pool = uu_avl_pool_create("zfs_pool", sizeof (zpool_node_t),
	    offsetof(zpool_node_t, zn_avlnode), zpool_compare, UU_DEFAULT);

	if (zlp->zl_pool == NULL)
		zpool_no_memory();

	if ((zlp->zl_avl = uu_avl_create(zlp->zl_pool, NULL,
	    UU_DEFAULT)) == NULL)
		zpool_no_memory();

	zlp->zl_proplist = proplist;

	if (argc == 0) {
		(void) zpool_iter(g_zfs, add_pool, zlp);
		zlp->zl_findall = B_TRUE;
	} else {
		int i;

		for (i = 0; i < argc; i++) {
			zpool_handle_t *zhp;

			if ((zhp = zpool_open_canfail(g_zfs, argv[i])) !=
			    NULL) {
				if (add_pool(zhp, zlp) != 0)
					*err = B_TRUE;
			} else {
				*err = B_TRUE;
			}
		}
	}

	return (zlp);
}

/*
 * Search for any new pools, adding them to the list.  We only add pools when no
 * options were given on the command line.  Otherwise, we keep the list fixed as
 * those that were explicitly specified.
 */
void
pool_list_update(zpool_list_t *zlp)
{
	if (zlp->zl_findall)
		(void) zpool_iter(g_zfs, add_pool, zlp);
}

/*
 * Iterate over all pools in the list, executing the callback for each
 */
int
pool_list_iter(zpool_list_t *zlp, int unavail, zpool_iter_f func,
    void *data)
{
	zpool_node_t *node, *next_node;
	int ret = 0;

	for (node = uu_avl_first(zlp->zl_avl); node != NULL; node = next_node) {
		next_node = uu_avl_next(zlp->zl_avl, node);
		if (zpool_get_state(node->zn_handle) != POOL_STATE_UNAVAIL ||
		    unavail)
			ret |= func(node->zn_handle, data);
	}

	return (ret);
}

/*
 * Remove the given pool from the list.  When running iostat, we want to remove
 * those pools that no longer exist.
 */
void
pool_list_remove(zpool_list_t *zlp, zpool_handle_t *zhp)
{
	zpool_node_t search, *node;

	search.zn_handle = zhp;
	if ((node = uu_avl_find(zlp->zl_avl, &search, NULL, NULL)) != NULL) {
		uu_avl_remove(zlp->zl_avl, node);
		zpool_close(node->zn_handle);
		free(node);
	}
}

/*
 * Free all the handles associated with this list.
 */
void
pool_list_free(zpool_list_t *zlp)
{
	uu_avl_walk_t *walk;
	zpool_node_t *node;

	if ((walk = uu_avl_walk_start(zlp->zl_avl, UU_WALK_ROBUST)) == NULL) {
		(void) fprintf(stderr,
		    gettext("internal error: out of memory"));
		exit(1);
	}

	while ((node = uu_avl_walk_next(walk)) != NULL) {
		uu_avl_remove(zlp->zl_avl, node);
		zpool_close(node->zn_handle);
		free(node);
	}

	uu_avl_walk_end(walk);
	uu_avl_destroy(zlp->zl_avl);
	uu_avl_pool_destroy(zlp->zl_pool);

	free(zlp);
}

/*
 * Returns the number of elements in the pool list.
 */
int
pool_list_count(zpool_list_t *zlp)
{
	return (uu_avl_numnodes(zlp->zl_avl));
}

/*
 * High level function which iterates over all pools given on the command line,
 * using the pool_list_* interfaces.
 */
int
for_each_pool(int argc, char **argv, boolean_t unavail,
    zprop_list_t **proplist, zpool_iter_f func, void *data)
{
	zpool_list_t *list;
	int ret = 0;

	if ((list = pool_list_get(argc, argv, proplist, &ret)) == NULL)
		return (1);

	if (pool_list_iter(list, unavail, func, data) != 0)
		ret = 1;

	pool_list_free(list);

	return (ret);
}

static int
for_each_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, pool_vdev_iter_f func,
    void *data)
{
	nvlist_t **child;
	uint_t c, children;
	int ret = 0;
	int i;
	char *type;

	const char *list[] = {
	    ZPOOL_CONFIG_SPARES,
	    ZPOOL_CONFIG_L2CACHE,
	    ZPOOL_CONFIG_CHILDREN
	};

	for (i = 0; i < ARRAY_SIZE(list); i++) {
		if (nvlist_lookup_nvlist_array(nv, list[i], &child,
		    &children) == 0) {
			for (c = 0; c < children; c++) {
				uint64_t ishole = 0;

				(void) nvlist_lookup_uint64(child[c],
				    ZPOOL_CONFIG_IS_HOLE, &ishole);

				if (ishole)
					continue;

				ret |= for_each_vdev_cb(zhp, child[c], func,
				    data);
			}
		}
	}

	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
		return (ret);

	/* Don't run our function on root vdevs */
	if (strcmp(type, VDEV_TYPE_ROOT) != 0) {
		ret |= func(zhp, nv, data);
	}

	return (ret);
}

/*
 * This is the equivalent of for_each_pool() for vdevs.  It iterates thorough
 * all vdevs in the pool, ignoring root vdevs and holes, calling func() on
 * each one.
 *
 * @zhp:	Zpool handle
 * @func:	Function to call on each vdev
 * @data:	Custom data to pass to the function
 */
int
for_each_vdev(zpool_handle_t *zhp, pool_vdev_iter_f func, void *data)
{
	nvlist_t *config, *nvroot = NULL;

	if ((config = zpool_get_config(zhp, NULL)) != NULL) {
		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
		    &nvroot) == 0);
	}
	return (for_each_vdev_cb(zhp, nvroot, func, data));
}

/*
 * Process the vcdl->vdev_cmd_data[] array to figure out all the unique column
 * names and their widths.  When this function is done, vcdl->uniq_cols,
 * vcdl->uniq_cols_cnt, and vcdl->uniq_cols_width will be filled in.
 */
static void
process_unique_cmd_columns(vdev_cmd_data_list_t *vcdl)
{
	char **uniq_cols = NULL, **tmp = NULL;
	int *uniq_cols_width;
	vdev_cmd_data_t *data;
	int cnt = 0;
	int k;

	/* For each vdev */
	for (int i = 0; i < vcdl->count; i++) {
		data = &vcdl->data[i];
		/* For each column the vdev reported */
		for (int j = 0; j < data->cols_cnt; j++) {
			/* Is this column in our list of unique column names? */
			for (k = 0; k < cnt; k++) {
				if (strcmp(data->cols[j], uniq_cols[k]) == 0)
					break; /* yes it is */
			}
			if (k == cnt) {
				/* No entry for column, add to list */
				tmp = realloc(uniq_cols, sizeof (*uniq_cols) *
				    (cnt + 1));
				if (tmp == NULL)
					break; /* Nothing we can do... */
				uniq_cols = tmp;
				uniq_cols[cnt] = data->cols[j];
				cnt++;
			}
		}
	}

	/*
	 * We now have a list of all the unique column names.  Figure out the
	 * max width of each column by looking at the column name and all its
	 * values.
	 */
	uniq_cols_width = safe_malloc(sizeof (*uniq_cols_width) * cnt);
	for (int i = 0; i < cnt; i++) {
		/* Start off with the column title's width */
		uniq_cols_width[i] = strlen(uniq_cols[i]);
		/* For each vdev */
		for (int j = 0; j < vcdl->count; j++) {
			/* For each of the vdev's values in a column */
			data = &vcdl->data[j];
			for (k = 0; k < data->cols_cnt; k++) {
				/* Does this vdev have a value for this col? */
				if (strcmp(data->cols[k], uniq_cols[i]) == 0) {
					/* Is the value width larger? */
					uniq_cols_width[i] =
					    MAX(uniq_cols_width[i],
					    strlen(data->lines[k]));
				}
			}
		}
	}

	vcdl->uniq_cols = uniq_cols;
	vcdl->uniq_cols_cnt = cnt;
	vcdl->uniq_cols_width = uniq_cols_width;
}


/*
 * Process a line of command output
 *
 * When running 'zpool iostat|status -c' the lines of output can either be
 * in the form of:
 *
 *	column_name=value
 *
 * Or just:
 *
 *	value
 *
 * Process the column_name (if any) and value.
 *
 * Returns 0 if line was processed, and there are more lines can still be
 * processed.
 *
 * Returns 1 if this was the last line to process, or error.
 */
static int
vdev_process_cmd_output(vdev_cmd_data_t *data, char *line)
{
	char *col = NULL;
	char *val = line;
	char *equals;
	char **tmp;

	if (line == NULL)
		return (1);

	equals = strchr(line, '=');
	if (equals != NULL) {
		/*
		 * We have a 'column=value' type line.  Split it into the
		 * column and value strings by turning the '=' into a '\0'.
		 */
		*equals = '\0';
		col = line;
		val = equals + 1;
	} else {
		val = line;
	}

	/* Do we already have a column by this name?  If so, skip it. */
	if (col != NULL) {
		for (int i = 0; i < data->cols_cnt; i++) {
			if (strcmp(col, data->cols[i]) == 0)
				return (0); /* Duplicate, skip */
		}
	}

	if (val != NULL) {
		tmp = realloc(data->lines,
		    (data->lines_cnt + 1) * sizeof (*data->lines));
		if (tmp == NULL)
			return (1);

		data->lines = tmp;
		data->lines[data->lines_cnt] = strdup(val);
		data->lines_cnt++;
	}

	if (col != NULL) {
		tmp = realloc(data->cols,
		    (data->cols_cnt + 1) * sizeof (*data->cols));
		if (tmp == NULL)
			return (1);

		data->cols = tmp;
		data->cols[data->cols_cnt] = strdup(col);
		data->cols_cnt++;
	}

	if (val != NULL && col == NULL)
		return (1);

	return (0);
}

/*
 * Run the cmd and store results in *data.
 */
static void
vdev_run_cmd(vdev_cmd_data_t *data, char *cmd)
{
	int rc;
	char *argv[2] = {cmd, 0};
	char *env[5] = {"PATH=/bin:/sbin:/usr/bin:/usr/sbin", NULL, NULL, NULL,
	    NULL};
	char **lines = NULL;
	int lines_cnt = 0;
	int i;

	/* Setup our custom environment variables */
	rc = asprintf(&env[1], "VDEV_PATH=%s",
	    data->path ? data->path : "");
	if (rc == -1)
		goto out;

	rc = asprintf(&env[2], "VDEV_UPATH=%s",
	    data->upath ? data->upath : "");
	if (rc == -1)
		goto out;

	rc = asprintf(&env[3], "VDEV_ENC_SYSFS_PATH=%s",
	    data->vdev_enc_sysfs_path ?
	    data->vdev_enc_sysfs_path : "");
	if (rc == -1)
		goto out;

	/* Run the command */
	rc = libzfs_run_process_get_stdout_nopath(cmd, argv, env, &lines,
	    &lines_cnt);
	if (rc != 0)
		goto out;

	/* Process the output we got */
	for (i = 0; i < lines_cnt; i++)
		if (vdev_process_cmd_output(data, lines[i]) != 0)
			break;

out:
	if (lines != NULL)
		libzfs_free_str_array(lines, lines_cnt);

	/* Start with i = 1 since env[0] was statically allocated */
	for (i = 1; i < ARRAY_SIZE(env); i++)
		if (env[i] != NULL)
			free(env[i]);
}

/*
 * Generate the search path for zpool iostat/status -c scripts.
 * The string returned must be freed.
 */
char *
zpool_get_cmd_search_path(void)
{
	const char *env;
	char *sp = NULL;

	env = getenv("ZPOOL_SCRIPTS_PATH");
	if (env != NULL)
		return (strdup(env));

	env = getenv("HOME");
	if (env != NULL) {
		if (asprintf(&sp, "%s/.zpool.d:%s",
		    env, ZPOOL_SCRIPTS_DIR) != -1) {
			return (sp);
		}
	}

	if (asprintf(&sp, "%s", ZPOOL_SCRIPTS_DIR) != -1)
		return (sp);

	return (NULL);
}

/* Thread function run for each vdev */
static void
vdev_run_cmd_thread(void *cb_cmd_data)
{
	vdev_cmd_data_t *data = cb_cmd_data;
	char *cmd = NULL, *cmddup, *cmdrest;

	cmddup = strdup(data->cmd);
	if (cmddup == NULL)
		return;

	cmdrest = cmddup;
	while ((cmd = strtok_r(cmdrest, ",", &cmdrest))) {
		char *dir = NULL, *sp, *sprest;
		char fullpath[MAXPATHLEN];

		if (strchr(cmd, '/') != NULL)
			continue;

		sp = zpool_get_cmd_search_path();
		if (sp == NULL)
			continue;

		sprest = sp;
		while ((dir = strtok_r(sprest, ":", &sprest))) {
			if (snprintf(fullpath, sizeof (fullpath),
			    "%s/%s", dir, cmd) == -1)
				continue;

			if (access(fullpath, X_OK) == 0) {
				vdev_run_cmd(data, fullpath);
				break;
			}
		}
		free(sp);
	}
	free(cmddup);
}

/* For each vdev in the pool run a command */
static int
for_each_vdev_run_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_vcdl)
{
	vdev_cmd_data_list_t *vcdl = cb_vcdl;
	vdev_cmd_data_t *data;
	char *path = NULL;
	char *vname = NULL;
	char *vdev_enc_sysfs_path = NULL;
	int i, match = 0;

	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
		return (1);

	nvlist_lookup_string(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
	    &vdev_enc_sysfs_path);

	/* Spares show more than once if they're in use, so skip if exists */
	for (i = 0; i < vcdl->count; i++) {
		if ((strcmp(vcdl->data[i].path, path) == 0) &&
		    (strcmp(vcdl->data[i].pool, zpool_get_name(zhp)) == 0)) {
			/* vdev already exists, skip it */
			return (0);
		}
	}

	/* Check for whitelisted vdevs here, if any */
	for (i = 0; i < vcdl->vdev_names_count; i++) {
		vname = zpool_vdev_name(g_zfs, zhp, nv, vcdl->cb_name_flags);
		if (strcmp(vcdl->vdev_names[i], vname) == 0) {
			free(vname);
			match = 1;
			break; /* match */
		}
		free(vname);
	}

	/* If we whitelisted vdevs, and this isn't one of them, then bail out */
	if (!match && vcdl->vdev_names_count)
		return (0);

	/*
	 * Resize our array and add in the new element.
	 */
	if (!(vcdl->data = realloc(vcdl->data,
	    sizeof (*vcdl->data) * (vcdl->count + 1))))
		return (ENOMEM);	/* couldn't realloc */

	data = &vcdl->data[vcdl->count];

	data->pool = strdup(zpool_get_name(zhp));
	data->path = strdup(path);
	data->upath = zfs_get_underlying_path(path);
	data->cmd = vcdl->cmd;
	data->lines = data->cols = NULL;
	data->lines_cnt = data->cols_cnt = 0;
	if (vdev_enc_sysfs_path)
		data->vdev_enc_sysfs_path = strdup(vdev_enc_sysfs_path);
	else
		data->vdev_enc_sysfs_path = NULL;

	vcdl->count++;

	return (0);
}

/* Get the names and count of the vdevs */
static int
all_pools_for_each_vdev_gather_cb(zpool_handle_t *zhp, void *cb_vcdl)
{
	return (for_each_vdev(zhp, for_each_vdev_run_cb, cb_vcdl));
}

/*
 * Now that vcdl is populated with our complete list of vdevs, spawn
 * off the commands.
 */
static void
all_pools_for_each_vdev_run_vcdl(vdev_cmd_data_list_t *vcdl)
{
	tpool_t *t;

	t = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN), 0, NULL);
	if (t == NULL)
		return;

	/* Spawn off the command for each vdev */
	for (int i = 0; i < vcdl->count; i++) {
		(void) tpool_dispatch(t, vdev_run_cmd_thread,
		    (void *) &vcdl->data[i]);
	}

	/* Wait for threads to finish */
	tpool_wait(t);
	tpool_destroy(t);
}

/*
 * Run command 'cmd' on all vdevs in all pools in argv.  Saves the first line of
 * output from the command in vcdk->data[].line for all vdevs.  If you want
 * to run the command on only certain vdevs, fill in g_zfs, vdev_names,
 * vdev_names_count, and cb_name_flags.  Otherwise leave them as zero.
 *
 * Returns a vdev_cmd_data_list_t that must be freed with
 * free_vdev_cmd_data_list();
 */
vdev_cmd_data_list_t *
all_pools_for_each_vdev_run(int argc, char **argv, char *cmd,
    libzfs_handle_t *g_zfs, char **vdev_names, int vdev_names_count,
    int cb_name_flags)
{
	vdev_cmd_data_list_t *vcdl;
	vcdl = safe_malloc(sizeof (vdev_cmd_data_list_t));
	vcdl->cmd = cmd;

	vcdl->vdev_names = vdev_names;
	vcdl->vdev_names_count = vdev_names_count;
	vcdl->cb_name_flags = cb_name_flags;
	vcdl->g_zfs = g_zfs;

	/* Gather our list of all vdevs in all pools */
	for_each_pool(argc, argv, B_TRUE, NULL,
	    all_pools_for_each_vdev_gather_cb, vcdl);

	/* Run command on all vdevs in all pools */
	all_pools_for_each_vdev_run_vcdl(vcdl);

	/*
	 * vcdl->data[] now contains all the column names and values for each
	 * vdev.  We need to process that into a master list of unique column
	 * names, and figure out the width of each column.
	 */
	process_unique_cmd_columns(vcdl);

	return (vcdl);
}

/*
 * Free the vdev_cmd_data_list_t created by all_pools_for_each_vdev_run()
 */
void
free_vdev_cmd_data_list(vdev_cmd_data_list_t *vcdl)
{
	free(vcdl->uniq_cols);
	free(vcdl->uniq_cols_width);

	for (int i = 0; i < vcdl->count; i++) {
		free(vcdl->data[i].path);
		free(vcdl->data[i].pool);
		free(vcdl->data[i].upath);

		for (int j = 0; j < vcdl->data[i].lines_cnt; j++)
			free(vcdl->data[i].lines[j]);

		free(vcdl->data[i].lines);

		for (int j = 0; j < vcdl->data[i].cols_cnt; j++)
			free(vcdl->data[i].cols[j]);

		free(vcdl->data[i].cols);
		free(vcdl->data[i].vdev_enc_sysfs_path);
	}
	free(vcdl->data);
	free(vcdl);
}
