File: crostini_sshfs.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (121 lines) | stat: -rw-r--r-- 4,533 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_CROSTINI_CROSTINI_SSHFS_H_
#define CHROME_BROWSER_ASH_CROSTINI_CROSTINI_SSHFS_H_

#include <queue>
#include <set>
#include <utility>

#include "base/files/file_path.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "chrome/browser/ash/crostini/crostini_manager.h"
#include "chromeos/ash/components/disks/disk_mount_manager.h"

namespace crostini {

class CrostiniSshfs : ContainerShutdownObserver {
 public:
  explicit CrostiniSshfs(Profile* profile);

  CrostiniSshfs(const CrostiniSshfs&) = delete;
  CrostiniSshfs& operator=(const CrostiniSshfs&) = delete;

  ~CrostiniSshfs() override;
  using MountCrostiniFilesCallback = base::OnceCallback<void(bool succeeded)>;

  // Mounts the user's Crostini home directory so it's accessible from the host.
  // Must be called from the UI thread, no-op if the home directory is already
  // mounted. If this is something running in the background set background to
  // true, if failures are user-visible set it to false. If you're setting
  // base::DoNothing as the callback then background should be true.
  void MountCrostiniFiles(const guest_os::GuestId& container_id,
                          MountCrostiniFilesCallback callback,
                          bool background);

  // Unmounts the user's Crostini home directory. Must be called from the UI
  // thread.
  void UnmountCrostiniFiles(const guest_os::GuestId& container_id,
                            MountCrostiniFilesCallback callback);

  // ContainerShutdownObserver.
  void OnContainerShutdown(const guest_os::GuestId& container_id) override;

  void OnMountEvent(ash::MountError error_code,
                    const ash::disks::DiskMountManager::MountPoint& mount_info);

  // Returns true if sshfs is mounted for the specified container, else false.
  bool IsSshfsMounted(const guest_os::GuestId& container);

  // Only public so unit tests can reference them without needing to FRIEND_TEST
  // every single test case.
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class CrostiniSshfsResult {
    kSuccess = 0,
    kNotDefaultContainer = 1,
    kContainerNotRunning = 2,
    kGetSshKeysFailed = 3,
    kGetContainerInfoFailed = 4,
    kMountErrorInternal = 5,
    kMountErrorProgramFailed = 6,
    kMountErrorOther = 7,
    kMaxValue = kMountErrorOther,
  };

 private:
  void SetSshfsMounted(const guest_os::GuestId& container, bool mounted);
  void Finish(CrostiniSshfsResult result);

  void OnRemoveSshfsCrostiniVolume(const guest_os::GuestId& container_id,
                                   MountCrostiniFilesCallback callback,
                                   base::Time started,
                                   bool success);

  struct InProgressMount {
    std::string source_path;
    guest_os::GuestId container_id;
    base::FilePath container_homedir;
    MountCrostiniFilesCallback callback;
    base::Time started;
    bool background;
    InProgressMount(const guest_os::GuestId& container,
                    MountCrostiniFilesCallback callback,
                    bool background);
    InProgressMount(InProgressMount&& other) noexcept;
    InProgressMount& operator=(InProgressMount&& other) noexcept;
    ~InProgressMount();
  };
  struct PendingRequest {
    guest_os::GuestId container_id;
    MountCrostiniFilesCallback callback;
    bool background;
    PendingRequest(const guest_os::GuestId& container_id,
                   MountCrostiniFilesCallback callback,
                   bool background);
    PendingRequest(PendingRequest&& other) noexcept;
    PendingRequest& operator=(PendingRequest&& other) noexcept;
    ~PendingRequest();
  };
  raw_ptr<Profile> profile_;

  base::ScopedObservation<CrostiniManager, ContainerShutdownObserver>
      container_shutdown_observer_{this};

  std::unique_ptr<InProgressMount> in_progress_mount_;

  std::set<guest_os::GuestId> sshfs_mounted_;
  std::queue<PendingRequest> pending_requests_;

  // Note: This should remain the last member so it'll be destroyed and
  // invalidate its weak pointers before any other members are destroyed.
  base::WeakPtrFactory<CrostiniSshfs> weak_ptr_factory_{this};
};
}  // namespace crostini

#endif  // CHROME_BROWSER_ASH_CROSTINI_CROSTINI_SSHFS_H_