1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME 80** 81** server.c 82** 83** FACILITY: 84** 85** Remote Procedure Call (RPC) 86** 87** ABSTRACT: 88** 89** Server main code for performance and system exerciser. 90** 91** 92*/ 93 94#ifdef HAVE_CONFIG_H 95#include <config.h> 96#endif 97 98#include <string.h> 99#include <perf_c.h> 100#include <perf_p.h> 101#ifdef HAVE_GETOPT_H 102#include <getopt.h> 103#endif 104#include <stdlib.h> 105#include <unistd.h> 106 107#ifdef AUTH_KRB 108#include <dce/id_base.h> 109#endif /* AUTH_KRB */ 110 111 112idl_boolean auth = false; /* should we check authentication? */ 113 114unsigned16 server_loops = 1; /* # of times to loop on calls to rpc_server_listen */ 115#define SERVER_LOOP_SLEEP_TIME 15 /* # of secs to sleep after return from " " " */ 116 117idl_boolean use_reserved_threads = false; 118idl_boolean pool_active = false; 119static rpc_thread_pool_handle_t thread_poolh; 120static rpc_if_id_t perfg_if_id; 121static rpc_if_id_t perf_if_id; 122 123int verbose = 1; 124 125unsigned32 socket_buf_size = 0; /* os default */ 126 127rpc_binding_vector_p_t bv; 128 129static struct 130{ 131 unsigned32 count; 132 uuid_p_t uuid[2]; 133} object_vec = 134{ 135 2, 136 { 137 &NilObj, 138 &NilTypeObj, 139 } 140}; 141 142 143/* 144 * M G M T _ A U T H _ F N 145 * 146 * Procedure called to determine whether server will be allowed to be shutdown 147 * remotely. 148 */ 149 150idl_boolean shut_ok = true; 151 152static boolean32 mgmt_auth_fn (h, op, st) 153 154handle_t h __attribute__(unused); 155unsigned32 op; 156unsigned32 *st; 157 158{ 159 boolean32 b; 160 161 b = (op == rpc_c_mgmt_stop_server_listen) ? shut_ok : true; 162 163 VRprintf (1, ("+ In management authorization function: op=%lu, returning \"%s\"\n", 164 op, b ? "true" : "false")); 165 166 *st = b ? rpc_s_ok : rpc_s_mgmt_op_disallowed; 167 168 return (b); 169} 170 171/* 172 * I F _ I D _ I S _ E Q U A L 173 * 174 * return true iff the rpc_if_id_t's are identical. 175 */ 176static idl_boolean if_id_is_equal(ifid1, ifid2) 177rpc_if_id_p_t ifid1, ifid2; 178{ 179 unsigned32 st; 180 181 return (ifid1->vers_major == ifid2->vers_major 182 && ifid1->vers_minor == ifid2->vers_minor 183 && uuid_equal(&ifid1->uuid, &ifid2->uuid, &st)); 184} 185 186/* 187 * T H R E A D _ P O O L _ F N 188 * 189 * Thread pool lookup function. Manage the thread pool(s) 190 * based on a simple object uuid scheme: 191 * for perfg.idl/perfg_op2 for non-nil object id use reserved pool threads 192 * for perf.idl/perf_null_slow use reserved pool threads 193 * otherwise use a default pool thread 194 */ 195static void thread_pool_fn(obj_uuid, if_id, opnum, phandle, status) 196uuid_p_t obj_uuid; 197rpc_if_id_p_t if_id; 198unsigned32 opnum; 199rpc_thread_pool_handle_t *phandle; 200unsigned32 *status; 201{ 202 unsigned32 st; 203 static int once = 1; 204 205 if (once == 1) 206 { 207 VRprintf (1, ("+ Thread pool selection function active\n")); 208 once = 0; 209 } 210 211 if (! use_reserved_threads) 212 { 213 fprintf(stderr, "Thread Pool FN called without being enabled\n"); 214 fprintf(stderr, "Ignoring RPC\n"); 215 *status = -1; 216 } 217 218 *phandle = NULL; 219 if ((opnum == 1 && if_id_is_equal(if_id, &perfg_if_id) 220 && obj_uuid != NULL && ! uuid_is_nil(obj_uuid, &st)) 221 || (opnum == 15 && if_id_is_equal(if_id, &perf_if_id))) 222 { 223 *phandle = thread_poolh; 224 } 225 *status = 0; 226} 227 228/* 229 * S E T U P _ T H R E A D _ P O O L S 230 * 231 * Create a threads pool and register a pool lookup function. 232 * Create a thread pool for the specified interface. 233 * return 0 - ok 234 * -1 - couldn't create pool 235 * 1 - couldn't set thread pool fn 236 */ 237static int setup_thread_pools() 238{ 239 unsigned32 st; 240 241 if (! use_reserved_threads) 242 return 0; 243 244 rpc_server_create_thread_pool(2, &thread_poolh, &st); 245 if (st != error_status_ok) 246 { 247 fprintf(stderr, "Cannot create thread pool - %s\n", error_text(st)); 248 return -1; 249 } 250 pool_active = true; 251 252 rpc_server_set_thread_pool_fn(thread_pool_fn, &st); 253 if (st != error_status_ok) 254 { 255 fprintf(stderr, "Cannot set thread pool fn - %s\n", error_text(st)); 256 return 1; 257 } 258 259 /* 260 * A little more setup for the thread_pool_fn(). 261 */ 262 rpc_if_inq_id(perfg_v1_0_s_ifspec, &perfg_if_id, &st); 263 rpc_if_inq_id(perf_v2_0_s_ifspec, &perf_if_id, &st); 264 265 return 0; 266} 267 268/* 269 * T E A R D O W N _ T H R E A D _ P O O L S 270 * 271 * Free our thread pools and unregister our lookup fn. 272 * return 0 - ok 273 * -1 - couldn't free pool 274 * 1 - couldn't set thread pool fn NULL 275 */ 276int teardown_thread_pools(wait_flg) 277idl_boolean wait_flg; 278{ 279 unsigned32 st; 280 281 if (! use_reserved_threads) 282 return 0; 283 284 rpc_server_set_thread_pool_fn(NULL, &st); 285 if (st != error_status_ok) 286 { 287 fprintf(stderr, "Cannot thread pool fn NULL - %s\n", error_text(st)); 288 return 1; 289 } 290 291 if (pool_active) 292 { 293 pool_active = false; 294 rpc_server_free_thread_pool(&thread_poolh, wait_flg, &st); 295 if (st != error_status_ok) 296 { 297 fprintf(stderr, "Cannot free thread pool - %s\n", error_text(st)); 298 return -1; 299 } 300 } 301 302 return 0; 303} 304 305/* 306 * R E G I S T E R _ I F S 307 * 308 * Register the interfaces we export. 309 */ 310 311static void register_ifs () 312 313{ 314 unsigned32 st; 315 316 rpc_server_register_if (perf_v2_0_s_ifspec, NULL, 317 (rpc_mgr_epv_t) &perf_epv, &st); 318 319 if (st != 0) 320 { 321 fprintf(stderr, "*** Can't register - %s\n", error_text(st)); 322 exit(1); 323 } 324 325 rpc_server_register_if (perfg_v1_0_s_ifspec, (uuid_p_t) &FooType, 326 (rpc_mgr_epv_t) &foo_perfg_epv, &st); 327 328 if (st != 0) 329 { 330 fprintf(stderr, "*** Can't register Foo mgr - %s\n", error_text(st)); 331 exit(1); 332 } 333 334 rpc_server_register_if (perfg_v1_0_s_ifspec, (uuid_p_t) &BarType, 335 (rpc_mgr_epv_t) &bar_perfg_epv, &st); 336 337 if (st != 0) 338 { 339 fprintf(stderr, "*** Can't register Bar mgr - %s\n", error_text(st)); 340 exit(1); 341 } 342} 343 344/* 345 * R E G I S T E R _ O B J S 346 * 347 * Register the bogus objects we handle. 348 */ 349 350static void register_objs () 351 352{ 353 unsigned32 st; 354 355 rpc_object_set_type ((uuid_p_t) &FooObj1, (uuid_p_t) &FooType, &st); 356 357 if (st != 0) 358 { 359 fprintf(stderr, "*** Can't register Foo1 object - %s\n", error_text(st)); 360 exit(1); 361 } 362 363 rpc_object_set_type ((uuid_p_t) &BarObj1, (uuid_p_t) &BarType, &st); 364 365 if (st != 0) 366 { 367 fprintf(stderr, "*** Can't register Bar1 object - %s\n", error_text(st)); 368 exit(1); 369 } 370 371 rpc_object_set_type ((uuid_p_t) &FooObj2, (uuid_p_t) &FooType, &st); 372 373 if (st != 0) 374 { 375 fprintf(stderr, "*** Can't register Foo1 object - %s\n", error_text(st)); 376 exit(1); 377 } 378 379 rpc_object_set_type ((uuid_p_t) &BarObj2, (uuid_p_t) &BarType, &st); 380 381 if (st != 0) 382 { 383 fprintf(stderr, "*** Can't register Bar2 object - %s\n", error_text(st)); 384 exit(1); 385 } 386 387 rpc_object_set_type ((uuid_p_t) &ZotObj, (uuid_p_t) &ZotType, &st); 388 389 if (st != 0) 390 { 391 fprintf(stderr, "*** Can't register Zot object - %s\n", error_text(st)); 392 exit(1); 393 } 394} 395 396/* 397 * G E T _ S O C K E T S 398 * 399 * Create sockets to listen on. 400 */ 401 402static void get_sockets (argc, argv, max_calls) 403 404int argc; 405char *argv[]; 406unsigned32 max_calls; 407 408{ 409 unsigned32 st; 410 unsigned long i; 411 412 i = 2; 413 414 while (i < (unsigned)argc) 415 { 416 if (strcmp(argv[i], "all") == 0) 417 { 418 rpc_server_use_all_protseqs (max_calls, &st); 419 } 420 else if (strcmp(argv[i], "allif") == 0) 421 { 422 rpc_server_use_all_protseqs_if (max_calls, perf_v2_0_s_ifspec, &st); 423 } 424 else if (strcmp(argv[i], "notif") == 0) 425 { 426 rpc_server_use_protseq 427 ((unsigned_char_p_t) argv[i + 1], max_calls, &st); 428 i += 1; 429 } 430 else if (strcmp(argv[i], "ep") == 0) 431 { 432 rpc_server_use_protseq_ep 433 ((unsigned_char_p_t) argv[i + 1], max_calls, 434 (unsigned_char_p_t) argv[i + 2], &st); 435 i += 2; 436 } 437 else 438 { 439 rpc_server_use_protseq_if 440 ((unsigned_char_p_t) argv[i], max_calls, perf_v2_0_s_ifspec, &st); 441 } 442 443 if (st != rpc_s_ok) 444 { 445 fprintf(stderr, "*** Can't use_protseq - %s\n", error_text(st)); 446 exit(1); 447 } 448 449 i += 1; 450 } 451 452 rpc_server_inq_bindings(&bv, &st); 453 454 if (st != rpc_s_ok) 455 { 456 fprintf(stderr, "*** Can't inq_bindings - %lx\n", st); 457 exit(1); 458 } 459 460 for (i = 0; i < bv->count; i++) 461 { 462 unsigned_char_p_t sb; 463 464 rpc_binding_to_string_binding (bv->binding_h[i], &sb, &st); 465 466 if (st != rpc_s_ok) 467 { 468 fprintf(stderr, "*** Can't get string binding - %lx\n", st); 469 exit(1); 470 } 471 472 VRprintf (1, ("Got binding: %s\n", sb)); 473 474 rpc_string_free(&sb, &st); 475 } 476} 477 478/* 479 * U S A G E 480 */ 481 482void usage(void) 483 484{ 485 fprintf(stderr, "usage: server [-sD] [-S <server loops>] [-d <debug switches>]\n"); 486 fprintf(stderr, " [-p <authn proto>,<principal>[,<keytab file>]] [-v <verbose level>]\n"); 487 fprintf(stderr, " [-B <bufsize>\n"); 488 fprintf(stderr, " <max calls> <protseq spec> [<protseq spec> ...]\n"); 489 fprintf(stderr, " -d: Turns on NCK runtime debug output\n"); 490 fprintf(stderr, " -D: Turns on default NCK runtime debug output\n"); 491 fprintf(stderr, " -s: Disable remote shutdown\n"); 492 fprintf(stderr, " -S: Number of times to run listen loop (default = 1)\n"); 493 fprintf(stderr, " -p: Accept authentication using <authn proto> to <principal>\n"); 494 fprintf(stderr, " -r: Use reserved threads\n"); 495 fprintf(stderr, " -e: Register with endpoint map at startup\n"); 496 fprintf(stderr, " -B: Set CN TCP socket buffer size (bytes)\n"); 497 fprintf(stderr, " -b: Register B interface with endpoint map at startup\n"); 498 fprintf(stderr, " <protseq spec> is one of:\n"); 499 fprintf(stderr, " <protseq> (rpc_server_use_protseq_if)\n"); 500 fprintf(stderr, " all (rpc_server_use_all_protseqs)\n"); 501 fprintf(stderr, " allif (rpc_server_use_all_protseqs_if)\n"); 502 fprintf(stderr, " ep <endpoint> (rpc_server_use_protseq_ep)\n"); 503 fprintf(stderr, " notif <protseq> (rpc_server_use_protseq)\n"); 504 505 exit(1); 506} 507 508/* 509 * P R I N T _ B I N D I N G _ I N F O 510 * 511 * Print out binding info (location and auth info) for a server binding. This 512 * routine is called (selectively) from manager routines. 513 */ 514 515void print_binding_info(text, h) 516 517char *text; 518handle_t h; 519 520{ 521 unsigned32 st; 522 unsigned32 authn_level, authn_protocol, authz_protocol; 523 unsigned_char_p_t server_princ, client_princ; 524 unsigned_char_p_t name; 525 526 if (h == NULL) 527 { 528 return; 529 } 530 531 rpc_binding_to_string_binding (h, &name, &st); 532 if (st != rpc_s_ok) 533 { 534 fprintf (stderr, "*** Can't convert binding to string binding - %s\n", 535 error_text (st)); 536 exit(1); 537 } 538 539 VRprintf (1, ("+ %s: called from %s ", text, name)); 540 541 rpc_string_free (&name, &st); 542 543 if (verbose <= 1) 544 { 545 VRprintf (1, ("\n")); 546 return; 547 } 548 549 rpc_binding_inq_auth_client 550 (h, (rpc_authz_handle_t *) &client_princ, &server_princ, 551 &authn_level, &authn_protocol, &authz_protocol, &st); 552 553 if (st == rpc_s_binding_has_no_auth) 554 { 555 printf ("(unauthenticated)\n"); 556 } 557 else if (st != rpc_s_ok) 558 { 559 printf ("(can't get auth info - %s)\n", error_text (st)); 560 } 561 else 562 { 563 printf("(authentication info follows)\n"); 564 565 printf(" authn protocol: %s\n authz protocol: %s\n level: %s\n server princ: \"%s\"\n", 566 authn_names[authn_protocol], 567 authz_names[authz_protocol], 568 authn_level_names[authn_level], 569 server_princ == NULL ? "(NULL)" : (char *) server_princ); 570 571 if (server_princ != NULL) 572 { 573 rpc_string_free (&server_princ, &st); 574 } 575 576 switch (authz_protocol) 577 { 578 case rpc_c_authz_name: 579 printf(" client princ: \"%s\"\n", 580 client_princ == NULL ? "(NULL)" : (char *) client_princ); 581 break; 582 583#ifdef AUTH_KRB 584 case rpc_c_authz_dce: 585 { 586 sec_id_pac_t *pac = (sec_id_pac_t *) client_princ; 587 unsigned16 i; 588 589 printf(" PAC: uid %d, gid %d, ngroups %d:", 590 pac->principal.uuid.time_low, 591 pac->group.uuid.time_low, 592 pac->num_groups); 593 for (i = 0; i < pac->num_groups; i++) 594 { 595 printf (" %d", pac->groups[i].uuid.time_low); 596 } 597 printf ("\n"); 598 break; 599 } 600#endif /* AUTH_KRB */ 601 default: 602 printf(" unknown authorization protocol\n"); 603 break; 604 } 605 } 606} 607 608/* 609 * M A I N 610 * 611 * Main program. 612 */ 613extern void dump_stg_info(void); 614extern void rpc__dbg_set_switches ( 615 char * /*s*/, 616 unsigned32 * /*st*/ 617 ); 618void rpc__cn_set_sock_buffsize ( 619 unsigned32 /* rsize */, 620 unsigned32 /* ssize */, 621 unsigned32 * /* st */); 622void rpc__cn_inq_sock_buffsize ( 623 unsigned32 * /* rsize */, 624 unsigned32 * /* ssize */, 625 unsigned32 * /* st */); 626 627extern int lookup_name(char *table[], char *s); 628 629int main (argc, argv) 630 631int argc; 632char *argv[]; 633 634{ 635 unsigned32 st; 636 idl_boolean debug = false; 637 idl_char *auth_principal, *auth_principal_2; 638 char *s; 639 int c; 640 unsigned32 authn_protocol; 641 unsigned16 i; 642 extern int optind; 643 extern char *optarg; 644 unsigned32 max_calls; 645 idl_boolean ep_reg = false; /* should we rpc_ep_register() at startup? */ 646 idl_boolean b_reg = false; /* ditto for perfb i/f */ 647 idl_char *keytab; 648 unsigned32 ssize,rsize; 649 650 DO_NOT_CLOBBER(i); 651 DO_NOT_CLOBBER(ep_reg); 652 653 while ((c = getopt(argc, argv, "beslrDB:d:p:S:v:")) != EOF) 654 { 655 switch (c) 656 { 657 case 'd': 658 case 'D': 659 rpc__dbg_set_switches(c == 'd' ? optarg : DEBUG_LEVEL, &st); 660 if (st != rpc_s_ok) 661 { 662 fprintf(stderr, "*** Error setting debug level - %s\n", 663 error_text(st)); 664 usage(); 665 } 666 667 debug = true; 668 break; 669 670 case 'p': 671 if ((s = (char *)strtok(optarg, ",")) == NULL) 672 usage(); 673 authn_protocol = strcmp(s, "default") == 0 ? 674 rpc_c_authn_default : lookup_name(authn_names, s); 675 676 if ((auth_principal = (idl_char *) strtok(NULL, ",")) == NULL) 677 usage(); 678 679 keytab = (idl_char *) strtok(NULL, " "); 680 681 VRprintf(2, ("+ Authentication params; authn_protocol: %s, auth_principal: %s, keytab: %s\n", 682 authn_protocol == (unsigned32)rpc_c_authn_default ? 683 "default" : authn_names[authn_protocol], 684 auth_principal, 685 keytab == NULL ? 686 (idl_char *) "<not specified>" : keytab 687 )); 688 689 rpc_server_register_auth_info 690 ((unsigned_char_p_t) auth_principal, authn_protocol, NULL, keytab, &st); 691 if (st != rpc_s_ok) 692 { 693 fprintf(stderr, "*** Error setting principal - %s\n", error_text(st)); 694 exit(1); 695 } 696 697 rpc_mgmt_inq_server_princ_name 698 (NULL, authn_protocol, &auth_principal_2, &st); 699 if (st != rpc_s_ok) 700 { 701 fprintf(stderr, "*** Can't get my principal name %s\n", error_text(st)); 702 exit(1); 703 } 704 VRprintf(2, ("+ Server principal name set to \"%s\"\n", auth_principal_2)); 705 706 auth = true; 707 break; 708 709 case 's': 710 shut_ok = false; 711 break; 712 713 case 'S': 714 server_loops = atoi(optarg); 715 break; 716 717 case 'v': 718 verbose = atoi(optarg); 719 break; 720 721 case 'r': 722 use_reserved_threads = true; 723 if (setup_thread_pools() != 0) 724 exit(1); 725 break; 726 727 case 'e': 728 ep_reg = true; 729 break; 730 731 case 'b': 732 b_reg = true; 733 break; 734 735 case 'B': 736 socket_buf_size = atoi(optarg); 737 break; 738 739 default: 740 usage(); 741 } 742 } 743 744 argc -= optind - 1; 745 argv = &argv[optind - 1]; 746 747 if (argc < 3) 748 { 749 usage(); 750 } 751 752 if (debug) 753 { 754 dump_stg_info(); 755 } 756 757 rpc__cn_set_sock_buffsize(socket_buf_size, socket_buf_size, &st); 758 if (st != rpc_s_ok) 759 { 760 fprintf(stderr,"*** rpc__cn_set_sock_buffsize failed (0x%lx)\n", st); 761 exit(1); 762 } 763 764 rpc__cn_inq_sock_buffsize(&rsize, &ssize, &st); 765 if (st != rpc_s_ok) 766 { 767 fprintf(stderr,"*** rpc__cn_inq_sock_buffsize failed (0x%lx)\n", st); 768 exit(1); 769 } 770 if (socket_buf_size != rsize || socket_buf_size != ssize) 771 { 772 fprintf(stderr, "*** CN socket buffer sizes dont match:\n"); 773 fprintf(stderr, "*** READ desired: %lu actual: %lu\n", socket_buf_size, rsize); 774 fprintf(stderr, "*** WRITE desired: %lu actual: %lu\n", socket_buf_size, ssize); 775 exit(1); 776 } 777 778 rpc_mgmt_set_authorization_fn(mgmt_auth_fn, &st); 779 780 max_calls = atoi(argv[1]); 781 782 get_sockets(argc, argv, max_calls); 783 register_ifs(); 784 register_objs(); 785 786 if (ep_reg) 787 { 788 rpc_ep_register(perf_v2_0_s_ifspec, bv, (uuid_vector_p_t) &object_vec, 789 (unsigned_char_p_t) "perf test", &st); 790 if (st != rpc_s_ok) 791 { 792 fprintf(stderr, "*** Can't register with endpoint map - %s\n", 793 error_text(st)); 794 exit(1); 795 } 796 } 797 798 if (b_reg) 799 { 800 perf_register_b(NULL, false, &st); 801 if (st != rpc_s_ok) 802 { 803 fprintf(stderr, "*** Can't register B interface with endpoint map - %s\n", 804 error_text(st)); 805 exit(1); 806 } 807 } 808 809 i = 0; 810 811 TRY 812 { 813 while (true) 814 { 815 VRprintf(1, ("+ Listening...\n")); 816 817 rpc_server_listen(max_calls, &st); 818 if (st != rpc_s_ok) 819 { 820 fprintf(stderr, "*** Listen returns - %s\n", error_text(st)); 821 exit(1); 822 } 823 824 if (++i >= server_loops) 825 { 826 break; 827 } 828 829 /* 830 * Unreserve threads on the last server_loop iteration. 831 */ 832 if (use_reserved_threads && i == (server_loops - 1)) 833 { 834 VRprintf (1, ("+ Returned from listen; unreserving threads\n")); 835 teardown_thread_pools(true /* block */); 836 } 837 838 VRprintf (2, ("+ Returned from listen; sleeping for %d secs\n", 839 SERVER_LOOP_SLEEP_TIME)); 840 SLEEP (SERVER_LOOP_SLEEP_TIME); 841 } 842 } 843 FINALLY 844 { 845 if (ep_reg) 846 { 847 rpc_ep_unregister(perf_v2_0_s_ifspec, bv, (uuid_vector_p_t) &object_vec, 848 &st); 849 if (st != rpc_s_ok) 850 { 851 fprintf(stderr, "*** Can't unregister from endpoint map - %s\n", 852 error_text(st)); 853 } 854 } 855 } 856 ENDTRY 857 858 VRprintf(1, ("Exiting\n")); 859 return 0; 860} 861