1*a53f50b9Schristos /* $NetBSD: nfs_start.c,v 1.1.1.1 2008/09/19 20:07:16 christos Exp $ */ 2*a53f50b9Schristos 3*a53f50b9Schristos /* 4*a53f50b9Schristos * Copyright (c) 1997-2007 Erez Zadok 5*a53f50b9Schristos * Copyright (c) 1990 Jan-Simon Pendry 6*a53f50b9Schristos * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 7*a53f50b9Schristos * Copyright (c) 1990 The Regents of the University of California. 8*a53f50b9Schristos * All rights reserved. 9*a53f50b9Schristos * 10*a53f50b9Schristos * This code is derived from software contributed to Berkeley by 11*a53f50b9Schristos * Jan-Simon Pendry at Imperial College, London. 12*a53f50b9Schristos * 13*a53f50b9Schristos * Redistribution and use in source and binary forms, with or without 14*a53f50b9Schristos * modification, are permitted provided that the following conditions 15*a53f50b9Schristos * are met: 16*a53f50b9Schristos * 1. Redistributions of source code must retain the above copyright 17*a53f50b9Schristos * notice, this list of conditions and the following disclaimer. 18*a53f50b9Schristos * 2. Redistributions in binary form must reproduce the above copyright 19*a53f50b9Schristos * notice, this list of conditions and the following disclaimer in the 20*a53f50b9Schristos * documentation and/or other materials provided with the distribution. 21*a53f50b9Schristos * 3. All advertising materials mentioning features or use of this software 22*a53f50b9Schristos * must display the following acknowledgment: 23*a53f50b9Schristos * This product includes software developed by the University of 24*a53f50b9Schristos * California, Berkeley and its contributors. 25*a53f50b9Schristos * 4. Neither the name of the University nor the names of its contributors 26*a53f50b9Schristos * may be used to endorse or promote products derived from this software 27*a53f50b9Schristos * without specific prior written permission. 28*a53f50b9Schristos * 29*a53f50b9Schristos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30*a53f50b9Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31*a53f50b9Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32*a53f50b9Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33*a53f50b9Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34*a53f50b9Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35*a53f50b9Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36*a53f50b9Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37*a53f50b9Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38*a53f50b9Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39*a53f50b9Schristos * SUCH DAMAGE. 40*a53f50b9Schristos * 41*a53f50b9Schristos * 42*a53f50b9Schristos * File: am-utils/amd/nfs_start.c 43*a53f50b9Schristos * 44*a53f50b9Schristos */ 45*a53f50b9Schristos 46*a53f50b9Schristos #ifdef HAVE_CONFIG_H 47*a53f50b9Schristos # include <config.h> 48*a53f50b9Schristos #endif /* HAVE_CONFIG_H */ 49*a53f50b9Schristos #include <am_defs.h> 50*a53f50b9Schristos #include <amd.h> 51*a53f50b9Schristos 52*a53f50b9Schristos #ifndef SELECT_MAXWAIT 53*a53f50b9Schristos # define SELECT_MAXWAIT 16 54*a53f50b9Schristos #endif /* not SELECT_MAXWAIT */ 55*a53f50b9Schristos 56*a53f50b9Schristos SVCXPRT *nfsxprt = NULL; 57*a53f50b9Schristos u_short nfs_port = 0; 58*a53f50b9Schristos 59*a53f50b9Schristos #ifndef HAVE_SIGACTION 60*a53f50b9Schristos # define MASKED_SIGS (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGCHLD)|sigmask(SIGHUP)) 61*a53f50b9Schristos #endif /* not HAVE_SIGACTION */ 62*a53f50b9Schristos 63*a53f50b9Schristos #ifdef DEBUG 64*a53f50b9Schristos /* 65*a53f50b9Schristos * Check that we are not burning resources 66*a53f50b9Schristos */ 67*a53f50b9Schristos static void 68*a53f50b9Schristos checkup(void) 69*a53f50b9Schristos { 70*a53f50b9Schristos static int max_fd = 0; 71*a53f50b9Schristos static char *max_mem = NULL; 72*a53f50b9Schristos int next_fd = dup(0); 73*a53f50b9Schristos caddr_t next_mem = sbrk(0); 74*a53f50b9Schristos 75*a53f50b9Schristos close(next_fd); 76*a53f50b9Schristos 77*a53f50b9Schristos if (max_fd < next_fd) { 78*a53f50b9Schristos dlog("%d new fds allocated; total is %d", 79*a53f50b9Schristos next_fd - max_fd, next_fd); 80*a53f50b9Schristos max_fd = next_fd; 81*a53f50b9Schristos } 82*a53f50b9Schristos if (max_mem < next_mem) { 83*a53f50b9Schristos #ifdef HAVE_GETPAGESIZE 84*a53f50b9Schristos dlog("%#lx bytes of memory allocated; total is %#lx (%ld pages)", 85*a53f50b9Schristos (long) (next_mem - max_mem), (unsigned long) next_mem, 86*a53f50b9Schristos ((long) next_mem + getpagesize() - 1) / (long) getpagesize()); 87*a53f50b9Schristos #else /* not HAVE_GETPAGESIZE */ 88*a53f50b9Schristos dlog("%#lx bytes of memory allocated; total is %#lx", 89*a53f50b9Schristos (long) (next_mem - max_mem), (unsigned long) next_mem); 90*a53f50b9Schristos #endif /* not HAVE_GETPAGESIZE */ 91*a53f50b9Schristos max_mem = next_mem; 92*a53f50b9Schristos 93*a53f50b9Schristos } 94*a53f50b9Schristos } 95*a53f50b9Schristos #else /* not DEBUG */ 96*a53f50b9Schristos #define checkup() 97*a53f50b9Schristos #endif /* not DEBUG */ 98*a53f50b9Schristos 99*a53f50b9Schristos 100*a53f50b9Schristos static int 101*a53f50b9Schristos #ifdef HAVE_SIGACTION 102*a53f50b9Schristos do_select(sigset_t smask, int fds, fd_set *fdp, struct timeval *tvp) 103*a53f50b9Schristos #else /* not HAVE_SIGACTION */ 104*a53f50b9Schristos do_select(int smask, int fds, fd_set *fdp, struct timeval *tvp) 105*a53f50b9Schristos #endif /* not HAVE_SIGACTION */ 106*a53f50b9Schristos { 107*a53f50b9Schristos 108*a53f50b9Schristos int sig; 109*a53f50b9Schristos int nsel; 110*a53f50b9Schristos 111*a53f50b9Schristos if ((sig = setjmp(select_intr))) { 112*a53f50b9Schristos select_intr_valid = 0; 113*a53f50b9Schristos /* Got a signal */ 114*a53f50b9Schristos switch (sig) { 115*a53f50b9Schristos case SIGINT: 116*a53f50b9Schristos case SIGTERM: 117*a53f50b9Schristos amd_state = Finishing; 118*a53f50b9Schristos reschedule_timeout_mp(); 119*a53f50b9Schristos break; 120*a53f50b9Schristos } 121*a53f50b9Schristos nsel = -1; 122*a53f50b9Schristos errno = EINTR; 123*a53f50b9Schristos } else { 124*a53f50b9Schristos select_intr_valid = 1; 125*a53f50b9Schristos /* 126*a53f50b9Schristos * Allow interrupts. If a signal 127*a53f50b9Schristos * occurs, then it will cause a longjmp 128*a53f50b9Schristos * up above. 129*a53f50b9Schristos */ 130*a53f50b9Schristos #ifdef HAVE_SIGACTION 131*a53f50b9Schristos sigprocmask(SIG_SETMASK, &smask, NULL); 132*a53f50b9Schristos #else /* not HAVE_SIGACTION */ 133*a53f50b9Schristos (void) sigsetmask(smask); 134*a53f50b9Schristos #endif /* not HAVE_SIGACTION */ 135*a53f50b9Schristos 136*a53f50b9Schristos /* 137*a53f50b9Schristos * Wait for input 138*a53f50b9Schristos */ 139*a53f50b9Schristos nsel = select(fds, fdp, (fd_set *) NULL, (fd_set *) NULL, 140*a53f50b9Schristos tvp->tv_sec ? tvp : (struct timeval *) NULL); 141*a53f50b9Schristos } 142*a53f50b9Schristos 143*a53f50b9Schristos #ifdef HAVE_SIGACTION 144*a53f50b9Schristos sigprocmask(SIG_BLOCK, &masked_sigs, NULL); 145*a53f50b9Schristos #else /* not HAVE_SIGACTION */ 146*a53f50b9Schristos (void) sigblock(MASKED_SIGS); 147*a53f50b9Schristos #endif /* not HAVE_SIGACTION */ 148*a53f50b9Schristos 149*a53f50b9Schristos /* 150*a53f50b9Schristos * Perhaps reload the cache? 151*a53f50b9Schristos */ 152*a53f50b9Schristos if (do_mapc_reload < clocktime(NULL)) { 153*a53f50b9Schristos mapc_reload(); 154*a53f50b9Schristos do_mapc_reload = clocktime(NULL) + gopt.map_reload_interval; 155*a53f50b9Schristos } 156*a53f50b9Schristos return nsel; 157*a53f50b9Schristos } 158*a53f50b9Schristos 159*a53f50b9Schristos 160*a53f50b9Schristos /* 161*a53f50b9Schristos * Determine whether anything is left in 162*a53f50b9Schristos * the RPC input queue. 163*a53f50b9Schristos */ 164*a53f50b9Schristos static int 165*a53f50b9Schristos rpc_pending_now(void) 166*a53f50b9Schristos { 167*a53f50b9Schristos struct timeval tvv; 168*a53f50b9Schristos int nsel; 169*a53f50b9Schristos fd_set readfds; 170*a53f50b9Schristos 171*a53f50b9Schristos FD_ZERO(&readfds); 172*a53f50b9Schristos FD_SET(fwd_sock, &readfds); 173*a53f50b9Schristos 174*a53f50b9Schristos tvv.tv_sec = tvv.tv_usec = 0; 175*a53f50b9Schristos nsel = select(FD_SETSIZE, &readfds, (fd_set *) NULL, (fd_set *) NULL, &tvv); 176*a53f50b9Schristos if (nsel < 1) 177*a53f50b9Schristos return (0); 178*a53f50b9Schristos if (FD_ISSET(fwd_sock, &readfds)) 179*a53f50b9Schristos return (1); 180*a53f50b9Schristos 181*a53f50b9Schristos return (0); 182*a53f50b9Schristos } 183*a53f50b9Schristos 184*a53f50b9Schristos 185*a53f50b9Schristos static serv_state 186*a53f50b9Schristos run_rpc(void) 187*a53f50b9Schristos { 188*a53f50b9Schristos #ifdef HAVE_SIGACTION 189*a53f50b9Schristos sigset_t smask; 190*a53f50b9Schristos sigprocmask(SIG_BLOCK, &masked_sigs, &smask); 191*a53f50b9Schristos #else /* not HAVE_SIGACTION */ 192*a53f50b9Schristos int smask = sigblock(MASKED_SIGS); 193*a53f50b9Schristos #endif /* not HAVE_SIGACTION */ 194*a53f50b9Schristos 195*a53f50b9Schristos next_softclock = clocktime(NULL); 196*a53f50b9Schristos 197*a53f50b9Schristos amd_state = Run; 198*a53f50b9Schristos 199*a53f50b9Schristos /* 200*a53f50b9Schristos * Keep on trucking while we are in Run mode. This state 201*a53f50b9Schristos * is switched to Quit after all the file systems have 202*a53f50b9Schristos * been unmounted. 203*a53f50b9Schristos */ 204*a53f50b9Schristos while ((int) amd_state <= (int) Finishing) { 205*a53f50b9Schristos struct timeval tvv; 206*a53f50b9Schristos int nsel; 207*a53f50b9Schristos time_t now; 208*a53f50b9Schristos fd_set readfds; 209*a53f50b9Schristos 210*a53f50b9Schristos #ifdef HAVE_SVC_GETREQSET 211*a53f50b9Schristos memmove(&readfds, &svc_fdset, sizeof(svc_fdset)); 212*a53f50b9Schristos #else /* not HAVE_SVC_GETREQSET */ 213*a53f50b9Schristos FD_ZERO(&readfds); 214*a53f50b9Schristos # ifdef HAVE_FD_SET_FDS_BITS 215*a53f50b9Schristos readfds.fds_bits[0] = svc_fds; 216*a53f50b9Schristos # else /* not HAVE_FD_SET_FDS_BITS */ 217*a53f50b9Schristos readfds = svc_fds; 218*a53f50b9Schristos # endif /* not HAVE_FD_SET_FDS_BITS */ 219*a53f50b9Schristos #endif /* not HAVE_SVC_GETREQSET */ 220*a53f50b9Schristos FD_SET(fwd_sock, &readfds); 221*a53f50b9Schristos 222*a53f50b9Schristos checkup(); 223*a53f50b9Schristos 224*a53f50b9Schristos /* 225*a53f50b9Schristos * If the full timeout code is not called, 226*a53f50b9Schristos * then recompute the time delta manually. 227*a53f50b9Schristos */ 228*a53f50b9Schristos now = clocktime(NULL); 229*a53f50b9Schristos 230*a53f50b9Schristos if (next_softclock <= now) { 231*a53f50b9Schristos if (amd_state == Finishing) 232*a53f50b9Schristos umount_exported(); 233*a53f50b9Schristos tvv.tv_sec = softclock(); 234*a53f50b9Schristos } else { 235*a53f50b9Schristos tvv.tv_sec = next_softclock - now; 236*a53f50b9Schristos } 237*a53f50b9Schristos tvv.tv_usec = 0; 238*a53f50b9Schristos 239*a53f50b9Schristos if (amd_state == Finishing && get_exported_ap(0) == NULL) { 240*a53f50b9Schristos flush_mntfs(); 241*a53f50b9Schristos amd_state = Quit; 242*a53f50b9Schristos break; 243*a53f50b9Schristos } 244*a53f50b9Schristos 245*a53f50b9Schristos #ifdef HAVE_FS_AUTOFS 246*a53f50b9Schristos autofs_add_fdset(&readfds); 247*a53f50b9Schristos #endif /* HAVE_FS_AUTOFS */ 248*a53f50b9Schristos 249*a53f50b9Schristos if (tvv.tv_sec <= 0) 250*a53f50b9Schristos tvv.tv_sec = SELECT_MAXWAIT; 251*a53f50b9Schristos if (tvv.tv_sec) { 252*a53f50b9Schristos dlog("Select waits for %ds", (int) tvv.tv_sec); 253*a53f50b9Schristos } else { 254*a53f50b9Schristos dlog("Select waits for Godot"); 255*a53f50b9Schristos } 256*a53f50b9Schristos 257*a53f50b9Schristos nsel = do_select(smask, FD_SETSIZE, &readfds, &tvv); 258*a53f50b9Schristos 259*a53f50b9Schristos switch (nsel) { 260*a53f50b9Schristos case -1: 261*a53f50b9Schristos if (errno == EINTR) { 262*a53f50b9Schristos dlog("select interrupted"); 263*a53f50b9Schristos continue; 264*a53f50b9Schristos } 265*a53f50b9Schristos plog(XLOG_ERROR, "select: %m"); 266*a53f50b9Schristos break; 267*a53f50b9Schristos 268*a53f50b9Schristos case 0: 269*a53f50b9Schristos break; 270*a53f50b9Schristos 271*a53f50b9Schristos default: 272*a53f50b9Schristos /* 273*a53f50b9Schristos * Read all pending NFS responses at once to avoid having responses 274*a53f50b9Schristos * queue up as a consequence of retransmissions. 275*a53f50b9Schristos */ 276*a53f50b9Schristos if (FD_ISSET(fwd_sock, &readfds)) { 277*a53f50b9Schristos FD_CLR(fwd_sock, &readfds); 278*a53f50b9Schristos --nsel; 279*a53f50b9Schristos do { 280*a53f50b9Schristos fwd_reply(); 281*a53f50b9Schristos } while (rpc_pending_now() > 0); 282*a53f50b9Schristos } 283*a53f50b9Schristos 284*a53f50b9Schristos #ifdef HAVE_FS_AUTOFS 285*a53f50b9Schristos if (nsel) 286*a53f50b9Schristos nsel = autofs_handle_fdset(&readfds, nsel); 287*a53f50b9Schristos #endif /* HAVE_FS_AUTOFS */ 288*a53f50b9Schristos 289*a53f50b9Schristos if (nsel) { 290*a53f50b9Schristos /* 291*a53f50b9Schristos * Anything left must be a normal 292*a53f50b9Schristos * RPC request. 293*a53f50b9Schristos */ 294*a53f50b9Schristos #ifdef HAVE_SVC_GETREQSET 295*a53f50b9Schristos svc_getreqset(&readfds); 296*a53f50b9Schristos #else /* not HAVE_SVC_GETREQSET */ 297*a53f50b9Schristos # ifdef HAVE_FD_SET_FDS_BITS 298*a53f50b9Schristos svc_getreq(readfds.fds_bits[0]); 299*a53f50b9Schristos # else /* not HAVE_FD_SET_FDS_BITS */ 300*a53f50b9Schristos svc_getreq(readfds); 301*a53f50b9Schristos # endif /* not HAVE_FD_SET_FDS_BITS */ 302*a53f50b9Schristos #endif /* not HAVE_SVC_GETREQSET */ 303*a53f50b9Schristos } 304*a53f50b9Schristos break; 305*a53f50b9Schristos } 306*a53f50b9Schristos } 307*a53f50b9Schristos 308*a53f50b9Schristos #ifdef HAVE_SIGACTION 309*a53f50b9Schristos sigprocmask(SIG_SETMASK, &smask, NULL); 310*a53f50b9Schristos #else /* not HAVE_SIGACTION */ 311*a53f50b9Schristos (void) sigsetmask(smask); 312*a53f50b9Schristos #endif /* not HAVE_SIGACTION */ 313*a53f50b9Schristos 314*a53f50b9Schristos if (amd_state == Quit) 315*a53f50b9Schristos amd_state = Done; 316*a53f50b9Schristos 317*a53f50b9Schristos return amd_state; 318*a53f50b9Schristos } 319*a53f50b9Schristos 320*a53f50b9Schristos 321*a53f50b9Schristos int 322*a53f50b9Schristos mount_automounter(int ppid) 323*a53f50b9Schristos { 324*a53f50b9Schristos /* 325*a53f50b9Schristos * Old code replaced by rpc-trash patch. 326*a53f50b9Schristos * Erez Zadok <ezk@cs.columbia.edu> 327*a53f50b9Schristos int so = socket(AF_INET, SOCK_DGRAM, 0); 328*a53f50b9Schristos */ 329*a53f50b9Schristos SVCXPRT *udp_amqp = NULL, *tcp_amqp = NULL; 330*a53f50b9Schristos int nmount, ret; 331*a53f50b9Schristos int soNFS; 332*a53f50b9Schristos int udp_soAMQ, tcp_soAMQ; 333*a53f50b9Schristos struct netconfig *udp_amqncp, *tcp_amqncp; 334*a53f50b9Schristos 335*a53f50b9Schristos /* 336*a53f50b9Schristos * This must be done first, because it attempts to bind 337*a53f50b9Schristos * to various UDP ports and we don't want anything else 338*a53f50b9Schristos * potentially taking over those ports before we get a chance 339*a53f50b9Schristos * to reserve them. 340*a53f50b9Schristos */ 341*a53f50b9Schristos if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS) 342*a53f50b9Schristos restart_automounter_nodes(); 343*a53f50b9Schristos 344*a53f50b9Schristos /* 345*a53f50b9Schristos * Start RPC forwarding 346*a53f50b9Schristos */ 347*a53f50b9Schristos if (fwd_init() != 0) 348*a53f50b9Schristos return 3; 349*a53f50b9Schristos 350*a53f50b9Schristos /* 351*a53f50b9Schristos * Construct the root automount node 352*a53f50b9Schristos */ 353*a53f50b9Schristos make_root_node(); 354*a53f50b9Schristos 355*a53f50b9Schristos /* 356*a53f50b9Schristos * Pick up the pieces from a previous run 357*a53f50b9Schristos * This is likely to (indirectly) need the rpc_fwd package 358*a53f50b9Schristos * so it *must* come after the call to fwd_init(). 359*a53f50b9Schristos */ 360*a53f50b9Schristos if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS) 361*a53f50b9Schristos restart(); 362*a53f50b9Schristos 363*a53f50b9Schristos /* 364*a53f50b9Schristos * Create the nfs service for amd 365*a53f50b9Schristos * If nfs_port is already initialized, it means we 366*a53f50b9Schristos * already created the service during restart_automounter_nodes(). 367*a53f50b9Schristos */ 368*a53f50b9Schristos if (nfs_port == 0) { 369*a53f50b9Schristos ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2); 370*a53f50b9Schristos if (ret != 0) 371*a53f50b9Schristos return ret; 372*a53f50b9Schristos } 373*a53f50b9Schristos xsnprintf(pid_fsname, sizeof(pid_fsname), "%s:(pid%ld,port%u)", 374*a53f50b9Schristos am_get_hostname(), (long) am_mypid, nfs_port); 375*a53f50b9Schristos 376*a53f50b9Schristos /* security: if user sets -D noamq, don't even create listening socket */ 377*a53f50b9Schristos if (amuDebug(D_AMQ)) { 378*a53f50b9Schristos ret = create_amq_service(&udp_soAMQ, 379*a53f50b9Schristos &udp_amqp, 380*a53f50b9Schristos &udp_amqncp, 381*a53f50b9Schristos &tcp_soAMQ, 382*a53f50b9Schristos &tcp_amqp, 383*a53f50b9Schristos &tcp_amqncp, 384*a53f50b9Schristos gopt.preferred_amq_port); 385*a53f50b9Schristos if (ret != 0) 386*a53f50b9Schristos return ret; 387*a53f50b9Schristos } 388*a53f50b9Schristos 389*a53f50b9Schristos #ifdef HAVE_FS_AUTOFS 390*a53f50b9Schristos if (amd_use_autofs) { 391*a53f50b9Schristos /* 392*a53f50b9Schristos * Create the autofs service for amd. 393*a53f50b9Schristos */ 394*a53f50b9Schristos ret = create_autofs_service(); 395*a53f50b9Schristos /* if autofs service fails it is OK if using a test amd */ 396*a53f50b9Schristos if (ret != 0) { 397*a53f50b9Schristos plog(XLOG_WARNING, "autofs service registration failed, turning off autofs support"); 398*a53f50b9Schristos amd_use_autofs = 0; 399*a53f50b9Schristos } 400*a53f50b9Schristos } 401*a53f50b9Schristos #endif /* HAVE_FS_AUTOFS */ 402*a53f50b9Schristos 403*a53f50b9Schristos /* 404*a53f50b9Schristos * Mount the top-level auto-mountpoints 405*a53f50b9Schristos */ 406*a53f50b9Schristos nmount = mount_exported(); 407*a53f50b9Schristos 408*a53f50b9Schristos /* 409*a53f50b9Schristos * Now safe to tell parent that we are up and running 410*a53f50b9Schristos */ 411*a53f50b9Schristos if (ppid) 412*a53f50b9Schristos kill(ppid, SIGQUIT); 413*a53f50b9Schristos 414*a53f50b9Schristos if (nmount == 0) { 415*a53f50b9Schristos plog(XLOG_FATAL, "No work to do - quitting"); 416*a53f50b9Schristos amd_state = Done; 417*a53f50b9Schristos return 0; 418*a53f50b9Schristos } 419*a53f50b9Schristos 420*a53f50b9Schristos if (amuDebug(D_AMQ)) { 421*a53f50b9Schristos /* 422*a53f50b9Schristos * Complete registration of amq (first TCP service then UDP) 423*a53f50b9Schristos */ 424*a53f50b9Schristos int tcp_ok = 0, udp_ok = 0; 425*a53f50b9Schristos 426*a53f50b9Schristos unregister_amq(); /* unregister leftover Amd, if any, just in case */ 427*a53f50b9Schristos 428*a53f50b9Schristos tcp_ok = amu_svc_register(tcp_amqp, get_amd_program_number(), AMQ_VERSION, 429*a53f50b9Schristos amq_program_1, IPPROTO_TCP, tcp_amqncp); 430*a53f50b9Schristos if (!tcp_ok) 431*a53f50b9Schristos plog(XLOG_FATAL, 432*a53f50b9Schristos "unable to register (AMQ_PROGRAM=%lu, AMQ_VERSION, tcp)", 433*a53f50b9Schristos get_amd_program_number()); 434*a53f50b9Schristos 435*a53f50b9Schristos udp_ok = amu_svc_register(udp_amqp, get_amd_program_number(), AMQ_VERSION, 436*a53f50b9Schristos amq_program_1, IPPROTO_UDP, udp_amqncp); 437*a53f50b9Schristos if (!udp_ok) 438*a53f50b9Schristos plog(XLOG_FATAL, 439*a53f50b9Schristos "unable to register (AMQ_PROGRAM=%lu, AMQ_VERSION, udp)", 440*a53f50b9Schristos get_amd_program_number()); 441*a53f50b9Schristos 442*a53f50b9Schristos /* return error only if both failed */ 443*a53f50b9Schristos if (!tcp_ok && !udp_ok) { 444*a53f50b9Schristos amd_state = Done; 445*a53f50b9Schristos return 3; 446*a53f50b9Schristos } 447*a53f50b9Schristos } 448*a53f50b9Schristos 449*a53f50b9Schristos /* 450*a53f50b9Schristos * Start timeout_mp rolling 451*a53f50b9Schristos */ 452*a53f50b9Schristos reschedule_timeout_mp(); 453*a53f50b9Schristos 454*a53f50b9Schristos /* 455*a53f50b9Schristos * Start the server 456*a53f50b9Schristos */ 457*a53f50b9Schristos if (run_rpc() != Done) { 458*a53f50b9Schristos plog(XLOG_FATAL, "run_rpc failed"); 459*a53f50b9Schristos amd_state = Done; 460*a53f50b9Schristos } 461*a53f50b9Schristos return 0; 462*a53f50b9Schristos } 463