VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibPidFile.cpp@ 98472

Last change on this file since 98472 was 98472, checked in by vboxsync, 16 months ago

Guest Library: Introduce VbglR3DaemonizeEx and VbglR3PidfileWait, bugref:10359.

VbglR3DaemonizeEx is a wrapper function for VbglR3Daemonize. In addition to the
original version it sets pidfile lock for the parent process and notifies caller
when child process terminates with exit status VBGLR3EXITCODERELOAD (currently
equal to 2) indicating that parent process should release its reference to vboxguest
kernel module and wait for SIGUSR2 in order to restart itself. This is a part of
the procedure to install and reload/restart Guest Additions kernel modules and
user services without requiring guest reboot. It is currently only has effect
on X11 guests.

VbglR3PidfileWait is a wrapper function for VbglR3Pidfile. In addition to the
original version, it waits specified amount of time until pidfile lock become
available or fails on timeout.

  • Property svn:eol-style set to native
  • Property svn:keyword set to Id
  • Property svn:keywords set to Id Revision
File size: 5.2 KB
Line 
1/** $Id: VBoxGuestR3LibPidFile.cpp 98472 2023-02-03 18:56:59Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions,
4 * Create a PID file.
5 */
6
7/*
8 * Copyright (C) 2015-2023 Oracle and/or its affiliates.
9 *
10 * This file is part of VirtualBox base platform packages, as
11 * available from https://www.virtualbox.org.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation, in version 3 of the
16 * License.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <https://www.gnu.org/licenses>.
25 *
26 * The contents of this file may alternatively be used under the terms
27 * of the Common Development and Distribution License Version 1.0
28 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
29 * in the VirtualBox distribution, in which case the provisions of the
30 * CDDL are applicable instead of those of the GPL.
31 *
32 * You may elect to license modified versions of this file under the
33 * terms and conditions of either the GPL or the CDDL or both.
34 *
35 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
36 */
37
38
39/*********************************************************************************************************************************
40* Header Files *
41*********************************************************************************************************************************/
42#include <iprt/file.h>
43#include <iprt/string.h>
44#include <iprt/process.h>
45#include <iprt/err.h>
46#include "VBoxGuestR3LibInternal.h"
47
48/* A time to wait before starting the next attempt to check a pidfile. */
49#define VBGL_PIDFILE_WAIT_RELAX_TIME_MS (250)
50
51/**
52 * Creates a PID File and returns the open file descriptor.
53 *
54 * On DOS based system, file sharing (deny write) is used for locking the PID
55 * file.
56 *
57 * On Unix-y systems, an exclusive advisory lock is used for locking the PID
58 * file since the file sharing support is usually missing there.
59 *
60 * This API will overwrite any existing PID Files without a lock on them, on the
61 * assumption that they are stale files which an old process did not properly
62 * clean up.
63 *
64 * @returns IPRT status code.
65 * @param pszPath The path and filename to create the PID File under
66 * @param phFile Where to store the file descriptor of the open (and locked
67 * on Unix-y systems) PID File. On failure, or if another
68 * process owns the PID File, this will be set to NIL_RTFILE.
69 */
70VBGLR3DECL(int) VbglR3PidFile(const char *pszPath, PRTFILE phFile)
71{
72 AssertPtrReturn(pszPath, VERR_INVALID_PARAMETER);
73 AssertPtrReturn(phFile, VERR_INVALID_PARAMETER);
74 *phFile = NIL_RTFILE;
75
76 RTFILE hPidFile;
77 int rc = RTFileOpen(&hPidFile, pszPath,
78 RTFILE_O_READWRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE
79 | (0644 << RTFILE_O_CREATE_MODE_SHIFT));
80 if (RT_SUCCESS(rc))
81 {
82#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2)
83 /** @todo using size 0 for locking means lock all on Posix.
84 * We should adopt this as our convention too, or something
85 * similar. */
86 rc = RTFileLock(hPidFile, RTFILE_LOCK_WRITE, 0, 0);
87 if (RT_FAILURE(rc))
88 RTFileClose(hPidFile);
89 else
90#endif
91 {
92 char szBuf[256];
93 size_t cbPid = RTStrPrintf(szBuf, sizeof(szBuf), "%d\n",
94 RTProcSelf());
95 RTFileWrite(hPidFile, szBuf, cbPid, NULL);
96 *phFile = hPidFile;
97 }
98 }
99 return rc;
100}
101
102
103/**
104 * Close and remove an open PID File.
105 *
106 * @param pszPath The path to the PID File,
107 * @param hFile The handle for the file. NIL_RTFILE is ignored as usual.
108 */
109VBGLR3DECL(void) VbglR3ClosePidFile(const char *pszPath, RTFILE hFile)
110{
111 AssertPtrReturnVoid(pszPath);
112 if (hFile != NIL_RTFILE)
113 {
114#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
115 RTFileWriteAt(hFile, 0, "-1", 2, NULL);
116#else
117 RTFileDelete(pszPath);
118#endif
119 RTFileClose(hFile);
120 }
121}
122
123
124/**
125 * Wait for other process to release pidfile.
126 *
127 * This function is a wrapper to VbglR3PidFile().
128 *
129 * @returns IPRT status code.
130 * @param szPidfile Path to pidfile.
131 * @param phPidfile Handle to pidfile.
132 * @param u64TimeoutMs A timeout value in milliseconds to wait for
133 * other process to release pidfile.
134 */
135VBGLR3DECL(int) VbglR3PidfileWait(const char *szPidfile, RTFILE *phPidfile, uint64_t u64TimeoutMs)
136{
137 int rc = VERR_FILE_LOCK_VIOLATION;
138 uint64_t u64Start = RTTimeSystemMilliTS();
139
140 AssertPtrReturn(szPidfile, VERR_INVALID_PARAMETER);
141 AssertPtrReturn(phPidfile, VERR_INVALID_PARAMETER);
142
143 while ( !RT_SUCCESS((rc = VbglR3PidFile(szPidfile, phPidfile)))
144 && (RTTimeSystemMilliTS() - u64Start < u64TimeoutMs))
145 {
146 RTThreadSleep(VBGL_PIDFILE_WAIT_RELAX_TIME_MS);
147 }
148
149 return rc;
150}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use