- Timestamp:
- Feb 3, 2023 7:20:53 PM (2 years ago)
- Location:
- trunk/src/VBox/Additions/x11/VBoxClient
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/VBoxClient.h
r98103 r98474 77 77 /** @todo Should this also have a component relative to the X server number? 78 78 */ 79 const char *pszPidFilePath ;79 const char *pszPidFilePathTemplate; 80 80 /** The usage options stuff for the --help screen. */ 81 81 const char *pszUsage; -
trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
r98103 r98474 429 429 "shcl", /* szName */ 430 430 "Shared Clipboard", /* pszDescription */ 431 ".vboxclient-clipboard .pid", /* pszPidFilePath*/431 ".vboxclient-clipboard", /* pszPidFilePathTemplate */ 432 432 NULL, /* pszUsage */ 433 433 NULL, /* pszOptions */ -
trunk/src/VBox/Additions/x11/VBoxClient/display-svga-session.cpp
r98103 r98474 46 46 * 47 47 * Multiple instances of this daemon are allowed to run in parallel 48 * with the following limitations (see also vbclSVGASessionPidFileLock()).48 * with the following limitations. 49 49 * A single user cannot run multiple daemon instances per single TTY device, 50 50 * however, multiple instances are allowed for the user on different … … 67 67 #include <iprt/linux/sysfs.h> 68 68 69 /** Lock file handle. */70 static RTFILE g_hPidFile;71 /** Full path to PID lock file. */72 static char g_szPidFilePath[RTPATH_MAX];73 69 74 70 /** Handle to IPC client connection. */ … … 117 113 118 114 /** 119 * Prevent multiple instances of the service from start.120 *121 * @returns IPRT status code.122 */123 static int vbclSVGASessionPidFileLock(void)124 {125 int rc;126 127 /* Allow parallel running instances of the service for processes128 * which are running in separate X11/Wayland sessions. Compose129 * custom PID file name based on currently active TTY device. */130 131 char *pszPidFileName = RTStrAlloc(RTPATH_MAX);132 if (pszPidFileName)133 {134 rc = RTPathUserHome(g_szPidFilePath, sizeof(g_szPidFilePath));135 if (RT_SUCCESS(rc))136 {137 char pszActiveTTY[128];138 size_t cchRead;139 140 RT_ZERO(pszActiveTTY);141 142 RTStrAAppend(&pszPidFileName, ".vboxclient-vmsvga-session");143 144 rc = RTLinuxSysFsReadStrFile(pszActiveTTY, sizeof(pszActiveTTY) - 1 /* reserve last byte for string termination */,145 &cchRead, "class/tty/tty0/active");146 if (RT_SUCCESS(rc))147 {148 RTStrAAppend(&pszPidFileName, "-");149 RTStrAAppend(&pszPidFileName, pszActiveTTY);150 }151 else152 VBClLogInfo("cannot detect currently active tty device, "153 "multiple service instances for a single user will not be allowed, rc=%Rrc", rc);154 155 RTStrAAppend(&pszPidFileName, ".pid");156 157 RTPathAppend(g_szPidFilePath, sizeof(g_szPidFilePath), pszPidFileName);158 159 VBClLogVerbose(1, "lock file path: %s\n", g_szPidFilePath);160 rc = VbglR3PidFile(g_szPidFilePath, &g_hPidFile);161 }162 else163 VBClLogError("unable to get user home directory, rc=%Rrc\n", rc);164 165 RTStrFree(pszPidFileName);166 }167 else168 rc = VERR_NO_MEMORY;169 170 return rc;171 }172 173 /**174 * Release lock file.175 */176 static void vbclSVGASessionPidFileRelease(void)177 {178 VbglR3ClosePidFile(g_szPidFilePath, g_hPidFile);179 }180 181 /**182 115 * @interface_method_impl{VBCLSERVICE,pfnInit} 183 116 */ … … 192 125 193 126 VBClLogSetLogPrefix(pszLogPrefix); 194 195 rc = vbclSVGASessionPidFileLock();196 if (RT_FAILURE(rc))197 {198 VBClLogVerbose(1, "cannot acquire pid lock, rc=%Rrc\n", rc);199 return rc;200 }201 127 202 128 rc = RTCritSectInit(&g_hClientCritSect); … … 517 443 } 518 444 519 vbclSVGASessionPidFileRelease();520 521 445 return VINF_SUCCESS; 522 446 } … … 526 450 "vmsvga-session", /* szName */ 527 451 "VMSVGA display assistant", /* pszDescription */ 528 NULL, /* pszPidFilePath (no pid file lock)*/452 ".vboxclient-vmsvga-session", /* pszPidFilePathTemplate */ 529 453 NULL, /* pszUsage */ 530 454 NULL, /* pszOptions */ -
trunk/src/VBox/Additions/x11/VBoxClient/display-svga-x11.cpp
r98103 r98474 1391 1391 "dp-svga-x11", /* szName */ 1392 1392 "SVGA X11 display", /* pszDescription */ 1393 ".vboxclient-display-svga-x11 .pid", /* pszPidFilePath*/1393 ".vboxclient-display-svga-x11", /* pszPidFilePathTemplate */ 1394 1394 NULL, /* pszUsage */ 1395 1395 NULL, /* pszOptions */ -
trunk/src/VBox/Additions/x11/VBoxClient/display.cpp
r98103 r98474 294 294 "dp-legacy-x11", /* szName */ 295 295 "Legacy display assistant", /* pszDescription */ 296 ".vboxclient-display .pid", /* pszPidFilePath (no pid file lock)*/296 ".vboxclient-display", /* pszPidFilePathTemplate */ 297 297 NULL, /* pszUsage */ 298 298 NULL, /* pszOptions */ -
trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
r98103 r98474 3866 3866 "dnd", /* szName */ 3867 3867 "Drag'n'Drop", /* pszDescription */ 3868 ".vboxclient-draganddrop .pid", /* pszPidFilePath*/3868 ".vboxclient-draganddrop", /* pszPidFilePathTemplate */ 3869 3869 NULL, /* pszUsage */ 3870 3870 NULL, /* pszOptions */ -
trunk/src/VBox/Additions/x11/VBoxClient/hostversion.cpp
r98103 r98474 119 119 "hostversion", /* szName */ 120 120 "VirtualBox host version check", /* pszDescription */ 121 ".vboxclient-hostversion .pid", /* pszPidFilePath*/121 ".vboxclient-hostversion", /* pszPidFilePathTemplate */ 122 122 NULL, /* pszUsage */ 123 123 NULL, /* pszOptions */ -
trunk/src/VBox/Additions/x11/VBoxClient/main.cpp
r98103 r98474 45 45 #include <iprt/stream.h> 46 46 #include <iprt/env.h> 47 #include <iprt/process.h> 48 #include <iprt/linux/sysfs.h> 47 49 #include <VBox/VBoxGuestLib.h> 48 50 #include <VBox/err.h> … … 107 109 * cleanup routine. */ 108 110 static RTFILE g_hPidFile; 111 /** The name of pidfile for parent (control) process. */ 112 static char g_szControlPidFile[RTPATH_MAX] = ""; 113 /** The file handle of parent process pidfile. */ 114 static RTFILE g_hControlPidFile; 115 109 116 /** Global critical section held during the clean-up routine (to prevent it 110 117 * being called on multiple threads at once) or things which may not happen … … 118 125 /** Absolute path to log file, if any. */ 119 126 static char g_szLogFile[RTPATH_MAX + 128] = ""; 127 /** Set by the signal handler when SIGUSR1 received. */ 128 static volatile bool g_fProcessReloadRequested = false; 120 129 121 130 /** … … 212 221 VBClLogVerbose(2, "Received signal %d\n", iSignal); 213 222 g_fSignalHandlerCalled = true; 223 224 /* In our internal convention, when VBoxClient process receives SIGUSR1, 225 * this is a trigger for restarting a process with exec() call. Usually 226 * happens as a result of Guest Additions update in order to seamlessly 227 * restart newly installed binaries. */ 228 if (iSignal == SIGUSR1) 229 g_fProcessReloadRequested = true; 214 230 215 231 /* Leave critical section before stopping the service. */ … … 368 384 369 385 /** 386 * Wait for SIGUSR1 and re-exec. 387 */ 388 static void vbclHandleUpdateStarted(char *const argv[]) 389 { 390 /* Context of parent process */ 391 sigset_t signalMask; 392 int iSignal; 393 int rc; 394 395 /* Release reference to guest driver. */ 396 VbglR3Term(); 397 398 sigemptyset(&signalMask); 399 sigaddset(&signalMask, SIGUSR1); 400 rc = pthread_sigmask(SIG_BLOCK, &signalMask, NULL); 401 402 if (rc == 0) 403 { 404 LogRel(("%s: waiting for Guest Additions installation to be completed\n", 405 g_Service.pDesc->pszDesc)); 406 407 /* Wait for SIGUSR1. */ 408 rc = sigwait(&signalMask, &iSignal); 409 if (rc == 0) 410 { 411 LogRel(("%s: Guest Additions installation to be completed, reloading service\n", 412 g_Service.pDesc->pszDesc)); 413 414 /* Release pidfile, otherwise new VBoxClient instance won't be able to quire it. */ 415 VBClShutdown(false); 416 417 rc = RTProcCreate(argv[0], argv, RTENV_DEFAULT, 418 RTPROC_FLAGS_DETACHED | RTPROC_FLAGS_SEARCH_PATH, NULL); 419 if (RT_SUCCESS(rc)) 420 LogRel(("%s: service restarted\n", g_Service.pDesc->pszDesc)); 421 else 422 LogRel(("%s: cannot replace running image with %s (%s), automatic service reloading has failed\n", 423 g_Service.pDesc->pszDesc, argv[0], strerror(errno))); 424 } 425 else 426 LogRel(("%s: cannot wait for signal (%s), automatic service reloading has failed\n", 427 g_Service.pDesc->pszDesc, strerror(errno))); 428 } 429 else 430 LogRel(("%s: failed to setup signal handler, automatic service reloading has failed\n", 431 g_Service.pDesc->pszDesc)); 432 433 exit(RT_BOOL(rc != 0)); 434 } 435 436 /** 437 * Compose pidfile name. 438 * 439 * @returns IPRT status code. 440 * @param szBuf Buffer to store pidfile name into. 441 * @param cbBuf Size of buffer. 442 * @param szTemplate Null-terminated string which contains pidfile name. 443 * @param fParentProcess Whether pidfile path should be composed for 444 * parent (control) process or for a child (actual 445 * service) process. 446 */ 447 static int vbclGetPidfileName(char *szBuf, size_t cbBuf, const char *szTemplate, 448 bool fParentProcess) 449 { 450 int rc; 451 char pszActiveTTY[128]; 452 size_t cchRead; 453 454 RT_ZERO(pszActiveTTY); 455 456 AssertPtrReturn(szBuf, VERR_INVALID_PARAMETER); 457 AssertReturn(cbBuf > 0, VERR_INVALID_PARAMETER); 458 AssertPtrReturn(szTemplate, VERR_INVALID_PARAMETER); 459 460 rc = RTPathUserHome(szBuf, cbBuf); 461 if (RT_FAILURE(rc)) 462 VBClLogFatalError("%s: getting home directory failed: %Rrc\n", 463 g_Service.pDesc->pszDesc, rc); 464 465 if (RT_SUCCESS(rc)) 466 rc = RTPathAppend(szBuf, cbBuf, szTemplate); 467 468 #ifdef RT_OS_LINUX 469 if (RT_SUCCESS(rc)) 470 rc = RTLinuxSysFsReadStrFile(pszActiveTTY, sizeof(pszActiveTTY) - 1 /* reserve last byte for string termination */, 471 &cchRead, "class/tty/tty0/active"); 472 if (RT_SUCCESS(rc)) 473 { 474 RTStrCat(szBuf, cbBuf, "-"); 475 RTStrCat(szBuf, cbBuf, pszActiveTTY); 476 } 477 else 478 VBClLogInfo("%s: cannot detect currently active tty device, " 479 "multiple service instances for a single user will not be allowed, rc=%Rrc", 480 g_Service.pDesc->pszDesc, rc); 481 #endif /* RT_OS_LINUX */ 482 483 if (RT_SUCCESS(rc)) 484 RTStrCat(szBuf, cbBuf, fParentProcess ? "-control.pid" : "-service.pid"); 485 486 if (RT_FAILURE(rc)) 487 VBClLogFatalError("%s: reating PID file path failed: %Rrc\n", 488 g_Service.pDesc->pszDesc, rc); 489 490 return rc; 491 } 492 493 /** 370 494 * The main loop for the VBoxClient daemon. 371 495 */ … … 378 502 if (RT_FAILURE(rc)) 379 503 return RTMsgInitFailure(rc); 504 505 /* A flag which is returned to the parent process when Guest Additions update started. */ 506 bool fUpdateStarted = false; 380 507 381 508 /* This should never be called twice in one process - in fact one Display … … 606 733 if (RT_FAILURE(rc)) 607 734 VBClLogFatalError("Initializing critical section failed: %Rrc\n", rc); 608 if (g_Service.pDesc->pszPidFilePath) 609 { 610 rc = RTPathUserHome(g_szPidFile, sizeof(g_szPidFile)); 735 if (g_Service.pDesc->pszPidFilePathTemplate) 736 { 737 /* Get pidfile name for parent (control) process. */ 738 rc = vbclGetPidfileName(g_szControlPidFile, sizeof(g_szControlPidFile), g_Service.pDesc->pszPidFilePathTemplate, true); 611 739 if (RT_FAILURE(rc)) 612 VBClLogFatalError("Getting home directory failed: %Rrc\n", rc); 613 rc = RTPathAppend(g_szPidFile, sizeof(g_szPidFile), g_Service.pDesc->pszPidFilePath); 740 return RTEXITCODE_FAILURE; 741 742 /* Get pidfile name for service process. */ 743 rc = vbclGetPidfileName(g_szPidFile, sizeof(g_szPidFile), g_Service.pDesc->pszPidFilePathTemplate, false); 614 744 if (RT_FAILURE(rc)) 615 VBClLogFatalError("Creating PID file path failed: %Rrc\n", rc);745 return RTEXITCODE_FAILURE; 616 746 } 617 747 618 748 if (fDaemonise) 619 rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */, fRespawn, &g_cRespawn); 749 { 750 rc = VbglR3DaemonizeEx(false /* fNoChDir */, false /* fNoClose */, fRespawn, &g_cRespawn, 751 true /* fReturnOnUpdate */, &fUpdateStarted, g_szControlPidFile, &g_hControlPidFile); 752 /* This combination only works in context of parent process. */ 753 if (RT_SUCCESS(rc) && fUpdateStarted) 754 vbclHandleUpdateStarted(argv); 755 } 756 620 757 if (RT_FAILURE(rc)) 621 758 VBClLogFatalError("Daemonizing service failed: %Rrc\n", rc); … … 625 762 rc = VbglR3PidFile(g_szPidFile, &g_hPidFile); 626 763 if (rc == VERR_FILE_LOCK_VIOLATION) /* Already running. */ 764 { 765 VBClLogInfo("%s: service already running, exitting\n", 766 g_Service.pDesc->pszDesc); 627 767 return RTEXITCODE_SUCCESS; 768 } 628 769 if (RT_FAILURE(rc)) 629 VBClLogFatalError("Creating PID file failed: %Rrc\n", rc); 770 { 771 VBClLogFatalError("Creating PID file %s failed: %Rrc\n", g_szPidFile, rc); 772 return RTEXITCODE_FAILURE; 773 } 630 774 } 631 775 … … 737 881 /** @todo r=andy Should we return an appropriate exit code if the service failed to init? 738 882 * Must be tested carefully with our init scripts first. */ 739 return RTEXITCODE_SUCCESS;740 } 741 883 return g_fProcessReloadRequested ? VBGLR3EXITCODERELOAD : RTEXITCODE_SUCCESS; 884 } 885 -
trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp
r98103 r98474 349 349 "seamless", /* szName */ 350 350 "Seamless Mode Support", /* pszDescription */ 351 ".vboxclient-seamless .pid", /* pszPidFilePath*/351 ".vboxclient-seamless", /* pszPidFilePathTemplate */ 352 352 NULL, /* pszUsage */ 353 353 NULL, /* pszOptions */
Note:
See TracChangeset
for help on using the changeset viewer.