- Restored two functions: + rf_buildroothack(), + rf_release_all_vps(). First one is used to call rf_auto_config_set() when needed, it also cleans up sets after autoconfiguration. Function rf_release_all_vps() is used for destroying consumer and geom releated to given autoset. - Changed returned type of rf_have_enough_components() to boolean_t. - Removed last argument from rf_auto_config_set(). This is a global variable (raidctl) and can be used directly. diff -ruP raidframe.2004.01.14/rf_freebsdkintf.c raidframe.2004.01.14_2/rf_freebsdkintf.c --- raidframe.2004.01.14/rf_freebsdkintf.c Wed Jan 14 11:53:28 2004 +++ raidframe.2004.01.14_2/rf_freebsdkintf.c Wed Jan 14 11:58:21 2004 @@ -278,21 +278,14 @@ static void rf_ReconstructInPlaceThread(struct rf_recon_req *); static boolean_t rf_does_it_fit(RF_ConfigSet_t *,RF_AutoConfig_t *); static int rf_reasonable_label(RF_ComponentLabel_t *); -#ifdef not_used static void rf_create_configuration(RF_AutoConfig_t *,RF_Config_t *, RF_Raid_t *); -#endif static int rf_set_autoconfig(RF_Raid_t *, int); static int rf_set_rootpartition(RF_Raid_t *, int); -#ifdef not_used +static void rf_release_all_vps(RF_ConfigSet_t *); static void rf_cleanup_config_set(RF_ConfigSet_t *); -#endif -#ifdef not_used -static int rf_have_enough_components(RF_ConfigSet_t *); -#endif -#ifdef not_used -static int rf_auto_config_set(RF_ConfigSet_t *, int *, struct raidctl_softc *); -#endif +static boolean_t rf_have_enough_components(RF_ConfigSet_t *); +static int rf_auto_config_set(RF_ConfigSet_t *, int *); static void rf_complete_autoconf(void); static int raidgetunit(struct raidctl_softc *, int); @@ -439,6 +432,67 @@ } static void +rf_buildroothack(void) +{ + RF_ConfigSet_t *cset, *tmpcset; + int retcode; + int raidID; + int rootID; + int num_root; + + rootID = 0; + num_root = 0; + + TAILQ_FOREACH_SAFE(cset, &raidctl->cset_head, cset_link, tmpcset) { + if (rf_have_enough_components(cset) && + TAILQ_FIRST(&cset->ac_head)->clabel->autoconfigure==1) { + retcode = rf_auto_config_set(cset, &raidID); + if (!retcode) { + if (cset->rootable) { + rootID = raidID; + num_root++; + } + /* + * XXX: We shouldn't do a 'break' here or + * 'continue'? If we don't do that, this + * cset will be cleaned up. + */ + } else { + /* The autoconfig didn't work :( */ + rf_printf(1, "Autoconfig failed with code %d" + "for raid%d\n", retcode, raidID); + rf_release_all_vps(cset); + } + } else { + /* we're not autoconfiguring this set... + release the associated resources */ + rf_release_all_vps(cset); + } + /* cleanup */ + /* + * XXX: We're calling cleanup here, we shouldn't call + * rf_release_all_vps() as well? + */ + rf_cleanup_config_set(cset); + } + + if (boothowto & RB_ASKNAME) { + /* We don't auto-config... */ + } else { + /* They didn't ask, and we found something bootable... */ + +#if 0 + if (num_root == 1) { + booted_device = &raidrootdev[rootID]; + } else if (num_root > 1) { + /* we can't guess.. require the user to answer... */ + boothowto |= RB_ASKNAME; + } +#endif + } +} + +static void rf_add_provider(RF_AutoConfig_t *ac) { RF_ConfigSet_t *cset; @@ -578,12 +632,12 @@ if (atomic_cmpset_int(&first_taste, 1, 0)) { printf("LAST Provider: %s\n", pp->name); /* - * XXX: Call rescan function. * For now returned 'gp' is not used by GEOM * so rescan function could be called directly * from here, if it will change, we have to * call rescan function from event queue. */ + rf_buildroothack(); } } if (gp != NULL && gp->softc != NULL) @@ -2356,8 +2410,7 @@ return(1); } -#ifdef not_used -static int +static boolean_t rf_have_enough_components(cset) RF_ConfigSet_t *cset; { @@ -2458,9 +2511,7 @@ at autoconfiguring this set */ return(1); } -#endif -#ifdef not_used static void rf_create_configuration(ac,config,raidPtr) RF_AutoConfig_t *ac; @@ -2497,7 +2548,6 @@ config->debugVars[i][0] = '\0'; } } -#endif static int rf_set_autoconfig(raidPtr, new_value) @@ -2555,7 +2605,25 @@ return(new_value); } -#ifdef not_used +static void +rf_release_all_vps(cset) + RF_ConfigSet_t *cset; +{ + RF_AutoConfig_t *ac; + struct g_geom *gp; + struct g_consumer *cp; + + TAILQ_FOREACH(ac, &cset->ac_head, ac_link) { + cp = ac->dev; + gp = cp->geom; + + g_access_rel(cp, -cp->acr, -cp->acw, -cp->ace); + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_geom(gp); + } +} + static void rf_cleanup_config_set(RF_ConfigSet_t *cset) { @@ -2574,7 +2642,6 @@ /* and, finally, nuke the config set */ free(cset, M_RAIDFRAME); } -#endif void raid_init_component_label(raidPtr, clabel) @@ -2606,12 +2673,10 @@ clabel->config_order = raidPtr->config_order; } -#ifdef not_used static int -rf_auto_config_set(cset, unit, ctl) +rf_auto_config_set(cset, unit) RF_ConfigSet_t *cset; int *unit; - struct raidctl_softc *ctl; { int retcode = 0; RF_Raid_t *raidPtr; @@ -2643,9 +2708,9 @@ raidID = TAILQ_FIRST(&cset->ac_head)->clabel->last_unit; if (raidID < 0) { /* let's not wander off into lala land. */ - raidID = raidgetunit(ctl, 0); + raidID = raidgetunit(raidctl, 0); } else { - raidID = raidgetunit(ctl, raidID); + raidID = raidgetunit(raidctl, raidID); } if (raidID < 0) { @@ -2674,15 +2739,15 @@ if (retcode == 0) { - ctl->raiddevs[raidID] = raidinit(raidPtr); - if (ctl->raiddevs[raidID] == NULL) { + raidctl->raiddevs[raidID] = raidinit(raidPtr); + if (raidctl->raiddevs[raidID] == NULL) { rf_printf(0, "Could not create RAID device\n"); RF_Free(raidPtr, sizeof(RF_Raid_t)); free(config, M_RAIDFRAME); return (1); } - ctl->numraid++; + raidctl->numraid++; rf_markalldirty(raidPtr); raidPtr->autoconfigure = 1; /* XXX do this here? */ if (TAILQ_FIRST(&cset->ac_head)->clabel->root_partition==1) { @@ -2700,7 +2765,6 @@ *unit = raidID; return(retcode); } -#endif void rf_disk_unbusy(desc)