OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromecast/crash/linux/synchronized_minidump_manager.h" | 5 #include "chromecast/crash/linux/synchronized_minidump_manager.h" |
6 | 6 |
7 #include <dirent.h> | 7 #include <dirent.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 DCHECK_GE(period_dumps, 0); | 115 DCHECK_GE(period_dumps, 0); |
116 | 116 |
117 base::DictionaryValue* ratelimit_params = GetRatelimitParams(metadata); | 117 base::DictionaryValue* ratelimit_params = GetRatelimitParams(metadata); |
118 RCHECK(ratelimit_params, -1); | 118 RCHECK(ratelimit_params, -1); |
119 | 119 |
120 ratelimit_params->SetInteger(kLockfileRatelimitPeriodDumpsKey, period_dumps); | 120 ratelimit_params->SetInteger(kLockfileRatelimitPeriodDumpsKey, period_dumps); |
121 | 121 |
122 return 0; | 122 return 0; |
123 } | 123 } |
124 | 124 |
125 // Increment the number of dumps in the current ratelimit period in deserialized | |
126 // |metadata| by |increment|. Returns 0 on success, < 0 on error. | |
127 int IncrementCurrentPeriodDumps(base::Value* metadata, int increment) { | |
128 DCHECK_GE(increment, 0); | |
129 int last_dumps = GetRatelimitPeriodDumps(metadata); | |
130 RCHECK(last_dumps >= 0, -1); | |
131 | |
132 return SetRatelimitPeriodDumps(metadata, last_dumps + increment); | |
133 } | |
134 | |
135 // Returns true if |metadata| contains valid metadata, false otherwise. | 125 // Returns true if |metadata| contains valid metadata, false otherwise. |
136 bool ValidateMetadata(base::Value* metadata) { | 126 bool ValidateMetadata(base::Value* metadata) { |
137 RCHECK(metadata, false); | 127 RCHECK(metadata, false); |
138 | 128 |
139 // Validate ratelimit params | 129 // Validate ratelimit params |
140 base::DictionaryValue* ratelimit_params = GetRatelimitParams(metadata); | 130 base::DictionaryValue* ratelimit_params = GetRatelimitParams(metadata); |
141 | 131 |
142 return ratelimit_params && | 132 return ratelimit_params && |
143 ratelimit_params->size() == kLockfileNumRatelimitParams && | 133 ratelimit_params->size() == kLockfileNumRatelimitParams && |
144 GetRatelimitPeriodStart(metadata) >= 0 && | 134 GetRatelimitPeriodStart(metadata) >= 0 && |
145 GetRatelimitPeriodDumps(metadata) >= 0; | 135 GetRatelimitPeriodDumps(metadata) >= 0; |
146 } | 136 } |
147 | 137 |
148 } // namespace | 138 } // namespace |
149 | 139 |
150 const int SynchronizedMinidumpManager::kMaxLockfileDumps = 5; | |
151 | |
152 // One day | 140 // One day |
153 const int SynchronizedMinidumpManager::kRatelimitPeriodSeconds = 24 * 3600; | 141 const int SynchronizedMinidumpManager::kRatelimitPeriodSeconds = 24 * 3600; |
154 const int SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps = 100; | 142 const int SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps = 100; |
155 | 143 |
156 SynchronizedMinidumpManager::SynchronizedMinidumpManager() | 144 SynchronizedMinidumpManager::SynchronizedMinidumpManager() |
157 : non_blocking_(false), | 145 : non_blocking_(false), |
158 dump_path_(GetHomePathASCII(kMinidumpsDir)), | 146 dump_path_(GetHomePathASCII(kMinidumpsDir)), |
159 lockfile_path_(dump_path_.Append(kLockfileName).value()), | 147 lockfile_path_(dump_path_.Append(kLockfileName).value()), |
160 metadata_path_(dump_path_.Append(kMetadataName).value()), | 148 metadata_path_(dump_path_.Append(kMetadataName).value()), |
161 lockfile_fd_(-1) { | 149 lockfile_fd_(-1) { |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 int SynchronizedMinidumpManager::AddEntryToLockFile(const DumpInfo& dump_info) { | 319 int SynchronizedMinidumpManager::AddEntryToLockFile(const DumpInfo& dump_info) { |
332 DCHECK_LE(0, lockfile_fd_); | 320 DCHECK_LE(0, lockfile_fd_); |
333 DCHECK(dumps_); | 321 DCHECK(dumps_); |
334 | 322 |
335 // Make sure dump_info is valid. | 323 // Make sure dump_info is valid. |
336 if (!dump_info.valid()) { | 324 if (!dump_info.valid()) { |
337 LOG(ERROR) << "Entry to be added is invalid"; | 325 LOG(ERROR) << "Entry to be added is invalid"; |
338 return -1; | 326 return -1; |
339 } | 327 } |
340 | 328 |
341 if (!CanWriteDumps(1)) { | |
342 LOG(ERROR) << "Can't Add Dump: Ratelimited"; | |
343 return -1; | |
344 } | |
345 | |
346 IncrementCurrentPeriodDumps(metadata_.get(), 1); | |
347 dumps_->Append(dump_info.GetAsValue()); | 329 dumps_->Append(dump_info.GetAsValue()); |
348 | 330 |
349 return 0; | 331 return 0; |
350 } | 332 } |
351 | 333 |
352 int SynchronizedMinidumpManager::RemoveEntryFromLockFile(int index) { | 334 int SynchronizedMinidumpManager::RemoveEntryFromLockFile(int index) { |
353 return dumps_->Remove(static_cast<size_t>(index), nullptr) ? 0 : -1; | 335 return dumps_->Remove(static_cast<size_t>(index), nullptr) ? 0 : -1; |
354 } | 336 } |
355 | 337 |
356 void SynchronizedMinidumpManager::ReleaseLockFile() { | 338 void SynchronizedMinidumpManager::ReleaseLockFile() { |
(...skipping 27 matching lines...) Expand all Loading... |
384 int SynchronizedMinidumpManager::SetCurrentDumps( | 366 int SynchronizedMinidumpManager::SetCurrentDumps( |
385 const ScopedVector<DumpInfo>& dumps) { | 367 const ScopedVector<DumpInfo>& dumps) { |
386 dumps_->Clear(); | 368 dumps_->Clear(); |
387 | 369 |
388 for (DumpInfo* dump : dumps) | 370 for (DumpInfo* dump : dumps) |
389 dumps_->Append(dump->GetAsValue()); | 371 dumps_->Append(dump->GetAsValue()); |
390 | 372 |
391 return 0; | 373 return 0; |
392 } | 374 } |
393 | 375 |
394 bool SynchronizedMinidumpManager::CanWriteDumps(int num_dumps) { | 376 int SynchronizedMinidumpManager::IncrementNumDumpsInCurrentPeriod() { |
395 const auto dumps(GetDumps()); | 377 DCHECK(metadata_); |
| 378 int last_dumps = GetRatelimitPeriodDumps(metadata_.get()); |
| 379 RCHECK(last_dumps >= 0, -1); |
396 | 380 |
397 // If no more dumps can be written, return false. | 381 return SetRatelimitPeriodDumps(metadata_.get(), last_dumps + 1); |
398 if (static_cast<int>(dumps.size()) + num_dumps > kMaxLockfileDumps) | 382 } |
399 return false; | |
400 | 383 |
401 // If too many dumps have been written recently, return false. | 384 bool SynchronizedMinidumpManager::CanUploadDump() { |
402 time_t cur_time = time(nullptr); | 385 time_t cur_time = time(nullptr); |
403 time_t period_start = GetRatelimitPeriodStart(metadata_.get()); | 386 time_t period_start = GetRatelimitPeriodStart(metadata_.get()); |
404 int period_dumps_count = GetRatelimitPeriodDumps(metadata_.get()); | 387 int period_dumps_count = GetRatelimitPeriodDumps(metadata_.get()); |
405 | 388 |
406 // If we're in invalid state, or we passed the period, reset the ratelimit. | 389 // If we're in invalid state, or we passed the period, reset the ratelimit. |
407 // When the device reboots, |cur_time| may be incorrectly reported to be a | 390 // When the device reboots, |cur_time| may be incorrectly reported to be a |
408 // very small number for a short period of time. So only consider | 391 // very small number for a short period of time. So only consider |
409 // |period_start| invalid when |cur_time| is less if |cur_time| is not very | 392 // |period_start| invalid when |cur_time| is less if |cur_time| is not very |
410 // close to 0. | 393 // close to 0. |
411 if (period_dumps_count < 0 || | 394 if (period_dumps_count < 0 || |
412 (cur_time < period_start && cur_time > kRatelimitPeriodSeconds) || | 395 (cur_time < period_start && cur_time > kRatelimitPeriodSeconds) || |
413 difftime(cur_time, period_start) >= kRatelimitPeriodSeconds) { | 396 difftime(cur_time, period_start) >= kRatelimitPeriodSeconds) { |
414 period_start = cur_time; | 397 period_start = cur_time; |
415 period_dumps_count = 0; | 398 period_dumps_count = 0; |
416 SetRatelimitPeriodStart(metadata_.get(), period_start); | 399 SetRatelimitPeriodStart(metadata_.get(), period_start); |
417 SetRatelimitPeriodDumps(metadata_.get(), period_dumps_count); | 400 SetRatelimitPeriodDumps(metadata_.get(), period_dumps_count); |
418 } | 401 } |
419 | 402 |
420 return period_dumps_count + num_dumps <= kRatelimitPeriodMaxDumps; | 403 return period_dumps_count < kRatelimitPeriodMaxDumps; |
421 } | 404 } |
422 | 405 |
423 } // namespace chromecast | 406 } // namespace chromecast |
OLD | NEW |