Index: /trunk/src/VBox/Additions/x11/VBoxClient/VBoxClient.h
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/VBoxClient.h	(revision 98473)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/VBoxClient.h	(revision 98474)
@@ -77,5 +77,5 @@
     /** @todo Should this also have a component relative to the X server number?
      */
-    const char *pszPidFilePath;
+    const char *pszPidFilePathTemplate;
     /** The usage options stuff for the --help screen. */
     const char *pszUsage;
Index: /trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp	(revision 98473)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp	(revision 98474)
@@ -429,5 +429,5 @@
     "shcl",                      /* szName */
     "Shared Clipboard",          /* pszDescription */
-    ".vboxclient-clipboard.pid", /* pszPidFilePath */
+    ".vboxclient-clipboard",     /* pszPidFilePathTemplate */
     NULL,                        /* pszUsage */
     NULL,                        /* pszOptions */
Index: /trunk/src/VBox/Additions/x11/VBoxClient/display-svga-session.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/display-svga-session.cpp	(revision 98473)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/display-svga-session.cpp	(revision 98474)
@@ -46,5 +46,5 @@
  *
  * Multiple instances of this daemon are allowed to run in parallel
- * with the following limitations (see also vbclSVGASessionPidFileLock()).
+ * with the following limitations.
  * A single user cannot run multiple daemon instances per single TTY device,
  * however, multiple instances are allowed for the user on different
@@ -67,8 +67,4 @@
 #include <iprt/linux/sysfs.h>
 
-/** Lock file handle. */
-static RTFILE g_hPidFile;
-/** Full path to PID lock file. */
-static char g_szPidFilePath[RTPATH_MAX];
 
 /** Handle to IPC client connection. */
@@ -117,67 +113,4 @@
 
 /**
- * Prevent multiple instances of the service from start.
- *
- * @returns IPRT status code.
- */
-static int vbclSVGASessionPidFileLock(void)
-{
-    int rc;
-
-    /* Allow parallel running instances of the service for processes
-     * which are running in separate X11/Wayland sessions. Compose
-     * custom PID file name based on currently active TTY device. */
-
-    char *pszPidFileName = RTStrAlloc(RTPATH_MAX);
-    if (pszPidFileName)
-    {
-        rc = RTPathUserHome(g_szPidFilePath, sizeof(g_szPidFilePath));
-        if (RT_SUCCESS(rc))
-        {
-            char pszActiveTTY[128];
-            size_t cchRead;
-
-            RT_ZERO(pszActiveTTY);
-
-            RTStrAAppend(&pszPidFileName, ".vboxclient-vmsvga-session");
-
-            rc = RTLinuxSysFsReadStrFile(pszActiveTTY, sizeof(pszActiveTTY) - 1 /* reserve last byte for string termination */,
-                                         &cchRead, "class/tty/tty0/active");
-            if (RT_SUCCESS(rc))
-            {
-                RTStrAAppend(&pszPidFileName, "-");
-                RTStrAAppend(&pszPidFileName, pszActiveTTY);
-            }
-            else
-                VBClLogInfo("cannot detect currently active tty device, "
-                            "multiple service instances for a single user will not be allowed, rc=%Rrc", rc);
-
-            RTStrAAppend(&pszPidFileName, ".pid");
-
-            RTPathAppend(g_szPidFilePath, sizeof(g_szPidFilePath), pszPidFileName);
-
-            VBClLogVerbose(1, "lock file path: %s\n", g_szPidFilePath);
-            rc = VbglR3PidFile(g_szPidFilePath, &g_hPidFile);
-        }
-        else
-            VBClLogError("unable to get user home directory, rc=%Rrc\n", rc);
-
-        RTStrFree(pszPidFileName);
-    }
-    else
-        rc = VERR_NO_MEMORY;
-
-    return rc;
-}
-
-/**
- * Release lock file.
- */
-static void vbclSVGASessionPidFileRelease(void)
-{
-    VbglR3ClosePidFile(g_szPidFilePath, g_hPidFile);
-}
-
-/**
  * @interface_method_impl{VBCLSERVICE,pfnInit}
  */
@@ -192,11 +125,4 @@
 
     VBClLogSetLogPrefix(pszLogPrefix);
-
-    rc = vbclSVGASessionPidFileLock();
-    if (RT_FAILURE(rc))
-    {
-        VBClLogVerbose(1, "cannot acquire pid lock, rc=%Rrc\n", rc);
-        return rc;
-    }
 
     rc = RTCritSectInit(&g_hClientCritSect);
@@ -517,6 +443,4 @@
     }
 
-    vbclSVGASessionPidFileRelease();
-
     return VINF_SUCCESS;
 }
@@ -526,5 +450,5 @@
     "vmsvga-session",                   /* szName */
     "VMSVGA display assistant",         /* pszDescription */
-    NULL,                               /* pszPidFilePath (no pid file lock) */
+    ".vboxclient-vmsvga-session",       /* pszPidFilePathTemplate */
     NULL,                               /* pszUsage */
     NULL,                               /* pszOptions */
Index: /trunk/src/VBox/Additions/x11/VBoxClient/display-svga-x11.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/display-svga-x11.cpp	(revision 98473)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/display-svga-x11.cpp	(revision 98474)
@@ -1391,5 +1391,5 @@
     "dp-svga-x11",                      /* szName */
     "SVGA X11 display",                 /* pszDescription */
-    ".vboxclient-display-svga-x11.pid", /* pszPidFilePath */
+    ".vboxclient-display-svga-x11",     /* pszPidFilePathTemplate */
     NULL,                               /* pszUsage */
     NULL,                               /* pszOptions */
Index: /trunk/src/VBox/Additions/x11/VBoxClient/display.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/display.cpp	(revision 98473)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/display.cpp	(revision 98474)
@@ -294,5 +294,5 @@
     "dp-legacy-x11",                    /* szName */
     "Legacy display assistant",         /* pszDescription */
-    ".vboxclient-display.pid",          /* pszPidFilePath (no pid file lock) */
+    ".vboxclient-display",              /* pszPidFilePathTemplate */
     NULL,                               /* pszUsage */
     NULL,                               /* pszOptions */
Index: /trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp	(revision 98473)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp	(revision 98474)
@@ -3866,5 +3866,5 @@
     "dnd",                         /* szName */
     "Drag'n'Drop",                 /* pszDescription */
-    ".vboxclient-draganddrop.pid", /* pszPidFilePath */
+    ".vboxclient-draganddrop",     /* pszPidFilePathTemplate */
     NULL,                          /* pszUsage */
     NULL,                          /* pszOptions */
Index: /trunk/src/VBox/Additions/x11/VBoxClient/hostversion.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/hostversion.cpp	(revision 98473)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/hostversion.cpp	(revision 98474)
@@ -119,5 +119,5 @@
     "hostversion",                   /* szName */
     "VirtualBox host version check", /* pszDescription */
-    ".vboxclient-hostversion.pid",   /* pszPidFilePath */
+    ".vboxclient-hostversion",       /* pszPidFilePathTemplate */
     NULL,                            /* pszUsage */
     NULL,                            /* pszOptions */
Index: /trunk/src/VBox/Additions/x11/VBoxClient/main.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/main.cpp	(revision 98473)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/main.cpp	(revision 98474)
@@ -45,4 +45,6 @@
 #include <iprt/stream.h>
 #include <iprt/env.h>
+#include <iprt/process.h>
+#include <iprt/linux/sysfs.h>
 #include <VBox/VBoxGuestLib.h>
 #include <VBox/err.h>
@@ -107,4 +109,9 @@
  * cleanup routine. */
 static RTFILE        g_hPidFile;
+/** The name of pidfile for parent (control) process. */
+static char          g_szControlPidFile[RTPATH_MAX] = "";
+/** The file handle of parent process pidfile. */
+static RTFILE        g_hControlPidFile;
+
 /** Global critical section held during the clean-up routine (to prevent it
  * being called on multiple threads at once) or things which may not happen
@@ -118,4 +125,6 @@
 /** Absolute path to log file, if any. */
 static char          g_szLogFile[RTPATH_MAX + 128] = "";
+/** Set by the signal handler when SIGUSR1 received. */
+static volatile bool g_fProcessReloadRequested = false;
 
 /**
@@ -212,4 +221,11 @@
         VBClLogVerbose(2, "Received signal %d\n", iSignal);
         g_fSignalHandlerCalled = true;
+
+        /* In our internal convention, when VBoxClient process receives SIGUSR1,
+         * this is a trigger for restarting a process with exec() call. Usually
+         * happens as a result of Guest Additions update in order to seamlessly
+         * restart newly installed binaries. */
+        if (iSignal == SIGUSR1)
+            g_fProcessReloadRequested = true;
 
         /* Leave critical section before stopping the service. */
@@ -368,4 +384,112 @@
 
 /**
+ * Wait for SIGUSR1 and re-exec.
+ */
+static void vbclHandleUpdateStarted(char *const argv[])
+{
+    /* Context of parent process */
+    sigset_t signalMask;
+    int      iSignal;
+    int      rc;
+
+    /* Release reference to guest driver. */
+    VbglR3Term();
+
+    sigemptyset(&signalMask);
+    sigaddset(&signalMask, SIGUSR1);
+    rc = pthread_sigmask(SIG_BLOCK, &signalMask, NULL);
+
+    if (rc == 0)
+    {
+        LogRel(("%s: waiting for Guest Additions installation to be completed\n",
+                g_Service.pDesc->pszDesc));
+
+        /* Wait for SIGUSR1. */
+        rc = sigwait(&signalMask, &iSignal);
+        if (rc == 0)
+        {
+            LogRel(("%s: Guest Additions installation to be completed, reloading service\n",
+                    g_Service.pDesc->pszDesc));
+
+            /* Release pidfile, otherwise new VBoxClient instance won't be able to quire it. */
+            VBClShutdown(false);
+
+            rc = RTProcCreate(argv[0], argv, RTENV_DEFAULT,
+                              RTPROC_FLAGS_DETACHED | RTPROC_FLAGS_SEARCH_PATH, NULL);
+            if (RT_SUCCESS(rc))
+                LogRel(("%s: service restarted\n", g_Service.pDesc->pszDesc));
+            else
+                LogRel(("%s: cannot replace running image with %s (%s), automatic service reloading has failed\n",
+                        g_Service.pDesc->pszDesc, argv[0], strerror(errno)));
+        }
+        else
+            LogRel(("%s: cannot wait for signal (%s), automatic service reloading has failed\n",
+                    g_Service.pDesc->pszDesc, strerror(errno)));
+    }
+    else
+        LogRel(("%s: failed to setup signal handler, automatic service reloading has failed\n",
+                g_Service.pDesc->pszDesc));
+
+    exit(RT_BOOL(rc != 0));
+}
+
+/**
+ * Compose pidfile name.
+ *
+ * @returns IPRT status code.
+ * @param   szBuf           Buffer to store pidfile name into.
+ * @param   cbBuf           Size of buffer.
+ * @param   szTemplate      Null-terminated string which contains pidfile name.
+ * @param   fParentProcess  Whether pidfile path should be composed for
+ *                          parent (control) process or for a child (actual
+ *                          service) process.
+ */
+static int vbclGetPidfileName(char *szBuf, size_t cbBuf, const char *szTemplate,
+                              bool fParentProcess)
+{
+    int rc;
+    char pszActiveTTY[128];
+    size_t cchRead;
+
+    RT_ZERO(pszActiveTTY);
+
+    AssertPtrReturn(szBuf, VERR_INVALID_PARAMETER);
+    AssertReturn(cbBuf > 0, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(szTemplate, VERR_INVALID_PARAMETER);
+
+    rc = RTPathUserHome(szBuf, cbBuf);
+    if (RT_FAILURE(rc))
+        VBClLogFatalError("%s: getting home directory failed: %Rrc\n",
+                          g_Service.pDesc->pszDesc, rc);
+
+    if (RT_SUCCESS(rc))
+        rc = RTPathAppend(szBuf, cbBuf, szTemplate);
+
+#ifdef RT_OS_LINUX
+    if (RT_SUCCESS(rc))
+        rc = RTLinuxSysFsReadStrFile(pszActiveTTY, sizeof(pszActiveTTY) - 1 /* reserve last byte for string termination */,
+                                     &cchRead, "class/tty/tty0/active");
+    if (RT_SUCCESS(rc))
+    {
+        RTStrCat(szBuf, cbBuf, "-");
+        RTStrCat(szBuf, cbBuf, pszActiveTTY);
+    }
+    else
+        VBClLogInfo("%s: cannot detect currently active tty device, "
+                    "multiple service instances for a single user will not be allowed, rc=%Rrc",
+                    g_Service.pDesc->pszDesc, rc);
+#endif /* RT_OS_LINUX */
+
+    if (RT_SUCCESS(rc))
+        RTStrCat(szBuf, cbBuf, fParentProcess ? "-control.pid" : "-service.pid");
+
+    if (RT_FAILURE(rc))
+        VBClLogFatalError("%s: reating PID file path failed: %Rrc\n",
+                          g_Service.pDesc->pszDesc, rc);
+
+    return rc;
+}
+
+/**
  * The main loop for the VBoxClient daemon.
  */
@@ -378,4 +502,7 @@
     if (RT_FAILURE(rc))
         return RTMsgInitFailure(rc);
+
+    /* A flag which is returned to the parent process when Guest Additions update started. */
+    bool fUpdateStarted = false;
 
     /* This should never be called twice in one process - in fact one Display
@@ -606,16 +733,26 @@
     if (RT_FAILURE(rc))
         VBClLogFatalError("Initializing critical section failed: %Rrc\n", rc);
-    if (g_Service.pDesc->pszPidFilePath)
-    {
-        rc = RTPathUserHome(g_szPidFile, sizeof(g_szPidFile));
+    if (g_Service.pDesc->pszPidFilePathTemplate)
+    {
+        /* Get pidfile name for parent (control) process. */
+        rc = vbclGetPidfileName(g_szControlPidFile, sizeof(g_szControlPidFile), g_Service.pDesc->pszPidFilePathTemplate, true);
         if (RT_FAILURE(rc))
-            VBClLogFatalError("Getting home directory failed: %Rrc\n", rc);
-        rc = RTPathAppend(g_szPidFile, sizeof(g_szPidFile), g_Service.pDesc->pszPidFilePath);
+            return RTEXITCODE_FAILURE;
+
+        /* Get pidfile name for service process. */
+        rc = vbclGetPidfileName(g_szPidFile, sizeof(g_szPidFile), g_Service.pDesc->pszPidFilePathTemplate, false);
         if (RT_FAILURE(rc))
-            VBClLogFatalError("Creating PID file path failed: %Rrc\n", rc);
+            return RTEXITCODE_FAILURE;
     }
 
     if (fDaemonise)
-        rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */, fRespawn, &g_cRespawn);
+    {
+        rc = VbglR3DaemonizeEx(false /* fNoChDir */, false /* fNoClose */, fRespawn, &g_cRespawn,
+                               true /* fReturnOnUpdate */, &fUpdateStarted, g_szControlPidFile, &g_hControlPidFile);
+        /* This combination only works in context of parent process. */
+        if (RT_SUCCESS(rc) && fUpdateStarted)
+            vbclHandleUpdateStarted(argv);
+    }
+
     if (RT_FAILURE(rc))
         VBClLogFatalError("Daemonizing service failed: %Rrc\n", rc);
@@ -625,7 +762,14 @@
         rc = VbglR3PidFile(g_szPidFile, &g_hPidFile);
         if (rc == VERR_FILE_LOCK_VIOLATION)  /* Already running. */
+        {
+            VBClLogInfo("%s: service already running, exitting\n",
+                        g_Service.pDesc->pszDesc);
             return RTEXITCODE_SUCCESS;
+        }
         if (RT_FAILURE(rc))
-            VBClLogFatalError("Creating PID file failed: %Rrc\n", rc);
+        {
+            VBClLogFatalError("Creating PID file %s failed: %Rrc\n", g_szPidFile, rc);
+            return RTEXITCODE_FAILURE;
+        }
     }
 
@@ -737,5 +881,5 @@
     /** @todo r=andy Should we return an appropriate exit code if the service failed to init?
      *               Must be tested carefully with our init scripts first. */
-    return RTEXITCODE_SUCCESS;
-}
-
+    return g_fProcessReloadRequested ? VBGLR3EXITCODERELOAD : RTEXITCODE_SUCCESS;
+}
+
Index: /trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp	(revision 98473)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp	(revision 98474)
@@ -349,5 +349,5 @@
     "seamless",                 /* szName */
     "Seamless Mode Support",    /* pszDescription */
-    ".vboxclient-seamless.pid", /* pszPidFilePath */
+    ".vboxclient-seamless",     /* pszPidFilePathTemplate */
     NULL,                       /* pszUsage */
     NULL,                       /* pszOptions */
