Ensure low-memory renderers retry failed loads correctly.
[chromium-blink-merge.git] / components / storage_monitor / mtab_watcher_linux.cc
blob31dda98606c3374e47c5562376adcdad1fb2f07d
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // MtabWatcherLinux implementation.
7 #include "components/storage_monitor/mtab_watcher_linux.h"
9 #include <mntent.h>
10 #include <stdio.h>
12 #include "base/bind.h"
13 #include "content/public/browser/browser_thread.h"
15 namespace {
17 // List of file systems we care about.
18 const char* const kKnownFileSystems[] = {
19 "btrfs",
20 "ext2",
21 "ext3",
22 "ext4",
23 "fat",
24 "hfsplus",
25 "iso9660",
26 "msdos",
27 "ntfs",
28 "udf",
29 "vfat",
32 } // namespace
34 namespace storage_monitor {
36 MtabWatcherLinux::MtabWatcherLinux(const base::FilePath& mtab_path,
37 base::WeakPtr<Delegate> delegate)
38 : mtab_path_(mtab_path),
39 delegate_(delegate),
40 weak_ptr_factory_(this) {
41 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
42 bool ret = file_watcher_.Watch(
43 mtab_path_, false,
44 base::Bind(&MtabWatcherLinux::OnFilePathChanged,
45 weak_ptr_factory_.GetWeakPtr()));
46 if (!ret) {
47 LOG(ERROR) << "Adding watch for " << mtab_path_.value() << " failed";
48 return;
51 ReadMtab();
54 MtabWatcherLinux::~MtabWatcherLinux() {
55 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
58 void MtabWatcherLinux::ReadMtab() const {
59 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
61 FILE* fp = setmntent(mtab_path_.value().c_str(), "r");
62 if (!fp)
63 return;
65 MountPointDeviceMap device_map;
66 mntent entry;
67 char buf[512];
69 // We return the same device mounted to multiple locations, but hide
70 // devices that have been mounted over.
71 while (getmntent_r(fp, &entry, buf, sizeof(buf))) {
72 // We only care about real file systems.
73 for (size_t i = 0; i < arraysize(kKnownFileSystems); ++i) {
74 if (strcmp(kKnownFileSystems[i], entry.mnt_type) == 0) {
75 device_map[base::FilePath(entry.mnt_dir)] =
76 base::FilePath(entry.mnt_fsname);
77 break;
81 endmntent(fp);
83 content::BrowserThread::PostTask(
84 content::BrowserThread::UI, FROM_HERE,
85 base::Bind(&Delegate::UpdateMtab, delegate_, device_map));
88 void MtabWatcherLinux::OnFilePathChanged(
89 const base::FilePath& path, bool error) {
90 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
92 if (path != mtab_path_) {
93 // This cannot happen unless FilePathWatcher is buggy. Just ignore this
94 // notification and do nothing.
95 NOTREACHED();
96 return;
98 if (error) {
99 LOG(ERROR) << "Error watching " << mtab_path_.value();
100 return;
103 ReadMtab();
106 } // namespace storage_monitor