diff options
Diffstat (limited to 'src/VBox/Runtime/r3/linux')
-rw-r--r-- | src/VBox/Runtime/r3/linux/RTProcIsRunningByName-linux.cpp | 2 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/linux/RTSystemShutdown-linux.cpp | 13 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/linux/fileaio-linux.cpp | 12 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/linux/mp-linux.cpp | 70 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/linux/rtProcInitExePath-linux.cpp | 2 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/linux/sched-linux.cpp | 2 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp | 2 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/linux/semmutex-linux.cpp | 2 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/linux/sysfs.cpp | 166 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/linux/systemmem-linux.cpp | 42 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/linux/time-linux.cpp | 2 |
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; |