lib/messages.c

Module for internal messaging between Samba daemons. [詳細]

ソースコードを見る。

データ構造

struct  message_rec
struct  dispatch_fns
struct  msg_all
struct  messaging_callback
struct  messaging_context

関数

void gfree_messages (void)
static void sig_usr1 (void)
static void ping_message (int msg_type, struct process_id src, void *buf, size_t len, void *private_data)
BOOL message_init (void)
static TDB_DATA message_key_pid (struct process_id pid)
static NTSTATUS message_notify (struct process_id procid)
static NTSTATUS message_send_pid_internal (struct process_id pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed, unsigned int timeout)
NTSTATUS message_send_pid (struct process_id pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed)
NTSTATUS message_send_pid_with_timeout (struct process_id pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed, unsigned int timeout)
unsigned int messages_pending_for_pid (struct process_id pid)
static BOOL retrieve_all_messages (char **msgs_buf, size_t *total_len)
static BOOL message_recv (char *msgs_buf, size_t total_len, int *msg_type, struct process_id *src, char **buf, size_t *len)
void message_dispatch (void)
void message_register (int msg_type, void(*fn)(int msg_type, struct process_id pid, void *buf, size_t len, void *private_data), void *private_data)
void message_deregister (int msg_type)
static int traverse_fn (TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
BOOL message_send_all (TDB_CONTEXT *conn_tdb, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed, int *n_sent)
 Send a message to all smbd processes.
void message_block (void)
void message_unblock (void)
static int messaging_context_destructor (struct messaging_context *ctx)
messaging_contextmessaging_init (TALLOC_CTX *mem_ctx, struct server_id server_id, struct event_context *ev)
static void messaging_callback (int msg_type, struct process_id pid, void *buf, size_t len, void *private_data)
NTSTATUS messaging_register (struct messaging_context *ctx, void *private_data, uint32_t msg_type, void(*fn)(struct messaging_context *msg, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data))
void messaging_deregister (struct messaging_context *ctx, uint32_t msg_type, void *private_data)
NTSTATUS messaging_send (struct messaging_context *msg, struct server_id server, uint32_t msg_type, DATA_BLOB *data)

変数

static TDB_CONTEXTtdb
static int received_signal


説明

Module for internal messaging between Samba daemons.

The idea is that if a part of Samba wants to do communication with another Samba process then it will do a message_register() of a dispatch function, and use message_send_pid() to send messages to that process.

The dispatch function is given the pid of the sender, and it can use that to reply by message_send_pid(). See ping_message() for a simple example.

Dispatch functions must be able to cope with incoming messages on an *odd* byte boundary.

This system doesn't have any inherent size limitations but is not very efficient for large messages or when messages are sent in very quick succession.

messages.c で定義されています。


関数

void gfree_messages ( void   ) 

messages.c78 行で定義されています。

参照先 dispatch_fns::next.

参照元 gfree_all().

00079 {
00080         struct dispatch_fns *dfn, *next;
00081 
00082         /* delete the dispatch_fns list */
00083         dfn = dispatch_fns;
00084         while( dfn ) {
00085                 next = dfn->next;
00086                 DLIST_REMOVE(dispatch_fns, dfn);
00087                 SAFE_FREE(dfn);
00088                 dfn = next;
00089         }
00090 }

static void sig_usr1 ( void   )  [static]

messages.c96 行で定義されています。

参照先 received_signalsys_select_signal().

参照元 main()message_init().

00097 {
00098         received_signal = 1;
00099         sys_select_signal(SIGUSR1);
00100 }

static void ping_message ( int  msg_type,
struct process_id  src,
void *  buf,
size_t  len,
void *  private_data 
) [static]

messages.c106 行で定義されています。

参照先 message_send_pid()procid_str_static().

参照元 message_init().

00108 {
00109         const char *msg = buf ? (const char *)buf : "none";
00110 
00111         DEBUG(1,("INFO: Received PING message from PID %s [%s]\n",
00112                  procid_str_static(&src), msg));
00113         message_send_pid(src, MSG_PONG, buf, len, True);
00114 }

BOOL message_init ( void   ) 

messages.c120 行で定義されています。

参照先 CatchSignal()lock_path()message_register()ping_message()register_dmalloc_msgs()register_msg_pool_usage()sec_init()sig_usr1()tdbtdb_open_log()tdb_set_max_dead().

参照元 cli_send_mailslot()main()send_message().

00121 {
00122         sec_init();
00123 
00124         if (tdb)
00125                 return True;
00126 
00127         tdb = tdb_open_log(lock_path("messages.tdb"), 
00128                        0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, 
00129                        O_RDWR|O_CREAT,0600);
00130 
00131         if (!tdb) {
00132                 DEBUG(0,("ERROR: Failed to initialise messages database\n"));
00133                 return False;
00134         }
00135 
00136         /* Activate the per-hashchain freelist */
00137         tdb_set_max_dead(tdb, 5);
00138 
00139         CatchSignal(SIGUSR1, SIGNAL_CAST sig_usr1);
00140 
00141         message_register(MSG_PING, ping_message, NULL);
00142 
00143         /* Register some debugging related messages */
00144 
00145         register_msg_pool_usage();
00146         register_dmalloc_msgs();
00147 
00148         return True;
00149 }

static TDB_DATA message_key_pid ( struct process_id  pid  )  [static]

messages.c155 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizeprocid_str_static().

参照元 message_notify()message_send_pid_internal()messages_pending_for_pid()retrieve_all_messages().

00156 {
00157         static char key[20];
00158         TDB_DATA kbuf;
00159 
00160         slprintf(key, sizeof(key)-1, "PID/%s", procid_str_static(&pid));
00161         
00162         kbuf.dptr = (char *)key;
00163         kbuf.dsize = strlen(key)+1;
00164         return kbuf;
00165 }

static NTSTATUS message_notify ( struct process_id  procid  )  [static]

messages.c172 行で定義されています。

参照先 errnomessage_key_pid()process_id::pidrestore_re_uid_fromroot()save_re_uid()set_effective_uid()strerror()tdbtdb_delete().

参照元 message_send_pid_internal().

00173 {
00174         pid_t pid = procid.pid;
00175         int ret;
00176         uid_t euid = geteuid();
00177 
00178         /*
00179          * Doing kill with a non-positive pid causes messages to be
00180          * sent to places we don't want.
00181          */
00182 
00183         SMB_ASSERT(pid > 0);
00184 
00185         if (euid != 0) {
00186                 /* If we're not root become so to send the message. */
00187                 save_re_uid();
00188                 set_effective_uid(0);
00189         }
00190 
00191         ret = kill(pid, SIGUSR1);
00192 
00193         if (euid != 0) {
00194                 /* Go back to who we were. */
00195                 int saved_errno = errno;
00196                 restore_re_uid_fromroot();
00197                 errno = saved_errno;
00198         }
00199 
00200         if (ret == -1) {
00201                 if (errno == ESRCH) {
00202                         DEBUG(2,("pid %d doesn't exist - deleting messages record\n",
00203                                  (int)pid));
00204                         tdb_delete(tdb, message_key_pid(procid));
00205 
00206                         /*
00207                          * INVALID_HANDLE is the closest I can think of -- vl
00208                          */
00209                         return NT_STATUS_INVALID_HANDLE;
00210                 }
00211 
00212                 DEBUG(2,("message to process %d failed - %s\n", (int)pid,
00213                          strerror(errno)));
00214 
00215                 /*
00216                  * No call to map_nt_error_from_unix -- don't want to link in
00217                  * errormap.o into lots of utils.
00218                  */
00219 
00220                 if (errno == EINVAL) return NT_STATUS_INVALID_PARAMETER;
00221                 if (errno == EPERM)  return NT_STATUS_ACCESS_DENIED;
00222                 return NT_STATUS_UNSUCCESSFUL;
00223         }
00224 
00225         return NT_STATUS_OK;
00226 }

static NTSTATUS message_send_pid_internal ( struct process_id  pid,
int  msg_type,
const void *  buf,
size_t  len,
BOOL  duplicates_allowed,
unsigned int  timeout 
) [static]

messages.c232 行で定義されています。

参照先 message_rec::destTDB_DATA::dptrTDB_DATA::dsizeerrnomessage_rec::lenmessage_key_pid()message_notify()message_rec::msg_typemessage_rec::msg_versionprocid_self()procid_to_pid()message_rec::srctdbtdb_append()tdb_chainlock()tdb_chainlock_with_timeout()tdb_chainunlock()tdb_fetch()tdb_store().

参照元 message_send_pid()message_send_pid_with_timeout()messaging_send().

00236 {
00237         TDB_DATA kbuf;
00238         TDB_DATA dbuf;
00239         TDB_DATA old_dbuf;
00240         struct message_rec rec;
00241         char *ptr;
00242         struct message_rec prec;
00243 
00244         /* NULL pointer means implicit length zero. */
00245         if (!buf) {
00246                 SMB_ASSERT(len == 0);
00247         }
00248 
00249         /*
00250          * Doing kill with a non-positive pid causes messages to be
00251          * sent to places we don't want.
00252          */
00253 
00254         SMB_ASSERT(procid_to_pid(&pid) > 0);
00255 
00256         rec.msg_version = MESSAGE_VERSION;
00257         rec.msg_type = msg_type;
00258         rec.dest = pid;
00259         rec.src = procid_self();
00260         rec.len = buf ? len : 0;
00261 
00262         kbuf = message_key_pid(pid);
00263 
00264         dbuf.dptr = (char *)SMB_MALLOC(len + sizeof(rec));
00265         if (!dbuf.dptr) {
00266                 return NT_STATUS_NO_MEMORY;
00267         }
00268 
00269         memcpy(dbuf.dptr, &rec, sizeof(rec));
00270         if (len > 0 && buf)
00271                 memcpy((void *)((char*)dbuf.dptr+sizeof(rec)), buf, len);
00272 
00273         dbuf.dsize = len + sizeof(rec);
00274 
00275         if (duplicates_allowed) {
00276 
00277                 /* If duplicates are allowed we can just append the message and return. */
00278 
00279                 /* lock the record for the destination */
00280                 if (timeout) {
00281                         if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {
00282                                 DEBUG(0,("message_send_pid_internal: failed to get "
00283                                          "chainlock with timeout %ul.\n", timeout));
00284                                 SAFE_FREE(dbuf.dptr);
00285                                 return NT_STATUS_IO_TIMEOUT;
00286                         }
00287                 } else {
00288                         if (tdb_chainlock(tdb, kbuf) == -1) {
00289                                 DEBUG(0,("message_send_pid_internal: failed to get "
00290                                          "chainlock.\n"));
00291                                 SAFE_FREE(dbuf.dptr);
00292                                 return NT_STATUS_LOCK_NOT_GRANTED;
00293                         }
00294                 }       
00295                 tdb_append(tdb, kbuf, dbuf);
00296                 tdb_chainunlock(tdb, kbuf);
00297 
00298                 SAFE_FREE(dbuf.dptr);
00299                 errno = 0;                    /* paranoia */
00300                 return message_notify(pid);
00301         }
00302 
00303         /* lock the record for the destination */
00304         if (timeout) {
00305                 if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {
00306                         DEBUG(0,("message_send_pid_internal: failed to get chainlock "
00307                                  "with timeout %ul.\n", timeout));
00308                         SAFE_FREE(dbuf.dptr);
00309                         return NT_STATUS_IO_TIMEOUT;
00310                 }
00311         } else {
00312                 if (tdb_chainlock(tdb, kbuf) == -1) {
00313                         DEBUG(0,("message_send_pid_internal: failed to get "
00314                                  "chainlock.\n"));
00315                         SAFE_FREE(dbuf.dptr);
00316                         return NT_STATUS_LOCK_NOT_GRANTED;
00317                 }
00318         }       
00319 
00320         old_dbuf = tdb_fetch(tdb, kbuf);
00321 
00322         if (!old_dbuf.dptr) {
00323                 /* its a new record */
00324 
00325                 tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
00326                 tdb_chainunlock(tdb, kbuf);
00327 
00328                 SAFE_FREE(dbuf.dptr);
00329                 errno = 0;                    /* paranoia */
00330                 return message_notify(pid);
00331         }
00332 
00333         /* Not a new record. Check for duplicates. */
00334 
00335         for(ptr = (char *)old_dbuf.dptr; ptr < old_dbuf.dptr + old_dbuf.dsize; ) {
00336                 /*
00337                  * First check if the message header matches, then, if it's a non-zero
00338                  * sized message, check if the data matches. If so it's a duplicate and
00339                  * we can discard it. JRA.
00340                  */
00341 
00342                 if (!memcmp(ptr, &rec, sizeof(rec))) {
00343                         if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {
00344                                 tdb_chainunlock(tdb, kbuf);
00345                                 DEBUG(10,("message_send_pid_internal: discarding "
00346                                           "duplicate message.\n"));
00347                                 SAFE_FREE(dbuf.dptr);
00348                                 SAFE_FREE(old_dbuf.dptr);
00349                                 return NT_STATUS_OK;
00350                         }
00351                 }
00352                 memcpy(&prec, ptr, sizeof(prec));
00353                 ptr += sizeof(rec) + prec.len;
00354         }
00355 
00356         /* we're adding to an existing entry */
00357 
00358         tdb_append(tdb, kbuf, dbuf);
00359         tdb_chainunlock(tdb, kbuf);
00360 
00361         SAFE_FREE(old_dbuf.dptr);
00362         SAFE_FREE(dbuf.dptr);
00363 
00364         errno = 0;                    /* paranoia */
00365         return message_notify(pid);
00366 }

NTSTATUS message_send_pid ( struct process_id  pid,
int  msg_type,
const void *  buf,
size_t  len,
BOOL  duplicates_allowed 
)

messages.c372 行で定義されています。

参照先 message_send_pid_internal().

参照元 _srv_net_sess_del()child_msg_onlinestatus()cli_send_mailslot()debug_message_send()debuglevel_message()fork_child_dc_connect()main()msg_pool_usage()notify_deferred_opens()ping_message()print_queue_update()process_kernel_oplocks()process_oplock_break_message()release_level_2_oplocks_on_change()rename_share_filename()reply_to_oplock_break_requests()reqprofile_message()send_message()shutdown_other_smbds()srv_spoolss_drv_upgrade_printer()srv_spoolss_reset_printerdata()traverse_fn()winbind_msg_offline()winbind_msg_online()winbind_msg_onlinestatus().

00374 {
00375         return message_send_pid_internal(pid, msg_type, buf, len,
00376                                          duplicates_allowed, 0);
00377 }

NTSTATUS message_send_pid_with_timeout ( struct process_id  pid,
int  msg_type,
const void *  buf,
size_t  len,
BOOL  duplicates_allowed,
unsigned int  timeout 
)

messages.c383 行で定義されています。

参照先 message_send_pid_internal().

00386 {
00387         return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed,
00388                                          timeout);
00389 }

unsigned int messages_pending_for_pid ( struct process_id  pid  ) 

messages.c395 行で定義されています。

参照先 bufTDB_DATA::dptrTDB_DATA::dsizemessage_key_pid()tdbtdb_fetch().

00396 {
00397         TDB_DATA kbuf;
00398         TDB_DATA dbuf;
00399         char *buf;
00400         unsigned int message_count = 0;
00401 
00402         kbuf = message_key_pid(pid);
00403 
00404         dbuf = tdb_fetch(tdb, kbuf);
00405         if (dbuf.dptr == NULL || dbuf.dsize == 0) {
00406                 SAFE_FREE(dbuf.dptr);
00407                 return 0;
00408         }
00409 
00410         for (buf = dbuf.dptr; dbuf.dsize > sizeof(struct message_rec);) {
00411                 struct message_rec rec;
00412                 memcpy(&rec, buf, sizeof(rec));
00413                 buf += (sizeof(rec) + rec.len);
00414                 dbuf.dsize -= (sizeof(rec) + rec.len);
00415                 message_count++;
00416         }
00417 
00418         SAFE_FREE(dbuf.dptr);
00419         return message_count;
00420 }

static BOOL retrieve_all_messages ( char **  msgs_buf,
size_t *  total_len 
) [static]

messages.c426 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizemessage_key_pid()pid_to_procid()sys_getpid()tdbtdb_chainlock()tdb_chainunlock()tdb_fetch()tdb_store().

参照元 message_dispatch().

00427 {
00428         TDB_DATA kbuf;
00429         TDB_DATA dbuf;
00430         TDB_DATA null_dbuf;
00431 
00432         ZERO_STRUCT(null_dbuf);
00433 
00434         *msgs_buf = NULL;
00435         *total_len = 0;
00436 
00437         kbuf = message_key_pid(pid_to_procid(sys_getpid()));
00438 
00439         if (tdb_chainlock(tdb, kbuf) == -1)
00440                 return False;
00441 
00442         dbuf = tdb_fetch(tdb, kbuf);
00443         /*
00444          * Replace with an empty record to keep the allocated
00445          * space in the tdb.
00446          */
00447         tdb_store(tdb, kbuf, null_dbuf, TDB_REPLACE);
00448         tdb_chainunlock(tdb, kbuf);
00449 
00450         if (dbuf.dptr == NULL || dbuf.dsize == 0) {
00451                 SAFE_FREE(dbuf.dptr);
00452                 return False;
00453         }
00454 
00455         *msgs_buf = dbuf.dptr;
00456         *total_len = dbuf.dsize;
00457 
00458         return True;
00459 }

static BOOL message_recv ( char *  msgs_buf,
size_t  total_len,
int *  msg_type,
struct process_id src,
char **  buf,
size_t *  len 
) [static]

messages.c465 行で定義されています。

参照先 message_rec::src.

参照元 message_dispatch().

00467 {
00468         struct message_rec rec;
00469         char *ret_buf = *buf;
00470 
00471         *buf = NULL;
00472         *len = 0;
00473 
00474         if (total_len - (ret_buf - msgs_buf) < sizeof(rec))
00475                 return False;
00476 
00477         memcpy(&rec, ret_buf, sizeof(rec));
00478         ret_buf += sizeof(rec);
00479 
00480         if (rec.msg_version != MESSAGE_VERSION) {
00481                 DEBUG(0,("message version %d received (expected %d)\n", rec.msg_version, MESSAGE_VERSION));
00482                 return False;
00483         }
00484 
00485         if (rec.len > 0) {
00486                 if (total_len - (ret_buf - msgs_buf) < rec.len)
00487                         return False;
00488         }
00489 
00490         *len = rec.len;
00491         *msg_type = rec.msg_type;
00492         *src = rec.src;
00493         *buf = ret_buf;
00494 
00495         return True;
00496 }

void message_dispatch ( void   ) 

messages.c505 行で定義されています。

参照先 bufdispatch_fns::fnlenmessage_recv()dispatch_fns::msg_typemessage_rec::msg_typedispatch_fns::nextdispatch_fns::private_dataprocid_to_pid()received_signalretrieve_all_messages()sys_getpid().

参照元 main()open_sockets_smbd()process()process_loop()receive_message_or_smb()start_background_queue()wait_replies().

00506 {
00507         int msg_type;
00508         struct process_id src;
00509         char *buf;
00510         char *msgs_buf;
00511         size_t len, total_len;
00512         int n_handled;
00513 
00514         if (!received_signal)
00515                 return;
00516 
00517         DEBUG(10,("message_dispatch: received_signal = %d\n", received_signal));
00518 
00519         received_signal = 0;
00520 
00521         if (!retrieve_all_messages(&msgs_buf, &total_len))
00522                 return;
00523 
00524         for (buf = msgs_buf; message_recv(msgs_buf, total_len, &msg_type, &src, &buf, &len); buf += len) {
00525                 struct dispatch_fns *dfn;
00526 
00527                 DEBUG(10,("message_dispatch: received msg_type=%d "
00528                           "src_pid=%u\n", msg_type,
00529                           (unsigned int) procid_to_pid(&src)));
00530 
00531                 n_handled = 0;
00532                 for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
00533                         if (dfn->msg_type == msg_type) {
00534                                 DEBUG(10,("message_dispatch: processing message of type %d.\n", msg_type));
00535                                 dfn->fn(msg_type, src,
00536                                         len ? (void *)buf : NULL, len,
00537                                         dfn->private_data);
00538                                 n_handled++;
00539                                 break;
00540                         }
00541                 }
00542                 if (!n_handled) {
00543                         DEBUG(5,("message_dispatch: warning: no handler registed for "
00544                                  "msg_type %d in pid %u\n",
00545                                  msg_type, (unsigned int)sys_getpid()));
00546                 }
00547         }
00548         SAFE_FREE(msgs_buf);
00549 }

void message_register ( int  msg_type,
void(*)(int msg_type, struct process_id pid, void *buf, size_t len, void *private_data)  fn,
void *  private_data 
)

messages.c558 行で定義されています。

参照先 dispatch_fns::fndispatch_fns::msg_typedispatch_fns::next.

参照元 blocking_lock_cancel()debug_init()do_debuglevel()do_ping()do_poolusage()do_profilelevel()do_winbind_onlinestatus()fork_child_dc_connect()fork_domain_child()init_oplocks()main()message_init()messaging_register()nt_printing_init()open_sockets_smbd()profile_setup()push_blocking_lock_request()register_dmalloc_msgs()register_msg_pool_usage()srv_spoolss_replyopenprinter()start_background_queue().

00563 {
00564         struct dispatch_fns *dfn;
00565 
00566         for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
00567                 if (dfn->msg_type == msg_type) {
00568                         dfn->fn = fn;
00569                         return;
00570                 }
00571         }
00572 
00573         dfn = SMB_MALLOC_P(struct dispatch_fns);
00574 
00575         if (dfn != NULL) {
00576 
00577                 ZERO_STRUCTPN(dfn);
00578 
00579                 dfn->msg_type = msg_type;
00580                 dfn->fn = fn;
00581                 dfn->private_data = private_data;
00582 
00583                 DLIST_ADD(dispatch_fns, dfn);
00584         }
00585         else {
00586         
00587                 DEBUG(0,("message_register: Not enough memory. malloc failed!\n"));
00588         }
00589 }

void message_deregister ( int  msg_type  ) 

messages.c595 行で定義されています。

参照先 dispatch_fns::msg_typedispatch_fns::next.

参照元 do_debuglevel()do_ping()do_poolusage()do_profilelevel()do_winbind_onlinestatus()fork_domain_child()messaging_context_destructor()set_domain_online()srv_spoolss_replycloseprinter().

00596 {
00597         struct dispatch_fns *dfn, *next;
00598 
00599         for (dfn = dispatch_fns; dfn; dfn = next) {
00600                 next = dfn->next;
00601                 if (dfn->msg_type == msg_type) {
00602                         DLIST_REMOVE(dispatch_fns, dfn);
00603                         SAFE_FREE(dfn);
00604                         return;
00605                 }
00606         }       
00607 }

static int traverse_fn ( TDB_CONTEXT the_tdb,
TDB_DATA  kbuf,
TDB_DATA  dbuf,
void *  state 
) [static]

messages.c622 行で定義されています。

参照先 msg_all::bufTDB_DATA::dptrTDB_DATA::dsizemsg_all::duplicatesmsg_all::lenmessage_send_pid()msg_all::msg_flagmsg_all::msg_typemsg_all::n_sentprocid_str_static()statustdb_delete().

参照元 brl_forall()clear_unexpected()dump_tdb()dump_wins_subnet_namelist()info_tdb()main()message_send_all()share_mode_forall()wcache_invalidate_cache().

00623 {
00624         struct connections_data crec;
00625         struct msg_all *msg_all = (struct msg_all *)state;
00626         NTSTATUS status;
00627 
00628         if (dbuf.dsize != sizeof(crec))
00629                 return 0;
00630 
00631         memcpy(&crec, dbuf.dptr, sizeof(crec));
00632 
00633         if (crec.cnum != -1)
00634                 return 0;
00635 
00636         /* Don't send if the receiver hasn't registered an interest. */
00637 
00638         if(!(crec.bcast_msg_flags & msg_all->msg_flag))
00639                 return 0;
00640 
00641         /* If the msg send fails because the pid was not found (i.e. smbd died), 
00642          * the msg has already been deleted from the messages.tdb.*/
00643 
00644         status = message_send_pid(crec.pid, msg_all->msg_type,
00645                                   msg_all->buf, msg_all->len,
00646                                   msg_all->duplicates);
00647 
00648         if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
00649                 
00650                 /* If the pid was not found delete the entry from connections.tdb */
00651 
00652                 DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n",
00653                          procid_str_static(&crec.pid), crec.cnum, crec.servicename));
00654                 tdb_delete(the_tdb, kbuf);
00655         }
00656         msg_all->n_sent++;
00657         return 0;
00658 }

BOOL message_send_all ( TDB_CONTEXT conn_tdb,
int  msg_type,
const void *  buf,
size_t  len,
BOOL  duplicates_allowed,
int *  n_sent 
)

Send a message to all smbd processes.

It isn't very efficient, but should be OK for the sorts of applications that use it. When we need efficient broadcast we can add it.

引数:
n_sent Set to the number of messages sent. This should be equal to the number of processes, but be careful for races.
戻り値:
True for success.

messages.c672 行で定義されています。

参照先 msg_all::bufmsg_all::duplicatesmsg_all::lenmsg_all::msg_flagmsg_all::msg_typemsg_all::n_senttdb_traverse()traverse_fn().

参照元 _srv_net_share_add()_srv_net_share_del()_srv_net_share_set_info()add_printer_hook()api_RNetShareAdd()delete_printer_hook()send_message()send_repl_message()send_stat_cache_delete_message()send_sync_message().

00676 {
00677         struct msg_all msg_all;
00678 
00679         msg_all.msg_type = msg_type;
00680         if (msg_type < 1000)
00681                 msg_all.msg_flag = FLAG_MSG_GENERAL;
00682         else if (msg_type > 1000 && msg_type < 2000)
00683                 msg_all.msg_flag = FLAG_MSG_NMBD;
00684         else if (msg_type > 2000 && msg_type < 2100)
00685                 msg_all.msg_flag = FLAG_MSG_PRINT_NOTIFY;
00686         else if (msg_type > 2100 && msg_type < 3000)
00687                 msg_all.msg_flag = FLAG_MSG_PRINT_GENERAL;
00688         else if (msg_type > 3000 && msg_type < 4000)
00689                 msg_all.msg_flag = FLAG_MSG_SMBD;
00690         else
00691                 return False;
00692 
00693         msg_all.buf = buf;
00694         msg_all.len = len;
00695         msg_all.duplicates = duplicates_allowed;
00696         msg_all.n_sent = 0;
00697 
00698         tdb_traverse(conn_tdb, traverse_fn, &msg_all);
00699         if (n_sent)
00700                 *n_sent = msg_all.n_sent;
00701         return True;
00702 }

void message_block ( void   ) 

messages.c709 行で定義されています。

参照先 BlockSignals().

参照元 fork_child_dc_connect()fork_domain_child().

00710 {
00711         BlockSignals(True, SIGUSR1);
00712 }

void message_unblock ( void   ) 

messages.c714 行で定義されています。

参照先 BlockSignals().

参照元 fork_child_dc_connect()fork_domain_child().

00715 {
00716         BlockSignals(False, SIGUSR1);
00717 }

static int messaging_context_destructor ( struct messaging_context ctx  )  [static]

messages.c738 行で定義されています。

参照先 ctxmessage_deregister()messaging_callback::msg_typemessaging_callback::next.

参照元 messaging_init().

00739 {
00740         struct messaging_callback *cb;
00741 
00742         for (cb = ctx->callbacks; cb; cb = cb->next) {
00743                 /*
00744                  * We unconditionally remove all instances of our callback
00745                  * from the tdb basis.
00746                  */
00747                 message_deregister(cb->msg_type);
00748         }
00749         return 0;
00750 }

struct messaging_context* messaging_init ( TALLOC_CTX mem_ctx,
struct server_id  server_id,
struct event_context ev 
)

messages.c752 行で定義されています。

参照先 ctxmessaging_context_destructor().

参照元 smbd_messaging_context().

00755 {
00756         struct messaging_context *ctx;
00757 
00758         if (!(ctx = TALLOC_ZERO_P(mem_ctx, struct messaging_context))) {
00759                 return NULL;
00760         }
00761 
00762         ctx->id = server_id;
00763         talloc_set_destructor(ctx, messaging_context_destructor);
00764         return ctx;
00765 }

static void messaging_callback ( int  msg_type,
struct process_id  pid,
void *  buf,
size_t  len,
void *  private_data 
) [static]

messages.c767 行で定義されています。

参照先 ctxdata_blob_::datamessaging_callback::fniddata_blob_::lengthmessaging_callback::msg_typemessaging_callback::nextmessaging_callback::private_data.

00769 {
00770         struct messaging_context *ctx = talloc_get_type_abort(
00771                 private_data, struct messaging_context);
00772         struct messaging_callback *cb, *next;
00773 
00774         for (cb = ctx->callbacks; cb; cb = next) {
00775                 /*
00776                  * Allow a callback to remove itself
00777                  */
00778                 next = cb->next;
00779 
00780                 if (msg_type == cb->msg_type) {
00781                         DATA_BLOB blob;
00782                         struct server_id id;
00783 
00784                         blob.data = (uint8 *)buf;
00785                         blob.length = len;
00786                         id.id = pid;
00787 
00788                         cb->fn(ctx, cb->private_data, msg_type, id, &blob);
00789                 }
00790         }
00791 }

NTSTATUS messaging_register ( struct messaging_context ctx,
void *  private_data,
uint32_t  msg_type,
void(*)(struct messaging_context *msg, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)  fn 
)

messages.c797 行で定義されています。

参照先 ctxmessaging_callback::fnmessage_register()messaging_callback::msg_typemessaging_callback::private_data.

参照元 notify_init().

00804 {
00805         struct messaging_callback *cb;
00806 
00807         if (!(cb = talloc(ctx, struct messaging_callback))) {
00808                 return NT_STATUS_NO_MEMORY;
00809         }
00810 
00811         cb->msg_type = msg_type;
00812         cb->fn = fn;
00813         cb->private_data = private_data;
00814 
00815         DLIST_ADD(ctx->callbacks, cb);
00816         message_register(msg_type, messaging_callback, ctx);
00817         return NT_STATUS_OK;
00818 }

void messaging_deregister ( struct messaging_context ctx,
uint32_t  msg_type,
void *  private_data 
)

messages.c823 行で定義されています。

参照先 ctxmessaging_callback::msg_typemessaging_callback::nextmessaging_callback::private_data.

参照元 notify_destructor().

00825 {
00826         struct messaging_callback *cb, *next;
00827 
00828         for (cb = ctx->callbacks; cb; cb = next) {
00829                 next = cb->next;
00830                 if ((cb->msg_type == msg_type)
00831                     && (cb->private_data == private_data)) {
00832                         DLIST_REMOVE(ctx->callbacks, cb);
00833                         TALLOC_FREE(cb);
00834                 }
00835         }
00836 }

NTSTATUS messaging_send ( struct messaging_context msg,
struct server_id  server,
uint32_t  msg_type,
DATA_BLOB data 
)

messages.c841 行で定義されています。

参照先 data_blob_::datadata_blob_::lengthmessage_send_pid_internal()server.

参照元 notify_send().

00844 {
00845         return message_send_pid_internal(server.id, msg_type, data->data,
00846                                          data->length, True, 0);
00847 }


変数

TDB_CONTEXT* tdb [static]

messages.c51 行で定義されています。

int received_signal [static]

messages.c52 行で定義されています。

参照元 message_dispatch()sig_usr1().


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