]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Sync git tree with internal development branch @ 2009.08.24.
authorMarcelo Vanzin <mvanzin@mvanzin-dev1.eng.vmware.com>
Thu, 17 Sep 2009 22:35:39 +0000 (15:35 -0700)
committerMarcelo Vanzin <mvanzin@mvanzin-dev1.eng.vmware.com>
Fri, 18 Sep 2009 22:18:27 +0000 (15:18 -0700)
55 files changed:
open-vm-tools/hgfsmounter/hgfsmounter.c
open-vm-tools/lib/file/fileInt.h
open-vm-tools/lib/file/fileLockPosix.c
open-vm-tools/lib/file/fileLockPrimitive.c
open-vm-tools/lib/foundryMsg/foundryThreads.c
open-vm-tools/lib/guestApp/guestApp.c
open-vm-tools/lib/include/backdoor_def.h
open-vm-tools/lib/include/conf.h
open-vm-tools/lib/include/dynbuf.h
open-vm-tools/lib/include/fileLock.h
open-vm-tools/lib/include/foundryThreads.h
open-vm-tools/lib/include/loglevel_user.h
open-vm-tools/lib/include/message.h
open-vm-tools/lib/include/netutil.h
open-vm-tools/lib/include/procMgr.h
open-vm-tools/lib/include/system.h
open-vm-tools/lib/include/vm_version.h
open-vm-tools/lib/include/win32util.h
open-vm-tools/lib/message/Makefile.am
open-vm-tools/lib/message/message.c
open-vm-tools/lib/message/messageBackdoor.c [deleted file]
open-vm-tools/lib/message/messageStub.c [deleted file]
open-vm-tools/lib/misc/dynbuf.c
open-vm-tools/lib/vixTools/vixTools.c
open-vm-tools/lib/vmCheck/vmcheck.c
open-vm-tools/modules/freebsd/vmhgfs/Makefile
open-vm-tools/modules/freebsd/vmmemctl/balloon_def.h
open-vm-tools/modules/freebsd/vmmemctl/os.c
open-vm-tools/modules/freebsd/vmmemctl/os.h
open-vm-tools/modules/freebsd/vmmemctl/vmballoon.c
open-vm-tools/modules/freebsd/vmmemctl/vmballoon.h
open-vm-tools/modules/linux/pvscsi/pvscsi.c
open-vm-tools/modules/linux/pvscsi/pvscsi_version.h
open-vm-tools/modules/linux/pvscsi/scsi_defs.h
open-vm-tools/modules/linux/shared/vmci_defs.h
open-vm-tools/modules/linux/shared/vmci_infrastructure.h
open-vm-tools/modules/linux/shared/vmci_iocontrols.h
open-vm-tools/modules/linux/vmhgfs/Makefile.kernel
open-vm-tools/modules/linux/vmhgfs/Makefile.normal
open-vm-tools/modules/linux/vmhgfs/fsutil.c
open-vm-tools/modules/linux/vmhgfs/inode.c
open-vm-tools/modules/linux/vmmemctl/balloon_def.h
open-vm-tools/modules/linux/vmmemctl/os.c
open-vm-tools/modules/linux/vmmemctl/os.h
open-vm-tools/modules/linux/vmmemctl/vmballoon.c
open-vm-tools/modules/linux/vmmemctl/vmballoon.h
open-vm-tools/modules/solaris/vmhgfs/Makefile
open-vm-tools/modules/solaris/vmmemctl/balloon_def.h
open-vm-tools/modules/solaris/vmmemctl/os.c
open-vm-tools/modules/solaris/vmmemctl/os.h
open-vm-tools/modules/solaris/vmmemctl/vmballoon.c
open-vm-tools/modules/solaris/vmmemctl/vmballoon.h
open-vm-tools/modules/solaris/vmmemctl/vmballoon_kstats.c
open-vm-tools/scripts/linux/resume-vm-default
open-vm-tools/scripts/linux/suspend-vm-default

index 52bde0afc51d598dd2f1fea7b80b6cb01d983c56..e4e488d7a7f66e37417d964eca8fc99e942564d1 100644 (file)
@@ -592,7 +592,7 @@ ParseTtl(const char *option,        // IN:  option string along with value
    optString = StrUtil_GetNextToken(&idx, option, "=");
    ASSERT(optString);
 
-   if (StrUtil_GetNextIntToken(&ttl, &idx, option, "=") && ttl > 0) {
+   if (StrUtil_GetNextIntToken(&ttl, &idx, option, "=") && ttl >= 0) {
       LOG("Setting maximum attribute TTL to %u\n", ttl);
       mountInfo->ttl = ttl;
       success = TRUE;
index a202066395f479bb6e412606bc71deb689b65e52..79fca7462edc8c9d6e3a69abb2c78e7ac129c6a1 100644 (file)
@@ -249,6 +249,9 @@ EXTERN void *FileLockIntrinsic(ConstUnicode filePathName,
 EXTERN int FileUnlockIntrinsic(ConstUnicode filePathName,
                                const void *lockToken);
 
+EXTERN Bool FileLockIsLocked(ConstUnicode filePath,
+                             int *err);
+
 EXTERN Bool FileLockValidOwner(const char *executionID,
                                const char *payload);
 
index c2a2ffa2f1036bc4c10857d130445278ddd6a599..f3542ac2d4835398e70bf979184d5394de16acfd 100644 (file)
@@ -1172,6 +1172,7 @@ FileLock_Lock(ConstUnicode filePath,         // IN:
    normalizedPath = FileLockNormalizePath(filePath);
    if (normalizedPath == NULL) {
       *err = EINVAL;
+
       return NULL;
    }
 
@@ -1187,6 +1188,49 @@ FileLock_Lock(ConstUnicode filePath,         // IN:
 }
 
 
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileLock_IsLocked --
+ *
+ *      Is a file currently locked (at the time of the call)?
+ *
+ * Results:
+ *      TRUE    YES
+ *      FALSE   NO; if err is not NULL may check *err for an error
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Bool
+FileLock_IsLocked(ConstUnicode filePath,  // IN:
+                  int *err)               // OUT:
+{
+   Bool isLocked;
+   Unicode normalizedPath;
+
+   ASSERT(filePath);
+
+   normalizedPath = FileLockNormalizePath(filePath);
+   if (normalizedPath == NULL) {
+      if (err != NULL) {
+         *err = EINVAL;
+      }
+
+      return FALSE;
+   }
+
+   isLocked = FileLockIsLocked(normalizedPath, err);
+
+   Unicode_Free(normalizedPath);
+
+   return isLocked;
+}
+
+
 /*
  *----------------------------------------------------------------------
  *
index 64b475b105b8ee8d7fa19010043bafe4a7853a29..ae0e3924c0b8011539e931b349935b9f37ac9085 100644 (file)
@@ -1373,6 +1373,7 @@ CreateEntryDirectory(const char *machineID,    // IN:
    return err;
 }
 
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -1474,6 +1475,7 @@ CreateMemberFile(FILELOCK_FILE_HANDLE entryHandle,  // IN:
    return 0;
 }
 
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -1657,6 +1659,71 @@ bail:
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * FileLockIsLocked --
+ *
+ *      Is a file currently locked (at the time of the call)?
+ *
+ * Results:
+ *      TRUE    YES
+ *      FALSE   NO; if err is not NULL may check *err for an error
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+FileLockIsLocked(ConstUnicode pathName,  // IN:
+                 int *err)               // OUT:
+{
+   uint32 i;
+   int errValue;
+   int numEntries;
+   Unicode lockDir;
+
+   Bool isLocked = FALSE;
+   Unicode *fileList = NULL;
+
+   lockDir = Unicode_Append(pathName, FILELOCK_SUFFIX);
+
+   numEntries = FileListDirectoryRobust(lockDir, &fileList);
+
+   if (numEntries == -1) {
+      errValue = errno;
+
+      goto bail;
+   }
+
+   for (i = 0; i < numEntries; i++) {
+      if (Unicode_StartsWith(fileList[i], "M")) {
+         isLocked = TRUE;
+         break;
+      }
+   }
+
+   for (i = 0; i < numEntries; i++) {
+      Unicode_Free(fileList[i]);
+   }
+
+   free(fileList);
+
+   errValue = 0;
+
+bail:
+   Unicode_Free(lockDir);
+
+   if (err != NULL) {
+      *err = errValue;
+   }
+
+   return isLocked;
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
index fcc60008496f0b88dd89ff70882152ca19e2726c..9777bb7e7c69e7f88acf57bf0a77286929e4000b 100644 (file)
@@ -37,6 +37,9 @@
 
 #include "vix.h"
 #include "foundryThreads.h"
+#include "vixOpenSource.h"
+#include "str.h"
+#include "msg.h"
 
 #if _WIN32
 #include <objbase.h.> // For CoInitializeEx
@@ -44,6 +47,9 @@ static DWORD WINAPI FoundryThreadWrapperProc(LPVOID lpParameter);
 #else // Linux
 #include <pthread.h>
 static void *FoundryThreadWrapperProc(void *lpParameter);
+#if defined(linux)
+#include <sys/prctl.h>
+#endif
 #endif
 
 
@@ -64,7 +70,8 @@ static void *FoundryThreadWrapperProc(void *lpParameter);
 
 FoundryWorkerThread *
 FoundryThreads_StartThread(FoundryThreadProc proc,    // IN
-                           void *threadParam)         // IN
+                           void *threadParam,         // IN
+                           const char *threadName)    // IN
 {
    VixError err = VIX_OK;
    FoundryWorkerThread *threadState = NULL;
@@ -79,6 +86,7 @@ FoundryThreads_StartThread(FoundryThreadProc proc,    // IN
    threadState = (FoundryWorkerThread *) Util_SafeCalloc(1, sizeof(*threadState));
    threadState->threadProc = proc;
    threadState->threadParam = threadParam;
+   threadState->threadName = threadName;
 
 #ifdef _WIN32
    threadState->threadHandle = CreateThread(NULL,
@@ -264,6 +272,17 @@ FoundryThreadWrapperProc(void *threadParameter)      // IN
       ASSERT(0);
       goto abort;
    }
+#if defined(linux) && defined(PR_SET_NAME)
+   {
+      char threadName[64];
+      int retval;
+      Str_Sprintf(threadName, sizeof threadName, "vix-%s", threadState->threadName);
+      retval = prctl(PR_SET_NAME, (unsigned long)threadName, 0,0, 0);
+      if (retval != 0) {
+         VIX_DEBUG(("%s prctl PR_SET_NAME failed = %s\n", __FUNCTION__, Msg_ErrString()));
+      }
+   }
+#endif
 
    if (NULL != threadState->threadProc) {
       (*(threadState->threadProc))(threadState);
index d0ee6baf91b221d81e6ac7391c2f0a7a562e187b..89c2f15b34ed4c12859915b9acef8d91349cd111 100644 (file)
@@ -51,11 +51,9 @@ extern "C" {
 #include "productState.h"
 #include "posix.h"
 
-#if !defined(N_PLAT_NLM)
-# include "hgfs.h"
-# include "cpName.h"
-# include "cpNameUtil.h"
-#endif
+#include "hgfs.h"
+#include "cpName.h"
+#include "cpNameUtil.h"
 
 #ifdef _MSC_VER
 #include <windows.h>
@@ -71,9 +69,7 @@ extern "C" {
  * intelligent for that platform as well.
  */
 
-#if defined(N_PLAT_NLM)
-#define GUESTAPP_TOOLS_INSTALL_PATH "SYS:\\ETC\\VMWTOOL"
-#elif defined(_WIN32)
+#if defined(_WIN32)
 #define GUESTAPP_TOOLS_INSTALL_PATH ""
 #else
 #define GUESTAPP_TOOLS_INSTALL_PATH "/etc/vmware-tools"
@@ -442,7 +438,7 @@ GuestApp_GetDictEntryBool(GuestApp_Dict *dict, // IN
       return FALSE;
    }
 
-#if  (defined N_PLAT_NLM || defined _WIN32)
+#if defined (_WIN32)
    return (stricmp(value, "TRUE") == 0);
 #else
    return (strcasecmp(value, "TRUE") == 0);
@@ -1644,7 +1640,6 @@ GuestApp_HostCopyStep(uint8 c) // IN
 }
 
 
-#if !defined(N_PLAT_NLM)
 /*
  *----------------------------------------------------------------------------
  *
@@ -1792,7 +1787,6 @@ GuestApp_RpcSendOneCPName(char const *cmd,  // IN: RPCI command
    free(rpcMessage);
    return TRUE;
 }
-#endif
 
 
 /*
index bb524d767a51b495475fecb97d49a3c9c64acf11..0c643932013a94ee5a845513cf77639097c6e216 100644 (file)
 #define BDOOR_CMD_GET_HOST_VIDEO_MODES  59 /* Not in use */
 #define BDOOR_CMD_ACPI_HOTPLUG_CPU      60
 #define BDOOR_CMD_USB_HOTPLUG_MOUSE     61 /* Not in use */
-#define BDOOR_CMD_MAX                   62
+#define BDOOR_CMD_XPMODE                62
+#define BDOOR_CMD_MAX                   63
 
 
 /* 
index a86706581587ec8768eca8369a883838323d1392..961c56d8682c6c713d7bf38bf24f97fa038a5e40 100644 (file)
 
 #include "guestApp.h"
 
-#ifdef N_PLAT_NLM
-#define CONF_FILE         "tools.cfg"
-#else
 #define CONF_FILE         "tools.conf"
-#endif
 
-#ifdef N_PLAT_NLM
-#   define CONFVAL_POWERONSCRIPT_DEFAULT  "POWERON.NCF"
-#   define CONFVAL_POWEROFFSCRIPT_DEFAULT "POWEROFF.NCF"
-#   define CONFVAL_RESUMESCRIPT_DEFAULT   "RESUME.NCF"
-#   define CONFVAL_SUSPENDSCRIPT_DEFAULT  "SUSPEND.NCF"
-#elif ! defined(_WIN32)
+#if ! defined(_WIN32)
 #   define CONFVAL_POWERONSCRIPT_DEFAULT  "poweron-vm-default"
 #   define CONFVAL_POWEROFFSCRIPT_DEFAULT "poweroff-vm-default"
 #   define CONFVAL_RESUMESCRIPT_DEFAULT   "resume-vm-default"
@@ -74,7 +65,7 @@
  * Directory containing the tools library files.  Currently only intended
  * for vmware-user.
  */
-#if !defined(_WIN32) && !defined(N_PLAT_NLM)
+#if !defined(_WIN32)
 #   define CONFNAME_LIBDIR                        "libdir"
 #endif
 
index f6a3776d2bc2bd56699c63b54d45f8c996ee1eee..90c1e59d1ab8bed041a607419e775650d0cfd39f 100644 (file)
@@ -70,6 +70,16 @@ Bool
 DynBuf_Copy(DynBuf *src,    // IN
             DynBuf *dest);  // OUT
 
+void
+DynBuf_SafeInternalAppend(DynBuf *b,            // IN
+                          void const *data,     // IN
+                          size_t size,          // IN
+                          char const *file,     // IN
+                          unsigned int lineno); // IN
+
+#define DynBuf_SafeAppend(_buf, _data, _size) \
+   DynBuf_SafeInternalAppend(_buf, _data, _size, __FILE__, __LINE__)
+
 
 /*
  *-----------------------------------------------------------------------------
index 4f9bb52984cd6cdf6f5982810ad519f2c50a6b01..fe4eea93dfba82bf1cd0f0df766d710aa9af3d07 100644 (file)
@@ -65,6 +65,9 @@ EXTERN void *FileLock_Lock(ConstUnicode filePath,
 EXTERN int FileLock_Unlock(ConstUnicode filePath,
                            const void *fileLockToken);
 
+EXTERN Bool FileLock_IsLocked(ConstUnicode filePath,
+                              int *err);
+
 EXTERN int FileLock_Remove(ConstUnicode filePath);
 EXTERN int FileLock_CleanupVM(ConstUnicode cfgfilePath);
 
index dafdc0b3eb79843dbd219514b6a8427009b3cff2..9eda3b7c0a2abe4ad6b9d9c87630966b21e4be6b 100644 (file)
@@ -40,7 +40,8 @@ struct FoundryWorkerThread;
 typedef void (*FoundryThreadProc)(struct FoundryWorkerThread *threadState);
 
 struct FoundryWorkerThread *FoundryThreads_StartThread(FoundryThreadProc proc,
-                                                       void *threadParam);
+                                                       void *threadParam,
+                                                       const char *threadName);
 void FoundryThreads_StopThread(struct FoundryWorkerThread *threadState);
 void FoundryThreads_Free(struct FoundryWorkerThread *threadState);
 Bool FoundryThreads_IsCurrentThread(struct FoundryWorkerThread *threadState);
@@ -61,6 +62,7 @@ typedef struct FoundryWorkerThread {
    Bool                    stopThread;
 
    void                    *threadParam;
+   const char              *threadName;
 } FoundryWorkerThread;
 
 
index c09285f7a86636a83f3137cad9a59d9f44e488ca..0cc95785f303822615831470d931c997628071f4 100644 (file)
    LOGLEVEL_VAR(ipc), \
    LOGLEVEL_VAR(smbios), \
    LOGLEVEL_VAR(acpi), \
+   LOGLEVEL_VAR(xpmode), \
    LOGLEVEL_VAR(snapshot), \
    LOGLEVEL_VAR(asyncsocket), \
    LOGLEVEL_VAR(mainMem), \
    LOGLEVEL_VAR(brtalk), /* macWireless and wpa_supplicant */ \
    LOGLEVEL_VAR(button), \
    LOGLEVEL_VAR(util), \
+   LOGLEVEL_VAR(win32util), \
    LOGLEVEL_VAR(largepage), \
-   LOGLEVEL_VAR(guestAppMonitor),
+   LOGLEVEL_VAR(guestAppMonitor), \
+
 
 LOGLEVEL_EXTENSION_DECLARE(LOGLEVEL_USER);
 
index 43428220ed9977895a22038de3ec13a7d2411c6f..757e9f4c09b5847257b584b65605d35a96143c2d 100644 (file)
@@ -72,34 +72,9 @@ typedef Bool (*MessageReceiveProcType)(Message_Channel *chan,
 typedef Bool (*MessageCloseProcType)(Message_Channel *chan);
 
 
-/*
- * This tells the message layer to use an alternate transport
- * for messages. By default, we use the backdoor, so this function
- * overrides that default at runtime and switches everything over to
- * an alternate transport.
- */
-void Message_SetTransport(MessageOpenProcType openProc,
-                          MessageGetReadEventProcType getReadEeventProc,
-                          MessageSendProcType sendProc,
-                          MessageReceiveProcType receiveProc,
-                          MessageCloseProcType closeProc);
-
-void MessageStub_RegisterTransport(void);
-
 Message_Channel *
 Message_Open(uint32 proto); // IN
 
-/*
- * This allows higher levels of the IPC stack to use an event to detect
- * when a message has arrived. This allows an interrupt-model rather than
- * continually calling Message_Receive in a busy loop. This may only be supported
- * by some transports. The backdoor does not, so the IPC code will still
- * have to poll in those cases.
- */
-Bool
-Message_GetReadEvent(Message_Channel *chan,    // IN
-                     int64 *event);            // OUT
-
 Bool
 Message_Send(Message_Channel *chan,    // IN/OUT
              const unsigned char *buf, // IN
index c7af8e341c0259312b4fbcec4c578ccba46cae5b..8cd2193ae8bd95a217f22bfb4731094f94374266 100644 (file)
 #endif
 
 #include "vm_basic_types.h"
-
-#if !defined(N_PLAT_NLM)
-#  include "guestInfo.h"
-#endif
+#include "guestInfo.h"
 
 /*
  * Interface types as assigned by IANA.
@@ -72,9 +69,7 @@ typedef FIXED_INFO_W2KSP1 *PFIXED_INFO;
 
 char *NetUtil_GetPrimaryIP(void);
 
-#if !defined(N_PLAT_NLM)
 GuestNic *NetUtil_GetPrimaryNic(void);
-#endif
 
 #ifdef _WIN32
 DWORD NetUtil_LoadIpHlpApiDll(void);
@@ -95,12 +90,6 @@ PMIB_IPFORWARD_TABLE2 NetUtilWin32_GetIpForwardTable2(void);
 void NetUtilWin32_FreeMibTable(PMIB_IPFORWARD_TABLE2);
 #endif
 
-#ifdef N_PLAT_NLM
-/* Monitoring IP changes */
-void NetUtil_MonitorIPStart(void);
-void NetUtil_MonitorIPStop(void);
-#endif
-
 #ifdef WIN32
 int NetUtil_InetPToN(int af, const char *src, void *dst);
 const char *NetUtil_InetNToP(int af, const void *src, char *dst,
index b7ba805393b86a24c01648e01b581530f05adc92..150214e53563ed7ff894cc8a1777b028c6911e42 100644 (file)
 #   define __PROCMGR_H__
 
 #include "vm_basic_types.h"
-#if !defined(N_PLAT_NLM)
 #include "auth.h"
+#if !defined(_WIN32)
+#  include <sys/types.h>
 #endif
-#if defined(N_PLAT_NLM)
-#include <nwconio.h>
-#elif !defined(_WIN32)
-#include <sys/types.h>
-#endif
-
-#if !defined(N_PLAT_NLM)
 #include <time.h>
-#endif
 
 /*
  * Keeps track of the platform-specific handle(s) to an asynchronous process.
  */
 typedef struct ProcMgr_AsyncProc ProcMgr_AsyncProc;
 
-#if defined(N_PLAT_NLM)
-   typedef LONG ProcMgr_Pid;
-#elif defined(_WIN32)
+#if defined(_WIN32)
    typedef DWORD ProcMgr_Pid;
 #else /* POSIX */
    typedef pid_t ProcMgr_Pid;
@@ -64,9 +55,7 @@ typedef struct ProcMgr_ProcList {
 #if defined(_WIN32)
    Bool        *procDebugged;
 #endif
-#if !defined(N_PLAT_NLM)
    time_t      *startTime;
-#endif
 } ProcMgr_ProcList;
 
 
@@ -140,7 +129,7 @@ ProcMgr_Pid ProcMgr_GetPid(ProcMgr_AsyncProc *asyncProc);
 Bool ProcMgr_IsAsyncProcRunning(ProcMgr_AsyncProc *asyncProc);
 int ProcMgr_GetExitCode(ProcMgr_AsyncProc *asyncProc, int *result);
 void ProcMgr_Free(ProcMgr_AsyncProc *asyncProc);
-#if !defined(N_PLAT_NLM) && !defined(_WIN32)
+#if !defined(_WIN32)
 Bool ProcMgr_ImpersonateUserStart(const char *user,      // UTF-8
                                   AuthToken token);
 Bool ProcMgr_ImpersonateUserStop(void);
index 5588a5bf73bd4fe71fa4b4ab94784b2d26acef7d..ba104f6c6f9e918c31e143f9262b0399012a8b0a 100644 (file)
@@ -95,7 +95,7 @@ DblLnkLst_Links *System_GetMonitors();
  *        then acted upon and translates to a -DPOSIX_LIKE_ENVIRONMENT
  *        preprocessor option.
  */
-#if !defined(_WIN32) && !defined(N_PLAT_NLM)
+#if !defined(_WIN32)
 Bool System_WritePidFile(const char *fileName, pid_t pid);
 const char **System_GetNativeEnviron(const char **compatEnviron);
 void System_FreeNativeEnviron(const char **nativeEnviron);
index a881c916df0a7d6bbf50bb15185733c3d73d5d55..f037df950eacc6d4a8e99147742f83f726d0dbc5 100644 (file)
 /*
  * The current Tools version, derived from vm_tools_version.h. Do not modify this.
  */
-#define TOOLS_VERSION "2009.08.24"
+#define TOOLS_VERSION TOOLS_VERSION_CURRENT_STR
 
 #ifdef VMX86_VPX
 #define VIM_API_TYPE "VirtualCenter"
index b06c2807f533424c5e0a1df0e6031d013e42724c..e7cd712412a22811aa4382f72c6c2e080dd1476d 100644 (file)
@@ -212,5 +212,7 @@ Bool W32Util_ReplaceObjectSD(HANDLE hObject,
 
 HMODULE W32Util_GetModuleByAddress(const void *addr);
 
+Bool Win32Util_VerifyXPModeHostLicense(void);
+
 #endif // _WIN32
 #endif // WIN32UTIL_H_
index 1c2aa4f548883ed162e452d09a738377de27f8b1..02d8f850d8af6e8dc64507141c58410cb88018fe 100644 (file)
@@ -19,6 +19,4 @@ noinst_LTLIBRARIES = libMessage.la
 
 libMessage_la_SOURCES =
 libMessage_la_SOURCES += message.c
-libMessage_la_SOURCES += messageBackdoor.c
-libMessage_la_SOURCES += messageStub.c
 
index 9c678e1999abd76d2ee5b55d300e79e92631c398..195c7182257c49f1d4915b10c845d202b82f0f43 100644 (file)
@@ -68,66 +68,28 @@ extern "C" {
 #include "backdoor.h"
 #include "message.h"
 
-static MessageOpenProcType externalOpenProc = NULL;
-static MessageGetReadEventProcType externalGetReadEventProc = NULL;
-static MessageSendProcType externalSendProc = NULL;
-static MessageReceiveProcType externalReceiveProc = NULL;
-static MessageCloseProcType externalCloseProc = NULL;
-
-/*
- * Currently, the default implementation is to use the backdoor. Soon,
- * this will not be the default, as we will explicitly set it when we
- * decide to use the backdoor.
- */
-EXTERN Message_Channel *MessageBackdoor_Open(uint32 proto);
-
-EXTERN Bool MessageBackdoor_GetReadEvent(Message_Channel *chan,
-                                         int64 *event);
-
-EXTERN Bool MessageBackdoor_Send(Message_Channel *chan,
-                                 const unsigned char *buf,
-                                 size_t bufSize);
-
-EXTERN Bool MessageBackdoor_Receive(Message_Channel *chan,
-                                    unsigned char **buf,
-                                    size_t *bufSize);
-
-EXTERN Bool MessageBackdoor_Close(Message_Channel *chan);
 
+#if defined(MESSAGE_DEBUG)
+#  define MESSAGE_LOG(...)   Warning(__VA_ARGS__)
+#else
+#  define MESSAGE_LOG(...)
+#endif
 
+/* The channel object */
+struct Message_Channel {
+   /* Identifier */
+   uint16 id;
 
-/*
- *-----------------------------------------------------------------------------
- *
- * Message_SetTransport --
- *
- *    This tells the message layer to use an alternate transport
- *    for messages. By default, we use the backdoor, so this function
- *    overrides that default at runtime and switches everything over to
- *    an alternate transport.
- *
- * Result:
- *    None
- *
- * Side-effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
+   /* Reception buffer */
+   /*  Data */
+   unsigned char *in;
+   /*  Allocated size */
+   size_t inAlloc;
 
-void 
-Message_SetTransport(MessageOpenProcType openProc,                   // IN
-                     MessageGetReadEventProcType getReadEeventProc,  // IN
-                     MessageSendProcType sendProc,                   // IN
-                     MessageReceiveProcType receiveProc,             // IN
-                     MessageCloseProcType closeProc)                 // IN
-{
-   externalOpenProc = openProc;
-   externalGetReadEventProc = getReadEeventProc;
-   externalSendProc = sendProc;
-   externalReceiveProc = receiveProc;
-   externalCloseProc = closeProc;
-}
+   /* The cookie */
+   uint32 cookieHigh;
+   uint32 cookieLow;
+};
 
 
 /*
@@ -150,55 +112,52 @@ Message_SetTransport(MessageOpenProcType openProc,                   // IN
 Message_Channel *
 Message_Open(uint32 proto) // IN
 {
-   /*
-    * If there is an alterate backdoor implementation, then call that.
-    */
-   if (NULL != externalOpenProc) {
-      return((*externalOpenProc)(proto));
+   Message_Channel *chan;
+   uint32 flags;
+   Backdoor_proto bp;
+
+   chan = (Message_Channel *)malloc(sizeof(*chan));
+   if (chan == NULL) {
+      goto error_quit;
    }
 
-   /*
-    * Otherwise, we default to the backdoor.
-    */
-   return(MessageBackdoor_Open(proto));
-}
+   flags = GUESTMSG_FLAG_COOKIE;
+retry:
+   /* IN: Type */
+   bp.in.cx.halfs.high = MESSAGE_TYPE_OPEN;
+   /* IN: Magic number of the protocol and flags */
+   bp.in.size = proto | flags;
+
+   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
+   Backdoor(&bp);
+
+   /* OUT: Status */
+   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
+      if (flags) {
+         /* Cookies not supported. Fall back to no cookie. --hpreg */
+         flags = 0;
+         goto retry;
+      }
+
+      MESSAGE_LOG("Message: Unable to open a communication channel\n");
+      goto error_quit;
+   }
 
+   /* OUT: Id and cookie */
+   chan->id = bp.in.dx.halfs.high;
+   chan->cookieHigh = bp.out.si.word;
+   chan->cookieLow = bp.out.di.word;
 
-/*
- *-----------------------------------------------------------------------------
- *
- * Message_GetReadEvent --
- *
- *    This allows higher levels of the IPC stack to use an event to detect
- *    when a message has arrived. This allows an asynchronous, event-based-model 
- *    rather than continually calling Message_Receive in a busy loop. This may 
- *    only be supported by some transports. The backdoor does not, so the IPC
- *    code will still have to poll in those cases.
- *
- * Result:
- *    Bool - whether this feature is supported by this transport.
- *
- * Side-effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
+   /* Initialize the channel */
+   chan->in = NULL;
+   chan->inAlloc = 0;
 
-Bool 
-Message_GetReadEvent(Message_Channel *chan,  // IN
-                     int64 *event)           // OUT
-{
-   /*
-    * If there is an alterate backdoor implementation, then call that.
-    */
-   if (NULL != externalGetReadEventProc) {
-      return((*externalGetReadEventProc)(chan, event));
-   }
+   return chan;
 
-   /*
-    * Otherwise, we default to the backdoor.
-    */
-   return(MessageBackdoor_GetReadEvent(chan, event));
+error_quit:
+   free(chan);
+   chan = NULL;
+   return NULL;
 }
 
 
@@ -224,17 +183,127 @@ Message_Send(Message_Channel *chan,    // IN/OUT
              const unsigned char *buf, // IN
              size_t bufSize)           // IN
 {
+   const unsigned char *myBuf;
+   size_t myBufSize;
+   Backdoor_proto bp;
+
+retry:
+   myBuf = buf;
+   myBufSize = bufSize;
+
    /*
-    * If there is an alterate backdoor implementation, then call that.
+    * Send the size.
     */
-   if (NULL != externalSendProc) {
-      return((*externalSendProc)(chan, buf, bufSize));
+
+   /* IN: Type */
+   bp.in.cx.halfs.high = MESSAGE_TYPE_SENDSIZE;
+   /* IN: Id and cookie */
+   bp.in.dx.halfs.high = chan->id;
+   bp.in.si.word = chan->cookieHigh;
+   bp.in.di.word = chan->cookieLow;
+   /* IN: Size */
+   bp.in.size = myBufSize;
+
+   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
+   Backdoor(&bp);
+
+   /* OUT: Status */
+   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
+      MESSAGE_LOG("Message: Unable to send a message over the communication "
+                  "channel %u\n", chan->id);
+      return FALSE;
    }
 
-   /*
-    * Otherwise, we default to the backdoor.
-    */
-   return(MessageBackdoor_Send(chan, buf, bufSize));
+   if (bp.in.cx.halfs.high & MESSAGE_STATUS_HB) {
+      /*
+       * High-bandwidth backdoor port supported. Send the message in one
+       * backdoor operation. --hpreg
+       */
+
+      if (myBufSize) {
+         Backdoor_proto_hb bphb;
+
+         bphb.in.bx.halfs.low = BDOORHB_CMD_MESSAGE;
+         bphb.in.bx.halfs.high = MESSAGE_STATUS_SUCCESS;
+         bphb.in.dx.halfs.high = chan->id;
+         bphb.in.bp.word = chan->cookieHigh;
+         bphb.in.dstAddr = chan->cookieLow;
+         bphb.in.size = myBufSize;
+         bphb.in.srcAddr = (uintptr_t) myBuf;
+         Backdoor_HbOut(&bphb);
+         if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
+            if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
+               /* A checkpoint occurred. Retry the operation. --hpreg */
+               goto retry;
+            }
+
+            MESSAGE_LOG("Message: Unable to send a message over the "
+                        "communication channel %u\n", chan->id);
+            return FALSE;
+         }
+      }
+   } else {
+      /*
+       * High-bandwidth backdoor port not supported. Send the message, 4 bytes
+       * at a time. --hpreg
+       */
+
+      for (;;) {
+         if (myBufSize == 0) {
+            /* We are done */
+           break;
+         }
+
+         /* IN: Type */
+         bp.in.cx.halfs.high = MESSAGE_TYPE_SENDPAYLOAD;
+         /* IN: Id and cookie */
+         bp.in.dx.halfs.high = chan->id;
+         bp.in.si.word = chan->cookieHigh;
+         bp.in.di.word = chan->cookieLow;
+         /* IN: Piece of message */
+         /*
+          * Beware in case we are not allowed to read extra bytes beyond the
+          * end of the buffer.
+          */
+         switch (myBufSize) {
+         case 1:
+            bp.in.size = myBuf[0];
+            myBufSize -= 1;
+            break;
+         case 2:
+            bp.in.size = myBuf[0] | myBuf[1] << 8;
+            myBufSize -= 2;
+            break;
+         case 3:
+            bp.in.size = myBuf[0] | myBuf[1] << 8 | myBuf[2] << 16;
+            myBufSize -= 3;
+            break;
+         default:
+            bp.in.size = *(const uint32 *)myBuf;
+            myBufSize -= 4;
+            break;
+         }
+
+         bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
+         Backdoor(&bp);
+
+         /* OUT: Status */
+         if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
+            if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
+               /* A checkpoint occurred. Retry the operation. --hpreg */
+               goto retry;
+            }
+
+            MESSAGE_LOG("Message: Unable to send a message over the "
+                        "communication channel %u\n", chan->id);
+            return FALSE;
+         }
+
+         myBuf += 4;
+      }
+   }
+
+   return TRUE;
 }
 
 
@@ -260,17 +329,227 @@ Message_Receive(Message_Channel *chan, // IN/OUT
                 unsigned char **buf,   // OUT
                 size_t *bufSize)       // OUT
 {
+   Backdoor_proto bp;
+   size_t myBufSize;
+   unsigned char *myBuf;
+
+retry:
+   /*
+    * Is there a message waiting for our retrieval?
+    */
+
+   /* IN: Type */
+   bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSIZE;
+   /* IN: Id and cookie */
+   bp.in.dx.halfs.high = chan->id;
+   bp.in.si.word = chan->cookieHigh;
+   bp.in.di.word = chan->cookieLow;
+
+   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
+   Backdoor(&bp);
+
+   /* OUT: Status */
+   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
+      MESSAGE_LOG("Message: Unable to poll for messages over the "
+                  "communication channel %u\n", chan->id);
+      return FALSE;
+   }
+
+   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_DORECV) == 0) {
+      /* No message to retrieve */
+      *bufSize = 0;
+      return TRUE;
+   }
+
    /*
-    * If there is an alterate backdoor implementation, then call that.
+    * Receive the size.
     */
-   if (NULL != externalReceiveProc) {
-      return((*externalReceiveProc)(chan, buf, bufSize));
+
+   /* OUT: Type */
+   if (bp.in.dx.halfs.high != MESSAGE_TYPE_SENDSIZE) {
+      MESSAGE_LOG("Message: Protocol error. Expected a "
+                  "MESSAGE_TYPE_SENDSIZE request from vmware\n");
+      return FALSE;
    }
 
+   /* OUT: Size */
+   myBufSize = bp.out.bx.word;
+
    /*
-    * Otherwise, we default to the backdoor.
+    * Allocate an extra byte for a trailing NUL character. The code that will
+    * deal with this message may not know about binary strings, and may expect
+    * a C string instead. --hpreg
     */
-   return(MessageBackdoor_Receive(chan, buf, bufSize));
+   if (myBufSize + 1 > chan->inAlloc) {
+      myBuf = (unsigned char *)realloc(chan->in, myBufSize + 1);
+      if (myBuf == NULL) {
+         MESSAGE_LOG("Message: Not enough memory to receive a message over "
+                     "the communication channel %u\n", chan->id);
+         goto error_quit;
+      }
+
+      chan->in = myBuf;
+      chan->inAlloc = myBufSize + 1;
+   }
+   *bufSize = myBufSize;
+   myBuf = *buf = chan->in;
+
+   if (bp.in.cx.halfs.high & MESSAGE_STATUS_HB) {
+      /*
+       * High-bandwidth backdoor port supported. Receive the message in one
+       * backdoor operation. --hpreg
+       */
+
+      if (myBufSize) {
+         Backdoor_proto_hb bphb;
+
+         bphb.in.bx.halfs.low = BDOORHB_CMD_MESSAGE;
+         bphb.in.bx.halfs.high = MESSAGE_STATUS_SUCCESS;
+         bphb.in.dx.halfs.high = chan->id;
+         bphb.in.srcAddr = chan->cookieHigh;
+         bphb.in.bp.word = chan->cookieLow;
+         bphb.in.size = myBufSize;
+         bphb.in.dstAddr = (uintptr_t) myBuf;
+         Backdoor_HbIn(&bphb);
+         if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
+            if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
+               /* A checkpoint occurred. Retry the operation. --hpreg */
+               goto retry;
+            }
+
+            MESSAGE_LOG("Message: Unable to receive a message over the "
+                        "communication channel %u\n", chan->id);
+            goto error_quit;
+         }
+      }
+   } else {
+      /*
+       * High-bandwidth backdoor port not supported. Receive the message, 4
+       * bytes at a time. --hpreg
+       */
+
+      for (;;) {
+         if (myBufSize == 0) {
+            /* We are done */
+            break;
+         }
+
+         /* IN: Type */
+         bp.in.cx.halfs.high = MESSAGE_TYPE_RECVPAYLOAD;
+         /* IN: Id and cookie */
+         bp.in.dx.halfs.high = chan->id;
+         bp.in.si.word = chan->cookieHigh;
+         bp.in.di.word = chan->cookieLow;
+         /* IN: Status for the previous request (that succeeded) */
+         bp.in.size = MESSAGE_STATUS_SUCCESS;
+
+         bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
+         Backdoor(&bp);
+
+         /* OUT: Status */
+         if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
+            if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
+               /* A checkpoint occurred. Retry the operation. --hpreg */
+               goto retry;
+            }
+
+            MESSAGE_LOG("Message: Unable to receive a message over the "
+                        "communication channel %u\n", chan->id);
+            goto error_quit;
+         }
+
+         /* OUT: Type */
+         if (bp.in.dx.halfs.high != MESSAGE_TYPE_SENDPAYLOAD) {
+            MESSAGE_LOG("Message: Protocol error. Expected a "
+                        "MESSAGE_TYPE_SENDPAYLOAD from vmware\n");
+            goto error_quit;
+         }
+
+         /* OUT: Piece of message */
+         /*
+          * Beware in case we are not allowed to write extra bytes beyond the
+          * end of the buffer. --hpreg
+          */
+         switch (myBufSize) {
+         case 1:
+            myBuf[0] = bp.out.bx.word & 0xff;
+            myBufSize -= 1;
+            break;
+         case 2:
+            myBuf[0] = bp.out.bx.word & 0xff;
+            myBuf[1] = (bp.out.bx.word >> 8) & 0xff;
+            myBufSize -= 2;
+            break;
+         case 3:
+            myBuf[0] = bp.out.bx.word & 0xff;
+            myBuf[1] = (bp.out.bx.word >> 8) & 0xff;
+            myBuf[2] = (bp.out.bx.word >> 16) & 0xff;
+            myBufSize -= 3;
+            break;
+         default:
+            *(uint32 *)myBuf = bp.out.bx.word;
+            myBufSize -= 4;
+            break;
+         }
+
+         myBuf += 4;
+      }
+   }
+
+   /* Write a trailing NUL just after the message. --hpreg */
+   chan->in[*bufSize] = '\0';
+
+   /* IN: Type */
+   bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSTATUS;
+   /* IN: Id and cookie */
+   bp.in.dx.halfs.high = chan->id;
+   bp.in.si.word = chan->cookieHigh;
+   bp.in.di.word = chan->cookieLow;
+   /* IN: Status for the previous request (that succeeded) */
+   bp.in.size = MESSAGE_STATUS_SUCCESS;
+
+   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
+   Backdoor(&bp);
+
+   /* OUT: Status */
+   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
+      if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
+        /* A checkpoint occurred. Retry the operation. --hpreg */
+        goto retry;
+      }
+
+      MESSAGE_LOG("Message: Unable to receive a message over the "
+                  "communication channel %u\n", chan->id);
+      goto error_quit;
+   }
+
+   return TRUE;
+
+error_quit:
+   /* IN: Type */
+   if (myBufSize == 0) {
+      bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSTATUS;
+   } else {
+      bp.in.cx.halfs.high = MESSAGE_TYPE_RECVPAYLOAD;
+   }
+   /* IN: Id and cookie */
+   bp.in.dx.halfs.high = chan->id;
+   bp.in.si.word = chan->cookieHigh;
+   bp.in.di.word = chan->cookieLow;
+   /* IN: Status for the previous request (that failed) */
+   bp.in.size = 0;
+
+   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
+   Backdoor(&bp);
+
+   /* OUT: Status */
+   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
+      MESSAGE_LOG("Message: Unable to signal an error of reception over the "
+                  "communication channel %u\n", chan->id);
+      return FALSE;
+   }
+
+   return FALSE;
 }
 
 
@@ -294,17 +573,31 @@ Message_Receive(Message_Channel *chan, // IN/OUT
 Bool
 Message_Close(Message_Channel *chan) // IN/OUT
 {
-   /*
-    * If there is an alterate backdoor implementation, then call that.
-    */
-   if (NULL != externalCloseProc) {
-      return((*externalCloseProc)(chan));
+   Backdoor_proto bp;
+   Bool ret = TRUE;
+
+   /* IN: Type */
+   bp.in.cx.halfs.high = MESSAGE_TYPE_CLOSE;
+   /* IN: Id and cookie */
+   bp.in.dx.halfs.high = chan->id;
+   bp.in.si.word = chan->cookieHigh;
+   bp.in.di.word = chan->cookieLow;
+
+   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
+   Backdoor(&bp);
+
+   /* OUT: Status */
+   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
+      MESSAGE_LOG("Message: Unable to close the communication channel %u\n",
+                  chan->id);
+      ret = FALSE;
    }
 
-   /*
-    * Otherwise, we default to the backdoor.
-    */
-   return(MessageBackdoor_Close(chan));
+   free(chan->in);
+   chan->in = NULL;
+
+   free(chan);
+   return ret;
 }
 
 #ifdef __cplusplus
diff --git a/open-vm-tools/lib/message/messageBackdoor.c b/open-vm-tools/lib/message/messageBackdoor.c
deleted file mode 100644 (file)
index bf19e17..0000000
+++ /dev/null
@@ -1,642 +0,0 @@
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/*********************************************************
- * The contents of this file are subject to the terms of the Common
- * Development and Distribution License (the "License") version 1.0
- * and no later version.  You may not use this file except in
- * compliance with the License.
- *
- * You can obtain a copy of the License at
- *         http://www.opensource.org/licenses/cddl1.php
- *
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- *********************************************************/
-
-/*
- * messageBackdoor.c --
- *
- *    Second layer of the internal communication channel between guest
- *    applications and vmware
- *
- *    Build a generic messaging system between guest applications and vmware.
- *
- *    The protocol is not completely symmetrical, because:
- *     . basic requests can only be sent by guest applications (when vmware
- *       wants to post a message to a guest application, the message will be
- *       really fetched only when the guest application will poll for new
- *       available messages)
- *     . several guest applications can talk to vmware, while the contrary is
- *       not true
- *
- *    Operations that are not atomic (in terms of number of backdoor calls)
- *    can be aborted by vmware if a checkpoint/restore occurs in the middle of
- *    such an operation. This layer takes care of retrying those operations.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#if defined(__KERNEL__) || defined(_KERNEL) || defined(KERNEL)
-#   include "kernelStubs.h"
-#else
-#   include <stdio.h>
-#   include <stdlib.h>
-#   include "debug.h"
-#endif
-
-#ifdef MESSAGE_DEBUG
-#   define MESSAGE_LOG(args) Debug args
-#else /* MESSAGE_DEBUG */
-#   define MESSAGE_LOG(args)
-#endif /* MESSAGE_DEBUG */
-
-
-#include "backdoor_def.h"
-#include "guest_msg_def.h"
-#include "backdoor.h"
-#include "message.h"
-
-
-/* The channel object */
-struct Message_Channel {
-   /* Identifier */
-   uint16 id;
-
-   /* Reception buffer */
-   /*  Data */
-   unsigned char *in;
-   /*  Allocated size */
-   size_t inAlloc;
-
-   /* The cookie */
-   uint32 cookieHigh;
-   uint32 cookieLow;
-};
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * MessageBackdoor_Open --
- *
- *    Open a communication channel
- *
- * Result:
- *    An allocated Message_Channel on success
- *    NULL on failure
- *
- * Side-effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-
-Message_Channel *
-MessageBackdoor_Open(uint32 proto) // IN
-{
-   Message_Channel *chan;
-   uint32 flags;
-   Backdoor_proto bp;
-
-   chan = (Message_Channel *)malloc(sizeof(*chan));
-   if (chan == NULL) {
-      MESSAGE_LOG(("Message: Not enough memory\n"));
-      goto error_quit;
-   }
-
-   flags = GUESTMSG_FLAG_COOKIE;
-retry:
-   /* IN: Type */
-   bp.in.cx.halfs.high = MESSAGE_TYPE_OPEN;
-   /* IN: Magic number of the protocol and flags */
-   bp.in.size = proto | flags;
-
-   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
-   Backdoor(&bp);
-
-   /* OUT: Status */
-   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
-      if (flags) {
-         /* Cookies not supported. Fall back to no cookie. --hpreg */
-         flags = 0;
-         goto retry;
-      }
-
-      MESSAGE_LOG(("Message: Unable to open a communication channel\n"));
-      goto error_quit;
-   }
-
-   /* OUT: Id and cookie */
-   chan->id = bp.in.dx.halfs.high;
-   chan->cookieHigh = bp.out.si.word;
-   chan->cookieLow = bp.out.di.word;
-
-   /* Initialize the channel */
-   chan->in = NULL;
-   chan->inAlloc = 0;
-
-   MESSAGE_LOG(("Message: Communication channel %u opened\n", chan->id));
-   return chan;
-
-error_quit:
-   free(chan);
-   chan = NULL;
-   return NULL;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * MessageBackdoor_GetReadEvent --
- *
- *    This allows higher levels of the IPC stack to use an event to detect
- *    when a message has arrived. This allows an interrupt-model rather than
- *    continually calling Message_Receive in a busy loop. This may only be supported
- *    by some transports. The backdoor does not, so the IPC code will still
- *    have to poll in those cases.
- *
- * Result:
- *    Bool - whether this feature is supported by this transport.
- *
- * Side-effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool 
-MessageBackdoor_GetReadEvent(Message_Channel *chan,  // IN
-                             int64 *event)           // OUT
-{
-   return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * MessageBackdoor_Send --
- *
- *    Send a message over a communication channel
- *
- * Result:
- *    TRUE on success
- *    FALSE on failure (the message is discarded by vmware)
- *
- * Side-effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-MessageBackdoor_Send(Message_Channel *chan,    // IN/OUT
-                     const unsigned char *buf, // IN
-                     size_t bufSize)           // IN
-{
-   const unsigned char *myBuf;
-   size_t myBufSize;
-   Backdoor_proto bp;
-
-retry:
-   myBuf = buf;
-   myBufSize = bufSize;
-
-   /*
-    * Send the size.
-    */
-
-   /* IN: Type */
-   bp.in.cx.halfs.high = MESSAGE_TYPE_SENDSIZE;
-   /* IN: Id and cookie */
-   bp.in.dx.halfs.high = chan->id;
-   bp.in.si.word = chan->cookieHigh;
-   bp.in.di.word = chan->cookieLow;
-   /* IN: Size */
-   bp.in.size = myBufSize;
-
-   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
-   Backdoor(&bp);
-
-   /* OUT: Status */
-   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
-      MESSAGE_LOG(("Message: Unable to send a message over the communication "
-                   "channel %u\n", chan->id));
-      return FALSE;
-   }
-
-   if (bp.in.cx.halfs.high & MESSAGE_STATUS_HB) {
-      /*
-       * High-bandwidth backdoor port supported. Send the message in one
-       * backdoor operation. --hpreg
-       */
-
-      if (myBufSize) {
-         Backdoor_proto_hb bphb;
-
-         bphb.in.bx.halfs.low = BDOORHB_CMD_MESSAGE;
-         bphb.in.bx.halfs.high = MESSAGE_STATUS_SUCCESS;
-         bphb.in.dx.halfs.high = chan->id;
-         bphb.in.bp.word = chan->cookieHigh;
-         bphb.in.dstAddr = chan->cookieLow;
-         bphb.in.size = myBufSize;
-         bphb.in.srcAddr = (uintptr_t) myBuf;
-         Backdoor_HbOut(&bphb);
-         if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
-            if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
-               /* A checkpoint occurred. Retry the operation. --hpreg */
-               goto retry;
-            }
-
-            MESSAGE_LOG(("Message: Unable to send a message over the "
-                         "communication channel %u\n", chan->id));
-            return FALSE;
-         }
-      }
-   } else {
-      /*
-       * High-bandwidth backdoor port not supported. Send the message, 4 bytes
-       * at a time. --hpreg
-       */
-
-      for (;;) {
-         if (myBufSize == 0) {
-            /* We are done */
-           break;
-         }
-
-         /* IN: Type */
-         bp.in.cx.halfs.high = MESSAGE_TYPE_SENDPAYLOAD;
-         /* IN: Id and cookie */
-         bp.in.dx.halfs.high = chan->id;
-         bp.in.si.word = chan->cookieHigh;
-         bp.in.di.word = chan->cookieLow;
-         /* IN: Piece of message */
-         /*
-          * Beware in case we are not allowed to read extra bytes beyond the
-          * end of the buffer.
-          */
-         switch (myBufSize) {
-         case 1:
-            bp.in.size = myBuf[0];
-            myBufSize -= 1;
-            break;
-         case 2:
-            bp.in.size = myBuf[0] | myBuf[1] << 8;
-            myBufSize -= 2;
-            break;
-         case 3:
-            bp.in.size = myBuf[0] | myBuf[1] << 8 | myBuf[2] << 16;
-            myBufSize -= 3;
-            break;
-         default:
-            bp.in.size = *(const uint32 *)myBuf;
-            myBufSize -= 4;
-            break;
-         }
-
-         bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
-         Backdoor(&bp);
-
-         /* OUT: Status */
-         if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
-            if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
-               /* A checkpoint occurred. Retry the operation. --hpreg */
-               goto retry;
-            }
-
-            MESSAGE_LOG(("Message: Unable to send a message over the "
-                         "communication channel %u\n", chan->id));
-            return FALSE;
-         }
-
-         myBuf += 4;
-      }
-   }
-
-   MESSAGE_LOG(("Message: Sent a message over the communication channel %u\n",
-                chan->id));
-
-   return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * MessageBackdoor_Receive --
- *
- *    If vmware has posted a message for this channel, retrieve it
- *
- * Result:
- *    TRUE on success (bufSize is 0 if there is no message)
- *    FALSE on failure
- *
- * Side-effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-MessageBackdoor_Receive(Message_Channel *chan, // IN/OUT
-                        unsigned char **buf,   // OUT
-                        size_t *bufSize)       // OUT
-{
-   Backdoor_proto bp;
-   size_t myBufSize;
-   unsigned char *myBuf;
-
-retry:
-   /*
-    * Is there a message waiting for our retrieval?
-    */
-
-   /* IN: Type */
-   bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSIZE;
-   /* IN: Id and cookie */
-   bp.in.dx.halfs.high = chan->id;
-   bp.in.si.word = chan->cookieHigh;
-   bp.in.di.word = chan->cookieLow;
-
-   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
-   Backdoor(&bp);
-
-   /* OUT: Status */
-   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
-      MESSAGE_LOG(("Message: Unable to poll for messages over the "
-                   "communication channel %u\n", chan->id));
-      return FALSE;
-   }
-
-   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_DORECV) == 0) {
-      /* No message to retrieve */
-      *bufSize = 0;
-      return TRUE;
-   }
-
-   /*
-    * Receive the size.
-    */
-
-   /* OUT: Type */
-   if (bp.in.dx.halfs.high != MESSAGE_TYPE_SENDSIZE) {
-      MESSAGE_LOG(("Message: Protocol error. Expected a "
-                   "MESSAGE_TYPE_SENDSIZE request from vmware\n"));
-      return FALSE;
-   }
-
-   /* OUT: Size */
-   myBufSize = bp.out.bx.word;
-
-   /*
-    * Allocate an extra byte for a trailing NUL character. The code that will
-    * deal with this message may not know about binary strings, and may expect
-    * a C string instead. --hpreg
-    */
-   if (myBufSize + 1 > chan->inAlloc) {
-      myBuf = (unsigned char *)realloc(chan->in, myBufSize + 1);
-      if (myBuf == NULL) {
-        MESSAGE_LOG(("Message: Not enough memory to receive a message over "
-                      "the communication channel %u\n", chan->id));
-        goto error_quit;
-      }
-
-      chan->in = myBuf;
-      chan->inAlloc = myBufSize + 1;
-   }
-   *bufSize = myBufSize;
-   myBuf = *buf = chan->in;
-
-   if (bp.in.cx.halfs.high & MESSAGE_STATUS_HB) {
-      /*
-       * High-bandwidth backdoor port supported. Receive the message in one
-       * backdoor operation. --hpreg
-       */
-
-      if (myBufSize) {
-         Backdoor_proto_hb bphb;
-
-         bphb.in.bx.halfs.low = BDOORHB_CMD_MESSAGE;
-         bphb.in.bx.halfs.high = MESSAGE_STATUS_SUCCESS;
-         bphb.in.dx.halfs.high = chan->id;
-         bphb.in.srcAddr = chan->cookieHigh;
-         bphb.in.bp.word = chan->cookieLow;
-         bphb.in.size = myBufSize;
-         bphb.in.dstAddr = (uintptr_t) myBuf;
-         Backdoor_HbIn(&bphb);
-         if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
-            if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
-               /* A checkpoint occurred. Retry the operation. --hpreg */
-               goto retry;
-            }
-
-            MESSAGE_LOG(("Message: Unable to receive a message over the "
-                         "communication channel %u\n", chan->id));
-            goto error_quit;
-         }
-      }
-   } else {
-      /*
-       * High-bandwidth backdoor port not supported. Receive the message, 4
-       * bytes at a time. --hpreg
-       */
-
-      for (;;) {
-         if (myBufSize == 0) {
-            /* We are done */
-            break;
-         }
-
-         /* IN: Type */
-         bp.in.cx.halfs.high = MESSAGE_TYPE_RECVPAYLOAD;
-         /* IN: Id and cookie */
-         bp.in.dx.halfs.high = chan->id;
-         bp.in.si.word = chan->cookieHigh;
-         bp.in.di.word = chan->cookieLow;
-         /* IN: Status for the previous request (that succeeded) */
-         bp.in.size = MESSAGE_STATUS_SUCCESS;
-
-         bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
-         Backdoor(&bp);
-
-         /* OUT: Status */
-         if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
-            if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
-               /* A checkpoint occurred. Retry the operation. --hpreg */
-               goto retry;
-            }
-
-            MESSAGE_LOG(("Message: Unable to receive a message over the "
-                         "communication channel %u\n", chan->id));
-            goto error_quit;
-         }
-
-         /* OUT: Type */
-         if (bp.in.dx.halfs.high != MESSAGE_TYPE_SENDPAYLOAD) {
-            MESSAGE_LOG(("Message: Protocol error. Expected a "
-                         "MESSAGE_TYPE_SENDPAYLOAD from vmware\n"));
-            goto error_quit;
-         }
-
-         /* OUT: Piece of message */
-         /*
-          * Beware in case we are not allowed to write extra bytes beyond the
-          * end of the buffer. --hpreg
-          */
-         switch (myBufSize) {
-         case 1:
-            myBuf[0] = bp.out.bx.word & 0xff;
-            myBufSize -= 1;
-            break;
-         case 2:
-            myBuf[0] = bp.out.bx.word & 0xff;
-            myBuf[1] = (bp.out.bx.word >> 8) & 0xff;
-            myBufSize -= 2;
-            break;
-         case 3:
-            myBuf[0] = bp.out.bx.word & 0xff;
-            myBuf[1] = (bp.out.bx.word >> 8) & 0xff;
-            myBuf[2] = (bp.out.bx.word >> 16) & 0xff;
-            myBufSize -= 3;
-            break;
-         default:
-            *(uint32 *)myBuf = bp.out.bx.word;
-            myBufSize -= 4;
-            break;
-         }
-
-         myBuf += 4;
-      }
-   }
-
-   /* Write a trailing NUL just after the message. --hpreg */
-   chan->in[*bufSize] = '\0';
-
-   /* IN: Type */
-   bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSTATUS;
-   /* IN: Id and cookie */
-   bp.in.dx.halfs.high = chan->id;
-   bp.in.si.word = chan->cookieHigh;
-   bp.in.di.word = chan->cookieLow;
-   /* IN: Status for the previous request (that succeeded) */
-   bp.in.size = MESSAGE_STATUS_SUCCESS;
-
-   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
-   Backdoor(&bp);
-
-   /* OUT: Status */
-   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
-      if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
-        /* A checkpoint occurred. Retry the operation. --hpreg */
-        goto retry;
-      }
-
-      MESSAGE_LOG(("Message: Unable to receive a message over the "
-                   "communication channel %u\n", chan->id));
-      goto error_quit;
-   }
-
-   return TRUE;
-
-error_quit:
-   /* IN: Type */
-   if (myBufSize == 0) {
-      bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSTATUS;
-   } else {
-      bp.in.cx.halfs.high = MESSAGE_TYPE_RECVPAYLOAD;
-   }
-   /* IN: Id and cookie */
-   bp.in.dx.halfs.high = chan->id;
-   bp.in.si.word = chan->cookieHigh;
-   bp.in.di.word = chan->cookieLow;
-   /* IN: Status for the previous request (that failed) */
-   bp.in.size = 0;
-
-   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
-   Backdoor(&bp);
-
-   /* OUT: Status */
-   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
-      MESSAGE_LOG(("Message: Unable to signal an error of reception over the "
-                   "communication channel %u\n", chan->id));
-      return FALSE;
-   }
-
-   return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * MessageBackdoor_Close --
- *
- *    Close a communication channel
- *
- * Result:
- *    TRUE on success, the channel is destroyed
- *    FALSE on failure
- *
- * Side-effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-MessageBackdoor_Close(Message_Channel *chan) // IN/OUT
-{
-   Backdoor_proto bp;
-   Bool ret = TRUE;
-
-   /* IN: Type */
-   bp.in.cx.halfs.high = MESSAGE_TYPE_CLOSE;
-   /* IN: Id and cookie */
-   bp.in.dx.halfs.high = chan->id;
-   bp.in.si.word = chan->cookieHigh;
-   bp.in.di.word = chan->cookieLow;
-
-   bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
-   Backdoor(&bp);
-
-   /* OUT: Status */
-   if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
-      MESSAGE_LOG(("Message: Unable to close the communication channel %u\n",
-                  chan->id));
-      ret = FALSE;
-   } else {
-      MESSAGE_LOG(("Message: Communication channel %u closed\n", chan->id));
-   }
-
-   free(chan->in);
-   chan->in = NULL;
-
-   free(chan);
-   return ret;
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/open-vm-tools/lib/message/messageStub.c b/open-vm-tools/lib/message/messageStub.c
deleted file mode 100644 (file)
index 021d3f4..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/*********************************************************
- * The contents of this file are subject to the terms of the Common
- * Development and Distribution License (the "License") version 1.0
- * and no later version.  You may not use this file except in
- * compliance with the License.
- *
- * You can obtain a copy of the License at
- *         http://www.opensource.org/licenses/cddl1.php
- *
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- *********************************************************/
-
-/*
- * MessageStub.c --
- *
- * Implement the message interface that does nothing.
- *
- */
-
-#if defined(__KERNEL__) || defined(_KERNEL) || defined(KERNEL)
-#   include "kernelStubs.h"
-#else
-#   include <stdio.h>
-#   include <stdlib.h>
-#   include "debug.h"
-#endif
-
-#include "backdoor_def.h"
-#include "guest_msg_def.h"
-#include "backdoor.h"
-#include "message.h"
-
-
-static Message_Channel *MessageStub_Open(uint32 proto);
-
-static Bool MessageStub_Close(Message_Channel *chan);
-
-static Bool MessageStub_Receive(Message_Channel *chan,
-                                  unsigned char **buf,
-                                  size_t *bufSize);
-
-static Bool MessageStub_Send(Message_Channel *chan,
-                               const unsigned char *buf,
-                               size_t  bufSize);
-
-static Bool MessageStub_GetReadEvent(Message_Channel *chan,
-                                       int64 *readEvent);
-
-
-static int globalStubChannel = 0;
-
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * MessageStub_RegisterTransport --
- *
- *
- * Results:
- *      Bool
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-MessageStub_RegisterTransport(void)
-{
-   Message_SetTransport(MessageStub_Open,
-                        MessageStub_GetReadEvent,
-                        MessageStub_Send,
-                        MessageStub_Receive,
-                        MessageStub_Close);
-} // MessageStub_RegisterTransport
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * MessageStub_Open --
- *
- *      Open a new channel, which can receive new socket connections.
- *
- * Results:
- *      Bool
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Message_Channel *
-MessageStub_Open(uint32 proto) // IN
-{
-   return((Message_Channel *) &globalStubChannel);
-} // MessageStub_Open
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * MessageStub_Close --
- *
- *      Close the channel and all socket connections.
- *
- * Results:
- *      Bool
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-MessageStub_Close(Message_Channel *chan)  // IN
-{
-   return(TRUE);
-} // MessageStub_Close
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * MessageStub_GetReadEvent --
- * *
- * Results:
- *      Bool
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-MessageStub_GetReadEvent(Message_Channel *chan,       // IN
-                         int64 *readEvent)            // OUT
-{
-   return(FALSE);
-} // MessageStub_GetReadEvent
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * MessageStub_Receive --
- *
- * Results:
- *      Bool.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-MessageStub_Receive(Message_Channel *chan,     // IN
-                    unsigned char **buf,       // IN
-                    size_t *bufSize)           // IN
-{
-   if (NULL != buf) {
-      *buf = NULL;
-   }
-   if (NULL != bufSize) {
-      *bufSize = 0;
-   }
-
-   return(TRUE);
-} // MessageStub_Receive
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * MessageStub_Send --
- *
- * Results:
- *      Bool.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-MessageStub_Send(Message_Channel *chan,     // IN
-                 const unsigned char *buf,  // IN
-                 size_t  bufSize)           // IN
-{
-   return(TRUE);
-} // MessageStub_Send
-
index 57c7e8439008e324209f1f26579c4f480d4acf89..be8f19dc349a034636c3f9a9e2373907f6c8df88 100644 (file)
@@ -339,6 +339,38 @@ DynBuf_Append(DynBuf *b,        // IN
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * DynBuf_SafeInternalAppend --
+ *
+ *      Append data at the end of a dynamic buffer. Memory allocation failure
+ *      are handled the same way as Util_SafeMalloc, that is to say, with a
+ *      Panic.
+ *
+ * Results:
+ *      None
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+DynBuf_SafeInternalAppend(DynBuf *b,            // IN
+                          void const *data,     // IN
+                          size_t size,          // IN
+                          char const *file,     // IN
+                          unsigned int lineno)  // IN
+{
+   if (!DynBuf_Append(b, data, size)) {
+      Panic("Unrecoverable memory allocation failure at %s:%u\n",
+            file, lineno);
+   }
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
index 174ab59156588eb04014e2551ddbc7d682918ca0..9b8827c79f9660e4fa9191c24730f713b68b90ce 100644 (file)
@@ -818,8 +818,6 @@ VixTools_GetToolsPropertiesImpl(GuestApp_Dict **confDictRef,      // IN
 
 #ifdef _WIN32
    osFamily = GUEST_OS_FAMILY_WINDOWS;
-#elif defined(N_PLAT_NLM)
-   osFamily = GUEST_OS_FAMILY_NETWARE;
 #else
    osFamily = GUEST_OS_FAMILY_LINUX;
 #endif
@@ -3251,7 +3249,7 @@ VixToolsProcessHgfsPacket(VixCommandHgfsSendPacket *requestMsg,   // IN
    hgfsPacket = ((char *) requestMsg) + sizeof(*requestMsg);
    hgfsPacketSize = requestMsg->hgfsPacketSize;
 
-#if !defined(N_PLAT_NLM) && !defined(__FreeBSD__)
+#if !defined(__FreeBSD__)
    /*
     * Impersonation was okay, so let's give our packet to
     * the HGFS server and forward the reply packet back.
index 2b61e4415b1313ff14622cbd57eb0863911d0e2a..ade41b3b4c6fe603ac9324d6fad34c7d7caf82a1 100644 (file)
@@ -36,13 +36,13 @@ extern "C" {
 #include "backdoor_def.h"
 #include "debug.h"
 
-#if !defined(_WIN32) && !defined(N_PLAT_NLM)
+#if !defined(_WIN32)
 #   include "vmsignal.h"
 #   include "setjmp.h"
 #endif
 
 
-#if !defined(_WIN32) && !defined(N_PLAT_NLM)
+#if !defined(_WIN32)
 static sigjmp_buf jmpBuf;
 static Bool       jmpIsSet;
 
@@ -167,15 +167,7 @@ VmCheck_IsVirtualWorld(void)
 {
    uint32 version;
    uint32 dummy;
-#ifdef N_PLAT_NLM
-   /*
-    * We are running at CPL0. So we'll not receive SIGSEGV on access
-    * and we must do it other way... --petr
-    */
-   if (!VmCheck_GetVersion(&version, &dummy)) {
-      return FALSE;
-   }
-#elif defined _WIN32
+#if defined _WIN32
    __try {
       VmCheck_GetVersion(&version, &dummy);
    } __except (GetExceptionCode() == STATUS_PRIVILEGED_INSTRUCTION) {
index b88f169ac1961026512eba85f8ec91de36c602af..28fe3f0c3bb3f153cde1daca8ba3316200dc5c2f 100644 (file)
@@ -39,7 +39,6 @@ COMMON_SRCS += hgfsEscape.c
 COMMON_SRCS += hgfsBd.c
 COMMON_SRCS += rpcout.c
 COMMON_SRCS += message.c
-COMMON_SRCS += messageBackdoor.c
 COMMON_SRCS += backdoor.c
 .if $(MACHINE_ARCH) == "amd64"
 COMMON_SRCS += backdoorGcc64.c
index 01452142d0a163e04b6598f26935d84ed3bb7b93..2d3385891bd39db06713dc15fa89b1594a5ae184 100644 (file)
 /* use config value for max balloon size */
 #define BALLOON_MAX_SIZE_USE_CONFIG     (0)
 
-/* guest identities */
-#define BALLOON_GUEST_UNKNOWN           (0)
-#define BALLOON_GUEST_LINUX             (1)
-#define BALLOON_GUEST_BSD               (2)
-#define BALLOON_GUEST_WINDOWS_NT4       (3)
-#define BALLOON_GUEST_WINDOWS_NT5       (4)
-#define BALLOON_GUEST_SOLARIS           (5)
+/*
+ * Guest identities
+ *
+ *      Note : all values should fit in 32 bits
+ */
+typedef enum {
+   BALLOON_GUEST_UNKNOWN     = 0,
+   BALLOON_GUEST_LINUX       = 1,
+   BALLOON_GUEST_BSD         = 2,
+   BALLOON_GUEST_WINDOWS_NT4 = 3,
+   BALLOON_GUEST_WINDOWS_NT5 = 4,
+   BALLOON_GUEST_SOLARIS     = 5,
+   BALLOON_GUEST_MACOS       = 6,
+} BalloonGuest;
 
 /* error codes */
 #define BALLOON_SUCCESS                 (0)
index b99761d87d0171ab2d7e40cdd5a912efd4f865b2..33776842907c9fea3752edfe4ee0f9740e7b57e6 100644 (file)
@@ -54,6 +54,7 @@
 #include <machine/stdarg.h>
 
 #include "os.h"
+#include "vmballoon.h"
 
 /*
  * Constants
@@ -128,7 +129,7 @@ static void vmmemctl_deinit_sysctl(void);
 void *
 OS_Malloc(size_t size) // IN
 {
-   return(malloc(size, M_VMMEMCTL, M_NOWAIT));
+   return malloc(size, M_VMMEMCTL, M_NOWAIT);
 }
 
 
@@ -252,33 +253,77 @@ OS_Snprintf(char *buf,          // OUT
    return result;
 }
 
+
 /*
- * System-Dependent Operations
+ *-----------------------------------------------------------------------------
+ *
+ * OS_Identity --
+ *
+ *      Returns an identifier for the guest OS family.
+ *
+ * Results:
+ *      The identifier
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
  */
 
-const char *
+BalloonGuest
 OS_Identity(void)
 {
-   return("bsd");
+   return BALLOON_GUEST_BSD;
 }
 
+
 /*
- * Predict the maximum achievable balloon size.
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageGetLimit --
  *
- * Currently we just return the total memory pages.
+ *      Predict the maximum achievable balloon size.
+ *
+ * Results:
+ *      Total memory pages.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
  */
-unsigned int
-OS_PredictMaxReservedPages(void)
+
+unsigned long
+OS_ReservedPageGetLimit(void)
 {
-   return(cnt.v_page_count);
+   return cnt.v_page_count;
 }
 
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageGetPPN --
+ *
+ *      Convert a page handle (of a physical page previously reserved with
+ *      OS_ReservedPageAlloc()) to a ppn.
+ *
+ * Results:
+ *      The ppn.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
 unsigned long
-OS_AddrToPPN(unsigned long addr)
+OS_ReservedPageGetPPN(PageHandle handle) // IN: A valid page handle
 {
-   return (((vm_page_t)addr)->phys_addr) >> PAGE_SHIFT;
+   return (((vm_page_t)handle)->phys_addr) >> PAGE_SHIFT;
 }
 
+
 static void os_pmap_alloc(os_pmap *p)
 {
    /* number of pages (div. 8) */
@@ -412,18 +457,62 @@ static void os_balloonobject_create(void)
                   OFF_TO_IDX(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS));
 }
 
-unsigned long
-OS_AllocReservedPage(int canSleep)
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageAlloc --
+ *
+ *      Reserve a physical page for the exclusive use of this driver.
+ *
+ * Results:
+ *      On success: A valid page handle that can be passed to OS_ReservedPageGetPPN()
+ *                  or OS_ReservedPageFree().
+ *      On failure: PAGE_HANDLE_INVALID
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+PageHandle
+OS_ReservedPageAlloc(int canSleep) // IN
 {
-   return (unsigned long)os_kmem_alloc(canSleep);
+   vm_page_t page;
+
+   page = os_kmem_alloc(canSleep);
+   if (page == NULL) {
+      return PAGE_HANDLE_INVALID;
+   }
+
+   return (PageHandle)page;
 }
 
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageFree --
+ *
+ *      Unreserve a physical page previously reserved with OS_ReservedPageAlloc().
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
 void
-OS_FreeReservedPage(unsigned long page)
+OS_ReservedPageFree(PageHandle handle) // IN: A valid page handle
 {
-   os_kmem_free((vm_page_t)page);
+   os_kmem_free((vm_page_t)handle);
 }
 
+
 static void os_timer_internal(void *data)
 {
    os_timer *t = (os_timer *) data;
@@ -435,32 +524,61 @@ static void os_timer_internal(void *data)
    }
 }
 
-void
-OS_TimerInit(OSTimerHandler *handler, // IN
-             void *clientData,        // IN
-             int period)              // IN
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_TimerStart --
+ *
+ *      Setup the timer callback function, then start it.
+ *
+ * Results:
+ *      Always TRUE, cannot fail.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+OS_TimerStart(OSTimerHandler *handler, // IN
+              void *clientData)        // IN
 {
    os_timer *t = &global_state.timer;
 
+   /* setup the timer structure */
    callout_handle_init(&t->callout_handle);
    t->handler = handler;
    t->data = clientData;
-   t->period = period;
-   t->stop = 0;
-}
-
-void
-OS_TimerStart(void)
-{
-   os_timer *t = &global_state.timer;
+   t->period = hz;
 
    /* clear termination flag */
    t->stop = 0;
 
    /* scheduler timer handler */
    t->callout_handle = timeout(os_timer_internal, t, t->period);
+
+   return TRUE;
 }
 
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_TimerStop --
+ *
+ *      Stop the timer.
+ *
+ * Results:
+ *      None
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
 void
 OS_TimerStop(void)
 {
@@ -473,12 +591,6 @@ OS_TimerStop(void)
    untimeout(os_timer_internal, t, t->callout_handle);
 }
 
-unsigned int
-OS_TimerHz(void)
-{
-   return hz;
-}
-
 
 /*
  *-----------------------------------------------------------------------------
@@ -556,16 +668,15 @@ OS_Cleanup(void)
  * Module Load/Unload Operations
  */
 
-extern int  init_module(void);
-extern void cleanup_module(void);
-
 static int vmmemctl_load(module_t mod, int cmd, void *arg)
 {
    int err = 0;
 
    switch (cmd) {
    case MOD_LOAD:
-      (void) init_module();
+      if (Balloon_ModuleInit() != BALLOON_SUCCESS) {
+         err = EAGAIN;
+      }
       break;
 
     case MOD_UNLOAD:
@@ -573,7 +684,7 @@ static int vmmemctl_load(module_t mod, int cmd, void *arg)
           /* prevent moudle unload */
           err = EBUSY;
        } else {
-          cleanup_module();
+          Balloon_ModuleCleanup();
        }
        break;
 
@@ -582,7 +693,7 @@ static int vmmemctl_load(module_t mod, int cmd, void *arg)
       break;
    }
 
-   return(err);
+   return err;
 }
 
 /* All these interfaces got added in 4.x, so we support 5.0 and above with them */
index b991edd7162768ce2ea1ed068a3fae4b46fc7054..ffbb93c1088311575ff4b409435c8368fe7fbc8a 100644 (file)
 #ifndef        OS_H
 #define        OS_H
 
+#include "vm_basic_types.h"
+#include "balloon_def.h"
+
 /*
  * Types
  */
 
 typedef void OSTimerHandler(void *clientData);
 typedef int  OSStatusHandler(char *buf, size_t size);
+typedef uintptr_t PageHandle;
+
+#define PAGE_HANDLE_INVALID 0
 
 /*
  * Operations
@@ -40,7 +46,7 @@ extern void OS_Init(const char *name,
                     const char *nameVerbose,
                     OSStatusHandler *handler);
 extern void OS_Cleanup(void);
-extern const char *OS_Identity(void);
+extern BalloonGuest OS_Identity(void);
 
 extern void OS_MemZero(void *ptr, size_t size);
 extern void OS_MemCopy(void *dest, const void *src, size_t size);
@@ -51,14 +57,12 @@ extern void OS_Free(void *ptr, size_t size);
 
 extern void OS_Yield(void);
 
-extern unsigned int OS_TimerHz(void);
-extern void OS_TimerInit(OSTimerHandler *handler, void *clientData, int period);
-extern void OS_TimerStart(void);
+extern Bool OS_TimerStart(OSTimerHandler *handler, void *clientData);
 extern void OS_TimerStop(void);
 
-extern unsigned int  OS_PredictMaxReservedPages(void);
-extern unsigned long OS_AddrToPPN(unsigned long addr);
-extern unsigned long OS_AllocReservedPage(int canSleep);
-extern void          OS_FreeReservedPage(unsigned long page);
+extern unsigned long OS_ReservedPageGetLimit(void);
+extern unsigned long OS_ReservedPageGetPPN(PageHandle handle);
+extern PageHandle    OS_ReservedPageAlloc(int canSleep);
+extern void          OS_ReservedPageFree(PageHandle handle);
 
 #endif  /* OS_H */
index 91212ec8fa036ccb365a6f85b8e463be8a9da713..283e791a527dd263ab597df995321442fffec057 100644 (file)
@@ -50,7 +50,6 @@ extern "C" {
  * Includes
  */
 
-#include "balloon_def.h"
 #include "os.h"
 #include "backdoor.h"
 #include "backdoor_balloon.h"
@@ -107,13 +106,14 @@ extern "C" {
  */
 
 typedef struct BalloonChunk {
-   unsigned long page[BALLOON_CHUNK_PAGES];
+   PageHandle page[BALLOON_CHUNK_PAGES];
    uint32 nextPage;
-   struct BalloonChunk *prev, *next;
+   struct BalloonChunk *prev;
+   struct BalloonChunk *next;
 } BalloonChunk;
 
 typedef struct {
-   unsigned long page[BALLOON_ERROR_PAGES];
+   PageHandle page[BALLOON_ERROR_PAGES];
    uint32 nextPage;
 } BalloonErrorPages;
 
@@ -148,30 +148,24 @@ typedef struct {
  */
 
 static Balloon globalBalloon;
+static Bool timerStarted;
 
 /*
  * Forward Declarations
  */
 
-static int BalloonGuestType(void);
-
-static unsigned long BalloonPrimAllocPage(BalloonPageAllocType canSleep);
-static void BalloonPrimFreePage(unsigned long page);
-
 static int  Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType);
 static int  Balloon_FreePage(Balloon *b, int monitorUnlock);
 static int  Balloon_AdjustSize(Balloon *b, uint32 target);
 static void Balloon_Reset(Balloon *b);
 
-static void Balloon_StartTimer(Balloon *b);
-static void Balloon_StopTimer(Balloon *b);
 static void BalloonTimerHandler(void *clientData);
 
 static int Balloon_MonitorStart(Balloon *b);
 static int Balloon_MonitorGuestType(Balloon *b);
 static int Balloon_MonitorGetTarget(Balloon *b, uint32 *nPages);
-static int Balloon_MonitorLockPage(Balloon *b, unsigned long addr);
-static int Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr);
+static int Balloon_MonitorLockPage(Balloon *b, PageHandle handle);
+static int Balloon_MonitorUnlockPage(Balloon *b, PageHandle handle);
 
 /*
  * Macros
@@ -253,7 +247,7 @@ BalloonProcRead(char *buf,      // OUT
    int len = 0;
    BalloonStats stats;
 
-   BalloonGetStats(&stats);
+   Balloon_GetStats(&stats);
 
    /* format size info */
    len += OS_Snprintf(buf + len, size - len,
@@ -307,138 +301,34 @@ BalloonProcRead(char *buf,      // OUT
  * Utility Operations
  */
 
-/*
- *----------------------------------------------------------------------
- *
- * AddrToPPN --
- *
- *      Return the physical page number corresponding to the specified
- *      kernel-mapped address.
- *
- * Results:
- *      Returns PPN for "addr".
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static inline unsigned long
-AddrToPPN(unsigned long addr)
-{
-   return OS_AddrToPPN(addr);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * BalloonPrimAllocPage --
- *
- *      Attempts to allocate and reserve a physical page.
- *
- *      If canSleep == 1, i.e., BALLOON_PAGE_ALLOC_CANSLEEP:
- *         The allocation can wait (sleep) for page writeout (swap)
- *         by the guest.
- *      otherwise canSleep == 0, i.e., BALLOON_PAGE_ALLOC_NOSLEEP:
- *         If allocation of a page requires disk writeout, then
- *         just fail. DON'T sleep.
- *
- * Results:
- *      Returns the physical address of the allocated page, or 0 if error.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static unsigned long
-BalloonPrimAllocPage(BalloonPageAllocType canSleep)
-{
-   return OS_AllocReservedPage(canSleep);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * BalloonPrimFreePage --
- *
- *      Unreserves and deallocates specified physical page.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static void
-BalloonPrimFreePage(unsigned long page)
-{
-   return OS_FreeReservedPage(page);
-}
 
 /*
  *----------------------------------------------------------------------
  *
- * BalloonGuestType --
+ * Balloon_GetStats --
  *
- *      Return balloon guest OS identifier obtained by parsing
- *      system-dependent identity string.
+ *      Returns information about balloon state, including the current and
+ *      target size, rates for allocating and freeing pages, and statistics
+ *      about past activity.
  *
  * Results:
- *      Returns one of BALLOON_GUEST_{LINUX,BSD,SOLARIS,UNKNOWN}.
+ *      None
  *
  * Side effects:
- *      None.
+ *      None
  *
  *----------------------------------------------------------------------
  */
-static int
-BalloonGuestType(void)
-{
-   const char *identity;
-
-   /* obtain OS identify string */
-   identity = OS_Identity();
-
-   /* unknown if not specified */
-   if (identity == NULL) {
-      return(BALLOON_GUEST_UNKNOWN);
-   }
 
-   /* classify based on first letter (avoid defining strcmp) */
-   switch (identity[0]) {
-   case 'l':
-   case 'L':
-      return BALLOON_GUEST_LINUX;
-   case 'b':
-   case 'B':
-      return BALLOON_GUEST_BSD;
-   case 's':
-   case 'S':
-      return BALLOON_GUEST_SOLARIS;
-   default:
-      break;
-   }
-
-   /* unknown */
-   return BALLOON_GUEST_UNKNOWN;
-}
-
-/*
- * Returns information about balloon state, including the current and
- * target size, rates for allocating and freeing pages, and statistics
- * about past activity.
- */
-void BalloonGetStats(BalloonStats *stats)
+void
+Balloon_GetStats(BalloonStats *stats) // OUT
 {
    Balloon *b = &globalBalloon;
 
    /*
     * Copy statistics out of global structure.
     */
-   OS_MemCopy(stats, &b->stats, sizeof (BalloonStats));
+   OS_MemCopy(stats, &b->stats, sizeof *stats);
 
    /*
     * Fill in additional information about size and rates, which is
@@ -450,9 +340,6 @@ void BalloonGetStats(BalloonStats *stats)
    stats->rateFree = b->rateFree;
 }
 
-/*
- * BalloonChunk Operations
- */
 
 /*
  *----------------------------------------------------------------------
@@ -490,7 +377,6 @@ BalloonChunk_Create(void)
    /* initialize */
    OS_MemZero(chunk, sizeof *chunk);
 
-   /* everything OK */
    return chunk;
 }
 
@@ -550,8 +436,7 @@ Balloon_Init(Balloon *b)
    /* initialize reset flag */
    b->resetFlag = 1;
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
 /*
@@ -641,7 +526,7 @@ static void
 BalloonTimerHandler(void *clientData)
 {
    Balloon *b = (Balloon *) clientData;
-   uint32 target;
+   uint32 target = 0; // Silence compiler warning.
    int status;
 
    /* update stats */
@@ -667,48 +552,6 @@ BalloonTimerHandler(void *clientData)
    }
 }
 
-/*
- *----------------------------------------------------------------------
- *
- * Balloon_StartTimer --
- *
- *      Schedules next execution of balloon timer handler.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static void
-Balloon_StartTimer(Balloon *b)
-{
-   OS_TimerStart();
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Balloon_StopTimer --
- *
- *      Deschedules balloon timer handler.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static void
-Balloon_StopTimer(Balloon *b)
-{
-   OS_TimerStop();
-}
-
 
 /*
  *----------------------------------------------------------------------
@@ -765,8 +608,8 @@ Balloon_ErrorPagesFree(Balloon *b)
 
    /* free all non-balloonable "error" pages */
    for (i = 0; i < b->errors.nextPage; i++) {
-      BalloonPrimFreePage(b->errors.page[i]);
-      b->errors.page[i] = 0;
+      OS_ReservedPageFree(b->errors.page[i]);
+      b->errors.page[i] = PAGE_HANDLE_INVALID;
       STATS_INC(b->stats.primErrorPageFree);
    }
    b->errors.nextPage = 0;
@@ -792,7 +635,7 @@ static int
 Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
 {
    BalloonChunk *chunk;
-   unsigned long page;
+   PageHandle page;
    int status;
 
  retry:
@@ -800,21 +643,32 @@ Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
    /* allocate page, fail if unable */
    STATS_INC(b->stats.primAlloc[allocType]);
 
-   page = BalloonPrimAllocPage(allocType);
+   /*
+    * Attempts to allocate and reserve a physical page.
+    *
+    * If canSleep == 1, i.e., BALLOON_PAGE_ALLOC_CANSLEEP:
+    *      The allocation can wait (sleep) for page writeout (swap) by the guest.
+    * otherwise canSleep == 0, i.e., BALLOON_PAGE_ALLOC_NOSLEEP:
+    *      If allocation of a page requires disk writeout, then just fail. DON'T sleep.
+    *
+    * Returns the physical address of the allocated page, or 0 if error.
+    */
+   page = OS_ReservedPageAlloc(allocType);
 
-   if (page == 0) {
+   if (page == PAGE_HANDLE_INVALID) {
       STATS_INC(b->stats.primAllocFail[allocType]);
-      return(BALLOON_PAGE_ALLOC_FAILURE);
+      return BALLOON_PAGE_ALLOC_FAILURE;
    }
 
    /* find chunk with space, create if necessary */
    chunk = b->chunks;
    if ((chunk == NULL) || (chunk->nextPage >= BALLOON_CHUNK_PAGES)) {
       /* create new chunk */
-      if ((chunk = BalloonChunk_Create()) == NULL) {
+      chunk = BalloonChunk_Create();
+      if (chunk == NULL) {
          /* reclaim storage, fail */
-         BalloonPrimFreePage(page);
-         return(BALLOON_PAGE_ALLOC_FAILURE);
+         OS_ReservedPageFree(page);
+         return BALLOON_PAGE_ALLOC_FAILURE;
       }
       BalloonChunk_Insert(&b->chunks, chunk);
 
@@ -832,8 +686,8 @@ Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
       }
 
       /* reclaim storage, fail */
-      BalloonPrimFreePage(page);
-      return(status);
+      OS_ReservedPageFree(page);
+      return status;
    }
 
    /* track allocated page */
@@ -843,8 +697,7 @@ Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
    /* update balloon size */
    b->nPages++;
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
 /*
@@ -868,7 +721,7 @@ static int
 Balloon_FreePage(Balloon *b, int monitorUnlock)
 {
    BalloonChunk *chunk;
-   unsigned long page;
+   PageHandle page;
    int status;
 
    chunk = b->chunks;
@@ -903,7 +756,7 @@ Balloon_FreePage(Balloon *b, int monitorUnlock)
    }
 
    /* deallocate page */
-   BalloonPrimFreePage(page);
+   OS_ReservedPageFree(page);
    STATS_INC(b->stats.primFree);
 
    /* update balloon size */
@@ -919,8 +772,7 @@ Balloon_FreePage(Balloon *b, int monitorUnlock)
       b->nChunks--;
    }
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
 /*
@@ -989,6 +841,7 @@ BalloonIncreaseRateAlloc(Balloon *b, uint32 nAlloc)
    }
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1004,6 +857,7 @@ BalloonIncreaseRateAlloc(Balloon *b, uint32 nAlloc)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 BalloonInflate(Balloon *b, uint32 target)
 {
@@ -1128,6 +982,7 @@ BalloonInflate(Balloon *b, uint32 target)
    return(BALLOON_SUCCESS);
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1143,6 +998,7 @@ BalloonInflate(Balloon *b, uint32 target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 BalloonDeflate(Balloon *b, uint32 target)
 {
@@ -1169,10 +1025,10 @@ BalloonDeflate(Balloon *b, uint32 target)
                         BALLOON_RATE_FREE_MAX);
    }
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1189,6 +1045,7 @@ BalloonDeflate(Balloon *b, uint32 target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 Balloon_AdjustSize(Balloon *b, uint32 target)
 {
@@ -1230,6 +1087,7 @@ Balloon_AdjustSize(Balloon *b, uint32 target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 Balloon_MonitorStart(Balloon *b)
 {
@@ -1253,10 +1111,10 @@ Balloon_MonitorStart(Balloon *b)
       STATS_INC(b->stats.startFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1272,15 +1130,20 @@ Balloon_MonitorStart(Balloon *b)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 Balloon_MonitorGuestType(Balloon *b)
 {
    uint32 status, target;
+   BalloonGuest identity;
    Backdoor_proto bp;
 
+   identity = OS_Identity();
+   ASSERT(identity == (uint32) identity);
+
    /* prepare backdoor args */
    bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_GUEST_ID;
-   bp.in.size = BalloonGuestType();
+   bp.in.size = identity;
 
    /* invoke backdoor */
    Backdoor_Balloon(&bp);
@@ -1300,10 +1163,10 @@ Balloon_MonitorGuestType(Balloon *b)
       STATS_INC(b->stats.guestTypeFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1315,7 +1178,7 @@ Balloon_MonitorGuestType(Balloon *b)
  *      Predicts the maximum achievable balloon size and sends it
  *      to vmm => vmkernel via vEbx register.
  *
- *      OS_PredictMaxReservedPages() returns either predicted max balloon
+ *      OS_ReservedPageGetLimit() returns either predicted max balloon
  *      pages or BALLOON_MAX_SIZE_USE_CONFIG. In the later scenario,
  *      vmkernel uses global config options for determining a guest's max
  *      balloon size. Note that older vmballoon drivers set vEbx to
@@ -1331,15 +1194,27 @@ Balloon_MonitorGuestType(Balloon *b)
  *
  *----------------------------------------------------------------------
  */
+
 static int
-Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
+Balloon_MonitorGetTarget(Balloon *b,     // IN
+                         uint32 *target) // OUT
 {
    Backdoor_proto bp;
+   unsigned long limit;
+   uint32 limit32;
    uint32 status;
 
+   limit = OS_ReservedPageGetLimit();
+
+   /* Ensure limit fits in 32-bits */
+   limit32 = (uint32)limit;
+   if (limit32 != limit) {
+      return BALLOON_FAILURE;
+   }
+
    /* prepare backdoor args */
    bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_TARGET;
-   bp.in.size = OS_PredictMaxReservedPages();
+   bp.in.size = limit;
 
    /* invoke backdoor */
    Backdoor_Balloon(&bp);
@@ -1359,17 +1234,17 @@ Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
       STATS_INC(b->stats.targetFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
  * Balloon_MonitorLockPage --
  *
- *      Attempts to contact monitor and add PPN containing "addr"
- *      to set of "balloon locked" pages.
+ *      Attempts to contact monitor and add PPN corresponding to
+ *      the page handle to set of "balloon locked" pages.
  *
  * Results:
  *      Returns BALLOON_SUCCESS if successful, otherwise error code.
@@ -1379,16 +1254,17 @@ Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
-Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
+Balloon_MonitorLockPage(Balloon *b,        // IN
+                        PageHandle handle) // IN
 {
    unsigned long ppn;
    uint32 ppn32;
    uint32 status, target;
    Backdoor_proto bp;
 
-   /* convert kernel-mapped "physical addr" to ppn */
-   ppn = AddrToPPN(addr);
+   ppn = OS_ReservedPageGetPPN(handle);
 
    /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
    ppn32 = (uint32)ppn;
@@ -1418,8 +1294,7 @@ Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
       STATS_INC(b->stats.lockFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
 /*
@@ -1427,8 +1302,8 @@ Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
  *
  * Balloon_MonitorUnlockPage --
  *
- *      Attempts to contact monitor and remove PPN containing "addr"
- *      from set of "balloon locked" pages.
+ *      Attempts to contact monitor and remove PPN corresponding to
+ *      the page handle from set of "balloon locked" pages.
  *
  * Results:
  *      Returns BALLOON_SUCCESS if successful, otherwise error code.
@@ -1439,15 +1314,15 @@ Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
  *----------------------------------------------------------------------
  */
 static int
-Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr)
+Balloon_MonitorUnlockPage(Balloon *b,        // IN
+                          PageHandle handle) // IN
 {
    unsigned long ppn;
    uint32 ppn32;
    uint32 status, target;
    Backdoor_proto bp;
 
-   /* convert kernel-mapped "physical addr" to ppn */
-   ppn = AddrToPPN(addr);
+   ppn = OS_ReservedPageGetPPN(handle);
 
    /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
    ppn32 = (uint32)ppn;
@@ -1477,23 +1352,36 @@ Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr)
       STATS_INC(b->stats.unlockFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
- * Module Operations
+ *----------------------------------------------------------------------
+ *
+ * Balloon_ModuleInit --
+ *
+ *      Startup the balloon module.
+ *
+ * Results:
+ *      On success: BALLOON_SUCCESS
+ *      On failure: BALLOON_FAILURE
+ *
+ * Side effects:
+ *      None
+ *
+ *----------------------------------------------------------------------
  */
 
-static int
-BalloonModuleInit(void)
+int
+Balloon_ModuleInit(void)
 {
    static int initialized = 0;
    Balloon *b = &globalBalloon;
 
    /* initialize only once */
    if (initialized++) {
-      return(BALLOON_FAILURE);
+      return BALLOON_FAILURE;
    }
 
    /* os-specific initialization */
@@ -1503,43 +1391,54 @@ BalloonModuleInit(void)
    Balloon_Init(b);
 
    /* start timer */
-   OS_TimerInit(BalloonTimerHandler, b, OS_TimerHz());
-   Balloon_StartTimer(b);
+   timerStarted = FALSE;
+   if (!OS_TimerStart(BalloonTimerHandler, b)) {
+      Balloon_ModuleCleanup();
+      return BALLOON_FAILURE;
+   }
 
-   /* everything OK */
+   timerStarted = TRUE;
    return BALLOON_SUCCESS;
 }
 
-static void
-BalloonModuleCleanup(void)
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_ModuleCleanup --
+ *
+ *      Terminate and cleanup the balloon module.
+ *
+ * Results:
+ *      None
+ *
+ * Side effects:
+ *      None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Balloon_ModuleCleanup(void)
 {
    Balloon *b = &globalBalloon;
 
    /* stop timer */
-   Balloon_StopTimer(b);
+   if (timerStarted) {
+      OS_TimerStop();
+   }
 
    /*
     * Deallocate all reserved memory, and reset connection with monitor.
     * Reset connection before deallocating memory to avoid potential for
     * additional spurious resets from guest touching deallocated pages.
     */
-   (void) Balloon_MonitorStart(b);
+   Balloon_MonitorStart(b);
    Balloon_Deallocate(b);
 
    /* os-specific cleanup */
    OS_Cleanup();
 }
 
-int init_module(void)
-{
-   return(BalloonModuleInit());
-}
-
-void cleanup_module(void)
-{
-   BalloonModuleCleanup();
-}
-
 #ifdef __cplusplus
 }
 #endif
index a31c4b369fe09cf883de94ce826725bf4489fcd4..caebe45dfb383ff916fa09b5ae6f28a8ef9812f3 100644 (file)
@@ -74,8 +74,9 @@ typedef struct {
  * Operations
  */
 
-extern void BalloonGetStats(BalloonStats *stats);
-extern int  init_module(void);
-extern void cleanup_module(void);
+extern int  Balloon_ModuleInit(void);
+extern void Balloon_ModuleCleanup(void);
+
+extern void Balloon_GetStats(BalloonStats *stats);
 
 #endif /* VMBALLOON_H */
index 125b5cc88e9872eab5cdf0cf9f1a40dae3bb50f5..931e01fcc78b4992e6bdc209228030a8e83a26c7 100644 (file)
@@ -1169,27 +1169,11 @@ pvscsi_complete_request(struct pvscsi_adapter *adapter, const PVSCSIRingCmpDesc
        if (sdstat != SAM_STAT_GOOD &&
            (btstat == BTSTAT_SUCCESS ||
             btstat == BTSTAT_LINKED_COMMAND_COMPLETED ||
-            btstat == BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG))
-               switch (sdstat) {
-               case SAM_STAT_CHECK_CONDITION:
-                       /*
-                        * Sense data is set by the emulation.
-                        * Linux seems to want DID_OK despite the error.
-                        */
-                       cmd->result = (DID_OK << 16) | (SAM_STAT_CHECK_CONDITION);
-                       if (cmd->sense_buffer)
-                               cmd->result |= (DRIVER_SENSE << 24);
-                       break;
-               case SAM_STAT_BUSY:
-                       /* Back off. */
-                       cmd->result = (DID_OK << 16) | sdstat;
-                       break;
-               default:
-                       cmd->result = (DID_ERROR << 16);
-                       LOG(0, "Unhandled SCSI status: 0x%x\n", sdstat);
-               }
-
-       else
+            btstat == BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG)) {
+               cmd->result = (DID_OK << 16) | sdstat;
+               if (sdstat == SAM_STAT_CHECK_CONDITION && cmd->sense_buffer)
+                       cmd->result |= (DRIVER_SENSE << 24);
+       } else
                switch (btstat) {
                case BTSTAT_SUCCESS:
                case BTSTAT_LINKED_COMMAND_COMPLETED:
index 85cdc7c4bf81a9f9c83bc960ddd2bdad9688eb8c..5e0b80cec178c9253950808151eae0cd1b765afb 100644 (file)
@@ -25,8 +25,8 @@
 #ifndef _PVSCSI_VERSION_H_
 #define _PVSCSI_VERSION_H_
 
-#define PVSCSI_DRIVER_VERSION           0.0.1.0
-#define PVSCSI_DRIVER_VERSION_COMMAS    0,0,1,0
-#define PVSCSI_DRIVER_VERSION_STRING   "0.0.1.0"
+#define PVSCSI_DRIVER_VERSION           0.0.1.1
+#define PVSCSI_DRIVER_VERSION_COMMAS    0,0,1,1
+#define PVSCSI_DRIVER_VERSION_STRING   "0.0.1.1"
 
 #endif /* _PVSCSI_VERSION_H_ */
index 855f67d00dde24d6bc92761b3afa33a3413f4c8d..7a256f532f9d728ecb2d45ddaeaa0ddeeee1e641 100644 (file)
@@ -1145,6 +1145,8 @@ struct {
 #include "vmware_pack_end.h"
 SCSIMediumRemovalCmd;
 
+#define SCSI_RW10_MAX_LBN      0xffffffffu
+#define SCSI_RW10_MAX_LENGTH       0xffffu
 
 /*
  * Format of READ CAPACITY (10) and (16) request and response blocks.
@@ -1158,7 +1160,6 @@ struct {
    uint8 rel   :1,
                :4,
          lun   :3;
-#define SCSI_RW10_MAX_LBN 0xffffffffu
    uint32 lbn;
    uint8 reserved[2];
    uint8 pmi   :1,
index 89873c5559f2244cffa8dc0ab7b7d2101d52950d..87adc19250d557489e6f4628be8fb71bd754e27f 100644 (file)
@@ -106,6 +106,59 @@ VMCIHandle VMCI_MAKE_HANDLE(VMCIId cid,
    return h;
 }
 
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCI_HANDLE_TO_UINT64 --
+ *
+ *     Helper for VMCI handle to uint64 conversion.
+ *
+ * Results:
+ *     The uint64 value.
+ * 
+ * Side effects:     
+ *     None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE uint64
+VMCI_HANDLE_TO_UINT64(VMCIHandle handle) // IN:
+{
+   uint64 handle64;
+
+   handle64 = handle.context;
+   handle64 <<= 32;
+   handle64 |= handle.resource;
+   return handle64;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCI_UINT64_TO_HANDLE --
+ *
+ *     Helper for uint64 to VMCI handle conversion.
+ *
+ * Results:
+ *     The VMCI handle value.
+ * 
+ * Side effects:     
+ *     None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE VMCIHandle
+VMCI_UINT64_TO_HANDLE(uint64 handle64) // IN:
+{
+   VMCIId context = (VMCIId)(handle64 >> 32);
+   VMCIId resource = (VMCIId)handle64;
+
+   return VMCI_MAKE_HANDLE(context, resource);
+}
+
 #define VMCI_HANDLE_TO_CONTEXT_ID(_handle) ((_handle).context)
 #define VMCI_HANDLE_TO_RESOURCE_ID(_handle) ((_handle).resource)
 #define VMCI_HANDLE_EQUAL(_h1, _h2) ((_h1).context == (_h2).context && \
index 67b6be9b7cff70481295c9d2f6ba15e5d8dc35e1..bd28b2a42f681affa4c735de5c0c9ecfb53304c5 100644 (file)
@@ -52,15 +52,14 @@ typedef enum {
 /* Used to determine what checkpoint state to get and set. */
 #define VMCI_NOTIFICATION_CPT_STATE 0x1
 #define VMCI_WELLKNOWN_CPT_STATE 0x2
-#define VMCI_QP_CPT_STATE 0x3
-#define VMCI_QP_INFO_CPT_STATE 0x4
 
 /* Used to control the VMCI device in the vmkernel */
 #define VMCI_DEV_RESET            0x01
-#define VMCI_DEV_QP_RESET         0x02
+#define VMCI_DEV_QP_RESET         0x02  // DEPRECATED
 #define VMCI_DEV_QUIESCE          0x03
 #define VMCI_DEV_UNQUIESCE        0x04
-#define VMCI_DEV_QP_BREAK_SHARING 0x05
+#define VMCI_DEV_QP_BREAK_SHARING 0x05  // DEPRECATED
+
 
 /*
  *-------------------------------------------------------------------------
index 979f8df5ccd7d4ed7affd4c6b9c67f3ff1299b41..68d10dd597a71e14eeae8157f51484effae61a50 100644 (file)
@@ -383,10 +383,15 @@ typedef struct VMCIQueuePairAllocInfo {
    uint32     flags;
    uint64     produceSize;
    uint64     consumeSize;
+#if !defined(VMX86_SERVER) && !defined(VMKERNEL)
    VA64       producePageFile; /* User VA. */
    VA64       consumePageFile; /* User VA. */
    uint64     producePageFileSize; /* Size of the file name array. */
    uint64     consumePageFileSize; /* Size of the file name array. */ 
+#else
+   PPN *      PPNs;
+   uint64     numPPNs;
+#endif
    int32      result;
    uint32     _pad;
 } VMCIQueuePairAllocInfo;
@@ -429,10 +434,12 @@ typedef struct VMCIQueuePairPageFileInfo_NoHostQP {
 
 typedef struct VMCIQueuePairPageFileInfo {
    VMCIHandle handle;
+#if !defined(VMX86_SERVER) && !defined(VMKERNEL)
    VA64       producePageFile; /* User VA. */
    VA64       consumePageFile; /* User VA. */
    uint64     producePageFileSize; /* Size of the file name array. */
    uint64     consumePageFileSize; /* Size of the file name array. */
+#endif
    int32      result;
    uint32     version;   /* Was _pad. */
    VA64       produceVA; /* User VA of the mapped file. */
index 89f18b109d6a93dc635969d2cd723b845222c6cc..0897f91fe3c80d351603b5d35ca955ecefec3156 100644 (file)
@@ -70,7 +70,6 @@ LIBHGFS          += hgfsUtil.o
 LIBHGFSBD        := hgfsBd.o
 
 LIBMESSAGE       := message.o
-LIBMESSAGE       += messageBackdoor.o
 
 LIBRPCOUT        := rpcout.o
 
index 0a7515d9b78d2e83f9527029d6498b6fc10199fe..2e16be8ef0b2f0e854389b509bab0e7a697943cc 100644 (file)
@@ -91,7 +91,6 @@ OBJS +=       hgfsEscape.o
 OBJS +=        hgfsUtil.o
 OBJS +=        kernelStubsLinux.o
 OBJS +=        message.o
-OBJS +=        messageBackdoor.o
 OBJS +=        rpcout.o
 
 ifeq ($(MACHINE),x86_64)
@@ -134,7 +133,6 @@ LIBHGFS          += hgfsUtil.o
 LIBHGFSBD        := hgfsBd.o
 
 LIBMESSAGE       := message.o
-LIBMESSAGE       += messageBackdoor.o
 
 LIBRPCOUT        := rpcout.o
 
index 8d28b79c9d7a81f7c1bb67f4383cd6bf5a4a219e..404096b5c67f3c63bd7962738f0d0bb3d59ad0ff 100644 (file)
@@ -968,17 +968,29 @@ HgfsIget(struct super_block *sb,         // IN: Superblock of this fs
 
          oldInode = HgfsInodeLookup(sb, attr->hostFileId);
          if (oldInode) {
-
             /*
              * If this inode's inode number was generated via iunique(), we
              * have a collision and cannot use the server's inode number.
-             * Otherwise, we should reuse this inode.
+             * Or, if the dentry is for a directory, we should not reuse the
+             * inode in case there are two directory dentries referring to the
+             * same inode. Otherwise, we should reuse this inode.
+             *
+             * Be careful of the following setting when resuing inodes:
+             *     host dir -> share name
+             *     C:/parent/         -> host1
+             *     C:/parent/child/   -> host2
+             * /mnt/hgfs/host1/child and /mnt/hgfs/host2 are actually the
+             * same directory in host. It also happens to the files in child.
+             * Here, we should prevent the inode reusing because in Linux kernel
+             * no inode can be pointed to by multiple directory entries; whereas
+             * it is OK to do that for the files in /mnt/hgfs/child/.
              */
             iinfo = INODE_GET_II_P(oldInode);
-            if (iinfo->isFakeInodeNumber) {
-               LOG(6, (KERN_DEBUG "VMware hgfs: HgfsIget: found existing "
-                       "iuniqued inode %"FMT64"d, generating new one\n",
-                       attr->hostFileId));
+            if (iinfo->isFakeInodeNumber ||
+                attr->type == HGFS_FILE_TYPE_DIRECTORY) {
+               LOG(6, ("VMware hgfs: %s: found existing iuniqued inode or "
+                       "directory inode %"FMT64"d, generating new one\n",
+                       __func__, attr->hostFileId));
                ino = iunique(sb, HGFS_RESERVED_INO);
                isFakeInodeNumber = TRUE;
             } else {
index fbf529aa0087a8cee8fafd4d0438d77a3fdff5c5..f413527958d8b044c94baf543ec3796c0940f0cc 100644 (file)
@@ -1363,6 +1363,27 @@ HgfsRename(struct inode *oldDir,      // IN: Inode of original directory
       goto out;
    }
 
+   if (oldDentry->d_inode && newDentry->d_inode) {
+      HgfsInodeInfo *oldIinfo;
+      HgfsInodeInfo *newIinfo;
+      /*
+       * Don't do rename if the source and target are identical (from the
+       * viewpoint of the host). It is possible that multiple guest inodes
+       * point to the same host inode under the case that both one folder
+       * and its subfolder are mapped as hgfs sharese. Please also see the
+       * comments at fsutil.c/HgfsIget.
+       */
+      oldIinfo = INODE_GET_II_P(oldDentry->d_inode);
+      newIinfo = INODE_GET_II_P(newDentry->d_inode);
+      if (oldIinfo->hostFileId !=0 && newIinfo->hostFileId != 0 &&
+          oldIinfo->hostFileId == newIinfo->hostFileId) {
+         LOG(4, ("VMware hgfs: %s: source and target are the same file.\n",
+                 __func__));
+         result = -EEXIST;
+         goto out;
+      }
+   }
+
    req = HgfsGetNewRequest();
    if (!req) {
       LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: out of memory while "
index 01452142d0a163e04b6598f26935d84ed3bb7b93..2d3385891bd39db06713dc15fa89b1594a5ae184 100644 (file)
 /* use config value for max balloon size */
 #define BALLOON_MAX_SIZE_USE_CONFIG     (0)
 
-/* guest identities */
-#define BALLOON_GUEST_UNKNOWN           (0)
-#define BALLOON_GUEST_LINUX             (1)
-#define BALLOON_GUEST_BSD               (2)
-#define BALLOON_GUEST_WINDOWS_NT4       (3)
-#define BALLOON_GUEST_WINDOWS_NT5       (4)
-#define BALLOON_GUEST_SOLARIS           (5)
+/*
+ * Guest identities
+ *
+ *      Note : all values should fit in 32 bits
+ */
+typedef enum {
+   BALLOON_GUEST_UNKNOWN     = 0,
+   BALLOON_GUEST_LINUX       = 1,
+   BALLOON_GUEST_BSD         = 2,
+   BALLOON_GUEST_WINDOWS_NT4 = 3,
+   BALLOON_GUEST_WINDOWS_NT5 = 4,
+   BALLOON_GUEST_SOLARIS     = 5,
+   BALLOON_GUEST_MACOS       = 6,
+} BalloonGuest;
 
 /* error codes */
 #define BALLOON_SUCCESS                 (0)
index 573cfc26f1164192fe92cd9e26b64605188c0547..a83dba68b463504ff3dee1a4ffbc402f020305be 100644 (file)
@@ -56,6 +56,7 @@
 
 #include "vmmemctl_version.h"
 #include "os.h"
+#include "vmballoon.h"
 
 
 /*
@@ -136,6 +137,8 @@ static struct file_operations global_proc_fops = {
 
 static os_state global_state;
 
+static int os_timer_thread_loop(void *clientData);
+
 
 /*
  *-----------------------------------------------------------------------------
@@ -157,7 +160,7 @@ static os_state global_state;
 void *
 OS_Malloc(size_t size) // IN
 {
-   return(kmalloc(size, OS_KMALLOC_NOSLEEP));
+   return kmalloc(size, OS_KMALLOC_NOSLEEP);
 }
 
 
@@ -266,28 +269,53 @@ OS_Snprintf(char *buf,          // OUT
    return result;
 }
 
+
 /*
- * System-Dependent Operations
+ *-----------------------------------------------------------------------------
+ *
+ * OS_Identity --
+ *
+ *      Returns an identifier for the guest OS family.
+ *
+ * Results:
+ *      The identifier
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
  */
 
-const char *
+BalloonGuest
 OS_Identity(void)
 {
-   return("linux");
+   return BALLOON_GUEST_LINUX;
 }
 
+
 /*
- * Predict the maximum achievable balloon size.
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageGetLimit --
+ *
+ *      Predict the maximum achievable balloon size.
+ *
+ *      In 2.4.x and 2.6.x kernels, the balloon driver can guess the number of pages
+ *      that can be ballooned. But, for now let us just pass the totalram-size as the
+ *      maximum achievable balloon size. Note that normally (unless guest kernel is
+ *      booted with a mem=XX parameter) the totalram-size is equal to alloc.max.
+ *
+ * Results:
+ *      The maximum achievable balloon size in pages.
  *
- * In 2.4.x and 2.6.x kernels, the balloon driver can guess the number of pages
- * that can be ballooned. But, for now let us just pass the totalram-size as the 
- * maximum achievable balloon size. Note that normally (unless guest kernel is
- * booted with a mem=XX parameter) the totalram-size is equal to alloc.max.
+ * Side effects:
+ *      None
  *
- * Returns the maximum achievable balloon size in pages
+ *-----------------------------------------------------------------------------
  */
-unsigned int
-OS_PredictMaxReservedPages(void)
+
+unsigned long
+OS_ReservedPageGetLimit(void)
 {
    struct sysinfo info;
    os_state *state = &global_state;
@@ -304,49 +332,142 @@ OS_PredictMaxReservedPages(void)
    return state->totalMemoryPages;
 }
 
+
 /*
- * Use newer alloc_page() interface on 2.4.x kernels.
- * Use "struct page *" value as page handle for clients.
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageGetPPN --
+ *
+ *      Convert a page handle (of a physical page previously reserved with
+ *      OS_ReservedPageAlloc()) to a ppn.
+ *
+ *      Use newer alloc_page() interface on 2.4.x kernels.
+ *
+ * Results:
+ *      The ppn.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
  */
+
 unsigned long
-OS_AddrToPPN(unsigned long addr)
+OS_ReservedPageGetPPN(PageHandle handle) // IN: A valid page handle
 {
-   struct page *page = (struct page *) addr;
+   struct page *page = (struct page *)handle;
 
    return page_to_pfn(page);
 }
 
-unsigned long
-OS_AllocReservedPage(int canSleep)
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageAlloc --
+ *
+ *      Reserve a physical page for the exclusive use of this driver.
+ *
+ * Results:
+ *      On success: A valid page handle that can be passed to OS_ReservedPageGetPPN()
+ *                  or OS_ReservedPageFree().
+ *      On failure: PAGE_HANDLE_INVALID
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+PageHandle
+OS_ReservedPageAlloc(int canSleep) // IN
 {
-   struct page *page = alloc_page(canSleep ?
-                           OS_PAGE_ALLOC_CANSLEEP : OS_PAGE_ALLOC_NOSLEEP);
+   struct page *page;
 
-   return (unsigned long)page;
+   page = alloc_page(canSleep ? OS_PAGE_ALLOC_CANSLEEP : OS_PAGE_ALLOC_NOSLEEP);
+   if (page == NULL) {
+      return PAGE_HANDLE_INVALID;
+   }
+
+   return (PageHandle)page;
 }
 
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageFree --
+ *
+ *      Unreserve a physical page previously reserved with OS_ReservedPageAlloc().
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
 void
-OS_FreeReservedPage(unsigned long addr)
+OS_ReservedPageFree(PageHandle handle) // IN: A valid page handle
 {
-   /* deallocate page */
-   struct page *page = (struct page *) addr;
+   struct page *page = (struct page *)handle;
+
    __free_page(page);
 }
 
-void
-OS_TimerInit(OSTimerHandler *handler, // IN
-             void *clientData,        // IN
-             int period)              // IN
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_TimerStart --
+ *
+ *      Setup the timer callback function, then start it.
+ *
+ * Results:
+ *      On success: TRUE
+ *      On failure: FALSE
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+OS_TimerStart(OSTimerHandler *handler, // IN
+              void *clientData)        // IN
 {
    os_timer *t = &global_state.timer;
+   os_status *s = &global_state.status;
+
+   /* initialize the timer structure */
    t->handler = handler;
    t->data = clientData;
-   t->period = period;
+   t->period = HZ;
+
+   /* initialize sync objects */
+   init_waitqueue_head(&t->delay);
+
+   /* create kernel thread */
+   t->task = kthread_run(os_timer_thread_loop, t, "vmmemctl");
+   if (IS_ERR(t->task)) {
+      printk(KERN_WARNING "%s: unable to create kernel thread\n", s->name);
+      return FALSE;
+   }
+   if (OS_DEBUG) {
+      printk(KERN_DEBUG "%s: started kernel thread pid=%d\n", s->name, t->task->pid);
+   }
+
+   return TRUE;
 }
 
-static int os_timer_thread_loop(void *data)
+
+static int
+os_timer_thread_loop(void *clientData) // IN
 {
-   os_timer *t = (os_timer *) data;
+   os_timer *t = clientData;
 
    /* we are running */
    compat_set_freezable();
@@ -367,29 +488,25 @@ static int os_timer_thread_loop(void *data)
       t->handler(t->data);
    }
 
-   /* terminate */
-   return(0);
+   return 0;
 }
 
-void
-OS_TimerStart(void)
-{
-   os_timer *t = &global_state.timer;
-   os_status *s = &global_state.status;
-
-   /* initialize sync objects */
-   init_waitqueue_head(&t->delay);
 
-   /* create kernel thread */
-   t->task = kthread_run(os_timer_thread_loop, t, "vmmemctl");
-   if (IS_ERR(t->task)) {
-      /* fail */
-      printk(KERN_WARNING "%s: unable to create kernel thread\n", s->name);
-   } else if (OS_DEBUG) {
-      printk(KERN_DEBUG "%s: started kernel thread pid=%d\n", s->name,
-             t->task->pid);
-   }
-}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_TimerStop --
+ *
+ *      Stop the timer.
+ *
+ * Results:
+ *      None
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
 
 void
 OS_TimerStop(void)
@@ -397,12 +514,6 @@ OS_TimerStop(void)
    kthread_stop(global_state.timer.task);
 }
 
-unsigned int
-OS_TimerHz(void)
-{
-   return HZ;
-}
-
 
 /*
  *-----------------------------------------------------------------------------
@@ -426,6 +537,7 @@ OS_Yield(void)
    cond_resched();
 }
 
+
 #ifdef CONFIG_PROC_FS
 static int os_proc_show(struct seq_file *f,
                        void *data)
@@ -460,6 +572,7 @@ static int os_proc_show(struct seq_file *f,
    return err;
 }
 
+
 static int os_proc_open(struct inode *inode,
                        struct file *file)
 {
@@ -468,6 +581,7 @@ static int os_proc_open(struct inode *inode,
 
 #endif
 
+
 void
 OS_Init(const char *name,
         const char *name_verbose,
@@ -506,6 +620,7 @@ OS_Init(const char *name,
    printk(KERN_INFO "%s initialized\n", state->status.name_verbose);
 }
 
+
 void
 OS_Cleanup(void)
 {
@@ -520,6 +635,29 @@ OS_Cleanup(void)
    printk(KERN_INFO "%s unloaded\n", s->name_verbose);
 }
 
+
+int
+init_module(void)
+{
+   if (Balloon_ModuleInit() == BALLOON_SUCCESS) {
+      return 0;
+   } else {
+      return -EAGAIN;
+   }
+}
+
+
+void
+cleanup_module(void)
+{
+   /*
+    * We cannot use module_exit(Balloon_ModuleCleanup) because compilation
+    * would fail for 'Kernel Verify Build Status', see bug #459403.
+    */
+   Balloon_ModuleCleanup();
+}
+
+
 /* Module information. */
 MODULE_AUTHOR("VMware, Inc.");
 MODULE_DESCRIPTION("VMware Memory Control Driver");
index b991edd7162768ce2ea1ed068a3fae4b46fc7054..ffbb93c1088311575ff4b409435c8368fe7fbc8a 100644 (file)
 #ifndef        OS_H
 #define        OS_H
 
+#include "vm_basic_types.h"
+#include "balloon_def.h"
+
 /*
  * Types
  */
 
 typedef void OSTimerHandler(void *clientData);
 typedef int  OSStatusHandler(char *buf, size_t size);
+typedef uintptr_t PageHandle;
+
+#define PAGE_HANDLE_INVALID 0
 
 /*
  * Operations
@@ -40,7 +46,7 @@ extern void OS_Init(const char *name,
                     const char *nameVerbose,
                     OSStatusHandler *handler);
 extern void OS_Cleanup(void);
-extern const char *OS_Identity(void);
+extern BalloonGuest OS_Identity(void);
 
 extern void OS_MemZero(void *ptr, size_t size);
 extern void OS_MemCopy(void *dest, const void *src, size_t size);
@@ -51,14 +57,12 @@ extern void OS_Free(void *ptr, size_t size);
 
 extern void OS_Yield(void);
 
-extern unsigned int OS_TimerHz(void);
-extern void OS_TimerInit(OSTimerHandler *handler, void *clientData, int period);
-extern void OS_TimerStart(void);
+extern Bool OS_TimerStart(OSTimerHandler *handler, void *clientData);
 extern void OS_TimerStop(void);
 
-extern unsigned int  OS_PredictMaxReservedPages(void);
-extern unsigned long OS_AddrToPPN(unsigned long addr);
-extern unsigned long OS_AllocReservedPage(int canSleep);
-extern void          OS_FreeReservedPage(unsigned long page);
+extern unsigned long OS_ReservedPageGetLimit(void);
+extern unsigned long OS_ReservedPageGetPPN(PageHandle handle);
+extern PageHandle    OS_ReservedPageAlloc(int canSleep);
+extern void          OS_ReservedPageFree(PageHandle handle);
 
 #endif  /* OS_H */
index 91212ec8fa036ccb365a6f85b8e463be8a9da713..283e791a527dd263ab597df995321442fffec057 100644 (file)
@@ -50,7 +50,6 @@ extern "C" {
  * Includes
  */
 
-#include "balloon_def.h"
 #include "os.h"
 #include "backdoor.h"
 #include "backdoor_balloon.h"
@@ -107,13 +106,14 @@ extern "C" {
  */
 
 typedef struct BalloonChunk {
-   unsigned long page[BALLOON_CHUNK_PAGES];
+   PageHandle page[BALLOON_CHUNK_PAGES];
    uint32 nextPage;
-   struct BalloonChunk *prev, *next;
+   struct BalloonChunk *prev;
+   struct BalloonChunk *next;
 } BalloonChunk;
 
 typedef struct {
-   unsigned long page[BALLOON_ERROR_PAGES];
+   PageHandle page[BALLOON_ERROR_PAGES];
    uint32 nextPage;
 } BalloonErrorPages;
 
@@ -148,30 +148,24 @@ typedef struct {
  */
 
 static Balloon globalBalloon;
+static Bool timerStarted;
 
 /*
  * Forward Declarations
  */
 
-static int BalloonGuestType(void);
-
-static unsigned long BalloonPrimAllocPage(BalloonPageAllocType canSleep);
-static void BalloonPrimFreePage(unsigned long page);
-
 static int  Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType);
 static int  Balloon_FreePage(Balloon *b, int monitorUnlock);
 static int  Balloon_AdjustSize(Balloon *b, uint32 target);
 static void Balloon_Reset(Balloon *b);
 
-static void Balloon_StartTimer(Balloon *b);
-static void Balloon_StopTimer(Balloon *b);
 static void BalloonTimerHandler(void *clientData);
 
 static int Balloon_MonitorStart(Balloon *b);
 static int Balloon_MonitorGuestType(Balloon *b);
 static int Balloon_MonitorGetTarget(Balloon *b, uint32 *nPages);
-static int Balloon_MonitorLockPage(Balloon *b, unsigned long addr);
-static int Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr);
+static int Balloon_MonitorLockPage(Balloon *b, PageHandle handle);
+static int Balloon_MonitorUnlockPage(Balloon *b, PageHandle handle);
 
 /*
  * Macros
@@ -253,7 +247,7 @@ BalloonProcRead(char *buf,      // OUT
    int len = 0;
    BalloonStats stats;
 
-   BalloonGetStats(&stats);
+   Balloon_GetStats(&stats);
 
    /* format size info */
    len += OS_Snprintf(buf + len, size - len,
@@ -307,138 +301,34 @@ BalloonProcRead(char *buf,      // OUT
  * Utility Operations
  */
 
-/*
- *----------------------------------------------------------------------
- *
- * AddrToPPN --
- *
- *      Return the physical page number corresponding to the specified
- *      kernel-mapped address.
- *
- * Results:
- *      Returns PPN for "addr".
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static inline unsigned long
-AddrToPPN(unsigned long addr)
-{
-   return OS_AddrToPPN(addr);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * BalloonPrimAllocPage --
- *
- *      Attempts to allocate and reserve a physical page.
- *
- *      If canSleep == 1, i.e., BALLOON_PAGE_ALLOC_CANSLEEP:
- *         The allocation can wait (sleep) for page writeout (swap)
- *         by the guest.
- *      otherwise canSleep == 0, i.e., BALLOON_PAGE_ALLOC_NOSLEEP:
- *         If allocation of a page requires disk writeout, then
- *         just fail. DON'T sleep.
- *
- * Results:
- *      Returns the physical address of the allocated page, or 0 if error.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static unsigned long
-BalloonPrimAllocPage(BalloonPageAllocType canSleep)
-{
-   return OS_AllocReservedPage(canSleep);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * BalloonPrimFreePage --
- *
- *      Unreserves and deallocates specified physical page.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static void
-BalloonPrimFreePage(unsigned long page)
-{
-   return OS_FreeReservedPage(page);
-}
 
 /*
  *----------------------------------------------------------------------
  *
- * BalloonGuestType --
+ * Balloon_GetStats --
  *
- *      Return balloon guest OS identifier obtained by parsing
- *      system-dependent identity string.
+ *      Returns information about balloon state, including the current and
+ *      target size, rates for allocating and freeing pages, and statistics
+ *      about past activity.
  *
  * Results:
- *      Returns one of BALLOON_GUEST_{LINUX,BSD,SOLARIS,UNKNOWN}.
+ *      None
  *
  * Side effects:
- *      None.
+ *      None
  *
  *----------------------------------------------------------------------
  */
-static int
-BalloonGuestType(void)
-{
-   const char *identity;
-
-   /* obtain OS identify string */
-   identity = OS_Identity();
-
-   /* unknown if not specified */
-   if (identity == NULL) {
-      return(BALLOON_GUEST_UNKNOWN);
-   }
 
-   /* classify based on first letter (avoid defining strcmp) */
-   switch (identity[0]) {
-   case 'l':
-   case 'L':
-      return BALLOON_GUEST_LINUX;
-   case 'b':
-   case 'B':
-      return BALLOON_GUEST_BSD;
-   case 's':
-   case 'S':
-      return BALLOON_GUEST_SOLARIS;
-   default:
-      break;
-   }
-
-   /* unknown */
-   return BALLOON_GUEST_UNKNOWN;
-}
-
-/*
- * Returns information about balloon state, including the current and
- * target size, rates for allocating and freeing pages, and statistics
- * about past activity.
- */
-void BalloonGetStats(BalloonStats *stats)
+void
+Balloon_GetStats(BalloonStats *stats) // OUT
 {
    Balloon *b = &globalBalloon;
 
    /*
     * Copy statistics out of global structure.
     */
-   OS_MemCopy(stats, &b->stats, sizeof (BalloonStats));
+   OS_MemCopy(stats, &b->stats, sizeof *stats);
 
    /*
     * Fill in additional information about size and rates, which is
@@ -450,9 +340,6 @@ void BalloonGetStats(BalloonStats *stats)
    stats->rateFree = b->rateFree;
 }
 
-/*
- * BalloonChunk Operations
- */
 
 /*
  *----------------------------------------------------------------------
@@ -490,7 +377,6 @@ BalloonChunk_Create(void)
    /* initialize */
    OS_MemZero(chunk, sizeof *chunk);
 
-   /* everything OK */
    return chunk;
 }
 
@@ -550,8 +436,7 @@ Balloon_Init(Balloon *b)
    /* initialize reset flag */
    b->resetFlag = 1;
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
 /*
@@ -641,7 +526,7 @@ static void
 BalloonTimerHandler(void *clientData)
 {
    Balloon *b = (Balloon *) clientData;
-   uint32 target;
+   uint32 target = 0; // Silence compiler warning.
    int status;
 
    /* update stats */
@@ -667,48 +552,6 @@ BalloonTimerHandler(void *clientData)
    }
 }
 
-/*
- *----------------------------------------------------------------------
- *
- * Balloon_StartTimer --
- *
- *      Schedules next execution of balloon timer handler.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static void
-Balloon_StartTimer(Balloon *b)
-{
-   OS_TimerStart();
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Balloon_StopTimer --
- *
- *      Deschedules balloon timer handler.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static void
-Balloon_StopTimer(Balloon *b)
-{
-   OS_TimerStop();
-}
-
 
 /*
  *----------------------------------------------------------------------
@@ -765,8 +608,8 @@ Balloon_ErrorPagesFree(Balloon *b)
 
    /* free all non-balloonable "error" pages */
    for (i = 0; i < b->errors.nextPage; i++) {
-      BalloonPrimFreePage(b->errors.page[i]);
-      b->errors.page[i] = 0;
+      OS_ReservedPageFree(b->errors.page[i]);
+      b->errors.page[i] = PAGE_HANDLE_INVALID;
       STATS_INC(b->stats.primErrorPageFree);
    }
    b->errors.nextPage = 0;
@@ -792,7 +635,7 @@ static int
 Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
 {
    BalloonChunk *chunk;
-   unsigned long page;
+   PageHandle page;
    int status;
 
  retry:
@@ -800,21 +643,32 @@ Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
    /* allocate page, fail if unable */
    STATS_INC(b->stats.primAlloc[allocType]);
 
-   page = BalloonPrimAllocPage(allocType);
+   /*
+    * Attempts to allocate and reserve a physical page.
+    *
+    * If canSleep == 1, i.e., BALLOON_PAGE_ALLOC_CANSLEEP:
+    *      The allocation can wait (sleep) for page writeout (swap) by the guest.
+    * otherwise canSleep == 0, i.e., BALLOON_PAGE_ALLOC_NOSLEEP:
+    *      If allocation of a page requires disk writeout, then just fail. DON'T sleep.
+    *
+    * Returns the physical address of the allocated page, or 0 if error.
+    */
+   page = OS_ReservedPageAlloc(allocType);
 
-   if (page == 0) {
+   if (page == PAGE_HANDLE_INVALID) {
       STATS_INC(b->stats.primAllocFail[allocType]);
-      return(BALLOON_PAGE_ALLOC_FAILURE);
+      return BALLOON_PAGE_ALLOC_FAILURE;
    }
 
    /* find chunk with space, create if necessary */
    chunk = b->chunks;
    if ((chunk == NULL) || (chunk->nextPage >= BALLOON_CHUNK_PAGES)) {
       /* create new chunk */
-      if ((chunk = BalloonChunk_Create()) == NULL) {
+      chunk = BalloonChunk_Create();
+      if (chunk == NULL) {
          /* reclaim storage, fail */
-         BalloonPrimFreePage(page);
-         return(BALLOON_PAGE_ALLOC_FAILURE);
+         OS_ReservedPageFree(page);
+         return BALLOON_PAGE_ALLOC_FAILURE;
       }
       BalloonChunk_Insert(&b->chunks, chunk);
 
@@ -832,8 +686,8 @@ Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
       }
 
       /* reclaim storage, fail */
-      BalloonPrimFreePage(page);
-      return(status);
+      OS_ReservedPageFree(page);
+      return status;
    }
 
    /* track allocated page */
@@ -843,8 +697,7 @@ Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
    /* update balloon size */
    b->nPages++;
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
 /*
@@ -868,7 +721,7 @@ static int
 Balloon_FreePage(Balloon *b, int monitorUnlock)
 {
    BalloonChunk *chunk;
-   unsigned long page;
+   PageHandle page;
    int status;
 
    chunk = b->chunks;
@@ -903,7 +756,7 @@ Balloon_FreePage(Balloon *b, int monitorUnlock)
    }
 
    /* deallocate page */
-   BalloonPrimFreePage(page);
+   OS_ReservedPageFree(page);
    STATS_INC(b->stats.primFree);
 
    /* update balloon size */
@@ -919,8 +772,7 @@ Balloon_FreePage(Balloon *b, int monitorUnlock)
       b->nChunks--;
    }
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
 /*
@@ -989,6 +841,7 @@ BalloonIncreaseRateAlloc(Balloon *b, uint32 nAlloc)
    }
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1004,6 +857,7 @@ BalloonIncreaseRateAlloc(Balloon *b, uint32 nAlloc)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 BalloonInflate(Balloon *b, uint32 target)
 {
@@ -1128,6 +982,7 @@ BalloonInflate(Balloon *b, uint32 target)
    return(BALLOON_SUCCESS);
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1143,6 +998,7 @@ BalloonInflate(Balloon *b, uint32 target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 BalloonDeflate(Balloon *b, uint32 target)
 {
@@ -1169,10 +1025,10 @@ BalloonDeflate(Balloon *b, uint32 target)
                         BALLOON_RATE_FREE_MAX);
    }
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1189,6 +1045,7 @@ BalloonDeflate(Balloon *b, uint32 target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 Balloon_AdjustSize(Balloon *b, uint32 target)
 {
@@ -1230,6 +1087,7 @@ Balloon_AdjustSize(Balloon *b, uint32 target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 Balloon_MonitorStart(Balloon *b)
 {
@@ -1253,10 +1111,10 @@ Balloon_MonitorStart(Balloon *b)
       STATS_INC(b->stats.startFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1272,15 +1130,20 @@ Balloon_MonitorStart(Balloon *b)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 Balloon_MonitorGuestType(Balloon *b)
 {
    uint32 status, target;
+   BalloonGuest identity;
    Backdoor_proto bp;
 
+   identity = OS_Identity();
+   ASSERT(identity == (uint32) identity);
+
    /* prepare backdoor args */
    bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_GUEST_ID;
-   bp.in.size = BalloonGuestType();
+   bp.in.size = identity;
 
    /* invoke backdoor */
    Backdoor_Balloon(&bp);
@@ -1300,10 +1163,10 @@ Balloon_MonitorGuestType(Balloon *b)
       STATS_INC(b->stats.guestTypeFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1315,7 +1178,7 @@ Balloon_MonitorGuestType(Balloon *b)
  *      Predicts the maximum achievable balloon size and sends it
  *      to vmm => vmkernel via vEbx register.
  *
- *      OS_PredictMaxReservedPages() returns either predicted max balloon
+ *      OS_ReservedPageGetLimit() returns either predicted max balloon
  *      pages or BALLOON_MAX_SIZE_USE_CONFIG. In the later scenario,
  *      vmkernel uses global config options for determining a guest's max
  *      balloon size. Note that older vmballoon drivers set vEbx to
@@ -1331,15 +1194,27 @@ Balloon_MonitorGuestType(Balloon *b)
  *
  *----------------------------------------------------------------------
  */
+
 static int
-Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
+Balloon_MonitorGetTarget(Balloon *b,     // IN
+                         uint32 *target) // OUT
 {
    Backdoor_proto bp;
+   unsigned long limit;
+   uint32 limit32;
    uint32 status;
 
+   limit = OS_ReservedPageGetLimit();
+
+   /* Ensure limit fits in 32-bits */
+   limit32 = (uint32)limit;
+   if (limit32 != limit) {
+      return BALLOON_FAILURE;
+   }
+
    /* prepare backdoor args */
    bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_TARGET;
-   bp.in.size = OS_PredictMaxReservedPages();
+   bp.in.size = limit;
 
    /* invoke backdoor */
    Backdoor_Balloon(&bp);
@@ -1359,17 +1234,17 @@ Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
       STATS_INC(b->stats.targetFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
  * Balloon_MonitorLockPage --
  *
- *      Attempts to contact monitor and add PPN containing "addr"
- *      to set of "balloon locked" pages.
+ *      Attempts to contact monitor and add PPN corresponding to
+ *      the page handle to set of "balloon locked" pages.
  *
  * Results:
  *      Returns BALLOON_SUCCESS if successful, otherwise error code.
@@ -1379,16 +1254,17 @@ Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
-Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
+Balloon_MonitorLockPage(Balloon *b,        // IN
+                        PageHandle handle) // IN
 {
    unsigned long ppn;
    uint32 ppn32;
    uint32 status, target;
    Backdoor_proto bp;
 
-   /* convert kernel-mapped "physical addr" to ppn */
-   ppn = AddrToPPN(addr);
+   ppn = OS_ReservedPageGetPPN(handle);
 
    /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
    ppn32 = (uint32)ppn;
@@ -1418,8 +1294,7 @@ Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
       STATS_INC(b->stats.lockFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
 /*
@@ -1427,8 +1302,8 @@ Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
  *
  * Balloon_MonitorUnlockPage --
  *
- *      Attempts to contact monitor and remove PPN containing "addr"
- *      from set of "balloon locked" pages.
+ *      Attempts to contact monitor and remove PPN corresponding to
+ *      the page handle from set of "balloon locked" pages.
  *
  * Results:
  *      Returns BALLOON_SUCCESS if successful, otherwise error code.
@@ -1439,15 +1314,15 @@ Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
  *----------------------------------------------------------------------
  */
 static int
-Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr)
+Balloon_MonitorUnlockPage(Balloon *b,        // IN
+                          PageHandle handle) // IN
 {
    unsigned long ppn;
    uint32 ppn32;
    uint32 status, target;
    Backdoor_proto bp;
 
-   /* convert kernel-mapped "physical addr" to ppn */
-   ppn = AddrToPPN(addr);
+   ppn = OS_ReservedPageGetPPN(handle);
 
    /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
    ppn32 = (uint32)ppn;
@@ -1477,23 +1352,36 @@ Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr)
       STATS_INC(b->stats.unlockFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
- * Module Operations
+ *----------------------------------------------------------------------
+ *
+ * Balloon_ModuleInit --
+ *
+ *      Startup the balloon module.
+ *
+ * Results:
+ *      On success: BALLOON_SUCCESS
+ *      On failure: BALLOON_FAILURE
+ *
+ * Side effects:
+ *      None
+ *
+ *----------------------------------------------------------------------
  */
 
-static int
-BalloonModuleInit(void)
+int
+Balloon_ModuleInit(void)
 {
    static int initialized = 0;
    Balloon *b = &globalBalloon;
 
    /* initialize only once */
    if (initialized++) {
-      return(BALLOON_FAILURE);
+      return BALLOON_FAILURE;
    }
 
    /* os-specific initialization */
@@ -1503,43 +1391,54 @@ BalloonModuleInit(void)
    Balloon_Init(b);
 
    /* start timer */
-   OS_TimerInit(BalloonTimerHandler, b, OS_TimerHz());
-   Balloon_StartTimer(b);
+   timerStarted = FALSE;
+   if (!OS_TimerStart(BalloonTimerHandler, b)) {
+      Balloon_ModuleCleanup();
+      return BALLOON_FAILURE;
+   }
 
-   /* everything OK */
+   timerStarted = TRUE;
    return BALLOON_SUCCESS;
 }
 
-static void
-BalloonModuleCleanup(void)
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_ModuleCleanup --
+ *
+ *      Terminate and cleanup the balloon module.
+ *
+ * Results:
+ *      None
+ *
+ * Side effects:
+ *      None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Balloon_ModuleCleanup(void)
 {
    Balloon *b = &globalBalloon;
 
    /* stop timer */
-   Balloon_StopTimer(b);
+   if (timerStarted) {
+      OS_TimerStop();
+   }
 
    /*
     * Deallocate all reserved memory, and reset connection with monitor.
     * Reset connection before deallocating memory to avoid potential for
     * additional spurious resets from guest touching deallocated pages.
     */
-   (void) Balloon_MonitorStart(b);
+   Balloon_MonitorStart(b);
    Balloon_Deallocate(b);
 
    /* os-specific cleanup */
    OS_Cleanup();
 }
 
-int init_module(void)
-{
-   return(BalloonModuleInit());
-}
-
-void cleanup_module(void)
-{
-   BalloonModuleCleanup();
-}
-
 #ifdef __cplusplus
 }
 #endif
index a31c4b369fe09cf883de94ce826725bf4489fcd4..caebe45dfb383ff916fa09b5ae6f28a8ef9812f3 100644 (file)
@@ -74,8 +74,9 @@ typedef struct {
  * Operations
  */
 
-extern void BalloonGetStats(BalloonStats *stats);
-extern int  init_module(void);
-extern void cleanup_module(void);
+extern int  Balloon_ModuleInit(void);
+extern void Balloon_ModuleCleanup(void);
+
+extern void Balloon_GetStats(BalloonStats *stats);
 
 #endif /* VMBALLOON_H */
index ce3239c155695be9b9f39c3fdffdfc23432dcc17..8132c96ddce0aee6654de14988c7970200980ff7 100644 (file)
@@ -80,7 +80,6 @@ SOLHGFS_LIB_OBJS += hgfsBd.o
 SOLHGFS_LIB_OBJS += hgfsEscape.o
 SOLHGFS_LIB_OBJS += hgfsUtil.o
 SOLHGFS_LIB_OBJS += message.o
-SOLHGFS_LIB_OBJS += messageBackdoor.o
 SOLHGFS_LIB_OBJS += rpcout.o
 SOLHGFS_LIB_OBJS += sha1.o
 
index f5cdec321b8c9567b4869cd4b1caaf42eb7ae2af..33fb4504aa03e6ef65d59dbe69f23b7c41dae8f2 100644 (file)
 /* use config value for max balloon size */
 #define BALLOON_MAX_SIZE_USE_CONFIG     (0)
 
-/* guest identities */
-#define BALLOON_GUEST_UNKNOWN           (0)
-#define BALLOON_GUEST_LINUX             (1)
-#define BALLOON_GUEST_BSD               (2)
-#define BALLOON_GUEST_WINDOWS_NT4       (3)
-#define BALLOON_GUEST_WINDOWS_NT5       (4)
-#define BALLOON_GUEST_SOLARIS           (5)
+/*
+ * Guest identities
+ *
+ *      Note : all values should fit in 32 bits
+ */
+typedef enum {
+   BALLOON_GUEST_UNKNOWN     = 0,
+   BALLOON_GUEST_LINUX       = 1,
+   BALLOON_GUEST_BSD         = 2,
+   BALLOON_GUEST_WINDOWS_NT4 = 3,
+   BALLOON_GUEST_WINDOWS_NT5 = 4,
+   BALLOON_GUEST_SOLARIS     = 5,
+   BALLOON_GUEST_MACOS       = 6,
+} BalloonGuest;
 
 /* error codes */
 #define BALLOON_SUCCESS                 (0)
index f3badc8423ee8da55480a1a06790dda5bf708e0e..ab214cebc3439d331e2e18319ecd64db607fc597 100644 (file)
@@ -41,6 +41,7 @@
 #include <sys/ksynch.h>
 
 #include "os.h"
+#include "vmballoon.h"
 #include "vm_assert.h"
 #include "balloon_def.h"
 #include "vmballoon_kstats.h"
@@ -234,33 +235,77 @@ OS_Snprintf(char *buf,          // OUT
    return 0;
 }
 
+
 /*
- * System-Dependent Operations
+ *-----------------------------------------------------------------------------
+ *
+ * OS_Identity --
+ *
+ *      Returns an identifier for the guest OS family.
+ *
+ * Results:
+ *      The identifier
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
  */
 
-const char *
+BalloonGuest
 OS_Identity(void)
 {
-   return "solaris";
+   return BALLOON_GUEST_SOLARIS;
 }
 
+
 /*
- * Predict the maximum achievable balloon size.
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageGetLimit --
  *
- * Currently we just return the total memory pages.
+ *      Predict the maximum achievable balloon size.
+ *
+ * Results:
+ *      Currently we just return the total memory pages.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
  */
-unsigned int
-OS_PredictMaxReservedPages(void)
+
+unsigned long
+OS_ReservedPageGetLimit(void)
 {
-   return(maxmem);
+   return maxmem;
 }
 
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageGetPPN --
+ *
+ *      Convert a page handle (of a physical page previously reserved with
+ *      OS_ReservedPageAlloc()) to a ppn.
+ *
+ * Results:
+ *      The ppn.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
 unsigned long
-OS_AddrToPPN(unsigned long addr)
+OS_ReservedPageGetPPN(PageHandle handle) // IN: A valid page handle
 {
-   return (ulong_t)page_pptonum(((os_page *)addr)->pp);
+   return page_pptonum(((os_page *)handle)->pp);
 }
 
+
 /*
  * NOTE: cast id before shifting to avoid overflow (id_t is 32 bits,
  * u_offset_t is 64 bits).  Also, can't use ptob because it will
@@ -270,20 +315,38 @@ OS_AddrToPPN(unsigned long addr)
 #define idtooff(id)    ((u_offset_t)(id) << PAGESHIFT)
 #define offtoid(off)   ((id_t)((off) >> PAGESHIFT))
 
+
 /*
- * This is a bit ugly.  In order to allocate a page, we need a vnode to
- * hang it from and a unique offset within that vnode.  We do this by
- * using our own vnode (used only to hang pages from) and allocating
- * offsets by use of the id space allocator.  The id allocator hands
- * us back unique integers between 0 and INT_MAX; we can then use those
- * as page indices into our fake vnode space.
- *
- * Future versions of Solaris will have a devmap_pmem_alloc/free
- * interface for allocating physical pages that may allow us to
- * eliminate some of this.
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageAlloc --
+ *
+ *      Reserve a physical page for the exclusive use of this driver.
+ *
+ *      This is a bit ugly.  In order to allocate a page, we need a vnode to
+ *      hang it from and a unique offset within that vnode.  We do this by
+ *      using our own vnode (used only to hang pages from) and allocating
+ *      offsets by use of the id space allocator.  The id allocator hands
+ *      us back unique integers between 0 and INT_MAX; we can then use those
+ *      as page indices into our fake vnode space.
+ *
+ *      Future versions of Solaris will have a devmap_pmem_alloc/free
+ *      interface for allocating physical pages that may allow us to
+ *      eliminate some of this.
+ *
+ * Results:
+ *      On success: A valid page handle that can be passed to OS_ReservedPageGetPPN()
+ *                  or OS_ReservedPageFree().
+ *      On failure: PAGE_HANDLE_INVALID
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
  */
-unsigned long
-OS_AllocReservedPage(int canSleep)
+
+PageHandle
+OS_ReservedPageAlloc(int canSleep) // IN
 {
    os_state *state = &global_state;
    page_t *pp;
@@ -299,17 +362,17 @@ OS_AllocReservedPage(int canSleep)
     */
    flags = canSleep ? KM_SLEEP : KM_NOSLEEP;
    if (!page_resv(1, flags))
-      return 0;                /* no space! */
+      return PAGE_HANDLE_INVALID; /* no space! */
 
    /*
     * Allocating space for os_page early simplifies error handling.
     */
    if ((page = kmem_alloc(sizeof (os_page), flags)) == NULL) {
       page_unresv(1);
-      return 0;
+      return PAGE_HANDLE_INVALID;
    }
 
-   /* 
+   /*
     * Construct an offset for page_create.
     */
    off = idtooff(id_alloc(idp));
@@ -341,14 +404,31 @@ OS_AllocReservedPage(int canSleep)
       page = NULL;
    }
 
-   return (unsigned long)page;
+   return (PageHandle)page;
 }
 
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_ReservedPageFree --
+ *
+ *      Unreserve a physical page previously reserved with OS_ReservedPageAlloc().
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
 void
-OS_FreeReservedPage(unsigned long addr)
+OS_ReservedPageFree(PageHandle handle) // IN: A valid page handle
 {
    os_state *state = &global_state;
-   os_page *page = (os_page *)addr;
+   os_page *page = (os_page *)handle;
    page_t *pp = page->pp;
    u_offset_t off = page->offset;
    id_space_t *idp = state->id_space;
@@ -359,6 +439,7 @@ OS_FreeReservedPage(unsigned long addr)
    kmem_free(page, sizeof (os_page));
 }
 
+
 /*
  * Worker thread that periodically calls the timer handler.  This is
  * executed by a user context thread so that it can block waiting for
@@ -393,34 +474,61 @@ static int os_worker(void)
    return 0;                   /* normal termination */
 }
 
+
 /*
- * Initialize timer data.
+ *-----------------------------------------------------------------------------
+ *
+ * OS_TimerStart --
+ *
+ *      Setup the timer callback function, then start it.
+ *
+ * Results:
+ *      Always TRUE, cannot fail.
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
  */
-void
-OS_TimerInit(OSTimerHandler *handler, // IN
-             void *clientData,        // IN
-             int period)              // IN
+
+Bool
+OS_TimerStart(OSTimerHandler *handler, // IN
+              void *clientData)        // IN
 {
    os_timer *t = &global_state.timer;
 
+   /* setup the timer structure */
    t->id = 0;
    t->handler = handler;
    t->data = clientData;
-   t->period = period;
-   t->stop = 0;
+   t->period = drv_usectohz(ONE_SECOND_IN_MICROSECONDS);
 
    mutex_init(&t->lock, NULL, MUTEX_DRIVER, NULL);
    cv_init(&t->cv, NULL, CV_DRIVER, NULL);
-}
-
-void
-OS_TimerStart(void)
-{
-   os_timer *t = &global_state.timer;
 
+   /* start the timer */
    t->stop = 0;
+
+   return TRUE;
 }
 
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OS_TimerStop --
+ *
+ *      Stop the timer.
+ *
+ * Results:
+ *      None
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
 void
 OS_TimerStop(void)
 {
@@ -445,12 +553,6 @@ static void os_timer_cleanup(void)
    cv_destroy(&timer->cv);
 }
 
-unsigned int
-OS_TimerHz(void)
-{
-   return drv_usectohz(ONE_SECOND_IN_MICROSECONDS);
-}
-
 
 /*
  *-----------------------------------------------------------------------------
@@ -517,12 +619,6 @@ void OS_Cleanup(void)
    cmn_err(CE_CONT, "!%s unloaded\n", state->name_verbose);
 }
 
-/*
- * Module Load/Unload Operations
- */
-
-extern int  init_module(void);
-extern void cleanup_module(void);
 
 /*
  * Device configuration entry points
@@ -650,10 +746,13 @@ int _init(void)
 {
    int error;
 
-   if (init_module() != BALLOON_SUCCESS)
-      return EINVAL;
-   if ((error = mod_install(&vmmodlinkage)) != 0)
-      cleanup_module();
+   if (Balloon_ModuleInit() != BALLOON_SUCCESS) {
+      return EAGAIN;
+   }
+   error = mod_install(&vmmodlinkage);
+   if (error != 0) {
+      Balloon_ModuleCleanup();
+   }
    return error;
 }
 
@@ -670,8 +769,10 @@ int _fini(void)
     * Check if the module is busy (i.e., there's a worker thread active)
     * before cleaning up.
     */
-   if ((error = mod_remove(&vmmodlinkage)) == 0)
-      cleanup_module();
+   error = mod_remove(&vmmodlinkage);
+   if (error == 0) {
+      Balloon_ModuleCleanup();
+   }
    return error;
 }
 
index 39d5d2a2500e12a74cbf39d2781095c92d1ddc2e..2c6933aaaef13fc91f59b6367870e683a5c9d9ac 100644 (file)
 #ifndef        OS_H
 #define        OS_H
 
+#include "vm_basic_types.h"
+#include "balloon_def.h"
+
 /*
  * Types
  */
 
 typedef void OSTimerHandler(void *clientData);
 typedef int  OSStatusHandler(char *buf, size_t size);
+typedef uintptr_t PageHandle;
+
+#define PAGE_HANDLE_INVALID 0
 
 /*
  * Operations
@@ -38,7 +44,7 @@ extern void OS_Init(const char *name,
                     const char *nameVerbose,
                     OSStatusHandler *handler);
 extern void OS_Cleanup(void);
-extern const char *OS_Identity(void);
+extern BalloonGuest OS_Identity(void);
 
 extern void OS_MemZero(void *ptr, size_t size);
 extern void OS_MemCopy(void *dest, const void *src, size_t size);
@@ -49,14 +55,12 @@ extern void OS_Free(void *ptr, size_t size);
 
 extern void OS_Yield(void);
 
-extern unsigned int OS_TimerHz(void);
-extern void OS_TimerInit(OSTimerHandler *handler, void *clientData, int period);
-extern void OS_TimerStart(void);
+extern Bool OS_TimerStart(OSTimerHandler *handler, void *clientData);
 extern void OS_TimerStop(void);
 
-extern unsigned int  OS_PredictMaxReservedPages(void);
-extern unsigned long OS_AddrToPPN(unsigned long addr);
-extern unsigned long OS_AllocReservedPage(int canSleep);
-extern void          OS_FreeReservedPage(unsigned long page);
+extern unsigned long OS_ReservedPageGetLimit(void);
+extern unsigned long OS_ReservedPageGetPPN(PageHandle handle);
+extern PageHandle    OS_ReservedPageAlloc(int canSleep);
+extern void          OS_ReservedPageFree(PageHandle handle);
 
 #endif  /* OS_H */
index f2f055878e6ce13699ffaf34c7c29fdf7efb7bc6..d74ab20244a9c2d8d35d2e9e8f2e1f06b8bc6cf5 100644 (file)
@@ -48,7 +48,6 @@ extern "C" {
  * Includes
  */
 
-#include "balloon_def.h"
 #include "os.h"
 #include "backdoor.h"
 #include "backdoor_balloon.h"
@@ -105,13 +104,14 @@ extern "C" {
  */
 
 typedef struct BalloonChunk {
-   unsigned long page[BALLOON_CHUNK_PAGES];
+   PageHandle page[BALLOON_CHUNK_PAGES];
    uint32 nextPage;
-   struct BalloonChunk *prev, *next;
+   struct BalloonChunk *prev;
+   struct BalloonChunk *next;
 } BalloonChunk;
 
 typedef struct {
-   unsigned long page[BALLOON_ERROR_PAGES];
+   PageHandle page[BALLOON_ERROR_PAGES];
    uint32 nextPage;
 } BalloonErrorPages;
 
@@ -146,30 +146,24 @@ typedef struct {
  */
 
 static Balloon globalBalloon;
+static Bool timerStarted;
 
 /*
  * Forward Declarations
  */
 
-static int BalloonGuestType(void);
-
-static unsigned long BalloonPrimAllocPage(BalloonPageAllocType canSleep);
-static void BalloonPrimFreePage(unsigned long page);
-
 static int  Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType);
 static int  Balloon_FreePage(Balloon *b, int monitorUnlock);
 static int  Balloon_AdjustSize(Balloon *b, uint32 target);
 static void Balloon_Reset(Balloon *b);
 
-static void Balloon_StartTimer(Balloon *b);
-static void Balloon_StopTimer(Balloon *b);
 static void BalloonTimerHandler(void *clientData);
 
 static int Balloon_MonitorStart(Balloon *b);
 static int Balloon_MonitorGuestType(Balloon *b);
 static int Balloon_MonitorGetTarget(Balloon *b, uint32 *nPages);
-static int Balloon_MonitorLockPage(Balloon *b, unsigned long addr);
-static int Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr);
+static int Balloon_MonitorLockPage(Balloon *b, PageHandle handle);
+static int Balloon_MonitorUnlockPage(Balloon *b, PageHandle handle);
 
 /*
  * Macros
@@ -251,7 +245,7 @@ BalloonProcRead(char *buf,      // OUT
    int len = 0;
    BalloonStats stats;
 
-   BalloonGetStats(&stats);
+   Balloon_GetStats(&stats);
 
    /* format size info */
    len += OS_Snprintf(buf + len, size - len,
@@ -305,138 +299,34 @@ BalloonProcRead(char *buf,      // OUT
  * Utility Operations
  */
 
-/*
- *----------------------------------------------------------------------
- *
- * AddrToPPN --
- *
- *      Return the physical page number corresponding to the specified
- *      kernel-mapped address.
- *
- * Results:
- *      Returns PPN for "addr".
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static inline unsigned long
-AddrToPPN(unsigned long addr)
-{
-   return OS_AddrToPPN(addr);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * BalloonPrimAllocPage --
- *
- *      Attempts to allocate and reserve a physical page.
- *
- *      If canSleep == 1, i.e., BALLOON_PAGE_ALLOC_CANSLEEP:
- *         The allocation can wait (sleep) for page writeout (swap)
- *         by the guest.
- *      otherwise canSleep == 0, i.e., BALLOON_PAGE_ALLOC_NOSLEEP:
- *         If allocation of a page requires disk writeout, then
- *         just fail. DON'T sleep.
- *
- * Results:
- *      Returns the physical address of the allocated page, or 0 if error.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static unsigned long
-BalloonPrimAllocPage(BalloonPageAllocType canSleep)
-{
-   return OS_AllocReservedPage(canSleep);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * BalloonPrimFreePage --
- *
- *      Unreserves and deallocates specified physical page.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static void
-BalloonPrimFreePage(unsigned long page)
-{
-   return OS_FreeReservedPage(page);
-}
 
 /*
  *----------------------------------------------------------------------
  *
- * BalloonGuestType --
+ * Balloon_GetStats --
  *
- *      Return balloon guest OS identifier obtained by parsing
- *      system-dependent identity string.
+ *      Returns information about balloon state, including the current and
+ *      target size, rates for allocating and freeing pages, and statistics
+ *      about past activity.
  *
  * Results:
- *      Returns one of BALLOON_GUEST_{LINUX,BSD,SOLARIS,UNKNOWN}.
+ *      None
  *
  * Side effects:
- *      None.
+ *      None
  *
  *----------------------------------------------------------------------
  */
-static int
-BalloonGuestType(void)
-{
-   const char *identity;
-
-   /* obtain OS identify string */
-   identity = OS_Identity();
-
-   /* unknown if not specified */
-   if (identity == NULL) {
-      return(BALLOON_GUEST_UNKNOWN);
-   }
 
-   /* classify based on first letter (avoid defining strcmp) */
-   switch (identity[0]) {
-   case 'l':
-   case 'L':
-      return BALLOON_GUEST_LINUX;
-   case 'b':
-   case 'B':
-      return BALLOON_GUEST_BSD;
-   case 's':
-   case 'S':
-      return BALLOON_GUEST_SOLARIS;
-   default:
-      break;
-   }
-
-   /* unknown */
-   return BALLOON_GUEST_UNKNOWN;
-}
-
-/*
- * Returns information about balloon state, including the current and
- * target size, rates for allocating and freeing pages, and statistics
- * about past activity.
- */
-void BalloonGetStats(BalloonStats *stats)
+void
+Balloon_GetStats(BalloonStats *stats) // OUT
 {
    Balloon *b = &globalBalloon;
 
    /*
     * Copy statistics out of global structure.
     */
-   OS_MemCopy(stats, &b->stats, sizeof (BalloonStats));
+   OS_MemCopy(stats, &b->stats, sizeof *stats);
 
    /*
     * Fill in additional information about size and rates, which is
@@ -448,9 +338,6 @@ void BalloonGetStats(BalloonStats *stats)
    stats->rateFree = b->rateFree;
 }
 
-/*
- * BalloonChunk Operations
- */
 
 /*
  *----------------------------------------------------------------------
@@ -488,7 +375,6 @@ BalloonChunk_Create(void)
    /* initialize */
    OS_MemZero(chunk, sizeof *chunk);
 
-   /* everything OK */
    return chunk;
 }
 
@@ -548,8 +434,7 @@ Balloon_Init(Balloon *b)
    /* initialize reset flag */
    b->resetFlag = 1;
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
 /*
@@ -639,7 +524,7 @@ static void
 BalloonTimerHandler(void *clientData)
 {
    Balloon *b = (Balloon *) clientData;
-   uint32 target;
+   uint32 target = 0; // Silence compiler warning.
    int status;
 
    /* update stats */
@@ -665,48 +550,6 @@ BalloonTimerHandler(void *clientData)
    }
 }
 
-/*
- *----------------------------------------------------------------------
- *
- * Balloon_StartTimer --
- *
- *      Schedules next execution of balloon timer handler.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static void
-Balloon_StartTimer(Balloon *b)
-{
-   OS_TimerStart();
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Balloon_StopTimer --
- *
- *      Deschedules balloon timer handler.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-static void
-Balloon_StopTimer(Balloon *b)
-{
-   OS_TimerStop();
-}
-
 
 /*
  *----------------------------------------------------------------------
@@ -763,8 +606,8 @@ Balloon_ErrorPagesFree(Balloon *b)
 
    /* free all non-balloonable "error" pages */
    for (i = 0; i < b->errors.nextPage; i++) {
-      BalloonPrimFreePage(b->errors.page[i]);
-      b->errors.page[i] = 0;
+      OS_ReservedPageFree(b->errors.page[i]);
+      b->errors.page[i] = PAGE_HANDLE_INVALID;
       STATS_INC(b->stats.primErrorPageFree);
    }
    b->errors.nextPage = 0;
@@ -790,7 +633,7 @@ static int
 Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
 {
    BalloonChunk *chunk;
-   unsigned long page;
+   PageHandle page;
    int status;
 
  retry:
@@ -798,21 +641,32 @@ Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
    /* allocate page, fail if unable */
    STATS_INC(b->stats.primAlloc[allocType]);
 
-   page = BalloonPrimAllocPage(allocType);
+   /*
+    * Attempts to allocate and reserve a physical page.
+    *
+    * If canSleep == 1, i.e., BALLOON_PAGE_ALLOC_CANSLEEP:
+    *      The allocation can wait (sleep) for page writeout (swap) by the guest.
+    * otherwise canSleep == 0, i.e., BALLOON_PAGE_ALLOC_NOSLEEP:
+    *      If allocation of a page requires disk writeout, then just fail. DON'T sleep.
+    *
+    * Returns the physical address of the allocated page, or 0 if error.
+    */
+   page = OS_ReservedPageAlloc(allocType);
 
-   if (page == 0) {
+   if (page == PAGE_HANDLE_INVALID) {
       STATS_INC(b->stats.primAllocFail[allocType]);
-      return(BALLOON_PAGE_ALLOC_FAILURE);
+      return BALLOON_PAGE_ALLOC_FAILURE;
    }
 
    /* find chunk with space, create if necessary */
    chunk = b->chunks;
    if ((chunk == NULL) || (chunk->nextPage >= BALLOON_CHUNK_PAGES)) {
       /* create new chunk */
-      if ((chunk = BalloonChunk_Create()) == NULL) {
+      chunk = BalloonChunk_Create();
+      if (chunk == NULL) {
          /* reclaim storage, fail */
-         BalloonPrimFreePage(page);
-         return(BALLOON_PAGE_ALLOC_FAILURE);
+         OS_ReservedPageFree(page);
+         return BALLOON_PAGE_ALLOC_FAILURE;
       }
       BalloonChunk_Insert(&b->chunks, chunk);
 
@@ -830,8 +684,8 @@ Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
       }
 
       /* reclaim storage, fail */
-      BalloonPrimFreePage(page);
-      return(status);
+      OS_ReservedPageFree(page);
+      return status;
    }
 
    /* track allocated page */
@@ -841,8 +695,7 @@ Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
    /* update balloon size */
    b->nPages++;
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
 /*
@@ -866,7 +719,7 @@ static int
 Balloon_FreePage(Balloon *b, int monitorUnlock)
 {
    BalloonChunk *chunk;
-   unsigned long page;
+   PageHandle page;
    int status;
 
    chunk = b->chunks;
@@ -901,7 +754,7 @@ Balloon_FreePage(Balloon *b, int monitorUnlock)
    }
 
    /* deallocate page */
-   BalloonPrimFreePage(page);
+   OS_ReservedPageFree(page);
    STATS_INC(b->stats.primFree);
 
    /* update balloon size */
@@ -917,8 +770,7 @@ Balloon_FreePage(Balloon *b, int monitorUnlock)
       b->nChunks--;
    }
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
 /*
@@ -987,6 +839,7 @@ BalloonIncreaseRateAlloc(Balloon *b, uint32 nAlloc)
    }
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1002,6 +855,7 @@ BalloonIncreaseRateAlloc(Balloon *b, uint32 nAlloc)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 BalloonInflate(Balloon *b, uint32 target)
 {
@@ -1126,6 +980,7 @@ BalloonInflate(Balloon *b, uint32 target)
    return(BALLOON_SUCCESS);
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1141,6 +996,7 @@ BalloonInflate(Balloon *b, uint32 target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 BalloonDeflate(Balloon *b, uint32 target)
 {
@@ -1167,10 +1023,10 @@ BalloonDeflate(Balloon *b, uint32 target)
                         BALLOON_RATE_FREE_MAX);
    }
 
-   /* everything OK */
-   return(BALLOON_SUCCESS);
+   return BALLOON_SUCCESS;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1187,6 +1043,7 @@ BalloonDeflate(Balloon *b, uint32 target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 Balloon_AdjustSize(Balloon *b, uint32 target)
 {
@@ -1228,6 +1085,7 @@ Balloon_AdjustSize(Balloon *b, uint32 target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 Balloon_MonitorStart(Balloon *b)
 {
@@ -1251,10 +1109,10 @@ Balloon_MonitorStart(Balloon *b)
       STATS_INC(b->stats.startFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1270,15 +1128,20 @@ Balloon_MonitorStart(Balloon *b)
  *
  *----------------------------------------------------------------------
  */
+
 static int
 Balloon_MonitorGuestType(Balloon *b)
 {
    uint32 status, target;
+   BalloonGuest identity;
    Backdoor_proto bp;
 
+   identity = OS_Identity();
+   ASSERT(identity == (uint32) identity);
+
    /* prepare backdoor args */
    bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_GUEST_ID;
-   bp.in.size = BalloonGuestType();
+   bp.in.size = identity;
 
    /* invoke backdoor */
    Backdoor_Balloon(&bp);
@@ -1298,10 +1161,10 @@ Balloon_MonitorGuestType(Balloon *b)
       STATS_INC(b->stats.guestTypeFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1313,7 +1176,7 @@ Balloon_MonitorGuestType(Balloon *b)
  *      Predicts the maximum achievable balloon size and sends it
  *      to vmm => vmkernel via vEbx register.
  *
- *      OS_PredictMaxReservedPages() returns either predicted max balloon
+ *      OS_ReservedPageGetLimit() returns either predicted max balloon
  *      pages or BALLOON_MAX_SIZE_USE_CONFIG. In the later scenario,
  *      vmkernel uses global config options for determining a guest's max
  *      balloon size. Note that older vmballoon drivers set vEbx to
@@ -1329,15 +1192,27 @@ Balloon_MonitorGuestType(Balloon *b)
  *
  *----------------------------------------------------------------------
  */
+
 static int
-Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
+Balloon_MonitorGetTarget(Balloon *b,     // IN
+                         uint32 *target) // OUT
 {
    Backdoor_proto bp;
+   unsigned long limit;
+   uint32 limit32;
    uint32 status;
 
+   limit = OS_ReservedPageGetLimit();
+
+   /* Ensure limit fits in 32-bits */
+   limit32 = (uint32)limit;
+   if (limit32 != limit) {
+      return BALLOON_FAILURE;
+   }
+
    /* prepare backdoor args */
    bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_TARGET;
-   bp.in.size = OS_PredictMaxReservedPages();
+   bp.in.size = limit;
 
    /* invoke backdoor */
    Backdoor_Balloon(&bp);
@@ -1357,17 +1232,17 @@ Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
       STATS_INC(b->stats.targetFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
  *----------------------------------------------------------------------
  *
  * Balloon_MonitorLockPage --
  *
- *      Attempts to contact monitor and add PPN containing "addr"
- *      to set of "balloon locked" pages.
+ *      Attempts to contact monitor and add PPN corresponding to
+ *      the page handle to set of "balloon locked" pages.
  *
  * Results:
  *      Returns BALLOON_SUCCESS if successful, otherwise error code.
@@ -1377,16 +1252,17 @@ Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
  *
  *----------------------------------------------------------------------
  */
+
 static int
-Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
+Balloon_MonitorLockPage(Balloon *b,        // IN
+                        PageHandle handle) // IN
 {
    unsigned long ppn;
    uint32 ppn32;
    uint32 status, target;
    Backdoor_proto bp;
 
-   /* convert kernel-mapped "physical addr" to ppn */
-   ppn = AddrToPPN(addr);
+   ppn = OS_ReservedPageGetPPN(handle);
 
    /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
    ppn32 = (uint32)ppn;
@@ -1416,8 +1292,7 @@ Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
       STATS_INC(b->stats.lockFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
 /*
@@ -1425,8 +1300,8 @@ Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
  *
  * Balloon_MonitorUnlockPage --
  *
- *      Attempts to contact monitor and remove PPN containing "addr"
- *      from set of "balloon locked" pages.
+ *      Attempts to contact monitor and remove PPN corresponding to
+ *      the page handle from set of "balloon locked" pages.
  *
  * Results:
  *      Returns BALLOON_SUCCESS if successful, otherwise error code.
@@ -1437,15 +1312,15 @@ Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
  *----------------------------------------------------------------------
  */
 static int
-Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr)
+Balloon_MonitorUnlockPage(Balloon *b,        // IN
+                          PageHandle handle) // IN
 {
    unsigned long ppn;
    uint32 ppn32;
    uint32 status, target;
    Backdoor_proto bp;
 
-   /* convert kernel-mapped "physical addr" to ppn */
-   ppn = AddrToPPN(addr);
+   ppn = OS_ReservedPageGetPPN(handle);
 
    /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
    ppn32 = (uint32)ppn;
@@ -1475,23 +1350,36 @@ Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr)
       STATS_INC(b->stats.unlockFail);
    }
 
-   /* everything OK */
-   return(status);
+   return status;
 }
 
+
 /*
- * Module Operations
+ *----------------------------------------------------------------------
+ *
+ * Balloon_ModuleInit --
+ *
+ *      Startup the balloon module.
+ *
+ * Results:
+ *      On success: BALLOON_SUCCESS
+ *      On failure: BALLOON_FAILURE
+ *
+ * Side effects:
+ *      None
+ *
+ *----------------------------------------------------------------------
  */
 
-static int
-BalloonModuleInit(void)
+int
+Balloon_ModuleInit(void)
 {
    static int initialized = 0;
    Balloon *b = &globalBalloon;
 
    /* initialize only once */
    if (initialized++) {
-      return(BALLOON_FAILURE);
+      return BALLOON_FAILURE;
    }
 
    /* os-specific initialization */
@@ -1501,43 +1389,54 @@ BalloonModuleInit(void)
    Balloon_Init(b);
 
    /* start timer */
-   OS_TimerInit(BalloonTimerHandler, b, OS_TimerHz());
-   Balloon_StartTimer(b);
+   timerStarted = FALSE;
+   if (!OS_TimerStart(BalloonTimerHandler, b)) {
+      Balloon_ModuleCleanup();
+      return BALLOON_FAILURE;
+   }
 
-   /* everything OK */
+   timerStarted = TRUE;
    return BALLOON_SUCCESS;
 }
 
-static void
-BalloonModuleCleanup(void)
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_ModuleCleanup --
+ *
+ *      Terminate and cleanup the balloon module.
+ *
+ * Results:
+ *      None
+ *
+ * Side effects:
+ *      None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Balloon_ModuleCleanup(void)
 {
    Balloon *b = &globalBalloon;
 
    /* stop timer */
-   Balloon_StopTimer(b);
+   if (timerStarted) {
+      OS_TimerStop();
+   }
 
    /*
     * Deallocate all reserved memory, and reset connection with monitor.
     * Reset connection before deallocating memory to avoid potential for
     * additional spurious resets from guest touching deallocated pages.
     */
-   (void) Balloon_MonitorStart(b);
+   Balloon_MonitorStart(b);
    Balloon_Deallocate(b);
 
    /* os-specific cleanup */
    OS_Cleanup();
 }
 
-int init_module(void)
-{
-   return(BalloonModuleInit());
-}
-
-void cleanup_module(void)
-{
-   BalloonModuleCleanup();
-}
-
 #ifdef __cplusplus
 }
 #endif
index b3a2b82137df07faaa2d3007f874417513200be0..07cf58f04b448d44b10fa6438bfcdbbadb3c592a 100644 (file)
@@ -72,8 +72,9 @@ typedef struct {
  * Operations
  */
 
-extern void BalloonGetStats(BalloonStats *stats);
-extern int  init_module(void);
-extern void cleanup_module(void);
+extern int  Balloon_ModuleInit(void);
+extern void Balloon_ModuleCleanup(void);
+
+extern void Balloon_GetStats(BalloonStats *stats);
 
 #endif /* VMBALLOON_H */
index ecd72bc8ac2019fa162dcf8c26e530f632dd9052..4b191823677e05fd00e0d3e2987e5a8606f78688 100644 (file)
@@ -90,7 +90,7 @@ BalloonKstatUpdate(kstat_t *ksp, int rw)
    if (rw == KSTAT_WRITE)
       return (EACCES);
 
-   BalloonGetStats(&stats);
+   Balloon_GetStats(&stats);
 
    /* size info */
    bkp->nPagesTarget.value.ui32 = stats.nPagesTarget;
index 211ad26d667902259623f6c79ec4e0e7c2dfef93..82771fe28e2df12f35b49075b8b3ae6b64dcf4cc 100644 (file)
@@ -103,6 +103,11 @@ wakeNetworkManager() {
    # `which' may be a bit noisy, so we'll shush it.
    dbusSend=`which dbus-send 2>/dev/null`
    if [ $? -eq 0 ]; then
+      # NetworkManager 0.6
+      $dbusSend --system --dest=org.freedesktop.NetworkManager          \
+         /org/freedesktop/NetworkManager                                \
+         org.freedesktop.NetworkManager.wake
+      # NetworkManager 0.7.0
       $dbusSend --system --dest=org.freedesktop.NetworkManager          \
          /org/freedesktop/NetworkManager                                \
          org.freedesktop.NetworkManager.Sleep boolean:false
index 4c4f3b2acab07b9bcbeff397e47ad7770da74700..f882fca1129c59f807197013f3301d3a1f78ddc8 100644 (file)
@@ -82,6 +82,11 @@ tranquilizeNetworkManager() {
    # `which' may be a bit noisy, so we'll shush it.
    dbusSend=`which dbus-send 2>/dev/null`
    if [ $? -eq 0 ]; then
+      # NetworkManager 0.6
+      $dbusSend --system --dest=org.freedesktop.NetworkManager          \
+         /org/freedesktop/NetworkManager                                \
+         org.freedesktop.NetworkManager.sleep
+      # NetworkManager 0.7.0
       $dbusSend --system --dest=org.freedesktop.NetworkManager          \
          /org/freedesktop/NetworkManager                                \
          org.freedesktop.NetworkManager.Sleep boolean:true