/* make a IRPC call to the drepl task to ask it to get the RID Manager to give us another RID pool. This function just sends the message to the drepl task then returns immediately. It should be called well before we completely run out of RIDs */ static void ridalloc_poke_rid_manager(struct ldb_module *module) { struct messaging_context *msg; struct server_id *server; struct ldb_context *ldb = ldb_module_get_ctx(module); struct loadparm_context *lp_ctx = (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"); TALLOC_CTX *tmp_ctx = talloc_new(module); msg = messaging_client_init(tmp_ctx, lpcfg_messaging_path(tmp_ctx, lp_ctx), ldb_get_event_context(ldb)); if (!msg) { DEBUG(3,(__location__ ": Failed to create messaging context\n")); talloc_free(tmp_ctx); return; } server = irpc_servers_byname(msg, msg, "dreplsrv"); if (!server) { /* this means the drepl service is not running */ talloc_free(tmp_ctx); return; } messaging_send(msg, server[0], MSG_DREPL_ALLOCATE_RID, NULL); /* we don't care if the message got through */ talloc_free(tmp_ctx); }
static void writer_thread() { while (s_port != nullptr) { telemetry_t* packet = serial_interface_next_packet(&serial_interface); if (packet != nullptr) messaging_send(packet, message_flags_dont_send_over_usb); } }
/* A useful function for testing the message system. */ static void ping_message(struct messaging_context *msg, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { DEBUG(1,("INFO: Received PING message from server %u.%u [%.*s]\n", (uint_t)src.node, (uint_t)src.id, (int)data->length, data->data?(const char *)data->data:"")); messaging_send(msg, src, MSG_PONG, data); }
static void ping_message(struct messaging_context *msg, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { NTSTATUS status; status = messaging_send(msg, src, msg_pong, data); if (!NT_STATUS_IS_OK(status)) { printf("pong failed - %s\n", nt_errstr(status)); } }
static void smbd_scavenger_msg(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { struct smbd_scavenger_state *state = talloc_get_type_abort(private_data, struct smbd_scavenger_state); TALLOC_CTX *frame = talloc_stackframe(); struct server_id self = messaging_server_id(msg_ctx); struct scavenger_message *msg = NULL; struct server_id_buf tmp1, tmp2; DEBUG(10, ("smbd_scavenger_msg: %s got message from %s\n", server_id_str_buf(self, &tmp1), server_id_str_buf(src, &tmp2))); if (server_id_equal(&state->parent_id, &self)) { NTSTATUS status; if (!smbd_scavenger_running(state) && !smbd_scavenger_start(state)) { DEBUG(2, ("Failed to start scavenger\n")); goto done; } DEBUG(10, ("forwarding message to scavenger\n")); status = messaging_send(msg_ctx, *state->scavenger_id, msg_type, data); if (!NT_STATUS_IS_OK(status)) { DEBUG(2, ("forwarding message to scavenger failed: " "%s\n", nt_errstr(status))); goto done; } goto done; } if (!state->am_scavenger) { DEBUG(10, ("im not the scavenger: ignore message\n")); goto done; } if (!server_id_equal(&state->parent_id, &src)) { DEBUG(10, ("scavenger: ignore spurious message\n")); goto done; } DEBUG(10, ("scavenger: got a message\n")); msg = (struct scavenger_message*)data->data; scavenger_add_timer(state, msg); done: talloc_free(frame); }
void scavenger_schedule_disconnected(struct files_struct *fsp) { NTSTATUS status; struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx); struct timeval disconnect_time, until; uint64_t timeout_usec; struct scavenger_message msg; DATA_BLOB msg_blob; struct server_id_buf tmp; if (fsp->op == NULL) { return; } nttime_to_timeval(&disconnect_time, fsp->op->global->disconnect_time); timeout_usec = 1000 * fsp->op->global->durable_timeout_msec; until = timeval_add(&disconnect_time, timeout_usec / 1000000, timeout_usec % 1000000); ZERO_STRUCT(msg); msg.file_id = fsp->file_id; msg.open_persistent_id = fsp->op->global->open_persistent_id; msg.until = timeval_to_nttime(&until); DEBUG(10, ("smbd: %s mark file %s as disconnected at %s with timeout " "at %s in %fs\n", server_id_str_buf(self, &tmp), file_id_string_tos(&fsp->file_id), timeval_string(talloc_tos(), &disconnect_time, true), timeval_string(talloc_tos(), &until, true), fsp->op->global->durable_timeout_msec/1000.0)); SMB_ASSERT(server_id_is_disconnected(&fsp->op->global->server_id)); SMB_ASSERT(!server_id_equal(&self, &smbd_scavenger_state->parent_id)); SMB_ASSERT(!smbd_scavenger_state->am_scavenger); msg_blob = data_blob_const(&msg, sizeof(msg)); DEBUG(10, ("send message to scavenger\n")); status = messaging_send(smbd_scavenger_state->msg, smbd_scavenger_state->parent_id, MSG_SMB_SCAVENGER, &msg_blob); if (!NT_STATUS_IS_OK(status)) { struct server_id_buf tmp1, tmp2; DEBUG(2, ("Failed to send message to parent smbd %s " "from %s: %s\n", server_id_str_buf(smbd_scavenger_state->parent_id, &tmp1), server_id_str_buf(self, &tmp2), nt_errstr(status))); } }
NTSTATUS messaging_send_to_children(struct messaging_context *msg_ctx, uint32_t msg_type, DATA_BLOB* data) { NTSTATUS status; struct child_pid *child; for (child = children; child != NULL; child = child->next) { status = messaging_send(msg_ctx, pid_to_procid(child->pid), msg_type, data); if (!NT_STATUS_IS_OK(status)) { return status; } } return NT_STATUS_OK; }
void prefork_warn_active_children(struct messaging_context *msg_ctx, struct prefork_pool *pfp) { const DATA_BLOB ping = data_blob_null; int i; for (i = 0; i < pfp->pool_size; i++) { if (pfp->pool[i].status == PF_WORKER_NONE) { continue; } messaging_send(msg_ctx, pid_to_procid(pfp->pool[i].pid), MSG_PREFORK_PARENT_EVENT, &ping); } }
int prefork_retire_children(struct messaging_context *msg_ctx, struct prefork_pool *pfp, int num_children, time_t age_limit) { const DATA_BLOB ping = data_blob_null; time_t now = time(NULL); struct prefork_oldest *oldest; int i, j; oldest = talloc_array(pfp, struct prefork_oldest, pfp->pool_size); if (!oldest) { return -1; } for (i = 0; i < pfp->pool_size; i++) { oldest[i].num = i; if (pfp->pool[i].status == PF_WORKER_ALIVE || pfp->pool[i].status == PF_WORKER_ACCEPTING) { oldest[i].started = pfp->pool[i].started; } else { oldest[i].started = now; } } qsort(oldest, pfp->pool_size, sizeof(struct prefork_oldest), prefork_sort_oldest); for (i = 0, j = 0; i < pfp->pool_size && j < num_children; i++) { if (((pfp->pool[i].status == PF_WORKER_ALIVE) && (pfp->pool[i].num_clients < 1)) && (pfp->pool[i].started <= age_limit)) { /* tell the child it's time to give up */ DEBUG(5, ("Retiring pid %u!\n", (unsigned int)pfp->pool[i].pid)); pfp->pool[i].cmds = PF_SRV_MSG_EXIT; messaging_send(msg_ctx, pid_to_procid(pfp->pool[i].pid), MSG_PREFORK_PARENT_EVENT, &ping); j++; } } return j; }
NTSTATUS messaging_send_to_children(struct messaging_context *msg_ctx, uint32_t msg_type, DATA_BLOB* data) { NTSTATUS status; struct smbd_parent_context *parent = am_parent; struct smbd_child_pid *child; if (parent == NULL) { return NT_STATUS_INTERNAL_ERROR; } for (child = parent->children; child != NULL; child = child->next) { status = messaging_send(parent->msg_ctx, pid_to_procid(child->pid), msg_type, data); if (!NT_STATUS_IS_OK(status)) { return status; } } return NT_STATUS_OK; }
messaging_send_return_codes messaging_producer_send_timestamp(message_producer_t *producer, message_metadata_t flags, const uint8_t *data, uint32_t timestamp) { if (producer->impl == NULL) { COMPONENT_STATE_UPDATE(avionics_component_messaging, state_error); return messaging_send_invalid_producer; } telemetry_t* packet = telemetry_allocator_alloc(producer->telemetry_allocator, producer->payload_size); if (packet == nullptr) { COMPONENT_STATE_UPDATE(avionics_component_messaging, state_error); return messaging_send_producer_heap_full; } memcpy(packet->payload, data, producer->payload_size); // We have already checked the tag and source don't overlap earlier packet->header.id = producer->packet_id; packet->header.length = (uint8_t) producer->payload_size; packet->header.timestamp = timestamp; return messaging_send(packet, flags); }
/* test ping speed */ static bool test_ping_speed(struct torture_context *tctx) { struct tevent_context *ev; struct messaging_context *msg_client_ctx; struct messaging_context *msg_server_ctx; int ping_count = 0; int pong_count = 0; struct timeval tv; int timelimit = torture_setting_int(tctx, "timelimit", 10); uint32_t msg_ping, msg_exit; lp_set_cmdline(tctx->lp_ctx, "pid directory", "piddir.tmp"); ev = tctx->ev; msg_server_ctx = messaging_init(tctx, lp_messaging_path(tctx, tctx->lp_ctx), cluster_id(0, 1), lp_iconv_convenience(tctx->lp_ctx), ev); torture_assert(tctx, msg_server_ctx != NULL, "Failed to init ping messaging context"); messaging_register_tmp(msg_server_ctx, NULL, ping_message, &msg_ping); messaging_register_tmp(msg_server_ctx, tctx, exit_message, &msg_exit); msg_client_ctx = messaging_init(tctx, lp_messaging_path(tctx, tctx->lp_ctx), cluster_id(0, 2), lp_iconv_convenience(tctx->lp_ctx), ev); torture_assert(tctx, msg_client_ctx != NULL, "msg_client_ctx messaging_init() failed"); messaging_register_tmp(msg_client_ctx, &pong_count, pong_message, &msg_pong); tv = timeval_current(); torture_comment(tctx, "Sending pings for %d seconds\n", timelimit); while (timeval_elapsed(&tv) < timelimit) { DATA_BLOB data; NTSTATUS status1, status2; data.data = discard_const_p(uint8_t, "testing"); data.length = strlen((const char *)data.data); status1 = messaging_send(msg_client_ctx, cluster_id(0, 1), msg_ping, &data); status2 = messaging_send(msg_client_ctx, cluster_id(0, 1), msg_ping, NULL); torture_assert_ntstatus_ok(tctx, status1, "msg1 failed"); ping_count++; torture_assert_ntstatus_ok(tctx, status2, "msg2 failed"); ping_count++; while (ping_count > pong_count + 20) { event_loop_once(ev); } } torture_comment(tctx, "waiting for %d remaining replies (done %d)\n", ping_count - pong_count, pong_count); while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) { event_loop_once(ev); } torture_comment(tctx, "sending exit\n"); messaging_send(msg_client_ctx, cluster_id(0, 1), msg_exit, NULL); torture_assert_int_equal(tctx, ping_count, pong_count, "ping test failed"); torture_comment(tctx, "ping rate of %.0f messages/sec\n", (ping_count+pong_count)/timeval_elapsed(&tv)); talloc_free(msg_client_ctx); talloc_free(msg_server_ctx); return true; }
int main(int argc, char *argv[]) { struct tevent_context *evt_ctx; struct messaging_context *msg_ctx; pid_t pid; int i, n; char buf[12]; int ret; TALLOC_CTX *frame = talloc_stackframe(); load_case_tables(); setup_logging(argv[0], DEBUG_STDOUT); lp_load_global(get_dyn_CONFIGFILE()); if (!(evt_ctx = samba_tevent_context_init(NULL)) || !(msg_ctx = messaging_init(NULL, evt_ctx))) { fprintf(stderr, "could not init messaging context\n"); TALLOC_FREE(frame); exit(1); } if (argc != 3) { fprintf(stderr, "%s: Usage - %s pid count\n", argv[0], argv[0]); TALLOC_FREE(frame); exit(1); } pid = atoi(argv[1]); n = atoi(argv[2]); messaging_register(msg_ctx, NULL, MSG_PONG, pong_message); for (i=0;i<n;i++) { messaging_send(msg_ctx, pid_to_procid(pid), MSG_PING, &data_blob_null); } while (pong_count < i) { ret = tevent_loop_once(evt_ctx); if (ret != 0) { break; } } /* Ensure all messages get through to ourselves. */ pong_count = 0; strlcpy(buf, "1234567890", sizeof(buf)); for (i=0;i<n;i++) { messaging_send(msg_ctx, messaging_server_id(msg_ctx), MSG_PING, &data_blob_null); messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx), MSG_PING,(uint8 *)buf, 11); } /* * We have to loop at least 2 times for * each message as local ping messages are * handled by an immediate callback, that * has to be dispatched, which sends a pong * message, which also has to be dispatched. * Above we sent 2*n messages, which means * we have to dispatch 4*n times. */ while (pong_count < n*2) { ret = tevent_loop_once(evt_ctx); if (ret != 0) { break; } } if (pong_count != 2*n) { fprintf(stderr, "Message count failed (%d).\n", pong_count); } /* Speed testing */ pong_count = 0; { struct timeval tv = timeval_current(); size_t timelimit = n; size_t ping_count = 0; printf("Sending pings for %d seconds\n", (int)timelimit); while (timeval_elapsed(&tv) < timelimit) { if(NT_STATUS_IS_OK(messaging_send_buf( msg_ctx, pid_to_procid(pid), MSG_PING, (uint8 *)buf, 11))) ping_count++; if(NT_STATUS_IS_OK(messaging_send( msg_ctx, pid_to_procid(pid), MSG_PING, &data_blob_null))) ping_count++; while (ping_count > pong_count + 20) { ret = tevent_loop_once(evt_ctx); if (ret != 0) { break; } } } printf("waiting for %d remaining replies (done %d)\n", (int)(ping_count - pong_count), pong_count); while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) { ret = tevent_loop_once(evt_ctx); if (ret != 0) { break; } } if (ping_count != pong_count) { fprintf(stderr, "ping test failed! received %d, sent " "%d\n", pong_count, (int)ping_count); } printf("ping rate of %.0f messages/sec\n", (ping_count+pong_count)/timeval_elapsed(&tv)); } TALLOC_FREE(frame); return (0); }
int main(int argc, char *argv[]) { struct tevent_context *evt_ctx; struct messaging_context *msg_ctx; pid_t pid; int i, n; char buf[12]; int ret; load_case_tables(); setup_logging(argv[0], DEBUG_STDOUT); lp_load(get_dyn_CONFIGFILE(),False,False,False,True); if (!(evt_ctx = tevent_context_init(NULL)) || !(msg_ctx = messaging_init(NULL, procid_self(), evt_ctx))) { fprintf(stderr, "could not init messaging context\n"); exit(1); } if (argc != 3) { fprintf(stderr, "%s: Usage - %s pid count\n", argv[0], argv[0]); exit(1); } pid = atoi(argv[1]); n = atoi(argv[2]); messaging_register(msg_ctx, NULL, MSG_PONG, pong_message); for (i=0;i<n;i++) { messaging_send(msg_ctx, pid_to_procid(pid), MSG_PING, &data_blob_null); } while (pong_count < i) { ret = tevent_loop_once(evt_ctx); if (ret != 0) { break; } } /* Now test that the duplicate filtering code works. */ pong_count = 0; strlcpy(buf, "1234567890", sizeof(buf)); for (i=0;i<n;i++) { messaging_send(msg_ctx, messaging_server_id(msg_ctx), MSG_PING, &data_blob_null); messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx), MSG_PING,(uint8 *)buf, 11); } for (i=0;i<n;i++) { ret = tevent_loop_once(evt_ctx); if (ret != 0) { break; } } if (pong_count != 2) { fprintf(stderr, "Duplicate filter failed (%d).\n", pong_count); } /* Speed testing */ pong_count = 0; { struct timeval tv = timeval_current(); size_t timelimit = n; size_t ping_count = 0; printf("Sending pings for %d seconds\n", (int)timelimit); while (timeval_elapsed(&tv) < timelimit) { if(NT_STATUS_IS_OK(messaging_send_buf( msg_ctx, pid_to_procid(pid), MSG_PING, (uint8 *)buf, 11))) ping_count++; if(NT_STATUS_IS_OK(messaging_send( msg_ctx, pid_to_procid(pid), MSG_PING, &data_blob_null))) ping_count++; while (ping_count > pong_count + 20) { ret = tevent_loop_once(evt_ctx); if (ret != 0) { break; } } } printf("waiting for %d remaining replies (done %d)\n", (int)(ping_count - pong_count), pong_count); while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) { ret = tevent_loop_once(evt_ctx); if (ret != 0) { break; } } if (ping_count != pong_count) { fprintf(stderr, "ping test failed! received %d, sent " "%d\n", pong_count, (int)ping_count); } printf("ping rate of %.0f messages/sec\n", (ping_count+pong_count)/timeval_elapsed(&tv)); } return (0); }