예제 #1
0
static int
walk_cpus(topo_mod_t *mod, struct cpu_walk_data *swdp, tnode_t *parent,
    int (*func)(ldom_hdl_t *, nvlist_t *))
{
	topo_walk_t *twp;
	int err;

	swdp->lhp = pi_lhp;
	swdp->parent = parent;
	swdp->func = func;
	swdp->err = swdp->offline = swdp->online = swdp->fail = 0;

	/*
	 * Return failure if ldom service is not initialized.
	 */
	if (pi_lhp == NULL) {
		swdp->fail++;
		return (0);
	}

	twp = topo_mod_walk_init(mod, parent, cpu_walker, swdp, &err);
	if (twp == NULL)
		return (-1);

	err = topo_walk_step(twp, TOPO_WALK_CHILD);
	topo_walk_fini(twp);

	if (err == TOPO_WALK_ERR || swdp->err > 0)
		return (-1);

	return (0);
}
예제 #2
0
/*
 * Walk all of the topology nodes looking for DISKs that match the structure
 * described in the overview.  Once we find them, check their fault status
 * and update their fault indiciator accordingly.
 */
static void
dl_examine_topo(disk_lights_t *dl)
{
	int err;
	topo_hdl_t *thp = NULL;
	topo_walk_t *twp = NULL;

	thp = fmd_hdl_topo_hold(dl->dl_fmd, TOPO_VERSION);
	if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC, dl_fault_walk_outer,
	    dl, &err)) == NULL) {
		fmd_hdl_error(dl->dl_fmd, "failed to get topology: %s\n",
		    topo_strerror(err));
		goto out;
	}

	if (topo_walk_step(twp, TOPO_WALK_CHILD) == TOPO_WALK_ERR) {
		fmd_hdl_error(dl->dl_fmd, "failed to walk topology: %s\n",
		    topo_strerror(err));
		goto out;
	}

out:
	if (twp != NULL)
		topo_walk_fini(twp);
	if (thp != NULL)
		fmd_hdl_topo_rele(dl->dl_fmd, thp);
}
예제 #3
0
파일: smbios.c 프로젝트: bahamas10/openzfs
static void
do_slot_mapping(smbios_slot_t *s, topo_hdl_t *thp)
{
	int err;
	uint_t dev, func;
	topo_walk_t *twp;
	char pciex[256];

	/*
	 * Bits 7:3 are the device number and bits 2:0 are the function.
	 */
	dev = s->smbl_df >> 3;
	func = s->smbl_df & 0x7;

	(void) snprintf(pciex, sizeof (pciex), "%s=%u/%s=%u/%s=%d",
	    PCIEX_BUS, s->smbl_bus, PCIEX_DEVICE, dev, PCIEX_FUNCTION, func);

	twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC, do_slot_mapping_cb, pciex,
	    &err);
	if (twp == NULL)
		return;

	(void) topo_walk_step(twp, TOPO_WALK_CHILD);
	topo_walk_fini(twp);
}
예제 #4
0
/*
 * The cmd_dimm_t structure created for a DIMM in a branch never has a
 * Jxxx in its unum; the cmd_dimm_t structure created for a DIMM containing
 * a page, or in a bank (i.e. for ECC errors)-always-has a Jxxx in its
 * unum. Therefore the set of cmd_dimm_t's created for a branch is always
 * disjoint from the set of cmd_dimm_t's created for pages and/or banks, so
 * the cmd_dimm_create will never link a 'branch' cmd_dimm_t into bank.
 * Faulting a DIMM for ECC will not prevent subsequent faulting of "same"
 * dimm for FBR/FBU and vice versa
 */
static int
branch_dimmlist_create(fmd_hdl_t *hdl, cmd_branch_t *branch)
{
	topo_hdl_t *thp;
	topo_walk_t *twp;
	int err, dimm_count;
	cmd_list_t *bp;

	if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
		return (0);
	if ((twp = topo_walk_init(thp,
	    FM_FMRI_SCHEME_MEM, branch_dimm_cb, branch, &err))
	    == NULL) {
		fmd_hdl_topo_rele(hdl, thp);
		return (0);
	}
	br_hdl = hdl;
	(void) topo_walk_step(twp, TOPO_WALK_CHILD);
	topo_walk_fini(twp);
	fmd_hdl_topo_rele(hdl, thp);

	for (dimm_count = 0, bp = cmd_list_next(&branch->branch_dimms);
	    bp != NULL; bp = cmd_list_next(bp), dimm_count++)
		;
	return (dimm_count);
}
예제 #5
0
nvlist_t *
cmd_find_dimm_by_sn(fmd_hdl_t *hdl, char *schemename, char *sn)
{
	topo_hdl_t *thp;
	topo_walk_t *twp;
	int err;

	dimm_nvl = NULL;

	if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
		return (NULL);
	if (strcmp(schemename, FM_FMRI_SCHEME_MEM) == 0) {
		if ((twp = topo_walk_init(thp,
		    schemename, find_dimm_sn_mem, sn, &err)) == NULL) {
			fmd_hdl_topo_rele(hdl, thp);
			return (NULL);
		}
	} else {
		if ((twp = topo_walk_init(thp,
		    schemename, find_dimm_sn_hc, sn, &err)) == NULL) {
			fmd_hdl_topo_rele(hdl, thp);
			return (NULL);
		}
	}
	(void) topo_walk_step(twp, TOPO_WALK_CHILD);
	topo_walk_fini(twp);
	fmd_hdl_topo_rele(hdl, thp);
	return (dimm_nvl);
}
예제 #6
0
static int
step_sibling(tnode_t *cnp, topo_walk_t *wp, int flag, int bottomup)
{
	int status;
	tnode_t *nnp;

	nnp = topo_child_next(cnp->tn_parent, cnp);

	if (nnp == NULL) {
		topo_dprintf(wp->tw_thp, TOPO_DBG_WALK,
		    "step_sibling: TOPO_WALK_TERMINATE for %s=%d\n",
		    cnp->tn_name, cnp->tn_instance);
		return (TOPO_WALK_TERMINATE);
	}

	topo_dprintf(wp->tw_thp, TOPO_DBG_WALK,
	    "step_sibling: through sibling node %s=%d to %s=%d\n",
	    cnp->tn_name, cnp->tn_instance, nnp->tn_name, nnp->tn_instance);

	topo_node_hold(nnp); /* released on return from walk_step */
	wp->tw_node = nnp;
	if (bottomup == 1)
		status = topo_walk_bottomup(wp, flag);
	else
		status = topo_walk_step(wp, flag);

	return (status);
}
예제 #7
0
/*
 * Return snapshot id
 */
char *
topo_snap_hold(topo_hdl_t *thp, const char *uuid, int *errp)
{
	topo_walk_t *twp;

	if (thp == NULL)
		return (NULL);

	if (uuid == NULL) {
		char *ret;

		if (thp->th_debug & TOPO_DBG_FORCE) {
			ret = topo_snap_create(thp, errp, B_TRUE);
		} else {
			ret = topo_snap_create(thp, errp, B_FALSE);
		}

		/*
		 * Now walk the tree and invoke any facility enumeration methods
		 */
		if (ret != NULL && getzoneid() == 0) {
			if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC,
			    fac_walker, (void *)0, errp)) == NULL) {
				return (ret);
			}
			(void) topo_walk_step(twp, TOPO_WALK_CHILD);
			topo_walk_fini(twp);
		}
		return (ret);
	}
	return (topo_snap_log_create(thp, uuid, errp));
}
예제 #8
0
파일: topo_fmri.c 프로젝트: andreiw/polaris
int
topo_fmri_invoke(topo_hdl_t *thp, nvlist_t *nvl, topo_walk_cb_t cb_f,
    void *pdata, int *err)
{
	topo_walk_t *wp;
	char *scheme;
	struct topo_lookup tl;

	if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &scheme)	 != 0)
		return (set_error(thp, ETOPO_METHOD_INVAL, err,
		    "topo_fmri_invoke", NULL));

	tl.tl_resource = nvl;
	tl.tl_func = cb_f;
	tl.tl_pdata = pdata;
	tl.tl_err = 0;
	if ((wp = topo_walk_init(thp, scheme, walk_lookup, &tl, err)) == NULL)
		return (set_error(thp, *err, err, "topo_fmri_invoke", NULL));

	(void) topo_walk_step(wp, TOPO_WALK_CHILD);
	topo_walk_fini(wp);

	if (tl.tl_err != 0) {
		*err = tl.tl_err;
		return (-1);
	}

	return (0);
}
예제 #9
0
int
update_configuration_from_topo(diskmon_t *diskp)
{
	int err;
	topo_hdl_t *thp;
	topo_walk_t *twp;
	char *uuid;

	if ((thp = topo_open(TOPO_VERSION, NULL, &err)) == NULL) {

		return (TOPO_OPEN_ERROR);
	}

	if ((uuid = topo_snap_hold(thp, NULL, &err)) == NULL) {

		topo_close(thp);
		return (TOPO_SNAP_ERROR);
	}


	if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC, gather_topo_cfg,
	    diskp, &err)) == NULL) {

		topo_snap_release(thp);
		topo_hdl_strfree(thp, uuid);
		topo_close(thp);

		return (err ? TOPO_WALK_INIT_ERROR : TOPO_SUCCESS);
	}

	topo_hdl_strfree(thp, uuid);

	if (topo_walk_step(twp, TOPO_WALK_CHILD) == TOPO_WALK_ERR) {

		topo_walk_fini(twp);
		topo_snap_release(thp);
		topo_close(thp);

		return (TOPO_WALK_ERROR);
	}

	topo_walk_fini(twp);
	topo_snap_release(thp);
	topo_close(thp);

	return (TOPO_SUCCESS);
}
예제 #10
0
static nvlist_t *
fru_by_label(fmd_hdl_t *hdl, const char *target)
{
	topo_hdl_t *thp;
	topo_walk_t *twp;
	int err;

	br_memb_nvl = NULL;
	if (((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) != NULL) &&
	    ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC,
	    fru_by_label_cb, (void *)target, &err)) != NULL)) {
		br_hdl = hdl;
		(void) topo_walk_step(twp, TOPO_WALK_CHILD);
		topo_walk_fini(twp);
	}
	fmd_hdl_topo_rele(hdl, thp);
	return (br_memb_nvl);
}
예제 #11
0
nvlist_t *
cmd_find_cpu_rsc_by_sn(fmd_hdl_t *hdl, cpuid_t *cpuid)
{
	topo_hdl_t *thp;
	topo_walk_t *twp;
	int err;

	rsc_nvl = NULL;
	if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
		return (NULL);
	if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC,
	    find_cpu_rsc_by_sn, cpuid, &err)) == NULL) {
		fmd_hdl_topo_rele(hdl, thp);
		return (NULL);
	}
	(void) topo_walk_step(twp, TOPO_WALK_CHILD);
	topo_walk_fini(twp);
	fmd_hdl_topo_rele(hdl, thp);
	return (rsc_nvl);
}
예제 #12
0
nvlist_t *
init_mb(fmd_hdl_t *hdl)
{
	topo_hdl_t *thp;
	topo_walk_t *twp;
	int err;

	if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
		return (NULL);
	if ((twp = topo_walk_init(thp,
	    FM_FMRI_SCHEME_HC, find_mb, NULL, &err))
	    == NULL) {
		fmd_hdl_topo_rele(hdl, thp);
		return (NULL);
	}
	(void) topo_walk_step(twp, TOPO_WALK_CHILD);
	topo_walk_fini(twp);
	fmd_hdl_topo_rele(hdl, thp);
	return (mb_nvl);
}
예제 #13
0
static int
walk_topo(topo_hdl_t *thp, char *uuid)
{
	int err;
	topo_walk_t *twp;
	int flag;

	if ((twp = topo_walk_init(thp, opt_s, walk_node, NULL, &err))
	    == NULL) {
		(void) fprintf(stderr, "%s: failed to walk %s topology:"
		    " %s\n", g_pname, opt_s, topo_strerror(err));

		return (-1);
	}

	/*
	 * Print standard header
	 */
	if (!opt_e) {
		char buf[32];
		time_t tod = time(NULL);

		(void) printf("TIME                 UUID\n");
		(void) strftime(buf, sizeof (buf), "%b %d %T", localtime(&tod));
		(void) printf("%-15s %-32s\n", buf, uuid);
		(void) printf("\n");
	}

	flag = opt_b != 0 ? TOPO_WALK_SIBLING : TOPO_WALK_CHILD;

	if (topo_walk_step(twp, flag) == TOPO_WALK_ERR) {
		(void) fprintf(stderr, "%s: failed to walk topology\n",
		    g_pname);
		topo_walk_fini(twp);
		return (-1);
	}

	topo_walk_fini(twp);

	return (0);
}
예제 #14
0
static int
branch_exist(fmd_hdl_t *hdl, cmd_branch_t *branch)
{
	topo_hdl_t *thp;
	topo_walk_t *twp;
	int err;

	if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
		return (0);
	if ((twp = topo_walk_init(thp,
	    FM_FMRI_SCHEME_MEM, branch_exist_cb, branch, &err))
	    == NULL) {
		fmd_hdl_topo_rele(hdl, thp);
		return (0);
	}
	br_dimmcount = 0;
	(void) topo_walk_step(twp, TOPO_WALK_CHILD);
	topo_walk_fini(twp);
	fmd_hdl_topo_rele(hdl, thp);

	return (br_dimmcount);
}
예제 #15
0
static int
platform_pci_fru_location(topo_mod_t *mod, tnode_t *node, uchar_t *loc,
    int locsiz)
{
	int		err;
	tnode_t		*parent;
	tnode_t		*top;
	topo_walk_t	*wp;
	_pci_fru_t	walkdata;

	topo_mod_dprintf(mod, "entering platform_pci_fru_location\n");

	/* Find the root node */
	top = node;
	while ((parent = topo_node_parent(top)) != NULL) {
		top = parent;
	}
	walkdata.node = node;
	walkdata.locsiz = locsiz;
	walkdata.location = alloca(locsiz+1);
	(void) memset(walkdata.location, 0, locsiz+1);
	(void) memcpy(walkdata.location, loc, locsiz);

	/* Create a walker starting at the root node */
	wp = topo_mod_walk_init(mod, top, platform_pci_fru_cb, &walkdata, &err);
	if (wp == NULL) {
		return (topo_mod_seterrno(mod, err));
	}

	/*
	 * Walk the tree breadth first to hopefully avoid visiting too many
	 * nodes while searching for the node with the appropriate FMRI.
	 */
	(void) topo_walk_step(wp, TOPO_WALK_SIBLING);
	topo_walk_fini(wp);

	return (0);
}
예제 #16
0
/*ARGSUSED*/
int
update_configuration_from_topo(fmd_hdl_t *hdl, diskmon_t *diskp)
{
	int err;
	topo_hdl_t *thp;
	topo_walk_t *twp;
	walk_diskmon_t wd;

	if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL) {
		return (TOPO_OPEN_ERROR);
	}

	wd.target = diskp;
	wd.pfmri = NULL;
	if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC, gather_topo_cfg,
	    &wd, &err)) == NULL) {
		fmd_hdl_topo_rele(hdl, thp);
		return (err ? TOPO_WALK_INIT_ERROR : TOPO_SUCCESS);
	}

	if (topo_walk_step(twp, TOPO_WALK_CHILD) == TOPO_WALK_ERR) {

		topo_walk_fini(twp);
		if (wd.pfmri != NULL)
			dstrfree(wd.pfmri);

		fmd_hdl_topo_rele(hdl, thp);
		return (TOPO_WALK_ERROR);
	}

	topo_walk_fini(twp);
	fmd_hdl_topo_rele(hdl, thp);
	if (wd.pfmri != NULL)
		dstrfree(wd.pfmri);

	return (TOPO_SUCCESS);
}