void probe_raid_devs(boolean_e verbose) { mdnamelist_t *nlp, *toplp; int cnt; md_error_t e = mdnullerror; nlp = toplp = NULL; if (meta_get_raid_names(sp, &nlp, 0, &e) > 0) { /* * We have some mirrors to probe * get a list of top-level mirrors */ cnt = get_toplevel_mds(&nlp, &toplp, verbose); if (cnt && (md_probe_ioctl(toplp, cnt, MD_RAID, verbose) < 0)) monitord_print(0, gettext( "probe_raid_devs: " "RAID-5 components %d ioctl error\n"), cnt); } metafreenamelist(nlp); metafreenamelist(toplp); }
/* * NAME: meta_raid_resync_all * DESCRIPTION: loop through the RAID devices synch'ing all * PARAMETERS: char *sp - the set to synch * daddr_t size - resync size * md_error_t *ep - return error info * */ int meta_raid_resync_all( mdsetname_t *sp, daddr_t size, md_error_t *ep ) { mdnamelist_t *nlp = NULL; mdnamelist_t *p; int rval = 0, fval; /* should have a set */ assert(sp != NULL); /* get raids */ if (meta_get_raid_names(sp, &nlp, 0, ep) < 0) return (-1); /* fork a process */ if ((fval = md_daemonize(sp, ep)) != 0) { /* * md_daemonize forks off a process to do the work. This * is the parent or errror. */ if (fval > 0) { if (nlp != NULL) metafreenamelist(nlp); return (0); } mdclrerror(ep); } assert((fval == 0) || (fval == -1)); /* resync each raid */ for (p = nlp; (p != NULL); p = p->next) { mdname_t *raidnp = p->namep; if (meta_raid_resync(sp, raidnp, size, ep) != 0) rval = -1; } /* cleanup, return success */ if (nlp != NULL) metafreenamelist(nlp); if (fval == 0) exit(0); return (rval); }
void probe_trans_devs(boolean_e verbose) { mdnamelist_t *nlp, *toplp; mdnamelist_t *trans_raidlp, *trans_mmlp, *trans_stripelp; int cnt; md_error_t e = mdnullerror; nlp = toplp = NULL; trans_raidlp = trans_mmlp = trans_stripelp = NULL; if (meta_get_trans_names(sp, &nlp, 0, &e) > 0) { /* * get a list of master and log metadevices. */ cnt = create_trans_compslist(&nlp, &toplp, verbose); if (verbose == True) { int i; for (i = 0, nlp = toplp; i < cnt; i++) { monitord_print(6, gettext( "tran: underlying drv %s\n"), (nlp->namep)->cname); nlp = nlp->next; } } /* underlying RAID-5 components */ cnt = get_namelist(&toplp, &trans_raidlp, MD_RAID); if ((cnt > 0) && (md_probe_ioctl(trans_raidlp, cnt, MD_RAID, verbose) < 0)) monitord_print(0, gettext( "probe_trans_devs: " "RAID-5 components %d ioctl error\n"), cnt); metafreenamelist(trans_raidlp); /* underlying mirror components */ cnt = get_namelist(&toplp, &trans_mmlp, MD_MIRROR); if ((cnt > 0) && (md_probe_ioctl(trans_mmlp, cnt, MD_MIRROR, verbose) < 0)) monitord_print(0, gettext( "probe_trans_devs: " "mirror components %d ioctl error\n"), cnt); metafreenamelist(trans_mmlp); /* underlying stripe components */ cnt = get_namelist(&toplp, &trans_stripelp, MD_STRIPE); if ((cnt > 0) && (md_probe_ioctl(trans_stripelp, cnt, MD_STRIPE, verbose) < 0)) monitord_print(0, gettext( "probe_trans_devs: " "stripe components %d ioctl error\n"), cnt); metafreenamelist(trans_stripelp); metafreenamelist(nlp); } }
int get_mdcomponents(char *uname, svm_info_t **svmpp) { svm_info_t *svmp; md_error_t status, *ep; mdname_t *namep; mdnamelist_t *nlp = NULL; mdnamelist_t *p; mdsetname_t *sp = NULL; char *strp = NULL; int rval, cnt; rval = RET_SUCCESS; cnt = 0; status = mdnullerror; ep = &status; svmp = *svmpp; (void) init_metalib(); debug_printf("get_mdcomponents(): Enter unit name %s\n", uname); if (((namep = metaname(&sp, uname, META_DEVICE, ep)) == NULL) || (metachkmeta(namep, ep) != 0)) { debug_printf("get_mdcomponents(): " "metaname or metachkmeta failed\n"); mdclrerror(ep); return (RET_ERROR); } debug_printf("get_mdcomponents(): meta_getdevs %s\n", namep->cname); if ((meta_getdevs(sp, namep, &nlp, ep)) < 0) { debug_printf("get_mdcomponents(): " "comp %s - meta_getdevs failed\n", uname); metafreenamelist(nlp); mdclrerror(ep); return (RET_ERROR); } /* compute the number of devices */ for (p = nlp, cnt = 0; p != NULL; p = p->next, cnt++) ; /* * Need to add n -1 components since slvmp already has space * for one device. */ svmp = (svm_info_t *)realloc(svmp, sizeof (svm_info_t) + (sizeof (char *) * (cnt - 1))); if (svmp == NULL) { debug_printf("get_mdcomponents(): realloc of svmp failed\n"); metafreenamelist(nlp); return (RET_ERROR); } for (p = nlp, cnt = 0; p != NULL; p = p->next, cnt++) { mdname_t *devnp = p->namep; if ((strp = strdup(devnp->cname)) == NULL) { rval = RET_ERROR; break; } svmp->md_comps[cnt] = strp; } /* count is set to the number of devices in the list */ svmp->count = cnt; svmp->root_md = strdup(uname); if (rval == RET_SUCCESS && svmp->root_md != NULL) { debug_printf("get_mdcomponents(): root_md %s count %d \n", svmp->root_md, svmp->count); for (cnt = 0; cnt < svmp->count; cnt++) debug_printf("get_mdcomponents(): %s\n", svmp->md_comps[cnt]); } else { rval = RET_ERROR; svm_free(svmp); svmp = NULL; debug_printf("get_mdcomponents(): malloc failed\n"); } metafreenamelist(nlp); *svmpp = svmp; return (rval); }
/* * This routine is called from preenlib the first time. It is then * recursively called through preen_subdev. * * The argument passed in (uname) starts with the special device from * /etc/vfstab. Recursive calls pass in the underlying physical device * names. */ void preen_build_devs( char *uname, /* name of metadevice */ struct dk_cinfo *dkiop, /* associated controller info */ void *dp /* magic info */ ) { char *setname = NULL; char *tname = NULL; mdsetname_t *sp; mdname_t *namep; /* metadevice name */ mdnamelist_t *nlp = NULL; /* list of real devices */ mdnamelist_t *p; devid_nmlist_t *nm_list = NULL; md_error_t status = mdnullerror; md_error_t *ep = &status; int ep_valid = 0; /* does ep contain a real error */ struct stat statb; static int md_major = -1; side_t sideno; /* * The rest of the code in this library can't work within a * non-global zone so we just return the top level metadevice back * to be fscked. */ if (getzoneid() != GLOBAL_ZONEID) { preen_addunit(dp, dkiop->dki_dname, NULL, NULL, dkiop->dki_unit); return; } if (stat(uname, &statb) != 0) return; if (md_major == -1 && get_major_from_n2m(MD_MODULE, &md_major) != 0) return; /* * If the path passed in is not a metadevice, then add that * device to the list (preen_addunit) since it has to be a * physical device. */ if (major(statb.st_rdev) != md_major) { preen_addunit(dp, dkiop->dki_dname, NULL, NULL, dkiop->dki_unit); return; } /* * Bind to the cluster library */ if (sdssc_bind_library() == SDSSC_ERROR) return; if (md_init_daemon("fsck", ep) != 0) { ep_valid = 1; goto out; } /* * parse the path name to get the diskset name. */ parse_device(NULL, uname, &tname, &setname); Free(tname); if ((sp = metasetname(setname, ep)) == NULL) { ep_valid = 1; goto out; } /* check for ownership */ if (meta_check_ownership(sp, ep) != 0) { /* * Don't own the set but we are here implies * that this is a clustered proxy device. Simply add * the unit. */ preen_addunit(dp, dkiop->dki_dname, NULL, NULL, dkiop->dki_unit); ep_valid = 1; goto out; } /* * get list of underlying physical devices. */ if ((namep = metaname(&sp, uname, UNKNOWN, ep)) == NULL) { ep_valid = 1; goto out; } if (namep->dev == NODEV64) { goto out; } if (meta_getdevs(sp, namep, &nlp, ep) != 0) { ep_valid = 1; goto out; } if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD) { ep_valid = 1; goto out; } /* gather and add the underlying devs */ for (p = nlp; (p != NULL); p = p->next) { mdname_t *devnp = p->namep; int fd; struct dk_cinfo cinfo; ddi_devid_t md_did; char *devname; char *minor_name = NULL; char mname[MAXPATHLEN]; /* * we don't want to use the rname anymore because * that may have changed. Use the device id information * to find the correct ctd name and open based on that. * If there isn't a devid or we have a did device, then * use the rname. In clustering, it's corrected for us. * If no devid it's at least worth a try. */ if (((md_did = meta_getdidbykey(sp->setno, sideno, devnp->key, ep)) == NULL) || ((minor_name = meta_getdidminorbykey(sp->setno, sideno, devnp->key, ep)) == NULL)) { devname = devnp->rname; if (md_did) Free(md_did); } else { if (strstr(minor_name, ",raw") == NULL) { (void) snprintf(mname, MAXPATHLEN, "%s,raw", minor_name); } else { (void) snprintf(mname, MAXPATHLEN, "%s", minor_name); } /* * We need to make sure we call this with a specific * mname (raw mname) so that we get the exact slice * with the given device id. Otherwise we could try * to open a slice that doesn't really exist. */ if (meta_deviceid_to_nmlist("/dev", md_did, mname, &nm_list) != 0) { (void) mdsyserror(ep, errno, devnp->rname); ep_valid = 1; Free(md_did); Free(minor_name); goto out; } devname = Strdup(nm_list->devname); Free(md_did); Free(minor_name); devid_free_nmlist(nm_list); } /* get device name and (real) cinfo */ if ((fd = open(devname, O_RDONLY, 0)) < 0) { (void) mdsyserror(ep, errno, devname); ep_valid = 1; /* * We need to scan all sub devices even if some fail * since exit here would end up in not finishing fsck * on all devices and prevent us from going into * multiuser mode. */ continue; } if (ioctl(fd, DKIOCINFO, &cinfo) != 0) { (void) mdsyserror(ep, errno, devname); (void) close(fd); ep_valid = 1; /* Continue here too. See comment from before */ continue; } (void) close(fd); /* sd/ssd bug */ /* * preen_subdev fails when the device name has been * resolved to the physical layer. Hence it is added * to preen_addunit. */ if (preen_subdev(devname, &cinfo, dp) != 0) { preen_addunit(dp, cinfo.dki_dname, NULL, NULL, cinfo.dki_unit); } } /* cleanup, if we fail, just add this composite device to the list */ out: if (setname != NULL) Free(setname); if (ep_valid != 0) { mde_perror(&status, ""); mdclrerror(&status); } metafreenamelist(nlp); }