| // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "shill/diagnostics_reporter.h" |
| |
| #include <base/file_util.h> |
| |
| #include "shill/minijail.h" |
| #include "shill/process_killer.h" |
| #include "shill/shill_time.h" |
| #include "shill/shims/net_diags_upload.h" |
| |
| using base::Closure; |
| using std::vector; |
| |
| namespace shill { |
| |
| namespace { |
| |
| base::LazyInstance<DiagnosticsReporter> g_reporter = LAZY_INSTANCE_INITIALIZER; |
| const char kNetDiagsUpload[] = SHIMDIR "/net-diags-upload"; |
| const char kNetDiagsUploadUser[] = "syslog"; |
| |
| } // namespace |
| |
| // static |
| const int DiagnosticsReporter::kLogStashThrottleSeconds = 30 * 60; |
| |
| DiagnosticsReporter::DiagnosticsReporter() |
| : minijail_(Minijail::GetInstance()), |
| process_killer_(ProcessKiller::GetInstance()), |
| time_(Time::GetInstance()), |
| last_log_stash_(0), |
| stashed_net_log_(shims::kStashedNetLog) {} |
| |
| DiagnosticsReporter::~DiagnosticsReporter() {} |
| |
| // static |
| DiagnosticsReporter *DiagnosticsReporter::GetInstance() { |
| return g_reporter.Pointer(); |
| } |
| |
| void DiagnosticsReporter::OnConnectivityEvent() { |
| LOG(INFO) << "Diagnostics event triggered."; |
| |
| struct timeval now = (const struct timeval){ 0 }; |
| time_->GetTimeMonotonic(&now); |
| if (last_log_stash_ && |
| last_log_stash_ + kLogStashThrottleSeconds > |
| static_cast<uint64>(now.tv_sec)) { |
| LOG(INFO) << "Diagnostics throttled."; |
| return; |
| } |
| |
| last_log_stash_ = now.tv_sec; |
| // Delete logs possibly stashed by a different user. |
| file_util::Delete(stashed_net_log_, false); |
| |
| LOG(INFO) << "Spawning " << kNetDiagsUpload << " @ " << last_log_stash_; |
| vector<char *> args; |
| args.push_back(const_cast<char *>(kNetDiagsUpload)); |
| if (IsReportingEnabled()) { |
| args.push_back(const_cast<char *>("--upload")); |
| } |
| args.push_back(NULL); |
| pid_t pid = 0; |
| struct minijail *jail = minijail_->New(); |
| minijail_->DropRoot(jail, kNetDiagsUploadUser); |
| if (minijail_->RunAndDestroy(jail, args, &pid)) { |
| process_killer_->Wait(pid, Closure()); |
| } else { |
| LOG(ERROR) << "Unable to spawn " << kNetDiagsUpload; |
| } |
| } |
| |
| bool DiagnosticsReporter::IsReportingEnabled() { |
| // TODO(petkov): Implement this when there's a way to control reporting |
| // through policy. crosbug.com/35946. |
| return false; |
| } |
| |
| } // namespace shill |