Mercurial > hg > release > heapstats-1.1
changeset 16:6086194b2867
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:45 +0900 |
parents | 6c73e9d7876c |
children | bfde41acb148 |
files | agent/ChangeLog agent/src/fsUtil.cpp agent/src/fsUtil.hpp agent/src/logManager.cpp agent/src/util.hpp |
diffstat | 5 files changed, 198 insertions(+), 227 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/ChangeLog Wed Mar 12 18:54:11 2014 +0900 +++ b/agent/ChangeLog Mon Mar 17 19:52:45 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:54:11 2014 +0900 +++ b/agent/src/fsUtil.cpp Mon Mar 17 19:52:45 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" @@ -45,85 +46,88 @@ * \return Value is zero, if process is succeed.<br /> * Value is error number a.k.a. "errno", if process is failure. */ -int copyFile(char const* sourceFile, char const* destPath, char const* destName) { - int result = 0; - /* Make file name. */ - char *newFile = NULL; - if (destName == NULL) { - newFile = createFilename(destPath, (char*)sourceFile); - } else { - newFile = createFilename(destPath, (char*)destName); - } - - /* Failure make filename. */ - if (unlikely(newFile == NULL)) { - PRINT_WARN_MSG("Couldn't allocate copy source file path."); - - /* - * Because exist below two pattern when "createFilename" return NULL. - * 1, Illegal argument. "errno" don't change. - * 2, No usable memory. "errno" maybe "ENOMEM". - */ - return (errno != 0) ? errno : EINVAL; - } - - /* Get uniq file name. */ - char *destFile = createUniquePath(newFile, false); - if (unlikely(destFile == NULL)) { - PRINT_WARN_MSG("Couldn't allocate unique destination file name."); - free(newFile); - return ENOMEM; - } +int copyFile(char const* sourceFile, char const* destPath, char const* destName){ + char rpath[PATH_MAX]; + + if(unlikely(!isCopiablePath(sourceFile, rpath))){ + return EINVAL; + } + + int result = 0; + /* Make file name. */ + char *newFile = destName == NULL ? createFilename(destPath, (char*)sourceFile) + : createFilename(destPath, (char*)destName); + + /* Failure make filename. */ + if(unlikely(newFile == NULL)){ + PRINT_WARN_MSG("Couldn't allocate copy source file path."); + + /* + * Because exist below two pattern when "createFilename" return NULL. + * 1, Illegal argument. "errno" don't change. + * 2, No usable memory. "errno" maybe "ENOMEM". + */ + return (errno != 0) ? errno : EINVAL; + } - /* Open copy source file. */ - int sourceFd = open(sourceFile, O_RDONLY); - if (unlikely(sourceFd < 0)) { - result = errno; - PRINT_WARN_MSG("Couldn't open copy source file."); - free(newFile); - free(destFile); - return result; - } - - /* Open destination file. */ - int destFd = open(destFile, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR); - if (unlikely(destFd < 0)) { - result = errno; - PRINT_WARN_MSG("Couldn't open copy destination file."); - free(newFile); - free(destFile); - close(sourceFd); - return result; - } + /* Get uniq file name. */ + char *destFile = createUniquePath(newFile, false); + if(unlikely(destFile == NULL)){ + PRINT_WARN_MSG("Couldn't allocate unique destination file name."); + free(newFile); + return ENOMEM; + } - /* 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 buffer. */ - ssize_t readSize = 0; - 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)) { - result = errno; - PRINT_WARN_MSG("Couldn't write copy file data."); - break; - } - } - - /* Cleanup. */ - - close(sourceFd); - if (unlikely(close(destFd) < 0 && result == 0)) { - result = errno; - PRINT_WARN_MSG("Couldn't write copy file data."); - } + /* Open copy source file. */ + int sourceFd = open(sourceFile, O_RDONLY); + if(unlikely(sourceFd < 0)){ + result = errno; + PRINT_WARN_MSG("Couldn't open copy source file."); free(newFile); free(destFile); return result; + } + + /* Get source file size */ + struct stat st; + if(unlikely(fstat(sourceFd, &st) != 0)){ + result = errno; + PRINT_WARN_MSG("Couldn't open copy destination file."); + free(newFile); + free(destFile); + close(sourceFd); + return result; + } + + /* Open destination file. */ + int destFd = open(destFile, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR); + if(unlikely(destFd < 0)){ + result = errno; + PRINT_WARN_MSG("Couldn't open copy destination file."); + free(newFile); + free(destFile); + close(sourceFd); + return result; + } + + /* Copy data */ + if(unlikely(sendfile64(destFd, sourceFd, NULL, st.st_size) == -1)){ + result = errno; + PRINT_WARN_MSG("Couldn't write copy file data."); + } + + /* Clean up */ + close(sourceFd); + + if(unlikely((close(destFd) != 0) && (result == 0))){ + result = errno; + PRINT_WARN_MSG("Couldn't write copy file data."); + } + + free(newFile); + free(destFile); + + return result; } /*! @@ -183,49 +187,28 @@ } /*! - * \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 pathSize [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 pathSize) { - struct stat st = {0}; - char unlinkPath[PATH_MAX + 1] = {0}; - - /* Get real path and check file kind. */ - if (unlikely(readlink(linkPath, unlinkPath, PATH_MAX) < 0)) { - - /* Failure read link. Maybe raised error. */ - int raisedErrNum = errno; - PRINT_WARN_MSG_AND_ERRNO("Failure read information about link.", - raisedErrNum); - return false; - - } else if (unlikely(stat(linkPath, &st) != 0)) { - - /* Failure get file information. */ - int raisedErrNum = errno; - PRINT_WARN_MSG_AND_ERRNO("Failure get file information.", - raisedErrNum); - return false; - - } else if ((st.st_mode & S_IFMT) != S_IFREG) { - - /* File isn't regular file. This route is not error. */ - return false; - } - - /* Calculate copy size. */ - size_t copyStrSize = strlen(unlinkPath); - copyStrSize = (copyStrSize > pathSize) ? pathSize : copyStrSize; - /* Copy real path. */ - strncpy(filePath, unlinkPath, copyStrSize); - - /* File is able copy. */ - return true; +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_AND_ERRNO("Failure get file information (stat).", errno); + return false; + } + + if((st.st_mode & S_IFMT) != S_IFREG){ + /* File isn't regular file. This route is not error. */ + return false; + } + + return true; } /*!
--- a/agent/src/fsUtil.hpp Wed Mar 12 18:54:11 2014 +0900 +++ b/agent/src/fsUtil.hpp Mon Mar 17 19:52:45 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 @@ -49,15 +49,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 pathSize [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 pathSize); +bool isCopiablePath(const char *path, char *rpath); /*! * \brief Create temporary directory in designated directory.
--- a/agent/src/logManager.cpp Wed Mar 12 18:54:11 2014 +0900 +++ b/agent/src/logManager.cpp Mon Mar 17 19:52:45 2014 +0900 @@ -1,7 +1,7 @@ /*! * \file logManager.cpp * \brief This file is used collect log information. - * 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 @@ -1201,11 +1201,11 @@ * \return Value is zero, if process is succeed.<br /> * Value is error number a.k.a. "errno", if process is failure. */ -int TLogManager::copyInfoFiles(char const* basePath) { - - int result = 0; - /* Copy distribution file list. */ - const char distFileList[][255] = { +int TLogManager::copyInfoFiles(char const* basePath){ + int result = 0; + + /* Copy distribution file list. */ + const char distFileList[][255] = { /* Distribution release. */ "/etc/redhat-release", /* For other distribution. */ @@ -1217,35 +1217,36 @@ "/etc/issue", /* End flag. */ {0} - }; - bool flagCopyedDistFile = false; - - /* Copy distribution file. */ - for (int i = 0; strlen(distFileList[i]) > 0; i++) { - - result = copyFile(distFileList[i], basePath); - if (result == 0 || isRaisedDiskFull(result)) { - flagCopyedDistFile = (result == 0); - break; - } + }; + bool flagCopyedDistFile = false; + + /* Copy distribution file. */ + for(int i = 0; strlen(distFileList[i]) > 0; i++){ + result = copyFile(distFileList[i], basePath); + + if((result == 0) || isRaisedDiskFull(result)){ + flagCopyedDistFile = (result == 0); + break; } - - /* If failure copy distribution file. */ - if (unlikely(!flagCopyedDistFile)) { - PRINT_WARN_MSG_AND_ERRNO( - "Failure copy file. path:\"distribution file\"", result); - } - - /* If disk is full. */ - if (unlikely(isRaisedDiskFull(result))) { - return result; - } - - /* Copy file list. */ - const char copyFileList[][255] = { + + } + + /* If failure copy distribution file. */ + if(unlikely(!flagCopyedDistFile)){ + PRINT_WARN_MSG_AND_ERRNO( + "Failure copy file. path:\"distribution file\"", result); + } + + /* If disk is full. */ + if(unlikely(isRaisedDiskFull(result))){ + return result; + } + + /* 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", @@ -1253,76 +1254,55 @@ "/var/log/messages", /* 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. */ - result = copyFile(buff, basePath); - if (unlikely(result != 0)) { - PRINT_WARN_MSG_HEADER << "Failure copy file." - << " path:\"" << buff << "\"" - << " cause:\"" << strerror(result) << "\"" + }; + + /* Copy files in list. */ + for(int i = 0; strlen(copyFileList[i]) > 0; i++){ + /* Copy file. */ + result = copyFile(copyFileList[i], basePath); + if(unlikely(result != 0)){ + char error_string[1024]; + strerror_r(result, error_string, 1024); + + PRINT_WARN_MSG_HEADER << "Failure copy file." + << " path:\"" << copyFileList[i] << "\"" + << " cause:\"" << error_string << "\"" << NEWLINE; - - /* If disk is full. */ - if (unlikely(isRaisedDiskFull(result))) { - return result; - } - } + + /* If disk is full. */ + if(unlikely(isRaisedDiskFull(result))){ + return result; + } + } - - /* 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)) { - result = copyFile(stdOutRealPath, basePath, "fd1"); - - if (unlikely(result != 0)) { - PRINT_WARN_MSG_AND_ERRNO( - "Failure copy file. path:\"stdout\"", result); - - /* If disk is full. */ - if (unlikely(isRaisedDiskFull(result))) { - return result; - } - } + + } + + /* Copy stdout */ + result = copyFile("/proc/self/fd/1", basePath, "fd1"); + if(unlikely(result != 0)){ + PRINT_WARN_MSG_AND_ERRNO("Failure copy file. path:\"stdout\"", result); + + /* If disk is full. */ + if(unlikely(isRaisedDiskFull(result))){ + return result; } - - /* If stdout is not equal stderr. */ - if (strncmp(stdOutRealPath, stdErrRealPath, PATH_MAX) != 0) { - - /* Copy stderr. */ - if (unlikely(copyableStdErr)) { - result = copyFile(stdErrRealPath, basePath, "fd2"); - - if (unlikely(result != 0)) { - PRINT_WARN_MSG_AND_ERRNO( - "Failure copy file. path:\"stderr\"", result); - } - } + + } + + /* Copy stderr */ + result = copyFile("/proc/self/fd/2", basePath, "fd2"); + if(unlikely(result != 0)){ + PRINT_WARN_MSG_AND_ERRNO("Failure copy file. path:\"stderr\"", result); + + /* If disk is full. */ + if(unlikely(isRaisedDiskFull(result))){ + return result; } - return result; + + } + + return result; } /*!
--- a/agent/src/util.hpp Wed Mar 12 18:54:11 2014 +0900 +++ b/agent/src/util.hpp Mon Mar 17 19:52:45 2014 +0900 @@ -1,7 +1,7 @@ /*! * \file util.hpp * \brief This file is utilities. - * 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 @@ -114,8 +114,10 @@ * \brief Warning message and errno macro. */ #define PRINT_WARN_MSG_AND_ERRNO(msg, errnum) \ + char error_string[1024]; \ + strerror_r(errnum, error_string, 1024); \ PRINT_WARN_MSG_HEADER << (msg) \ - << " cause:\"" << strerror((errnum)) << "\"" << NEWLINE + << " cause:\"" << error_string << "\"" << NEWLINE /* Info message. */