Ejemplo n.º 1
0
static int
logpage_selftest_analyze(ds_scsi_info_t *sip, scsi_log_parameter_header_t *lphp,
    int log_length)
{
	int i, plen = 0;
	int entries = 0;
	ushort_t param_code;
	scsi_selftest_log_param_t *stp;
	nvlist_t *nvl;

	assert(sip->si_dsp->ds_testfail == NULL);
	if (nvlist_alloc(&sip->si_dsp->ds_testfail, NV_UNIQUE_NAME, 0) != 0)
		return (scsi_set_errno(sip, EDS_NOMEM));
	nvl = sip->si_dsp->ds_testfail;

	for (i = 0; i < log_length; i += plen, entries++) {
		lphp = (scsi_log_parameter_header_t *)((char *)lphp + plen);
		param_code = BE_16(lphp->lph_param);
		stp = (scsi_selftest_log_param_t *)lphp;

		if (param_code >= LOGPAGE_SELFTEST_MIN_PARAM_CODE &&
		    param_code <= LOGPAGE_SELFTEST_MAX_PARAM_CODE &&
		    lphp->lph_length >= LOGPAGE_SELFTEST_PARAM_LEN) {
			/*
			 * We always log the last result, or the result of the
			 * last completed test.
			 */
			if ((param_code == 1 ||
			    SELFTEST_COMPLETE(stp->st_results))) {
				if (nvlist_add_uint8(nvl,
				    FM_EREPORT_PAYLOAD_SCSI_RESULTCODE,
				    stp->st_results) != 0 ||
				    nvlist_add_uint16(nvl,
				    FM_EREPORT_PAYLOAD_SCSI_TIMESTAMP,
				    BE_16(stp->st_timestamp)) != 0 ||
				    nvlist_add_uint8(nvl,
				    FM_EREPORT_PAYLOAD_SCSI_SEGMENT,
				    stp->st_number) != 0 ||
				    nvlist_add_uint64(nvl,
				    FM_EREPORT_PAYLOAD_SCSI_ADDRESS,
				    BE_64(stp->st_lba)) != 0)
					return (scsi_set_errno(sip,
					    EDS_NOMEM));

				if (SELFTEST_COMPLETE(stp->st_results)) {
					if (stp->st_results != SELFTEST_OK)
						sip->si_dsp->ds_faults |=
						    DS_FAULT_TESTFAIL;
					return (0);
				}
			}
		}

		plen = lphp->lph_length +
		    sizeof (scsi_log_parameter_header_t);
	}

	return (0);
}
Ejemplo n.º 2
0
static int
logpage_temp_analyze(ds_scsi_info_t *sip, scsi_log_parameter_header_t *lphp,
    int log_length)
{
	int i, plen = 0;
	uint8_t reftemp, curtemp;
	ushort_t param_code;
	scsi_temp_log_param_t *temp;
	nvlist_t *nvl;

	assert(sip->si_dsp->ds_overtemp == NULL);
	if (nvlist_alloc(&sip->si_dsp->ds_overtemp, NV_UNIQUE_NAME, 0) != 0)
		return (scsi_set_errno(sip, EDS_NOMEM));
	nvl = sip->si_dsp->ds_overtemp;

	reftemp = curtemp = INVALID_TEMPERATURE;
	for (i = 0; i < log_length; i += plen) {
		lphp = (scsi_log_parameter_header_t *)((char *)lphp + plen);
		param_code = BE_16(lphp->lph_param);
		temp = (scsi_temp_log_param_t *)lphp;

		switch (param_code) {
		case LOGPARAM_TEMP_CURTEMP:
			if (lphp->lph_length != LOGPARAM_TEMP_LEN)
				break;

			if (nvlist_add_uint8(nvl,
			    FM_EREPORT_PAYLOAD_SCSI_CURTEMP,
			    temp->t_temp) != 0)
				return (scsi_set_errno(sip, EDS_NOMEM));
			curtemp = temp->t_temp;
			break;

		case LOGPARAM_TEMP_REFTEMP:
			if (lphp->lph_length != LOGPARAM_TEMP_LEN)
				break;

			if (nvlist_add_uint8(nvl,
			    FM_EREPORT_PAYLOAD_SCSI_THRESHTEMP,
			    temp->t_temp) != 0)
				return (scsi_set_errno(sip, EDS_NOMEM));
			reftemp = temp->t_temp;
			break;
		}

		plen = lphp->lph_length +
		    sizeof (scsi_log_parameter_header_t);
	}

	if (reftemp != INVALID_TEMPERATURE && curtemp != INVALID_TEMPERATURE &&
	    curtemp > reftemp)
		sip->si_dsp->ds_faults |= DS_FAULT_OVERTEMP;

	return (0);
}
Ejemplo n.º 3
0
/*
 * Verify the contents of the temperature log page.  The temperature log page
 * contains two log parameters: the current temperature, and (optionally) the
 * reference temperature.  For the verification phase, we check that the two
 * parameters we care about are well-formed.  If there is no reference
 * temperature, then we cannot use the page for monitoring purposes.
 */
static int
logpage_temp_verify(ds_scsi_info_t *sip,
    scsi_log_parameter_header_t *lphp, int log_length, nvlist_t *nvl)
{
	int i, plen = 0;
	boolean_t has_reftemp = B_FALSE;
	boolean_t bad_length = B_FALSE;
	ushort_t param_code;

	for (i = 0; i < log_length; i += plen) {
		lphp = (scsi_log_parameter_header_t *)((char *)lphp + plen);
		param_code = BE_16(lphp->lph_param);

		switch (param_code) {
		case LOGPARAM_TEMP_CURTEMP:
			if (nvlist_add_boolean_value(nvl, "current-temperature",
			    B_TRUE) != 0)
				return (scsi_set_errno(sip, EDS_NOMEM));
			if (lphp->lph_length != LOGPARAM_TEMP_LEN) {
				if (nvlist_add_uint8(nvl,
				    "invalid-length", lphp->lph_length) != 0)
					return (scsi_set_errno(sip, EDS_NOMEM));
				bad_length = B_TRUE;
			}
			break;

		case LOGPARAM_TEMP_REFTEMP:
			if (nvlist_add_boolean_value(nvl,
			    "reference-temperature", B_TRUE) != 0)
				return (scsi_set_errno(sip, EDS_NOMEM));
			if (lphp->lph_length != LOGPARAM_TEMP_LEN) {
				if (nvlist_add_uint8(nvl,
				    "invalid-length", lphp->lph_length) != 0)
					return (scsi_set_errno(sip, EDS_NOMEM));
				bad_length = B_TRUE;
			}
			has_reftemp = B_TRUE;
			break;
		}

		plen = lphp->lph_length +
		    sizeof (scsi_log_parameter_header_t);
	}

	if (bad_length || !has_reftemp) {
		sip->si_supp_log &= ~LOGPAGE_SUPP_TEMP;
		printf("temperature logpage validation failed\n");
	}

	return (0);
}
Ejemplo n.º 4
0
void
inhm_create_nvl(int chip)
{
	nvlist_t *nvl;

	(void) nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP);
	(void) nvlist_add_uint8(nvl, MCINTEL_NVLIST_VERSTR,
	    MCINTEL_NVLIST_VERS);
	(void) nvlist_add_string(nvl, MCINTEL_NVLIST_MEM, inhm_mc_name());
	(void) nvlist_add_uint8(nvl, MCINTEL_NVLIST_NMEM, 1);
	(void) nvlist_add_uint8(nvl, MCINTEL_NVLIST_NRANKS, 4);
	inhm_dimmlist(chip, nvl);

	if (inhm_mc_nvl[chip])
		nvlist_free(inhm_mc_nvl[chip]);
	inhm_mc_nvl[chip] = nvl;
}
Ejemplo n.º 5
0
/*
 * Load the current IE mode pages
 */
static int
load_ie_modepage(ds_scsi_info_t *sip)
{
	struct scsi_ms_hdrs junk_hdrs;
	int result;
	uint_t skey, asc, ascq;

	if (!(sip->si_supp_mode & MODEPAGE_SUPP_IEC))
		return (0);

	bzero(&sip->si_iec_current, sizeof (sip->si_iec_current));
	bzero(&sip->si_iec_changeable, sizeof (sip->si_iec_changeable));

	if ((result = scsi_mode_sense(sip,
	    MODEPAGE_INFO_EXCPT, PC_CURRENT, &sip->si_iec_current,
	    MODEPAGE_INFO_EXCPT_LEN, &sip->si_hdrs, &skey, &asc,
	    &ascq)) == 0) {
		result = scsi_mode_sense(sip,
		    MODEPAGE_INFO_EXCPT, PC_CHANGEABLE,
		    &sip->si_iec_changeable,
		    MODEPAGE_INFO_EXCPT_LEN, &junk_hdrs, &skey, &asc, &ascq);
	}

	if (result != 0) {
		printf("failed to get IEC modepage (KEY=0x%x "
		    "ASC=0x%x ASCQ=0x%x)", skey, asc, ascq);
		sip->si_supp_mode &= ~MODEPAGE_SUPP_IEC;
	} else  {
		if (nvlist_add_boolean_value(sip->si_state_iec,
		    "dexcpt", sip->si_iec_current.ie_dexcpt) != 0 ||
		    nvlist_add_boolean_value(sip->si_state_iec,
		    "logerr", sip->si_iec_current.ie_logerr) != 0 ||
		    nvlist_add_uint8(sip->si_state_iec,
		    "mrie", sip->si_iec_current.ie_mrie) != 0 ||
		    nvlist_add_boolean_value(sip->si_state_iec,
		    "test", sip->si_iec_current.ie_test) != 0 ||
		    nvlist_add_boolean_value(sip->si_state_iec,
		    "ewasc", sip->si_iec_current.ie_ewasc) != 0 ||
		    nvlist_add_boolean_value(sip->si_state_iec,
		    "perf", sip->si_iec_current.ie_perf) != 0 ||
		    nvlist_add_boolean_value(sip->si_state_iec,
		    "ebf", sip->si_iec_current.ie_ebf) != 0 ||
		    nvlist_add_uint32(sip->si_state_iec,
		    "interval-timer",
		    BE_32(sip->si_iec_current.ie_interval_timer)) != 0 ||
		    nvlist_add_uint32(sip->si_state_iec,
		    "report-count",
		    BE_32(sip->si_iec_current.ie_report_count)) != 0)
			return (scsi_set_errno(sip, EDS_NOMEM));
	}

	return (0);
}
Ejemplo n.º 6
0
/*
 * Analyze the IE logpage.  If we find an IE log record with a non-zero 'asc',
 * then we have a fault.
 */
static int
logpage_ie_analyze(ds_scsi_info_t *sip, scsi_log_parameter_header_t *lphp,
    int log_length)
{
	int i, plen = 0;
	scsi_ie_log_param_t *iep = (scsi_ie_log_param_t *)lphp;
	nvlist_t *nvl;

	assert(sip->si_dsp->ds_predfail == NULL);
	if (nvlist_alloc(&sip->si_dsp->ds_predfail, NV_UNIQUE_NAME, 0) != 0)
		return (scsi_set_errno(sip, EDS_NOMEM));
	nvl = sip->si_dsp->ds_predfail;

	for (i = 0; i < log_length; i += plen) {
		iep = (scsi_ie_log_param_t *)((char *)iep + plen);

		/*
		 * Even though we validated the length during the initial phase,
		 * never trust the device.
		 */
		if (BE_16(iep->ie_hdr.lph_param) == LOGPARAM_IE &&
		    iep->ie_hdr.lph_length >= LOGPARAM_IE_MIN_LEN) {
			if (nvlist_add_uint8(nvl, FM_EREPORT_PAYLOAD_SCSI_ASC,
			    iep->ie_asc) != 0 ||
			    nvlist_add_uint8(nvl, FM_EREPORT_PAYLOAD_SCSI_ASCQ,
			    iep->ie_ascq) != 0)
				return (scsi_set_errno(sip, EDS_NOMEM));

			if (iep->ie_asc != 0)
				sip->si_dsp->ds_faults |=
				    DS_FAULT_PREDFAIL;
			break;
		}
		plen = iep->ie_hdr.lph_length +
		    sizeof (scsi_log_parameter_header_t);
	}

	return (0);
}
Ejemplo n.º 7
0
/*
 * Analyze the IE mode sense page explicitly.  This is only needed if the IE log
 * page is not supported.
 */
static int
analyze_ie_sense(ds_scsi_info_t *sip)
{
	uint_t skey, asc, ascq;
	nvlist_t *nvl;

	/*
	 * Don't bother checking if we weren't able to set our MRIE correctly.
	 */
	if (sip->si_iec_current.ie_mrie != IE_REPORT_ON_REQUEST)
		return (0);

	if (scsi_request_sense(sip, &skey, &asc, &ascq) != 0) {
		printf("failed to request IE page (KEY=0x%x ASC=0x%x "
		    "ASCQ=0x%x)\n", skey, asc, ascq);
		return (scsi_set_errno(sip, EDS_IO));
	} else if (skey == KEY_NO_SENSE) {
		assert(sip->si_dsp->ds_predfail == NULL);
		if (nvlist_alloc(&sip->si_dsp->ds_predfail,
		    NV_UNIQUE_NAME, 0) != 0)
			return (scsi_set_errno(sip, EDS_NOMEM));
		nvl = sip->si_dsp->ds_predfail;

		if (nvlist_add_uint8(nvl,
		    FM_EREPORT_PAYLOAD_SCSI_ASC, asc) != 0 ||
		    nvlist_add_uint8(nvl,
		    FM_EREPORT_PAYLOAD_SCSI_ASCQ, ascq) != 0) {
			nvlist_free(nvl);
			return (scsi_set_errno(sip, EDS_NOMEM));
		}

		if (asc != 0)
			sip->si_dsp->ds_faults |= DS_FAULT_PREDFAIL;
	}

	return (0);
}
Ejemplo n.º 8
0
/*
 * fps_fmri_cpu_set(nvlist_t *fmri_cpu, uint32_t cpu_id)
 * adds the resource data to fmri_cpu.
 */
static int
fps_fmri_cpu_set(nvlist_t *fmri_cpu, uint32_t cpu_id)
{
	if (fmri_cpu == NULL)
		return (1);

	if (nvlist_add_uint8(fmri_cpu, FM_VERSION,
	    FM_CPU_SCHEME_VERSION) != 0)
		return (1);

	if (nvlist_add_string(fmri_cpu, FM_FMRI_SCHEME,
	    FM_FMRI_SCHEME_CPU) != 0)
		return (1);

	if (nvlist_add_uint32(fmri_cpu, FM_FMRI_CPU_ID, cpu_id) != 0)
		return (1);
	return (0);
}
Ejemplo n.º 9
0
/*
 * Solve a given ZFS case.  This first checks to make sure the diagnosis is
 * still valid, as well as cleaning up any pending timer associated with the
 * case.
 */
static void
zfs_case_solve(fmd_hdl_t *hdl, zfs_case_t *zcp, const char *faultname,
    boolean_t checkunusable)
{
	nvlist_t *detector, *fault;
	boolean_t serialize;
	nvlist_t *fru = NULL;
	fmd_hdl_debug(hdl, "solving fault '%s'", faultname);

	/*
	 * Construct the detector from the case data.  The detector is in the
	 * ZFS scheme, and is either the pool or the vdev, depending on whether
	 * this is a vdev or pool fault.
	 */
	detector = fmd_nvl_alloc(hdl, FMD_SLEEP);

	(void) nvlist_add_uint8(detector, FM_VERSION, ZFS_SCHEME_VERSION0);
	(void) nvlist_add_string(detector, FM_FMRI_SCHEME, FM_FMRI_SCHEME_ZFS);
	(void) nvlist_add_uint64(detector, FM_FMRI_ZFS_POOL,
	    zcp->zc_data.zc_pool_guid);
	if (zcp->zc_data.zc_vdev_guid != 0) {
		(void) nvlist_add_uint64(detector, FM_FMRI_ZFS_VDEV,
		    zcp->zc_data.zc_vdev_guid);
	}

	fault = fmd_nvl_create_fault(hdl, faultname, 100, detector,
	    fru, detector);
	fmd_case_add_suspect(hdl, zcp->zc_case, fault);

	nvlist_free(fru);

	fmd_case_solve(hdl, zcp->zc_case);

	serialize = B_FALSE;
	if (zcp->zc_data.zc_has_remove_timer) {
		fmd_timer_remove(hdl, zcp->zc_remove_timer);
		zcp->zc_data.zc_has_remove_timer = 0;
		serialize = B_TRUE;
	}
	if (serialize)
		zfs_case_serialize(hdl, zcp);

	nvlist_free(detector);
}
Ejemplo n.º 10
0
/*
 * Verify the contents of the self test log page.  The log supports a maximum of
 * 20 entries, where each entry's parameter code is its index in the log.  We
 * check that the parameter codes fall within this range, and that the size of
 * each page is what we expect.  It's perfectly acceptable for there to be no
 * entries in this log, so we must also be sure to validate the contents as part
 * of the analysis phase.
 */
static int
logpage_selftest_verify(ds_scsi_info_t *sip,
    scsi_log_parameter_header_t *lphp, int log_length, nvlist_t *nvl)
{
	int i, plen = 0;
	boolean_t bad = B_FALSE;
	int entries = 0;
	ushort_t param_code;

	for (i = 0; i < log_length; i += plen, entries++) {
		lphp = (scsi_log_parameter_header_t *)((char *)lphp + plen);
		param_code = BE_16(lphp->lph_param);

		if (param_code < LOGPAGE_SELFTEST_MIN_PARAM_CODE ||
		    param_code > LOGPAGE_SELFTEST_MAX_PARAM_CODE) {
			if (nvlist_add_uint16(nvl, "invalid-param-code",
			    param_code) != 0)
				return (scsi_set_errno(sip, EDS_NOMEM));
			bad = B_TRUE;
			break;
		}

		if (lphp->lph_length != LOGPAGE_SELFTEST_PARAM_LEN) {
			if (nvlist_add_uint8(nvl, "invalid-length",
			    lphp->lph_length) != 0)
				return (scsi_set_errno(sip, EDS_NOMEM));
			bad = B_TRUE;
			break;

		}

		plen = lphp->lph_length +
		    sizeof (scsi_log_parameter_header_t);
	}

	if (bad) {
		sip->si_supp_log &= ~LOGPAGE_SUPP_SELFTEST;
		printf("selftest logpage validation failed\n");
	}

	return (0);
}
Ejemplo n.º 11
0
/*
 * fps_fmri_svc_set(nvlist_t *fmri_svc, const char *svc_fmri)
 * adds the detector data to fmri_svc.
 */
static int
fps_fmri_svc_set(nvlist_t *fmri_svc, const char *svc_fmri)
{
	if (fmri_svc == NULL)
		return (1);

	if (svc_fmri == NULL)
		return (1);

	if (nvlist_add_uint8(fmri_svc, FM_VERSION, FM_SVC_SCHEME_VERSION) != 0)
		return (1);

	if (nvlist_add_string(fmri_svc, FM_FMRI_SCHEME,
	    FM_FMRI_SCHEME_SVC) != 0)
		return (1);

	if (nvlist_add_string(fmri_svc, FM_FMRI_SVC_NAME,
	    svc_fmri) != 0)
		return (1);

	return (0);
}
Ejemplo n.º 12
0
/*
 * Verify that the IE log page is sane.  This log page is potentially chock-full
 * of vendor specific information that we do not know how to access.  All we can
 * do is check for the generic predictive failure bit.  If this log page is not
 * well-formed, then bail out.
 */
static int
logpage_ie_verify(ds_scsi_info_t *sip, scsi_log_parameter_header_t *lphp,
    int log_length, nvlist_t *nvl)
{
	int i, plen = 0;
	boolean_t seen = B_FALSE;
	scsi_ie_log_param_t *iep =
	    (scsi_ie_log_param_t *)lphp;

	for (i = 0; i < log_length; i += plen) {
		iep = (scsi_ie_log_param_t *)((char *)iep + plen);

		if (BE_16(iep->ie_hdr.lph_param) == LOGPARAM_IE) {
			if (nvlist_add_boolean_value(nvl, "general",
			    B_TRUE) != 0)
				return (scsi_set_errno(sip, EDS_NOMEM));

			if (lphp->lph_length < LOGPARAM_IE_MIN_LEN) {
				if (nvlist_add_uint8(nvl,
				    "invalid-length", lphp->lph_length) != 0)
					return (scsi_set_errno(sip, EDS_NOMEM));
			} else {
				seen = B_TRUE;
			}
			break;
		}

		plen = iep->ie_hdr.lph_length +
		    sizeof (scsi_log_parameter_header_t);
	}

	if (!seen) {
		sip->si_supp_log &= ~LOGPAGE_SUPP_IE;
		printf("IE logpage validation failed\n");
	}

	return (0);
}
Ejemplo n.º 13
0
static nvlist_t *
mem_fmri_create(topo_mod_t *mod, char *serial, char *label)
{
	int err;
	nvlist_t *fmri;

	if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0)
		return (NULL);
	err = nvlist_add_uint8(fmri, FM_VERSION, FM_MEM_SCHEME_VERSION);
	err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_MEM);
	if (serial != NULL)
		err |= nvlist_add_string_array(fmri, FM_FMRI_MEM_SERIAL_ID,
		    &serial, 1);
	if (label != NULL)
		err |= nvlist_add_string(fmri, FM_FMRI_MEM_UNUM, label);
	if (err != 0) {
		nvlist_free(fmri);
		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
		return (NULL);
	}

	return (fmri);
}
Ejemplo n.º 14
0
void
fnvlist_add_uint8(nvlist_t *nvl, const char *name, uint8_t val)
{
	VERIFY0(nvlist_add_uint8(nvl, name, val));
}
Ejemplo n.º 15
0
/*ARGSUSED3*/
static nvlist_t *
fmevt_detector(nvlist_t *attr, char *ruleset, int user, int priv,
    fmev_pri_t pri)
{
	char buf[FMEV_MAX_RULESET_LEN + 1];
	char *ns, *subsys;
	nvlist_t *obj, *dtcr, *site, *ctxt;
	char *execname = NULL;
	int32_t i32;
	int64_t i64;
	int err = 0;
	char *str;

	(void) strncpy(buf, ruleset, sizeof (buf));
	if (!fmevt_rs_burst(NULL, buf, &ns, &subsys, B_FALSE))
		return (NULL);

	obj = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP);
	dtcr = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP);
	site = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP);
	ctxt = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP);

	if (obj == NULL || dtcr == NULL || site == NULL || ctxt == NULL) {
		err++;
		goto done;
	}

	/*
	 * Build up 'object' nvlist.
	 */
	if (nvlist_lookup_string(attr, "__fmev_execname", &execname) == 0)
		err += nvlist_add_string(obj, FM_FMRI_SW_OBJ_PATH, execname);

	/*
	 * Build up 'site' nvlist.  We should have source file and line
	 * number and, if the producer was compiled with C99, function name.
	 */
	if (nvlist_lookup_string(attr, "__fmev_file", &str) == 0) {
		err += nvlist_add_string(site, FM_FMRI_SW_SITE_FILE, str);
		(void) nvlist_remove(attr, "__fmev_file", DATA_TYPE_STRING);
	}

	if (nvlist_lookup_string(attr, "__fmev_func", &str) == 0) {
		err += nvlist_add_string(site, FM_FMRI_SW_SITE_FUNC, str);
		(void) nvlist_remove(attr, "__fmev_func", DATA_TYPE_STRING);
	}

	if (nvlist_lookup_int64(attr, "__fmev_line", &i64) == 0) {
		err += nvlist_add_int64(site, FM_FMRI_SW_SITE_LINE, i64);
		(void) nvlist_remove(attr, "__fmev_line", DATA_TYPE_INT64);
	}

	/*
	 * Build up 'context' nvlist.  We do not include contract id at
	 * this time.
	 */

	err += nvlist_add_string(ctxt, FM_FMRI_SW_CTXT_ORIGIN,
	    user ? "userland" : "kernel");

	if (execname) {
		err += nvlist_add_string(ctxt, FM_FMRI_SW_CTXT_EXECNAME,
		    execname);
		(void) nvlist_remove(attr, "__fmev_execname", DATA_TYPE_STRING);
	}

	if (nvlist_lookup_int32(attr, "__fmev_pid", &i32) == 0) {
		err += nvlist_add_int32(ctxt, FM_FMRI_SW_CTXT_PID, i32);
		(void) nvlist_remove(attr, "__fmev_pid", DATA_TYPE_INT32);
	}

	if (!isglobalzone)
		err += nvlist_add_string(ctxt, FM_FMRI_SW_CTXT_ZONE, zonename);

	/* Put it all together */

	err += nvlist_add_uint8(dtcr, FM_VERSION, SW_SCHEME_VERSION0);
	err += nvlist_add_string(dtcr, FM_FMRI_SCHEME, FM_FMRI_SCHEME_SW);
	err += nvlist_add_nvlist(dtcr, FM_FMRI_SW_OBJ, obj);
	err += nvlist_add_nvlist(dtcr, FM_FMRI_SW_SITE, site);
	err += nvlist_add_nvlist(dtcr, FM_FMRI_SW_CTXT, ctxt);

done:
	nvlist_free(obj);
	nvlist_free(site);
	nvlist_free(ctxt);

	if (err == 0) {
		return (dtcr);
	} else {
		nvlist_free(dtcr);
		return (NULL);
	}
}
Ejemplo n.º 16
0
/*
 * fps_generate_ereport_struct(struct fps_test_ereport *report)
 * takes report and constructs an nvlist that will be used
 * for the ereport.
 */
int
fps_generate_ereport_struct(struct fps_test_ereport *report)
{
	char class_name[FM_MAX_CLASS];
	char *cpu_brand;
	char *string_data;
	int expect_size;
	int is_valid_cpu;
	int mask;
	int observe_size;
	int ret;
	nvlist_t *detector;
	nvlist_t *ereport;
	nvlist_t *resource;
	uint32_t cpu_id;
	uint32_t test;
	uint8_t fps_ver;
	uint64_t ena;
	uint64_t ereport_time;
	uint64_t *expect;
	uint64_t *observe;

	if (report == NULL)
		return (FPU_EREPORT_FAIL);

	ret = FPU_FOROFFLINE;
	cpu_id = report->cpu_id;
	test = report->test_id;
	mask = report->mask;
	is_valid_cpu = report->is_valid_cpu;
	expect_size = report->expected_size;
	expect = report->expected;
	observe_size = report->observed_size;
	observe = report->observed;
	string_data = report->info;

	/* allocate nvlists */
	if ((ereport = fps_nvlist_create()) == NULL)
		_exit(FPU_EREPORT_FAIL);

	if ((detector = fps_nvlist_create()) == NULL) {
		_exit(FPU_EREPORT_FAIL);
	}

	/* setup class */
	if ((cpu_brand = fps_get_cpu_brand(cpu_id)) == NULL)
		_exit(FPU_EREPORT_FAIL);

	if ((snprintf(class_name, FM_MAX_CLASS, "%s.%s.%s",
	    CLASS_HEAD, cpu_brand, CLASS_TAIL)) < 0)
		_exit(FPU_EREPORT_FAIL);

	/* setup ena */
	ereport_time = gethrtime();
	ena = fps_ena_generate(ereport_time, cpu_id, FM_ENA_FMT1);

	/* setup detector */
	if (fps_fmri_svc_set(detector, getenv("SMF_FMRI")) != 0) {
		_exit(FPU_EREPORT_FAIL);
	}

	/* setup fps-version */
	fps_ver = FPS_VERSION;

	/* setup resource */
	if (is_valid_cpu) {
		resource = fps_nvlist_create();

		if (fps_fmri_cpu_set(resource, cpu_id)) {
			_exit(FPU_EREPORT_FAIL);
		}
	} else {
		resource = NULL;
	}

	/* put it together */
	if (nvlist_add_string(ereport, NAME_FPS_CLASS, class_name) != 0)
		_exit(FPU_EREPORT_FAIL);

	if (ena != 0) {
		if (nvlist_add_uint64(ereport, NAME_FPS_ENA, ena) != 0)
			_exit(FPU_EREPORT_FAIL);
	} else
		_exit(FPU_EREPORT_FAIL);

	if (nvlist_add_nvlist(ereport, NAME_FPS_DETECTOR,
	    (nvlist_t *)detector) != 0)
		_exit(FPU_EREPORT_FAIL);

	if (nvlist_add_uint8(ereport, NAME_FPS_VERSION, fps_ver) != 0)
		_exit(FPU_EREPORT_FAIL);

	if (nvlist_add_uint32(ereport, NAME_FPS_TEST_ID, test) != 0)
		ret = FPU_EREPORT_INCOM;

	if (nvlist_add_uint64_array(ereport, NAME_FPS_EXPECTED_VALUE,
	    expect, expect_size) != 0)
		ret = FPU_EREPORT_INCOM;

	if (nvlist_add_uint64_array(ereport, NAME_FPS_OBSERVED_VALUE,
	    observe, observe_size) != 0)
		ret = FPU_EREPORT_INCOM;

	if (mask & IS_EREPORT_INFO) {
		if (nvlist_add_string(ereport, NAME_FPS_STRING_DATA,
		    string_data) != 0)
			ret = FPU_EREPORT_INCOM;
	}

	if (is_valid_cpu) {
		if (nvlist_add_nvlist(ereport, NAME_FPS_RESOURCE,
		    (nvlist_t *)resource) != 0)
			_exit(FPU_EREPORT_FAIL);
	}

	/* publish */
	if (fps_post_ereport(ereport)) {
		ret = FPU_EREPORT_FAIL;
	}

	/* free nvlists */
	nvlist_free(ereport);

	if (resource != NULL)
		nvlist_free(resource);

	if (detector != NULL)
		nvlist_free(detector);

	return (ret);
}
Ejemplo n.º 17
0
/*
 * Solve a given ZFS case.  This first checks to make sure the diagnosis is
 * still valid, as well as cleaning up any pending timer associated with the
 * case.
 */
static void
zfs_case_solve(fmd_hdl_t *hdl, zfs_case_t *zcp, const char *faultname,
    boolean_t checkunusable)
{
	libzfs_handle_t *zhdl = fmd_hdl_getspecific(hdl);
	nvlist_t *detector, *fault;
	boolean_t serialize;
	nvlist_t *fmri, *fru;
	topo_hdl_t *thp;
	int err;

	/*
	 * Construct the detector from the case data.  The detector is in the
	 * ZFS scheme, and is either the pool or the vdev, depending on whether
	 * this is a vdev or pool fault.
	 */
	detector = fmd_nvl_alloc(hdl, FMD_SLEEP);

	(void) nvlist_add_uint8(detector, FM_VERSION, ZFS_SCHEME_VERSION0);
	(void) nvlist_add_string(detector, FM_FMRI_SCHEME, FM_FMRI_SCHEME_ZFS);
	(void) nvlist_add_uint64(detector, FM_FMRI_ZFS_POOL,
	    zcp->zc_data.zc_pool_guid);
	if (zcp->zc_data.zc_vdev_guid != 0) {
		(void) nvlist_add_uint64(detector, FM_FMRI_ZFS_VDEV,
		    zcp->zc_data.zc_vdev_guid);
	}

	/*
	 * We also want to make sure that the detector (pool or vdev) properly
	 * reflects the diagnosed state, when the fault corresponds to internal
	 * ZFS state (i.e. not checksum or I/O error-induced).  Otherwise, a
	 * device which was unavailable early in boot (because the driver/file
	 * wasn't available) and is now healthy will be mis-diagnosed.
	 */
	if (!fmd_nvl_fmri_present(hdl, detector) ||
	    (checkunusable && !fmd_nvl_fmri_unusable(hdl, detector))) {
		fmd_case_close(hdl, zcp->zc_case);
		nvlist_free(detector);
		return;
	}


	fru = NULL;
	if (zcp->zc_fru != NULL &&
	    (thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) != NULL) {
		/*
		 * If the vdev had an associated FRU, then get the FRU nvlist
		 * from the topo handle and use that in the suspect list.  We
		 * explicitly lookup the FRU because the fmri reported from the
		 * kernel may not have up to date details about the disk itself
		 * (serial, part, etc).
		 */
		if (topo_fmri_str2nvl(thp, zcp->zc_fru, &fmri, &err) == 0) {
			/*
			 * If the disk is part of the system chassis, but the
			 * FRU indicates a different chassis ID than our
			 * current system, then ignore the error.  This
			 * indicates that the device was part of another
			 * cluster head, and for obvious reasons cannot be
			 * imported on this system.
			 */
			if (libzfs_fru_notself(zhdl, zcp->zc_fru)) {
				fmd_case_close(hdl, zcp->zc_case);
				nvlist_free(fmri);
				fmd_hdl_topo_rele(hdl, thp);
				nvlist_free(detector);
				return;
			}

			/*
			 * If the device is no longer present on the system, or
			 * topo_fmri_fru() fails for other reasons, then fall
			 * back to the fmri specified in the vdev.
			 */
			if (topo_fmri_fru(thp, fmri, &fru, &err) != 0)
				fru = fmd_nvl_dup(hdl, fmri, FMD_SLEEP);
			nvlist_free(fmri);
		}

		fmd_hdl_topo_rele(hdl, thp);
	}

	fault = fmd_nvl_create_fault(hdl, faultname, 100, detector,
	    fru, detector);
	fmd_case_add_suspect(hdl, zcp->zc_case, fault);

	nvlist_free(fru);

	fmd_case_solve(hdl, zcp->zc_case);

	serialize = B_FALSE;
	if (zcp->zc_data.zc_has_remove_timer) {
		fmd_timer_remove(hdl, zcp->zc_remove_timer);
		zcp->zc_data.zc_has_remove_timer = 0;
		serialize = B_TRUE;
	}
	if (serialize)
		zfs_case_serialize(hdl, zcp);

	nvlist_free(detector);
}
Ejemplo n.º 18
0
/*ARGSUSED*/
static int
sw_fmri_create(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *in, nvlist_t **out)
{
	nvlist_t *args, *fmri = NULL, *obj = NULL, *site = NULL, *ctxt = NULL;
	topo_mod_errno_t moderr;
	int err = 0;

	char *obj_path, *obj_root;
	nvlist_t *obj_pkg;

	char *site_token, *site_module, *site_file, *site_func;
	int64_t site_line;

	char *ctxt_origin, *ctxt_execname, *ctxt_zone;
	int64_t ctxt_pid, ctxt_ctid;
	char **ctxt_stack;
	uint_t ctxt_stackdepth;


	if (version > TOPO_METH_FMRI_VERSION)
		return (topo_mod_seterrno(mod, EMOD_VER_NEW));

	if (nvlist_lookup_nvlist(in, TOPO_METH_FMRI_ARG_NVL, &args) != 0)
		return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));

	if (nvlist_lookup_string(args, "obj_path", &obj_path) != 0)
		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
	err |= sw_get_optl_string(args, "obj_root", &obj_root);
	err |= sw_get_optl_nvlist(args, "obj-pkg", &obj_pkg);

	err |= sw_get_optl_string(args, "site_token", &site_token);
	err |= sw_get_optl_string(args, "site_module", &site_module);
	err |= sw_get_optl_string(args, "site_file", &site_file);
	err |= sw_get_optl_string(args, "site_func", &site_func);
	err |= sw_get_optl_int64(args, "site_line", &site_line);

	err |= sw_get_optl_string(args, "ctxt_origin", &ctxt_origin);
	err |= sw_get_optl_string(args, "ctxt_execname", &ctxt_execname);
	err |= sw_get_optl_string(args, "ctxt_zone", &ctxt_zone);
	err |= sw_get_optl_int64(args, "ctxt_pid", &ctxt_pid);
	err |= sw_get_optl_int64(args, "ctxt_ctid", &ctxt_ctid);

	if (nvlist_lookup_string_array(args, "stack", &ctxt_stack,
	    &ctxt_stackdepth) != 0) {
		if (errno == ENOENT)
			ctxt_stack = NULL;
		else
			err++;
	}

	if (err)
		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);

	if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0 ||
	    topo_mod_nvalloc(mod, &obj, NV_UNIQUE_NAME) != 0) {
		moderr = EMOD_NOMEM;
		goto out;
	}

	/*
	 * Add standard FMRI members 'version' and 'scheme'.
	 */
	err |= nvlist_add_uint8(fmri, FM_VERSION, FM_SW_SCHEME_VERSION);
	err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_SW);

	/*
	 * Build up the 'object' nvlist.
	 */
	err |= nvlist_add_string(obj, FM_FMRI_SW_OBJ_PATH, obj_path);
	err |= sw_add_optl_string(obj, FM_FMRI_SW_OBJ_ROOT, obj_root);
	if (obj_pkg)
		err |= nvlist_add_nvlist(obj, FM_FMRI_SW_OBJ_PKG, obj_pkg);

	/*
	 * Add 'object' to the fmri.
	 */
	if (err == 0)
		err |= nvlist_add_nvlist(fmri, FM_FMRI_SW_OBJ, obj);

	if (err) {
		moderr = EMOD_NOMEM;
		goto out;
	}

	/*
	 * Do we have anything for a 'site' nvlist?
	 */
	if (site_token == NULL && site_module == NULL && site_file == NULL &&
	    site_func == NULL && site_line == -1)
		goto context;

	/*
	 * Allocate and build 'site' nvlist.
	 */
	if (topo_mod_nvalloc(mod, &site, NV_UNIQUE_NAME) != 0) {
		moderr = EMOD_NOMEM;
		goto out;
	}

	err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_TOKEN, site_token);
	err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_MODULE, site_module);
	err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_FILE, site_file);
	err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_FUNC, site_func);
	if ((site_token || site_module || site_file || site_func) &&
	    site_line != -1)
		err |= nvlist_add_int64(site, FM_FMRI_SW_SITE_LINE, site_line);

	/*
	 * Add 'site' to the fmri.
	 */
	if (err == 0)
		err |= nvlist_add_nvlist(fmri, FM_FMRI_SW_SITE, site);

	if (err) {
		moderr = EMOD_NOMEM;
		goto out;
	}

context:
	/*
	 * Do we have anything for a 'context' nvlist?
	 */
	if (ctxt_origin || ctxt_execname || ctxt_zone ||
	    ctxt_pid != -1 || ctxt_ctid != -1 || ctxt_stack != NULL)
		goto out;

	/*
	 * Allocate and build 'context' nvlist.
	 */
	if (topo_mod_nvalloc(mod, &ctxt, NV_UNIQUE_NAME) != 0) {
		moderr = EMOD_NOMEM;
		goto out;
	}

	err |= sw_add_optl_string(ctxt, FM_FMRI_SW_CTXT_ORIGIN, ctxt_origin);
	err |= sw_add_optl_string(ctxt, FM_FMRI_SW_CTXT_EXECNAME,
	    ctxt_execname);
	err |= sw_add_optl_string(ctxt, FM_FMRI_SW_CTXT_ZONE, ctxt_zone);
	if (ctxt_pid != -1)
		err |= nvlist_add_int64(ctxt, FM_FMRI_SW_CTXT_PID, ctxt_pid);
	if (ctxt_ctid != -1)
		err |= nvlist_add_int64(ctxt, FM_FMRI_SW_CTXT_CTID, ctxt_ctid);
	if (ctxt_stack != NULL)
		err |= nvlist_add_string_array(ctxt, FM_FMRI_SW_CTXT_STACK,
		    ctxt_stack, ctxt_stackdepth);

	/*
	 * Add 'context' to the fmri.
	 */
	if (err == 0)
		err |= nvlist_add_nvlist(fmri, FM_FMRI_SW_CTXT, ctxt);

	moderr = err ? EMOD_NOMEM : 0;
out:
	if (moderr == 0)
		*out = fmri;

	if (moderr != 0 && fmri)
		nvlist_free(fmri);

	if (obj)
		nvlist_free(obj);

	if (site)
		nvlist_free(site);

	if (ctxt)
		nvlist_free(ctxt);

	return (moderr == 0 ? 0 : topo_mod_seterrno(mod, moderr));
}
Ejemplo n.º 19
0
int
main(int argc, char *argv[])
{
	fmd_msg_hdl_t *h;
	pid_t pid;
	int i, err = 0;
	char *s;

	nvlist_t *auth, *fmri, *list, *test_arr[TEST_ARR_SZ];
	const char *code = "TEST-8000-08";
	int64_t tod[] = { 0x9400000, 0 };

	if (argc > 1) {
		(void) fprintf(stderr, "Usage: %s\n", argv[0]);
		return (2);
	}

	/*
	 * Build up a valid list.suspect event for a fictional diagnosis
	 * using a diagnosis code from our test dictionary so we can format
	 * messages.
	 */
	if (nvlist_alloc(&auth, NV_UNIQUE_NAME, 0) != 0 ||
	    nvlist_alloc(&fmri, NV_UNIQUE_NAME, 0) != 0 ||
	    nvlist_alloc(&list, NV_UNIQUE_NAME, 0) != 0) {
		(void) fprintf(stderr, "%s: nvlist_alloc failed\n", argv[0]);
		return (1);
	}

	err |= nvlist_add_uint8(auth, FM_VERSION, FM_FMRI_AUTH_VERSION);
	err |= nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT, "product");
	err |= nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT_SN, "product_sn");
	err |= nvlist_add_string(auth, FM_FMRI_AUTH_CHASSIS, "chassis");
	err |= nvlist_add_string(auth, FM_FMRI_AUTH_DOMAIN, "domain");
	err |= nvlist_add_string(auth, FM_FMRI_AUTH_SERVER, "server");

	if (err != 0) {
		(void) fprintf(stderr, "%s: failed to build auth nvlist: %s\n",
		    argv[0], strerror(err));
		return (1);
	}

	err |= nvlist_add_uint8(fmri, FM_VERSION, FM_FMD_SCHEME_VERSION);
	err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_FMD);
	err |= nvlist_add_nvlist(fmri, FM_FMRI_AUTHORITY, auth);
	err |= nvlist_add_string(fmri, FM_FMRI_FMD_NAME, "fmd_msg_test");
	err |= nvlist_add_string(fmri, FM_FMRI_FMD_VERSION, "1.0");

	if (err != 0) {
		(void) fprintf(stderr, "%s: failed to build fmri nvlist: %s\n",
		    argv[0], strerror(err));
		return (1);
	}

	err |= nvlist_add_uint8(list, FM_VERSION, FM_SUSPECT_VERSION);
	err |= nvlist_add_string(list, FM_CLASS, FM_LIST_SUSPECT_CLASS);
	err |= nvlist_add_string(list, FM_SUSPECT_UUID, "12345678");
	err |= nvlist_add_string(list, FM_SUSPECT_DIAG_CODE, code);
	err |= nvlist_add_int64_array(list, FM_SUSPECT_DIAG_TIME, tod, 2);
	err |= nvlist_add_nvlist(list, FM_SUSPECT_DE, fmri);
	err |= nvlist_add_uint32(list, FM_SUSPECT_FAULT_SZ, 0);

	/*
	 * Add a contrived nvlist array to our list.suspect so that we can
	 * exercise the expansion syntax for dereferencing nvlist array members
	 */
	for (i = 0; i < TEST_ARR_SZ; i++) {
		if (nvlist_alloc(&test_arr[i], NV_UNIQUE_NAME, 0) != 0) {
			(void) fprintf(stderr, "%s: failed to alloc nvlist "
			    "array: %s\n", argv[0], strerror(err));
			return (1);
		}
		err |= nvlist_add_uint8(test_arr[i], "index", i);
	}
	err |= nvlist_add_nvlist_array(list, "test_arr", test_arr, TEST_ARR_SZ);

	if (err != 0) {
		(void) fprintf(stderr, "%s: failed to build list nvlist: %s\n",
		    argv[0], strerror(err));
		return (1);
	}

	/*
	 * Now initialize the libfmd_msg library for testing, using the message
	 * catalogs found in the proto area of the current workspace.
	 */
	if ((h = fmd_msg_init(getenv("ROOT"), FMD_MSG_VERSION)) == NULL) {
		(void) fprintf(stderr, "%s: fmd_msg_init failed: %s\n",
		    argv[0], strerror(errno));
		return (1);
	}

	/*
	 * Test 0: Verify that both fmd_msg_getitem_id and fmd_msg_gettext_id
	 * return NULL and EINVAL for an illegal message code, and NULL
	 * and ENOENT for a valid but not defined message code.
	 */
	s = fmd_msg_getitem_id(h, NULL, "I_AM_NOT_VALID", 0);
	if (s != NULL || errno != EINVAL) {
		(void) fprintf(stderr, "%s: test0 FAIL: illegal code returned "
		    "s = %p, errno = %d\n", argv[0], (void *)s, errno);
		return (1);
	}

	s = fmd_msg_gettext_id(h, NULL, "I_AM_NOT_VALID");
	if (s != NULL || errno != EINVAL) {
		(void) fprintf(stderr, "%s: test0 FAIL: illegal code returned "
		    "s = %p, errno = %d\n", argv[0], (void *)s, errno);
		return (1);
	}

	s = fmd_msg_getitem_id(h, NULL, "I_AM_NOT_HERE-0000-0000", 0);
	if (s != NULL || errno != ENOENT) {
		(void) fprintf(stderr, "%s: test0 FAIL: missing code returned "
		    "s = %p, errno = %d\n", argv[0], (void *)s, errno);
		return (1);
	}

	s = fmd_msg_gettext_id(h, NULL, "I_AM_NOT_HERE-0000-0000");
	if (s != NULL || errno != ENOENT) {
		(void) fprintf(stderr, "%s: test0 FAIL: missing code returned "
		    "s = %p, errno = %d\n", argv[0], (void *)s, errno);
		return (1);
	}

	/*
	 * Test 1: Use fmd_msg_getitem_id to retrieve the item strings for
	 * a known message code without having any actual event handle.
	 */
	for (i = 0; i < FMD_MSG_ITEM_MAX; i++) {
		if ((s = fmd_msg_getitem_id(h, NULL, code, i)) == NULL) {
			(void) fprintf(stderr, "%s: fmd_msg_getitem_id failed "
			    "for %s, item %d: %s\n",
			    argv[0], code, i, strerror(errno));
		}

		(void) printf("code %s item %d = <<%s>>\n", code, i, s);
		free(s);
	}

	/*
	 * Test 2: Use fmd_msg_gettext_id to retrieve the complete message for
	 * a known message code without having any actual event handle.
	 */
	if ((s = fmd_msg_gettext_id(h, NULL, code)) == NULL) {
		(void) fprintf(stderr, "%s: fmd_msg_gettext_id failed for %s: "
		    "%s\n", argv[0], code, strerror(errno));
		return (1);
	}

	(void) printf("%s\n", s);
	free(s);

	/*
	 * Test 3: Use fmd_msg_getitem_nv to retrieve the item strings for
	 * our list.suspect event handle.
	 */
	for (i = 0; i < FMD_MSG_ITEM_MAX; i++) {
		if ((s = fmd_msg_getitem_nv(h, NULL, list, i)) == NULL) {
			(void) fprintf(stderr, "%s: fmd_msg_getitem_nv failed "
			    "for %s, item %d: %s\n",
			    argv[0], code, i, strerror(errno));
		}

		(void) printf("code %s item %d = <<%s>>\n", code, i, s);
		free(s);
	}

	/*
	 * Test 4: Use fmd_msg_getitem_nv to retrieve the complete message for
	 * a known message code using our list.suspect event handle.
	 */
	if ((s = fmd_msg_gettext_nv(h, NULL, list)) == NULL) {
		(void) fprintf(stderr, "%s: fmd_msg_gettext_nv failed for %s: "
		    "%s\n", argv[0], code, strerror(errno));
		return (1);
	}

	(void) printf("%s\n", s);
	free(s);

	/*
	 * Test 5: Use fmd_msg_getitem_nv to retrieve the complete message for
	 * a known message code using our list.suspect event handle, but this
	 * time set the URL to our own customized URL.  Our contrived message
	 * has been designed to exercise the key aspects of the variable
	 * expansion syntax.
	 */
	if (fmd_msg_url_set(h, "http://foo.bar.com/") != 0) {
		(void) fprintf(stderr, "%s: fmd_msg_url_set failed: %s\n",
		    argv[0], strerror(errno));
	}

	if ((s = fmd_msg_gettext_nv(h, NULL, list)) == NULL) {
		(void) fprintf(stderr, "%s: fmd_msg_gettext_nv failed for %s: "
		    "%s\n", argv[0], code, strerror(errno));
		return (1);
	}

	(void) printf("%s\n", s);
	free(s);

	for (i = 0; i < TEST_ARR_SZ; i++)
		nvlist_free(test_arr[i]);
	nvlist_free(fmri);
	nvlist_free(auth);
	nvlist_free(list);

	fmd_msg_fini(h);	/* free library state before dumping core */
	pid = fork();		/* fork into background to not bother make(1) */

	switch (pid) {
	case -1:
		(void) fprintf(stderr, "FAIL (failed to fork)\n");
		return (1);
	case 0:
		abort();
		return (1);
	}

	if (waitpid(pid, &err, 0) == -1) {
		(void) fprintf(stderr, "FAIL (failed to wait for %d: %s)\n",
		    (int)pid, strerror(errno));
		return (1);
	}

	if (WIFSIGNALED(err) == 0 || WTERMSIG(err) != SIGABRT) {
		(void) fprintf(stderr, "FAIL (child did not SIGABRT)\n");
		return (1);
	}

	if (!WCOREDUMP(err)) {
		(void) fprintf(stderr, "FAIL (no core generated)\n");
		return (1);
	}

	(void) fprintf(stderr, "done\n");
	return (0);
}
Ejemplo n.º 20
0
nvlist_t *
cmd_mkboard_fru(fmd_hdl_t *hdl, char *frustr, char *serialstr, char *partstr) {

	char *nac, *nac_name;
	int n, i, len;
	nvlist_t *fru, **hc_list;

	if (frustr == NULL)
		return (NULL);

	if ((nac_name = strstr(frustr, "MB")) == NULL)
		return (NULL);

	len = strlen(nac_name) + 1;

	nac = fmd_hdl_zalloc(hdl, len, FMD_SLEEP);
	(void) strcpy(nac, nac_name);

	n = cmd_count_components(nac, '/');

	fmd_hdl_debug(hdl, "cmd_mkboard_fru: nac=%s components=%d\n", nac, n);

	hc_list = fmd_hdl_zalloc(hdl, sizeof (nvlist_t *)*n, FMD_SLEEP);

	for (i = 0; i < n; i++) {
		(void) nvlist_alloc(&hc_list[i],
		    NV_UNIQUE_NAME|NV_UNIQUE_NAME_TYPE, 0);
	}

	if (cmd_breakup_components(nac, "/", hc_list) < 0) {
		for (i = 0; i < n; i++) {
			if (hc_list[i] != NULL)
			    nvlist_free(hc_list[i]);
		}
		fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
		fmd_hdl_free(hdl, nac, len);
		return (NULL);
	}

	if (nvlist_alloc(&fru, NV_UNIQUE_NAME, 0) != 0) {
		for (i = 0; i < n; i++) {
			if (hc_list[i] != NULL)
			    nvlist_free(hc_list[i]);
		}
		fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
		fmd_hdl_free(hdl, nac, len);
		return (NULL);
	}

	if (nvlist_add_uint8(fru, FM_VERSION, FM_HC_SCHEME_VERSION) != 0 ||
	    nvlist_add_string(fru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC) != 0 ||
	    nvlist_add_string(fru, FM_FMRI_HC_ROOT, "") != 0 ||
	    nvlist_add_uint32(fru, FM_FMRI_HC_LIST_SZ, n) != 0 ||
	    nvlist_add_nvlist_array(fru, FM_FMRI_HC_LIST, hc_list, n) != 0) {
		for (i = 0; i < n; i++) {
			if (hc_list[i] != NULL)
			    nvlist_free(hc_list[i]);
		}
		fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
		fmd_hdl_free(hdl, nac, len);
		nvlist_free(fru);
		return (NULL);
	}

	for (i = 0; i < n; i++) {
		if (hc_list[i] != NULL)
		    nvlist_free(hc_list[i]);
	}
	fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
	fmd_hdl_free(hdl, nac, len);

	if ((serialstr != NULL &&
	    nvlist_add_string(fru, FM_FMRI_HC_SERIAL_ID, serialstr) != 0) ||
	    (partstr != NULL &&
	    nvlist_add_string(fru, FM_FMRI_HC_PART, partstr) != 0)) {
		nvlist_free(fru);
		return (NULL);
	}

	return (fru);
}