Changes to support non-NameServer-capable slaves on Linux
authorRobert Tivy <rtivy@ti.com>
Tue, 27 Aug 2013 23:19:16 +0000 (16:19 -0700)
committerChris Ring <cring@ti.com>
Wed, 28 Aug 2013 23:46:53 +0000 (16:46 -0700)
Ipc setup code was giving up when any slave failed to connect to Linux
sockets.  It now succeeds when at least one slave connects.  Previously,
both NameServer_setup() (in LAD) and MessageQ_attach()es called from
Ipc_start() were expected to succeed for all remote cores specified in
MultiProc.  Now those functions can tolerate slave connection failures and
will report success if at least one slave can connect.

linux/src/api/Ipc.c
linux/src/api/MessageQ.c
linux/src/daemon/NameServer_daemon.c
linux/src/utils/SocketFxns.c

index ebd6c470f46ae483d12dc0e30f1cc439b185583e..46db4ae16507a9f3176753d6bba30e4b3a484979 100644 (file)
@@ -73,9 +73,10 @@ Int Ipc_start (Void)
 {
     MessageQ_Config   msgqCfg;
     MultiProc_Config  mpCfg;
-    Int32             status = Ipc_S_SUCCESS;
+    Int32             status;
     LAD_Status        ladStatus;
     UInt16            rprocId;
+    Int32             attachedAny = 0;
 
     /* Catch ctrl-C, and cleanup: */
     (void) signal(SIGINT, cleanup);
@@ -97,19 +98,28 @@ Int Ipc_start (Void)
         MessageQ_setup(&msgqCfg);
 
         /* Now attach to all remote processors, assuming they are up. */
-        for (rprocId = 0;
-             (rprocId < MultiProc_getNumProcessors()) && (status >= 0);
-             rprocId++) {
-           if (0 == rprocId) {
-               /* Skip host, which should always be 0th entry. */
-               continue;
-           }
-           status = MessageQ_attach (rprocId, NULL);
-           if (status < 0) {
-              printf("Ipc_start: MessageQ_attach(%d) failed: %d\n",
-                     rprocId, status);
-              status = Ipc_E_FAIL;
-           }
+        for (rprocId = 0; rprocId < MultiProc_getNumProcessors(); rprocId++) {
+            if (0 == rprocId) {
+                /* Skip host, which should always be 0th entry. */
+                continue;
+            }
+            status = MessageQ_attach(rprocId, NULL);
+            if (status == MessageQ_E_RESOURCE) {
+                continue;
+            }
+            if (status < 0) {
+                printf("Ipc_start: MessageQ_attach(%d) failed: %d\n",
+                       rprocId, status);
+                status = Ipc_E_FAIL;
+
+                break;
+            }
+            else {
+                attachedAny = 1;
+            }
+        }
+        if (attachedAny) {
+            status = Ipc_S_SUCCESS;
         }
     }
     else {
index 5921fe78325111b341ea28621cdc463a342bd9c5..827af575bd152447f5627250bb0eab09a98167a9 100644 (file)
@@ -221,7 +221,7 @@ Void MessageQ_getConfig (MessageQ_Config * cfg)
 }
 
 /* Function to setup the MessageQ module. */
-Int MessageQ_setup (const MessageQ_Config * cfg)
+Int MessageQ_setup(const MessageQ_Config * cfg)
 {
     Int status;
     LAD_ClientHandle handle;
@@ -266,10 +266,9 @@ Int MessageQ_setup (const MessageQ_Config * cfg)
 
     /* Clear sockets array. */
     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
-       MessageQ_module->sock[i]      = Transport_INVALIDSOCKET;
+        MessageQ_module->sock[i] = Transport_INVALIDSOCKET;
     }
 
-
     return status;
 }
 
@@ -333,7 +332,7 @@ Void MessageQ_Params_init (MessageQ_Params * params)
  */
 MessageQ_Handle MessageQ_create (String name, const MessageQ_Params * params)
 {
-    Int                   status    = MessageQ_S_SUCCESS;
+    Int                   status;
     MessageQ_Object *     obj    = NULL;
     UInt16                queueIndex = 0u;
     UInt16                procId;
@@ -413,7 +412,7 @@ MessageQ_Handle MessageQ_create (String name, const MessageQ_Params * params)
         status = transportCreateEndpoint(&obj->fd[rprocId], rprocId,
                                            queueIndex);
         if (status < 0) {
-           goto cleanup;
+           obj->fd[rprocId] = Transport_INVALIDSOCKET;
         }
     }
 
@@ -425,13 +424,20 @@ MessageQ_Handle MessageQ_create (String name, const MessageQ_Params * params)
     if (obj->unblockFd == -1)  {
         printf ("MessageQ_create: eventfd creation failed: %d, %s\n",
                    errno, strerror(errno));
-        status = MessageQ_E_FAIL;
+        MessageQ_delete((MessageQ_Handle *)&obj);
     }
+    else {
+        int endpointFound = 0;
 
-cleanup:
-    /* Cleanup if fail: */
-    if (status < 0) {
-        MessageQ_delete((MessageQ_Handle *)&obj);
+        for (rprocId = 0; rprocId < MultiProc_getNumProcessors(); rprocId++) {
+            if (obj->fd[rprocId] != Transport_INVALIDSOCKET) {
+                endpointFound = 1;
+            }
+        }
+        if (!endpointFound) {
+            printf("MessageQ_create: no transport endpoints found, deleting\n");
+            MessageQ_delete((MessageQ_Handle *)&obj);
+        }
     }
 
     return ((MessageQ_Handle) obj);
@@ -599,7 +605,8 @@ Int MessageQ_get (MessageQ_Handle handle, MessageQ_Msg * msg ,UInt timeout)
     /* Wait (with timeout) and retreive message from socket: */
     FD_ZERO(&rfds);
     for (rprocId = 0; rprocId < MultiProc_getNumProcessors(); rprocId++) {
-        if (rprocId == MultiProc_self()) {
+        if (rprocId == MultiProc_self() ||
+            obj->fd[rprocId] == Transport_INVALIDSOCKET) {
             continue;
         }
         maxfd = MAX(maxfd, obj->fd[rprocId]);
@@ -638,7 +645,8 @@ Int MessageQ_get (MessageQ_Handle handle, MessageQ_Msg * msg ,UInt timeout)
         else {
             for (rprocId = 0; rprocId < MultiProc_getNumProcessors();
                  rprocId++) {
-                if (rprocId == MultiProc_self()) {
+                if (rprocId == MultiProc_self() ||
+                    obj->fd[rprocId] == Transport_INVALIDSOCKET) {
                     continue;
                 }
                 if (FD_ISSET(obj->fd[rprocId], &rfds)) {
@@ -840,7 +848,13 @@ Int MessageQ_attach (UInt16 remoteProcId, Ptr sharedAddr)
             PRINTVERBOSE1("MessageQ_attach: created send socket: %d\n", sock)
             MessageQ_module->sock[remoteProcId] = sock;
             /* Attempt to connect: */
-            ConnectSocket(sock, remoteProcId, MESSAGEQ_RPMSG_PORT);
+            status = ConnectSocket(sock, remoteProcId, MESSAGEQ_RPMSG_PORT);
+            if (status < 0) {
+                status = MessageQ_E_RESOURCE;
+                /* don't hard-printf since this is no longer fatal */
+                PRINTVERBOSE1("MessageQ_attach: ConnectSocket(remoteProcId:%d) failed\n",
+                       remoteProcId);
+            }
         }
     }
     else {
@@ -849,6 +863,10 @@ Int MessageQ_attach (UInt16 remoteProcId, Ptr sharedAddr)
 
     pthread_mutex_unlock (&(MessageQ_module->gate));
 
+    if (status == MessageQ_E_RESOURCE) {
+        MessageQ_detach(remoteProcId);
+    }
+
 exit:
     return (status);
 }
@@ -870,14 +888,16 @@ Int MessageQ_detach (UInt16 remoteProcId)
     pthread_mutex_lock (&(MessageQ_module->gate));
 
     sock = MessageQ_module->sock[remoteProcId];
-    if (close (sock)) {
-        status = MessageQ_E_OSFAILURE;
-        printf ("MessageQ_detach: close failed: %d, %s\n",
-                       errno, strerror(errno));
-    }
-    else {
-        PRINTVERBOSE1("MessageQ_detach: closed socket: %d\n", sock)
-        MessageQ_module->sock[remoteProcId] = Transport_INVALIDSOCKET;
+    if (sock != Transport_INVALIDSOCKET) {
+        if (close(sock)) {
+            status = MessageQ_E_OSFAILURE;
+            printf("MessageQ_detach: close failed: %d, %s\n",
+                   errno, strerror(errno));
+        }
+        else {
+            PRINTVERBOSE1("MessageQ_detach: closed socket: %d\n", sock)
+            MessageQ_module->sock[remoteProcId] = Transport_INVALIDSOCKET;
+        }
     }
 
     pthread_mutex_unlock (&(MessageQ_module->gate));
@@ -900,7 +920,7 @@ Void MessageQ_msgInit (MessageQ_Msg msg)
     handle = LAD_findHandle();
     if (handle == LAD_MAXNUMCLIENTS) {
         PRINTVERBOSE1(
-          "MessageQ_setup: can't find connection to daemon for pid %d\n",
+          "MessageQ_msgInit: can't find connection to daemon for pid %d\n",
            getpid())
 
         return;
@@ -969,8 +989,9 @@ static Int transportCreateEndpoint(int * fd, UInt16 rprocId, UInt16 queueIndex)
     err = SocketBindAddr(*fd, rprocId, (UInt32)queueIndex);
     if (err < 0) {
         status = MessageQ_E_FAIL;
-        printf ("transportCreateEndpoint: bind failed: %d, %s\n",
-                  errno, strerror(errno));
+        /* don't hard-printf since this is no longer fatal */
+        PRINTVERBOSE2("transportCreateEndpoint: bind failed: %d, %s\n",
+                      errno, strerror(errno));
     }
 
 exit:
index 067bcd809a0630f3c2c2b432ead99a3b4f58e120..70742765d97d434c1ce51265573d1b732dd4e904 100644 (file)
@@ -464,15 +464,15 @@ Int NameServer_setup(Void)
 
             err = SocketBindAddr(sock, procId, NAME_SERVER_RPMSG_ADDR);
             if (err < 0) {
-               status = NameServer_E_FAIL;
-               LOG2("NameServer_setup: bind failed: %d, %s\n",
+                status = NameServer_E_FAIL;
+                LOG2("NameServer_setup: bind failed: %d, %s\n",
                     errno, strerror(errno))
 
                 LOG1("    closing recv socket: %d\n", sock)
                 close(sock);
             }
             else {
-               NameServer_module->recvSock[procId] = sock;
+                NameServer_module->recvSock[procId] = sock;
             }
         }
     }
@@ -489,6 +489,17 @@ Int NameServer_setup(Void)
 
         status = NameServer_E_FAIL;
     }
+    else {
+        /* look for at least one good send/recv pair to indicate success */
+        for (procId = 0; procId < numProcs; procId++) {
+            if (NameServer_module->sendSock[procId] != INVALIDSOCKET &&
+                NameServer_module->recvSock[procId] != INVALIDSOCKET) {
+                status = NameServer_S_SUCCESS;
+
+                break;
+            }
+        }
+    }
 
 exit:
     LOG1("NameServer_setup: exiting, refCount=%d\n", NameServer_module->refCount)
@@ -937,6 +948,13 @@ Int NameServer_getRemote(NameServer_Handle handle,
 
     /* Create request message and send to remote: */
     sock = NameServer_module->sendSock[procId];
+    if (sock == INVALIDSOCKET) {
+        LOG1("NameServer_getRemote: no socket connection to processor %d\n",
+             procId);
+        status = NameServer_E_RESOURCE;
+        goto exit;
+    }
+
     LOG1("NameServer_getRemote: Sending request via sock: %d\n", sock)
 
     /* Create request message and send to remote processor: */
@@ -1039,7 +1057,8 @@ Int NameServer_get(NameServer_Handle handle,
                 status = NameServer_getRemote(handle, name, value, len, i);
 
                 if ((status >= 0) ||
-                    ((status < 0) && (status != NameServer_E_NOTFOUND))) {
+                    ((status < 0) && (status != NameServer_E_NOTFOUND) &&
+                                     (status != NameServer_E_RESOURCE))) {
                     break;
                 }
             }
@@ -1060,7 +1079,8 @@ Int NameServer_get(NameServer_Handle handle,
             }
 
             if ((status >= 0) ||
-                ((status < 0) && (status != NameServer_E_NOTFOUND))) {
+                ((status < 0) && (status != NameServer_E_NOTFOUND) &&
+                                 (status != NameServer_E_RESOURCE))) {
                 break;
             }
 
@@ -1068,6 +1088,10 @@ Int NameServer_get(NameServer_Handle handle,
         }
     }
 
+    if (status == NameServer_E_RESOURCE) {
+        status = NameServer_E_NOTFOUND;
+    }
+
     return (status);
 }
 
index bbb40fadb24507cb7d9f5beb579db2a5f2fd28ac..8aa9ab167d20a2e31a5e916303b98b8a3a66eb99 100644 (file)
@@ -73,15 +73,16 @@ int ConnectSocket(int sock, UInt16 procId, int dst)
     len = sizeof(struct sockaddr_rpmsg);
     err = connect(sock, (struct sockaddr *)&dstAddr, len);
     if (err < 0) {
-         printf("connect failed: %s (%d)\n", strerror(errno), errno);
-         return (-1);
+        /* don't hard-printf since this is no longer fatal */
+        PRINTVERBOSE2("connect failed: %s (%d)\n", strerror(errno), errno);
+        return (-1);
     }
 
     /* let's see what local address we got */
     err = getsockname(sock, (struct sockaddr *)&srcAddr, &len);
     if (err < 0) {
-         printf("getpeername failed: %s (%d)\n", strerror(errno), errno);
-         return (-1);
+        printf("getpeername failed: %s (%d)\n", strerror(errno), errno);
+        return (-1);
     }
 
     PRINTVERBOSE3("Connected over sock: %d\n\tdst vproc_id: %d, dst addr: %d\n",