struct sm_stat * sm_unmon_all_1_svc(struct my_id *argp, struct svc_req *rqstp) { short int count = 0; static sm_stat result; notify_list *clnt; char *my_name = argp->my_name; xlog(D_CALL, "Received SM_UNMON_ALL for %s", my_name); if (!caller_is_localhost(rqstp)) goto failure; result.state = MY_STATE; if (rtnl == NULL) { xlog_warn("Received SM_UNMON_ALL request from %s " "while not monitoring any hosts", my_name); return (&result); } clnt = rtnl; while ((clnt = nlist_gethost(clnt, my_name, 1))) { if (NL_MY_PROC(clnt) == argp->my_proc && NL_MY_PROG(clnt) == argp->my_prog && NL_MY_VERS(clnt) == argp->my_vers) { /* Watch stack! */ char mon_name[SM_MAXSTRLEN + 1]; notify_list *temp; xlog(D_GENERAL, "UNMONITORING (SM_UNMON_ALL) %s for %s", NL_MON_NAME(clnt), NL_MY_NAME(clnt)); strncpy(mon_name, NL_MON_NAME(clnt), sizeof (mon_name) - 1); mon_name[sizeof (mon_name) - 1] = '\0'; temp = NL_NEXT(clnt); /* PRC: do the HA callout: */ ha_callout("del-client", mon_name, my_name, -1); nsm_delete_monitored_host(clnt->dns_name, mon_name, my_name); nlist_free(&rtnl, clnt); ++count; clnt = temp; } else clnt = NL_NEXT(clnt); } if (!count) { xlog(D_GENERAL, "SM_UNMON_ALL request from %s with no " "SM_MON requests from it", my_name); } failure: return (&result); }
/* * Process a datagram received on the notify socket */ int process_reply(FD_SET_TYPE *rfds) { notify_list *lp; u_long port; if (sockfd == -1 || !FD_ISSET(sockfd, rfds)) return 0; if (!(lp = recv_rply(&port))) return 1; if (lp->port == 0) { if (port != 0) { lp->port = htons((unsigned short) port); process_entry(lp); NL_WHEN(lp) = time(NULL) + NOTIFY_TIMEOUT; nlist_remove(¬ify, lp); nlist_insert_timer(¬ify, lp); return 1; } xlog_warn("%s: service %d not registered on localhost", __func__, NL_MY_PROG(lp)); } else { xlog(D_GENERAL, "%s: Callback to %s (for %d) succeeded", __func__, NL_MY_NAME(lp), NL_MON_NAME(lp)); } nlist_free(¬ify, lp); return 1; }
/* * LH - The linked list code had some bugs. Used this to help debug * new code. */ static void plist(notify_list *head, int en) { /* case where we ran off the end */ if (!head) return; printf("Entry %d: %s\n",en, NL_MON_NAME(head)); plist(head->next, ++en); }
/* * Notify operation for a single list entry */ static int process_entry(notify_list *lp) { struct sockaddr_in sin; if (NL_TIMES(lp) == 0) { xlog(D_GENERAL, "%s: Cannot notify localhost, giving up", __func__); return 0; } memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = lp->port; /* LH - moved address into switch */ /* __FORCE__ loopback for callbacks to lockd ... */ /* Just in case we somehow ignored it thus far */ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (sin.sin_port == 0) lp->xid = nsm_xmit_getport(sockfd, &sin, (rpcprog_t)NL_MY_PROG(lp), (rpcvers_t)NL_MY_VERS(lp)); else { struct mon m; memcpy(m.priv, NL_PRIV(lp), SM_PRIV_SIZE); m.mon_id.mon_name = NL_MON_NAME(lp); m.mon_id.my_id.my_name = NULL; m.mon_id.my_id.my_prog = NL_MY_PROG(lp); m.mon_id.my_id.my_vers = NL_MY_VERS(lp); m.mon_id.my_id.my_proc = NL_MY_PROC(lp); lp->xid = nsm_xmit_nlmcall(sockfd, (struct sockaddr *)(char *)&sin, (socklen_t)sizeof(sin), &m, NL_STATE(lp)); } if (lp->xid == 0) { xlog_warn("%s: failed to notify port %d", __func__, ntohs(lp->port)); } NL_TIMES(lp) -= 1; return 1; }