int OseGW_PLT_DestroyReply_cbk(int skt, int len, char *payload, struct ClientInfo *cinfo) { OseGW_UL payload_len = sizeof(struct OseGW_DestroyReply); struct OseGW_TransportData *reply = NULL; struct OseGW_DestroyRequest *destroy_request = NULL; int status = 0; int size = 0; destroy_request = (struct OseGW_DestroyRequest *) payload; size = sizeof(struct OseGW_TransportHdr) + payload_len; reply = (struct OseGW_TransportData *) malloc(size); if (reply == NULL) { return -1; } reply->hdr.payload_type = htonl(OseGW_PLT_DestroyReply); reply->hdr.payload_len = htonl(sizeof(struct OseGW_DestroyReply)); if (ntohl(destroy_request->pid) == cinfo->curr_pid) { LOG(LOG_INFO, "Gateway Client: Destroy: pid: %d", cinfo->curr_pid); reply->payload.destroy_reply.status = htonl(OseGW_StatusOk); } else { LOG(LOG_INFO, "Gateway Client: Destroy: " "<unknown pid: %#lx>\n", (long unsigned int) ntohl(destroy_request->pid)); reply->payload.destroy_reply.status = (uint32_t)htonl((uint32_t)OseGW_StatusErr); } size = sizeof(struct OseGW_TransportHdr) + payload_len; status = send(skt, (void *) reply, size, 0); if (status == size) { LOG(LOG_INFO,"Gateway Client: replying DestroyReply " "on socket %d", skt); } else { syslog(LOG_INFO,"Gateway Client: failed replying" " DestroyReply on socket %d", skt); } free(reply); close(cinfo->sd); linx_close(cinfo->linx); exit(EXIT_SUCCESS); }
void server_main() { LINX_SIGSELECT sigsel_any[] = { 0 }; LINX *linx; LINX_SPID client; union LINX_SIGNAL *sig; printf("Server started.\n"); /* Open LINX socket */ linx = linx_open(SERVER_NAME, 0, NULL); if (linx == NULL) { ERR("linx_open() failed"); } for (;;) { /* Wait until a signal arrives */ if (linx_receive_w_tmo(linx, &sig, IDLE_TIMEOUT, sigsel_any) == -1) { ERR("linx_receive() failed"); } if (sig == LINX_NIL) { printf("Server: Idle too long, terminating.\n"); if (linx_close(linx) == -1) { ERR("linx_close() failed"); } break; } switch (sig->sig_no) { case REQUEST_SIG: { printf("Server: REQUEST_SIG received.\n"); client = linx_sender(linx, &sig); if (client == LINX_ILLEGAL_SPID) { ERR("linx_sender() failed"); } /* Use same signal for REPLY, just change the * signal number */ printf("Server: Sending REPLY_SIG.\n"); sig->sig_no = REPLY_SIG; if (linx_send(linx, &sig, client) == -1) { ERR("linx_send() failed."); exit(1); } break; } default: { printf("Server: Unexpected signal received " "(sig_no = %d) - ignored\n", sig->sig_no); if (linx_free_buf(linx, &sig) == -1) { ERR("linx_free_buf() failed"); } break; } } } }
int OseGW_PLT_HuntReply_cbk(int skt, int len, char *payload, struct ClientInfo *cinfo) { OseGW_UL payload_len = sizeof(struct OseGW_HuntReply); struct OseGW_TransportData *reply = NULL; struct OseGW_HuntRequest *hunt_request = (struct OseGW_HuntRequest *) payload; union LINX_SIGNAL *hunt_sig = NULL; const LINX_SIGSELECT hunt_sigsel[] = { 1, LINX_OS_HUNT_SIG }; LINX *gws_hunter; PROCESS pid = 0; int status = 0; int size = 0; /*Fill the header */ size = sizeof(struct OseGW_TransportHdr) + payload_len; reply = (struct OseGW_TransportData *) malloc(size); if (reply == NULL) { syslog(LOG_ERR, "Malloc failure in Hunt reply"); return -1; } reply->hdr.payload_type = htonl(OseGW_PLT_HuntReply); reply->hdr.payload_len = htonl(sizeof(struct OseGW_HuntReply)); /* Fill the payload */ hunt_request->user = ntohl(hunt_request->user); hunt_request->sig_len = ntohl(hunt_request->sig_len); hunt_request->name_index = ntohl(hunt_request->name_index); if (hunt_request->sig_len != 0) { hunt_sig = linx_alloc(cinfo->linx, hunt_request->sig_len, ntohl(hunt_request->sig_no)); if (hunt_sig == LINX_NIL) { syslog(LOG_ERR, "Linx alloc failed in Hunt reply"); free(reply); return -1; } size = hunt_request->sig_len - sizeof(SIGSELECT); memcpy(&((char *) hunt_sig)[sizeof(SIGSELECT)], &hunt_request-> data[ntohl(hunt_request->sig_index)], size); /* * This hunt sig will be returned to caller or be cleaned * up when caller closes the gateway socket. */ status = linx_hunt(cinfo->linx, &hunt_request->data [hunt_request->name_index], &hunt_sig); if (status == -1) { free(reply); return status; } } /* * The gateway hunt(...) returns the pid of the hunted process if the * process exist when the hunt is done. The LINX hunt(...) does not so * a hunt/receive_w_tmo/sender is done to get the pid. The gws_hunter * socket is opened to prevent at client from flooding the gw server * with hunt requests that could lead to out-of-memory in the LINX * kernel module. If the hunted process does not exist the hunt is * cleaned up when the gws_hunter socket is closed. */ gws_hunter = linx_open("gws_hunter", 0, NULL); status = linx_hunt(gws_hunter, &hunt_request->data[hunt_request->name_index], NULL); if (status == -1) { free(reply); return status; } status = linx_receive_w_tmo(gws_hunter, &hunt_sig, 0, hunt_sigsel); if (status == -1) { free(reply); return status; } if (hunt_sig != LINX_NIL) { pid = linx_sender(gws_hunter, &hunt_sig); if (pid == LINX_ILLEGAL_SPID) { free(reply); return -1; } linx_free_buf(gws_hunter, &hunt_sig); } /* free up the "hunt" */ linx_close(gws_hunter); reply->payload.hunt_reply.status = htonl(cinfo->status); reply->payload.hunt_reply.pid = htonl(pid); /*Send */ size = sizeof(struct OseGW_TransportHdr) + payload_len; status = send(skt, (void *) reply, size, 0); if (status == size) { LOG(LOG_INFO, "Gateway Client: replying HuntReply " "on socket %d", skt); } else { syslog(LOG_INFO, "Gateway Clinet: failed replying " "HuntReply on socket %d", skt); status = -1; } free(reply); return status; }
int main(int argc, char *argv[]) { LINX *linx; LINX_SPID server_spid; union LINX_SIGNAL *sig; pthread_t server_th; int c; int loop_cnt = LOOP_CNT; int use_linx_api = LINX_SOCKET; size_t msg_size = BURST_SIZE; unsigned long burst_cnt = BURST_CNT; size_t start_msg_size = START_MSG_SIZE; size_t end_msg_size = END_MSG_SIZE; unsigned long throughput_instances = THROUGHPUT_INSTANCES; int iterations = ITERATIONS; LINX_SIGSELECT any_sig[] = { 0 }; char *path = NULL; char *server_name = NULL; int run_attach_test = 0; int run_com_test = 0; int kill_server = 0; int all = 0; int use_pthreads = 0; if (argc < 2) { print_usage(argv[0]); return 0; } while ((c = getopt(argc, argv, "S?p:ac:n:m:b:i:s:e:Alt:qP")) != -1) { switch (c) { case 'S': /* Start server */ server_name = (optarg == NULL ? SERVER_NAME : optarg); break; case 'P': /* Start server as posix thread */ server_name = SERVER_NAME; use_pthreads = 1; break; case 'p': /* Hunt path */ path = optarg; break; case 'a': /* Run attach test */ run_attach_test = 1; break; case 'c': /* Connection test */ run_com_test = atoi(optarg); break; case 'n': /* Loop count */ loop_cnt = atoi(optarg); break; case 'm': /* Message size */ msg_size = atol(optarg); break; case 'b': /* Burst count */ burst_cnt = atol(optarg); break; case 'i': /* Iterations */ iterations = atoi(optarg); break; case 's': /* Start message size */ start_msg_size = atol(optarg); break; case 'e': /* End message size */ end_msg_size = atol(optarg); break; case 'A': /* Run all tests */ all = 1; break; case 'l': /* Use linx api in tests */ use_linx_api = LINX_API; break; case 't': /* Number of instances in throughput */ throughput_instances = atoi(optarg); break; case 'q': /* Quit the server */ kill_server = 1; break; default: print_usage(argv[0]); return 0; } } if(use_pthreads) { kill_server = 1; if (pthread_create(&server_th, NULL, server, (void *)server_name)) { fprintf(stderr, "pthread_create(): %d\n", errno); exit(errno); } } else if (server_name != NULL) { (void)server(server_name); return 0; } /* Path to server */ path = path && *path ? path : CS_PATH SERVER_NAME; /* Hunt for server */ linx = linx_open(CLIENT_NAME, 0, NULL); linx_hunt(linx, path, NULL); linx_receive_w_tmo(linx, &sig, 1000, any_sig); if (sig == NULL) { printf("Hunt failed. No server found at path '%s'.\n" "Is the server started and path ok? " "(Server started with -S option)\n", path); linx_close(linx); return 1; } if (sig->sigNo != LINX_OS_HUNT_SIG) { ERR("Failed to hunt for '%s'", path); linx_free_buf(linx, &sig); linx_close(linx); return 1; } server_spid = linx_sender(linx, &sig); linx_free_buf(linx, &sig); /* Attach to server */ sig = linx_alloc(linx, sizeof(LINX_SIGSELECT), ATTACH_SERV_SIG); linx_attach(linx, &sig, server_spid); if (run_attach_test) { attach_test(linx, path, loop_cnt, server_spid, use_linx_api, use_pthreads); } switch (run_com_test) { case 1: /* Start com test 1 */ linx_bmark_latency(linx, path, loop_cnt, msg_size, msg_size, ONE_ITERATION, server_spid, use_linx_api, use_pthreads); break; case 2: /* Start com test 2 */ linx_bmark_burst(linx, path, loop_cnt, msg_size, msg_size, ONE_ITERATION, burst_cnt, server_spid, use_linx_api, use_pthreads); break; case 3: /* Start com test 3 */ linx_bmark_latency(linx, path, loop_cnt, start_msg_size, end_msg_size, iterations, server_spid, use_linx_api, use_pthreads); break; case 4: /* Start com test 4 */ linx_bmark_burst(linx, path, loop_cnt, start_msg_size, end_msg_size, iterations, burst_cnt, server_spid, use_linx_api, use_pthreads); break; case 5: /* Start com test 5 */ linx_bmark_throughput(path, loop_cnt, msg_size, server_spid, use_linx_api, throughput_instances, use_pthreads); break; default: break; } if (all) { /* All tests */ attach_test(linx, path, loop_cnt, server_spid, use_linx_api, use_pthreads); linx_bmark_latency(linx, path, loop_cnt, msg_size, msg_size, ONE_ITERATION, server_spid, use_linx_api, use_pthreads); linx_bmark_burst(linx, path, loop_cnt, msg_size, msg_size, ONE_ITERATION, burst_cnt, server_spid, use_linx_api, use_pthreads); linx_bmark_latency(linx, path, loop_cnt, start_msg_size, end_msg_size, iterations, server_spid, use_linx_api, use_pthreads); linx_bmark_burst(linx, path, loop_cnt, start_msg_size, end_msg_size, iterations, burst_cnt, server_spid, use_linx_api, use_pthreads); linx_bmark_throughput(path, loop_cnt, msg_size, server_spid, use_linx_api, throughput_instances, use_pthreads); } if (kill_server) { /* If no test argument specified, let server close */ sig = linx_alloc(linx, sizeof(LINX_SIGSELECT), CONN_TERM); linx_send(linx, &sig, server_spid); printf("Waiting for attach from server.\n"); linx_receive(linx, &sig, any_sig); if (sig == LINX_NIL) { ERR("No attach signal was received from the server."); } if (sig->sigNo != ATTACH_SERV_SIG) { ERR("Wrong signal received while waiting for " "attach signal from server."); } linx_free_buf(linx, &sig); /* Close client spid */ linx_close(linx); } if(use_pthreads) pthread_join(server_th, NULL); return 0; }
void *server(void *server_name) { LINX *linx; union LINX_SIGNAL *sig; LINX_SPID client; pid_t pid; LINX_SIGSELECT any_sig[] = { 0 }; unsigned slave_no = 0; char *name = (char *)server_name; if (!(name && *name)) name = SERVER_NAME; PRINT(INFO, "Server master start. Using service name \"%s\"\n", name); linx = linx_open(name, 0, NULL); if (linx == NULL) { ERR("server linx_open failed. (insmod linx.ko done?)"); } for (;;) { linx_receive(linx, &sig, any_sig); if (sig->sigNo == CONN_EST) { uint32_t use_linx_api = ntohl(sig->connEst.use_linx_api); uint32_t use_pthreads = ntohl(sig->connEst.use_pthreads); client = linx_sender(linx, &sig); linx_free_buf(linx, &sig); slave_no++; /* Spawn a test slave handling the * requests from the client */ if (use_pthreads) { pthread_t server_slave_th; struct slave_args *input = malloc(sizeof(*input)); if(input == NULL) { ERR("Failed to allocate memory"); exit(1); } input->client = client; input->slave_no = slave_no; input->use_linx_api = use_linx_api; input->use_pthreads = use_pthreads; if (pthread_create(&server_slave_th, NULL, test_slave_proc, (void *)input)) { fprintf(stderr, "pthread_create(): %d\n", errno); exit(errno); } /* thread frees arguments */ } else { pid = fork(); if (pid < 0) { ERR("server failed to fork. pid %d", pid); exit(1); } if (!pid) { pid = fork(); if (pid < 0) { ERR("server failed to perform second " "fork. pid %d", pid); exit(1); } if (!pid) { struct slave_args arg_; arg_.client = client; arg_.slave_no = slave_no; arg_.use_linx_api = use_linx_api; arg_.use_pthreads = use_pthreads; (void)test_slave_proc((void *)&arg_); exit(0); } exit(0); } wait(NULL); } } else if (sig->sigNo == CONN_TERM) { printf("server_master received conn_term\n"); linx_free_buf(linx, &sig); printf("closing...\n"); linx_close(linx); return NULL; } else { WARN("Ignoring unknown signal %ud", sig->sigNo); linx_free_buf(linx, &sig); } } return NULL; }
static void test_without_linxlib(LINX_SPID client, LINX * linx) { int len, sig_len; struct sockaddr_linx to; socklen_t socklen; int sd = linx_get_descriptor(linx); size_t msg_size = 65536; union LINX_SIGNAL *sig = malloc(msg_size); if (sig == NULL) { ERR("Failed to allocate memory"); exit(1); } socklen = sizeof(struct sockaddr_linx); to.family = AF_LINX; to.spid = LINX_ILLEGAL_SPID; for (;;) { len = sig_len = recvfrom(sd, sig, msg_size, 0, (struct sockaddr *)(void *)&to, &socklen); if (unlikely(len <= 0)) { ERR("Failed to receive a signal(%d, %d)\n", len, errno); continue; } if (unlikely(to.spid != client)) { WARN("Ignoring signal from spid %#x since it is" " not %#x", to.spid, client); continue; } switch (sig->sigNo) { case ECHO_SIG: TRACE(1, "Sending echo"); len = sendto(sd, sig, len, 0, (struct sockaddr *)(void *)&to, socklen); if (unlikely(sig_len != len)) { ERR("sendto returned: %d when asked " "for: %d", len, sig_len); } if (unlikely(len <= 0)) { ERR("Failed to send the echo signal " "(%d, %s)\n", len, strerror(errno)); } break; case TERMINATE_REQ: TRACE(1, "Terminating"); free(sig); linx_close(linx); return; case ATTACH_TEST_REQ: len = sendto(sd, sig, len, 0, (struct sockaddr *)(void *)&to, socklen); if (unlikely(sig_len != len)) { ERR("sendto returned: %d when asked " "for: %d", len, sig_len); } if (unlikely(len <= 0)) { ERR("Failed to send the echo signal " "(%d, %s)\n", len, strerror(errno)); } linx_close(linx); return; case BURST_REQ: { uint32_t sigCnt = ntohl(sig->burstReq.n); uint32_t reply_size = ntohl(sig->burstReq.reply_size); LINX_SIGSELECT reply_sigNo = ntohl(sig->burstReq.reply_sigNo); /* Allocate all signals before sending then to * make the send loop as tight as possible */ sig->burstSig.sigNo = reply_sigNo; while (sigCnt--) { len = sendto(sd, sig, reply_size, 0, (struct sockaddr *)(void *)&to, socklen); if (unlikely (reply_size != (uint32_t) len)) { ERR("sendto returned: %d when " "asked for: %d", len, reply_size); } if (unlikely(len <= 0)) { ERR("Failed to send the echo " "signal (%d, %s)\n", len, strerror(errno)); } } break; } default: WARN("Ignoring unknown signal %ud", sig->sigNo); } } free(sig); }
static void test_with_linxlib(LINX_SPID client, LINX * linx) { LINX_SPID sender; union LINX_SIGNAL *sig; LINX_SIGSELECT any_sig[] = { 0 }; for (;;) { linx_receive(linx, &sig, any_sig); sender = linx_sender(linx, &sig); if (sender != client) { WARN("Ignoring signal from spid %ud", sender); linx_free_buf(linx, &sig); continue; } switch (sig->sigNo) { case ECHO_SIG: TRACE(1, "Sending echo"); linx_send(linx, &sig, client); break; case TERMINATE_REQ: TRACE(1, "Terminating"); linx_free_buf(linx, &sig); linx_close(linx); return; case ATTACH_TEST_REQ: linx_send(linx, &sig, client); linx_close(linx); return; case BURST_REQ: { int sigCnt = ntohl(sig->burstReq.n); int reply_size = ntohl(sig->burstReq.reply_size); LINX_SIGSELECT reply_sigNo = ntohl(sig->burstReq.reply_sigNo); union LINX_SIGNAL *list = 0; linx_free_buf(linx, &sig); /* Allocate all signals before sending then to * make the send loop as tight as possible */ while (sigCnt--) { sig = linx_alloc(linx, reply_size, reply_sigNo); sig->burstSig.sigNo = reply_sigNo; sig->burstSig.next = list; list = sig; } while (list) { sig = list; list = list->burstSig.next; sig->burstSig.next = NULL; linx_send(linx, &sig, client); } break; } default: WARN("Ignoring unknown signal %ud", sig->sigNo); linx_free_buf(linx, &sig); } } }