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_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); }
/*ARGSUSED*/ static int net_passthru(rcm_handle_t *hd, int op, const char *rsrc, uint_t flag, char **reason, rcm_info_t **dependent_reason, void *arg) { net_cache_t *node; char *exported; datalink_id_t linkid; int len; int rv; /* * Lock the cache just long enough to extract information about this * resource. */ (void) mutex_lock(&cache_lock); node = cache_lookup(rsrc); if (!node) { rcm_log_message(RCM_WARNING, _("NET: unrecognized resource %s\n"), rsrc); (void) mutex_unlock(&cache_lock); return (RCM_SUCCESS); } /* * Since node could be freed after we drop cache_lock, allocate a * stack-local copy. We don't use malloc() because some of the * operations (such as NET_REMOVE) are not allowed to fail. Note * that exported is never more than MAXPATHLEN bytes. */ len = strlen("SUNW_datalink/") + LINKID_STR_WIDTH + 1; exported = alloca(len); linkid = node->linkid; (void) snprintf(exported, len, "SUNW_datalink/%u", linkid); /* * Remove notifications are unconditional in the RCM state model, * so it's safe to remove the node from the cache at this point. * And we need to remove it so that we will recognize it as a new * resource following the reattachment of the resource. */ if (op == NET_REMOVE) { cache_remove(node); free_node(node); } (void) mutex_unlock(&cache_lock); switch (op) { case NET_SUSPEND: rv = rcm_request_suspend(hd, exported, flag, (timespec_t *)arg, dependent_reason); break; case NET_OFFLINE: rv = rcm_request_offline(hd, exported, flag, dependent_reason); break; case NET_ONLINE: rv = rcm_notify_online(hd, exported, flag, dependent_reason); break; case NET_REMOVE: rv = rcm_notify_remove(hd, exported, flag, dependent_reason); if (rv == RCM_SUCCESS) { rcm_log_message(RCM_DEBUG, _("NET: mark link %d as removed\n"), linkid); /* * Delete active linkprop before this active link * is deleted. */ (void) dladm_set_linkprop(dld_handle, linkid, NULL, NULL, 0, DLADM_OPT_ACTIVE); (void) dladm_destroy_datalink_id(dld_handle, linkid, DLADM_OPT_ACTIVE); } break; case NET_RESUME: rv = rcm_notify_resume(hd, exported, flag, dependent_reason); break; default: rcm_log_message(RCM_WARNING, _("NET: bad RCM operation %1$d for %2$s\n"), op, exported); errno = EINVAL; return (RCM_FAILURE); } if (rv != RCM_SUCCESS) { char format[256]; (void) snprintf(format, sizeof (format), _("RCM operation on dependent %s did not succeed"), exported); rcm_log_message(RCM_WARNING, "NET: %s\n", format); } return (rv); }