2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 ///////////////////////////////////////////////////////////////////////////////
18 /// \ingroup tag_SS_LoggerService
19 /// \brief This file supports error event logging.
21 ///////////////////////////////////////////////////////////////////////////////
22 #include "ss_logger_error_event_archive.h"
27 #include <sys/types.h>
30 #include <libtar_listhash.h>
34 #include <boost/bind.hpp>
35 #include <native_service/frameworkunified_framework_if.h>
36 #include <system_service/ss_services.h>
37 #include <system_service/ss_templates.h>
42 #include "ss_logger_util.h"
43 #include "loggerservicedebug_loggerservicelog.h"
44 #include "ss_logger_fs_directory.h"
47 static gzFile g_gzFile;
49 CErrorEventArchive::CErrorEventArchive(void) {
50 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
53 m_gztype.openfunc = (openfunc_t) &CErrorEventArchive::gzOpenArchive;
54 m_gztype.closefunc = (closefunc_t) &CErrorEventArchive::gzCloseArchive;
55 m_gztype.readfunc = (readfunc_t) &CErrorEventArchive::gzReadArchive;
56 m_gztype.writefunc = (writefunc_t) &CErrorEventArchive::gzWriteArchive;
57 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
60 CErrorEventArchive::~CErrorEventArchive(void) {
61 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
62 if (NULL != m_pTarInfo) { // LCOV_EXCL_BR_LINE 6: it will close after close
63 // LCOV_EXCL_START 6: it will close after close
64 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
65 (void) closeArchive();
69 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
72 EFrameworkunifiedStatus CErrorEventArchive::openArchive(std::string f_pathAndName) {
73 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
74 EFrameworkunifiedStatus l_eFrameworkunifiedStatus = eFrameworkunifiedStatusOK;
76 if (NULL == m_pTarInfo) { // LCOV_EXCL_BR_LINE 6: closeArchive will be set to null
77 m_pathAndName = f_pathAndName;
79 /* check if directory exists */
80 size_t l_found = f_pathAndName.find_last_of('/');
81 std::string l_path = f_pathAndName.substr(0, l_found);
83 if (0 != access(l_path.c_str(), F_OK)) {
84 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Directory does not exist. Creating...");
85 l_eFrameworkunifiedStatus = CFSDirectory::CreateDirectory(l_path);
88 /* create archive in tmp */
89 m_tmpName = "/tmp/log.tar.gz";
91 int l_tarRetVal = tar_open(&m_pTarInfo, const_cast<char*>(m_tmpName.c_str()),
97 if ((l_tarRetVal != 0) || (m_pTarInfo == NULL) || (g_gzFile == NULL)) { // LCOV_EXCL_BR_LINE 5: tar_open's error case. // NOLINT[whitespace/line_length]
98 // LCOV_EXCL_START 5: tar_open's error case.
99 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
100 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Could not open TAR-Archive!");
101 l_eFrameworkunifiedStatus = eFrameworkunifiedStatusAccessError;
105 // LCOV_EXCL_START 6: closeArchive will be set to null
106 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
107 FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__, "Tar is still open");
108 l_eFrameworkunifiedStatus = eFrameworkunifiedStatusFail;
112 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
113 return (l_eFrameworkunifiedStatus);
116 EFrameworkunifiedStatus CErrorEventArchive::addToArchive(std::string f_filePathAndName,
117 std::string f_destinationName,
119 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
120 EFrameworkunifiedStatus l_eFrameworkunifiedStatus = eFrameworkunifiedStatusFileLoadError;
124 if (0 != access(f_filePathAndName.c_str(), F_OK)) { // LCOV_EXCL_BR_LINE 200: file is aways exist
125 // LCOV_EXCL_START 200: file is aways exist
126 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
127 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
128 " Error. The specified file path and name does not exist: %s",
129 f_filePathAndName.c_str());
131 } else if (0 != (l_statRetVal = stat(f_filePathAndName.c_str(), &l_stat))) { // LCOV_EXCL_BR_LINE 5: stat's error case. // NOLINT[whitespace/line_length]
132 // LCOV_EXCL_START 5: stat's error case.
133 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
134 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
135 " Error. stat() for file or directory returned error: %s -> %d",
136 f_filePathAndName.c_str(), l_statRetVal);
138 } else if (0 != S_ISDIR(l_stat.st_mode)) {
139 if (0 < f_depth) { // LCOV_EXCL_BR_LINE 6: it aways 4
140 l_eFrameworkunifiedStatus = addDirectoryToArchive(f_filePathAndName, f_destinationName,
143 // LCOV_EXCL_START 6: it aways 4
144 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
145 FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__,
146 "Maximum recursive depth reached! File %s not added to archive.",
147 f_filePathAndName.c_str());
150 } else if (0 != S_ISREG(l_stat.st_mode)) { // LCOV_EXCL_BR_LINE 200: it can not be a symbolic link
151 l_eFrameworkunifiedStatus = addFileToArchive(f_filePathAndName, f_destinationName);
153 // LCOV_EXCL_START 200: it can not be a symbolic link
154 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
158 " Error. specified file may be a symbolic link or other non 'regular' type. File: %s, mode: 0x%04X.",
159 f_filePathAndName.c_str(), l_stat.st_mode);
163 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
164 return (l_eFrameworkunifiedStatus);
167 // LCOV_EXCL_START 8: can not be called
168 EFrameworkunifiedStatus CErrorEventArchive::addToArchive(
169 std::vector<std::string> f_filePathAndNameList) {
170 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
171 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
172 EFrameworkunifiedStatus l_eFrameworkunifiedStatus = eFrameworkunifiedStatusOK;
174 std::vector<std::string>::iterator l_vIter = f_filePathAndNameList.begin();
175 while ((eFrameworkunifiedStatusOK == l_eFrameworkunifiedStatus)
176 && (l_vIter != f_filePathAndNameList.end())) {
177 l_eFrameworkunifiedStatus = addToArchive(*l_vIter, *l_vIter);
181 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
182 return (l_eFrameworkunifiedStatus);
186 EFrameworkunifiedStatus CErrorEventArchive::closeArchive(void) {
187 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
188 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
190 if (0 != tar_append_eof(m_pTarInfo)) { // LCOV_EXCL_BR_LINE 5: tar_append_eof's error case.
191 // LCOV_EXCL_START 5: tar_append_eof's error case.
192 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
193 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __PRETTY_FUNCTION__, "tar_append_eof()");
194 l_eStatus = eFrameworkunifiedStatusFail;
197 if (0 != tar_close(m_pTarInfo)) { // LCOV_EXCL_BR_LINE 5: tar_close's error case.
198 // LCOV_EXCL_START 5: tar_close's error case.
199 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
200 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Could not close archive");
201 l_eStatus = eFrameworkunifiedStatusFail;
208 if (eFrameworkunifiedStatusOK == l_eStatus) { // LCOV_EXCL_BR_LINE 6: it aways be ok
210 l_eStatus = CLoggerUtil::PathCheckAndCopyFile(m_tmpName, m_pathAndName);
212 l_eStatus = CLoggerUtil::CopyFile(m_tmpName, m_pathAndName);
213 #endif // RELEASE_BUILD
214 if (eFrameworkunifiedStatusOK == l_eStatus) {
216 (0 == remove(m_tmpName.c_str())) ? eFrameworkunifiedStatusOK : eFrameworkunifiedStatusFault;
217 if (eFrameworkunifiedStatusOK != l_eStatus) { // LCOV_EXCL_BR_LINE 5: remove's error case.
218 // LCOV_EXCL_START 5: remove's error case.
219 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
223 " Warning. Failed to remove temporary archive. Will overwrite on next event");
226 } else if (eFrameworkunifiedStatusErrNoEAGAIN == l_eStatus) { // LCOV_EXCL_BR_LINE 200: write can not be ErrNoEAGAIN
227 // LCOV_EXCL_START 200: write can not be ErrNoEAGAIN
228 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
232 if (stat(m_tmpName.c_str(), &st_buf) != -1) { // LCOV_EXCL_BR_LINE 5: stat's error case.
233 req_size = st_buf.st_size;
234 if (eFrameworkunifiedStatusOK
235 == CLoggerUtil::forceDeleteOldLog(m_pathAndName, req_size)) {
237 l_eStatus = CLoggerUtil::PathCheckAndCopyFile(m_tmpName, m_pathAndName);
239 l_eStatus = CLoggerUtil::CopyFile(m_tmpName, m_pathAndName);
240 #endif // RELEASE_BUILD
241 if (eFrameworkunifiedStatusOK != l_eStatus) { // LCOV_EXCL_BR_LINE 200: PathCheckAndCopyFile can not be fail
245 "Try Again but Error. Failed to copy to destination.%s, size=%d",
246 m_pathAndName.c_str(), req_size);
249 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
250 "Error. force delete failed.%s, size=%d",
251 m_pathAndName.c_str(), req_size);
253 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " emmc full: dest=%s, size=%d",
254 m_pathAndName.c_str(), req_size);
256 // LCOV_EXCL_START 5: stat's error case.
257 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
258 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
259 "Warning. Failed to get tmp log file stat. dest=%s",
260 m_pathAndName.c_str());
265 /*should we copy lost archive to emmc??*/
266 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
267 " Error. Failed to copy to destination. %s", m_pathAndName.c_str());
269 remove(m_tmpName.c_str());
273 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
277 EFrameworkunifiedStatus CErrorEventArchive::addFileToArchive(std::string f_filename,
278 std::string f_destinationName) {
279 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
280 EFrameworkunifiedStatus l_eFrameworkunifiedStatus = eFrameworkunifiedStatusOK; /*check if Tar is open and if file can be read */
284 if ((NULL != m_pTarInfo) && (0 != f_destinationName.length()) // LCOV_EXCL_BR_LINE 200: it will awalys be true
285 && (realpath(f_filename.c_str(), path) != NULL)) {
286 int l_tarRetVal = tar_append_file(m_pTarInfo, path,
287 const_cast<char*>(f_destinationName. c_str()));
288 if (0 != l_tarRetVal) { // LCOV_EXCL_BR_LINE 5: tar_append_file's error case.
289 // LCOV_EXCL_START 5: tar_append_file's error case.
290 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
291 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
292 "Could not add file \'%s\' to tar archive.", f_filename.c_str());
293 l_eFrameworkunifiedStatus = eFrameworkunifiedStatusAccessError;
297 // LCOV_EXCL_START 200: it will awalys be true
298 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
299 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
300 "Archive not opened or could not access file: \"%s\"",
302 l_eFrameworkunifiedStatus = eFrameworkunifiedStatusInvldParam;
306 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
307 return (l_eFrameworkunifiedStatus);
310 EFrameworkunifiedStatus CErrorEventArchive::addDirectoryToArchive(
311 std::string f_path, std::string f_destinationName, UI_8 f_depth) {
312 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
313 EFrameworkunifiedStatus l_eFrameworkunifiedStatus = eFrameworkunifiedStatusOK;
314 struct dirent l_pDirent;
317 DIR *l_pDir = opendir(f_path.c_str());
318 if (l_pDir != NULL) { // LCOV_EXCL_BR_LINE 5: opendir's error case.
319 while (0 == readdir_r(l_pDir, &l_pDirent, &next) && next != NULL) {
320 if ((0 != strcmp(l_pDirent.d_name, ".")) && /* Ignore special . directory. */
321 (0 != strcmp(l_pDirent.d_name, "..")) && /* Ignore special .. directory. */
322 (0 != strcmp(l_pDirent.d_name, "lost+found")) && /* Ignore lost+found. */
323 ('.' != l_pDirent.d_name[0])) { /* Ignore hidden files */
324 std::string l_extension = "/";
325 std::string l_fileName = f_path;
326 std::string l_destName = f_destinationName;
327 l_extension.append(l_pDirent.d_name);
328 l_fileName.append(l_extension);
329 l_destName.append(l_extension);
330 l_eFrameworkunifiedStatus = addToArchive(l_fileName, l_destName, static_cast<UI_8>(f_depth - 1));
337 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
338 return (l_eFrameworkunifiedStatus);
341 SI_32 CErrorEventArchive::gzOpenArchive(PCHAR f_pcPathname, SI_32 f_siOflags,
343 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
344 SI_32 l_siFileDescriptor = -1;
346 if (f_pcPathname) { // LCOV_EXCL_BR_LINE 6: Pathname is awalys be set
349 switch (f_siOflags & O_ACCMODE) { // LCOV_EXCL_BR_LINE 6: only O_WRONLY be set
351 l_pcGzoflags = (PCHAR) "wb";
354 // LCOV_EXCL_START 6: only O_WRONLY be set
356 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
357 l_pcGzoflags = (PCHAR) "rb";
367 if (-1 == (l_siFileDescriptor = // LCOV_EXCL_BR_LINE 5: open's error case.
368 open(f_pcPathname, f_siOflags, f_siMode))) {
369 // LCOV_EXCL_START 5: open's error case.
370 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
371 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
376 if ((f_siOflags & O_CREAT) // LCOV_EXCL_BR_LINE 5: fchmod's error case.
377 && fchmod(l_siFileDescriptor, f_siMode)) {
378 // LCOV_EXCL_START 5: fchmod's error case.
379 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
380 close(l_siFileDescriptor);
381 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
386 g_gzFile = gzdopen(l_siFileDescriptor, l_pcGzoflags);
387 if (!g_gzFile) { // LCOV_EXCL_BR_LINE 5: gzdopen's error case.
388 // LCOV_EXCL_START 5: gzdopen's error case.
389 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
390 close(l_siFileDescriptor);
391 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
396 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Source Path empty.");
399 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
400 return (SI_32) l_siFileDescriptor;
402 SI_32 CErrorEventArchive::gzCloseArchive() {
403 return gzclose(g_gzFile);
406 ssize_t CErrorEventArchive::gzWriteArchive(int fd, const void* buf,
408 return gzwrite(g_gzFile, const_cast<void*>(buf), (unsigned int) count);
411 ssize_t CErrorEventArchive::gzReadArchive(int fd, void* buf, size_t count) {
412 return gzread(g_gzFile, buf, (unsigned int) count);