Exemple #1
0
/*ARGSUSED*/
static void
ppb_init_hotplug(ppb_devstate_t *ppb)
{
	ppb->hotplug_capable = B_FALSE;

	if (ddi_prop_exists(DDI_DEV_T_ANY, ppb->dip, DDI_PROP_DONTPASS,
	    "hotplug-capable")) {
		(void) modload("misc", "pcihp");

		if (pcihp_init(ppb->dip) != DDI_SUCCESS) {
			cmn_err(CE_WARN,
			    "%s #%d: Failed setting hotplug framework",
			    ddi_driver_name(ppb->dip),
			    ddi_get_instance(ppb->dip));
		} else
			ppb->hotplug_capable = B_TRUE;
	}

	if (ppb->hotplug_capable == B_FALSE) {
		/*
		 * create minor node for devctl interfaces
		 */
		if (ddi_create_minor_node(ppb->dip, "devctl", S_IFCHR,
		    PCI_MINOR_NUM(ddi_get_instance(ppb->dip), PCI_DEVCTL_MINOR),
		    DDI_NT_NEXUS, 0) != DDI_SUCCESS)
			cmn_err(CE_WARN,
			    "%s #%d: Failed to create a minor node",
			    ddi_driver_name(ppb->dip),
			    ddi_get_instance(ppb->dip));
	}
}
Exemple #2
0
/*
 * Load the generic IA32 MCA cpu module, which may still supplement
 * itself with model-specific support through cpu model-specific modules.
 */
static cmi_t *
cmi_load_generic(cmi_hdl_t hdl, void **datap)
{
	modctl_t *modp;
	cmi_t *cmi;
	int modid;
	int err;

	ASSERT(MUTEX_HELD(&cmi_load_lock));

	if ((modid = modload(CPUMOD_SUBDIR, CPUMOD_PREFIX ".generic")) == -1)
		return (NULL);

	modp = mod_hold_by_id(modid);
	cmi = cmi_load_modctl(modp);
	if (cmi)
		cmi_hold(cmi);
	mod_release_mod(modp);

	if (cmi == NULL)
		return (NULL);

	if ((err = cmi->cmi_ops->cmi_init(hdl, datap)) != 0) {
		if (err != ENOTSUP)
			cmn_err(CE_WARN, CPUMOD_PREFIX ".generic failed to "
			    "init: err=%d", err);
		cmi_rele(cmi);
		return (NULL);
	}

	return (cmi);
}
Exemple #3
0
/*
 * Load system call module.
 *	Returns with pointer to held read lock for module.
 */
static krwlock_t *
lock_syscall(struct sysent *table, uint_t code)
{
	krwlock_t	*module_lock;
	struct modctl	*modp;
	int		id;
	struct sysent   *callp;

	module_lock = table[code].sy_lock;
	callp = &table[code];

	/*
	 * Optimization to only call modload if we don't have a loaded
	 * syscall.
	 */
	rw_enter(module_lock, RW_READER);
	if (LOADED_SYSCALL(callp))
		return (module_lock);
	rw_exit(module_lock);

	for (;;) {
		if ((id = modload("sys", syscallnames[code])) == -1)
			break;

		/*
		 * If we loaded successfully at least once, the modctl
		 * will still be valid, so we try to grab it by filename.
		 * If this call fails, it's because the mod_filename
		 * was changed after the call to modload() (mod_hold_by_name()
		 * is the likely culprit).  We can safely just take
		 * another lap if this is the case;  the modload() will
		 * change the mod_filename back to one by which we can
		 * find the modctl.
		 */
		modp = mod_find_by_filename("sys", syscallnames[code]);

		if (modp == NULL)
			continue;

		mutex_enter(&mod_lock);

		if (!modp->mod_installed) {
			mutex_exit(&mod_lock);
			continue;
		}
		break;
	}

	rw_enter(module_lock, RW_READER);

	if (id != -1)
		mutex_exit(&mod_lock);

	return (module_lock);
}
Exemple #4
0
void
psm_modload(void)
{
	char *this;

	mutex_init(&psmsw_lock, NULL, MUTEX_DEFAULT, NULL);
	open_mach_list();

	for (this = psm_get_impl_module(1);
		this != (char *)NULL;
		this = psm_get_impl_module(0)) {
		if (modload("mach", this) == -1)
			cmn_err(CE_WARN, "!Cannot load psm %s", this);
	}
	close_mach_list();
}
Exemple #5
0
/*
 * pcmem_attach()
 *
 */
static int
pcmem_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	char		adapter [MODMAXNAMELEN+1];
	static void	pcmem_create_pcram_node(dev_info_t *);

	/* resume from a checkpoint */
	if (cmd == DDI_RESUME) {
		return (DDI_SUCCESS);
	}

	(void) pcmem_create_pcram_node(dip);

	(void) strcpy(adapter, "pcram");
	(void) modload("drv", adapter);

	ddi_report_dev(dip);

	PCMEM_DEBUG((CE_CONT, "pcmem_attach - exit\n"));

	return (DDI_SUCCESS);
}
Exemple #6
0
/*
 * Called from CRYPTO_LOAD_SOFT_DISABLED ioctl.
 * If new_count is 0, then completely remove the entry.
 */
int
crypto_load_soft_disabled(char *name, uint_t new_count,
    crypto_mech_name_t *new_array)
{
	kcf_provider_desc_t *provider = NULL;
	crypto_mech_name_t *prev_array;
	uint_t prev_count = 0;
	int rv;

	provider = kcf_prov_tab_lookup_by_name(name);
	if (provider != NULL) {
		mutex_enter(&provider->pd_lock);
		/*
		 * Check if any other thread is disabling or removing
		 * this provider. We return if this is the case.
		 */
		if (provider->pd_state >= KCF_PROV_DISABLED) {
			mutex_exit(&provider->pd_lock);
			KCF_PROV_REFRELE(provider);
			return (CRYPTO_BUSY);
		}
		provider->pd_state = KCF_PROV_DISABLED;
		mutex_exit(&provider->pd_lock);

		undo_register_provider(provider, B_TRUE);
		KCF_PROV_REFRELE(provider);
		if (provider->pd_kstat != NULL)
			KCF_PROV_REFRELE(provider);

		mutex_enter(&provider->pd_lock);
		/* Wait till the existing requests complete. */
		while (provider->pd_state != KCF_PROV_FREED) {
			cv_wait(&provider->pd_remove_cv, &provider->pd_lock);
		}
		mutex_exit(&provider->pd_lock);
	}

	if (new_count == 0) {
		kcf_policy_remove_by_name(name, &prev_count, &prev_array);
		crypto_free_mech_list(prev_array, prev_count);
		rv = CRYPTO_SUCCESS;
		goto out;
	}

	/* put disabled mechanisms into policy table */
	if ((rv = kcf_policy_load_soft_disabled(name, new_count, new_array,
	    &prev_count, &prev_array)) == CRYPTO_SUCCESS) {
		crypto_free_mech_list(prev_array, prev_count);
	}

out:
	if (provider != NULL) {
		redo_register_provider(provider);
		if (provider->pd_kstat != NULL)
			KCF_PROV_REFHOLD(provider);
		mutex_enter(&provider->pd_lock);
		provider->pd_state = KCF_PROV_READY;
		mutex_exit(&provider->pd_lock);
	} else if (rv == CRYPTO_SUCCESS) {
		/*
		 * There are some cases where it is useful to kCF clients
		 * to have a provider whose mechanism is enabled now to be
		 * available. So, we attempt to load it here.
		 *
		 * The check, new_count < prev_count, ensures that we do this
		 * only in the case where a mechanism(s) is now enabled.
		 * This check assumes that enable and disable are separate
		 * administrative actions and are not done in a single action.
		 */
		if (new_count < prev_count && (in_soft_config_list(name)) &&
		    (modload("crypto", name) != -1)) {
			struct modctl *mcp;
			boolean_t load_again = B_FALSE;

			if ((mcp = mod_hold_by_name(name)) != NULL) {
				mcp->mod_loadflags |= MOD_NOAUTOUNLOAD;

				/* memory pressure may have unloaded module */
				if (!mcp->mod_installed)
					load_again = B_TRUE;
				mod_release_mod(mcp);

				if (load_again)
					(void) modload("crypto", name);
			}
		}
	}

	return (rv);
}
int  VBOXCALL   supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
{
    pImage->idSolMod   = -1;
    pImage->pSolModCtl = NULL;

# if 1 /* This approach requires _init/_fini/_info stubs. */
    /*
     * Construct a filename that escapes the module search path and let us
     * specify a root path.
     */
    /** @todo change this to use modctl and use_path=0. */
    const char *pszName = RTPathFilename(pszFilename);
    AssertReturn(pszName, VERR_INVALID_PARAMETER);
    char *pszSubDir = RTStrAPrintf2("../../../../../../../../../../..%.*s", pszName - pszFilename - 1, pszFilename);
    if (!pszSubDir)
        return VERR_NO_STR_MEMORY;
    int idMod = modload(pszSubDir, pszName);
    if (idMod == -1)
    {
        /* This is an horrible hack for avoiding the mod-present check in
           modrload on S10.  Fortunately, nobody else seems to be using that
           variable... */
        extern int swaploaded;
        int saved_swaploaded = swaploaded;
        swaploaded = 0;
        idMod = modload(pszSubDir, pszName);
        swaploaded = saved_swaploaded;
    }
    RTStrFree(pszSubDir);
    if (idMod == -1)
    {
        LogRel(("modload(,%s): failed, could be anything...\n", pszFilename));
        return VERR_LDR_GENERAL_FAILURE;
    }

    modctl_t *pModCtl = mod_hold_by_id(idMod);
    if (!pModCtl)
    {
        LogRel(("mod_hold_by_id(,%s): failed, weird.\n", pszFilename));
        /* No point in calling modunload. */
        return VERR_LDR_GENERAL_FAILURE;
    }
    pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD | MOD_NOUNLOAD; /* paranoia */

# else

    const int idMod = -1;
    modctl_t *pModCtl = mod_hold_by_name(pszFilename);
    if (!pModCtl)
    {
        LogRel(("mod_hold_by_name failed for '%s'\n", pszFilename));
        return VERR_LDR_GENERAL_FAILURE;
    }

    int rc = kobj_load_module(pModCtl, 0 /*use_path*/);
    if (rc != 0)
    {
        LogRel(("kobj_load_module failed with rc=%d for '%s'\n", rc, pszFilename));
        mod_release_mod(pModCtl);
        return RTErrConvertFromErrno(rc);
    }
# endif

    /*
     * Get the module info.
     *
     * Note! The text section is actually not at mi_base, but and the next
     *       alignment boundrary and there seems to be no easy way of
     *       getting at this address.  This sabotages supdrvOSLdrLoad.
     *       Bastards!
     */
    struct modinfo ModInfo;
    kobj_getmodinfo(pModCtl->mod_mp, &ModInfo);
    pImage->pvImage    = ModInfo.mi_base;
    pImage->idSolMod   = idMod;
    pImage->pSolModCtl = pModCtl;

    mod_release_mod(pImage->pSolModCtl);
    LogRel(("supdrvOSLdrOpen: succeeded for '%s' (mi_base=%p mi_size=%#x), id=%d ctl=%p\n",
            pszFilename, ModInfo.mi_base, ModInfo.mi_size, idMod, pModCtl));
    return VINF_SUCCESS;
}
int
kadmin(int cmd, int fcn, void *mdep, cred_t *credp)
{
	int error = 0;
	char *buf;
	size_t buflen = 0;
	boolean_t invoke_cb = B_FALSE;

	/*
	 * We might be called directly by the kernel's fault-handling code, so
	 * we can't assert that the caller is in the global zone.
	 */

	/*
	 * Make sure that cmd is one of the valid <sys/uadmin.h> command codes
	 * and that we have appropriate privileges for this action.
	 */
	switch (cmd) {
	case A_FTRACE:
	case A_SHUTDOWN:
	case A_REBOOT:
	case A_REMOUNT:
	case A_FREEZE:
	case A_DUMP:
	case A_SDTTEST:
	case A_CONFIG:
		if (secpolicy_sys_config(credp, B_FALSE) != 0)
			return (EPERM);
		break;

	default:
		return (EINVAL);
	}

	/*
	 * Serialize these operations on ualock.  If it is held, the
	 * system should shutdown, reboot, or remount shortly, unless there is
	 * an error.  We need a cv rather than just a mutex because proper
	 * functioning of A_REBOOT relies on being able to interrupt blocked
	 * userland callers.
	 *
	 * We only clear ua_shutdown_thread after A_REMOUNT or A_CONFIG.
	 * Other commands should never return.
	 */
	if (cmd == A_SHUTDOWN || cmd == A_REBOOT || cmd == A_REMOUNT ||
	    cmd == A_CONFIG) {
		mutex_enter(&ualock);
		while (ua_shutdown_thread != NULL) {
			if (cv_wait_sig(&uacond, &ualock) == 0) {
				/*
				 * If we were interrupted, leave, and handle
				 * the signal (or exit, depending on what
				 * happened)
				 */
				mutex_exit(&ualock);
				return (EINTR);
			}
		}
		ua_shutdown_thread = curthread;
		mutex_exit(&ualock);
	}

	switch (cmd) {
	case A_SHUTDOWN:
	{
		proc_t *p = ttoproc(curthread);

		/*
		 * Release (almost) all of our own resources if we are called
		 * from a user context, however if we are calling kadmin() from
		 * a kernel context then we do not release these resources.
		 */
		if (p != &p0) {
			proc_is_exiting(p);
			if ((error = exitlwps(0)) != 0) {
				/*
				 * Another thread in this process also called
				 * exitlwps().
				 */
				mutex_enter(&ualock);
				ua_shutdown_thread = NULL;
				cv_signal(&uacond);
				mutex_exit(&ualock);
				return (error);
			}
			mutex_enter(&p->p_lock);
			p->p_flag |= SNOWAIT;
			sigfillset(&p->p_ignore);
			curthread->t_lwp->lwp_cursig = 0;
			curthread->t_lwp->lwp_extsig = 0;
			if (p->p_exec) {
				vnode_t *exec_vp = p->p_exec;
				p->p_exec = NULLVP;
				mutex_exit(&p->p_lock);
				VN_RELE(exec_vp);
			} else {
				mutex_exit(&p->p_lock);
			}

			pollcleanup();
			closeall(P_FINFO(curproc));
			relvm();

		} else {
			/*
			 * Reset t_cred if not set because much of the
			 * filesystem code depends on CRED() being valid.
			 */
			if (curthread->t_cred == NULL)
				curthread->t_cred = kcred;
		}

		/* indicate shutdown in progress */
		sys_shutdown = 1;

		/*
		 * Communcate that init shouldn't be restarted.
		 */
		zone_shutdown_global();

		killall(ALL_ZONES);
		/*
		 * If we are calling kadmin() from a kernel context then we
		 * do not release these resources.
		 */
		if (ttoproc(curthread) != &p0) {
			VN_RELE(PTOU(curproc)->u_cdir);
			if (PTOU(curproc)->u_rdir)
				VN_RELE(PTOU(curproc)->u_rdir);
			if (PTOU(curproc)->u_cwd)
				refstr_rele(PTOU(curproc)->u_cwd);

			PTOU(curproc)->u_cdir = rootdir;
			PTOU(curproc)->u_rdir = NULL;
			PTOU(curproc)->u_cwd = NULL;
		}

		/*
		 * Allow the reboot/halt/poweroff code a chance to do
		 * anything it needs to whilst we still have filesystems
		 * mounted, like loading any modules necessary for later
		 * performing the actual poweroff.
		 */
		if ((mdep != NULL) && (*(char *)mdep == '/')) {
			buf = i_convert_boot_device_name(mdep, NULL, &buflen);
			mdpreboot(cmd, fcn, buf);
		} else
			mdpreboot(cmd, fcn, mdep);

		/*
		 * Allow fsflush to finish running and then prevent it
		 * from ever running again so that vfs_unmountall() and
		 * vfs_syncall() can acquire the vfs locks they need.
		 */
		sema_p(&fsflush_sema);
		(void) callb_execute_class(CB_CL_UADMIN_PRE_VFS, NULL);

		vfs_unmountall();
		(void) VFS_MOUNTROOT(rootvfs, ROOT_UNMOUNT);
		vfs_syncall();

		dump_ereports();
		dump_messages();

		invoke_cb = B_TRUE;

		/* FALLTHROUGH */
	}

	case A_REBOOT:
		if ((mdep != NULL) && (*(char *)mdep == '/')) {
			buf = i_convert_boot_device_name(mdep, NULL, &buflen);
			mdboot(cmd, fcn, buf, invoke_cb);
		} else
			mdboot(cmd, fcn, mdep, invoke_cb);
		/* no return expected */
		break;

	case A_CONFIG:
		switch (fcn) {
		case AD_UPDATE_BOOT_CONFIG:
#ifndef	__sparc
		{
			extern void fastboot_update_config(const char *);

			fastboot_update_config(mdep);
		}
#endif

			break;
		}
		/* Let other threads enter the shutdown path now */
		mutex_enter(&ualock);
		ua_shutdown_thread = NULL;
		cv_signal(&uacond);
		mutex_exit(&ualock);
		break;

	case A_REMOUNT:
		(void) VFS_MOUNTROOT(rootvfs, ROOT_REMOUNT);
		/* Let other threads enter the shutdown path now */
		mutex_enter(&ualock);
		ua_shutdown_thread = NULL;
		cv_signal(&uacond);
		mutex_exit(&ualock);
		break;

	case A_FREEZE:
	{
		/*
		 * This is the entrypoint for all suspend/resume actions.
		 */
		extern int cpr(int, void *);

		if (modload("misc", "cpr") == -1)
			return (ENOTSUP);
		/* Let the CPR module decide what to do with mdep */
		error = cpr(fcn, mdep);
		break;
	}

	case A_FTRACE:
	{
		switch (fcn) {
		case AD_FTRACE_START:
			(void) FTRACE_START();
			break;
		case AD_FTRACE_STOP:
			(void) FTRACE_STOP();
			break;
		default:
			error = EINVAL;
		}
		break;
	}

	case A_DUMP:
	{
		if (fcn == AD_NOSYNC) {
			in_sync = 1;
			break;
		}

		panic_bootfcn = fcn;
		panic_forced = 1;

		if ((mdep != NULL) && (*(char *)mdep == '/')) {
			panic_bootstr = i_convert_boot_device_name(mdep,
			    NULL, &buflen);
		} else
			panic_bootstr = mdep;

#ifndef	__sparc
		extern void fastboot_update_and_load(int, char *);

		fastboot_update_and_load(fcn, mdep);
#endif

		panic("forced crash dump initiated at user request");
		/*NOTREACHED*/
	}

	case A_SDTTEST:
	{
		DTRACE_PROBE7(test, int, 1, int, 2, int, 3, int, 4, int, 5,
		    int, 6, int, 7);
		break;
	}

	default:
		error = EINVAL;
	}

	return (error);
}
Exemple #9
0
int
loadrootmodules(void)
{
	struct vfssw	*vsw;
	char		*this;
	char		*name;
	int		err;
/* ONC_PLUS EXTRACT END */
	int		i, proplen;
	extern char	*impl_module_list[];
	extern char	*platform_module_list[];

	/* Make sure that the PROM's devinfo tree has been created */
	ASSERT(ddi_root_node());

	BMDPRINTF(("loadrootmodules: fstype %s\n", rootfs.bo_fstype));
	BMDPRINTF(("loadrootmodules: name %s\n", rootfs.bo_name));
	BMDPRINTF(("loadrootmodules: flags 0x%x\n", rootfs.bo_flags));

	/*
	 * zzz We need to honor what's in rootfs if it's not null.
	 * non-null means use what's there.  This way we can
	 * change rootfs with /etc/system AND with tunetool.
	 */
	if (root_is_svm) {
		/* user replaced rootdev, record obp_bootpath */
		obp_bootpath[0] = '\0';
		(void) getphysdev("root", obp_bootpath, BO_MAXOBJNAME);
		BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath));
	} else {
		/*
		 * Get the root fstype and root device path from boot.
		 */
		rootfs.bo_fstype[0] = '\0';
		rootfs.bo_name[0] = '\0';
	}

	/*
	 * This lookup will result in modloadonly-ing the root
	 * filesystem module - it gets _init-ed in rootconf()
	 */
	if ((vsw = getfstype("root", rootfs.bo_fstype, BO_MAXFSNAME)) == NULL)
		return (ENXIO);	/* in case we have no file system types */

	(void) strcpy(rootfs.bo_fstype, vsw->vsw_name);

	vfs_unrefvfssw(vsw);

	/*
	 * Load the favored drivers of the implementation.
	 * e.g. 'sbus' and possibly 'zs' (even).
	 *
	 * Called whilst boot is still loaded (because boot does
	 * the i/o for us), and DDI services are unavailable.
	 */
	BMDPRINTF(("loadrootmodules: impl_module_list\n"));
	for (i = 0; (this = impl_module_list[i]) != NULL; i++) {
		if ((err = load_boot_driver(this)) != 0) {
			cmn_err(CE_WARN, "Cannot load drv/%s", this);
			return (err);
			/* NOTREACHED */
		}
	}
	/*
	 * Now load the platform modules (if any)
	 */
	BMDPRINTF(("loadrootmodules: platform_module_list\n"));
	for (i = 0; (this = platform_module_list[i]) != NULL; i++) {
		if ((err = load_boot_platform_modules(this)) != 0) {
			cmn_err(CE_WARN, "Cannot load drv/%s", this);
			return (err);
			/* NOTREACHED */
		}
	}

loop:
	(void) getphysdev("root", rootfs.bo_name, BO_MAXOBJNAME);

	/*
	 * Given a physical pathname, load the correct set of driver
	 * modules into memory, including all possible parents.
	 *
	 * NB: The code sets the variable 'name' for error reporting.
	 */
	err = 0;
	BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name));
	if (root_is_svm == 0) {
		BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name));
		name = rootfs.bo_name;
		err = load_bootpath_drivers(rootfs.bo_name);
	}

	/*
	 * Load driver modules in obp_bootpath, this is always
	 * required for mountroot to succeed. obp_bootpath is
	 * is set if rootdev is set via /etc/system, which is
	 * the case if booting of a SVM/VxVM mirror.
	 */
	if ((err == 0) && obp_bootpath[0] != '\0') {
		BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath));
		name = obp_bootpath;
		err = load_bootpath_drivers(obp_bootpath);
	}

	if (err != 0) {
		cmn_err(CE_CONT, "Cannot load drivers for %s\n", name);
		goto out;
		/* NOTREACHED */
	}

	/*
	 * Check to see if the booter performed DHCP configuration
	 * ("bootp-response" boot property exists). If so, then before
	 * bootops disappears we need to save the value of this property
	 * such that the userland dhcpagent can adopt the DHCP management
	 * of our primary network interface.
	 */
	proplen = BOP_GETPROPLEN(bootops, "bootp-response");
	if (proplen > 0) {
		dhcack = kmem_zalloc(proplen, KM_SLEEP);
		if (BOP_GETPROP(bootops, "bootp-response", dhcack) == -1) {
			cmn_err(CE_WARN, "BOP_GETPROP of  "
			    "\"bootp-response\" failed\n");
			kmem_free(dhcack, dhcacklen);
			dhcack = NULL;
			goto out;
		}
		dhcacklen = proplen;

		/*
		 * Fetch the "netdev-path" boot property (if it exists), and
		 * stash it for later use by sysinfo(SI_DHCP_CACHE, ...).
		 */
		proplen = BOP_GETPROPLEN(bootops, "netdev-path");
		if (proplen > 0) {
			netdev_path = kmem_zalloc(proplen, KM_SLEEP);
			if (BOP_GETPROP(bootops, "netdev-path",
			    (uchar_t *)netdev_path) == -1) {
				cmn_err(CE_WARN, "BOP_GETPROP of  "
				    "\"netdev-path\" failed\n");
				kmem_free(netdev_path, proplen);
				goto out;
			}
		}
	}

	/*
	 * Preload (load-only, no init) all modules which
	 * were added to the /etc/system file with the
	 * FORCELOAD keyword.
	 */
	BMDPRINTF(("loadrootmodules: preload_module\n"));
	(void) mod_sysctl_type(MOD_FORCELOAD, preload_module, NULL);

/* ONC_PLUS EXTRACT START */
	/*
	 * If we booted otw then load in the plumbing
	 * routine now while we still can. If we didn't
	 * boot otw then we will load strplumb in main().
	 *
	 * NFS is actually a set of modules, the core routines,
	 * a diskless helper module, rpcmod, and the tli interface.  Load
	 * them now while we still can.
	 *
	 * Because we glomb all versions of nfs into a single module
	 * we check based on the initial string "nfs".
	 *
	 * XXX: A better test for this is to see if device_type
	 * XXX: from the PROM is "network".
	 */

	if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) {
		++netboot;

		if ((err = modload("misc", "tlimod")) < 0)  {
			cmn_err(CE_CONT, "Cannot load misc/tlimod\n");
			goto out;
			/* NOTREACHED */
		}
		if ((err = modload("strmod", "rpcmod")) < 0)  {
			cmn_err(CE_CONT, "Cannot load strmod/rpcmod\n");
			goto out;
			/* NOTREACHED */
		}
		if ((err = modload("misc", "nfs_dlboot")) < 0)  {
			cmn_err(CE_CONT, "Cannot load misc/nfs_dlboot\n");
			goto out;
			/* NOTREACHED */
		}
		if ((err = modload("mac", "mac_ether")) < 0)  {
			cmn_err(CE_CONT, "Cannot load mac/mac_ether\n");
			goto out;
			/* NOTREACHED */
		}
		if ((err = modload("misc", "strplumb")) < 0)  {
			cmn_err(CE_CONT, "Cannot load misc/strplumb\n");
			goto out;
			/* NOTREACHED */
		}
		if ((err = strplumb_load()) < 0) {
			goto out;
			/* NOTREACHED */
		}
	}

	/*
	 * Preload modules needed for booting as a cluster.
	 */
	err = clboot_loadrootmodules();

out:
	if (err != 0 && (boothowto & RB_ASKNAME))
		goto loop;

	return (err);
}
Exemple #10
0
/*
 * Configure root file system.
 */
int
rootconf(void)
{
	int error;
	struct vfssw *vsw;
	extern void pm_init(void);

	BMDPRINTF(("rootconf: fstype %s\n", rootfs.bo_fstype));
	BMDPRINTF(("rootconf: name %s\n", rootfs.bo_name));
	BMDPRINTF(("rootconf: flags 0x%x\n", rootfs.bo_flags));
	BMDPRINTF(("rootconf: obp_bootpath %s\n", obp_bootpath));

	/*
	 * Install cluster modules that were only loaded during
	 * loadrootmodules().
	 */
	if (error = clboot_rootconf())
		return (error);

	if (root_is_svm) {
		(void) strncpy(rootfs.bo_name, obp_bootpath, BO_MAXOBJNAME);

		BMDPRINTF(("rootconf: svm: rootfs name %s\n", rootfs.bo_name));
		BMDPRINTF(("rootconf: svm: svm name %s\n", svm_bootpath));
	}

	/*
	 * Run _init on the root filesystem (we already loaded it
	 * but we've been waiting until now to _init it) which will
	 * have the side-effect of running vsw_init() on this vfs.
	 * Because all the nfs filesystems are lumped into one
	 * module we need to special case it.
	 */
	if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) {
		if (modload("fs", "nfs") == -1) {
			cmn_err(CE_CONT, "Cannot initialize %s filesystem\n",
			    rootfs.bo_fstype);
			return (ENXIO);
		}
	} else {
		if (modload("fs", rootfs.bo_fstype) == -1) {
			cmn_err(CE_CONT, "Cannot initialize %s filesystem\n",
			    rootfs.bo_fstype);
			return (ENXIO);
		}
	}
	RLOCK_VFSSW();
	vsw = vfs_getvfsswbyname(rootfs.bo_fstype);
	RUNLOCK_VFSSW();
	VFS_INIT(rootvfs, &vsw->vsw_vfsops, (caddr_t)0);
	VFS_HOLD(rootvfs);

	if (root_is_svm) {
		rootvfs->vfs_flag |= VFS_RDONLY;
	}

	/*
	 * This pm-releated call has to occur before root is mounted since we
	 * need to power up all devices.  It is placed after VFS_INIT() such
	 * that opening a device via ddi_lyr_ interface just before root has
	 * been mounted would work.
	 */
	pm_init();

	if (netboot) {
		if ((error = strplumb()) != 0) {
			cmn_err(CE_CONT, "Cannot plumb network device\n");
			return (error);
		}
	}

	/*
	 * ufs_mountroot() ends up calling getrootdev()
	 * (below) which actually triggers the _init, identify,
	 * probe and attach of the drivers that make up root device
	 * bush; these are also quietly waiting in memory.
	 */
	BMDPRINTF(("rootconf: calling VFS_MOUNTROOT %s\n", rootfs.bo_fstype));

	error = VFS_MOUNTROOT(rootvfs, ROOT_INIT);
	vfs_unrefvfssw(vsw);
	rootdev = rootvfs->vfs_dev;

	if (error)
		cmn_err(CE_CONT, "Cannot mount root on %s fstype %s\n",
		    rootfs.bo_name, rootfs.bo_fstype);
	else
		cmn_err(CE_CONT, "?root on %s fstype %s\n",
		    rootfs.bo_name, rootfs.bo_fstype);
	return (error);
}
Exemple #11
0
int
rsm_get_controller(const char *name, uint_t number,
    rsm_controller_object_t *controller, uint_t version)
{
	rsmops_ctrl_t *p_ctrl;
	rsmops_drv_t *p_drv;
	vnode_t *vp;
	int error;
	int (*rsm_get_controller_handler)
	    (const char *name, uint_t number,
	    rsm_controller_object_t *pcontroller, uint_t version);

	mutex_enter(&rsmops_lock);

	/* check if the controller is already registered */
	if ((p_ctrl = find_rsmpi_controller(name, number)) == NULL) {
		/*
		 * controller is not registered.  We should try to load it
		 * First check if the driver is registered
		 */
		if ((p_drv = find_rsmpi_driver(name)) == NULL) {
			/* Cannot find the driver.  Try to load it */
			mutex_exit(&rsmops_lock);
			if ((error = modload("drv", (char *)name)) == -1) {
				return (RSMERR_CTLR_NOT_PRESENT);
			}
			mutex_enter(&rsmops_lock);
			if ((p_drv = find_rsmpi_driver(name)) == NULL) {
				mutex_exit(&rsmops_lock);
				/*
				 * Cannot find yet - maybe the driver we loaded
				 * was not a RSMPI driver at all.  We'll just
				 * fail this call.
				 */
				return (RSMERR_CTLR_NOT_PRESENT);
			}
		}
		ASSERT(p_drv);
		p_ctrl = find_rsmpi_controller(name, number);
		if (p_ctrl == NULL) {
			/*
			 * controller is not registered.
			 * try to do a VOP_OPEN to force it to get registered
			 */
			mutex_exit(&rsmops_lock);
			vp = rsmops_device_open(name, number);
			mutex_enter(&rsmops_lock);
			if (vp != NULL) {
				(void) VOP_CLOSE(vp, FREAD|FWRITE, 0, 0,
				    CRED(), NULL);
				VN_RELE(vp);
			}
			p_ctrl = find_rsmpi_controller(name, number);
			if (p_ctrl == NULL) {
				mutex_exit(&rsmops_lock);
				return (RSMERR_CTLR_NOT_PRESENT);
			}
		}
		ASSERT(p_ctrl);
	} else {
		p_drv = p_ctrl->p_drv;
	}
	ASSERT(p_drv);
	ASSERT(p_drv == p_ctrl->p_drv);

	rsm_get_controller_handler = p_drv->drv.rsm_get_controller_handler;
	/*
	 * Increase the refcnt right now, so that attempts to deregister
	 * while we are using this entry will fail
	 */
	p_ctrl->refcnt++;
	mutex_exit(&rsmops_lock);

	error = (*rsm_get_controller_handler)(name, number, controller,
	    version);
	if (error != RSM_SUCCESS) {
		/* We failed - drop the refcnt back */
		mutex_enter(&rsmops_lock);
		/*
		 * Even though we had released the global lock, we can
		 * guarantee that p_ctrl is still meaningful (and has not
		 * been deregistered, freed whatever) because we were holding
		 * refcnt on it.  So, it is okay to just use p_ctrl here
		 * after re-acquiring the global lock
		 */
		p_ctrl->refcnt--;
		mutex_exit(&rsmops_lock);
	} else {
		/*
		 * Initialize the controller handle field
		 */
		mutex_enter(&rsmops_lock);
		if ((p_ctrl = find_rsmpi_controller(name, number)) == NULL) {
			mutex_exit(&rsmops_lock);
			return (RSMERR_CTLR_NOT_PRESENT);
		}

		p_ctrl->handle = controller->handle;
		mutex_exit(&rsmops_lock);
	}
	return (error);
}