static int __osd_sa_xattr_get(const struct lu_env *env, struct osd_object *obj, const struct lu_buf *buf, const char *name, int *sizep) { uchar_t *nv_value; int rc; LASSERT(obj->oo_sa_hdl); if (obj->oo_sa_xattr == NULL) { rc = __osd_xattr_cache(env, obj); if (rc) return rc; } LASSERT(obj->oo_sa_xattr); rc = -nvlist_lookup_byte_array(obj->oo_sa_xattr, name, &nv_value, sizep); if (rc) return rc; if (buf == NULL || buf->lb_buf == NULL) { /* return the required size by *sizep */ return 0; } if (*sizep > buf->lb_len) return -ERANGE; /* match ldiskfs error */ memcpy(buf->lb_buf, nv_value, *sizep); return 0; }
/* * Convert a device path/nvlist pair to an nvp_list_t * Used to parse the nvlist format when reading * /etc/devices/devid_cache */ static nvp_list_t * devid_nvl2nvp(nvlist_t *nvl, char *name) { nvp_devid_t *np; ddi_devid_t devidp; int rval; uint_t n; np = kmem_zalloc(sizeof (nvp_devid_t), KM_SLEEP); np->nvp_devpath = i_ddi_strdup(name, KM_SLEEP); NVP_DEVID_DEBUG_PATH((np->nvp_devpath)); /* * check path for a devid */ np->nvp_devid = NULL; rval = nvlist_lookup_byte_array(nvl, DP_DEVID_ID, (uchar_t **)&devidp, &n); if (rval == 0) { if (ddi_devid_valid(devidp) == DDI_SUCCESS) { ASSERT(n == ddi_devid_sizeof(devidp)); np->nvp_devid = kmem_alloc(n, KM_SLEEP); (void) bcopy(devidp, np->nvp_devid, n); NVP_DEVID_DEBUG_DEVID((np->nvp_devid)); } else { DEVIDERR((CE_CONT, "%s: invalid devid\n", np->nvp_devpath)); } } return (NVPLIST(np)); }
static int zpl_xattr_get_sa(struct inode *ip, const char *name, void *value, size_t size) { znode_t *zp = ITOZ(ip); uchar_t *nv_value; uint_t nv_size; int error = 0; ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock)); mutex_enter(&zp->z_lock); if (zp->z_xattr_cached == NULL) error = -zfs_sa_get_xattr(zp); mutex_exit(&zp->z_lock); if (error) return (error); ASSERT(zp->z_xattr_cached); error = -nvlist_lookup_byte_array(zp->z_xattr_cached, name, &nv_value, &nv_size); if (error) return (error); if (!size) return (nv_size); if (size < nv_size) return (-ERANGE); memcpy(value, nv_value, nv_size); return (nv_size); }
static boolean_t sfunc_probe_target(ofmt_arg_t *ofmtarg, char *buf, uint_t bufsize) { ipmpstat_sfunc_arg_t *arg = ofmtarg->ofmt_cbarg; uint_t nelem; struct sockaddr_storage *target; nvlist_t *nvl = arg->sa_data; if (nvlist_lookup_byte_array(nvl, IPMP_PROBE_TARGET, (uchar_t **)&target, &nelem) != 0) return (sfunc_nvwarn("IPMP_PROBE_TARGET")); sockaddr2str(target, buf, bufsize); return (B_TRUE); }
static int bi_getval_bootmisc(bi_param_t *bip, void *valbuf, size_t *vallenp) { uchar_t *val; uint_t len; if (nvlist_lookup_byte_array(bi_nvl, (char *)bip->bi_name, &val, &len) != 0) { return (BI_E_NOVAL); } else if (*vallenp < len) { *vallenp = len; return (BI_E_BUF2SMALL); } *vallenp = len; (void) memcpy(valbuf, val, *vallenp); return (BI_E_SUCCESS); }
int __osd_sa_xattr_set(const struct lu_env *env, struct osd_object *obj, const struct lu_buf *buf, const char *name, int fl, struct osd_thandle *oh) { dmu_buf_impl_t *db; uchar_t *nv_value; size_t size; int nv_size; int rc; int too_big = 0; LASSERT(obj->oo_sa_hdl); if (obj->oo_sa_xattr == NULL) { rc = __osd_xattr_cache(env, obj); if (rc) return rc; } LASSERT(obj->oo_sa_xattr); /* Limited to 32k to keep nvpair memory allocations small */ if (buf->lb_len > DXATTR_MAX_ENTRY_SIZE) { too_big = 1; } else { /* Prevent the DXATTR SA from consuming the entire SA * region */ rc = -nvlist_size(obj->oo_sa_xattr, &size, NV_ENCODE_XDR); if (rc) return rc; if (size + buf->lb_len > DXATTR_MAX_SA_SIZE) too_big = 1; } /* even in case of -EFBIG we must lookup xattr and check can we * rewrite it then delete from SA */ rc = -nvlist_lookup_byte_array(obj->oo_sa_xattr, name, &nv_value, &nv_size); if (rc == 0) { if (fl & LU_XATTR_CREATE) { return -EEXIST; } else if (too_big) { rc = -nvlist_remove(obj->oo_sa_xattr, name, DATA_TYPE_BYTE_ARRAY); if (rc < 0) return rc; rc = __osd_sa_xattr_schedule_update(env, obj, oh); return rc == 0 ? -EFBIG : rc; } } else if (rc == -ENOENT) { if (fl & LU_XATTR_REPLACE) return -ENODATA; else if (too_big) return -EFBIG; } else { return rc; } /* Ensure xattr doesn't exist in ZAP */ if (obj->oo_xattr != ZFS_NO_OBJECT) { struct osd_device *osd = osd_obj2dev(obj); uint64_t objid; rc = -zap_lookup(osd->od_os, obj->oo_xattr, name, 8, 1, &objid); if (rc == 0) { rc = -dmu_object_free(osd->od_os, objid, oh->ot_tx); if (rc == 0) zap_remove(osd->od_os, obj->oo_xattr, name, oh->ot_tx); } } rc = -nvlist_add_byte_array(obj->oo_sa_xattr, name, (uchar_t *)buf->lb_buf, buf->lb_len); if (rc) return rc; /* batch updates only for just created dnodes where we * used to set number of EAs in a single transaction */ db = (dmu_buf_impl_t *)obj->oo_db; if (DB_DNODE(db)->dn_allocated_txg == oh->ot_tx->tx_txg) rc = __osd_sa_xattr_schedule_update(env, obj, oh); else rc = __osd_sa_xattr_update(env, obj, oh); return rc; }
int __osd_sa_xattr_set(const struct lu_env *env, struct osd_object *obj, const struct lu_buf *buf, const char *name, int fl, struct osd_thandle *oh) { uchar_t *nv_value; size_t size; int nv_size; int rc; int too_big = 0; LASSERT(obj->oo_sa_hdl); if (obj->oo_sa_xattr == NULL) { rc = __osd_xattr_cache(env, obj); if (rc) return rc; } LASSERT(obj->oo_sa_xattr); /* Limited to 32k to keep nvpair memory allocations small */ if (buf->lb_len > DXATTR_MAX_ENTRY_SIZE) { too_big = 1; } else { /* Prevent the DXATTR SA from consuming the entire SA * region */ rc = -nvlist_size(obj->oo_sa_xattr, &size, NV_ENCODE_XDR); if (rc) return rc; if (size + buf->lb_len > DXATTR_MAX_SA_SIZE) too_big = 1; } /* even in case of -EFBIG we must lookup xattr and check can we * rewrite it then delete from SA */ rc = -nvlist_lookup_byte_array(obj->oo_sa_xattr, name, &nv_value, &nv_size); if (rc == 0) { if (fl & LU_XATTR_CREATE) { return -EEXIST; } else if (too_big) { rc = -nvlist_remove(obj->oo_sa_xattr, name, DATA_TYPE_BYTE_ARRAY); if (rc < 0) return rc; rc = __osd_sa_xattr_update(env, obj, oh); return rc == 0 ? -EFBIG : rc; } } else if (rc == -ENOENT) { if (fl & LU_XATTR_REPLACE) return -ENODATA; else if (too_big) return -EFBIG; } else { return rc; } rc = -nvlist_add_byte_array(obj->oo_sa_xattr, name, (uchar_t *)buf->lb_buf, buf->lb_len); if (rc) return rc; rc = __osd_sa_xattr_update(env, obj, oh); return rc; }
/*ARGSUSED*/ static int enc_parse_feature_block(ses_plugin_t *sp, ses_node_t *np) { sun_feature_block_impl_t *sfbip; nvlist_t *encprops; uint8_t *vsp; uint_t vsp_len; uint_t cid_off, cid_len; uint16_t revision; uint64_t chunk; int nverr; encprops = ses_node_props(np); if (nvlist_lookup_byte_array(encprops, SES_EN_PROP_VS, &vsp, &vsp_len) != 0 || vsp_len < offsetof(sun_feature_block_impl_t, _reserved2)) return (0); sfbip = (sun_feature_block_impl_t *)vsp; if (strncmp((char *)sfbip->sfbi_spms_header, "SPMS", 4) != 0 || sfbip->sfbi_spms_major_ver != 1) return (0); revision = SCSI_READ16(&sfbip->sfbi_spms_revision); /* * The offset read from the Sun Feature Block needs to be adjusted * so that the difference in the sizes of the Enclosure * Descriptor and the INQUIRY data format is accounted for. */ cid_len = sfbip->sfbi_chassis_id_len; if (sfbip->sfbi_chassis_id_off >= 96 && cid_len >= 4) { cid_off = sfbip->sfbi_chassis_id_off - (sizeof (ses2_ed_impl_t) - 1); cid_off += offsetof(ses2_ed_impl_t, st_priv[0]) - offsetof(spc3_inquiry_data_t, id_vs_36[0]); if (cid_off + cid_len <= vsp_len) { SES_NV_ADD(fixed_string, nverr, encprops, LIBSES_EN_PROP_CSN, (char *)(vsp + cid_off), cid_len); } } if (revision >= 104) { SES_NV_ADD(boolean_value, nverr, encprops, LIBSES_EN_PROP_INTERNAL, sfbip->sfbi_int); } if (revision >= 105) { if (sfbip->sfbi_fw_upload_max_chunk_sz == 0) chunk = 512; else if (sfbip->sfbi_fw_upload_max_chunk_sz == 0x7f) chunk = 65536; else chunk = 512 * sfbip->sfbi_fw_upload_max_chunk_sz; SES_NV_ADD(uint64, nverr, encprops, LIBSES_EN_PROP_FIRMWARE_CHUNK_SIZE, chunk); } /* * If this is a subchassis, it will have a subchassis index field * with a value other than 0. See SPMS-1r111 4.1.3.1. If not, we * will see 0 and will not create the subchassis member at all; note * that this is backward-compatible with pre-111 implementations that * treated this as a reserved field. No such implementation contains * a subchassis. */ if (sfbip->sfbi_spms_revision >= 111 && sfbip->sfbi_subchassis_index != 0) { SES_NV_ADD(uint64, nverr, encprops, LIBSES_EN_PROP_SUBCHASSIS_ID, sfbip->sfbi_subchassis_index - 1); } return (0); }
static int osd_scrub_check_update(const struct lu_env *env, struct osd_device *dev, const struct lu_fid *fid, uint64_t oid, int val) { struct lustre_scrub *scrub = &dev->od_scrub; struct scrub_file *sf = &scrub->os_file; struct osd_inconsistent_item *oii = NULL; nvlist_t *nvbuf = NULL; dnode_t *dn = NULL; uint64_t oid2; int ops = DTO_INDEX_UPDATE; int rc; ENTRY; down_write(&scrub->os_rwsem); scrub->os_new_checked++; if (val < 0) GOTO(out, rc = val); if (scrub->os_in_prior) oii = list_entry(scrub->os_inconsistent_items.next, struct osd_inconsistent_item, oii_list); if (oid < sf->sf_pos_latest_start && !oii) GOTO(out, rc = 0); if (oii && oii->oii_insert) { ops = DTO_INDEX_INSERT; goto zget; } rc = osd_fid_lookup(env, dev, fid, &oid2); if (rc) { if (rc != -ENOENT) GOTO(out, rc); ops = DTO_INDEX_INSERT; zget: rc = __osd_obj2dnode(dev->od_os, oid, &dn); if (rc) { /* Someone removed the object by race. */ if (rc == -ENOENT || rc == -EEXIST) rc = 0; GOTO(out, rc); } scrub->os_full_speed = 1; sf->sf_flags |= SF_INCONSISTENT; } else if (oid == oid2) { GOTO(out, rc = 0); } else { struct lustre_mdt_attrs *lma = NULL; int size; rc = __osd_xattr_load_by_oid(dev, oid2, &nvbuf); if (rc == -ENOENT || rc == -EEXIST || rc == -ENODATA) goto update; if (rc) GOTO(out, rc); rc = -nvlist_lookup_byte_array(nvbuf, XATTR_NAME_LMA, (uchar_t **)&lma, &size); if (rc == -ENOENT || rc == -EEXIST || rc == -ENODATA) goto update; if (rc) GOTO(out, rc); lustre_lma_swab(lma); if (unlikely(lu_fid_eq(&lma->lma_self_fid, fid))) { CDEBUG(D_LFSCK, "%s: the FID "DFID" is used by " "two objects: %llu and %llu (in OI)\n", osd_name(dev), PFID(fid), oid, oid2); GOTO(out, rc = -EEXIST); } update: scrub->os_full_speed = 1; sf->sf_flags |= SF_INCONSISTENT; } rc = osd_scrub_refresh_mapping(env, dev, fid, oid, ops, false, NULL); if (!rc) { if (scrub->os_in_prior) sf->sf_items_updated_prior++; else sf->sf_items_updated++; } GOTO(out, rc); out: if (nvbuf) nvlist_free(nvbuf); if (rc < 0) { sf->sf_items_failed++; if (sf->sf_pos_first_inconsistent == 0 || sf->sf_pos_first_inconsistent > oid) sf->sf_pos_first_inconsistent = oid; } else { rc = 0; } /* There may be conflict unlink during the OI scrub, * if happend, then remove the new added OI mapping. */ if (ops == DTO_INDEX_INSERT && dn && dn->dn_free_txg) osd_scrub_refresh_mapping(env, dev, fid, oid, DTO_INDEX_DELETE, false, NULL); up_write(&scrub->os_rwsem); if (dn) osd_dnode_rele(dn); if (oii) { spin_lock(&scrub->os_lock); if (likely(!list_empty(&oii->oii_list))) list_del(&oii->oii_list); spin_unlock(&scrub->os_lock); OBD_FREE_PTR(oii); } RETURN(sf->sf_param & SP_FAILOUT ? rc : 0); }
/* * Create an instance of a transceiver with the specified id. We must create * both its port and the transceiver node. */ static int nic_create_transceiver(topo_mod_t *mod, tnode_t *pnode, dladm_handle_t handle, datalink_id_t linkid, uint_t tranid) { int ret; tnode_t *port; dld_ioc_gettran_t dgt; dld_ioc_tranio_t dti; uint8_t buf[256]; char ouibuf[16]; char *vendor = NULL, *part = NULL, *rev = NULL, *serial = NULL; nvlist_t *nvl = NULL; if ((ret = port_create_sff(mod, pnode, tranid, &port)) != 0) return (ret); bzero(&dgt, sizeof (dgt)); dgt.dgt_linkid = linkid; dgt.dgt_tran_id = tranid; if (ioctl(dladm_dld_fd(handle), DLDIOC_GETTRAN, &dgt) != 0) { if (errno == ENOTSUP) return (0); return (-1); } if (dgt.dgt_present == 0) return (0); bzero(&dti, sizeof (dti)); dti.dti_linkid = linkid; dti.dti_tran_id = tranid; dti.dti_page = 0xa0; dti.dti_nbytes = sizeof (buf); dti.dti_buf = (uintptr_t)buf; if (ioctl(dladm_dld_fd(handle), DLDIOC_READTRAN, &dti) == 0) { uchar_t *oui; uint_t nbyte; if (libsff_parse(buf, dti.dti_nbytes, dti.dti_page, &nvl) == 0) { if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_VENDOR, &vendor)) != 0 && nvlist_lookup_byte_array(nvl, LIBSFF_KEY_OUI, &oui, &nbyte) == 0 && nbyte == 3) { if (snprintf(ouibuf, sizeof (ouibuf), "%02x:%02x:%02x", oui[0], oui[1], oui[2]) < sizeof (ouibuf)) { vendor = ouibuf; } } else if (ret != 0) { vendor = NULL; } if (nvlist_lookup_string(nvl, LIBSFF_KEY_PART, &part) != 0) { part = NULL; } if (nvlist_lookup_string(nvl, LIBSFF_KEY_REVISION, &rev) != 0) { rev = NULL; } if (nvlist_lookup_string(nvl, LIBSFF_KEY_SERIAL, &serial) != 0) { serial = NULL; } } } if (transceiver_range_create(mod, port, 0, 0) != 0) { nvlist_free(nvl); return (-1); } if (transceiver_create_sff(mod, port, 0, dgt.dgt_usable, vendor, part, rev, serial, NULL) != 0) { nvlist_free(nvl); return (-1); } nvlist_free(nvl); return (0); }
/* * as we don't know FID, we can't use LU object, so this function * partially duplicate __osd_xattr_get() which is built around * LU-object and uses it to cache data like regular EA dnode, etc */ static int osd_find_parent_by_dnode(const struct lu_env *env, struct dt_object *o, struct lu_fid *fid) { struct lustre_mdt_attrs *lma; udmu_objset_t *uos = &osd_obj2dev(osd_dt_obj(o))->od_objset; struct lu_buf buf; sa_handle_t *sa_hdl; nvlist_t *nvbuf = NULL; uchar_t *value; uint64_t dnode; int rc, size; ENTRY; /* first of all, get parent dnode from own attributes */ LASSERT(osd_dt_obj(o)->oo_db); rc = -sa_handle_get(uos->os, osd_dt_obj(o)->oo_db->db_object, NULL, SA_HDL_PRIVATE, &sa_hdl); if (rc) RETURN(rc); dnode = ZFS_NO_OBJECT; rc = -sa_lookup(sa_hdl, SA_ZPL_PARENT(uos), &dnode, 8); sa_handle_destroy(sa_hdl); if (rc) RETURN(rc); /* now get EA buffer */ rc = __osd_xattr_load(uos, dnode, &nvbuf); if (rc) GOTO(regular, rc); /* XXX: if we get that far.. should we cache the result? */ /* try to find LMA attribute */ LASSERT(nvbuf != NULL); rc = -nvlist_lookup_byte_array(nvbuf, XATTR_NAME_LMA, &value, &size); if (rc == 0 && size >= sizeof(*lma)) { lma = (struct lustre_mdt_attrs *)value; lustre_lma_swab(lma); *fid = lma->lma_self_fid; GOTO(out, rc = 0); } regular: /* no LMA attribute in SA, let's try regular EA */ /* first of all, get parent dnode storing regular EA */ rc = -sa_handle_get(uos->os, dnode, NULL, SA_HDL_PRIVATE, &sa_hdl); if (rc) GOTO(out, rc); dnode = ZFS_NO_OBJECT; rc = -sa_lookup(sa_hdl, SA_ZPL_XATTR(uos), &dnode, 8); sa_handle_destroy(sa_hdl); if (rc) GOTO(out, rc); CLASSERT(sizeof(*lma) <= sizeof(osd_oti_get(env)->oti_buf)); buf.lb_buf = osd_oti_get(env)->oti_buf; buf.lb_len = sizeof(osd_oti_get(env)->oti_buf); /* now try to find LMA */ rc = __osd_xattr_get_large(env, uos, dnode, &buf, XATTR_NAME_LMA, &size); if (rc == 0 && size >= sizeof(*lma)) { lma = buf.lb_buf; lustre_lma_swab(lma); *fid = lma->lma_self_fid; GOTO(out, rc = 0); } else if (rc < 0) { GOTO(out, rc); } else { GOTO(out, rc = -EIO); } out: if (nvbuf != NULL) nvlist_free(nvbuf); RETURN(rc); }
/* * Actually processes events; returns a reply event */ static void process_event(int cmd, int seq_num, nvlist_t *nvl, nvlist_t **ret) { int i; int error; uint_t nvl_nrsrcs = 0; pid_t pid; uint32_t flag = (uint32_t)0; uint64_t pid64 = (uint64_t)0; size_t buflen = 0; size_t interval_size = 0; timespec_t *interval = NULL; nvlist_t *change_data = NULL; nvlist_t *event_data = NULL; rcm_info_t *info = NULL; char *modname = NULL; char *buf = NULL; char **rsrcnames = NULL; char **nvl_rsrcs = NULL; rcm_log_message(RCM_TRACE2, "servicing door command=%d\n", cmd); rcm_print_nvlist(nvl); /* * Extract data from the door argument nvlist. Not all arguments * are needed; sanity checks are performed later. */ (void) nvlist_lookup_string_array(nvl, RCM_RSRCNAMES, &nvl_rsrcs, &nvl_nrsrcs); (void) nvlist_lookup_string(nvl, RCM_CLIENT_MODNAME, &modname); (void) nvlist_lookup_uint64(nvl, RCM_CLIENT_ID, (uint64_t *)&pid64); pid = (pid_t)pid64; (void) nvlist_lookup_uint32(nvl, RCM_REQUEST_FLAG, (uint32_t *)&flag); (void) nvlist_lookup_byte_array(nvl, RCM_SUSPEND_INTERVAL, (uchar_t **)&interval, &interval_size); (void) nvlist_lookup_byte_array(nvl, RCM_CHANGE_DATA, (uchar_t **)&buf, &buflen); if (buf != NULL && buflen > 0) { (void) nvlist_unpack(buf, buflen, &change_data, 0); buf = NULL; buflen = 0; } (void) nvlist_lookup_byte_array(nvl, RCM_EVENT_DATA, (uchar_t **)&buf, &buflen); if (buf != NULL && buflen > 0) (void) nvlist_unpack(buf, buflen, &event_data, 0); rsrcnames = s_calloc(nvl_nrsrcs + 1, sizeof (char *)); for (i = 0; i < nvl_nrsrcs; i++) { rsrcnames[i] = nvl_rsrcs[i]; } rsrcnames[nvl_nrsrcs] = NULL; /* * Switch off the command being performed to do the appropriate * sanity checks and dispatch the arguments to the appropriate * implementation routine. */ switch (cmd) { case CMD_REGISTER: if ((modname == NULL) || (rsrcnames == NULL) || (rsrcnames[0] == NULL)) goto faildata; error = add_resource_client(modname, rsrcnames[0], pid, flag, &info); break; case CMD_UNREGISTER: if ((modname == NULL) || (rsrcnames == NULL) || (rsrcnames[0] == NULL)) goto faildata; error = remove_resource_client(modname, rsrcnames[0], pid, flag); break; case CMD_GETINFO: if ((rsrcnames == NULL) && ((flag & (RCM_DR_OPERATION | RCM_MOD_INFO)) == 0)) goto faildata; if ((error = get_resource_info(rsrcnames, flag, seq_num, &info)) == EINVAL) { rcm_log_message(RCM_DEBUG, "invalid argument in get info request\n"); generate_reply_event(EINVAL, NULL, ret); return; } break; case CMD_SUSPEND: if ((rsrcnames == NULL) || (rsrcnames[0] == NULL) || (interval == NULL)) goto faildata; error = process_resource_suspend(rsrcnames, pid, flag, seq_num, interval, &info); break; case CMD_RESUME: if ((rsrcnames == NULL) || (rsrcnames[0] == NULL)) goto faildata; error = notify_resource_resume(rsrcnames, pid, flag, seq_num, &info); break; case CMD_OFFLINE: if ((rsrcnames == NULL) || (rsrcnames[0] == NULL)) goto faildata; error = process_resource_offline(rsrcnames, pid, flag, seq_num, &info); break; case CMD_ONLINE: if ((rsrcnames == NULL) || (rsrcnames[0] == NULL)) goto faildata; error = notify_resource_online(rsrcnames, pid, flag, seq_num, &info); break; case CMD_REMOVE: if ((rsrcnames == NULL) || (rsrcnames[0] == NULL)) goto faildata; error = notify_resource_remove(rsrcnames, pid, flag, seq_num, &info); break; case CMD_EVENT: if ((rsrcnames == NULL) || (rsrcnames[0] == NULL) || (event_data == NULL)) goto faildata; error = notify_resource_event(rsrcnames[0], pid, flag, seq_num, event_data, &info); nvlist_free(event_data); break; case CMD_REQUEST_CHANGE: if ((rsrcnames == NULL) || (rsrcnames[0] == NULL) || (change_data == NULL)) goto faildata; error = request_capacity_change(rsrcnames[0], pid, flag, seq_num, change_data, &info); nvlist_free(change_data); break; case CMD_NOTIFY_CHANGE: if ((rsrcnames == NULL) || (rsrcnames[0] == NULL) || (change_data == NULL)) goto faildata; error = notify_capacity_change(rsrcnames[0], pid, flag, seq_num, change_data, &info); nvlist_free(change_data); break; case CMD_GETSTATE: if ((rsrcnames == NULL) || (rsrcnames[0] == NULL)) goto faildata; error = get_resource_state(rsrcnames[0], pid, &info); break; default: rcm_log_message(RCM_WARNING, gettext("unknown door command: %d\n"), cmd); generate_reply_event(EFAULT, NULL, ret); (void) free(rsrcnames); return; } rcm_log_message(RCM_TRACE2, "finish processing event 0x%x\n", cmd); generate_reply_event(error, info, ret); (void) free(rsrcnames); return; faildata: rcm_log_message(RCM_WARNING, gettext("data error in door arguments for cmd 0x%x\n"), cmd); generate_reply_event(EFAULT, NULL, ret); (void) free(rsrcnames); }
/*ARGSUSED*/ static int sun_riverwalk_parse_node(ses_plugin_t *sp, ses_node_t *np) { nvlist_t *props = ses_node_props(np); int nverr; ses_riverwalk_stringin_t *strp; char buf[32]; uint64_t type, index; char *pn, *sn; ses_node_t *encp; nvlist_t *encprops; uint8_t *stringin; uint_t len; if (ses_node_type(np) != SES_NODE_ENCLOSURE && ses_node_type(np) != SES_NODE_ELEMENT) return (0); /* * Find the containing enclosure node and extract the STRING IN * information. */ for (encp = np; ses_node_type(encp) != SES_NODE_ENCLOSURE; encp = ses_node_parent(encp)) ; encprops = ses_node_props(encp); if (nvlist_lookup_byte_array(encprops, SES_EN_PROP_STRING, &stringin, &len) != 0) return (0); if (len < sizeof (ses_riverwalk_stringin_t)) return (0); strp = (ses_riverwalk_stringin_t *)stringin; switch (ses_node_type(np)) { case SES_NODE_ELEMENT: /* * We can get part and serial information for power supplies and * the SIM cards (ESC_ELECTRONICS elements). */ VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE, &type) == 0); VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_CLASS_INDEX, &index) == 0); sn = pn = NULL; switch (type) { case SES_ET_POWER_SUPPLY: switch (index) { case 0: if (strncmp(strp->rws_ps0_id, "SPS0", 4) != 0) break; pn = strp->rws_ps0_pn; sn = strp->rws_ps0_sn; break; case 1: if (strncmp(strp->rws_ps1_id, "SPS1", 4) != 0) break; pn = strp->rws_ps1_pn; sn = strp->rws_ps1_sn; break; } break; case SES_ET_ESC_ELECTRONICS: switch (index) { case 0: if (strncmp(strp->rws_sim0_id, "SIM0", 4) != 0) break; pn = strp->rws_sim0_pn; sn = strp->rws_sim0_sn; break; case 1: if (strncmp(strp->rws_sim1_id, "SIM1", 4) != 0) break; pn = strp->rws_sim1_pn; sn = strp->rws_sim1_sn; break; } break; case SES_ET_COOLING: /* * The J4200 uses identical STRING IN data except that * the PSU part numbers are replaced with fan part * numbers. The power supply part and serial number * information are not available. */ switch (index) { case 0: if (strncmp(strp->rws_ps0_id, "FAN0", 4) != 0) break; pn = strp->rws_ps0_pn; sn = strp->rws_ps0_sn; break; case 1: if (strncmp(strp->rws_ps1_id, "FAN1", 4) != 0) break; pn = strp->rws_ps1_pn; sn = strp->rws_ps1_sn; break; } break; } if (pn == NULL) return (0); if (pn[0] != '\0') { (void) bcopy(pn, buf, sizeof (strp->rws_ps0_pn)); buf[sizeof (strp->rws_ps0_pn)] = '\0'; SES_NV_ADD(string, nverr, props, LIBSES_PROP_PART, buf); } if (sn[0] != '\0') { (void) bcopy(sn, buf, sizeof (strp->rws_ps0_sn)); buf[sizeof (strp->rws_ps0_sn)] = '\0'; SES_NV_ADD(string, nverr, props, LIBSES_PROP_SERIAL, sn); } break; case SES_NODE_ENCLOSURE: /* * The chassis serial number is derived from the MID FRU * descriptor. */ if (strncmp(strp->rws_mid_id, "MID ", 4) == 0 && strp->rws_mid_sn[0] != '\0') { (void) bcopy(strp->rws_mid_sn, buf, sizeof (strp->rws_mid_sn)); buf[sizeof (strp->rws_mid_sn)] = '\0'; SES_NV_ADD(string, nverr, props, LIBSES_EN_PROP_CSN, buf); } break; } return (0); }