static int cluster_unregister(rcm_handle_t *hdl) { if (cluster_SUNW_os_registered) { if (rcm_unregister_interest(hdl, SUNW_OS, 0) != RCM_SUCCESS) { rcm_log_message(RCM_ERROR, gettext("failed to unregister")); } cluster_SUNW_os_registered = 0; } return (RCM_SUCCESS); }
/* * Unregister all PHCIs and mark the whole registrants list as stale. */ static int mpxio_unregister(rcm_handle_t *hdl) { phci_list_t *reg; rcm_log_message(RCM_TRACE1, "MPXIO: unregister()\n"); (void) mutex_lock(&mpxio_lock); for (reg = reg_list; reg != NULL; reg = reg->next) { (void) rcm_unregister_interest(hdl, reg->phci.path, 0); reg->referenced = CACHE_STALE; } (void) mutex_unlock(&mpxio_lock); return (RCM_SUCCESS); }
/* * net_unregister() * * Manually walk through the cache, unregistering all the networks. * * Locking: the cache is locked throughout the execution of this routine * because it reads and modifies cache links continuously. */ static int net_unregister(rcm_handle_t *hd) { net_cache_t *probe; assert(hd != NULL); /* Walk the cache, unregistering everything */ (void) mutex_lock(&cache_lock); probe = cache_head.next; while (probe != &cache_tail) { (void) rcm_unregister_interest(hd, probe->resource, 0); cache_remove(probe); free_node(probe); probe = cache_head.next; } (void) mutex_unlock(&cache_lock); /* * Need to unregister interest in all new resources */ if (events_registered) { if (rcm_unregister_event(hd, RCM_RESOURCE_PHYSLINK_NEW, 0) != RCM_SUCCESS) { rcm_log_message(RCM_ERROR, _("NET: failed to unregister %s\n"), RCM_RESOURCE_PHYSLINK_NEW); return (RCM_FAILURE); } else { rcm_log_message(RCM_DEBUG, _("NET: unregistered %s\n"), RCM_RESOURCE_PHYSLINK_NEW); events_registered--; } } return (RCM_SUCCESS); }
/* * update_cache() * * The devinfo tree walking code is lifted from ifconfig.c. */ static void update_cache(rcm_handle_t *hd) { net_cache_t *probe; di_node_t root; int rv; (void) mutex_lock(&cache_lock); /* first we walk the entire cache, marking each entry stale */ probe = cache_head.next; while (probe != &cache_tail) { probe->flags |= CACHE_STALE; probe = probe->next; } root = di_init("/", DINFOSUBTREE | DINFOMINOR); if (root == DI_NODE_NIL) { goto done; } (void) di_walk_minor(root, DDI_NT_NET, DI_CHECK_ALIAS, NULL, devfs_entry); di_fini(root); probe = cache_head.next; while (probe != &cache_tail) { net_cache_t *freeit; if (probe->flags & CACHE_STALE) { (void) rcm_unregister_interest(hd, probe->resource, 0); rcm_log_message(RCM_DEBUG, _("NET: unregistered %s\n"), probe->resource); freeit = probe; probe = probe->next; cache_remove(freeit); free_node(freeit); continue; } if (!(probe->flags & CACHE_NEW)) { probe = probe->next; continue; } rcm_log_message(RCM_DEBUG, _("NET: registering %s\n"), probe->resource); rv = rcm_register_interest(hd, probe->resource, 0, NULL); if (rv != RCM_SUCCESS) { rcm_log_message(RCM_ERROR, _("NET: failed to register %s\n"), probe->resource); } else { rcm_log_message(RCM_DEBUG, _("NET: registered %s as SUNW_datalink/%u\n"), probe->resource, probe->linkid); probe->flags &= ~(CACHE_NEW); } probe = probe->next; } done: (void) mutex_unlock(&cache_lock); }
/* * After a new group_list has been constructed, this refreshes the RCM * registrations and the reg_list contents. It uses a clock like algorithm * with reference bits in the reg_list to know which registrants are new or * old. */ static void refresh_regs(rcm_handle_t *hdl) { int i; group_t *group; phci_list_t *reg; phci_list_t *prev_reg; /* * First part of the clock-like algorithm: clear reference bits. */ for (reg = reg_list; reg != NULL; reg = reg->next) reg->referenced = CACHE_STALE; /* * Second part of the clock-like algorithm: set the reference bits * on every registrant that's still active. (Also add new list nodes * for new registrants.) */ for (group = group_list; group != NULL; group = group->next) { for (i = 0; i < group->nphcis; i++) { /* * If already stale in the registrants list, just set * its reference bit to REFERENCED and update its state. */ if ((reg = lookup_phci(group->phcis[i].path)) != NULL) { if (reg->referenced == CACHE_STALE) reg->referenced = CACHE_REFERENCED; reg->phci.state = group->phcis[i].state; continue; } /* * Otherwise, build a new list node and mark it NEW. */ reg = (phci_list_t *)calloc(1, sizeof (*reg)); if (reg == NULL) { rcm_log_message(RCM_ERROR, "MPXIO: cannot allocate phci_list (%s).\n", strerror(errno)); continue; } reg->phci.path = strdup(group->phcis[i].path); if (reg->phci.path == NULL) { free(reg); rcm_log_message(RCM_ERROR, "MPXIO: cannot allocate phci path (%s).\n", strerror(errno)); continue; } reg->phci.state = group->phcis[i].state; reg->referenced = CACHE_NEW; /* Link it at the head of reg_list */ reg->next = reg_list; reg_list = reg; } } /* * Final part of the clock algorithm: unregister stale entries, and * register new entries. Stale entries get removed from the list. */ reg = reg_list; prev_reg = NULL; while (reg) { /* Unregister and remove stale entries. */ if (reg->referenced == CACHE_STALE) { (void) rcm_unregister_interest(hdl, reg->phci.path, 0); free(reg->phci.path); if (prev_reg == NULL) { reg_list = reg->next; free(reg); reg = reg_list; } else { prev_reg->next = reg->next; free(reg); reg = prev_reg->next; } continue; } /* Register new entries. */ if (reg->referenced == CACHE_NEW) { if (rcm_register_interest(hdl, reg->phci.path, 0, NULL) != RCM_SUCCESS) { rcm_log_message(RCM_ERROR, "MPXIO: failed to register %s (%s).\n", reg->phci.path, strerror(errno)); } } prev_reg = reg; reg = reg->next; } }