nmbd/nmbd_elections.c

ソースコードを見る。

関数

static void send_election_dgram (struct subnet_record *subrec, const char *workgroup_name, uint32 criterion, int timeup, const char *server_name)
static void check_for_master_browser_success (struct subnet_record *subrec, struct userdata_struct *userdata, struct nmb_name *answer_name, struct in_addr answer_ip, struct res_rec *rrec)
static void check_for_master_browser_fail (struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *question_name, int fail_code)
void check_master_browser_exists (time_t t)
void run_elections (time_t t)
static BOOL win_election (struct work_record *work, int version, uint32 criterion, int timeup, const char *server_name)
void process_election (struct subnet_record *subrec, struct packet_struct *p, char *buf)
BOOL check_elections (void)
void nmbd_message_election (int msg_type, struct process_id src, void *buf, size_t len, void *private_data)

変数

time_t StartupTime


関数

static void send_election_dgram ( struct subnet_record subrec,
const char *  workgroup_name,
uint32  criterion,
int  timeup,
const char *  server_name 
) [static]

nmbd_elections.c33 行で定義されています。

参照先 subnet_record::bcast_ipglobal_mynamesubnet_record::myipsend_mailslot()skip_string()strupper_m()subnet_record::subnet_name.

参照元 check_for_master_browser_fail()run_elections().

00035 {
00036         pstring outbuf;
00037         unstring srv_name;
00038         char *p;
00039 
00040         DEBUG(2,("send_election_dgram: Sending election packet for workgroup %s on subnet %s\n",
00041                 workgroup_name, subrec->subnet_name ));
00042 
00043         memset(outbuf,'\0',sizeof(outbuf));
00044         p = outbuf;
00045         SCVAL(p,0,ANN_Election); /* Election opcode. */
00046         p++;
00047 
00048         SCVAL(p,0,((criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION));
00049         SIVAL(p,1,criterion);
00050         SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */
00051         p += 13;
00052         unstrcpy(srv_name, server_name);
00053         strupper_m(srv_name);
00054         /* The following call does UNIX -> DOS charset conversion. */
00055         pstrcpy_base(p, srv_name, outbuf);
00056         p = skip_string(outbuf,sizeof(outbuf),p);
00057   
00058         send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
00059                 global_myname(), 0,
00060                 workgroup_name, 0x1e,
00061                 subrec->bcast_ip, subrec->myip, DGRAM_PORT);
00062 }

static void check_for_master_browser_success ( struct subnet_record subrec,
struct userdata_struct userdata,
struct nmb_name answer_name,
struct in_addr  answer_ip,
struct res_rec rrec 
) [static]

nmbd_elections.c68 行で定義されています。

参照先 nmb_name::namepull_ascii_nstring().

参照元 check_master_browser_exists().

00072 {
00073         unstring aname;
00074         pull_ascii_nstring(aname, sizeof(aname), answer_name->name);
00075         DEBUG(3,("check_for_master_browser_success: Local master browser for workgroup %s exists at \
00076 IP %s (just checking).\n", aname, inet_ntoa(answer_ip) ));
00077 }

static void check_for_master_browser_fail ( struct subnet_record subrec,
struct response_record rrec,
struct nmb_name question_name,
int  fail_code 
) [static]

nmbd_elections.c83 行で定義されています。

参照先 find_workgroup_on_subnet()lp_workgroup()nmb_name::namework_record::needelectionpull_ascii_nstring()send_election_dgram()strequal()subnet_record::subnet_namework_record::work_group.

参照元 check_master_browser_exists().

00087 {
00088         unstring workgroup_name;
00089         struct work_record *work;
00090 
00091         pull_ascii_nstring(workgroup_name,sizeof(workgroup_name),question_name->name);
00092 
00093         work = find_workgroup_on_subnet(subrec, workgroup_name);
00094         if(work == NULL) {
00095                 DEBUG(0,("check_for_master_browser_fail: Unable to find workgroup %s on subnet %s.=\n",
00096                         workgroup_name, subrec->subnet_name ));
00097                 return;
00098         }
00099 
00100         if (strequal(work->work_group, lp_workgroup())) {
00101 
00102                 if (lp_local_master()) {
00103                         /* We have discovered that there is no local master
00104                                 browser, and we are configured to initiate
00105                                 an election that we will participate in.
00106                         */
00107                         DEBUG(2,("check_for_master_browser_fail: Forcing election on workgroup %s subnet %s\n",
00108                                 work->work_group, subrec->subnet_name ));
00109 
00110                         /* Setting this means we will participate when the
00111                                 election is run in run_elections(). */
00112                         work->needelection = True;
00113                 } else {
00114                         /* We need to force an election, because we are configured
00115                                 not to become the local master, but we still need one,
00116                                 having detected that one doesn't exist.
00117                         */
00118                         send_election_dgram(subrec, work->work_group, 0, 0, "");
00119                 }
00120         }
00121 }

void check_master_browser_exists ( time_t  t  ) 

nmbd_elections.c128 行で定義されています。

参照先 check_for_master_browser_fail()check_for_master_browser_success()dump_workgroups()lp_workgroup()work_record::nextquery_name()strequal()subnet_record::workgrouplist.

参照元 process().

00129 {
00130         static time_t lastrun=0;
00131         struct subnet_record *subrec;
00132         const char *workgroup_name = lp_workgroup();
00133 
00134         if (!lastrun)
00135                 lastrun = t;
00136 
00137         if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60)))
00138                 return;
00139 
00140         lastrun = t;
00141 
00142         dump_workgroups(False);
00143 
00144         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
00145                 struct work_record *work;
00146 
00147                 for (work = subrec->workgrouplist; work; work = work->next) {
00148                         if (strequal(work->work_group, workgroup_name) && !AM_LOCAL_MASTER_BROWSER(work)) {
00149                                 /* Do a name query for the local master browser on this net. */
00150                                 query_name( subrec, work->work_group, 0x1d,
00151                                         check_for_master_browser_success,
00152                                         check_for_master_browser_fail,
00153                                         NULL);
00154                         }
00155                 }
00156         }
00157 }

void run_elections ( time_t  t  ) 

nmbd_elections.c163 行で定義されています。

参照先 become_local_master_browser()find_name_on_subnet()global_mynamemake_nmb_name()work_record::nextnmb_namestr()send_election_dgram()StartupTimesubnet_record::subnet_namesubnet_record::workgrouplist.

参照元 process().

00164 {
00165         static time_t lastime = 0;
00166   
00167         struct subnet_record *subrec;
00168   
00169         START_PROFILE(run_elections);
00170 
00171         /* Send election packets once every 2 seconds - note */
00172         if (lastime && (t - lastime < 2)) {
00173                 END_PROFILE(run_elections);
00174                 return;
00175         }
00176   
00177         lastime = t;
00178   
00179         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
00180                 struct work_record *work;
00181 
00182                 for (work = subrec->workgrouplist; work; work = work->next) {
00183                         if (work->RunningElection) {
00184                                 /*
00185                                  * We can only run an election for a workgroup if we have
00186                                  * registered the WORKGROUP<1e> name, as that's the name
00187                                  * we must listen to.
00188                                  */
00189                                 struct nmb_name nmbname;
00190 
00191                                 make_nmb_name(&nmbname, work->work_group, 0x1e);
00192                                 if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
00193                                         DEBUG(8,("run_elections: Cannot send election packet yet as name %s not \
00194 yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
00195                                         continue;
00196                                 }
00197 
00198                                 send_election_dgram(subrec, work->work_group, work->ElectionCriterion,
00199                                                 t - StartupTime, global_myname());
00200               
00201                                 if (work->ElectionCount++ >= 4) {
00202                                         /* Won election (4 packets were sent out uncontested. */
00203                                         DEBUG(2,("run_elections: >>> Won election for workgroup %s on subnet %s <<<\n",
00204                                                 work->work_group, subrec->subnet_name ));
00205 
00206                                         work->RunningElection = False;
00207 
00208                                         become_local_master_browser(subrec, work);
00209                                 }
00210                         }
00211                 }
00212         }
00213         END_PROFILE(run_elections);
00214 }

static BOOL win_election ( struct work_record work,
int  version,
uint32  criterion,
int  timeup,
const char *  server_name 
) [static]

nmbd_elections.c220 行で定義されています。

参照先 work_record::ElectionCriterionglobal_mynameStartupTimeStrCaseCmp().

参照元 process_election().

00222 {  
00223         int mytimeup = time(NULL) - StartupTime;
00224         uint32 mycriterion = work->ElectionCriterion;
00225 
00226         /* If local master is false then never win in election broadcasts. */
00227         if(!lp_local_master()) {
00228                 DEBUG(3,("win_election: Losing election as local master == False\n"));
00229                 return False;
00230         }
00231  
00232         DEBUG(4,("win_election: election comparison: %x:%x %x:%x %d:%d %s:%s\n",
00233                         version, ELECTION_VERSION,
00234                         criterion, mycriterion,
00235                         timeup, mytimeup,
00236                         server_name, global_myname()));
00237 
00238         if (version > ELECTION_VERSION)
00239                 return(False);
00240         if (version < ELECTION_VERSION)
00241                 return(True);
00242   
00243         if (criterion > mycriterion)
00244                 return(False);
00245         if (criterion < mycriterion)
00246                 return(True);
00247 
00248         if (timeup > mytimeup)
00249                 return(False);
00250         if (timeup < mytimeup)
00251                 return(True);
00252 
00253         if (StrCaseCmp(global_myname(), server_name) > 0)
00254                 return(False);
00255   
00256         return(True);
00257 }

void process_election ( struct subnet_record subrec,
struct packet_struct p,
char *  buf 
)

nmbd_elections.c263 行で定義されています。

参照先 dgram_packet::dest_namepacket_struct::dgramwork_record::ElectionCountfind_workgroup_on_subnet()packet_struct::iplp_workgroup()nmb_name::namework_record::needelectionpacket_struct::packetpull_ascii_nstring()work_record::RunningElectionstrequal()subnet_record::subnet_nameunbecome_local_master_browser()win_election()work_record::work_group.

参照元 process_browse_packet().

00264 {
00265         struct dgram_packet *dgram = &p->packet.dgram;
00266         int version = CVAL(buf,0);
00267         uint32 criterion = IVAL(buf,1);
00268         int timeup = IVAL(buf,5)/1000;
00269         unstring server_name;
00270         struct work_record *work;
00271         unstring workgroup_name;
00272 
00273         START_PROFILE(election);
00274 
00275         pull_ascii_nstring(server_name, sizeof(server_name), buf+13);
00276         pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name);
00277 
00278         server_name[15] = 0;  
00279 
00280         DEBUG(3,("process_election: Election request from %s at IP %s on subnet %s for workgroup %s.\n",
00281                 server_name,inet_ntoa(p->ip), subrec->subnet_name, workgroup_name ));
00282 
00283         DEBUG(5,("process_election: vers=%d criterion=%08x timeup=%d\n", version,criterion,timeup));
00284 
00285         if(( work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL) {
00286                 DEBUG(0,("process_election: Cannot find workgroup %s on subnet %s.\n",
00287                         workgroup_name, subrec->subnet_name ));
00288                 goto done;
00289         }
00290 
00291         if (!strequal(work->work_group, lp_workgroup())) {
00292                 DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \
00293 is not my workgroup.\n", work->work_group, subrec->subnet_name ));
00294                 goto done;
00295         }
00296 
00297         if (win_election(work, version,criterion,timeup,server_name)) {
00298                 /* We take precedence over the requesting server. */
00299                 if (!work->RunningElection) {
00300                         /* We weren't running an election - start running one. */
00301 
00302                         work->needelection = True;
00303                         work->ElectionCount=0;
00304                 }
00305 
00306                 /* Note that if we were running an election for this workgroup on this
00307                         subnet already, we just ignore the server we take precedence over. */
00308         } else {
00309                 /* We lost. Stop participating. */
00310                 work->needelection = False;
00311 
00312                 if (work->RunningElection || AM_LOCAL_MASTER_BROWSER(work)) {
00313                         work->RunningElection = False;
00314                         DEBUG(3,("process_election: >>> Lost election for workgroup %s on subnet %s <<<\n",
00315                                 work->work_group, subrec->subnet_name ));
00316                         if (AM_LOCAL_MASTER_BROWSER(work))
00317                                 unbecome_local_master_browser(subrec, work, False);
00318                 }
00319         }
00320 done:
00321 
00322         END_PROFILE(election);
00323 }

BOOL check_elections ( void   ) 

nmbd_elections.c332 行で定義されています。

参照先 find_name_on_subnet()make_nmb_name()work_record::nextnmb_namestr()subnet_record::subnet_namesubnet_record::workgrouplist.

参照元 process().

00333 {
00334         struct subnet_record *subrec;
00335         BOOL run_any_election = False;
00336 
00337         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
00338                 struct work_record *work;
00339                 for (work = subrec->workgrouplist; work; work = work->next) {
00340                         run_any_election |= work->RunningElection;
00341 
00342                         /* 
00343                          * Start an election if we have any chance of winning.
00344                          * Note this is a change to the previous code, that would
00345                          * only run an election if nmbd was in the potential browser
00346                          * state. We need to run elections in any state if we're told
00347                          * to. JRA.
00348                          */
00349 
00350                         if (work->needelection && !work->RunningElection && lp_local_master()) {
00351                                 /*
00352                                  * We can only run an election for a workgroup if we have
00353                                  * registered the WORKGROUP<1e> name, as that's the name
00354                                  * we must listen to.
00355                                  */
00356                                 struct nmb_name nmbname;
00357 
00358                                 make_nmb_name(&nmbname, work->work_group, 0x1e);
00359                                 if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
00360                                         DEBUG(8,("check_elections: Cannot send election packet yet as name %s not \
00361 yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
00362                                         continue;
00363                                 }
00364 
00365                                 DEBUG(3,("check_elections: >>> Starting election for workgroup %s on subnet %s <<<\n",
00366                                         work->work_group, subrec->subnet_name ));
00367 
00368                                 work->ElectionCount = 0;
00369                                 work->RunningElection = True;
00370                                 work->needelection = False;
00371                         }
00372                 }
00373         }
00374         return run_any_election;
00375 }

void nmbd_message_election ( int  msg_type,
struct process_id  src,
void *  buf,
size_t  len,
void *  private_data 
)

nmbd_elections.c381 行で定義されています。

参照先 lp_workgroup()MST_NONEMST_POTENTIALwork_record::nextstrequal()subnet_record::workgrouplist.

参照元 main().

00383 {
00384         struct subnet_record *subrec;
00385 
00386         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
00387                 struct work_record *work;
00388                 for (work = subrec->workgrouplist; work; work = work->next) {
00389                         if (strequal(work->work_group, lp_workgroup())) {
00390                                 work->needelection = True;
00391                                 work->ElectionCount=0;
00392                                 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
00393                         }
00394                 }
00395         }
00396 }


変数

time_t StartupTime

nmbd.c50 行で定義されています。

参照元 main()run_elections()win_election().


Sambaに対してSat Aug 29 21:23:53 2009に生成されました。  doxygen 1.4.7