changeset 34:48dc7c3ceee5

Bug 1467: Full mode log archiving does not work when using fifo pipe for gc log reviewed-by: ykubota, shintak
author Yasumasa Suenaga <suenaga.yasumasa@lab.ntt.co.jp>
date Mon, 17 Mar 2014 19:52:20 +0900
parents e99a12f039c6
children a4b4008e4ec0
files agent/ChangeLog agent/src/fsUtil.cpp agent/src/fsUtil.hpp agent/src/logManager.cpp
diffstat 4 files changed, 83 insertions(+), 119 deletions(-) [+]
line wrap: on
line diff
--- a/agent/ChangeLog	Wed Mar 12 18:56:41 2014 +0900
+++ b/agent/ChangeLog	Mon Mar 17 19:52:20 2014 +0900
@@ -1,3 +1,11 @@
+2014-03-17  Yasumasa Suenaga  <suenaga.yasumasa@lab.ntt.co.jp>
+
+	* Bug 1647: Full mode log archiving does not work when using fifo pipe for gc log
+
+2014-03-12  KUBOTA Yuji  <kubota.yuji@lab.ntt.co.jp>
+
+	* Bug 1696: The SNMP settings are changed unexpectedly when HeapStats agent reloads the configuration.
+
 2014-03-03  Yasumasa Suenaga  <suenaga.yasumasa@lab.ntt.co.jp>
 
 	* Bug 1691: Update HeapStats logos
--- a/agent/src/fsUtil.cpp	Wed Mar 12 18:56:41 2014 +0900
+++ b/agent/src/fsUtil.cpp	Mon Mar 17 19:52:20 2014 +0900
@@ -1,7 +1,7 @@
 /*!
  * \file fsUtil.cpp
  * \brief This file is utilities to access file system.
- * Copyright (C) 2011-2013 Nippon Telegraph and Telephone Corporation
+ * Copyright (C) 2011-2014 Nippon Telegraph and Telephone Corporation
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -27,6 +27,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <sys/sendfile.h>
 
 #include "fsUtil.hpp"
 #include "util.hpp"
@@ -44,75 +45,70 @@
  *                        Don't rename, if value is null.
  * \return Prosess is succeed or failure.
  */
-bool copyFile(char const* sourceFile, char const* destPath, char const* destName) {
+bool copyFile(char const* sourceFile, char const* destPath, char const* destName){
+  char rpath[PATH_MAX];
+
+  if(unlikely(!isCopiablePath(sourceFile, rpath))){
+    return false;
+  }
+
   /* Make file name. */
-  char *newFile = NULL;
-  if (destName == NULL) {
-    newFile = createFilename(destPath, (char*)sourceFile);
-  } else {
-    newFile = createFilename(destPath, (char*)destName);
-  }
+  char *newFile = destName == NULL ? createFilename(destPath, (char*)sourceFile)
+                                   : createFilename(destPath, (char*)destName);
   /* Failure make filename. */
-  if (unlikely(newFile == NULL)) {
-    
+  if(unlikely(newFile == NULL)){
     PRINT_WARN_MSG("Couldn't allocate copy source file path.");
     return false;
   }
-  
+
   /* Get uniq file name. */
   char *destFile = createUniquePath(newFile, false);
-  if (unlikely(destFile == NULL)) {
-    
+  if(unlikely(destFile == NULL)){
     PRINT_WARN_MSG("Couldn't allocate unique destination file name.");
     free(newFile);
     return false;
   }
-  
+
   /* Open copy source file. */
   int sourceFd = open(sourceFile, O_RDONLY);
-  if (unlikely(sourceFd < 0)) {
-    
+  if(unlikely(sourceFd < 0)){
     PRINT_WARN_MSG("Couldn't open copy source file.");
     free(newFile);
     free(destFile);
     return false;
   }
-  
-  /* Open destination file. */
-  int destFd = open(destFile, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
-  if (unlikely(destFd < 0)) {
-    
+
+  /* Get source file size */
+  struct stat st;
+  if(unlikely(fstat(sourceFd, &st) != 0)){
     PRINT_WARN_MSG("Couldn't open copy destination file.");
     free(newFile);
     free(destFile);
     close(sourceFd);
     return false;
   }
-  
-  /* Fetch advise. */
-  posix_fadvise(sourceFd, 0, 0, POSIX_FADV_SEQUENTIAL);
-  posix_fadvise(sourceFd, 0, 0, POSIX_FADV_NOREUSE);
-  posix_fadvise(destFd, 0, 0, POSIX_FADV_NOREUSE);
-  
-  /* Copy. */
-  size_t readSize;
-  char buff[1024];
-  /* Read from source file. */
-  while ((readSize = read(sourceFd, buff, sizeof(buff))) > 0) {
-    /* Write destination file. */
-    if (unlikely(write(destFd, buff, readSize) < 0)) {
-      
-      PRINT_WARN_MSG("Couldn't write copy file data.");
-      break;
-    }
+
+  /* Open destination file. */
+  int destFd = open(destFile, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
+  if (unlikely(destFd < 0)) {
+    PRINT_WARN_MSG("Couldn't open copy destination file.");
+    free(newFile);
+    free(destFile);
+    close(sourceFd);
+    return false;
   }
-  
+
+  /* Copy data */
+  if(unlikely(sendfile64(destFd, sourceFd, NULL, st.st_size) == -1)){
+    PRINT_WARN_MSG("Couldn't write copy file data.");
+  }
+
   /* Cleanup. */
-  
   close(sourceFd);
   close(destFd);
   free(newFile);
   free(destFile);
+
   return true;
 }
 
@@ -173,40 +169,27 @@
 }
 
 /*!
- * \brief Check link is regular file.
- * \param linkPath [in]  Path of link file.
- * \param filePath [out] Path of file is linked by link file.
- * \param nameSize [in]  Max size of paramter "filePath".
- * \return Value is true, if link is linked regular file.<br>
- *         Value is false, if link is linked directory or other.
+ * \brief Resolve canonicalized path path and check regular file or not.
+ * \param path [in]  Path of the target file.
+ * \param rpath [out] Real path which is pointed at "path".
+ *        Buffer size must be enough to store path (we recommend PATH_MAX).
+ * \return If "path" is copiable, this function returns true.
  */
-bool isCopyableLink(char const* linkPath, char *filePath, size_t nameSize) {
-  struct stat st = {0};
-  char unlinkPath[PATH_MAX] = {0};
-  
-  /* Get real path and check file kind. */
-  if (unlikely(readlink(linkPath, unlinkPath, PATH_MAX) < 0)) {
-    
-    /* Failure read link. Maybe raised error. */
-    PRINT_WARN_MSG("Failure read information about link.");
-    errno = 0;
+bool isCopiablePath(const char *path, char *rpath){
+  realpath(path, rpath);
+
+  struct stat st;
+  if(unlikely(stat(rpath, &st) != 0)){
+    /* Failure get file information. */
+    PRINT_WARN_MSG("Failure get file information (stat).");
     return false;
-    
-  } else if (unlikely(stat(linkPath, &st) != 0)) {
-    
-    /* Failure get file information. */
-    PRINT_WARN_MSG("Failure get file information.");
-    return false;
-    
-  } else if ((st.st_mode & S_IFMT) != S_IFREG) {
-    
+  }
+
+  if((st.st_mode & S_IFMT) != S_IFREG){
     /* File isn't regular file. This route is not error. */
     return false;
   }
-  
-  /* Copy real path. */
-  strncpy(filePath, unlinkPath, nameSize);
-  
+
   /* File is able copy. */
   return true;
 }
--- a/agent/src/fsUtil.hpp	Wed Mar 12 18:56:41 2014 +0900
+++ b/agent/src/fsUtil.hpp	Mon Mar 17 19:52:20 2014 +0900
@@ -1,7 +1,7 @@
 /*!
  * \file fsUtil.hpp
  * \brief This file is utilities to access file system.
- * Copyright (C) 2011-2013 Nippon Telegraph and Telephone Corporation
+ * Copyright (C) 2011-2014 Nippon Telegraph and Telephone Corporation
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -45,14 +45,13 @@
 char *createFilename(char const* basePath, char const* filename);
 
 /*!
- * \brief Check link is regular file.
- * \param linkPath [in]  Path of link file.
- * \param filePath [out] Path of file is linked by link file.
- * \param nameSize [in]  Max size of paramter "filePath".
- * \return Value is true, if link is linked regular file.<br>
- *         Value is false, if link is linked directory or other.
+ * \brief Resolve canonicalized path path and check regular file or not.
+ * \param path [in]  Path of the target file.
+ * \param rpath [out] Real path which is pointed at "path".
+ *        Buffer size must be enough to store path (we recommend PATH_MAX).
+ * \return If "path" is copiable, this function returns true.
  */
-bool isCopyableLink(char const* linkPath, char *filePath, size_t nameSize);
+bool isCopiablePath(const char *path, char *rpath);
 
 /*!
  * \brief Create temporary directory in current directory.
--- a/agent/src/logManager.cpp	Wed Mar 12 18:56:41 2014 +0900
+++ b/agent/src/logManager.cpp	Mon Mar 17 19:52:20 2014 +0900
@@ -1025,8 +1025,7 @@
  * \brief Collect files about JVM enviroment.
  * \param basePath [in] Temporary working directory.
  */
-void TLogManager::copyInfoFiles(char const* basePath) {
-  
+void TLogManager::copyInfoFiles(char const* basePath){
   /* Copy distribution file list. */
   const char distFileList[][255] = {
     /* Distribution release. */
@@ -1042,7 +1041,7 @@
     {0}
   };
   bool flagCopyedDistFile = false;
-  
+
   /* Copy distribution file. */
   for (int i = 0; strlen(distFileList[i]) > 0; i++) {
     if (likely(copyFile(distFileList[i], basePath))) {
@@ -1050,17 +1049,17 @@
       break;
     }
   }
-  
+
   /* If failure copy distribution file. */
   if (unlikely(!flagCopyedDistFile)) {
     PRINT_WARN_MSG("Failure copy file. path:\"distribution file\"");
   }
-  
+
   /* Copy file list. */
   const char copyFileList[][255] = {
     /* Process information. */
-    "/proc/%d/smaps",   "/proc/%d/limits",
-    "/proc/%d/cmdline", "/proc/%d/status",
+    "/proc/self/smaps",   "/proc/self/limits",
+    "/proc/self/cmdline", "/proc/self/status",
     /* Netstat infomation. */
     "/proc/net/tcp", "/proc/net/tcp6",
     "/proc/net/udp", "/proc/net/udp6",
@@ -1069,51 +1068,26 @@
     /* End flag. */
     {0}
   };
-  
+
   /* Copy files in list. */
   for (int i = 0; strlen(copyFileList[i]) > 0; i++) {
-    
-    /* Make copy file path. */
-    char buff[256] = {0};
-    snprintf(buff, 255, copyFileList[i], getpid());
-    
     /* Copy file. */
-    if (unlikely(!copyFile(buff, basePath))) {
+    if (unlikely(!copyFile(copyFileList[i], basePath))) {
       PRINT_WARN_MSG_HEADER << "Failure copy file."
-        << " path:\"" << buff << "\"" << NEWLINE;
+        << " path:\"" << copyFileList[i] << "\"" << NEWLINE;
     }
   }
-  
-  /* Copy file /proc/<pid>/fd/{1,2} */
-  char stdOutPath[256] = {0};
-  char stdErrPath[256] = {0};
-  snprintf(stdOutPath, 255, "/proc/%d/fd/1", getpid());
-  snprintf(stdErrPath, 255, "/proc/%d/fd/2", getpid());
-  char stdOutRealPath[PATH_MAX + 1] = {0};
-  char stdErrRealPath[PATH_MAX + 1] = {0};
-  
-  /* Check file is copyable. */
-  bool copyableStdOut = false;
-  bool copyableStdErr = false;
-  
-  copyableStdOut = isCopyableLink((char*)stdOutPath,
-                                       (char*)stdOutRealPath, PATH_MAX);
-  copyableStdErr = isCopyableLink((char*)stdErrPath,
-                                       (char*)stdErrRealPath, PATH_MAX);
-  
+
   /* Copy stdout. */
-  if (unlikely(copyableStdOut && !copyFile(stdOutRealPath, basePath, "fd1"))) {
+  if (unlikely(!copyFile("/proc/self/fd/1", basePath, "fd1"))) {
     PRINT_WARN_MSG("Failure copy standard output.");
   }
-  
-  /* If stdout is not equal stderr. */
-  if (strncmp(stdOutRealPath, stdErrRealPath, PATH_MAX) != 0) {
-    
-    /* Copy stderr. */
-    if (unlikely(copyableStdErr && !copyFile(stdErrRealPath, basePath, "fd2"))) {
-      PRINT_WARN_MSG("Failure copy standard error output.");
-    }
+
+  /* Copy stderr. */
+  if (unlikely(!copyFile("/proc/self/fd/2", basePath, "fd2"))) {
+    PRINT_WARN_MSG("Failure copy standard error.");
   }
+ 
 }
 
 /*!