summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/r3/linux
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Runtime/r3/linux
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Runtime/r3/linux')
-rw-r--r--src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/RTSystemShutdown-linux.cpp13
-rw-r--r--src/VBox/Runtime/r3/linux/fileaio-linux.cpp12
-rw-r--r--src/VBox/Runtime/r3/linux/mp-linux.cpp70
-rw-r--r--src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/sched-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/semmutex-linux.cpp2
-rw-r--r--src/VBox/Runtime/r3/linux/sysfs.cpp166
-rw-r--r--src/VBox/Runtime/r3/linux/systemmem-linux.cpp42
-rw-r--r--src/VBox/Runtime/r3/linux/time-linux.cpp2
11 files changed, 210 insertions, 105 deletions
diff --git a/src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp b/src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp
index 5582cef9..64edf958 100644
--- a/src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r3/linux/RTSystemShutdown-linux.cpp b/src/VBox/Runtime/r3/linux/RTSystemShutdown-linux.cpp
index a1da642c..e58365ac 100644
--- a/src/VBox/Runtime/r3/linux/RTSystemShutdown-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/RTSystemShutdown-linux.cpp
@@ -47,20 +47,24 @@ RTDECL(int) RTSystemShutdown(RTMSINTERVAL cMsDelay, uint32_t fFlags, const char
* Assemble the argument vector.
*/
int iArg = 0;
- const char *apszArgs[5];
+ const char *apszArgs[6];
+
+ RT_BZERO(apszArgs, sizeof(apszArgs));
apszArgs[iArg++] = "/sbin/shutdown";
switch (fFlags & RTSYSTEM_SHUTDOWN_ACTION_MASK)
{
case RTSYSTEM_SHUTDOWN_HALT:
- apszArgs[iArg++] = "--halt";
+ apszArgs[iArg++] = "-h";
+ apszArgs[iArg++] = "-H";
break;
case RTSYSTEM_SHUTDOWN_REBOOT:
- apszArgs[iArg++] = "--reboot";
+ apszArgs[iArg++] = "-r";
break;
case RTSYSTEM_SHUTDOWN_POWER_OFF:
case RTSYSTEM_SHUTDOWN_POWER_OFF_HALT:
- apszArgs[iArg++] = "--poweroff";
+ apszArgs[iArg++] = "-h";
+ apszArgs[iArg++] = "-P";
break;
}
@@ -95,4 +99,3 @@ RTDECL(int) RTSystemShutdown(RTMSINTERVAL cMsDelay, uint32_t fFlags, const char
}
RT_EXPORT_SYMBOL(RTSystemShutdown);
-
diff --git a/src/VBox/Runtime/r3/linux/fileaio-linux.cpp b/src/VBox/Runtime/r3/linux/fileaio-linux.cpp
index 51215de6..2cc8feb1 100644
--- a/src/VBox/Runtime/r3/linux/fileaio-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/fileaio-linux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -183,6 +183,8 @@ typedef struct RTFILEAIOCTXINTERNAL
volatile bool fWokenUp;
/** Flag whether the thread is currently waiting in the syscall. */
volatile bool fWaiting;
+ /** Flags given during creation. */
+ uint32_t fFlags;
/** Magic value (RTFILEAIOCTX_MAGIC). */
uint32_t u32Magic;
} RTFILEAIOCTXINTERNAL;
@@ -472,10 +474,12 @@ RTDECL(int) RTFileAioReqGetRC(RTFILEAIOREQ hReq, size_t *pcbTransfered)
}
-RTDECL(int) RTFileAioCtxCreate(PRTFILEAIOCTX phAioCtx, uint32_t cAioReqsMax)
+RTDECL(int) RTFileAioCtxCreate(PRTFILEAIOCTX phAioCtx, uint32_t cAioReqsMax,
+ uint32_t fFlags)
{
PRTFILEAIOCTXINTERNAL pCtxInt;
AssertPtrReturn(phAioCtx, VERR_INVALID_POINTER);
+ AssertReturn(!(fFlags & ~RTFILEAIOCTX_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
/* The kernel interface needs a maximum. */
if (cAioReqsMax == RTFILEAIO_UNLIMITED_REQS)
@@ -493,6 +497,7 @@ RTDECL(int) RTFileAioCtxCreate(PRTFILEAIOCTX phAioCtx, uint32_t cAioReqsMax)
pCtxInt->fWaiting = false;
pCtxInt->hThreadWait = NIL_RTTHREAD;
pCtxInt->cRequestsMax = cAioReqsMax;
+ pCtxInt->fFlags = fFlags;
pCtxInt->u32Magic = RTFILEAIOCTX_MAGIC;
*phAioCtx = (RTFILEAIOCTX)pCtxInt;
}
@@ -658,7 +663,8 @@ RTDECL(int) RTFileAioCtxWait(RTFILEAIOCTX hAioCtx, size_t cMinReqs, RTMSINTERVAL
/*
* Can't wait if there are not requests around.
*/
- if (RT_UNLIKELY(ASMAtomicUoReadS32(&pCtxInt->cRequests) == 0))
+ if ( RT_UNLIKELY(ASMAtomicUoReadS32(&pCtxInt->cRequests) == 0)
+ && !(pCtxInt->fFlags & RTFILEAIOCTX_FLAGS_WAIT_WITHOUT_PENDING_REQUESTS))
return VERR_FILE_AIO_NO_REQUEST;
/*
diff --git a/src/VBox/Runtime/r3/linux/mp-linux.cpp b/src/VBox/Runtime/r3/linux/mp-linux.cpp
index 54304aba..210f75a7 100644
--- a/src/VBox/Runtime/r3/linux/mp-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/mp-linux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -33,6 +33,9 @@
#include <errno.h>
#include <iprt/mp.h>
+#include "internal/iprt.h"
+
+#include <iprt/alloca.h>
#include <iprt/cpuset.h>
#include <iprt/assert.h>
#include <iprt/string.h>
@@ -82,7 +85,7 @@ static uint32_t rtMpLinuxGetFrequency(RTCPUID idCpu)
while (fgets(sz, sizeof(sz), pFile))
{
char *psz;
- if ( !strncmp(sz, "processor", 9)
+ if ( !strncmp(sz, RT_STR_TUPLE("processor"))
&& (sz[10] == ' ' || sz[10] == '\t' || sz[10] == ':')
&& (psz = strchr(sz, ':')))
{
@@ -93,7 +96,7 @@ static uint32_t rtMpLinuxGetFrequency(RTCPUID idCpu)
idCpuFound = iCpu;
}
else if ( idCpu == idCpuFound
- && !strncmp(sz, "cpu MHz", 7)
+ && !strncmp(sz, RT_STR_TUPLE("cpu MHz"))
&& (sz[10] == ' ' || sz[10] == '\t' || sz[10] == ':')
&& (psz = strchr(sz, ':')))
{
@@ -177,6 +180,36 @@ RTDECL(RTCPUID) RTMpGetCount(void)
}
+RTDECL(RTCPUID) RTMpGetCoreCount(void)
+{
+ RTCPUID cMax = rtMpLinuxMaxCpus();
+ uint32_t *paidCores = (uint32_t *)alloca(sizeof(paidCores[0]) * (cMax + 1));
+ uint32_t *paidPckgs = (uint32_t *)alloca(sizeof(paidPckgs[0]) * (cMax + 1));
+ uint32_t cCores = 0;
+ for (RTCPUID idCpu = 0; idCpu < cMax; idCpu++)
+ {
+ if (RTMpIsCpuPossible(idCpu))
+ {
+ uint32_t idCore = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/core_id", (int)idCpu);
+ uint32_t idPckg = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/physical_package_id", (int)idCpu);
+ uint32_t i;
+ for (i = 0; i < cCores; i++)
+ if ( paidCores[i] == idCore
+ && paidPckgs[i] == idPckg)
+ break;
+ if (i >= cCores)
+ {
+ paidCores[cCores] = idCore;
+ paidPckgs[cCores] = idPckg;
+ cCores++;
+ }
+ }
+ }
+ Assert(cCores > 0);
+ return cCores;
+}
+
+
RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
{
RTCpuSetEmpty(pSet);
@@ -196,6 +229,37 @@ RTDECL(RTCPUID) RTMpGetOnlineCount(void)
}
+RTDECL(RTCPUID) RTMpGetOnlineCoreCount(void)
+{
+ RTCPUID cMax = rtMpLinuxMaxCpus();
+ uint32_t *paidCores = (uint32_t *)alloca(sizeof(paidCores[0]) * (cMax + 1));
+ uint32_t *paidPckgs = (uint32_t *)alloca(sizeof(paidPckgs[0]) * (cMax + 1));
+ uint32_t cCores = 0;
+ for (RTCPUID idCpu = 0; idCpu < cMax; idCpu++)
+ {
+ if (RTMpIsCpuOnline(idCpu))
+ {
+ uint32_t idCore = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/core_id", (int)idCpu);
+ uint32_t idPckg = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/physical_package_id", (int)idCpu);
+ uint32_t i;
+ for (i = 0; i < cCores; i++)
+ if ( paidCores[i] == idCore
+ && paidPckgs[i] == idPckg)
+ break;
+ if (i >= cCores)
+ {
+ paidCores[cCores] = idCore;
+ paidPckgs[cCores] = idPckg;
+ cCores++;
+ }
+ }
+ }
+ Assert(cCores > 0);
+ return cCores;
+}
+
+
+
RTDECL(uint32_t) RTMpGetCurFrequency(RTCPUID idCpu)
{
int64_t kHz = RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", (int)idCpu);
diff --git a/src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp b/src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp
index 3ab0860b..cb43d9d0 100644
--- a/src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r3/linux/sched-linux.cpp b/src/VBox/Runtime/r3/linux/sched-linux.cpp
index 3972a6af..1e85af5b 100644
--- a/src/VBox/Runtime/r3/linux/sched-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/sched-linux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp b/src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp
index 01094187..b623c846 100644
--- a/src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r3/linux/semmutex-linux.cpp b/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
index 1be76f4e..60abc1ed 100644
--- a/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r3/linux/sysfs.cpp b/src/VBox/Runtime/r3/linux/sysfs.cpp
index aa1060ac..15309330 100644
--- a/src/VBox/Runtime/r3/linux/sysfs.cpp
+++ b/src/VBox/Runtime/r3/linux/sysfs.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -53,8 +53,7 @@
* Constructs the path of a sysfs file from the format parameters passed,
* prepending a prefix if the path is relative.
*
- * @returns The number of characters returned, or -1 and errno set to ERANGE on
- * failure.
+ * @returns The number of characters returned, or an iprt error code on failure.
*
* @param pszPrefix The prefix to prepend if the path is relative. Must end
* in '/'.
@@ -70,8 +69,8 @@ static ssize_t rtLinuxConstructPathV(char *pszBuf, size_t cchBuf,
const char *pszFormat, va_list va)
{
size_t cchPrefix = strlen(pszPrefix);
- AssertReturnStmt(pszPrefix[cchPrefix - 1] == '/', errno = ERANGE, -1);
- AssertReturnStmt(cchBuf > cchPrefix + 1, errno = ERANGE, -1);
+ AssertReturn(pszPrefix[cchPrefix - 1] == '/', VERR_INVALID_PARAMETER);
+ AssertReturn(cchBuf > cchPrefix + 1, VERR_INVALID_PARAMETER);
/** @todo While RTStrPrintfV prevents overflows, it doesn't make it easy to
* check for truncations. RTPath should provide some formatters and
@@ -80,7 +79,7 @@ static ssize_t rtLinuxConstructPathV(char *pszBuf, size_t cchBuf,
size_t cch = RTStrPrintfV(pszBuf, cchBuf, pszFormat, va);
if (*pszBuf != '/')
{
- AssertReturnStmt(cchBuf >= cch + cchPrefix + 1, errno = ERANGE, -1);
+ AssertReturn(cchBuf >= cch + cchPrefix + 1, VERR_BUFFER_OVERFLOW);
memmove(pszBuf + cchPrefix, pszBuf, cch + 1);
memcpy(pszBuf, pszPrefix, cchPrefix);
cch += cchPrefix;
@@ -93,8 +92,8 @@ static ssize_t rtLinuxConstructPathV(char *pszBuf, size_t cchBuf,
* Constructs the path of a sysfs file from the format parameters passed,
* prepending a prefix if the path is relative.
*
- * @returns The number of characters returned, or -1 and errno set to ERANGE on
- * failure.
+ * @returns The number of characters returned, or an iprt error code on failure.
+ * @note Unused.
*
* @param pszPrefix The prefix to prepend if the path is relative. Must end
* in '/'.
@@ -131,7 +130,11 @@ static ssize_t rtLinuxConstructPath(char *pszBuf, size_t cchBuf,
*/
static ssize_t rtLinuxSysFsConstructPath(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va)
{
- return rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va);
+ ssize_t rc = rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va);
+ if (rc >= 0)
+ return rc;
+ errno = ERANGE;
+ return -1;
}
@@ -409,125 +412,118 @@ RTDECL(ssize_t) RTLinuxSysFsGetLinkDest(char *pszBuf, size_t cchBuf, const char
}
-static ssize_t rtLinuxFindDevicePathRecursive(dev_t DevNum, RTFMODE fMode, const char *pszBasePath,
- char *pszBuf, size_t cchBuf)
+/** Search for a device node with the number @a DevNum and the type (character
+ * or block) @a fMode below the path @a pszPath. @a pszPath MUST point to a
+ * buffer of size at least RTPATH_MAX which will be modified during the function
+ * execution. On successful return it will contain the path to the device node
+ * found. */
+/** @note This function previously used a local stack buffer of size RTPATH_MAX
+ * to construct the path passed to the next recursive call, which used up 4K
+ * of stack space per iteration and caused a stack overflow on a path with
+ * too many components. */
+static int rtLinuxFindDevicePathRecursive(dev_t DevNum, RTFMODE fMode,
+ char *pszPath)
{
+ int rc;
+ PRTDIR pDir;
+ size_t const cchPath = strlen(pszPath);
+
/*
* Check assumptions made by the code below.
*/
- size_t const cchBasePath = strlen(pszBasePath);
- AssertReturnStmt(cchBasePath < RTPATH_MAX - 10U, errno = ENAMETOOLONG, -1);
-
- ssize_t rcRet;
- PRTDIR pDir;
- int rc = RTDirOpen(&pDir, pszBasePath);
+ AssertReturn(cchPath < RTPATH_MAX - 10U, VERR_BUFFER_OVERFLOW);
+ rc = RTDirOpen(&pDir, pszPath);
if (RT_SUCCESS(rc))
{
- char szPath[RTPATH_MAX]; /** @todo 4K per recursion - can easily be optimized away by passing it along pszBasePath
- and only remember the length. */
- memcpy(szPath, pszBasePath, cchBasePath + 1);
-
for (;;)
{
RTDIRENTRYEX Entry;
- rc = RTDirReadEx(pDir, &Entry, NULL, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
+ rc = RTDirReadEx(pDir, &Entry, NULL, RTFSOBJATTRADD_UNIX,
+ RTPATH_F_ON_LINK);
if (RT_FAILURE(rc))
- {
- errno = rc == VERR_NO_MORE_FILES
- ? ENOENT
- : rc == VERR_BUFFER_OVERFLOW
- ? EOVERFLOW
- : EIO;
- rcRet = -1;
break;
- }
if (RTFS_IS_SYMLINK(Entry.Info.Attr.fMode))
continue;
-
+ pszPath[cchPath] = '\0';
+ rc = RTPathAppend(pszPath, RTPATH_MAX, Entry.szName);
+ if (RT_FAILURE(rc))
+ break;
/* Do the matching. */
if ( Entry.Info.Attr.u.Unix.Device == DevNum
&& (Entry.Info.Attr.fMode & RTFS_TYPE_MASK) == fMode)
- {
- rcRet = rtLinuxConstructPath(pszBuf, cchBuf, pszBasePath, "%s", Entry.szName);
break;
- }
-
/* Recurse into subdirectories. */
if (!RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode))
continue;
if (Entry.szName[0] == '.')
continue;
-
- szPath[cchBasePath] = '\0';
- rc = RTPathAppend(szPath, sizeof(szPath) - 1, Entry.szName); /* -1: for slash */
- if (RT_FAILURE(rc))
- {
- errno = ENAMETOOLONG;
- rcRet = -1;
- break;
- }
- strcat(&szPath[cchBasePath], "/");
- rcRet = rtLinuxFindDevicePathRecursive(DevNum, fMode, szPath, pszBuf, cchBuf);
- if (rcRet >= 0 || errno != ENOENT)
+ rc = rtLinuxFindDevicePathRecursive(DevNum, fMode, pszPath);
+ if (RT_SUCCESS(rc) || rc != VERR_NO_MORE_FILES)
break;
}
RTDirClose(pDir);
}
- else
- {
- rcRet = -1;
- errno = RTErrConvertToErrno(rc);
- }
- return rcRet;
+ return rc;
}
-RTDECL(ssize_t) RTLinuxFindDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf,
- const char *pszSuggestion, va_list va)
+RTDECL(ssize_t) RTLinuxFindDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf,
+ size_t cchBuf, const char *pszSuggestion,
+ va_list va)
{
- AssertReturnStmt(cchBuf >= 2, errno = EINVAL, -1);
- AssertReturnStmt( fMode == RTFS_TYPE_DEV_CHAR
- || fMode == RTFS_TYPE_DEV_BLOCK,
- errno = EINVAL, -1);
+ char szFilename[RTPATH_MAX];
+ int rc = VINF_TRY_AGAIN;
+ AssertReturn(cchBuf >= 2, VERR_INVALID_PARAMETER);
+ AssertReturn( fMode == RTFS_TYPE_DEV_CHAR
+ || fMode == RTFS_TYPE_DEV_BLOCK,
+ VERR_INVALID_PARAMETER);
if (pszSuggestion)
{
/*
* Construct the filename and read the link.
*/
- char szFilename[RTPATH_MAX];
- int rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/", pszSuggestion, va);
- if (rc == -1)
- return -1;
-
- /*
- * Check whether the caller's suggestion was right.
- */
- RTFSOBJINFO Info;
- rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX);
- if ( RT_SUCCESS(rc)
- && Info.Attr.u.Unix.Device == DevNum
- && (Info.Attr.fMode & RTFS_TYPE_MASK) == fMode)
+ rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/",
+ pszSuggestion, va);
+ if (rc > 0)
{
- size_t cchPath = strlen(szFilename);
- if (cchPath >= cchBuf)
- {
- errno = EOVERFLOW;
- return -1;
- }
- memcpy(pszBuf, szFilename, cchPath + 1);
- return cchPath;
+ /*
+ * Check whether the caller's suggestion was right.
+ */
+ RTFSOBJINFO Info;
+ rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX);
+ if ( rc == VERR_PATH_NOT_FOUND
+ || rc == VERR_FILE_NOT_FOUND
+ || ( RT_SUCCESS(rc)
+ && ( Info.Attr.u.Unix.Device != DevNum
+ || (Info.Attr.fMode & RTFS_TYPE_MASK) != fMode)))
+ /* The suggestion was wrong, fall back on the brute force attack. */
+ rc = VINF_TRY_AGAIN;
}
-
- /* The suggestion was wrong, fall back on the brute force attack. */
}
- return rtLinuxFindDevicePathRecursive(DevNum, fMode, "/dev/", pszBuf, cchBuf);
+ if (rc == VINF_TRY_AGAIN)
+ {
+ RTStrCopy(szFilename, sizeof(szFilename), "/dev/");
+ rc = rtLinuxFindDevicePathRecursive(DevNum, fMode, szFilename);
+ }
+ if (RT_SUCCESS(rc))
+ {
+ size_t cchPath = strlen(szFilename);
+ if (cchPath >= cchBuf)
+ return VERR_BUFFER_OVERFLOW;
+ memcpy(pszBuf, szFilename, cchPath + 1);
+ return cchPath;
+ }
+ return rc;
}
-RTDECL(ssize_t) RTLinuxFindDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf,
- const char *pszSuggestion, ...)
+/** @todo Do we really need to return the string length? If the caller is
+ * interested (the current ones aren't) they can check themselves. */
+RTDECL(ssize_t) RTLinuxFindDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf,
+ size_t cchBuf, const char *pszSuggestion,
+ ...)
{
va_list va;
va_start(va, pszSuggestion);
diff --git a/src/VBox/Runtime/r3/linux/systemmem-linux.cpp b/src/VBox/Runtime/r3/linux/systemmem-linux.cpp
index f3234403..23fe70b8 100644
--- a/src/VBox/Runtime/r3/linux/systemmem-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/systemmem-linux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2012 Oracle Corporation
+ * Copyright (C) 2012-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -33,7 +33,9 @@
#include <iprt/err.h>
#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <stdio.h>
#include <errno.h>
/* Satisfy compiller warning */
@@ -50,7 +52,7 @@ RTDECL(int) RTSystemQueryTotalRam(uint64_t *pcb)
int rc = sysinfo(&info);
if (rc == 0)
{
- *pcb = (uint64_t)(info.totalram * (unsigned long)info.mem_unit);
+ *pcb = (uint64_t)info.totalram * info.mem_unit;
return VINF_SUCCESS;
}
return RTErrConvertFromErrno(errno);
@@ -61,11 +63,45 @@ RTDECL(int) RTSystemQueryAvailableRam(uint64_t *pcb)
{
AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+ FILE *pFile = fopen("/proc/meminfo", "r");
+ if (pFile)
+ {
+ int rc = VERR_NOT_FOUND;
+ uint64_t cbTotal = 0;
+ uint64_t cbFree = 0;
+ uint64_t cbBuffers = 0;
+ uint64_t cbCached = 0;
+ char sz[256];
+ while (fgets(sz, sizeof(sz), pFile))
+ {
+ if (!strncmp(sz, RT_STR_TUPLE("MemTotal:")))
+ rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("MemTotal:")]), NULL, 0, &cbTotal);
+ else if (!strncmp(sz, RT_STR_TUPLE("MemFree:")))
+ rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("MemFree:")]), NULL, 0, &cbFree);
+ else if (!strncmp(sz, RT_STR_TUPLE("Buffers:")))
+ rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("Buffers:")]), NULL, 0, &cbBuffers);
+ else if (!strncmp(sz, RT_STR_TUPLE("Cached:")))
+ rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("Cached:")]), NULL, 0, &cbCached);
+ if (RT_FAILURE(rc))
+ break;
+ }
+ fclose(pFile);
+ if (RT_SUCCESS(rc))
+ {
+ *pcb = (cbFree + cbBuffers + cbCached) * _1K;
+ return VINF_SUCCESS;
+ }
+ }
+ /*
+ * Fallback (e.g. /proc not mapped) to sysinfo. Less accurat because there
+ * is no information about the cached memory. 'Cached:' from above is only
+ * accessible through proc :-(
+ */
struct sysinfo info;
int rc = sysinfo(&info);
if (rc == 0)
{
- *pcb = (uint64_t)(info.freeram * (unsigned long)info.mem_unit);
+ *pcb = ((uint64_t)info.freeram + info.bufferram) * info.mem_unit;
return VINF_SUCCESS;
}
return RTErrConvertFromErrno(errno);
diff --git a/src/VBox/Runtime/r3/linux/time-linux.cpp b/src/VBox/Runtime/r3/linux/time-linux.cpp
index a9de927e..ab9c0e5a 100644
--- a/src/VBox/Runtime/r3/linux/time-linux.cpp
+++ b/src/VBox/Runtime/r3/linux/time-linux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;