Ejemplo n.º 1
0
/*
 * Encodes (packs) DFS information in 'info' into a flat
 * buffer in a name-value format. This function allocates a
 * buffer with appropriate size to contain all the information
 * so the caller MUST free the allocated memory by calling free().
 */
static uint32_t
dfs_root_encode(dfs_info_t *info, char **buf, size_t *bufsz)
{
	dfs_target_t *t;
	nvlist_t *nvl;
	int rc;

	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
		return (ERROR_NOT_ENOUGH_MEMORY);

	rc = nvlist_add_string(nvl, "comment", info->i_comment);
	rc |= nvlist_add_string(nvl, "guid", info->i_guid);
	rc |= nvlist_add_uint32(nvl, "state", info->i_state);
	rc |= nvlist_add_uint32(nvl, "timeout", info->i_timeout);
	rc |= nvlist_add_uint32(nvl, "propflags", info->i_propflags);
	t = info->i_targets;
	rc |= nvlist_add_string(nvl, "t_server", t->t_server);
	rc |= nvlist_add_string(nvl, "t_share", t->t_share);
	rc |= nvlist_add_uint32(nvl, "t_state", t->t_state);
	rc |= nvlist_add_uint32(nvl, "t_priority_class",
	    t->t_priority.p_class);
	rc |= nvlist_add_uint16(nvl, "t_priority_rank",
	    t->t_priority.p_rank);

	if (rc == 0)
		rc = nvlist_pack(nvl, buf, bufsz, NV_ENCODE_NATIVE, 0);

	nvlist_free(nvl);

	return ((rc == 0) ? ERROR_SUCCESS : ERROR_INTERNAL_ERROR);
}
Ejemplo n.º 2
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.º 3
0
static int
be_nvl_add_uint16(nvlist_t *nvl, const char *name, uint16_t val)
{
	assert(nvl != NULL);

	if (nvlist_add_uint16(nvl, name, val) != 0) {
		(void) fprintf(stderr, _("nvlist_add_uint16 failed for "
		    "%s (%hu).\n"), name, val);
		return (1);
	}

	return (0);
}
Ejemplo n.º 4
0
/*
 * Verify a single logpage.  This will do some generic validation and then call
 * the logpage-specific function for further verification.
 */
static int
verify_logpage(ds_scsi_info_t *sip, logpage_validation_entry_t *lp)
{
	scsi_log_header_t *lhp;
	struct scsi_extended_sense sense;
	int buflen;
	int log_length;
	int result = 0;
	uint_t kp, asc, ascq;
	nvlist_t *nvl;

	buflen = MAX_BUFLEN(scsi_log_header_t);
	if ((lhp = calloc(buflen, 1)) == NULL)
		return (scsi_set_errno(sip, EDS_NOMEM));
	bzero(&sense, sizeof (struct scsi_extended_sense));

	nvl = NULL;
	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
	    nvlist_add_nvlist(sip->si_state_logpage, lp->ve_desc, nvl) != 0) {
		nvlist_free(nvl);
		free(lhp);
		return (scsi_set_errno(sip, EDS_NOMEM));
	}
	nvlist_free(nvl);
	result = nvlist_lookup_nvlist(sip->si_state_logpage, lp->ve_desc, &nvl);
	assert(result == 0);

	result = scsi_log_sense(sip, lp->ve_code,
	    PC_CUMULATIVE, (caddr_t)lhp, buflen, &kp, &asc, &ascq);

	if (result == 0) {
		log_length = BE_16(lhp->lh_length);
		if (nvlist_add_uint16(nvl, "length", log_length) != 0) {
			free(lhp);
			return (scsi_set_errno(sip, EDS_NOMEM));
		}

		if (lp->ve_validate(sip, (scsi_log_parameter_header_t *)
		    (((char *)lhp) + sizeof (scsi_log_header_t)),
		    log_length, nvl) != 0) {
			free(lhp);
			return (-1);
		}
	} else {
		printf("failed to load %s log page (KEY=0x%x "
		    "ASC=0x%x ASCQ=0x%x)\n", lp->ve_desc, kp, asc, ascq);
	}

	free(lhp);
	return (0);
}
Ejemplo n.º 5
0
/*
 * Set the named uint16 in the given nvlist_t.
 *
 * @param       attrs
 *              the nvlist_t to search
 *
 * @param       which
 *              the string key for this element in the list
 *
 * @param       val
 *              the value to set
 *
 * @return      0
 *              if successful
 *
 * @return      EINVAL
 *              if there is an invalid argument
 *
 * @return      ENOMEM
 *              if there is insufficient memory
 */
int
set_uint16(
    nvlist_t *attrs,
    char *which,
    uint16_t val)
{
    int error = 0;

    if ((error = nvlist_add_uint16(attrs, which, val)) != 0) {
        volume_set_error(
            gettext("nvlist_add_int16(%s) failed: %d\n"), which, error);
    }

    return (error);
}
Ejemplo n.º 6
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.º 7
0
void
fnvlist_add_uint16(nvlist_t *nvl, const char *name, uint16_t val)
{
	VERIFY0(nvlist_add_uint16(nvl, name, val));
}