/* * Remove and return a pointer to the first call on queue 'queue'. However, * if the queue is empty returns NULL. */ struct t_call * dequeue_conind(uu_list_t *queue) { struct t_call *ret; tlx_conn_ind_t *ci = uu_list_first(queue); if (ci == NULL) return (NULL); ret = ci->call; uu_list_remove(queue, ci); free(ci); return (ret); }
/* * Remove a node from a gathered list. */ void changelist_remove(prop_changelist_t *clp, const char *name) { prop_changenode_t *cn; for (cn = uu_list_first(clp->cl_list); cn != NULL; cn = uu_list_next(clp->cl_list, cn)) { if (strcmp(cn->cn_handle->zfs_name, name) == 0) { uu_list_remove(clp->cl_list, cn); zfs_close(cn->cn_handle); free(cn); return; } } }
/* * A counterpart to register_method(), this function stops the monitoring of a * method process for its termination. */ static void unregister_method(method_el_t *me) { /* cancel any timer associated with the method */ if (me->inst->timer_id != -1) cancel_inst_timer(me->inst); /* stop polling on the psinfo file fd */ clear_pollfd(me->fd); (void) close(me->fd); /* remove method record from list */ uu_list_remove(method_list, me); if (me->proto_name != NULL) free(me->proto_name); free(me); }
void internal_detach_property(pgroup_t *pgrp, property_t *prop) { uu_list_remove(pgrp->sc_pgroup_props, prop); }
void internal_detach_pgroup(entity_t *ent, pgroup_t *pgrp) { uu_list_remove(ent->sc_pgroups, pgrp); }
/* * Handle a TLOOK notification received during a t_accept() call. * Returns -1 on failure, else 0. */ static int process_tlook(const char *fmri, tlx_info_t *tlx_info) { int event; int fd = tlx_info->pr_info.listen_fd; debug_msg("Entering process_tlook:"); switch (event = t_look(fd)) { case T_LISTEN: { struct t_call *call; debug_msg("process_tlook: T_LISTEN event"); if ((call = get_new_conind(fd)) == NULL) return (-1); if (queue_conind(tlx_info->conn_ind_queue, call) == -1) { error_msg(gettext("Failed to queue connection " "indication for instance %s"), fmri); (void) t_free((char *)call, T_CALL); return (-1); } break; } case T_DISCONNECT: { /* * Note: In Solaris 2.X (SunOS 5.X) bundled * connection-oriented transport drivers * [ e.g /dev/tcp and /dev/ticots and * /dev/ticotsord (tl)] we do not send disconnect * indications to listening endpoints. * So this will not be seen with endpoints on Solaris * bundled transport devices. However, Streams TPI * allows for this (broken?) behavior and so we account * for it here because of the possibility of unbundled * transport drivers causing this. */ tlx_conn_ind_t *cip; struct t_discon *discon; debug_msg("process_tlook: T_DISCONNECT event"); /* LINTED */ if ((discon = (struct t_discon *) t_alloc(fd, T_DIS, T_ALL)) == NULL) { error_msg("t_alloc: %s", t_strerror(t_errno)); return (-1); } if (t_rcvdis(fd, discon) < 0) { error_msg("t_rcvdis: %s", t_strerror(t_errno)); (void) t_free((char *)discon, T_DIS); return (-1); } /* * Find any queued connection pending that matches this * disconnect notice and remove from the pending queue. */ cip = uu_list_first(tlx_info->conn_ind_queue); while ((cip != NULL) && (cip->call->sequence != discon->sequence)) { cip = uu_list_next(tlx_info->conn_ind_queue, cip); } if (cip != NULL) { /* match found */ uu_list_remove(tlx_info->conn_ind_queue, cip); (void) t_free((char *)cip->call, T_CALL); free(cip); } (void) t_free((char *)discon, T_DIS); break; } case -1: error_msg("t_look: %s", t_errno); return (-1); default: error_msg(gettext("do_tlook: unexpected t_look event: %d"), event); return (-1); } return (0); }
/* * void wait_remove(wait_info_t *, int) * Remove the given wait_info structure from our list, performing various * cleanup operations along the way. If the direct flag is false (meaning * that we are being called with from restarter instance list context) and * the instance should not be ignored, then notify the restarter that the * associated instance has exited. If the wi_ignore flag is true then it * means that the stop was initiated from within svc.startd, rather than * from outside it. * * Since we may no longer be the startd that started this process, we only are * concerned with a waitpid(3C) failure if the wi_parent field is non-zero. */ static void wait_remove(wait_info_t *wi, int direct) { int status; stop_cause_t cause = RSTOP_EXIT; if (waitpid(wi->wi_pid, &status, 0) == -1) { if (wi->wi_parent) log_framework(LOG_INFO, "instance %s waitpid failure: %s\n", wi->wi_fmri, strerror(errno)); } else { if (WEXITSTATUS(status) != 0) { log_framework(LOG_NOTICE, "instance %s exited with status %d\n", wi->wi_fmri, WEXITSTATUS(status)); if (WEXITSTATUS(status) == SMF_EXIT_ERR_CONFIG) cause = RSTOP_ERR_CFG; else cause = RSTOP_ERR_EXIT; } } MUTEX_LOCK(&wait_info_lock); if (wi->wi_fd != -1) { startd_close(wi->wi_fd); wi->wi_fd = -1; } uu_list_remove(wait_info_list, wi); MUTEX_UNLOCK(&wait_info_lock); /* * Make an attempt to clear out any utmpx record associated with this * PID. */ utmpx_mark_dead(wi->wi_pid, status, B_FALSE); if (!direct && !wi->wi_ignore) { /* * Bind wait_hndl lazily. */ if (wait_hndl == NULL) { for (wait_hndl = libscf_handle_create_bound(SCF_VERSION); wait_hndl == NULL; wait_hndl = libscf_handle_create_bound(SCF_VERSION)) { log_error(LOG_INFO, "[wait_remove] Unable to " "bind a new repository handle: %s\n", scf_strerror(scf_error())); (void) sleep(2); } } log_framework(LOG_DEBUG, "wait_remove requesting stop of %s\n", wi->wi_fmri); (void) stop_instance_fmri(wait_hndl, wi->wi_fmri, cause); } uu_list_node_fini(wi, &wi->wi_link, wait_info_pool); startd_free(wi, sizeof (wait_info_t)); }