/* ARGSUSED */ void dhcp_renew(iu_tq_t *tqp, void *arg) { dhcp_lease_t *dlp = arg; dhcp_smach_t *dsmp = dlp->dl_smach; uint32_t t2; dhcpmsg(MSG_VERBOSE, "dhcp_renew: T1 timer expired on %s", dsmp->dsm_name); dlp->dl_t1.dt_id = -1; if (dsmp->dsm_state == RENEWING || dsmp->dsm_state == REBINDING) { dhcpmsg(MSG_DEBUG, "dhcp_renew: already renewing"); release_lease(dlp); return; } /* * Sanity check: don't send packets if we're past T2, or if we're * extremely close. */ t2 = dsmp->dsm_curstart_monosec + dlp->dl_t2.dt_start; if (monosec() + TOO_CLOSE >= t2) { dhcpmsg(MSG_DEBUG, "dhcp_renew: %spast T2 on %s", monosec() > t2 ? "" : "almost ", dsmp->dsm_name); release_lease(dlp); return; } /* * If there isn't an async event pending, or if we can cancel the one * that's there, then try to renew by sending an extension request. If * that fails, we'll try again when the next timer fires. */ if (!async_cancel(dsmp) || !async_start(dsmp, DHCP_EXTEND, B_FALSE) || !dhcp_extending(dsmp)) { if (monosec() + RETRY_DELAY < t2) { /* * Try again in RETRY_DELAY seconds; user command * should be gone. */ init_timer(&dlp->dl_t1, RETRY_DELAY); (void) set_smach_state(dsmp, BOUND); if (!schedule_lease_timer(dlp, &dlp->dl_t1, dhcp_renew)) { dhcpmsg(MSG_INFO, "dhcp_renew: unable to " "reschedule renewal around user command " "on %s; will wait for rebind", dsmp->dsm_name); } } else { dhcpmsg(MSG_DEBUG, "dhcp_renew: user busy on %s; will " "wait for rebind", dsmp->dsm_name); } } release_lease(dlp); }
int main() { struct async_oper op; int a = 0; async_init( &op, func, &a ); getchar(); async_start( &op ); getchar(); async_release( &op ); return 0; }
boolean_t ipc_action_start(dhcp_smach_t *dsmp, ipc_action_t *iareq) { struct ipc_action *ia = &dsmp->dsm_ia; if (ia->ia_fd != -1 || ia->ia_tid != -1 || iareq->ia_fd == -1) { dhcpmsg(MSG_CRIT, "ipc_action_start: attempted restart on %s", dsmp->dsm_name); return (B_FALSE); } if (!async_cancel(dsmp)) { dhcpmsg(MSG_WARNING, "ipc_action_start: unable to cancel " "action on %s", dsmp->dsm_name); return (B_FALSE); } if (iareq->ia_request->timeout == DHCP_IPC_WAIT_DEFAULT) iareq->ia_request->timeout = DHCP_IPC_DEFAULT_WAIT; if (iareq->ia_request->timeout == DHCP_IPC_WAIT_FOREVER) { iareq->ia_tid = -1; } else { iareq->ia_tid = iu_schedule_timer(tq, iareq->ia_request->timeout, ipc_action_timeout, dsmp); if (iareq->ia_tid == -1) { dhcpmsg(MSG_ERROR, "ipc_action_start: failed to set " "timer for %s on %s", dhcp_ipc_type_to_string(iareq->ia_cmd), dsmp->dsm_name); return (B_FALSE); } hold_smach(dsmp); } *ia = *iareq; /* We've taken ownership, so the input request is now invalid */ ipc_action_init(iareq); dhcpmsg(MSG_DEBUG, "ipc_action_start: started %s (command %d) on %s," " buffer length %u", dhcp_ipc_type_to_string(ia->ia_cmd), ia->ia_cmd, dsmp->dsm_name, ia->ia_request == NULL ? 0 : ia->ia_request->data_length); dsmp->dsm_dflags |= DHCP_IF_BUSY; /* This cannot fail due to the async_cancel above */ (void) async_start(dsmp, ia->ia_cmd, B_TRUE); return (B_TRUE); }
/* ARGSUSED */ void dhcp_renew(iu_tq_t *tqp, void *arg) { struct ifslist *ifsp = (struct ifslist *)arg; uint32_t next; ifsp->if_timer[DHCP_T1_TIMER] = -1; if (check_ifs(ifsp) == 0) { (void) release_ifs(ifsp); return; } /* * sanity check: don't send packets if we're past t2. */ if (monosec() > (ifsp->if_curstart_monosec + ifsp->if_t2)) return; next = next_extend_time(ifsp->if_curstart_monosec + ifsp->if_t2); /* * if there isn't an async event pending, then try to renew. */ if (!async_pending(ifsp)) if (async_start(ifsp, DHCP_EXTEND, B_FALSE) != 0) /* * try to send extend. if we don't succeed, * async_timeout() will clean us up. */ (void) dhcp_extending(ifsp); /* * if we're within DHCP_REBIND_MIN seconds of REBINDING, don't * reschedule ourselves. */ if (next == 0) return; /* * no big deal if we can't reschedule; we still have the REBIND * state to save us. */ (void) schedule_ifs_timer(ifsp, DHCP_T1_TIMER, next, dhcp_renew); }
/* ARGSUSED */ void dhcp_expire(iu_tq_t *tqp, void *arg) { struct ifslist *ifsp = (struct ifslist *)arg; ifsp->if_timer[DHCP_LEASE_TIMER] = -1; if (check_ifs(ifsp) == 0) { (void) release_ifs(ifsp); return; } if (async_pending(ifsp)) if (async_cancel(ifsp) == 0) { dhcpmsg(MSG_WARNING, "dhcp_expire: cannot cancel " "current asynchronous command against %s", ifsp->if_name); /* * try to schedule ourselves for callback. * we're really situation critical here * there's not much hope for us if this fails. */ if (iu_schedule_timer(tq, DHCP_EXPIRE_WAIT, dhcp_expire, ifsp) != -1) { hold_ifs(ifsp); return; } dhcpmsg(MSG_CRIT, "dhcp_expire: cannot reschedule " "dhcp_expire to get called back, proceeding..."); } /* * just march on if this fails; at worst someone will be able * to async_start() while we're actually busy with our own * asynchronous transaction. better than not having a lease. */ if (async_start(ifsp, DHCP_START, B_FALSE) == 0) dhcpmsg(MSG_WARNING, "dhcp_expire: cannot start asynchronous " "transaction on %s, continuing...", ifsp->if_name); (void) script_start(ifsp, EVENT_EXPIRE, dhcp_restart_lease, NULL, NULL); }
/* ARGSUSED */ static void ipc_event(iu_eh_t *ehp, int fd, short events, iu_event_id_t id, void *arg) { dhcp_ipc_request_t *request; struct ifslist *ifsp, *primary_ifsp; int error, is_priv = (int)arg; PKT_LIST *plp[2]; dhcp_ipc_type_t cmd; (void) iu_unregister_event(eh, id, NULL); if (dhcp_ipc_recv_request(fd, &request, DHCP_IPC_REQUEST_WAIT) != 0) { dhcpmsg(MSG_ERROR, "ipc_event: dhcp_ipc_recv_request failed"); (void) dhcp_ipc_close(fd); return; } cmd = DHCP_IPC_CMD(request->message_type); if (cmd >= DHCP_NIPC) { send_error_reply(request, DHCP_IPC_E_CMD_UNKNOWN, &fd); return; } /* return EPERM for any of the privileged actions */ if (!is_priv) { switch (cmd) { case DHCP_STATUS: case DHCP_PING: case DHCP_GET_TAG: break; default: dhcpmsg(MSG_WARNING, "ipc_event: privileged ipc " "command (%i) attempted on %s", cmd, request->ifname); send_error_reply(request, DHCP_IPC_E_PERM, &fd); return; } } /* * try to locate the ifs associated with this command. if the * command is DHCP_START or DHCP_INFORM, then if there isn't * an ifs already, make one (there may already be one from a * previous failed attempt to START or INFORM). otherwise, * verify the interface is still valid. */ ifsp = lookup_ifs(request->ifname); switch (cmd) { case DHCP_START: /* FALLTHRU */ case DHCP_INFORM: /* * it's possible that the interface already exists, but * has been abandoned. usually in those cases we should * return DHCP_IPC_E_UNKIF, but that makes little sense * in the case of "start" or "inform", so just ignore * the abandoned interface and start over anew. */ if (ifsp != NULL && verify_ifs(ifsp) == 0) ifsp = NULL; /* * as part of initializing the ifs, insert_ifs() * creates a DLPI stream at ifsp->if_dlpi_fd. */ if (ifsp == NULL) { ifsp = insert_ifs(request->ifname, B_FALSE, &error); if (ifsp == NULL) { send_error_reply(request, error, &fd); return; } } break; default: if (ifsp == NULL) { if (request->ifname[0] == '\0') error = DHCP_IPC_E_NOPRIMARY; else error = DHCP_IPC_E_UNKIF; send_error_reply(request, error, &fd); return; } break; } if (verify_ifs(ifsp) == 0) { send_error_reply(request, DHCP_IPC_E_UNKIF, &fd); return; } if (ifsp->if_dflags & DHCP_IF_BOOTP) { switch (cmd) { case DHCP_EXTEND: case DHCP_RELEASE: case DHCP_INFORM: send_error_reply(request, DHCP_IPC_E_BOOTP, &fd); return; default: break; } } /* * verify that the interface is in a state which will allow the * command. we do this up front so that we can return an error * *before* needlessly cancelling an in-progress transaction. */ if (!ipc_cmd_allowed[ifsp->if_state][cmd]) { send_error_reply(request, DHCP_IPC_E_OUTSTATE, &fd); return; } if ((request->message_type & DHCP_PRIMARY) && is_priv) { if ((primary_ifsp = lookup_ifs("")) != NULL) primary_ifsp->if_dflags &= ~DHCP_IF_PRIMARY; ifsp->if_dflags |= DHCP_IF_PRIMARY; } /* * current design dictates that there can be only one * outstanding transaction per interface -- this simplifies * the code considerably and also fits well with RFC2131. * it is worth classifying the different DHCP commands into * synchronous (those which we will handle now and be done * with) and asynchronous (those which require transactions * and will be completed at an indeterminate time in the * future): * * DROP: removes the agent's management of an interface. * asynchronous as the script program may be invoked. * * PING: checks to see if the agent controls an interface. * synchronous, since no packets need to be sent * to the DHCP server. * * STATUS: returns information about the an interface. * synchronous, since no packets need to be sent * to the DHCP server. * * RELEASE: releases the agent's management of an interface * and brings the interface down. asynchronous as * the script program may be invoked. * * EXTEND: renews a lease. asynchronous, since the agent * needs to wait for an ACK, etc. * * START: starts DHCP on an interface. asynchronous since * the agent needs to wait for OFFERs, ACKs, etc. * * INFORM: obtains configuration parameters for an externally * configured interface. asynchronous, since the * agent needs to wait for an ACK. * * notice that EXTEND, INFORM, START, DROP and RELEASE are * asynchronous. notice also that asynchronous commands may * occur from within the agent -- for instance, the agent * will need to do implicit EXTENDs to extend the lease. in * order to make the code simpler, the following rules apply * for asynchronous commands: * * there can only be one asynchronous command at a time per * interface. the current asynchronous command is managed by * the async_* api: async_start(), async_finish(), * async_timeout(), async_cancel(), and async_pending(). * async_start() starts management of a new asynchronous * command on an interface, which should only be done after * async_pending() is called to check that there are no * pending asynchronous commands on that interface. when the * command is completed, async_finish() should be called. all * asynchronous commands have an associated timer, which calls * async_timeout() when it times out. if async_timeout() * decides that the asynchronous command should be cancelled * (see below), it calls async_cancel() to attempt * cancellation. * * asynchronous commands started by a user command have an * associated ipc_action which provides the agent with * information for how to get in touch with the user command * when the action completes. these ipc_action records also * have an associated timeout which may be infinite. * ipc_action_start() should be called when starting an * asynchronous command requested by a user, which sets up the * timer and keeps track of the ipc information (file * descriptor, request type). when the asynchronous command * completes, ipc_action_finish() should be called to return a * command status code to the user and close the ipc * connection). if the command does not complete before the * timer fires, ipc_action_timeout() is called which closes * the ipc connection and returns DHCP_IPC_E_TIMEOUT to the * user. note that independent of ipc_action_timeout(), * ipc_action_finish() should be called. * * on a case-by-case basis, here is what happens (per interface): * * o when an asynchronous command is requested, then * async_pending() is called to see if there is already * an asynchronous event. if so, the command does not * proceed, and if there is an associated ipc_action, * the user command is sent DHCP_IPC_E_PEND. * * o otherwise, the the transaction is started with * async_start(). if the transaction is on behalf * of a user, ipc_action_start() is called to keep * track of the ipc information and set up the * ipc_action timer. * * o if the command completes normally and before a * timeout fires, then async_finish() is called. * if there was an associated ipc_action, * ipc_action_finish() is called to complete it. * * o if the command fails before a timeout fires, then * async_finish() is called, and the interface is * is returned to a known state based on the command. * if there was an associated ipc_action, * ipc_action_finish() is called to complete it. * * o if the ipc_action timer fires before command * completion, then DHCP_IPC_E_TIMEOUT is returned to * the user. however, the transaction continues to * be carried out asynchronously. * * o if async_timeout() fires before command completion, * then if the command was internal to the agent, it * is cancelled. otherwise, if it was a user command, * then if the user is still waiting for the command * to complete, the command continues and async_timeout() * is rescheduled. */ switch (cmd) { case DHCP_DROP: /* FALLTHRU */ case DHCP_RELEASE: /* FALLTHRU */ case DHCP_EXTEND: /* FALLTHRU */ case DHCP_INFORM: /* FALLTHRU */ case DHCP_START: /* * if shutdown request has been received, send back an error. */ if (shutdown_started) { send_error_reply(request, DHCP_IPC_E_OUTSTATE, &fd); return; } if (async_pending(ifsp)) { send_error_reply(request, DHCP_IPC_E_PEND, &fd); return; } if (ipc_action_start(ifsp, request, fd) == 0) { dhcpmsg(MSG_WARNING, "ipc_event: ipc_action_start " "failed for %s", ifsp->if_name); send_error_reply(request, DHCP_IPC_E_MEMORY, &fd); return; } if (async_start(ifsp, cmd, B_TRUE) == 0) { ipc_action_finish(ifsp, DHCP_IPC_E_MEMORY); return; } break; default: break; } switch (cmd) { case DHCP_DROP: (void) script_start(ifsp, EVENT_DROP, dhcp_drop, NULL, NULL); return; case DHCP_EXTEND: (void) dhcp_extending(ifsp); break; case DHCP_GET_TAG: { dhcp_optnum_t optnum; DHCP_OPT *opt = NULL; boolean_t did_alloc = B_FALSE; PKT_LIST *ack = ifsp->if_ack; /* * verify the request makes sense. */ if (request->data_type != DHCP_TYPE_OPTNUM || request->data_length != sizeof (dhcp_optnum_t)) { send_error_reply(request, DHCP_IPC_E_PROTO, &fd); return; } (void) memcpy(&optnum, request->buffer, sizeof (dhcp_optnum_t)); load_option: switch (optnum.category) { case DSYM_SITE: /* FALLTHRU */ case DSYM_STANDARD: if (optnum.code <= DHCP_LAST_OPT) opt = ack->opts[optnum.code]; break; case DSYM_VENDOR: /* * the test against VS_OPTION_START is broken up into * two tests to avoid compiler warnings under intel. */ if ((optnum.code > VS_OPTION_START || optnum.code == VS_OPTION_START) && optnum.code <= VS_OPTION_END) opt = ack->vs[optnum.code]; break; case DSYM_FIELD: if (optnum.code + optnum.size > sizeof (PKT)) break; /* + 2 to account for option code and length byte */ opt = malloc(optnum.size + 2); if (opt == NULL) { send_error_reply(request, DHCP_IPC_E_MEMORY, &fd); return; } did_alloc = B_TRUE; opt->len = optnum.size; opt->code = optnum.code; (void) memcpy(&opt->value, (caddr_t)ack->pkt + opt->code, opt->len); break; default: send_error_reply(request, DHCP_IPC_E_PROTO, &fd); return; } /* * return the option payload, if there was one. the "+ 2" * accounts for the option code number and length byte. */ if (opt != NULL) { send_data_reply(request, &fd, 0, DHCP_TYPE_OPTION, opt, opt->len + 2); if (did_alloc) free(opt); return; } else if (ack != ifsp->if_orig_ack) { /* * There wasn't any definition for the option in the * current ack, so now retry with the original ack if * the original ack is not the current ack. */ ack = ifsp->if_orig_ack; goto load_option; } /* * note that an "okay" response is returned either in * the case of an unknown option or a known option * with no payload. this is okay (for now) since * dhcpinfo checks whether an option is valid before * ever performing ipc with the agent. */ send_ok_reply(request, &fd); return; } case DHCP_INFORM: dhcp_inform(ifsp); /* next destination: dhcp_acknak() */ return; case DHCP_PING: if (ifsp->if_dflags & DHCP_IF_FAILED) send_error_reply(request, DHCP_IPC_E_FAILEDIF, &fd); else send_ok_reply(request, &fd); return; case DHCP_RELEASE: (void) script_start(ifsp, EVENT_RELEASE, dhcp_release, "Finished with lease.", NULL); return; case DHCP_START: (void) canonize_ifs(ifsp); /* * if we have a valid hostconf lying around, then jump * into INIT_REBOOT. if it fails, we'll end up going * through the whole selecting() procedure again. */ error = read_hostconf(ifsp->if_name, plp, 2); if (error != -1) { ifsp->if_orig_ack = ifsp->if_ack = plp[0]; if (error > 1) { /* * Return indicated we had more than one packet * second one is the original ack. Older * versions of the agent wrote only one ack * to the file, we now keep both the first * ack as well as the last one. */ ifsp->if_orig_ack = plp[1]; } dhcp_init_reboot(ifsp); /* next destination: dhcp_acknak() */ return; } /* * if not debugging, wait for a few seconds before * going into SELECTING. */ if (debug_level == 0) { if (iu_schedule_timer_ms(tq, lrand48() % DHCP_SELECT_WAIT, dhcp_start, ifsp) != -1) { hold_ifs(ifsp); /* next destination: dhcp_start() */ return; } } dhcp_selecting(ifsp); /* next destination: dhcp_requesting() */ return; case DHCP_STATUS: { dhcp_status_t status; status.if_began = monosec_to_time(ifsp->if_curstart_monosec); if (ifsp->if_lease == DHCP_PERM) { status.if_t1 = DHCP_PERM; status.if_t2 = DHCP_PERM; status.if_lease = DHCP_PERM; } else { status.if_t1 = status.if_began + ifsp->if_t1; status.if_t2 = status.if_began + ifsp->if_t2; status.if_lease = status.if_began + ifsp->if_lease; } status.version = DHCP_STATUS_VER; status.if_state = ifsp->if_state; status.if_dflags = ifsp->if_dflags; status.if_sent = ifsp->if_sent; status.if_recv = ifsp->if_received; status.if_bad_offers = ifsp->if_bad_offers; (void) strlcpy(status.if_name, ifsp->if_name, IFNAMSIZ); send_data_reply(request, &fd, 0, DHCP_TYPE_STATUS, &status, sizeof (dhcp_status_t)); return; } default: return; } }
/* ARGSUSED */ void dhcp_expire(iu_tq_t *tqp, void *arg) { dhcp_lif_t *lif = arg; dhcp_smach_t *dsmp; const char *event; dhcpmsg(MSG_VERBOSE, "dhcp_expire: lease timer expired on %s", lif->lif_name); lif->lif_expire.dt_id = -1; if (lif->lif_lease == NULL) { release_lif(lif); return; } set_lif_deprecated(lif); dsmp = lif->lif_lease->dl_smach; if (!async_cancel(dsmp)) { dhcpmsg(MSG_WARNING, "dhcp_expire: cannot cancel current asynchronous command " "on %s", dsmp->dsm_name); /* * Try to schedule ourselves for callback. We're really * situation-critical here; there's not much hope for us if * this fails. */ init_timer(&lif->lif_expire, DHCP_EXPIRE_WAIT); if (schedule_lif_timer(lif, &lif->lif_expire, dhcp_expire)) return; dhcpmsg(MSG_CRIT, "dhcp_expire: cannot reschedule dhcp_expire " "to get called back, proceeding..."); } if (!async_start(dsmp, DHCP_START, B_FALSE)) dhcpmsg(MSG_WARNING, "dhcp_expire: cannot start asynchronous " "transaction on %s, continuing...", dsmp->dsm_name); /* * Determine if this state machine has any non-expired LIFs left in it. * If it doesn't, then this is an "expire" event. Otherwise, if some * valid leases remain, it's a "loss" event. The SOMEEXP case can * occur only with DHCPv6. */ if (expired_lif_state(dsmp) == DHCP_EXP_SOMEEXP) event = EVENT_LOSS6; else if (dsmp->dsm_isv6) event = EVENT_EXPIRE6; else event = EVENT_EXPIRE; /* * just march on if this fails; at worst someone will be able * to async_start() while we're actually busy with our own * asynchronous transaction. better than not having a lease. */ (void) script_start(dsmp, event, dhcp_finish_expire, lif, NULL); }
/* ARGSUSED */ void dhcp_rebind(iu_tq_t *tqp, void *arg) { dhcp_lease_t *dlp = arg; dhcp_smach_t *dsmp = dlp->dl_smach; int nlifs; dhcp_lif_t *lif; boolean_t some_valid; uint32_t expiremax; DHCPSTATE oldstate; dhcpmsg(MSG_VERBOSE, "dhcp_rebind: T2 timer expired on %s", dsmp->dsm_name); dlp->dl_t2.dt_id = -1; if ((oldstate = dsmp->dsm_state) == REBINDING) { dhcpmsg(MSG_DEBUG, "dhcp_renew: already rebinding"); release_lease(dlp); return; } /* * Sanity check: don't send packets if we've already expired on all of * the addresses. We compute the maximum expiration time here, because * it won't matter for v4 (there's only one lease) and for v6 we need * to know when the last lease ages away. */ some_valid = B_FALSE; expiremax = monosec(); lif = dlp->dl_lifs; for (nlifs = dlp->dl_nlifs; nlifs > 0; nlifs--, lif = lif->lif_next) { uint32_t expire; expire = dsmp->dsm_curstart_monosec + lif->lif_expire.dt_start; if (expire > expiremax) { expiremax = expire; some_valid = B_TRUE; } } if (!some_valid) { dhcpmsg(MSG_DEBUG, "dhcp_rebind: all leases expired on %s", dsmp->dsm_name); release_lease(dlp); return; } /* * This is our first venture into the REBINDING state, so reset the * server address. We know the renew timer has already been cancelled * (or we wouldn't be here). */ if (dsmp->dsm_isv6) { dsmp->dsm_server = ipv6_all_dhcp_relay_and_servers; } else { IN6_IPADDR_TO_V4MAPPED(htonl(INADDR_BROADCAST), &dsmp->dsm_server); } /* {Bound,Renew}->rebind transitions cannot fail */ (void) set_smach_state(dsmp, REBINDING); /* * If there isn't an async event pending, or if we can cancel the one * that's there, then try to rebind by sending an extension request. * If that fails, we'll clean up when the lease expires. */ if (!async_cancel(dsmp) || !async_start(dsmp, DHCP_EXTEND, B_FALSE) || !dhcp_extending(dsmp)) { if (monosec() + RETRY_DELAY < expiremax) { /* * Try again in RETRY_DELAY seconds; user command * should be gone. */ init_timer(&dlp->dl_t2, RETRY_DELAY); (void) set_smach_state(dsmp, oldstate); if (!schedule_lease_timer(dlp, &dlp->dl_t2, dhcp_rebind)) { dhcpmsg(MSG_INFO, "dhcp_rebind: unable to " "reschedule rebind around user command on " "%s; lease may expire", dsmp->dsm_name); } } else { dhcpmsg(MSG_WARNING, "dhcp_rebind: user busy on %s; " "will expire", dsmp->dsm_name); } } release_lease(dlp); }
/** * @brief Post-initialization of SDF agent engine (fthread safe) * * Order of initialization (change accordingly): <br> * * 1. init_flash <br> * 2. init_action_home <br> * 3. home_flash_start <br> * 3. async_puts_start <br> * 4. spawn home node fthreads <br> * 5. init_containers <br> * * @return status, SDF_TRUE on success */ SDF_boolean_t agent_engine_post_init(struct sdf_agent_state * state ) { SDF_boolean_t success = SDF_TRUE; /* * Enable the Replication only if my node is part of * N+1, 2way, simple replication */ #ifdef SIMPLE_REPLICATION int grp_type; grp_type = SDFMyGroupGroupTypeFromConfig(); if( (grp_type == SDF_REPLICATION_V1_2_WAY) || (grp_type == SDF_REPLICATION_V1_N_PLUS_1)) { plat_log_msg(20851, LOG_CAT,PLAT_LOG_LEVEL_TRACE," Replication StateMachine Turned ON\n"); state->config.always_replicate = 1; } #endif /* * Initialize the flash subsystem. */ if (success) { success = init_flash(state ); plat_log_msg(20852, LOG_CAT, success ? LOG_LEV : PLAT_LOG_LEVEL_DEBUG, "init_flash = %u", success); } /* * Initialize the action and home protocol threads. */ if (success) { success = init_action_home(state); plat_log_msg(20853, LOG_CAT, success ? LOG_LEV : PLAT_LOG_LEVEL_DEBUG, "init_action_home = %u", success); } if ((!SDFNew_Mode) || SDFEnable_Replication) { /* we don't use any of this stuff in streamlined SDF mode */ /* * Initialize the home flash threads. */ if (success) { success = home_flash_start( state->FlashInitState.pfs ); /* * FIXME: home_flash_start returns 0 as success */ success = ( 0 == success ) ? SDF_TRUE : SDF_FALSE; plat_log_msg(20854, LOG_CAT, success ? LOG_LEV : PLAT_LOG_LEVEL_DEBUG, "home_flash_start = %u", success); } /* * Initialize the replication subsystem. */ // XXX: drew 2008-08-29 conditional until replication is re-fixed if (success && state->config.always_replicate) { success = sdf_replicator_adapter_start(state->ReplicationInitState.adapter); success = ( 0 == success ) ? SDF_TRUE : SDF_FALSE; plat_log_msg(20855, LOG_CAT, success ? LOG_LEV : PLAT_LOG_LEVEL_DEBUG, "sdf_replicator_adapter_start = %u", success); if (success) { struct sdf_replicator *replicator = NULL; replicator = sdf_replicator_adapter_get_replicator(state->ReplicationInitState.adapter); /* Request liveness callbacks from the messaging system */ msg_livecall(1, 1, live_back, replicator); } } } /* * Initialize the async put threads. */ if (success) { success = async_start( state->AsyncPutsInitState.paps ); /* * FIXME: async_puts_start returns 0 as success */ success = success ? SDF_TRUE : SDF_FALSE; plat_log_msg(20856, LOG_CAT, success ? LOG_LEV : PLAT_LOG_LEVEL_DEBUG, "async_puts_start = %u", success); } /* * Initialize the CMC. */ if (success) { // schedule_container_thread(state); success = init_containers(state); plat_log_msg(20857, LOG_CAT, success ? LOG_LEV : PLAT_LOG_LEVEL_DEBUG, "init_containers = %u", success); } /* Declare ourselves alive */ //msg_map_alive(); return (success); }
/* ARGSUSED */ void dhcp_rebind(iu_tq_t *tqp, void *arg) { struct ifslist *ifsp = (struct ifslist *)arg; uint32_t next; ifsp->if_timer[DHCP_T2_TIMER] = -1; if (check_ifs(ifsp) == 0) { (void) release_ifs(ifsp); return; } /* * sanity check: don't send packets if we've already expired. */ if (monosec() > (ifsp->if_curstart_monosec + ifsp->if_lease)) return; next = next_extend_time(ifsp->if_curstart_monosec + ifsp->if_lease); /* * if this is our first venture into the REBINDING state, then * reset the server address. we know the renew timer has * already been cancelled (or we wouldn't be here). */ if (ifsp->if_state == RENEWING) { ifsp->if_state = REBINDING; ifsp->if_server.s_addr = htonl(INADDR_BROADCAST); } /* * if there isn't an async event pending, then try to rebind. */ if (!async_pending(ifsp)) if (async_start(ifsp, DHCP_EXTEND, B_FALSE) != 0) /* * try to send extend. if we don't succeed, * async_timeout() will clean us up. */ (void) dhcp_extending(ifsp); /* * if we're within DHCP_REBIND_MIN seconds of EXPIRE, don't * reschedule ourselves. */ if (next == 0) { dhcpmsg(MSG_WARNING, "dhcp_rebind: lease on %s expires in less " "than %i seconds!", ifsp->if_name, DHCP_REBIND_MIN); return; } if (schedule_ifs_timer(ifsp, DHCP_T2_TIMER, next, dhcp_rebind) == 0) /* * we'll just end up in dhcp_expire(), but it sure sucks. */ dhcpmsg(MSG_CRIT, "dhcp_rebind: cannot reschedule another " "rebind attempt; lease may expire for %s", ifsp->if_name); }