xref: /onnv-gate/usr/src/lib/lvm/libmeta/common/meta_raid_resync.c (revision 0:68f95e015346)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1994-2002 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * raid operations
31  */
32 
33 #include <meta.h>
34 #include <sys/lvm/md_mirror.h>
35 
36 /*
37  * resync raid
38  */
39 int
meta_raid_resync(mdsetname_t * sp,mdname_t * raidnp,daddr_t size,md_error_t * ep)40 meta_raid_resync(
41 	mdsetname_t		*sp,
42 	mdname_t		*raidnp,
43 	daddr_t			size,
44 	md_error_t		*ep
45 )
46 {
47 	char			*miscname;
48 	md_resync_ioctl_t	ri;
49 
50 	/* should have a set */
51 	assert(sp != NULL);
52 	assert(sp->setno == MD_MIN2SET(meta_getminor(raidnp->dev)));
53 
54 	/* make sure we have a raid */
55 	if ((miscname = metagetmiscname(raidnp, ep)) == NULL)
56 		return (-1);
57 	if (strcmp(miscname, MD_RAID) != 0) {
58 		return (mdmderror(ep, MDE_NOT_RAID, meta_getminor(raidnp->dev),
59 		    raidnp->cname));
60 	}
61 
62 	/* start resync */
63 	(void) memset(&ri, 0, sizeof (ri));
64 	MD_SETDRIVERNAME(&ri, MD_RAID, sp->setno);
65 	ri.ri_mnum = meta_getminor(raidnp->dev);
66 	ri.ri_copysize = size;
67 	if (metaioctl(MD_IOCSETSYNC, &ri, &ri.mde, raidnp->cname) != 0)
68 		return (mdstealerror(ep, &ri.mde));
69 
70 	/* return success */
71 	return (0);
72 }
73 
74 /*
75  * NAME:	meta_raid_resync_all
76  * DESCRIPTION: loop through the RAID devices synch'ing all
77  * PARAMETERS:	char		*sp	- the set to synch
78  *		daddr_t		size	- resync size
79  *		md_error_t	*ep	- return error info
80  *
81  */
82 int
meta_raid_resync_all(mdsetname_t * sp,daddr_t size,md_error_t * ep)83 meta_raid_resync_all(
84 	mdsetname_t	*sp,
85 	daddr_t		size,
86 	md_error_t	*ep
87 )
88 {
89 	mdnamelist_t	*nlp = NULL;
90 	mdnamelist_t	*p;
91 	int		rval = 0, fval;
92 
93 	/* should have a set */
94 	assert(sp != NULL);
95 
96 	/* get raids */
97 	if (meta_get_raid_names(sp, &nlp, 0, ep) < 0)
98 		return (-1);
99 
100 	/* fork a process */
101 	if ((fval = md_daemonize(sp, ep)) != 0) {
102 		/*
103 		 * md_daemonize forks off a process to do the work.  This
104 		 * is the parent or errror.
105 		 */
106 		if (fval > 0) {
107 			if (nlp != NULL)
108 				metafreenamelist(nlp);
109 			return (0);
110 		}
111 		mdclrerror(ep);
112 	}
113 
114 	assert((fval == 0) || (fval == -1));
115 
116 	/* resync each raid */
117 	for (p = nlp; (p != NULL); p = p->next) {
118 		mdname_t	*raidnp = p->namep;
119 
120 		if (meta_raid_resync(sp, raidnp, size, ep) != 0)
121 			rval = -1;
122 	}
123 
124 	/* cleanup, return success */
125 	if (nlp != NULL)
126 		metafreenamelist(nlp);
127 	if (fval == 0)
128 		exit(0);
129 	return (rval);
130 }
131