/* * Create a list of metadevices associated with trans. top_pp points to * this list. The number of components in the list are also returned. */ int create_trans_compslist(mdnamelist_t **lpp, mdnamelist_t **top_pp, boolean_e verbose) { mdnamelist_t *p, *tailp, *toplp, *newlp; int ntoptrans; md_error_t e = mdnullerror; md_trans_t *tp; ntoptrans = 0; p = *lpp; tailp = toplp = NULL; /* * Scan the current list of trans devices. From that * extract all the lower level metadevices and put them on * toplp list. */ while (p) { if (tp = meta_get_trans(sp, p->namep, &e)) { /* * Check the master and log devices to see if they * are metadevices */ if (metaismeta(tp->masternamep)) { if (verbose == True) monitord_print(6, gettext( "master metadevice\n")); /* get a mdnamelist_t. */ newlp = create_nlp(); newlp->namep = tp->masternamep; if (toplp == NULL) { toplp = tailp = newlp; } else { tailp->next = newlp; tailp = newlp; } ntoptrans++; } if (tp->lognamep && metaismeta(tp->lognamep)) { if (verbose == True) monitord_print(6, gettext( "log metadevice\n")); newlp = create_nlp(); newlp->namep = tp->lognamep; if (toplp == NULL) { toplp = tailp = newlp; } else { tailp->next = newlp; tailp = newlp; } ntoptrans++; } p = p->next; } } *top_pp = toplp; return (ntoptrans); }
/* * check to see if a device is in its set */ int meta_check_inset( mdsetname_t *sp, mdname_t *np, md_error_t *ep ) { mdsetname_t *npsp; int bypass_daemon = FALSE; /* check devices set */ if (metaislocalset(sp)) bypass_daemon = TRUE; if ((npsp = metagetset(np, bypass_daemon, ep)) == NULL) { if ((! metaismeta(np)) && (metaislocalset(sp)) && (mdismddberror(ep, MDE_DB_NODB))) { mdclrerror(ep); npsp = sp; } else { return (-1); } } /* check set */ if (metaissameset(sp, npsp)) return (0); /* return appropriate error */ if (metaislocalset(sp)) return (mddeverror(ep, MDE_IN_SHARED_SET, np->dev, np->cname)); else return (mddeverror(ep, MDE_NOT_IN_SET, np->dev, np->cname)); }
/* * Return the current root filesystem block device name. This is only valid * when root is either a slice, a stripe or a mirror. */ mdname_t * meta_get_current_root_dev( mdsetname_t *sp, md_error_t *ep ) { md_stripe_t *stripep; md_mirror_t *mirrorp; md_row_t *rp; md_comp_t *cp; mdname_t *rootnp; void *curroot; char *miscname; int smi; if ((curroot = meta_get_current_root(ep)) == NULL) return (NULL); if ((rootnp = metaname(&sp, curroot, UNKNOWN, ep)) == NULL) return (NULL); if (metaismeta(rootnp)) { if ((miscname = metagetmiscname(rootnp, ep)) == NULL) return (NULL); if ((strcmp(miscname, MD_MIRROR) == 0) && ((mirrorp = meta_get_mirror(sp, rootnp, ep)) != NULL)) { for (smi = 0; smi < NMIRROR; smi++) { md_submirror_t *mdsp = &mirrorp->submirrors[smi]; rootnp = mdsp->submirnamep; /* skip unused submirrors */ if (rootnp == NULL) { assert(mdsp->state == SMS_UNUSED); continue; } if ((miscname = metagetmiscname(rootnp, ep)) == NULL) { (void) mdmderror(ep, MDE_UNKNOWN_TYPE, meta_getminor(rootnp->dev), rootnp->cname); return (NULL); } break; } } if ((strcmp(miscname, MD_STRIPE) == 0) && ((stripep = meta_get_stripe(sp, rootnp, ep)) != NULL)) { rp = &stripep->rows.rows_val[0]; cp = &rp->comps.comps_val[0]; if (metachkcomp(cp->compnamep, ep) == 0) return (cp->compnamep); } /* Root is not a single stripe metadevice */ (void) mddeverror(ep, MDE_INV_ROOT, rootnp->dev, rootnp->cname); return (NULL); } else return (rootnp); }
/* * grow the parent of a device */ int meta_concat_parent( mdsetname_t *sp, mdname_t *childnp, md_error_t *ep ) { md_common_t *mdp; mdname_t *parentnp; md_unit_t *mup; /* should have a set */ assert(sp != NULL); assert(sp->setno == MD_MIN2SET(meta_getminor(childnp->dev))); /* get parent */ if ((mdp = meta_get_unit(sp, childnp, ep)) == NULL) return (-1); if (! MD_HAS_PARENT(mdp->parent)) return (0); if (mdp->parent == MD_MULTI_PARENT) return (0); /* single parent */ if ((parentnp = metamnumname(&sp, mdp->parent, 0, ep)) == NULL) return (-1); /* don't grow non-metadevices or soft partitions */ if (! metaismeta(parentnp) || meta_sp_issp(sp, parentnp, ep) == 0) return (0); if ((mup = meta_get_mdunit(sp, childnp, ep)) == NULL) return (-1); /* grow parent */ if (meta_concat_generic(sp, parentnp, mup->c.un_revision, ep) != 0) return (-1); /* recursively check for parents of parents */ return (meta_concat_parent(sp, parentnp, ep)); }