vhost: vhost-user component may become unusable with too many open files (VPP-668) 31/5831/4
authorSteven <sluong@cisco.com>
Wed, 22 Mar 2017 19:05:19 +0000 (12:05 -0700)
committerDamjan Marion <dmarion.lists@gmail.com>
Wed, 29 Mar 2017 09:34:48 +0000 (09:34 +0000)
When the number of open files is reached in the system, vhost may
encounter a failure in socket call and return from vhost-user-process.
The return terminates all attempts of incoming socket connections
in the future, even if the condition is reconciled.

The fix is to not return from vhost-user-process, record the error in
the interface, spit out the error, and retry the connection every 3 seconds.

Change-Id: I806baedf13e8c9b73e7c7820c094240f39949950
Signed-off-by: Steven <sluong@cisco.com>
src/vnet/devices/virtio/vhost-user.c

index 5ad4cb6..00807dc 100644 (file)
@@ -2440,14 +2440,11 @@ vhost_user_process (vlib_main_t * vm,
   f64 timeout = 3153600000.0 /* 100 years */ ;
   uword *event_data = 0;
 
-  sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
+  sockfd = -1;
   sun.sun_family = AF_UNIX;
   template.read_function = vhost_user_socket_read;
   template.error_function = vhost_user_socket_error;
 
-  if (sockfd < 0)
-    return 0;
-
   while (1)
     {
       vlib_process_wait_for_event_or_clock (vm, timeout);
@@ -2462,6 +2459,23 @@ vhost_user_process (vlib_main_t * vm,
          if (vui->unix_server_index == ~0) { //Nothing to do for server sockets
              if (vui->unix_file_index == ~0)
                {
+                 if ((sockfd < 0) &&
+                     ((sockfd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0))
+                   {
+                     /*
+                      * 1st time error or new error for this interface,
+                      * spit out the message and record the error
+                      */
+                     if (!vui->sock_errno || (vui->sock_errno != errno))
+                       {
+                         clib_unix_warning
+                           ("Error: Could not open unix socket for %s",
+                            vui->sock_filename);
+                         vui->sock_errno = errno;
+                       }
+                     continue;
+                   }
+
                  /* try to connect */
                  strncpy (sun.sun_path, (char *) vui->sock_filename,
                           sizeof (sun.sun_path) - 1);
@@ -2483,11 +2497,8 @@ vhost_user_process (vlib_main_t * vm,
                          vui - vhost_user_main.vhost_user_interfaces;
                      vui->unix_file_index = unix_file_add (&unix_main, &template);
 
-                     //Re-open for next connect
-                     if ((sockfd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
-                         clib_warning("Critical: Could not open unix socket");
-                         return 0;
-                     }
+                     /* This sockfd is considered consumed */
+                     sockfd = -1;
                    }
                  else
                    {