int ses2_ctl_common_setprop(ses_plugin_t *sp, ses_node_t *np, ses2_diag_page_t page, nvpair_t *nvp) { ses2_cmn_elem_ctl_impl_t *eip; const char *name; boolean_t v; ASSERT(page == SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS); if ((eip = ses_plugin_ctlpage_lookup(sp, ses_node_snapshot(np), page, 0, np, B_FALSE)) == NULL) return (-1); name = nvpair_name(nvp); (void) nvpair_value_boolean_value(nvp, &v); if (strcmp(name, SES_PROP_SWAP) == 0) eip->seci_rst_swap = !v; else if (strcmp(name, SES_PROP_DISABLED) == 0) eip->seci_disable = v; else if (strcmp(name, SES_PROP_PRDFAIL) == 0) eip->seci_prdfail = v; else ses_panic("Bad property %s", name); return (0); }
static int elem_setprop_cooling(ses_plugin_t *sp, ses_node_t *np, ses2_diag_page_t page, nvpair_t *nvp) { ses2_cooling_ctl_impl_t *cip; const char *name; boolean_t v1; uint64_t v64; if ((cip = ses_plugin_ctlpage_lookup(sp, ses_node_snapshot(np), page, 0, np, B_FALSE)) == NULL) return (-1); name = nvpair_name(nvp); if (strcmp(name, SES_COOLING_PROP_SPEED_CODE) == 0) { (void) nvpair_value_uint64(nvp, &v64); cip->scci_requested_speed_code = v64; return (0); } (void) nvpair_value_boolean_value(nvp, &v1); if (strcmp(name, SES_PROP_IDENT) == 0) cip->scci_rqst_ident = v1; else if (strcmp(name, SES_PROP_REQUESTED_ON) == 0) cip->scci_rqst_on = v1; else if (strcmp(name, SES_PROP_FAIL) == 0) cip->scci_rqst_fail = v1; else ses_panic("Bad property %s", name); return (0); }
boolean_t fnvpair_value_boolean_value(nvpair_t *nvp) { boolean_t rv; VERIFY0(nvpair_value_boolean_value(nvp, &rv)); return (rv); }
static int elem_setprop_esc(ses_plugin_t *sp, ses_node_t *np, ses2_diag_page_t page, nvpair_t *nvp) { ses2_controller_ctl_impl_t *cip; const char *name; boolean_t v; if ((cip = ses_plugin_ctlpage_lookup(sp, ses_node_snapshot(np), page, 0, np, B_FALSE)) == NULL) return (-1); name = nvpair_name(nvp); (void) nvpair_value_boolean_value(nvp, &v); if (strcmp(name, SES_PROP_FAIL) == 0) cip->scci_rqst_fail = v; else if (strcmp(name, SES_PROP_IDENT) == 0) cip->scci_rqst_ident = v; else if (strcmp(name, SES_ESC_PROP_SELECT) == 0) cip->scci_select_element = v; else ses_panic("Bad property %s", name); return (0); }
static int elem_setprop_psu(ses_plugin_t *sp, ses_node_t *np, ses2_diag_page_t page, nvpair_t *nvp) { ses2_psu_ctl_impl_t *pip; const char *name; boolean_t v; if ((pip = ses_plugin_ctlpage_lookup(sp, ses_node_snapshot(np), page, 0, np, B_FALSE)) == NULL) return (-1); name = nvpair_name(nvp); (void) nvpair_value_boolean_value(nvp, &v); if (strcmp(name, SES_PROP_IDENT) == 0) pip->spci_rqst_ident = v; else if (strcmp(name, SES_PROP_REQUESTED_ON) == 0) pip->spci_rqst_on = v; else if (strcmp(name, SES_PROP_FAIL) == 0) pip->spci_rqst_fail = v; else ses_panic("Bad property %s", name); return (0); }
static int elem_setprop_lang(ses_plugin_t *sp, ses_node_t *np, ses2_diag_page_t page, nvpair_t *nvp) { ses2_lang_ctl_impl_t *lip; const char *name; boolean_t v1; uint64_t v64; if ((lip = ses_plugin_ctlpage_lookup(sp, ses_node_snapshot(np), page, 0, np, B_FALSE)) == NULL) return (-1); name = nvpair_name(nvp); if (strcmp(name, SES_LANG_PROP_LANGCODE) == 0) { (void) nvpair_value_uint64(nvp, &v64); SCSI_WRITE16(&lip->slci_language_code, v64); return (0); } (void) nvpair_value_boolean_value(nvp, &v1); if (strcmp(name, SES_PROP_IDENT) == 0) lip->slci_rqst_ident = v1; else ses_panic("Bad property %s", name); return (0); }
static int elem_setprop_arraydev(ses_plugin_t *sp, ses_node_t *np, ses2_diag_page_t page, nvpair_t *nvp) { ses2_array_device_ctl_impl_t *aip; const char *name; boolean_t v; if ((aip = ses_plugin_ctlpage_lookup(sp, ses_node_snapshot(np), page, 0, np, B_FALSE)) == NULL) return (-1); name = nvpair_name(nvp); (void) nvpair_value_boolean_value(nvp, &v); if (strcmp(name, SES_AD_PROP_RR_ABORT) == 0) aip->sadci_rqst_rr_abort = v; else if (strcmp(name, SES_AD_PROP_REBUILD) == 0) aip->sadci_rqst_rebuild = v; else if (strcmp(name, SES_AD_PROP_IN_FAILED_ARRAY) == 0) aip->sadci_rqst_in_failed_array = v; else if (strcmp(name, SES_AD_PROP_IN_CRIT_ARRAY) == 0) aip->sadci_rqst_in_crit_array = v; else if (strcmp(name, SES_AD_PROP_CONS_CHK) == 0) aip->sadci_rqst_cons_check = v; else if (strcmp(name, SES_AD_PROP_HOT_SPARE) == 0) aip->sadci_rqst_hot_spare = v; else if (strcmp(name, SES_AD_PROP_RSVD_DEVICE) == 0) aip->sadci_rqst_rsvd_device = v; else if (strcmp(name, SES_PROP_IDENT) == 0) aip->sadci_rqst_ident = v; else if (strcmp(name, SES_PROP_RMV) == 0) aip->sadci_rqst_remove = v; else if (strcmp(name, SES_DEV_PROP_READY_TO_INSERT) == 0) aip->sadci_rqst_insert = v; else if (strcmp(name, SES_DEV_PROP_REQ_MISSING) == 0) aip->sadci_rqst_missing = v; else if (strcmp(name, SES_DEV_PROP_DO_NOT_REMOVE) == 0) aip->sadci_do_not_remove = v; else if (strcmp(name, SES_DEV_PROP_REQ_ACTIVE) == 0) aip->sadci_rqst_active = v; else if (strcmp(name, SES_DEV_PROP_BYP_B) == 0) aip->sadci_enable_byp_b = v; else if (strcmp(name, SES_DEV_PROP_BYP_A) == 0) aip->sadci_enable_byp_a = v; else if (strcmp(name, SES_PROP_OFF) == 0) aip->sadci_device_off = v; else if (strcmp(name, SES_DEV_PROP_FAULT_RQSTD) == 0) aip->sadci_rqst_fault = v; else ses_panic("Bad property %s", name); return (0); }
static PyObject * nvl2py(nvlist_t *nvl) { PyObject *pyo; nvpair_t *nvp; pyo = PyDict_New(); for (nvp = nvlist_next_nvpair(nvl, NULL); nvp; nvp = nvlist_next_nvpair(nvl, nvp)) { PyObject *pyval; char *sval; uint64_t ival; boolean_t bval; nvlist_t *nval; switch (nvpair_type(nvp)) { case DATA_TYPE_STRING: (void) nvpair_value_string(nvp, &sval); pyval = Py_BuildValue("s", sval); break; case DATA_TYPE_UINT64: (void) nvpair_value_uint64(nvp, &ival); pyval = Py_BuildValue("K", ival); break; case DATA_TYPE_NVLIST: (void) nvpair_value_nvlist(nvp, &nval); pyval = nvl2py(nval); break; case DATA_TYPE_BOOLEAN: Py_INCREF(Py_None); pyval = Py_None; break; case DATA_TYPE_BOOLEAN_VALUE: (void) nvpair_value_boolean_value(nvp, &bval); pyval = Py_BuildValue("i", bval); break; default: PyErr_SetNone(PyExc_ValueError); Py_DECREF(pyo); return (NULL); } PyDict_SetItemString(pyo, nvpair_name(nvp), pyval); Py_DECREF(pyval); } return (pyo); }
nvlist_t * sysattr_list(char *cmd, int fd, char *fname) { boolean_t value; data_type_t type; nvlist_t *response; nvpair_t *pair; f_attr_t fattr; char *name; if (fgetattr(fd, XATTR_VIEW_READWRITE, &response) != 0) { (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "%s: %s: fgetattr failed\n"), cmd, fname); return (NULL); } pair = NULL; while ((pair = nvlist_next_nvpair(response, pair)) != NULL) { name = nvpair_name(pair); if (name != NULL) fattr = name_to_attr(name); else return (response); type = nvpair_type(pair); switch (type) { case DATA_TYPE_BOOLEAN_VALUE: if (nvpair_value_boolean_value(pair, &value) != 0) { (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "%s " "nvpair_value_boolean_value " "failed\n"), cmd); continue; } if (value && fattr != F_ARCHIVE && fattr != F_AV_MODIFIED) return (response); break; case DATA_TYPE_UINT64_ARRAY: if (fattr != F_CRTIME) return (response); break; case DATA_TYPE_NVLIST: default: return (response); } } nvlist_free(response); return (NULL); }
static int elem_setprop_device(ses_plugin_t *sp, ses_node_t *np, ses2_diag_page_t page, nvpair_t *nvp) { ses2_device_ctl_impl_t *dip; const char *name; boolean_t v; if ((dip = ses_plugin_ctlpage_lookup(sp, ses_node_snapshot(np), page, 0, np, B_FALSE)) == NULL) return (-1); name = nvpair_name(nvp); (void) nvpair_value_boolean_value(nvp, &v); if (strcmp(name, SES_PROP_IDENT) == 0) dip->sdci_rqst_ident = v; else if (strcmp(name, SES_PROP_RMV) == 0) dip->sdci_rqst_remove = v; else if (strcmp(name, SES_DEV_PROP_READY_TO_INSERT) == 0) dip->sdci_rqst_insert = v; else if (strcmp(name, SES_DEV_PROP_REQ_MISSING) == 0) dip->sdci_rqst_missing = v; else if (strcmp(name, SES_DEV_PROP_DO_NOT_REMOVE) == 0) dip->sdci_do_not_remove = v; else if (strcmp(name, SES_DEV_PROP_REQ_ACTIVE) == 0) dip->sdci_rqst_active = v; else if (strcmp(name, SES_DEV_PROP_BYP_B) == 0) dip->sdci_enable_byp_b = v; else if (strcmp(name, SES_DEV_PROP_BYP_A) == 0) dip->sdci_enable_byp_a = v; else if (strcmp(name, SES_PROP_OFF) == 0) dip->sdci_device_off = v; else if (strcmp(name, SES_DEV_PROP_FAULT_RQSTD) == 0) dip->sdci_rqst_fault = v; else ses_panic("Bad property %s", name); return (0); }
static int elem_setprop_display(ses_plugin_t *sp, ses_node_t *np, ses2_diag_page_t page, nvpair_t *nvp) { ses2_display_ctl_impl_t *dip; const char *name; boolean_t v1; uint16_t v16; uint64_t v64; if ((dip = ses_plugin_ctlpage_lookup(sp, ses_node_snapshot(np), page, 0, np, B_FALSE)) == NULL) return (-1); name = nvpair_name(nvp); if (strcmp(name, SES_DPY_PROP_MODE) == 0) { (void) nvpair_value_uint64(nvp, &v64); dip->sdci_display_mode = v64; return (0); } else if (strcmp(name, SES_DPY_PROP_CHAR) == 0) { (void) nvpair_value_uint16(nvp, &v16); SCSI_WRITE16(&dip->sdci_display_character, v16); return (0); } (void) nvpair_value_boolean_value(nvp, &v1); if (strcmp(name, SES_PROP_FAIL) == 0) dip->sdci_rqst_fail = v1; else if (strcmp(name, SES_PROP_IDENT) == 0) dip->sdci_rqst_ident = v1; else ses_panic("Bad property %s", name); return (0); }
static int elem_setprop_alarm(ses_plugin_t *sp, ses_node_t *np, ses2_diag_page_t page, nvpair_t *nvp) { ses2_alarm_ctl_impl_t *aip; const char *name; boolean_t v; if ((aip = ses_plugin_ctlpage_lookup(sp, ses_node_snapshot(np), page, 0, np, B_FALSE)) == NULL) return (-1); name = nvpair_name(nvp); (void) nvpair_value_boolean_value(nvp, &v); if (strcmp(name, SES_PROP_FAIL) == 0) aip->saci_rqst_fail = v; else if (strcmp(name, SES_PROP_IDENT) == 0) aip->saci_rqst_ident = v; else if (strcmp(name, SES_ALARM_PROP_UNRECOV) == 0) aip->saci_unrecov = v; else if (strcmp(name, SES_ALARM_PROP_CRIT) == 0) aip->saci_crit = v; else if (strcmp(name, SES_ALARM_PROP_NONCRIT) == 0) aip->saci_noncrit = v; else if (strcmp(name, SES_ALARM_PROP_INFO) == 0) aip->saci_info = v; else if (strcmp(name, SES_ALARM_PROP_REMIND) == 0) aip->saci_set_remind = v; else if (strcmp(name, SES_ALARM_PROP_MUTED) == 0) aip->saci_set_mute = v; else ses_panic("Bad property %s", name); return (0); }
/* * Convert the nvpair [nvp] to a string which is added to the environment * of the child process. * Return 0 on success, -1 on error. * * FIXME: Refactor with cmd/zpool/zpool_main.c:zpool_do_events_nvprint()? */ static void _zed_event_add_nvpair(uint64_t eid, zed_strings_t *zsp, nvpair_t *nvp) { const char *name; data_type_t type; char buf[4096]; int buflen; int n; char *p; const char *q; const char *fmt; boolean_t b; double d; uint8_t i8; uint16_t i16; uint32_t i32; uint64_t i64; char *str; assert(zsp != NULL); assert(nvp != NULL); name = nvpair_name(nvp); type = nvpair_type(nvp); buflen = sizeof (buf); /* Copy NAME prefix for ZED zevent namespace. */ n = strlcpy(buf, ZEVENT_VAR_PREFIX, sizeof (buf)); if (n >= sizeof (buf)) { zed_log_msg(LOG_WARNING, "Failed to convert nvpair \"%s\" for eid=%llu: %s", name, eid, "Exceeded buffer size"); return; } buflen -= n; p = buf + n; /* Convert NAME to alphanumeric uppercase. */ for (q = name; *q && (buflen > 0); q++) { *p++ = isalnum(*q) ? toupper(*q) : '_'; buflen--; } /* Separate NAME from VALUE. */ if (buflen > 0) { *p++ = '='; buflen--; } *p = '\0'; /* Convert VALUE. */ switch (type) { case DATA_TYPE_BOOLEAN: n = snprintf(p, buflen, "%s", "1"); break; case DATA_TYPE_BOOLEAN_VALUE: (void) nvpair_value_boolean_value(nvp, &b); n = snprintf(p, buflen, "%s", b ? "1" : "0"); break; case DATA_TYPE_BYTE: (void) nvpair_value_byte(nvp, &i8); n = snprintf(p, buflen, "%d", i8); break; case DATA_TYPE_INT8: (void) nvpair_value_int8(nvp, (int8_t *) &i8); n = snprintf(p, buflen, "%d", i8); break; case DATA_TYPE_UINT8: (void) nvpair_value_uint8(nvp, &i8); n = snprintf(p, buflen, "%u", i8); break; case DATA_TYPE_INT16: (void) nvpair_value_int16(nvp, (int16_t *) &i16); n = snprintf(p, buflen, "%d", i16); break; case DATA_TYPE_UINT16: (void) nvpair_value_uint16(nvp, &i16); n = snprintf(p, buflen, "%u", i16); break; case DATA_TYPE_INT32: (void) nvpair_value_int32(nvp, (int32_t *) &i32); n = snprintf(p, buflen, "%d", i32); break; case DATA_TYPE_UINT32: (void) nvpair_value_uint32(nvp, &i32); n = snprintf(p, buflen, "%u", i32); break; case DATA_TYPE_INT64: (void) nvpair_value_int64(nvp, (int64_t *) &i64); n = snprintf(p, buflen, "%lld", (longlong_t) i64); break; case DATA_TYPE_UINT64: (void) nvpair_value_uint64(nvp, &i64); fmt = _zed_event_value_is_hex(name) ? "0x%.16llX" : "%llu"; n = snprintf(p, buflen, fmt, (u_longlong_t) i64); break; case DATA_TYPE_DOUBLE: (void) nvpair_value_double(nvp, &d); n = snprintf(p, buflen, "%g", d); break; case DATA_TYPE_HRTIME: (void) nvpair_value_hrtime(nvp, (hrtime_t *) &i64); n = snprintf(p, buflen, "%llu", (u_longlong_t) i64); break; case DATA_TYPE_NVLIST: /* FIXME */ n = snprintf(p, buflen, "%s", "_NOT_IMPLEMENTED_"); break; case DATA_TYPE_STRING: (void) nvpair_value_string(nvp, &str); n = snprintf(p, buflen, "%s", (str ? str : "<NULL>")); break; case DATA_TYPE_BOOLEAN_ARRAY: /* FIXME */ n = snprintf(p, buflen, "%s", "_NOT_IMPLEMENTED_"); break; case DATA_TYPE_BYTE_ARRAY: /* FIXME */ n = snprintf(p, buflen, "%s", "_NOT_IMPLEMENTED_"); break; case DATA_TYPE_INT8_ARRAY: n = _zed_event_convert_int8_array(p, buflen, nvp); break; case DATA_TYPE_UINT8_ARRAY: n = _zed_event_convert_uint8_array(p, buflen, nvp); break; case DATA_TYPE_INT16_ARRAY: n = _zed_event_convert_int16_array(p, buflen, nvp); break; case DATA_TYPE_UINT16_ARRAY: n = _zed_event_convert_uint16_array(p, buflen, nvp); break; case DATA_TYPE_INT32_ARRAY: n = _zed_event_convert_int32_array(p, buflen, nvp); break; case DATA_TYPE_UINT32_ARRAY: n = _zed_event_convert_uint32_array(p, buflen, nvp); break; case DATA_TYPE_INT64_ARRAY: n = _zed_event_convert_int64_array(p, buflen, nvp); break; case DATA_TYPE_UINT64_ARRAY: fmt = _zed_event_value_is_hex(name) ? "0x%.16llX " : "%llu "; n = _zed_event_convert_uint64_array(p, buflen, nvp, fmt); break; case DATA_TYPE_STRING_ARRAY: n = _zed_event_convert_string_array(p, buflen, nvp); break; case DATA_TYPE_NVLIST_ARRAY: /* FIXME */ n = snprintf(p, buflen, "%s", "_NOT_IMPLEMENTED_"); break; default: zed_log_msg(LOG_WARNING, "Failed to convert nvpair \"%s\" for eid=%llu: " "Unrecognized type=%u", name, eid, (unsigned int) type); return; } if ((n < 0) || (n >= sizeof (buf))) { zed_log_msg(LOG_WARNING, "Failed to convert nvpair \"%s\" for eid=%llu: %s", name, eid, "Exceeded buffer size"); return; } if (zed_strings_add(zsp, buf) < 0) { zed_log_msg(LOG_WARNING, "Failed to convert nvpair \"%s\" for eid=%llu: %s", name, eid, strerror(ENOMEM)); return; } }
/* * Determine if string 'value' matches 'nvp' value. The 'value' string is * converted, depending on the type of 'nvp', prior to match. For numeric * types, a radix independent sscanf conversion of 'value' is used. If 'nvp' * is an array type, 'ai' is the index into the array against which we are * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass * in a regex_t compilation of value in 'value_regex' to trigger regular * expression string match instead of simple strcmp(). * * Return 1 on match, 0 on no-match, and -1 on error. If the error is * related to value syntax error and 'ep' is non-NULL, *ep will point into * the 'value' string at the location where the error exists. * * NOTE: It may be possible to move the non-regex_t version of this into * common code used by library/kernel/boot. */ int nvpair_value_match_regex(nvpair_t *nvp, int ai, char *value, regex_t *value_regex, char **ep) { char *evalue; uint_t a_len; int sr; if (ep) *ep = NULL; if ((nvp == NULL) || (value == NULL)) return (-1); /* error fail match - invalid args */ /* make sure array and index combination make sense */ if ((nvpair_type_is_array(nvp) && (ai < 0)) || (!nvpair_type_is_array(nvp) && (ai >= 0))) return (-1); /* error fail match - bad index */ /* non-string values should be single 'chunk' */ if ((nvpair_type(nvp) != DATA_TYPE_STRING) && (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) { value += strspn(value, " \t"); evalue = value + strcspn(value, " \t"); if (*evalue) { if (ep) *ep = evalue; return (-1); /* error fail match - syntax */ } } sr = EOF; switch (nvpair_type(nvp)) { case DATA_TYPE_STRING: { char *val; /* check string value for match */ if (nvpair_value_string(nvp, &val) == 0) { if (value_regex) { if (regexec(value_regex, val, (size_t)0, NULL, 0) == 0) return (1); /* match */ } else { if (strcmp(value, val) == 0) return (1); /* match */ } } break; } case DATA_TYPE_STRING_ARRAY: { char **val_array; /* check indexed string value of array for match */ if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) && (ai < a_len)) { if (value_regex) { if (regexec(value_regex, val_array[ai], (size_t)0, NULL, 0) == 0) return (1); } else { if (strcmp(value, val_array[ai]) == 0) return (1); } } break; } case DATA_TYPE_BYTE: { uchar_t val, val_arg; /* scanf uchar_t from value and check for match */ sr = sscanf(value, "%c", &val_arg); if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_BYTE_ARRAY: { uchar_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%c", &val_arg); if ((sr == 1) && (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_INT8: { int8_t val, val_arg; /* scanf int8_t from value and check for match */ sr = sscanf(value, "%"SCNi8, &val_arg); if ((sr == 1) && (nvpair_value_int8(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_INT8_ARRAY: { int8_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi8, &val_arg); if ((sr == 1) && (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_UINT8: { uint8_t val, val_arg; /* scanf uint8_t from value and check for match */ sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint8(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_UINT8_ARRAY: { uint8_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_INT16: { int16_t val, val_arg; /* scanf int16_t from value and check for match */ sr = sscanf(value, "%"SCNi16, &val_arg); if ((sr == 1) && (nvpair_value_int16(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_INT16_ARRAY: { int16_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi16, &val_arg); if ((sr == 1) && (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_UINT16: { uint16_t val, val_arg; /* scanf uint16_t from value and check for match */ sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint16(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_UINT16_ARRAY: { uint16_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_INT32: { int32_t val, val_arg; /* scanf int32_t from value and check for match */ sr = sscanf(value, "%"SCNi32, &val_arg); if ((sr == 1) && (nvpair_value_int32(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_INT32_ARRAY: { int32_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi32, &val_arg); if ((sr == 1) && (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_UINT32: { uint32_t val, val_arg; /* scanf uint32_t from value and check for match */ sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint32(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_UINT32_ARRAY: { uint32_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_INT64: { int64_t val, val_arg; /* scanf int64_t from value and check for match */ sr = sscanf(value, "%"SCNi64, &val_arg); if ((sr == 1) && (nvpair_value_int64(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_INT64_ARRAY: { int64_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi64, &val_arg); if ((sr == 1) && (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_UINT64: { uint64_t val_arg, val; /* scanf uint64_t from value and check for match */ sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint64(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_UINT64_ARRAY: { uint64_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_BOOLEAN_VALUE: { boolean_t val, val_arg; /* scanf boolean_t from value and check for match */ sr = sscanf(value, "%"SCNi32, &val_arg); if ((sr == 1) && (nvpair_value_boolean_value(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_BOOLEAN_ARRAY: { boolean_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi32, &val_arg); if ((sr == 1) && (nvpair_value_boolean_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_HRTIME: case DATA_TYPE_NVLIST: case DATA_TYPE_NVLIST_ARRAY: case DATA_TYPE_BOOLEAN: case DATA_TYPE_DOUBLE: case DATA_TYPE_UNKNOWN: default: /* * unknown/unsupported data type */ return (-1); /* error fail match */ } /* * check to see if sscanf failed conversion, return approximate * pointer to problem */ if (sr != 1) { if (ep) *ep = value; return (-1); /* error fail match - syntax */ } return (0); /* fail match */ }
/* ARGSUSED */ static int xattr_file_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct) { int error = 0; char *buf; char *domain; uint32_t rid; ssize_t size = uiop->uio_resid; nvlist_t *nvp; nvpair_t *pair = NULL; vnode_t *ppvp; xvattr_t xvattr; xoptattr_t *xoap = NULL; /* Pointer to optional attributes */ if (vfs_has_feature(vp->v_vfsp, VFSFT_XVATTR) == 0) return (EINVAL); /* * Validate file offset and size. */ if (uiop->uio_loffset < (offset_t)0) return (EINVAL); if (size == 0) return (EINVAL); xva_init(&xvattr); if ((xoap = xva_getxoptattr(&xvattr)) == NULL) { return (EINVAL); } /* * Copy and unpack the nvlist */ buf = kmem_alloc(size, KM_SLEEP); if (uiomove((caddr_t)buf, size, UIO_WRITE, uiop)) { return (EFAULT); } if (nvlist_unpack(buf, size, &nvp, KM_SLEEP) != 0) { kmem_free(buf, size); uiop->uio_resid = size; return (EINVAL); } kmem_free(buf, size); /* * Fasttrack empty writes (nvlist with no nvpairs) */ if (nvlist_next_nvpair(nvp, NULL) == 0) return (0); ppvp = gfs_file_parent(gfs_file_parent(vp)); while (pair = nvlist_next_nvpair(nvp, pair)) { data_type_t type; f_attr_t attr; boolean_t value; uint64_t *time, *times; uint_t elem, nelems; nvlist_t *nvp_sid; uint8_t *scanstamp; /* * Validate the name and type of each attribute. * Log any unknown names and continue. This will * help if additional attributes are added later. */ type = nvpair_type(pair); if ((attr = name_to_attr(nvpair_name(pair))) == F_ATTR_INVAL) { cmn_err(CE_WARN, "Unknown attribute %s", nvpair_name(pair)); continue; } /* * Verify nvlist type matches required type and view is OK */ if (type != attr_to_data_type(attr) || (attr_to_xattr_view(attr) == XATTR_VIEW_READONLY)) { nvlist_free(nvp); return (EINVAL); } /* * For OWNERSID/GROUPSID make sure the target * file system support ephemeral ID's */ if ((attr == F_OWNERSID || attr == F_GROUPSID) && (!(vp->v_vfsp->vfs_flag & VFS_XID))) { nvlist_free(nvp); return (EINVAL); } /* * Retrieve data from nvpair */ switch (type) { case DATA_TYPE_BOOLEAN_VALUE: if (nvpair_value_boolean_value(pair, &value)) { nvlist_free(nvp); return (EINVAL); } break; case DATA_TYPE_UINT64_ARRAY: if (nvpair_value_uint64_array(pair, ×, &nelems)) { nvlist_free(nvp); return (EINVAL); } break; case DATA_TYPE_NVLIST: if (nvpair_value_nvlist(pair, &nvp_sid)) { nvlist_free(nvp); return (EINVAL); } break; case DATA_TYPE_UINT8_ARRAY: if (nvpair_value_uint8_array(pair, &scanstamp, &nelems)) { nvlist_free(nvp); return (EINVAL); } break; default: nvlist_free(nvp); return (EINVAL); } switch (attr) { /* * If we have several similar optional attributes to * process then we should do it all together here so that * xoap and the requested bitmap can be set in one place. */ case F_READONLY: XVA_SET_REQ(&xvattr, XAT_READONLY); xoap->xoa_readonly = value; break; case F_HIDDEN: XVA_SET_REQ(&xvattr, XAT_HIDDEN); xoap->xoa_hidden = value; break; case F_SYSTEM: XVA_SET_REQ(&xvattr, XAT_SYSTEM); xoap->xoa_system = value; break; case F_ARCHIVE: XVA_SET_REQ(&xvattr, XAT_ARCHIVE); xoap->xoa_archive = value; break; case F_IMMUTABLE: XVA_SET_REQ(&xvattr, XAT_IMMUTABLE); xoap->xoa_immutable = value; break; case F_NOUNLINK: XVA_SET_REQ(&xvattr, XAT_NOUNLINK); xoap->xoa_nounlink = value; break; case F_APPENDONLY: XVA_SET_REQ(&xvattr, XAT_APPENDONLY); xoap->xoa_appendonly = value; break; case F_NODUMP: XVA_SET_REQ(&xvattr, XAT_NODUMP); xoap->xoa_nodump = value; break; case F_AV_QUARANTINED: XVA_SET_REQ(&xvattr, XAT_AV_QUARANTINED); xoap->xoa_av_quarantined = value; break; case F_AV_MODIFIED: XVA_SET_REQ(&xvattr, XAT_AV_MODIFIED); xoap->xoa_av_modified = value; break; case F_CRTIME: XVA_SET_REQ(&xvattr, XAT_CREATETIME); time = (uint64_t *)&(xoap->xoa_createtime); for (elem = 0; elem < nelems; elem++) *time++ = times[elem]; break; case F_OWNERSID: case F_GROUPSID: if (nvlist_lookup_string(nvp_sid, SID_DOMAIN, &domain) || nvlist_lookup_uint32(nvp_sid, SID_RID, &rid)) { nvlist_free(nvp); return (EINVAL); } /* * Now map domain+rid to ephemeral id's * * If mapping fails, then the uid/gid will * be set to UID_NOBODY by Winchester. */ if (attr == F_OWNERSID) { (void) kidmap_getuidbysid(crgetzone(cr), domain, rid, &xvattr.xva_vattr.va_uid); xvattr.xva_vattr.va_mask |= AT_UID; } else { (void) kidmap_getgidbysid(crgetzone(cr), domain, rid, &xvattr.xva_vattr.va_gid); xvattr.xva_vattr.va_mask |= AT_GID; } break; case F_AV_SCANSTAMP: if (ppvp->v_type == VREG) { XVA_SET_REQ(&xvattr, XAT_AV_SCANSTAMP); (void) memcpy(xoap->xoa_av_scanstamp, scanstamp, nelems); } else { nvlist_free(nvp); return (EINVAL); } break; case F_REPARSE: XVA_SET_REQ(&xvattr, XAT_REPARSE); xoap->xoa_reparse = value; break; case F_OFFLINE: XVA_SET_REQ(&xvattr, XAT_OFFLINE); xoap->xoa_offline = value; break; case F_SPARSE: XVA_SET_REQ(&xvattr, XAT_SPARSE); xoap->xoa_sparse = value; break; default: break; } } ppvp = gfs_file_parent(gfs_file_parent(vp)); error = VOP_SETATTR(ppvp, &xvattr.xva_vattr, 0, cr, ct); if (error) uiop->uio_resid = size; nvlist_free(nvp); return (error); }
/* * Convert the nvpair [nvp] to a string which is added to the environment * of the child process. * Return 0 on success, -1 on error. * * FIXME: Refactor with cmd/zpool/zpool_main.c:zpool_do_events_nvprint()? */ static void _zed_event_add_nvpair(uint64_t eid, zed_strings_t *zsp, nvpair_t *nvp) { const char *name; data_type_t type; const char *prefix = ZEVENT_VAR_PREFIX; boolean_t b; double d; uint8_t i8; uint16_t i16; uint32_t i32; uint64_t i64; char *str; assert(zsp != NULL); assert(nvp != NULL); name = nvpair_name(nvp); type = nvpair_type(nvp); switch (type) { case DATA_TYPE_BOOLEAN: _zed_event_add_var(eid, zsp, prefix, name, "%s", "1"); break; case DATA_TYPE_BOOLEAN_VALUE: (void) nvpair_value_boolean_value(nvp, &b); _zed_event_add_var(eid, zsp, prefix, name, "%s", b ? "1" : "0"); break; case DATA_TYPE_BYTE: (void) nvpair_value_byte(nvp, &i8); _zed_event_add_var(eid, zsp, prefix, name, "%d", i8); break; case DATA_TYPE_INT8: (void) nvpair_value_int8(nvp, (int8_t *) &i8); _zed_event_add_var(eid, zsp, prefix, name, "%d", i8); break; case DATA_TYPE_UINT8: (void) nvpair_value_uint8(nvp, &i8); _zed_event_add_var(eid, zsp, prefix, name, "%u", i8); break; case DATA_TYPE_INT16: (void) nvpair_value_int16(nvp, (int16_t *) &i16); _zed_event_add_var(eid, zsp, prefix, name, "%d", i16); break; case DATA_TYPE_UINT16: (void) nvpair_value_uint16(nvp, &i16); _zed_event_add_var(eid, zsp, prefix, name, "%u", i16); break; case DATA_TYPE_INT32: (void) nvpair_value_int32(nvp, (int32_t *) &i32); _zed_event_add_var(eid, zsp, prefix, name, "%d", i32); break; case DATA_TYPE_UINT32: (void) nvpair_value_uint32(nvp, &i32); _zed_event_add_var(eid, zsp, prefix, name, "%u", i32); break; case DATA_TYPE_INT64: (void) nvpair_value_int64(nvp, (int64_t *) &i64); _zed_event_add_var(eid, zsp, prefix, name, "%lld", (longlong_t) i64); break; case DATA_TYPE_UINT64: (void) nvpair_value_uint64(nvp, &i64); _zed_event_add_var(eid, zsp, prefix, name, (_zed_event_value_is_hex(name) ? "0x%.16llX" : "%llu"), (u_longlong_t) i64); /* * shadow readable strings for vdev state pairs */ if (strcmp(name, FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE) == 0 || strcmp(name, FM_EREPORT_PAYLOAD_ZFS_VDEV_LASTSTATE) == 0) { char alt[32]; (void) snprintf(alt, sizeof (alt), "%s_str", name); _zed_event_add_var(eid, zsp, prefix, alt, "%s", zpool_state_to_name(i64, VDEV_AUX_NONE)); } break; case DATA_TYPE_DOUBLE: (void) nvpair_value_double(nvp, &d); _zed_event_add_var(eid, zsp, prefix, name, "%g", d); break; case DATA_TYPE_HRTIME: (void) nvpair_value_hrtime(nvp, (hrtime_t *) &i64); _zed_event_add_var(eid, zsp, prefix, name, "%llu", (u_longlong_t) i64); break; case DATA_TYPE_NVLIST: _zed_event_add_var(eid, zsp, prefix, name, "%s", "_NOT_IMPLEMENTED_"); /* FIXME */ break; case DATA_TYPE_STRING: (void) nvpair_value_string(nvp, &str); _zed_event_add_var(eid, zsp, prefix, name, "%s", (str ? str : "<NULL>")); break; case DATA_TYPE_BOOLEAN_ARRAY: _zed_event_add_var(eid, zsp, prefix, name, "%s", "_NOT_IMPLEMENTED_"); /* FIXME */ break; case DATA_TYPE_BYTE_ARRAY: _zed_event_add_var(eid, zsp, prefix, name, "%s", "_NOT_IMPLEMENTED_"); /* FIXME */ break; case DATA_TYPE_INT8_ARRAY: _zed_event_add_int8_array(eid, zsp, prefix, nvp); break; case DATA_TYPE_UINT8_ARRAY: _zed_event_add_uint8_array(eid, zsp, prefix, nvp); break; case DATA_TYPE_INT16_ARRAY: _zed_event_add_int16_array(eid, zsp, prefix, nvp); break; case DATA_TYPE_UINT16_ARRAY: _zed_event_add_uint16_array(eid, zsp, prefix, nvp); break; case DATA_TYPE_INT32_ARRAY: _zed_event_add_int32_array(eid, zsp, prefix, nvp); break; case DATA_TYPE_UINT32_ARRAY: _zed_event_add_uint32_array(eid, zsp, prefix, nvp); break; case DATA_TYPE_INT64_ARRAY: _zed_event_add_int64_array(eid, zsp, prefix, nvp); break; case DATA_TYPE_UINT64_ARRAY: _zed_event_add_uint64_array(eid, zsp, prefix, nvp); break; case DATA_TYPE_STRING_ARRAY: _zed_event_add_string_array(eid, zsp, prefix, nvp); break; case DATA_TYPE_NVLIST_ARRAY: _zed_event_add_var(eid, zsp, prefix, name, "%s", "_NOT_IMPLEMENTED_"); /* FIXME */ break; default: errno = EINVAL; zed_log_msg(LOG_WARNING, "Failed to convert nvpair \"%s\" for eid=%llu: " "Unrecognized type=%u", name, eid, (unsigned int) type); break; } }
/*ARGSUSED*/ static int net_notify_event(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags, char **errorp, nvlist_t *nvl, rcm_info_t **depend_info) { nvpair_t *nvp = NULL; uint64_t id64 = (uint64_t)DATALINK_INVALID_LINKID; boolean_t reconfigured = B_FALSE; rcm_log_message(RCM_TRACE1, _("NET: notify_event(%s)\n"), rsrc); if (strcmp(rsrc, RCM_RESOURCE_PHYSLINK_NEW) != 0) { rcm_log_message(RCM_INFO, _("NET: unrecognized event for %s\n"), rsrc); errno = EINVAL; return (RCM_FAILURE); } /* Update cache to reflect latest physical links */ update_cache(hd); while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { if (strcmp(nvpair_name(nvp), RCM_NV_RECONFIGURED) == 0) { if (nvpair_value_boolean_value(nvp, &reconfigured) != 0) { rcm_log_message(RCM_INFO, _("NET: unrecognized %s event data\n"), RCM_NV_RECONFIGURED); errno = EINVAL; return (RCM_FAILURE); } rcm_log_message(RCM_TRACE1, "NET: %s event data (%sreconfiguration)\n", RCM_NV_RECONFIGURED, reconfigured ? "" : "not "); } if (strcmp(nvpair_name(nvp), RCM_NV_LINKID) == 0) { if (nvpair_value_uint64(nvp, &id64) != 0) { rcm_log_message(RCM_INFO, _("NET: unrecognized %s event data\n"), RCM_NV_LINKID); errno = EINVAL; return (RCM_FAILURE); } rcm_log_message(RCM_TRACE1, "NET: %s event data (linkid %d)\n", RCM_NV_LINKID, (datalink_id_t)id64); } } if ((datalink_id_t)id64 == DATALINK_INVALID_LINKID) { rcm_log_message(RCM_INFO, _("NET: invalid datalink\n")); errno = EINVAL; return (RCM_FAILURE); } /* * If this is device reconfiguration, populate the LINK_NEW event * to start the DR process. */ if (reconfigured) { nvlist_t *nnvl = NULL; rcm_log_message(RCM_TRACE1, "NET: reconfigured data-link (id %d)\n", (datalink_id_t)id64); if ((nvlist_alloc(&nnvl, 0, 0) != 0) || (nvlist_add_uint64(nnvl, RCM_NV_LINKID, id64) != 0) || (rcm_notify_event(hd, RCM_RESOURCE_LINK_NEW, 0, nnvl, NULL) != RCM_SUCCESS)) { nvlist_free(nnvl); rcm_log_message(RCM_INFO, _("NET: notify %s event failed\n"), RCM_RESOURCE_LINK_NEW); errno = EINVAL; return (RCM_FAILURE); } nvlist_free(nnvl); } rcm_log_message(RCM_TRACE1, _("NET: notify_event: device configuration complete\n")); return (RCM_SUCCESS); }
/* * nvlist_print - Prints elements in an event buffer */ static void nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth) { int i; char *name; uint_t nelem; nvpair_t *nvp; if (nvl == NULL) return; indent(fp, depth); (void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl)); nvp = nvlist_next_nvpair(nvl, NULL); while (nvp) { data_type_t type = nvpair_type(nvp); indent(fp, depth); name = nvpair_name(nvp); (void) fprintf(fp, "\t%s =", name); nelem = 0; switch (type) { case DATA_TYPE_BOOLEAN: { (void) fprintf(fp, " 1"); break; } case DATA_TYPE_BOOLEAN_VALUE: { boolean_t val; (void) nvpair_value_boolean_value(nvp, &val); (void) fprintf(fp, " %d", val); break; } case DATA_TYPE_BYTE: { uchar_t val; (void) nvpair_value_byte(nvp, &val); (void) fprintf(fp, " 0x%2.2x", val); break; } case DATA_TYPE_INT8: { int8_t val; (void) nvpair_value_int8(nvp, &val); (void) fprintf(fp, " %d", val); break; } case DATA_TYPE_UINT8: { uint8_t val; (void) nvpair_value_uint8(nvp, &val); (void) fprintf(fp, " 0x%x", val); break; } case DATA_TYPE_INT16: { int16_t val; (void) nvpair_value_int16(nvp, &val); (void) fprintf(fp, " %d", val); break; } case DATA_TYPE_UINT16: { uint16_t val; (void) nvpair_value_uint16(nvp, &val); (void) fprintf(fp, " 0x%x", val); break; } case DATA_TYPE_INT32: { int32_t val; (void) nvpair_value_int32(nvp, &val); (void) fprintf(fp, " %d", val); break; } case DATA_TYPE_UINT32: { uint32_t val; (void) nvpair_value_uint32(nvp, &val); (void) fprintf(fp, " 0x%x", val); break; } case DATA_TYPE_INT64: { int64_t val; (void) nvpair_value_int64(nvp, &val); (void) fprintf(fp, " %lld", (longlong_t)val); break; } case DATA_TYPE_UINT64: { uint64_t val; (void) nvpair_value_uint64(nvp, &val); (void) fprintf(fp, " 0x%llx", (u_longlong_t)val); break; } case DATA_TYPE_DOUBLE: { double val; (void) nvpair_value_double(nvp, &val); (void) fprintf(fp, " 0x%llf", val); break; } case DATA_TYPE_STRING: { char *val; (void) nvpair_value_string(nvp, &val); (void) fprintf(fp, " %s", val); break; } case DATA_TYPE_BOOLEAN_ARRAY: { boolean_t *val; (void) nvpair_value_boolean_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " %d", val[i]); break; } case DATA_TYPE_BYTE_ARRAY: { uchar_t *val; (void) nvpair_value_byte_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " 0x%2.2x", val[i]); break; } case DATA_TYPE_INT8_ARRAY: { int8_t *val; (void) nvpair_value_int8_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " %d", val[i]); break; } case DATA_TYPE_UINT8_ARRAY: { uint8_t *val; (void) nvpair_value_uint8_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " 0x%x", val[i]); break; } case DATA_TYPE_INT16_ARRAY: { int16_t *val; (void) nvpair_value_int16_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " %d", val[i]); break; } case DATA_TYPE_UINT16_ARRAY: { uint16_t *val; (void) nvpair_value_uint16_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " 0x%x", val[i]); break; } case DATA_TYPE_INT32_ARRAY: { int32_t *val; (void) nvpair_value_int32_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " %d", val[i]); break; } case DATA_TYPE_UINT32_ARRAY: { uint32_t *val; (void) nvpair_value_uint32_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " 0x%x", val[i]); break; } case DATA_TYPE_INT64_ARRAY: { int64_t *val; (void) nvpair_value_int64_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " %lld", (longlong_t)val[i]); break; } case DATA_TYPE_UINT64_ARRAY: { uint64_t *val; (void) nvpair_value_uint64_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " 0x%llx", (u_longlong_t)val[i]); break; } case DATA_TYPE_STRING_ARRAY: { char **val; (void) nvpair_value_string_array(nvp, &val, &nelem); for (i = 0; i < nelem; i++) (void) fprintf(fp, " %s", val[i]); break; } case DATA_TYPE_HRTIME: { hrtime_t val; (void) nvpair_value_hrtime(nvp, &val); (void) fprintf(fp, " 0x%llx", val); break; } case DATA_TYPE_NVLIST: { nvlist_t *val; (void) nvpair_value_nvlist(nvp, &val); (void) fprintf(fp, " (embedded nvlist)\n"); nvlist_print_with_indent(fp, val, depth + 1); indent(fp, depth + 1); (void) fprintf(fp, "(end %s)\n", name); break; } case DATA_TYPE_NVLIST_ARRAY: { nvlist_t **val; (void) nvpair_value_nvlist_array(nvp, &val, &nelem); (void) fprintf(fp, " (array of embedded nvlists)\n"); for (i = 0; i < nelem; i++) { indent(fp, depth + 1); (void) fprintf(fp, "(start %s[%d])\n", name, i); nvlist_print_with_indent(fp, val[i], depth + 1); indent(fp, depth + 1); (void) fprintf(fp, "(end %s[%d])\n", name, i); } break; } default: (void) fprintf(fp, " unknown data type (%d)", type); break; } (void) fprintf(fp, "\n"); nvp = nvlist_next_nvpair(nvl, nvp); } }
/* Handle a given list, boolean or numerical key=value pair */ static kv_status_t iser_handle_key(nvpair_t *nvp, const idm_kv_xlate_t *ikvx, nvlist_t *request_nvl, nvlist_t *response_nvl, nvlist_t *negotiated_nvl) { kv_status_t kvrc = KV_UNHANDLED; boolean_t bool_val; uint64_t num_val; int nvrc; /* Retrieve values for booleans and numericals */ switch (ikvx->ik_key_id) { /* Booleans */ case KI_RDMA_EXTENSIONS: case KI_IMMEDIATE_DATA: case KI_IFMARKER: case KI_OFMARKER: nvrc = nvpair_value_boolean_value(nvp, &bool_val); ASSERT(nvrc == 0); break; /* Numericals */ case KI_INITIATOR_RECV_DATA_SEGMENT_LENGTH: case KI_TARGET_RECV_DATA_SEGMENT_LENGTH: case KI_MAX_OUTSTANDING_UNEXPECTED_PDUS: nvrc = nvpair_value_uint64(nvp, &num_val); ASSERT(nvrc == 0); break; default: break; } /* Now handle the values according to the key name */ switch (ikvx->ik_key_id) { case KI_HEADER_DIGEST: case KI_DATA_DIGEST: /* Ensure "None" */ kvrc = iser_handle_digest(nvp, ikvx, request_nvl, response_nvl, negotiated_nvl); break; case KI_RDMA_EXTENSIONS: /* Ensure "Yes" */ kvrc = iser_handle_boolean(nvp, bool_val, ikvx, B_TRUE, request_nvl, response_nvl, negotiated_nvl); break; case KI_TARGET_RECV_DATA_SEGMENT_LENGTH: /* Validate the proposed value */ kvrc = iser_handle_numerical(nvp, num_val, ikvx, ISER_TARGET_RECV_DATA_SEGMENT_LENGTH_MIN, ISER_TARGET_RECV_DATA_SEGMENT_LENGTH_MAX, ISER_TARGET_RECV_DATA_SEGMENT_LENGTH_IMPL_MAX, request_nvl, response_nvl, negotiated_nvl); break; case KI_INITIATOR_RECV_DATA_SEGMENT_LENGTH: /* Validate the proposed value */ kvrc = iser_handle_numerical(nvp, num_val, ikvx, ISER_INITIATOR_RECV_DATA_SEGMENT_LENGTH_MIN, ISER_INITIATOR_RECV_DATA_SEGMENT_LENGTH_MAX, ISER_INITIATOR_RECV_DATA_SEGMENT_LENGTH_IMPL_MAX, request_nvl, response_nvl, negotiated_nvl); break; case KI_IMMEDIATE_DATA: case KI_OFMARKER: case KI_IFMARKER: /* Ensure "No" */ kvrc = iser_handle_boolean(nvp, bool_val, ikvx, B_FALSE, request_nvl, response_nvl, negotiated_nvl); break; case KI_MAX_OUTSTANDING_UNEXPECTED_PDUS: /* Validate the proposed value */ kvrc = iser_handle_numerical(nvp, num_val, ikvx, ISER_MAX_OUTSTANDING_UNEXPECTED_PDUS_MIN, ISER_MAX_OUTSTANDING_UNEXPECTED_PDUS_MAX, ISER_MAX_OUTSTANDING_UNEXPECTED_PDUS_IMPL_MAX, request_nvl, response_nvl, negotiated_nvl); break; default: /* * All other keys, including invalid keys, will be * handled at the client layer. */ kvrc = KV_HANDLED; break; } return (kvrc); }