void sync_all_dmbs(time_t t) { static time_t lastrun = 0; struct work_record *work; int count=0; /* Only do this if we are using a WINS server. */ if(we_are_a_wins_client() == False) return; /* Check to see if we are a domain master browser on the unicast subnet. */ work = find_workgroup_on_subnet(unicast_subnet, lp_workgroup()); if (!work) return; if (!AM_DOMAIN_MASTER_BROWSER(work)) return; if ((lastrun != 0) && (t < lastrun + (5 * 60))) return; /* count how many syncs we might need to do */ for (work=unicast_subnet->workgrouplist; work; work = work->next) { if (strcmp(lp_workgroup(), work->work_group)) { count++; } } /* sync with a probability of 1/count */ for (work=unicast_subnet->workgrouplist; work; work = work->next) { if (strcmp(lp_workgroup(), work->work_group)) { unstring dmb_name; if (((unsigned)sys_random()) % count != 0) continue; lastrun = t; if (!work->dmb_name.name[0]) { /* we don't know the DMB - assume it is the same as the unicast local master */ make_nmb_name(&work->dmb_name, work->local_master_browser_name, 0x20); } pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name); DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n", dmb_name, inet_ntoa(work->dmb_addr))); sync_browse_lists(work, dmb_name, work->dmb_name.name_type, work->dmb_addr, False, False); } } }
static bool_t distrib(state_t s, etime_t *delay) { float_t drop_rate = 0.01 ; float_t drop_delay = 0.002 ; float_t p = sys_random(1000000) / 1000000.0 ; if (p < drop_rate) { s->acct_dropped ++ ; return FALSE ; } else { *delay = time_of_float(p * drop_delay) ; return TRUE ; } }
static void upnm_handler(state_t s, event_t e) { switch(event_type(e)) { case EVENT_FAIL: assert(bool_array_super(event_failures(e), s->failed, s->vs->nmembers)) ; bool_array_copy_into(s->failed, event_failures(e), s->vs->nmembers) ; upnm(s, e) ; break ; case EVENT_INIT: dnnm(s, event_timer_time(time_zero())) ; upnm(s, e) ; break ; case EVENT_TIMER: { etime_t time = event_time(e) ; item_t item ; while (priq_get_upto(s->priq, time, NULL, (void**)&item)) { s->acct_delivered ++ ; switch(item->type) { case DROP_UP: { rank_t origin = event_peer(item->u.up.event) ; if (origin >= 0 && array_get(s->failed, origin)) { up_free(item->u.up.event, item->u.up.abv) ; } else { up(s, item->u.up.event, item->u.up.abv) ; } } break ; case DROP_UPNM: upnm(s, item->u.upnm.event) ; break ; OTHERWISE_ABORT() ; } record_free(item) ; } if (time_ge(time, s->next_sweep)) { if (!time_is_zero(s->next_sweep) && sys_random(5) == 1) { rank_t i ; bool_array_t suspects = bool_array_create_init(s->vs->nmembers, FALSE) ; for(i=0;i<s->vs->nmembers;i++) { if (i == s->ls->rank) { continue ; } if (sys_random(4) == 0) { array_set(suspects, i, TRUE) ; } } if (bool_array_exists(suspects, s->vs->nmembers)) { dnnm(s, event_suspect_reason_create(suspects, name)) ; } else { array_free(suspects) ; } } #if 0 /* Suspicions are randomly generated every 0-8 seconds. */ s->next_sweep = time_add(time, time_of_usecs(sys_random(1<<23/*8M*/))) ; #else s->next_sweep = time_add(time, time_of_usecs(sys_random(1<<20/*1M*/))) ; #endif dnnm(s, event_timer_time(s->next_sweep)) ; /* request next sweep */ } upnm(s, e) ; } break ; case EVENT_GOSSIP_EXT: { /*endpt_id_t origin = NULL ;*/ etime_t delay ; /* let origin = getExtender (function | HealGos(_,(_,endpt),_,_) -> Some (Some endpt) | SwitchGos(_,(_,endpt),_) -> Some (Some endpt) | _ -> None ) None ev in */ if (1 /*!origin*/) { upnm(s, e) ; } else if (s->partition) { sys_abort() ; } else if (!distrib(s, &delay)) { event_free(e) ; } else { /* Deliver after a certain delay.... */ etime_t when = time_add(alarm_gettime(s->alarm), delay) ; item_t item = record_create(item_t, item) ; item->type = DROP_UPNM ; item->u.upnm.event = e ; priq_add(s->priq, when, item) ; dnnm(s, event_timer_time(when)) ; } } break ; case EVENT_ACCOUNT: log(("delivered=%d dropped=%d", s->acct_delivered, s->acct_dropped)) ; upnm(s, e) ; break ; EVENT_DUMP_HANDLE() ; default: upnm(s, e) ; break ; } }