xref: /titanic_41/usr/src/cmd/lvm/md_monitord/probedev.c (revision 80148899834a4078a2bd348504aa2d6de9752837)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5236d2101Ssk102515  * Common Development and Distribution License (the "License").
6236d2101Ssk102515  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
2222b8c3a8SAndrew Balfour  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include "md_monitord.h"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #define	MD_PROBE_OPEN_T "probe open test"
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate  * Failure return's a 1
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate int
hotspare_ok(char * bname)357c478bd9Sstevel@tonic-gate hotspare_ok(char *bname)
367c478bd9Sstevel@tonic-gate {
377c478bd9Sstevel@tonic-gate 	int fd;
387c478bd9Sstevel@tonic-gate 	char buf[512];
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate 	if ((fd = open(bname, O_RDONLY)) < 0)
417c478bd9Sstevel@tonic-gate 		return (0);
42236d2101Ssk102515 	if (read(fd, buf, sizeof (buf)) < 0) {
43236d2101Ssk102515 		(void) close(fd);
447c478bd9Sstevel@tonic-gate 		return (0);
45236d2101Ssk102515 	}
46236d2101Ssk102515 	(void) close(fd);
477c478bd9Sstevel@tonic-gate 	return (1);
487c478bd9Sstevel@tonic-gate }
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate void
delete_hotspares_impl(mdhspname_t * hspnp,md_hsp_t * hspp,boolean_e verbose)517c478bd9Sstevel@tonic-gate delete_hotspares_impl(mdhspname_t *hspnp, md_hsp_t *hspp, boolean_e verbose)
527c478bd9Sstevel@tonic-gate {
537c478bd9Sstevel@tonic-gate 	md_hs_t *hsp;
547c478bd9Sstevel@tonic-gate 	uint_t		hsi;
557c478bd9Sstevel@tonic-gate 	char    *cname, *bname, *hs_state;
567c478bd9Sstevel@tonic-gate 	md_error_t e = mdnullerror;
577c478bd9Sstevel@tonic-gate 	int deleted_hs = 0;
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate 	for (hsi = 0; (hsi < hspp->hotspares.hotspares_len); ++hsi) {
607c478bd9Sstevel@tonic-gate 		mdnamelist_t *nlp;
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 		hsp = &hspp->hotspares.hotspares_val[hsi];
637c478bd9Sstevel@tonic-gate 		if (verbose == True)
647c478bd9Sstevel@tonic-gate 			monitord_print(6, "hsi %d\n", hsi);
657c478bd9Sstevel@tonic-gate 		cname = hsp->hsnamep->cname;
667c478bd9Sstevel@tonic-gate 		bname = hsp->hsnamep->bname;
677c478bd9Sstevel@tonic-gate 		nlp = NULL;
68*80148899SSurya Prakki 		(void) metanamelist_append(&nlp, hsp->hsnamep);
697c478bd9Sstevel@tonic-gate 		hs_state = hs_state_to_name(hsp, NULL);
707c478bd9Sstevel@tonic-gate 		/* print hotspare */
717c478bd9Sstevel@tonic-gate 		if (verbose == True)
727c478bd9Sstevel@tonic-gate 			monitord_print(6, "\t%-19s\t%-19s\t%-12s\n",
737c478bd9Sstevel@tonic-gate 			    cname, bname, hs_state);
747c478bd9Sstevel@tonic-gate 		if (hsp->state == HSS_AVAILABLE) {
757c478bd9Sstevel@tonic-gate 			if (hotspare_ok(bname))
767c478bd9Sstevel@tonic-gate 				continue;
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 			monitord_print(6, gettext(
797c478bd9Sstevel@tonic-gate 			    "NOTICE: Hotspare %s in %s has failed.\n"
807c478bd9Sstevel@tonic-gate 			    "\tDeleting %s since it is not in use\n\n"),
817c478bd9Sstevel@tonic-gate 			    bname, hspnp->hspname, bname);
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 			if (meta_hs_delete(sp, hspnp, nlp, 0, &e) != NULL) {
847c478bd9Sstevel@tonic-gate 				mde_perror(&e, "");
8522b8c3a8SAndrew Balfour 				mdclrerror(&e);
867c478bd9Sstevel@tonic-gate 			} else {
877c478bd9Sstevel@tonic-gate 				deleted_hs++;
887c478bd9Sstevel@tonic-gate 			}
897c478bd9Sstevel@tonic-gate 		} else {
907c478bd9Sstevel@tonic-gate 			if (verbose == True)
917c478bd9Sstevel@tonic-gate 				monitord_print(6, gettext(
927c478bd9Sstevel@tonic-gate 				    "%s in use - skipping\n"), cname);
937c478bd9Sstevel@tonic-gate 		}
947c478bd9Sstevel@tonic-gate 	}
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate /*
1007c478bd9Sstevel@tonic-gate  * Generic routine to issue probe ioctls
1017c478bd9Sstevel@tonic-gate  */
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate int
md_probe_ioctl(mdnamelist_t * nlp,int ndevs,char * drvname,boolean_e verbose)1047c478bd9Sstevel@tonic-gate md_probe_ioctl(mdnamelist_t *nlp, int ndevs, char *drvname, boolean_e verbose)
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate 	mdnamelist_t	*p;
1077c478bd9Sstevel@tonic-gate 	mdname_t	*np;
108236d2101Ssk102515 	md_probedev_t	probe_ioc, *iocp;
109236d2101Ssk102515 	int		i, retval = 0;
1107c478bd9Sstevel@tonic-gate 	/*
1117c478bd9Sstevel@tonic-gate 	 * Allocate space for all the metadevices and fill in
1127c478bd9Sstevel@tonic-gate 	 * the minor numbers.
1137c478bd9Sstevel@tonic-gate 	 */
1147c478bd9Sstevel@tonic-gate 
115*80148899SSurya Prakki 	(void) memset(&probe_ioc, 0, sizeof (probe_ioc));
1167c478bd9Sstevel@tonic-gate 	iocp = &probe_ioc;
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	if ((iocp->mnum_list = (uintptr_t)calloc(ndevs, sizeof (minor_t)))
1197c478bd9Sstevel@tonic-gate 	    == 0) {
1207c478bd9Sstevel@tonic-gate 		monitord_print(0, "md_probe_ioctl: calloc");
1217c478bd9Sstevel@tonic-gate 		return (-1);
1227c478bd9Sstevel@tonic-gate 	}
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 	(void) strcpy(iocp->test_name, MD_PROBE_OPEN_T);
1257c478bd9Sstevel@tonic-gate 	MD_SETDRIVERNAME(&probe_ioc, drvname, sp->setno);
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 	if (verbose == True) {
1287c478bd9Sstevel@tonic-gate 		monitord_print(6, "\n\nmd_probe_ioctl: %s: %s\n",
1297c478bd9Sstevel@tonic-gate 		    (strcmp(sp->setname, MD_LOCAL_NAME) == 0) ?
1307c478bd9Sstevel@tonic-gate 		    gettext("local_set") :
1317c478bd9Sstevel@tonic-gate 		    sp->setname, iocp->md_driver.md_drivername);
1327c478bd9Sstevel@tonic-gate 	}
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	iocp->nmdevs = ndevs;
1357c478bd9Sstevel@tonic-gate 	if (verbose == True)
1367c478bd9Sstevel@tonic-gate 		monitord_print(6, "...ndevs 0x%x\n", ndevs);
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 	for (p = nlp, i = 0; p; p = p->next, i++) {
1397c478bd9Sstevel@tonic-gate 		np = p->namep;
140b6c8bd52Sjeanm 		((minor_t *)(uintptr_t)iocp->mnum_list)[i] =
141b6c8bd52Sjeanm 		    meta_getminor(np->dev);
1427c478bd9Sstevel@tonic-gate 		if (verbose == True)
1437c478bd9Sstevel@tonic-gate 			monitord_print(6, "...%s 0x%lx\n", np->cname,
144b6c8bd52Sjeanm 			    ((minor_t *)(uintptr_t)iocp->mnum_list)[i]);
1457c478bd9Sstevel@tonic-gate 	}
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 	if (issue_ioctl == True) {
1497c478bd9Sstevel@tonic-gate 		if (metaioctl(MD_IOCPROBE_DEV, iocp, &(iocp->mde), NULL) != 0)
1507c478bd9Sstevel@tonic-gate 			retval = -1;
1517c478bd9Sstevel@tonic-gate 	}
15222b8c3a8SAndrew Balfour 
15322b8c3a8SAndrew Balfour 	Free((void *)(uintptr_t)iocp->mnum_list);
1547c478bd9Sstevel@tonic-gate 	return (retval);
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate /*
1577c478bd9Sstevel@tonic-gate  *
1587c478bd9Sstevel@tonic-gate  *  - remove p from nlp list
1597c478bd9Sstevel@tonic-gate  *  - put it on the toplp list.
1607c478bd9Sstevel@tonic-gate  *  - update the p to the next element
1617c478bd9Sstevel@tonic-gate  */
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate void
add_to_list(mdnamelist_t ** curpp,mdnamelist_t ** prevpp,mdnamelist_t ** newlpp)1647c478bd9Sstevel@tonic-gate add_to_list(mdnamelist_t **curpp, mdnamelist_t **prevpp,
1657c478bd9Sstevel@tonic-gate 		mdnamelist_t **newlpp)
1667c478bd9Sstevel@tonic-gate {
1677c478bd9Sstevel@tonic-gate 	mdnamelist_t	*p, *prevp, *nlp;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	p = *curpp;
1707c478bd9Sstevel@tonic-gate 	prevp = *prevpp;
1717c478bd9Sstevel@tonic-gate 	nlp = *newlpp;
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate 	if (prevp == p) {
1747c478bd9Sstevel@tonic-gate 		/* if first element reset prevp */
1757c478bd9Sstevel@tonic-gate 			prevp = p->next;
1767c478bd9Sstevel@tonic-gate 			p->next = nlp;
1777c478bd9Sstevel@tonic-gate 			nlp = p;
1787c478bd9Sstevel@tonic-gate 			p = prevp;
1797c478bd9Sstevel@tonic-gate 	} else {
1807c478bd9Sstevel@tonic-gate 		prevp->next = p->next;
1817c478bd9Sstevel@tonic-gate 		p->next = nlp;
1827c478bd9Sstevel@tonic-gate 		nlp = p;
1837c478bd9Sstevel@tonic-gate 		p = prevp->next;
1847c478bd9Sstevel@tonic-gate 	}
1857c478bd9Sstevel@tonic-gate 	*curpp = p;
1867c478bd9Sstevel@tonic-gate 	*prevpp = prevp;
1877c478bd9Sstevel@tonic-gate 	*newlpp = nlp;
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate /*
1907c478bd9Sstevel@tonic-gate  * Scans the given list of metadeivces and returns a list of top level
1917c478bd9Sstevel@tonic-gate  * metadevices.
1927c478bd9Sstevel@tonic-gate  * Note: The orignal list is not valid at the end and is set to NULL.
1937c478bd9Sstevel@tonic-gate  */
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate int
get_toplevel_mds(mdnamelist_t ** lpp,mdnamelist_t ** top_pp,boolean_e verbose)1967c478bd9Sstevel@tonic-gate get_toplevel_mds(mdnamelist_t **lpp, mdnamelist_t **top_pp, boolean_e verbose)
1977c478bd9Sstevel@tonic-gate {
1987c478bd9Sstevel@tonic-gate 	mdnamelist_t	*p, *prevp, *toplp;
1997c478bd9Sstevel@tonic-gate 	int		ntopmd, i;
2007c478bd9Sstevel@tonic-gate 	md_common_t	*mdp;
2017c478bd9Sstevel@tonic-gate 	md_error_t	e = mdnullerror;
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	i = ntopmd = 0;
2047c478bd9Sstevel@tonic-gate 	prevp = p = *lpp;
2057c478bd9Sstevel@tonic-gate 	toplp = NULL;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	while (p) {
2087c478bd9Sstevel@tonic-gate 		if ((mdp = meta_get_unit(sp, p->namep, &e)) == NULL) {
20922b8c3a8SAndrew Balfour 			mdclrerror(&e);
2107c478bd9Sstevel@tonic-gate 			if (verbose == True)
2117c478bd9Sstevel@tonic-gate 				monitord_print(6, gettext(
2127c478bd9Sstevel@tonic-gate 				    "......error on (%d)%s\n"), i,
2137c478bd9Sstevel@tonic-gate 				    p->namep->devicesname);
2147c478bd9Sstevel@tonic-gate 				prevp = p;
2157c478bd9Sstevel@tonic-gate 				p = p->next;
2167c478bd9Sstevel@tonic-gate 				continue;
2177c478bd9Sstevel@tonic-gate 		}
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 		if (mdp->parent == MD_NO_PARENT) {
2207c478bd9Sstevel@tonic-gate 			/* increment the top level md count. */
2217c478bd9Sstevel@tonic-gate 			ntopmd++;
2227c478bd9Sstevel@tonic-gate 			add_to_list(&p, &prevp, &toplp);
2237c478bd9Sstevel@tonic-gate 		} else {
2247c478bd9Sstevel@tonic-gate 			prevp = p;
2257c478bd9Sstevel@tonic-gate 			p = p->next;
2267c478bd9Sstevel@tonic-gate 		}
2277c478bd9Sstevel@tonic-gate 		i++;
2287c478bd9Sstevel@tonic-gate 	}
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	*lpp = NULL;
2317c478bd9Sstevel@tonic-gate 	*top_pp = toplp;
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	return (ntopmd);
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate int
get_namelist(mdnamelist_t ** transdevlist,mdnamelist_t ** devlist,char * dev_type)2377c478bd9Sstevel@tonic-gate get_namelist(mdnamelist_t **transdevlist, mdnamelist_t **devlist,
2387c478bd9Sstevel@tonic-gate 					char *dev_type)
2397c478bd9Sstevel@tonic-gate {
2407c478bd9Sstevel@tonic-gate 	mdnamelist_t *np, *prevp;
2417c478bd9Sstevel@tonic-gate 	md_error_t	e = mdnullerror;
2427c478bd9Sstevel@tonic-gate 	char		*type_name;
2437c478bd9Sstevel@tonic-gate 	int		i = 0;
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	prevp = np = *transdevlist;
2467c478bd9Sstevel@tonic-gate 	while (np) {
2477c478bd9Sstevel@tonic-gate 		if ((type_name = metagetmiscname(np->namep, &e)) == NULL) {
2487c478bd9Sstevel@tonic-gate 			*devlist = NULL;
24922b8c3a8SAndrew Balfour 			mdclrerror(&e);
2507c478bd9Sstevel@tonic-gate 			return (-1);
2517c478bd9Sstevel@tonic-gate 		}
2527c478bd9Sstevel@tonic-gate 		if (strcmp(type_name, dev_type) == 0) {
2537c478bd9Sstevel@tonic-gate 			/* move it to the devlist */
2547c478bd9Sstevel@tonic-gate 			add_to_list(&np, &prevp, devlist);
2557c478bd9Sstevel@tonic-gate 			i++;
2567c478bd9Sstevel@tonic-gate 		} else {
2577c478bd9Sstevel@tonic-gate 			prevp = np;
2587c478bd9Sstevel@tonic-gate 			np = np->next;
2597c478bd9Sstevel@tonic-gate 		}
2607c478bd9Sstevel@tonic-gate 	}
2617c478bd9Sstevel@tonic-gate 	return (i);
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate mdnamelist_t *
create_nlp()2667c478bd9Sstevel@tonic-gate create_nlp()
2677c478bd9Sstevel@tonic-gate {
2687c478bd9Sstevel@tonic-gate 	mdnamelist_t *np;
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 	if (np = (mdnamelist_t *)malloc(sizeof (mdnamelist_t))) {
2717c478bd9Sstevel@tonic-gate 		np->next = NULL;
2727c478bd9Sstevel@tonic-gate 		return (np);
2737c478bd9Sstevel@tonic-gate 	} else {
2747c478bd9Sstevel@tonic-gate 		/* error condition below */
2757c478bd9Sstevel@tonic-gate 		monitord_print(0, gettext(
2767c478bd9Sstevel@tonic-gate 		    "create_nlp: malloc failed\n"));
2777c478bd9Sstevel@tonic-gate 		monitord_exit(errno);
2787c478bd9Sstevel@tonic-gate 	}
279b6c8bd52Sjeanm 	return (0);
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate /*
2837c478bd9Sstevel@tonic-gate  * Create a list of metadevices associated with trans. top_pp points to
2847c478bd9Sstevel@tonic-gate  * this list. The number of components in the list are also returned.
2857c478bd9Sstevel@tonic-gate  */
2867c478bd9Sstevel@tonic-gate int
create_trans_compslist(mdnamelist_t ** lpp,mdnamelist_t ** top_pp,boolean_e verbose)2877c478bd9Sstevel@tonic-gate create_trans_compslist(mdnamelist_t **lpp, mdnamelist_t **top_pp,
2887c478bd9Sstevel@tonic-gate 							boolean_e verbose)
2897c478bd9Sstevel@tonic-gate {
2907c478bd9Sstevel@tonic-gate 	mdnamelist_t	*p, *tailp, *toplp, *newlp;
2917c478bd9Sstevel@tonic-gate 	int		ntoptrans;
2927c478bd9Sstevel@tonic-gate 	md_error_t	e = mdnullerror;
2937c478bd9Sstevel@tonic-gate 	md_trans_t	*tp;
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	ntoptrans = 0;
2967c478bd9Sstevel@tonic-gate 	p = *lpp;
2977c478bd9Sstevel@tonic-gate 	tailp = toplp = NULL;
2987c478bd9Sstevel@tonic-gate 	/*
2997c478bd9Sstevel@tonic-gate 	 * Scan the current list of trans devices. From that
3007c478bd9Sstevel@tonic-gate 	 * extract all the lower level metadevices and put them on
3017c478bd9Sstevel@tonic-gate 	 * toplp list.
3027c478bd9Sstevel@tonic-gate 	 */
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate 	while (p) {
3057c478bd9Sstevel@tonic-gate 		if (tp = meta_get_trans(sp, p->namep, &e)) {
3067c478bd9Sstevel@tonic-gate 			/*
3077c478bd9Sstevel@tonic-gate 			 * Check the master and log devices to see if they
3087c478bd9Sstevel@tonic-gate 			 * are metadevices
3097c478bd9Sstevel@tonic-gate 			 */
3107c478bd9Sstevel@tonic-gate 			if (metaismeta(tp->masternamep)) {
3117c478bd9Sstevel@tonic-gate 				if (verbose == True)
3127c478bd9Sstevel@tonic-gate 					monitord_print(6, gettext(
3137c478bd9Sstevel@tonic-gate 					    "master metadevice\n"));
3147c478bd9Sstevel@tonic-gate 				/* get a mdnamelist_t. */
3157c478bd9Sstevel@tonic-gate 				newlp = create_nlp();
3167c478bd9Sstevel@tonic-gate 				newlp->namep = tp->masternamep;
3177c478bd9Sstevel@tonic-gate 				if (toplp == NULL) {
3187c478bd9Sstevel@tonic-gate 					toplp = tailp = newlp;
3197c478bd9Sstevel@tonic-gate 				} else {
3207c478bd9Sstevel@tonic-gate 					tailp->next = newlp;
3217c478bd9Sstevel@tonic-gate 					tailp = newlp;
3227c478bd9Sstevel@tonic-gate 				}
3237c478bd9Sstevel@tonic-gate 				ntoptrans++;
3247c478bd9Sstevel@tonic-gate 			}
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 			if (tp->lognamep && metaismeta(tp->lognamep)) {
3277c478bd9Sstevel@tonic-gate 				if (verbose == True)
3287c478bd9Sstevel@tonic-gate 					monitord_print(6, gettext(
3297c478bd9Sstevel@tonic-gate 					    "log metadevice\n"));
3307c478bd9Sstevel@tonic-gate 				newlp = create_nlp();
3317c478bd9Sstevel@tonic-gate 				newlp->namep = tp->lognamep;
3327c478bd9Sstevel@tonic-gate 				if (toplp == NULL) {
3337c478bd9Sstevel@tonic-gate 					toplp = tailp = newlp;
3347c478bd9Sstevel@tonic-gate 				} else {
3357c478bd9Sstevel@tonic-gate 					tailp->next = newlp;
3367c478bd9Sstevel@tonic-gate 					tailp = newlp;
3377c478bd9Sstevel@tonic-gate 				}
3387c478bd9Sstevel@tonic-gate 				ntoptrans++;
3397c478bd9Sstevel@tonic-gate 			}
3407c478bd9Sstevel@tonic-gate 			p = p->next;
34122b8c3a8SAndrew Balfour 		} else {
34222b8c3a8SAndrew Balfour 			mdclrerror(&e);
3437c478bd9Sstevel@tonic-gate 		}
3447c478bd9Sstevel@tonic-gate 	}
3457c478bd9Sstevel@tonic-gate 	*top_pp = toplp;
3467c478bd9Sstevel@tonic-gate 	return (ntoptrans);
3477c478bd9Sstevel@tonic-gate }
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate void
probe_mirror_devs(boolean_e verbose)3507c478bd9Sstevel@tonic-gate probe_mirror_devs(boolean_e verbose)
3517c478bd9Sstevel@tonic-gate {
3527c478bd9Sstevel@tonic-gate 	mdnamelist_t	*nlp, *toplp;
3537c478bd9Sstevel@tonic-gate 	int		cnt;
3547c478bd9Sstevel@tonic-gate 	md_error_t	e = mdnullerror;
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate 	nlp = toplp = NULL;
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	if (meta_get_mirror_names(sp, &nlp, 0, &e) > 0) {
3597c478bd9Sstevel@tonic-gate 		/*
3607c478bd9Sstevel@tonic-gate 		 * We have some mirrors to probe
3617c478bd9Sstevel@tonic-gate 		 * get a list of top-level mirrors
3627c478bd9Sstevel@tonic-gate 		 */
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 		cnt = get_toplevel_mds(&nlp, &toplp, verbose);
3657c478bd9Sstevel@tonic-gate 		if (cnt && (md_probe_ioctl(toplp, cnt,
3667c478bd9Sstevel@tonic-gate 		    MD_MIRROR, verbose) < 0))
3677c478bd9Sstevel@tonic-gate 			monitord_print(0, gettext(
3687c478bd9Sstevel@tonic-gate 			    "probe_mirror_devs: "
3697c478bd9Sstevel@tonic-gate 			    "mirror components %d ioctl error\n"),
3707c478bd9Sstevel@tonic-gate 			    cnt);
3717c478bd9Sstevel@tonic-gate 
37222b8c3a8SAndrew Balfour 	} else {
37322b8c3a8SAndrew Balfour 		mdclrerror(&e);
3747c478bd9Sstevel@tonic-gate 	}
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	metafreenamelist(nlp);
3777c478bd9Sstevel@tonic-gate 	metafreenamelist(toplp);
3787c478bd9Sstevel@tonic-gate }
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate void
probe_raid_devs(boolean_e verbose)3817c478bd9Sstevel@tonic-gate probe_raid_devs(boolean_e verbose)
3827c478bd9Sstevel@tonic-gate {
3837c478bd9Sstevel@tonic-gate 	mdnamelist_t	*nlp, *toplp;
3847c478bd9Sstevel@tonic-gate 	int		cnt;
3857c478bd9Sstevel@tonic-gate 	md_error_t	e = mdnullerror;
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 	nlp = toplp = NULL;
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 	if (meta_get_raid_names(sp, &nlp, 0, &e) > 0) {
3907c478bd9Sstevel@tonic-gate 		/*
3917c478bd9Sstevel@tonic-gate 		 * We have some mirrors to probe
3927c478bd9Sstevel@tonic-gate 		 * get a list of top-level mirrors
3937c478bd9Sstevel@tonic-gate 		 */
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 		cnt = get_toplevel_mds(&nlp, &toplp, verbose);
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate 		if (cnt && (md_probe_ioctl(toplp, cnt,
3987c478bd9Sstevel@tonic-gate 		    MD_RAID, verbose) < 0))
3997c478bd9Sstevel@tonic-gate 			monitord_print(0, gettext(
4007c478bd9Sstevel@tonic-gate 			    "probe_raid_devs: "
4017c478bd9Sstevel@tonic-gate 			    "RAID-5 components %d ioctl error\n"),
4027c478bd9Sstevel@tonic-gate 			    cnt);
40322b8c3a8SAndrew Balfour 	} else {
40422b8c3a8SAndrew Balfour 		mdclrerror(&e);
4057c478bd9Sstevel@tonic-gate 	}
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 	metafreenamelist(nlp);
4087c478bd9Sstevel@tonic-gate 	metafreenamelist(toplp);
4097c478bd9Sstevel@tonic-gate }
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate /*
4127c478bd9Sstevel@tonic-gate  * Trans probes are different. -- so whats new.
4137c478bd9Sstevel@tonic-gate  * we separate out the master and log device and then issue the
4147c478bd9Sstevel@tonic-gate  * probe calls.
4157c478bd9Sstevel@tonic-gate  * Since the underlying device could be disk, stripe, RAID or miror,
4167c478bd9Sstevel@tonic-gate  * we have to sort them out and then call the ioctl for each.
4177c478bd9Sstevel@tonic-gate  */
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate void
probe_trans_devs(boolean_e verbose)4207c478bd9Sstevel@tonic-gate probe_trans_devs(boolean_e verbose)
4217c478bd9Sstevel@tonic-gate {
4227c478bd9Sstevel@tonic-gate 	mdnamelist_t	*nlp, *toplp;
4237c478bd9Sstevel@tonic-gate 	mdnamelist_t	*trans_raidlp, *trans_mmlp, *trans_stripelp;
4247c478bd9Sstevel@tonic-gate 	int		cnt;
4257c478bd9Sstevel@tonic-gate 	md_error_t	e = mdnullerror;
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate 	nlp = toplp = NULL;
4287c478bd9Sstevel@tonic-gate 	trans_raidlp = trans_mmlp = trans_stripelp = NULL;
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 	if (meta_get_trans_names(sp, &nlp, 0, &e) > 0) {
4317c478bd9Sstevel@tonic-gate 		/*
4327c478bd9Sstevel@tonic-gate 		 * get a list of master and log metadevices.
4337c478bd9Sstevel@tonic-gate 		 */
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 		cnt = create_trans_compslist(&nlp, &toplp, verbose);
4367c478bd9Sstevel@tonic-gate 		if (verbose == True) {
4377c478bd9Sstevel@tonic-gate 			int i;
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 			for (i = 0, nlp = toplp; i < cnt; i++) {
4407c478bd9Sstevel@tonic-gate 				monitord_print(6, gettext(
4417c478bd9Sstevel@tonic-gate 				    "tran: underlying drv %s\n"),
4427c478bd9Sstevel@tonic-gate 				    (nlp->namep)->cname);
4437c478bd9Sstevel@tonic-gate 				nlp = nlp->next;
4447c478bd9Sstevel@tonic-gate 			}
4457c478bd9Sstevel@tonic-gate 		}
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 		/* underlying RAID-5 components */
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 		cnt = get_namelist(&toplp, &trans_raidlp, MD_RAID);
4507c478bd9Sstevel@tonic-gate 		if ((cnt > 0) && (md_probe_ioctl(trans_raidlp, cnt,
4517c478bd9Sstevel@tonic-gate 		    MD_RAID, verbose) < 0))
4527c478bd9Sstevel@tonic-gate 			monitord_print(0, gettext(
4537c478bd9Sstevel@tonic-gate 			    "probe_trans_devs: "
4547c478bd9Sstevel@tonic-gate 			    "RAID-5 components %d ioctl error\n"),
4557c478bd9Sstevel@tonic-gate 			    cnt);
4567c478bd9Sstevel@tonic-gate 		metafreenamelist(trans_raidlp);
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 		/* underlying mirror components */
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 		cnt = get_namelist(&toplp, &trans_mmlp, MD_MIRROR);
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate 		if ((cnt > 0) && (md_probe_ioctl(trans_mmlp, cnt,
4637c478bd9Sstevel@tonic-gate 		    MD_MIRROR, verbose) < 0))
4647c478bd9Sstevel@tonic-gate 			monitord_print(0, gettext(
4657c478bd9Sstevel@tonic-gate 			    "probe_trans_devs: "
4667c478bd9Sstevel@tonic-gate 			    "mirror components %d ioctl error\n"),
4677c478bd9Sstevel@tonic-gate 			    cnt);
4687c478bd9Sstevel@tonic-gate 		metafreenamelist(trans_mmlp);
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 		/* underlying stripe components */
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 		cnt = get_namelist(&toplp, &trans_stripelp, MD_STRIPE);
4737c478bd9Sstevel@tonic-gate 		if ((cnt > 0) && (md_probe_ioctl(trans_stripelp, cnt,
4747c478bd9Sstevel@tonic-gate 		    MD_STRIPE, verbose) < 0))
4757c478bd9Sstevel@tonic-gate 			monitord_print(0, gettext(
4767c478bd9Sstevel@tonic-gate 			    "probe_trans_devs: "
4777c478bd9Sstevel@tonic-gate 			    "stripe components %d ioctl error\n"),
4787c478bd9Sstevel@tonic-gate 			    cnt);
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 		metafreenamelist(trans_stripelp);
4817c478bd9Sstevel@tonic-gate 		metafreenamelist(nlp);
48222b8c3a8SAndrew Balfour 	} else {
48322b8c3a8SAndrew Balfour 		mdclrerror(&e);
4847c478bd9Sstevel@tonic-gate 	}
4857c478bd9Sstevel@tonic-gate }
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate /*
4887c478bd9Sstevel@tonic-gate  * probe hot spares. This is differs from other approaches since
4897c478bd9Sstevel@tonic-gate  * there are no read/write routines through md. We check at the physical
4907c478bd9Sstevel@tonic-gate  * component level and then delete it if its bad.
4917c478bd9Sstevel@tonic-gate  */
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate void
probe_hotspare_devs(boolean_e verbose)4947c478bd9Sstevel@tonic-gate probe_hotspare_devs(boolean_e verbose)
4957c478bd9Sstevel@tonic-gate {
4967c478bd9Sstevel@tonic-gate 	mdhspnamelist_t *hspnlp = NULL;
4977c478bd9Sstevel@tonic-gate 	mdhspnamelist_t	*p;
4987c478bd9Sstevel@tonic-gate 	md_hsp_t	*hspp;
4997c478bd9Sstevel@tonic-gate 	md_error_t	e = mdnullerror;
5007c478bd9Sstevel@tonic-gate 
50122b8c3a8SAndrew Balfour 	if (meta_get_hsp_names(sp, &hspnlp, 0, &e) <= 0) {
50222b8c3a8SAndrew Balfour 		mdclrerror(&e);
5037c478bd9Sstevel@tonic-gate 		return;
5047c478bd9Sstevel@tonic-gate 	}
50522b8c3a8SAndrew Balfour 
5067c478bd9Sstevel@tonic-gate 	for (p = hspnlp; (p != NULL); p = p->next) {
5077c478bd9Sstevel@tonic-gate 		mdhspname_t	*hspnp = p->hspnamep;
5087c478bd9Sstevel@tonic-gate 
5097c478bd9Sstevel@tonic-gate 		if (verbose == True)
5107c478bd9Sstevel@tonic-gate 			monitord_print(6, "%s %s\n", gettext("name"),
5117c478bd9Sstevel@tonic-gate 			    hspnp->hspname);
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 		if ((hspp = meta_get_hsp(sp, hspnp, &e)) == NULL)
5147c478bd9Sstevel@tonic-gate 			continue;
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate 		if (hspp->hotspares.hotspares_len != 0) {
5177c478bd9Sstevel@tonic-gate 			if (verbose == True)
5187c478bd9Sstevel@tonic-gate 				monitord_print(6, " %u hotspares\n",
5197c478bd9Sstevel@tonic-gate 				    hspp->hotspares.hotspares_len);
5207c478bd9Sstevel@tonic-gate 			delete_hotspares_impl(hspnp, hspp, verbose);
5217c478bd9Sstevel@tonic-gate 		}
5227c478bd9Sstevel@tonic-gate 	}
52322b8c3a8SAndrew Balfour 	mdclrerror(&e);
5247c478bd9Sstevel@tonic-gate 	metafreehspnamelist(hspnlp);
5257c478bd9Sstevel@tonic-gate }
526