LINX_SPID create_test_slave(LINX * linx, LINX_SPID server, int use_linx_api, int use_pthreads) { LINX_SPID test_slave_spid; union LINX_SIGNAL *sig; LINX_SIGSELECT any_sig[] = { 0 }; sig = linx_alloc(linx, sizeof(struct connEst), CONN_EST); sig->connEst.use_linx_api = htonl(use_linx_api); sig->connEst.use_pthreads = htonl(use_pthreads); linx_send(linx, &sig, server); linx_receive(linx, &sig, any_sig); if (sig->sigNo != CONN_EST) { ERR("Unknown signal %ud", sig->sigNo); } test_slave_spid = linx_sender(linx, &sig); linx_free_buf(linx, &sig); return test_slave_spid; }
void destroy_test_slave(LINX * linx, LINX_SPID ts) { union LINX_SIGNAL *sig; LINX_SIGSELECT any_sig[] = { 0 }; sig = linx_alloc(linx, sizeof(LINX_SIGSELECT), ATTACH_SLAVE_SIG); linx_attach(linx, &sig, ts); sig = linx_alloc(linx, sizeof(LINX_SIGSELECT), TERMINATE_REQ); TRACE(1, "Terminate request"); linx_send(linx, &sig, ts); linx_receive(linx, &sig, any_sig); if (sig->sigNo != ATTACH_SLAVE_SIG) { ERR("Wrong signal received while waiting for attach signal" " from test slave. %d", sig->sigNo); } linx_free_buf(linx, &sig); }
/* * We end up here due to a osegw_receive, osegw_receive_w_tmo or * osegw_init_async_receive. While we are waiting for a signal, * we must be able to handle "pings" and osegw_cancel_async_receive * from the client. */ int OseGW_PLT_ReceiveRequest_cbk(int skt, int len, char *payload, struct ClientInfo *cinfo) { struct OseGW_ReceiveRequest *req; struct OseGW_TransportHdr thdr; union LINX_SIGNAL *sig; LINX_SIGSELECT *sigsel; int nfds, status, size, linx_skt, sigsel_len; fd_set rfds; struct timeval tv0, tv, *tvp; unsigned int tmo; void *buf; linx_skt = linx_get_descriptor(cinfo->linx); req = (struct OseGW_ReceiveRequest *)payload; sigsel_len = ntohl(req->sigsel_len); buf = NULL; /* 0. This may be a osegw_cancel_async_receive... */ if (sigsel_len == 0) { sig = NULL; size = 0; goto out; } /* 1. Setup signal filter that should be used while polling... */ sigsel = copy_sigselect(req); if (sigsel == NULL) goto e_exit; if (set_sigselect(linx_skt, sigsel) == -1) goto e_exit; /* 2. Setup time-out... */ tmo = ntohl(req->timeout); if (tmo != (unsigned int)~0) { tvp = msec_to_timeval(tmo, &tv); if (gettimeofday(&tv0, NULL) == -1) goto e_exit; } else tvp = NULL; /* Infinite */ again: /* 3. Setup descriptors... */ FD_ZERO(&rfds); FD_SET(linx_skt, &rfds); /* LINX socket */ FD_SET(skt, &rfds); /* TCP socket */ nfds = linx_skt > skt ? linx_skt : skt; /* 4. Wait for a signal, ping or osegw_cancel_async_receive */ status = select(nfds + 1, &rfds, NULL, NULL, tvp); if (status == -1) goto e_exit; if (status == 0) { /* osegw_receive_w_tmo has timed out */ sig = NULL; size = 0; goto out; } if (FD_ISSET(linx_skt, &rfds)) { /* A signal that matches the signal filter is available */ status = linx_receive(cinfo->linx, &sig, sigsel); if (status == -1) goto e_exit; size = linx_sigsize(cinfo->linx, &sig) - sizeof(SIGSELECT); goto out; } if (FD_ISSET(cinfo->sd, &rfds)) { /* Get command */ buf = get_command(skt, &thdr); if (buf == NULL) goto e_exit; switch (thdr.payload_type) { case OseGW_PLT_InterfaceRequest: status = OseGW_PLT_InterfaceRequest_cbk(skt, thdr.payload_len, buf, cinfo); if (status == -1) goto e_exit; /* Compensate for the time spent in select */ if (tvp != NULL) recalc_tmo(tmo, &tv0, &tv); goto again; break; case OseGW_PLT_ReceiveRequest: req = (struct OseGW_ReceiveRequest *)buf; sigsel_len = ntohl(req->sigsel_len); if (sigsel_len != 0) goto e_exit; /* Only cancel async receive is allowed */ sig = NULL; size = 0; goto out; break; default: syslog(LOG_INFO, "Gateway protocol violation detected, " "got type %d while in a receive", thdr.payload_type); goto e_exit; break; } } out: free(buf); free(sigsel); return OseGW_PLT_ReceiveReply_cbk(skt, size, (char *)sig, cinfo); e_exit: free(buf); free(sigsel); return -1; }
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_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); } } }