예제 #1
0
/*
 * Sends a request to the driver to load the module.  If/when the load has
 * completed successfully, kmdb_module_loaded is called.
 */
int
mdb_module_load(const char *fname, int mode)
{
    const char *modname = strbasename(fname);
    kmdb_wr_load_t *dlr;
    kmdb_modctl_t *kmc = NULL;
    const char *wformat = NULL;
    mdb_var_t *v;

    if (!mdb_module_validate_name(modname, &wformat))
        goto module_load_err;

    if ((v = mdb_nv_lookup(&mdb.m_dmodctl, modname)) != NULL) {
        kmc = MDB_NV_COOKIE(v);

        if (kmc->kmc_state == KMDB_MC_STATE_LOADING)
            wformat = "module %s is already being loaded\n";
        else
            wformat = "module %s is being unloaded\n";
        goto module_load_err;
    }

    kmc = mdb_zalloc(sizeof (kmdb_modctl_t), UM_SLEEP);
    kmc->kmc_loadmode = mode;
    kmc->kmc_modname = strdup(modname);
    kmc->kmc_state = KMDB_MC_STATE_LOADING;

    if (mdb_nv_insert(&mdb.m_dmodctl, modname, NULL, (uintptr_t)kmc, 0) ==
            NULL) {
        wformat = "module %s can't be registered for load\n";
        kmc_free(kmc);
        goto module_load_err;
    }

    dlr = mdb_zalloc(sizeof (kmdb_wr_load_t), UM_SLEEP);
    dlr->dlr_node.wn_task = WNTASK_DMOD_LOAD;
    dlr->dlr_fname = strdup(fname);

    kmdb_wr_driver_notify(dlr);

    if (!(mode & MDB_MOD_DEFER) &&
            mdb_tgt_continue(mdb.m_target, NULL) == 0)
        return (0);

    if (!(mode & MDB_MOD_SILENT))
        mdb_printf("%s load pending (:c to complete)\n", modname);

    return (0);

module_load_err:
    if (!(mode & MDB_MOD_SILENT))
        warn(wformat, modname);

    return (-1);
}
예제 #2
0
void
mdb_module_load_all(int mode)
{
    kmdb_wr_t *wn;

    ASSERT(mode & MDB_MOD_DEFER);

    wn = mdb_zalloc(sizeof (kmdb_wr_t), UM_SLEEP);
    wn->wn_task = WNTASK_DMOD_LOAD_ALL;

    kmdb_wr_driver_notify(wn);
}
예제 #3
0
static void
kmdb_module_request_unload(kmdb_modctl_t *kmc, const char *modname, int mode)
{
    kmdb_wr_unload_t *dur = mdb_zalloc(sizeof (kmdb_wr_unload_t), UM_SLEEP);
    dur->dur_node.wn_task = WNTASK_DMOD_UNLOAD;
    dur->dur_modname = strdup(modname);
    dur->dur_modctl = kmc->kmc_modctl;

    kmdb_wr_driver_notify(dur);

    kmc->kmc_state = KMDB_MC_STATE_UNLOADING;

    if (!(mode & MDB_MOD_DEFER) &&
            mdb_tgt_continue(mdb.m_target, NULL) == 0)
        return;

    if (!(mode & MDB_MOD_SILENT))
        mdb_printf("%s unload pending (:c to complete)\n", modname);
}
예제 #4
0
파일: kmdb_dpi.c 프로젝트: andreiw/polaris
static int
kmdb_dbgnotify_cb(kmdb_wr_t *wn, void *arg)
{
	work_results_t *res = arg;

	switch (WR_TASK(wn)) {
	case WNTASK_DMOD_LOAD: {
		/*
		 * If this is an ack, the driver finished processing a load we
		 * requested.  We process it and free the message.  If this
		 * isn't an ack, then it's a driver-initiated load.  We process
		 * the message, and send it back as an ack so the driver can
		 * free it.
		 */
		kmdb_wr_load_t *dlr = (kmdb_wr_load_t *)wn;

		mdb_dprintf(MDB_DBG_DPI, "received module load message\n");

		if (kmdb_module_loaded(dlr) && res != NULL) {
			(void) mdb_nv_insert(&res->res_loads,
			    strbasename(dlr->dlr_fname), NULL, 0, 0);
		}

		if (WR_ISACK(dlr)) {
			kmdb_module_load_ack(dlr);
			return (0);
		}

		/* Send it back as an ack */
		mdb_dprintf(MDB_DBG_DPI, "Sending load request for %s back "
		    "as an ack\n", dlr->dlr_fname);
		WR_ACK(wn);
		kmdb_wr_driver_notify(wn);
		return (0);
	}

	case WNTASK_DMOD_LOAD_ALL:
		/*
		 * We initiated the load-all, so this must be an ack.  The
		 * individual module load messages will arrive separately -
		 * there's no need to do anything further with this message.
		 */
		ASSERT(WR_ISACK(wn));

		mdb_dprintf(MDB_DBG_DPI, "received module load all ack\n");

		kmdb_module_load_all_ack(wn);
		return (0);

	case WNTASK_DMOD_UNLOAD: {
		/*
		 * The debugger received an unload message.  The driver isn't
		 * supposed to initiate unloads, so we shouldn't see anything
		 * but acks.  We tell the dmod subsystem that the module has
		 * been unloaded, and we free the message.
		 */
		kmdb_wr_unload_t *dur = (kmdb_wr_unload_t *)wn;

		ASSERT(WR_ISACK(dur));

		mdb_dprintf(MDB_DBG_DPI, "received module unload ack\n");

		if (kmdb_module_unloaded(dur) && res != NULL) {
			(void) mdb_nv_insert(&res->res_unloads,
			    dur->dur_modname, NULL, 0, 0);
		}

		/* Done with message */
		kmdb_module_unload_ack(dur);
		return (0);
	}

	case WNTASK_DMOD_PATH_CHANGE: {
		/*
		 * The debugger received a path change message.  The driver
		 * can't initiate these, so it must be an acknowledgement.
		 * There's no processing to be done, so just free the message.
		 */
		kmdb_wr_path_t *dpth = (kmdb_wr_path_t *)wn;

		ASSERT(WR_ISACK(dpth));

		mdb_dprintf(MDB_DBG_DPI, "received path change ack\n");

		kmdb_module_path_ack(dpth);
		return (0);
	}

	default:
		mdb_warn("Received unknown message type %d from driver\n",
		    wn->wn_task);
		/* Ignore it */
		return (0);
	}
}