]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Log messages when the network interface limit is hit.
authorJohn Wolfe <jwolfe@vmware.com>
Tue, 4 May 2021 02:39:40 +0000 (19:39 -0700)
committerJohn Wolfe <jwolfe@vmware.com>
Tue, 4 May 2021 02:39:40 +0000 (19:39 -0700)
Whenever the maximum NIC limit is reached, log a message to both the
VM guest.log file on the host and the vmsvc.log file inside the guest.

Moved the logging api added for powerOps plugin to vmtoolslib so
that it is available for all plugins.  Modified the powerOps code
accordingly.

open-vm-tools/lib/include/nicInfo.h
open-vm-tools/lib/include/vmware/tools/log.h
open-vm-tools/lib/nicInfo/nicInfo.c
open-vm-tools/lib/nicInfo/nicInfoInt.h
open-vm-tools/lib/nicInfo/nicInfoPosix.c
open-vm-tools/libvmtools/vmtoolsLog.c
open-vm-tools/services/plugins/guestInfo/guestInfoServer.c
open-vm-tools/services/plugins/powerOps/powerOps.c
open-vm-tools/toolbox/toolboxcmd-info.c

index 59b28b85156e4c4d58ff3e5f691b7a7301cd448b..bd223e94c7c4fd892a3f109582001cc82bd64ce1 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2014-2018 VMware, Inc. All rights reserved.
+ * Copyright (C) 2014-2021 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
@@ -41,7 +41,8 @@ typedef enum {
 Bool GuestInfo_GetFqdn(int outBufLen, char fqdn[]);
 Bool GuestInfo_GetNicInfo(unsigned int maxIPv4Routes,
                           unsigned int maxIPv6Routes,
-                          NicInfoV3 **nicInfo);
+                          NicInfoV3 **nicInfo,
+                          Bool *maxNicsError);
 void GuestInfo_FreeNicInfo(NicInfoV3 *nicInfo);
 char *GuestInfo_GetPrimaryIP(void);
 
index c810b6266332acd3917a8bf2cdf35a040cbac647..3773588057e530e7093a92182c27bcc9d634d768 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2011-2020 VMware, Inc. All rights reserved.
+ * Copyright (C) 2011-2021 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
 #endif
 
 #include <glib.h>
+#include "vmware/tools/guestrpc.h"
 
 #if defined(__GNUC__)
 #  define FUNC __func__
@@ -349,6 +350,11 @@ VMTools_Log(LogWhere where,
             const gchar *fmt,
             ...);
 
+void
+VMTools_VmxLog(RpcChannel *chan,
+               const gchar *fmt,
+               ...);
+
 G_END_DECLS
 
 #define host_warning(fmt, ...)                                          \
index 580fbf27579c1650c4a070687988d6b4d5f94094..02c760bd25f467806dff272ffcdcd14491efe8e8 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2014-2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2014-2021 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
@@ -284,6 +284,7 @@ GuestInfo_GetFqdn(int outBufLen,
  * @param[in]  maxIPv4Routes  Max IPv4 routes to gather.
  * @param[in]  maxIPv6Routes  Max IPv6 routes to gather.
  * @param[out] nicInfo        Will point to a newly allocated NicInfo.
+ * @param[out] maxNicsError   To determine NIC max limit error.
  *
  * @note
  * Caller is responsible for freeing @a nicInfo with GuestInfo_FreeNicInfo.
@@ -297,13 +298,15 @@ GuestInfo_GetFqdn(int outBufLen,
 Bool
 GuestInfo_GetNicInfo(unsigned int maxIPv4Routes,
                      unsigned int maxIPv6Routes,
-                     NicInfoV3 **nicInfo)
+                     NicInfoV3 **nicInfo,
+                     Bool *maxNicsError)
 {
    Bool retval;
 
    *nicInfo = Util_SafeCalloc(1, sizeof (struct NicInfoV3));
 
-   retval = GuestInfoGetNicInfo(maxIPv4Routes, maxIPv6Routes, *nicInfo);
+   retval = GuestInfoGetNicInfo(maxIPv4Routes, maxIPv6Routes, *nicInfo,
+                                maxNicsError);
    if (!retval) {
       GuestInfo_FreeNicInfo(*nicInfo);
       *nicInfo = NULL;
@@ -374,10 +377,11 @@ GuestInfo_GetPrimaryIP(void)
  *
  * @brief GuestNicV3 constructor.
  *
- * @param[in,out] nicInfo     List of NICs.
- * @param[in]     macAddress  MAC address of new NIC.
- * @param[in]     dnsInfo     Per-NIC DNS config state.
- * @param[in]     winsInfo    Per-NIC WINS config state.
+ * @param[in,out] nicInfo       List of NICs.
+ * @param[in]     macAddress    MAC address of new NIC.
+ * @param[in]     dnsInfo       Per-NIC DNS config state.
+ * @param[in]     winsInfo      Per-NIC WINS config state.
+ * @param[out]    maxNicsError  To determine NIC max limit error.
  *
  * @note The returned GuestNic will take ownership of @a dnsInfo and
  *       @a winsInfo  The caller must not free it directly.
@@ -391,14 +395,16 @@ GuestNicV3 *
 GuestInfoAddNicEntry(NicInfoV3 *nicInfo,
                      const char macAddress[NICINFO_MAC_LEN],
                      DnsConfigInfo *dnsInfo,
-                     WinsConfigInfo *winsInfo)
+                     WinsConfigInfo *winsInfo,
+                     Bool *maxNicsError)
 {
    GuestNicV3 *newNic;
 
    /* Check to see if we're going above our limit. See bug 605821. */
    if (nicInfo->nics.nics_len == NICINFO_MAX_NICS) {
-      g_message("%s: NIC limit (%d) reached, skipping overflow.",
-                __FUNCTION__, NICINFO_MAX_NICS);
+      if (maxNicsError != NULL) {
+         *maxNicsError = TRUE;
+      }
       return NULL;
    }
 
index c929722e7425a965f623bea82d6cb29bb842e0ef..47b484bfd226c9e3e803a74a5d2c2894c130ee13 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2014-2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2014-2021 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
 Bool GuestInfoGetFqdn(int outBufLen, char fqdn[]);
 Bool GuestInfoGetNicInfo(unsigned int maxIPv4Routes,   // IN
                          unsigned int maxIPv6Routes,   // IN
-                         NicInfoV3 *nicInfo);          // OUT
+                         NicInfoV3 *nicInfo,           // OUT
+                         Bool *maxNicsError);          // OUT
 
 GuestNicV3 *GuestInfoAddNicEntry(NicInfoV3 *nicInfo,                    // IN/OUT
                                  const char macAddress[NICINFO_MAC_LEN], // IN
                                  DnsConfigInfo *dnsInfo,                // IN
-                                 WinsConfigInfo *winsInfo);             // IN
+                                 WinsConfigInfo *winsInfo,              // IN
+                                 Bool *maxNicsError);                   // OUT
 
 IpAddressEntry *GuestInfoAddIpAddress(GuestNicV3 *nic,                  // IN/OUT
                                       const struct sockaddr *sockAddr,  // IN
index f13b23a0976298e4c36de9799786e4b527db4d4a..de57a4a90a38155a59783bdeba2bbb42efa03c5e 100644 (file)
@@ -284,10 +284,11 @@ IpEntryMatchesDevice(const char *devName,
  * @brief Gather IP addresses from ifaddrs and put into NicInfo, filtered
  *        by priority.
  *
- * @param[in]   ifaddrs  ifaddrs structure
- * @param[in]   priority the priority - only interfaces with this priority
- *                       will be considered
- * @param[out]  nicInfo  NicInfoV3 structure
+ * @param[in]   ifaddrs       ifaddrs structure
+ * @param[in]   priority      the priority - only interfaces with this priority
+ *                            will be considered
+ * @param[out]  nicInfo       NicInfoV3 structure
+ * @param[out]  maxNicsError  To determine NIC max limit error.
  *
  ******************************************************************************
  */
@@ -295,7 +296,8 @@ IpEntryMatchesDevice(const char *devName,
 static void
 GuestInfoGetInterface(struct ifaddrs *ifaddrs,
                       NicInfoPriority priority,
-                      NicInfoV3 *nicInfo)
+                      NicInfoV3 *nicInfo,
+                      Bool *maxNicsError)
 {
    struct ifaddrs *pkt;
    /*
@@ -335,7 +337,8 @@ GuestInfoGetInterface(struct ifaddrs *ifaddrs,
                      "%02x:%02x:%02x:%02x:%02x:%02x",
                      sll->sll_addr[0], sll->sll_addr[1], sll->sll_addr[2],
                      sll->sll_addr[3], sll->sll_addr[4], sll->sll_addr[5]);
-         nic = GuestInfoAddNicEntry(nicInfo, macAddress, NULL, NULL);
+         nic = GuestInfoAddNicEntry(nicInfo, macAddress, NULL, NULL,
+                                    maxNicsError);
          if (nic == NULL) {
             /*
              * We reached the maximum number of NICs that we can report.
@@ -399,6 +402,7 @@ GuestInfoGetInterface(struct ifaddrs *ifaddrs,
  * @param[in]  maxIPv4Routes  Max IPv4 routes to gather.
  * @param[in]  maxIPv6Routes  Max IPv6 routes to gather.
  * @param[out] nicInfo        NicInfoV3 container.
+ * @param[out] maxNicsError   To determine NIC max limit error.
  *
  * @copydoc GuestInfo_GetNicInfo
  *
@@ -408,7 +412,8 @@ GuestInfoGetInterface(struct ifaddrs *ifaddrs,
 Bool
 GuestInfoGetNicInfo(unsigned int maxIPv4Routes,
                     unsigned int maxIPv6Routes,
-                    NicInfoV3 *nicInfo)
+                    NicInfoV3 *nicInfo,
+                    Bool *maxNicsError)
 {
 #ifndef NO_DNET
    intf_t *intf;
@@ -459,7 +464,7 @@ GuestInfoGetNicInfo(unsigned int maxIPv4Routes,
       for (priority = NICINFO_PRIORITY_PRIMARY;
            priority < NICINFO_PRIORITY_MAX;
            priority++) {
-         GuestInfoGetInterface(ifaddrs, priority, nicInfo);
+         GuestInfoGetInterface(ifaddrs, priority, nicInfo, maxNicsError);
       }
       freeifaddrs(ifaddrs);
    }
@@ -693,7 +698,7 @@ ReadInterfaceDetails(const struct intf_entry *entry, // IN
             return 0;
          }
 
-         nic = GuestInfoAddNicEntry(nicInfo, macAddress, NULL, NULL);
+         nic = GuestInfoAddNicEntry(nicInfo, macAddress, NULL, NULL, NULL);
          if (NULL == nic) {
             /*
              * We reached maximum number of NICs we can report to the host.
index e63f0810797fd3a707327e5fc0b313936abf9801..14acd61928d3babf1ce440a7df3d1bfb04c6143a 100644 (file)
    }                                               \
 } while (0)
 
+#define VMX_LOG_CMD     "log "
+#define VMX_LOG_CMD_LEN (sizeof(VMX_LOG_CMD) - 1)
+
 
 typedef struct LogHandler {
    GlibLogger    *logger;
@@ -2713,3 +2716,59 @@ VMTools_Log(LogWhere where,
    LogWhereLevelV(where, level, domain, fmt, args);
    va_end(args);
 }
+
+
+/*
+ ******************************************************************************
+ * VMTools_VmxLog --
+ *
+ * Sends the log message through RPC to vmx to be logged on the host.
+ * Also, logs the message to vmsvc log file inside guest.
+ *
+ * @param[in]  chan         The RPC channel instance.
+ * @param[in]  fmt          Log message output format.
+ *
+ * @return None
+ *
+ ******************************************************************************
+ */
+
+void
+VMTools_VmxLog(RpcChannel *chan,
+               const gchar *fmt,
+               ...)
+{
+   char *reply = NULL;
+   size_t replyLen;
+   gchar msg[4096] = VMX_LOG_CMD;
+   va_list args;
+   gint len;
+
+   va_start(args, fmt);
+   len = g_vsnprintf(msg + VMX_LOG_CMD_LEN,
+                     sizeof msg - VMX_LOG_CMD_LEN,
+                     fmt, args);
+   va_end(args);
+
+   if (len <= 0) {
+      g_warning("%s: g_vsnprintf failed: return value: %d.\n", __FUNCTION__,
+                len);
+      return;
+   }
+
+   len += VMX_LOG_CMD_LEN;
+   if (len >= sizeof msg) {
+      len = sizeof msg - 1;
+      msg[len] = '\0';
+   }
+
+   if (!RpcChannel_Send(chan, msg, len + 1, &reply, &replyLen)) {
+      g_warning("%s: Error sending RPC message: %s. reply: %s\n",
+                __FUNCTION__, msg, reply ? reply : "NULL");
+   }
+   if (reply) {
+      free(reply);
+   }
+
+   g_message("%s\n", msg + VMX_LOG_CMD_LEN);
+}
index 01d51ecae3bd0314bfab049a9d51cf88a618cf17..8d05b72159610066ee2cc4d7e9672f16948d5e1a 100644 (file)
@@ -544,6 +544,7 @@ GuestInfoGather(gpointer data)
    int maxIPv6RoutesToGather;
    gchar *osNameOverride;
    gchar *osNameFullOverride;
+   Bool maxNicsError = FALSE;
 
    g_debug("Entered guest info gather.\n");
 
@@ -758,13 +759,17 @@ GuestInfoGather(gpointer data)
 
    if (!GuestInfo_GetNicInfo(maxIPv4RoutesToGather,
                              maxIPv6RoutesToGather,
-                             &nicInfo)) {
+                             &nicInfo, &maxNicsError)) {
       g_warning("Failed to get NIC info.\n");
       /*
        * Return an empty NIC info.
        */
       nicInfo = Util_SafeCalloc(1, sizeof (struct NicInfoV3));
    }
+   if (maxNicsError) {
+      VMTools_VmxLog(ctx->rpc, "%s: NIC limit (%d) reached.",
+                     __FUNCTION__, NICINFO_MAX_NICS);
+   }
 
    /*
     * We need to check if the setting for the primary interfaces or low
index f081285123074a55aa5d364b369e546a1ca3538a..db4d4f11e7b5f969e669ac5d39daeec868147875 100644 (file)
@@ -34,6 +34,7 @@
 #include "vmware/guestrpc/powerops.h"
 #include "vmware/tools/plugin.h"
 #include "vmware/tools/utils.h"
+#include "vmware/tools/log.h"
 
 #if defined(G_PLATFORM_WIN32)
 #  define INVALID_PID NULL
@@ -49,9 +50,6 @@
 VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING);
 #endif
 
-#define HOST_LOG_CMD     "log "
-#define HOST_LOG_CMD_LEN (sizeof(HOST_LOG_CMD) - 1)
-
 static const char *stateChgConfNames[] = {
    NULL,
    CONFNAME_POWEROFFSCRIPT,
@@ -165,48 +163,6 @@ PowerOpsShutdown(gpointer src,
 }
 
 
-/**
- * Sends the log message through RPC to vmx to be logged in guest.log on host.
- * Also, logs the message to vmsvc log file inside guest.
- *
- * @param[in]  ctx          The application context.
- * @param[in]  fmt          Log message output format.
- */
-
-static void
-PowerOpsLog(ToolsAppCtx *ctx,
-            const gchar *fmt,
-            ...)
-{
-   gchar msg[4096] = HOST_LOG_CMD;
-   va_list args;
-   gint len;
-
-   va_start(args, fmt);
-   len = g_vsnprintf(msg + HOST_LOG_CMD_LEN, sizeof msg - HOST_LOG_CMD_LEN,
-                     fmt, args);
-   va_end(args);
-
-   if (len <= 0) {
-      g_warning("g_vsnprintf failed: return value: %d", len);
-      return;
-   }
-
-   len += HOST_LOG_CMD_LEN;
-   if (len >= sizeof msg) {
-      len = sizeof msg - 1;
-      msg[len] = '\0';
-      g_message("Following log message is truncated: %s.\n", msg);
-   }
-
-   if (!RpcChannel_Send(ctx->rpc, msg, len + 1, NULL, NULL)) {
-      g_warning("%s: Error sending RPC message: %s.\n", __FUNCTION__, msg);
-   }
-
-   g_message("%s\n", msg + HOST_LOG_CMD_LEN);
-}
-
-
 /**
  * Called when a state change script is done running. Sends the state change
  * status to the VMX.
@@ -258,10 +214,10 @@ PowerOpsStateChangeDone(PowerOpState *state,
    /* Finally, perform the requested operation. */
    if (success) {
       if (state->stateChgInProgress == GUESTOS_STATECHANGE_REBOOT) {
-         PowerOpsLog(state->ctx, "Initiating reboot.");
+         VMTools_VmxLog(state->ctx->rpc, "Initiating reboot.");
          System_Shutdown(TRUE);
       } else if (state->stateChgInProgress == GUESTOS_STATECHANGE_HALT) {
-         PowerOpsLog(state->ctx, "Initiating halt.");
+         VMTools_VmxLog(state->ctx->rpc, "Initiating halt.");
          System_Shutdown(FALSE);
       }
    }
@@ -292,8 +248,8 @@ PowerOpsScriptCallback(gpointer _state)
 
       success = (ProcMgr_GetExitCode(state->pid, &exitcode) == 0 &&
                  exitcode == 0);
-      PowerOpsLog(state->ctx, "Script exit code: %d, success = %d",
-                  exitcode, success);
+      VMTools_VmxLog(state->ctx->rpc, "Script exit code: %d, success = %d",
+                     exitcode, success);
       PowerOpsStateChangeDone(state, success);
       ProcMgr_Free(state->pid);
       state->pid = INVALID_PID;
@@ -378,17 +334,17 @@ PowerOpsScriptCallback(GPid pid,
    ASSERT(state->pid != INVALID_PID);
 
    if (WIFEXITED(exitStatus)) {
-      PowerOpsLog(state->ctx, "Script exit code: %d, success = %d",
-                  WEXITSTATUS(exitStatus), success);
+      VMTools_VmxLog(state->ctx->rpc, "Script exit code: %d, success = %d",
+                     WEXITSTATUS(exitStatus), success);
    } else if (WIFSIGNALED(exitStatus)) {
-      PowerOpsLog(state->ctx, "Script canceled by signal: %d, success = %d",
-                  WTERMSIG(exitStatus), success);
+      VMTools_VmxLog(state->ctx->rpc, "Script canceled by signal: %d, "
+                     "success = %d", WTERMSIG(exitStatus), success);
    } else if (WIFSTOPPED(exitStatus)) {
-      PowerOpsLog(state->ctx, "Script stopped by signal: %d, success = %d",
-                  WSTOPSIG(exitStatus), success);
+      VMTools_VmxLog(state->ctx->rpc, "Script stopped by signal: %d, "
+                     "success = %d", WSTOPSIG(exitStatus), success);
    } else {
-      PowerOpsLog(state->ctx, "Script exit status: %d, success = %d",
-                  exitStatus, success);
+      VMTools_VmxLog(state->ctx->rpc, "Script exit status: %d, success = %d",
+                     exitStatus, success);
    }
    PowerOpsStateChangeDone(_state, success);
    g_spawn_close_pid(state->pid);
@@ -546,8 +502,8 @@ PowerOpsStateChange(RpcInData *data)
             script = tmp;
          }
 
-         PowerOpsLog(state->ctx, "Executing script for state change '%s'.",
-                     stateChangeCmdTable[i].tcloCmd);
+         VMTools_VmxLog(state->ctx->rpc, "Executing script for state change "
+                        "'%s'.", stateChangeCmdTable[i].tcloCmd);
          if (PowerOpsRunScript(state, script)) {
             result = "";
             ret = TRUE;
index ef32543b99b4403760e19d794be68c3c0a576782..7b45c52f023acd797cd92510f3193f8a4b355cc4 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2015-2020 VMware, Inc. All rights reserved.
+ * Copyright (C) 2015-2021 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
@@ -171,7 +171,7 @@ InfoUpdateNetwork(void)
 
    if (!GuestInfo_GetNicInfo(maxIPv4RoutesToGather,
                              maxIPv6RoutesToGather,
-                             &info)) {
+                             &info, NULL)) {
       g_warning("Failed to get nic info.\n");
       ret = EXIT_FAILURE;
       goto done;