2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*
2N/A * raid operations
2N/A */
2N/A
2N/A#include <meta.h>
2N/A#include <sys/lvm/md_mirror.h>
2N/A
2N/A/*
2N/A * resync raid
2N/A */
2N/Aint
2N/Ameta_raid_resync(
2N/A mdsetname_t *sp,
2N/A mdname_t *raidnp,
2N/A daddr_t size,
2N/A md_error_t *ep
2N/A)
2N/A{
2N/A char *miscname;
2N/A md_resync_ioctl_t ri;
2N/A
2N/A /* should have a set */
2N/A assert(sp != NULL);
2N/A assert(sp->setno == MD_MIN2SET(meta_getminor(raidnp->dev)));
2N/A
2N/A /* make sure we have a raid */
2N/A if ((miscname = metagetmiscname(raidnp, ep)) == NULL)
2N/A return (-1);
2N/A if (strcmp(miscname, MD_RAID) != 0) {
2N/A return (mdmderror(ep, MDE_NOT_RAID, meta_getminor(raidnp->dev),
2N/A raidnp->cname));
2N/A }
2N/A
2N/A /* start resync */
2N/A (void) memset(&ri, 0, sizeof (ri));
2N/A MD_SETDRIVERNAME(&ri, MD_RAID, sp->setno);
2N/A ri.ri_mnum = meta_getminor(raidnp->dev);
2N/A ri.ri_copysize = size;
2N/A if (metaioctl(MD_IOCSETSYNC, &ri, &ri.mde, raidnp->cname) != 0)
2N/A return (mdstealerror(ep, &ri.mde));
2N/A
2N/A /* return success */
2N/A return (0);
2N/A}
2N/A
2N/A/*
2N/A * NAME: meta_raid_resync_all
2N/A * DESCRIPTION: loop through the RAID devices synch'ing all
2N/A * PARAMETERS: char *sp - the set to synch
2N/A * daddr_t size - resync size
2N/A * md_error_t *ep - return error info
2N/A *
2N/A */
2N/Aint
2N/Ameta_raid_resync_all(
2N/A mdsetname_t *sp,
2N/A daddr_t size,
2N/A md_error_t *ep
2N/A)
2N/A{
2N/A mdnamelist_t *nlp = NULL;
2N/A mdnamelist_t *p;
2N/A int rval = 0, fval;
2N/A
2N/A /* should have a set */
2N/A assert(sp != NULL);
2N/A
2N/A /* get raids */
2N/A if (meta_get_raid_names(sp, &nlp, 0, ep) < 0)
2N/A return (-1);
2N/A
2N/A /* fork a process */
2N/A if ((fval = md_daemonize(sp, ep)) != 0) {
2N/A /*
2N/A * md_daemonize forks off a process to do the work. This
2N/A * is the parent or errror.
2N/A */
2N/A if (fval > 0) {
2N/A if (nlp != NULL)
2N/A metafreenamelist(nlp);
2N/A return (0);
2N/A }
2N/A mdclrerror(ep);
2N/A }
2N/A
2N/A assert((fval == 0) || (fval == -1));
2N/A
2N/A /* resync each raid */
2N/A for (p = nlp; (p != NULL); p = p->next) {
2N/A mdname_t *raidnp = p->namep;
2N/A
2N/A if (meta_raid_resync(sp, raidnp, size, ep) != 0)
2N/A rval = -1;
2N/A }
2N/A
2N/A /* cleanup, return success */
2N/A if (nlp != NULL)
2N/A metafreenamelist(nlp);
2N/A if (fval == 0)
2N/A exit(0);
2N/A return (rval);
2N/A}