static int drd_rcm_remove_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc) { char **rlist; int rv = 0; rcm_info_t *rinfo; drd_dbg("drd_rcm_remove_cpu_notify..."); if ((rlist = drd_rcm_cpu_rlist_init(rsrcs, nrsrc, DRCTL_STATUS_CONFIG_SUCCESS)) == NULL) { drd_dbg(" no CPUs in the success state, nothing to do"); return (0); } rv = rcm_notify_remove_list(rcm_hdl, rlist, 0, &rinfo); if (rv != RCM_SUCCESS) { drd_info("rcm_notify_remove_list failed: %d", rv); rcm_free_info(rinfo); rv = -1; } drd_rcm_cpu_rlist_fini(rlist); return (rv); }
static int drd_rcm_io_unconfig_request(drctl_rsrc_t *rsrc, int nrsrc) { int rv; char *dev = rsrc->res_dev_path; rcm_info_t *rinfo = NULL; if (nrsrc != 1) { drd_dbg("drd_io_unconfig_request: only 1 resource " "allowed for I/O requests, passed %d resources\n", nrsrc); rsrc->status = DRCTL_STATUS_DENY; return (-1); } if ((rv = rcm_request_offline(rcm_hdl, dev, 0, &rinfo)) == RCM_SUCCESS) rsrc->status = DRCTL_STATUS_ALLOW; else { rcm_notify_online(rcm_hdl, dev, 0, NULL); rsrc->status = DRCTL_STATUS_DENY; rsrc->offset = (uintptr_t)rcm_info_table(rinfo); } rcm_free_info(rinfo); drd_dbg("drd_rcm_io_unconfig_request(%s) = %d", dev, rv); return (rv); }
/* * sata_rcm_offline: * Offline SATA resource consumers. */ cfga_sata_ret_t sata_rcm_offline(const char *rsrc, char **errstring, char *rsrc_fixed, cfga_flags_t flags) { int rret; uint_t rflags = 0; rcm_info_t *rinfo = NULL; cfga_sata_ret_t ret = CFGA_SATA_OK; if ((ret = sata_rcm_init(rsrc, flags, errstring, &rflags)) != CFGA_SATA_OK) { return (ret); } if ((rret = rcm_request_offline(rcm_handle, rsrc_fixed, rflags, &rinfo)) != RCM_SUCCESS) { if (rinfo) { (void) sata_rcm_info_table(rinfo, errstring); rcm_free_info(rinfo); rinfo = NULL; } if (rret == RCM_FAILURE) { (void) sata_rcm_online(rsrc, errstring, rsrc_fixed, flags); } ret = CFGA_SATA_RCM_OFFLINE; } return (ret); }
/* * sata_rcm_online: * Online SATA resource consumers that were previously offlined. */ cfga_sata_ret_t sata_rcm_online(const char *rsrc, char **errstring, char *rsrc_fixed, cfga_flags_t flags) { rcm_info_t *rinfo = NULL; cfga_sata_ret_t ret = CFGA_SATA_OK; if ((ret = sata_rcm_init(rsrc, flags, errstring, NULL)) != CFGA_SATA_OK) { return (ret); } if (rcm_notify_online(rcm_handle, rsrc_fixed, 0, &rinfo) != RCM_SUCCESS && (rinfo != NULL)) { (void) sata_rcm_info_table(rinfo, errstring); rcm_free_info(rinfo); rinfo = NULL; ret = CFGA_SATA_RCM_ONLINE; } return (ret); }
static int drd_rcm_restore_cpu_notify(drctl_rsrc_t *rsrcs, int nrsrc) { char **rlist; char **full_rlist; int idx; int ridx; int state; int rv = 0; rcm_info_t *rinfo; drd_dbg("drd_rcm_restore_cpu_notify..."); if ((full_rlist = drd_rcm_cpu_rlist_init(rsrcs, nrsrc, DRCTL_STATUS_CONFIG_FAILURE)) == NULL) { drd_dbg(" no CPUs in the failed state, nothing to do"); return (0); } /* * Since the desired result of this operation is to * restore resources to the online state, filter out * the resources already in the online state before * passing the list to RCM. */ /* allocate a zero filled array to ensure NULL terminated list */ rlist = (char **)calloc((nrsrc + 1), sizeof (char *)); if (rlist == NULL) { drd_err("calloc failed: %s", strerror(errno)); rv = -1; goto done; } for (idx = 0, ridx = 0; full_rlist[idx] != NULL; idx++) { state = 0; rcm_get_rsrcstate(rcm_hdl, full_rlist[idx], &state); if (state != RCM_STATE_ONLINE) { rlist[ridx] = full_rlist[idx]; ridx++; } } /* check if everything got filtered out */ if (ridx == 0) { drd_dbg(" all CPUs already online, nothing to do"); goto done; } rv = rcm_notify_online_list(rcm_hdl, rlist, 0, &rinfo); if (rv != RCM_SUCCESS) { drd_info("rcm_notify_online_list failed: %d", rv); rcm_free_info(rinfo); rv = -1; } done: drd_rcm_cpu_rlist_fini(full_rlist); s_free(rlist); return (rv); }
static int drd_rcm_offline_cpu_request(drctl_rsrc_t *rsrcs, int nrsrc) { char **rlist; drctl_rsrc_t *rsrc; int idx; int state; int rv = 0; rcm_info_t *rinfo = NULL; rcm_info_tuple_t *tuple = NULL; const char *rsrcstr; const char *errstr; drd_dbg("drd_rcm_offline_cpu_request..."); if ((rlist = drd_rcm_cpu_rlist_init(rsrcs, nrsrc, DRCTL_STATUS_INIT)) == NULL) { drd_err("unable to generate resource list"); return (-1); } rv = rcm_request_offline_list(rcm_hdl, rlist, 0, &rinfo); if (rv == RCM_SUCCESS) { drd_dbg("RCM success, rinfo=%p", rinfo); goto done; } drd_dbg("RCM call failed (%d):", rv); /* * Loop through the result of the operation and add * any error messages to the resource structure. */ while ((tuple = rcm_info_next(rinfo, tuple)) != NULL) { /* find the resource of interest */ rsrcstr = rcm_info_rsrc(tuple); rsrc = cpu_rsrcstr_to_rsrc(rsrcstr, rsrcs, nrsrc); if (rsrc == NULL) { drd_dbg("unable to find resource for %s", rsrcstr); continue; } errstr = rcm_info_error(tuple); if (errstr) { drd_dbg(" %s: '%s'", rsrcstr, errstr); rsrc->offset = (uintptr_t)strdup(errstr); } } rcm_free_info(rinfo); rv = 0; done: /* * Set the state of the resource based on the RCM * state. CPUs in the offline state have the ok to * proceed. All others have been blocked. */ for (idx = 0; rlist[idx] != NULL; idx++) { state = 0; rcm_get_rsrcstate(rcm_hdl, rlist[idx], &state); /* find the resource of interest */ rsrc = cpu_rsrcstr_to_rsrc(rlist[idx], rsrcs, nrsrc); if (rsrc == NULL) { drd_dbg("unable to find resource for %s", rlist[idx]); continue; } rsrc->status = ((state == RCM_STATE_OFFLINE) ? DRCTL_STATUS_ALLOW : DRCTL_STATUS_DENY); } drd_rcm_cpu_rlist_fini(rlist); return (rv); }