blob: c8f123c164794e96cc31ba789b317aeca6ac6269 [file] [log] [blame]
// 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