lat_rpc.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*
  2. * lat_rpc.c - simple RPC transaction latency test
  3. *
  4. * Four programs in one -
  5. * server usage: lat_rpc -s
  6. * client usage: lat_rpc hostname
  7. * client usage: lat_rpc hostname tcp
  8. * shutdown: lat_rpc -hostname
  9. *
  10. * Copyright (c) 1994 Larry McVoy. Distributed under the FSF GPL with
  11. * additional restriction that results may published only if
  12. * (1) the benchmark is unmodified, and
  13. * (2) the version in the sccsid below is included in the report.
  14. * Support for this development by Sun Microsystems is gratefully acknowledged.
  15. */
  16. char *id = "$Id$\n";
  17. #include "bench.h"
  18. void client_main(int ac, char **av);
  19. void server_main(void);
  20. void benchmark(char *server, char* protocol);
  21. char *client_rpc_xact_1(char *argp, CLIENT *clnt);
  22. void
  23. doit(CLIENT *cl, char *server, char *protocol)
  24. {
  25. char c = 1;
  26. char *resp;
  27. char buf[1024];
  28. resp = client_rpc_xact_1(&c, cl);
  29. if (!resp) {
  30. sprintf(buf, "%s/%s", server, protocol);
  31. clnt_perror(cl, buf);
  32. exit(1);
  33. }
  34. if (*resp != 123) {
  35. fprintf(stderr, "lat_rpc: got bad data\n");
  36. exit(1);
  37. }
  38. }
  39. /* Default timeout can be changed using clnt_control() */
  40. static struct timeval TIMEOUT = { 0, 25000 };
  41. char *proto[] = { "tcp", "udp", 0 };
  42. int
  43. main(int ac, char **av)
  44. {
  45. CLIENT *cl;
  46. struct timeval tv;
  47. char *server;
  48. char buf[256];
  49. int i;
  50. if (ac != 2 && ac != 3) {
  51. fprintf(stderr, "Usage: %s -s\n OR %s serverhost [proto]\n OR %s -serverhost\n",
  52. av[0], av[0], av[0]);
  53. exit(1);
  54. }
  55. if (!strcmp(av[1], "-s")) {
  56. if (fork() == 0) {
  57. server_main();
  58. }
  59. exit(0);
  60. }
  61. server = av[1][0] == '-' ? &av[1][1] : av[1];
  62. if (av[1][0] == '-') {
  63. cl = clnt_create(server, XACT_PROG, XACT_VERS, proto[1]);
  64. if (!cl) {
  65. clnt_pcreateerror(server);
  66. exit(1);
  67. }
  68. clnt_call(cl, RPC_EXIT, (xdrproc_t)xdr_void, 0,
  69. (xdrproc_t)xdr_void, 0, TIMEOUT);
  70. exit(0);
  71. }
  72. if (ac == 3) {
  73. benchmark(server, av[2]);
  74. } else {
  75. benchmark(server, proto[0]);
  76. benchmark(server, proto[1]);
  77. }
  78. exit(0);
  79. }
  80. void
  81. benchmark(char *server, char* protocol)
  82. {
  83. CLIENT *cl;
  84. char buf[256];
  85. struct timeval tv;
  86. cl = clnt_create(server, XACT_PROG, XACT_VERS, protocol);
  87. if (!cl) {
  88. clnt_pcreateerror(server);
  89. exit(1);
  90. }
  91. if (strcasecmp(protocol, proto[1]) == 0) {
  92. tv.tv_sec = 0;
  93. tv.tv_usec = 2500;
  94. if (!clnt_control(cl, CLSET_RETRY_TIMEOUT, (char *)&tv)) {
  95. clnt_perror(cl, "setting timeout");
  96. exit(1);
  97. }
  98. }
  99. BENCH(doit(cl, server, protocol), MEDIUM);
  100. sprintf(buf, "RPC/%s latency using %s", protocol, server);
  101. micro(buf, get_n());
  102. }
  103. char *
  104. client_rpc_xact_1(char *argp, CLIENT *clnt)
  105. {
  106. static char res;
  107. bzero((void*)&res, sizeof(res));
  108. if (clnt_call(clnt, RPC_XACT, (xdrproc_t)xdr_char,
  109. argp, (xdrproc_t)xdr_char, &res, TIMEOUT) != RPC_SUCCESS) {
  110. return (NULL);
  111. }
  112. return (&res);
  113. }
  114. /*
  115. * The remote procedure[s] that will be called
  116. */
  117. /* ARGSUSED */
  118. char *
  119. rpc_xact_1(msg, transp)
  120. char *msg;
  121. register SVCXPRT *transp;
  122. {
  123. static char r = 123;
  124. return &r;
  125. }
  126. static void xact_prog_1();
  127. void
  128. server_main(void)
  129. {
  130. register SVCXPRT *transp;
  131. GO_AWAY;
  132. (void) pmap_unset(XACT_PROG, XACT_VERS);
  133. transp = svcudp_create(RPC_ANYSOCK);
  134. if (transp == NULL) {
  135. fprintf(stderr, "cannot create udp service.\n");
  136. exit(1);
  137. }
  138. if (!svc_register(transp, XACT_PROG, XACT_VERS, xact_prog_1, IPPROTO_UDP)) {
  139. fprintf(stderr, "unable to register (XACT_PROG, XACT_VERS, udp).\n");
  140. exit(1);
  141. }
  142. transp = svctcp_create(RPC_ANYSOCK, 0, 0);
  143. if (transp == NULL) {
  144. fprintf(stderr, "cannot create tcp service.\n");
  145. exit(1);
  146. }
  147. if (!svc_register(transp, XACT_PROG, XACT_VERS, xact_prog_1, IPPROTO_TCP)) {
  148. fprintf(stderr, "unable to register (XACT_PROG, XACT_VERS, tcp).\n");
  149. exit(1);
  150. }
  151. svc_run();
  152. fprintf(stderr, "svc_run returned\n");
  153. exit(1);
  154. /* NOTREACHED */
  155. }
  156. static void
  157. xact_prog_1(rqstp, transp)
  158. struct svc_req *rqstp;
  159. register SVCXPRT *transp;
  160. {
  161. union {
  162. char rpc_xact_1_arg;
  163. } argument;
  164. char *result;
  165. bool_t (*xdr_argument)(), (*xdr_result)();
  166. char *(*local)();
  167. switch (rqstp->rq_proc) {
  168. case NULLPROC:
  169. (void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
  170. return;
  171. case RPC_XACT:
  172. xdr_argument = xdr_char;
  173. xdr_result = xdr_char;
  174. local = (char *(*)()) rpc_xact_1;
  175. break;
  176. case RPC_EXIT:
  177. (void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
  178. (void) pmap_unset(XACT_PROG, XACT_VERS);
  179. exit(0);
  180. default:
  181. svcerr_noproc(transp);
  182. return;
  183. }
  184. bzero((char *)&argument, sizeof(argument));
  185. if (!svc_getargs(transp, (void *)xdr_argument, (char*)&argument)) {
  186. svcerr_decode(transp);
  187. return;
  188. }
  189. result = (*local)(&argument, rqstp);
  190. if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result, result)) {
  191. svcerr_systemerr(transp);
  192. }
  193. if (!svc_freeargs(transp, (void*)xdr_argument, (char*)&argument)) {
  194. fprintf(stderr, "unable to free arguments\n");
  195. exit(1);
  196. }
  197. return;
  198. }