diff options
Diffstat (limited to 'chromium/components/metrics/drive_metrics_provider_linux.cc')
-rw-r--r-- | chromium/components/metrics/drive_metrics_provider_linux.cc | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/chromium/components/metrics/drive_metrics_provider_linux.cc b/chromium/components/metrics/drive_metrics_provider_linux.cc new file mode 100644 index 00000000000..35c505a3492 --- /dev/null +++ b/chromium/components/metrics/drive_metrics_provider_linux.cc @@ -0,0 +1,65 @@ +// Copyright 2015 The Chromium 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 "components/metrics/drive_metrics_provider.h" + +#include <linux/kdev_t.h> // For MAJOR()/MINOR(). +#include <sys/stat.h> +#include <string> + +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/strings/stringprintf.h" +#include "build/build_config.h" + +#if defined(OS_CHROMEOS) +#include "base/sys_info.h" +#endif + +namespace metrics { + +namespace { + +// See http://www.kernel.org/doc/Documentation/devices.txt for more info. +const int kFirstScsiMajorNumber = 8; +const int kPartitionsPerScsiDevice = 16; +const char kRotationalFormat[] = "/sys/block/sd%c/queue/rotational"; + +} // namespace + +// static +bool DriveMetricsProvider::HasSeekPenalty(const base::FilePath& path, + bool* has_seek_penalty) { +#if defined(OS_CHROMEOS) + std::string board = base::SysInfo::GetLsbReleaseBoard(); + if (board != "unknown" && board != "parrot") { + // All ChromeOS devices have SSDs. Except some parrots. + *has_seek_penalty = false; + return true; + } +#endif + + base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); + if (!file.IsValid()) + return false; + + struct stat path_stat; + int error = fstat(file.GetPlatformFile(), &path_stat); + if (error < 0 || MAJOR(path_stat.st_dev) != kFirstScsiMajorNumber) { + // TODO(dbeam): support more SCSI major numbers (e.g. /dev/sdq+) and LVM? + return false; + } + + char sdX = 'a' + MINOR(path_stat.st_dev) / kPartitionsPerScsiDevice; + std::string rotational_path = base::StringPrintf(kRotationalFormat, sdX); + std::string rotates; + if (!base::ReadFileToString(base::FilePath(rotational_path), &rotates)) + return false; + + *has_seek_penalty = rotates.substr(0, 1) == "1"; + return true; +} + +} // namespace metrics |