/*
 * 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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
 * Copyright 2015 RackTop Systems.
 * Copyright 2016 Nexenta Systems, Inc.
 */

/*
 * Pool import support functions.
 *
 * To import a pool, we rely on reading the configuration information from the
 * ZFS label of each device.  If we successfully read the label, then we
 * organize the configuration information in the following hierarchy:
 *
 *	pool guid -> toplevel vdev guid -> label txg
 *
 * Duplicate entries matching this same tuple will be discarded.  Once we have
 * examined every device, we pick the best label txg config for each toplevel
 * vdev.  We then arrange these toplevel vdevs into a complete pool config, and
 * update any paths that have changed.  Finally, we attempt to import the pool
 * using our derived config, and record the results.
 */

#include <sys/types.h>
#include <sys/disk.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysctl.h>

#include <aio.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <libintl.h>
#include <libgen.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#include <sys/efi_partition.h>
#include <thread_pool.h>
#include <libgeom.h>

#include <sys/vdev_impl.h>

#include <libzutil.h>

#include "zutil_import.h"

/*
 * Update a leaf vdev's persistent device strings
 *
 * - only applies for a dedicated leaf vdev (aka whole disk)
 * - updated during pool create|add|attach|import
 * - used for matching device matching during auto-{online,expand,replace}
 * - stored in a leaf disk config label (i.e. alongside 'path' NVP)
 * - these strings are currently not used in kernel (i.e. for vdev_disk_open)
 *
 * On FreeBSD we currently just strip devid and phys_path to avoid confusion.
 */
void
update_vdev_config_dev_strs(nvlist_t *nv)
{
	(void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID);
	(void) nvlist_remove_all(nv, ZPOOL_CONFIG_PHYS_PATH);
}

/*
 * Do not even look at these devices.
 */
static const char * const excluded_devs[] = {
	"nfslock",
	"sequencer",
	"zfs",
};
#define	EXCLUDED_DIR		"/dev/"
#define	EXCLUDED_DIR_LEN	5

void
zpool_open_func(void *arg)
{
	rdsk_node_t *rn = arg;
	struct stat64 statbuf;
	nvlist_t *config;
	size_t i;
	int num_labels;
	int fd;
	off_t mediasize = 0;

	/*
	 * Do not even look at excluded devices.
	 */
	if (strncmp(rn->rn_name, EXCLUDED_DIR, EXCLUDED_DIR_LEN) == 0) {
		char *name = rn->rn_name + EXCLUDED_DIR_LEN;
		for (i = 0; i < nitems(excluded_devs); ++i) {
			const char *excluded_name = excluded_devs[i];
			size_t len = strlen(excluded_name);
			if (strncmp(name, excluded_name, len) == 0) {
				return;
			}
		}
	}

	/*
	 * O_NONBLOCK so we don't hang trying to open things like serial ports.
	 */
	if ((fd = open(rn->rn_name, O_RDONLY|O_NONBLOCK|O_CLOEXEC)) < 0)
		return;

	/*
	 * Ignore failed stats.
	 */
	if (fstat64(fd, &statbuf) != 0)
		goto out;
	/*
	 * We only want regular files, character devs and block devs.
	 */
	if (S_ISREG(statbuf.st_mode)) {
		/* Check if this file is too small to hold a zpool. */
		if (statbuf.st_size < SPA_MINDEVSIZE) {
			goto out;
		}
	} else if (S_ISCHR(statbuf.st_mode) || S_ISBLK(statbuf.st_mode)) {
		/* Check if this device is too small to hold a zpool. */
		if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) != 0 ||
		    mediasize < SPA_MINDEVSIZE) {
			goto out;
		}
	} else {
		goto out;
	}

	if (zpool_read_label(fd, &config, &num_labels) != 0)
		goto out;
	if (num_labels == 0) {
		nvlist_free(config);
		goto out;
	}

	rn->rn_config = config;
	rn->rn_num_labels = num_labels;

	/* TODO: Reuse labelpaths logic from Linux? */
out:
	(void) close(fd);
}

static const char *
zpool_default_import_path[] = {
	"/dev"
};

const char * const *
zpool_default_search_paths(size_t *count)
{
	*count = nitems(zpool_default_import_path);
	return (zpool_default_import_path);
}

int
zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
    avl_tree_t **slice_cache)
{
	const char *oid = "vfs.zfs.vol.recursive";
	char *end, path[MAXPATHLEN];
	rdsk_node_t *slice;
	struct gmesh mesh;
	struct gclass *mp;
	struct ggeom *gp;
	struct gprovider *pp;
	avl_index_t where;
	int error, value;
	size_t pathleft, size = sizeof (value);
	boolean_t skip_zvols = B_FALSE;

	end = stpcpy(path, "/dev/");
	pathleft = &path[sizeof (path)] - end;

	error = geom_gettree(&mesh);
	if (error != 0)
		return (error);

	if (sysctlbyname(oid, &value, &size, NULL, 0) == 0 && value == 0)
		skip_zvols = B_TRUE;

	*slice_cache = zutil_alloc(hdl, sizeof (avl_tree_t));
	avl_create(*slice_cache, slice_cache_compare, sizeof (rdsk_node_t),
	    offsetof(rdsk_node_t, rn_node));

	LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
		if (skip_zvols && strcmp(mp->lg_name, "ZFS::ZVOL") == 0)
			continue;
		LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
			LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
				strlcpy(end, pp->lg_name, pathleft);
				slice = zutil_alloc(hdl, sizeof (rdsk_node_t));
				slice->rn_name = zutil_strdup(hdl, path);
				slice->rn_vdev_guid = 0;
				slice->rn_lock = lock;
				slice->rn_avl = *slice_cache;
				slice->rn_hdl = hdl;
				slice->rn_labelpaths = B_FALSE;
				slice->rn_order = IMPORT_ORDER_DEFAULT;

				pthread_mutex_lock(lock);
				if (avl_find(*slice_cache, slice, &where)) {
					free(slice->rn_name);
					free(slice);
				} else {
					avl_insert(*slice_cache, slice, where);
				}
				pthread_mutex_unlock(lock);
			}
		}
	}

	geom_deletetree(&mesh);

	return (0);
}

int
zfs_dev_flush(int fd __unused)
{
	return (0);
}

void
update_vdevs_config_dev_sysfs_path(nvlist_t *config)
{
}
