fake_drivefs_launcher_client.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright 2018 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.
  4. #include "ash/components/drivefs/fake_drivefs_launcher_client.h"
  5. #include <utility>
  6. #include <vector>
  7. #include "base/bind.h"
  8. #include "base/no_destructor.h"
  9. #include "base/strings/strcat.h"
  10. #include "base/strings/string_util.h"
  11. #include "base/system/sys_info.h"
  12. #include "base/task/thread_pool.h"
  13. #include "chromeos/ash/components/dbus/cros_disks/cros_disks_client.h"
  14. #include "chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.h"
  15. #include "chromeos/components/mojo_bootstrap/pending_connection_manager.h"
  16. #include "mojo/public/cpp/bindings/pending_receiver.h"
  17. #include "mojo/public/cpp/platform/named_platform_channel.h"
  18. #include "mojo/public/cpp/platform/platform_channel.h"
  19. #include "mojo/public/cpp/platform/platform_channel_endpoint.h"
  20. #include "mojo/public/cpp/system/invitation.h"
  21. #include "mojo/public/cpp/system/platform_handle.h"
  22. #include "url/gurl.h"
  23. namespace drivefs {
  24. namespace {
  25. void ConnectAsync(mojo::PendingReceiver<mojom::FakeDriveFsLauncher> receiver,
  26. mojo::NamedPlatformChannel::ServerName server_name) {
  27. mojo::PlatformChannelEndpoint endpoint =
  28. mojo::NamedPlatformChannel::ConnectToServer(server_name);
  29. if (!endpoint.is_valid())
  30. return;
  31. mojo::OutgoingInvitation invitation;
  32. mojo::FuseMessagePipes(invitation.AttachMessagePipe("drivefs-launcher"),
  33. receiver.PassPipe());
  34. mojo::OutgoingInvitation::Send(std::move(invitation),
  35. base::kNullProcessHandle, std::move(endpoint));
  36. }
  37. } // namespace
  38. // static
  39. void FakeDriveFsLauncherClient::Init(const base::FilePath& chroot_path,
  40. const base::FilePath& socket_path) {
  41. DCHECK(!base::SysInfo::IsRunningOnChromeOS());
  42. DCHECK(chroot_path.IsAbsolute());
  43. DCHECK(!socket_path.IsAbsolute());
  44. static base::NoDestructor<FakeDriveFsLauncherClient>
  45. fake_drivefs_launcher_client(chroot_path, socket_path);
  46. }
  47. FakeDriveFsLauncherClient::FakeDriveFsLauncherClient(
  48. const base::FilePath& chroot_path,
  49. const base::FilePath& socket_path)
  50. : chroot_path_(chroot_path),
  51. socket_path_(chroot_path_.Append(socket_path)) {
  52. base::ThreadPool::PostTask(
  53. FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
  54. base::BindOnce(&ConnectAsync, launcher_.BindNewPipeAndPassReceiver(),
  55. socket_path_.value()));
  56. static_cast<ash::FakeCrosDisksClient*>(ash::CrosDisksClient::Get())
  57. ->AddCustomMountPointCallback(
  58. base::BindRepeating(&FakeDriveFsLauncherClient::MaybeMountDriveFs,
  59. base::Unretained(this)));
  60. }
  61. FakeDriveFsLauncherClient::~FakeDriveFsLauncherClient() = default;
  62. base::FilePath FakeDriveFsLauncherClient::MaybeMountDriveFs(
  63. const std::string& source_path,
  64. const std::vector<std::string>& mount_options) {
  65. GURL source_url(source_path);
  66. DCHECK(source_url.is_valid());
  67. if (source_url.scheme() != "drivefs") {
  68. return {};
  69. }
  70. const auto identity = base::FilePath(source_url.path()).BaseName().value();
  71. std::string datadir_suffix;
  72. for (const auto& option : mount_options) {
  73. if (base::StartsWith(option, "datadir=", base::CompareCase::SENSITIVE)) {
  74. auto datadir =
  75. base::FilePath(base::StringPiece(option).substr(strlen("datadir=")));
  76. CHECK(datadir.IsAbsolute());
  77. CHECK(!datadir.ReferencesParent());
  78. datadir_suffix = datadir.BaseName().value();
  79. break;
  80. }
  81. }
  82. const std::string datadir = base::StrCat({"drivefs-", datadir_suffix});
  83. mojo::PlatformChannel channel;
  84. mojo_bootstrap::PendingConnectionManager::Get().OpenIpcChannel(
  85. identity, channel.TakeLocalEndpoint().TakePlatformHandle().TakeFD());
  86. launcher_->LaunchDriveFs(
  87. base::FilePath("/tmp").Append(datadir),
  88. base::FilePath("/media/fuse").Append(datadir),
  89. mojo::WrapPlatformHandle(
  90. channel.TakeRemoteEndpoint().TakePlatformHandle()));
  91. return chroot_path_.Append("media/fuse").Append(datadir);
  92. }
  93. } // namespace drivefs