Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(430)

Side by Side Diff: components/arc/arc_bridge_bootstrap.cc

Issue 2397863003: Move free disk space check to session_manager. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "components/arc/arc_bridge_bootstrap.h" 5 #include "components/arc/arc_bridge_bootstrap.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <grp.h> 8 #include <grp.h>
9 #include <poll.h> 9 #include <poll.h>
10 #include <unistd.h> 10 #include <unistd.h>
(...skipping 28 matching lines...) Expand all
39 39
40 namespace arc { 40 namespace arc {
41 41
42 namespace { 42 namespace {
43 43
44 const base::FilePath::CharType kArcBridgeSocketPath[] = 44 const base::FilePath::CharType kArcBridgeSocketPath[] =
45 FILE_PATH_LITERAL("/var/run/chrome/arc_bridge.sock"); 45 FILE_PATH_LITERAL("/var/run/chrome/arc_bridge.sock");
46 46
47 const char kArcBridgeSocketGroup[] = "arc-bridge"; 47 const char kArcBridgeSocketGroup[] = "arc-bridge";
48 48
49 const base::FilePath::CharType kDiskCheckPath[] = "/home"; 49 // TODO(hidehiko): Share the constant between Chrome and ChromeOS.
50 50 constexpr char kArcLowDiskError[] =
51 const int64_t kCriticalDiskFreeBytes = 64 << 20; // 64MB 51 "org.chromium.SessionManagerInterface.LowFreeDisk";
52 52
53 // This is called when StopArcInstance D-Bus method completes. Since we have the 53 // This is called when StopArcInstance D-Bus method completes. Since we have the
54 // ArcInstanceStopped() callback and are notified if StartArcInstance fails, we 54 // ArcInstanceStopped() callback and are notified if StartArcInstance fails, we
55 // don't need to do anything when StopArcInstance completes. 55 // don't need to do anything when StopArcInstance completes.
56 void DoNothingInstanceStopped(bool) {} 56 void DoNothingInstanceStopped(bool) {}
57 57
58 chromeos::SessionManagerClient* GetSessionManagerClient() { 58 chromeos::SessionManagerClient* GetSessionManagerClient() {
59 // If the DBusThreadManager or the SessionManagerClient aren't available, 59 // If the DBusThreadManager or the SessionManagerClient aren't available,
60 // there isn't much we can do. This should only happen when running tests. 60 // there isn't much we can do. This should only happen when running tests.
61 if (!chromeos::DBusThreadManager::IsInitialized() || 61 if (!chromeos::DBusThreadManager::IsInitialized() ||
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 // TODO(hidehiko): Refactor more to make this class unittest-able, for at least 108 // TODO(hidehiko): Refactor more to make this class unittest-able, for at least
109 // state-machine part. 109 // state-machine part.
110 class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap, 110 class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap,
111 public chromeos::SessionManagerClient::Observer { 111 public chromeos::SessionManagerClient::Observer {
112 public: 112 public:
113 // The possible states of the bootstrap connection. In the normal flow, 113 // The possible states of the bootstrap connection. In the normal flow,
114 // the state changes in the following sequence: 114 // the state changes in the following sequence:
115 // 115 //
116 // NOT_STARTED 116 // NOT_STARTED
117 // Start() -> 117 // Start() ->
118 // CHECKING_DISK_SPACE 118 // CHECKING_DISK_SPACE
Shuhei Takahashi 2016/10/06 08:21:03 Please update these comments to remove CHECKING_DI
hidehiko 2016/10/06 08:33:21 Good catch. Done.
119 // OnDiskSpaceChecked() -> 119 // OnDiskSpaceChecked() ->
120 // CREATING_SOCKET 120 // CREATING_SOCKET
121 // CreateSocket() -> OnSocketCreated() -> 121 // CreateSocket() -> OnSocketCreated() ->
122 // STARTING_INSTANCE 122 // STARTING_INSTANCE
123 // -> OnInstanceStarted() -> 123 // -> OnInstanceStarted() ->
124 // CONNECTING_MOJO 124 // CONNECTING_MOJO
125 // ConnectMojo() -> OnMojoConnected() -> 125 // ConnectMojo() -> OnMojoConnected() ->
126 // RUNNING 126 // RUNNING
127 // 127 //
128 // At any state, Stop() can be called. It does not immediately stop the 128 // At any state, Stop() can be called. It does not immediately stop the
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 // Specifically, in STOPPED state, there may be inflight operations or 179 // Specifically, in STOPPED state, there may be inflight operations or
180 // pending callbacks. Though, what they do is just do-nothing conceptually 180 // pending callbacks. Though, what they do is just do-nothing conceptually
181 // and they can be safely ignored. 181 // and they can be safely ignored.
182 // 182 //
183 // Note: Order of constants below matters. Please make sure to sort them 183 // Note: Order of constants below matters. Please make sure to sort them
184 // in chronological order. 184 // in chronological order.
185 enum class State { 185 enum class State {
186 // ARC is not yet started. 186 // ARC is not yet started.
187 NOT_STARTED, 187 NOT_STARTED,
188 188
189 // Checking the disk space.
190 CHECKING_DISK_SPACE,
191
192 // An UNIX socket is being created. 189 // An UNIX socket is being created.
193 CREATING_SOCKET, 190 CREATING_SOCKET,
194 191
195 // The request to start the instance has been sent. 192 // The request to start the instance has been sent.
196 STARTING_INSTANCE, 193 STARTING_INSTANCE,
197 194
198 // The instance has started. Waiting for it to connect to the IPC bridge. 195 // The instance has started. Waiting for it to connect to the IPC bridge.
199 CONNECTING_MOJO, 196 CONNECTING_MOJO,
200 197
201 // The instance is fully set up. 198 // The instance is fully set up.
202 RUNNING, 199 RUNNING,
203 200
204 // ARC is terminated. 201 // ARC is terminated.
205 STOPPED, 202 STOPPED,
206 }; 203 };
207 204
208 ArcBridgeBootstrapImpl(); 205 ArcBridgeBootstrapImpl();
209 ~ArcBridgeBootstrapImpl() override; 206 ~ArcBridgeBootstrapImpl() override;
210 207
211 // ArcBridgeBootstrap: 208 // ArcBridgeBootstrap:
212 void Start() override; 209 void Start() override;
213 void Stop() override; 210 void Stop() override;
214 211
215 private: 212 private:
216 // Called after getting the device free disk space.
217 void OnFreeDiskSpaceObtained(int64_t disk_free_bytes);
218
219 // Creates the UNIX socket on the bootstrap thread and then processes its 213 // Creates the UNIX socket on the bootstrap thread and then processes its
220 // file descriptor. 214 // file descriptor.
221 static base::ScopedFD CreateSocket(); 215 static base::ScopedFD CreateSocket();
222 void OnSocketCreated(base::ScopedFD fd); 216 void OnSocketCreated(base::ScopedFD fd);
223 217
224 // DBus callback for StartArcInstance(). 218 // DBus callback for StartArcInstance().
225 void OnInstanceStarted(base::ScopedFD socket_fd, bool success); 219 void OnInstanceStarted(base::ScopedFD socket_fd,
220 bool success,
221 const std::string& error);
226 222
227 // Synchronously accepts a connection on |socket_fd| and then processes the 223 // Synchronously accepts a connection on |socket_fd| and then processes the
228 // connected socket's file descriptor. 224 // connected socket's file descriptor.
229 static base::ScopedFD ConnectMojo(base::ScopedFD socket_fd, 225 static base::ScopedFD ConnectMojo(base::ScopedFD socket_fd,
230 base::ScopedFD cancel_fd); 226 base::ScopedFD cancel_fd);
231 void OnMojoConnected(base::ScopedFD fd); 227 void OnMojoConnected(base::ScopedFD fd);
232 228
233 // Request to stop ARC instance via DBus. 229 // Request to stop ARC instance via DBus.
234 void StopArcInstance(); 230 void StopArcInstance();
235 231
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 chromeos::SessionManagerClient* client = GetSessionManagerClient(); 272 chromeos::SessionManagerClient* client = GetSessionManagerClient();
277 if (client == nullptr) 273 if (client == nullptr)
278 return; 274 return;
279 client->RemoveObserver(this); 275 client->RemoveObserver(this);
280 } 276 }
281 277
282 void ArcBridgeBootstrapImpl::Start() { 278 void ArcBridgeBootstrapImpl::Start() {
283 DCHECK(thread_checker_.CalledOnValidThread()); 279 DCHECK(thread_checker_.CalledOnValidThread());
284 DCHECK_EQ(state_, State::NOT_STARTED); 280 DCHECK_EQ(state_, State::NOT_STARTED);
285 VLOG(2) << "Starting ARC session."; 281 VLOG(2) << "Starting ARC session.";
286 VLOG(2) << "Checking disk space..."; 282 VLOG(2) << "Disk space check is done. Creating socket...";
Shuhei Takahashi 2016/10/06 08:21:03 Could you remove this line?
hidehiko 2016/10/06 08:33:21 Done.
287 state_ = State::CHECKING_DISK_SPACE;
288 283
289 // TODO(crbug.com/628124): Move disk space checking logic to session_manager.
290 base::PostTaskAndReplyWithResult(
291 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE,
292 base::Bind(&base::SysInfo::AmountOfFreeDiskSpace,
293 base::FilePath(kDiskCheckPath)),
294 base::Bind(&ArcBridgeBootstrapImpl::OnFreeDiskSpaceObtained,
295 weak_factory_.GetWeakPtr()));
296 }
297
298 void ArcBridgeBootstrapImpl::OnFreeDiskSpaceObtained(int64_t disk_free_bytes) {
299 DCHECK(thread_checker_.CalledOnValidThread());
300 DCHECK_EQ(state_, State::CHECKING_DISK_SPACE);
301
302 if (stop_requested_) {
303 VLOG(1) << "Stop() called while checking disk space";
304 OnStopped(ArcBridgeService::StopReason::SHUTDOWN);
305 return;
306 }
307
308 if (disk_free_bytes < 0) {
309 LOG(ERROR) << "ARC: Failed to get free disk space";
310 OnStopped(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE);
311 return;
312 }
313 if (disk_free_bytes < kCriticalDiskFreeBytes) {
314 LOG(ERROR) << "ARC: The device is too low on disk space to start ARC";
315 OnStopped(ArcBridgeService::StopReason::LOW_DISK_SPACE);
316 return;
317 }
318
319 VLOG(2) << "Disk space check is done. Creating socket...";
320 state_ = State::CREATING_SOCKET; 284 state_ = State::CREATING_SOCKET;
321 base::PostTaskAndReplyWithResult( 285 base::PostTaskAndReplyWithResult(
322 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, 286 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE,
323 base::Bind(&ArcBridgeBootstrapImpl::CreateSocket), 287 base::Bind(&ArcBridgeBootstrapImpl::CreateSocket),
324 base::Bind(&ArcBridgeBootstrapImpl::OnSocketCreated, 288 base::Bind(&ArcBridgeBootstrapImpl::OnSocketCreated,
325 weak_factory_.GetWeakPtr())); 289 weak_factory_.GetWeakPtr()));
326 } 290 }
327 291
328 // static 292 // static
329 base::ScopedFD ArcBridgeBootstrapImpl::CreateSocket() { 293 base::ScopedFD ArcBridgeBootstrapImpl::CreateSocket() {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 chromeos::SessionManagerClient* session_manager_client = 356 chromeos::SessionManagerClient* session_manager_client =
393 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); 357 chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
394 session_manager_client->StartArcInstance( 358 session_manager_client->StartArcInstance(
395 cryptohome_id, 359 cryptohome_id,
396 disable_boot_completed_broadcast, 360 disable_boot_completed_broadcast,
397 base::Bind(&ArcBridgeBootstrapImpl::OnInstanceStarted, 361 base::Bind(&ArcBridgeBootstrapImpl::OnInstanceStarted,
398 weak_factory_.GetWeakPtr(), base::Passed(&socket_fd))); 362 weak_factory_.GetWeakPtr(), base::Passed(&socket_fd)));
399 } 363 }
400 364
401 void ArcBridgeBootstrapImpl::OnInstanceStarted(base::ScopedFD socket_fd, 365 void ArcBridgeBootstrapImpl::OnInstanceStarted(base::ScopedFD socket_fd,
402 bool success) { 366 bool success,
367 const std::string& error) {
403 DCHECK(thread_checker_.CalledOnValidThread()); 368 DCHECK(thread_checker_.CalledOnValidThread());
404 if (state_ == State::STOPPED) { 369 if (state_ == State::STOPPED) {
405 // This is the case that error is notified via DBus before the 370 // This is the case that error is notified via DBus before the
406 // OnInstanceStarted() callback is invoked. The stopping procedure has 371 // OnInstanceStarted() callback is invoked. The stopping procedure has
407 // been run, so do nothing. 372 // been run, so do nothing.
408 return; 373 return;
409 } 374 }
410 375
411 DCHECK_EQ(state_, State::STARTING_INSTANCE); 376 DCHECK_EQ(state_, State::STARTING_INSTANCE);
412 377
413 if (stop_requested_) { 378 if (stop_requested_) {
414 if (success) { 379 if (success) {
415 // The ARC instance has started to run. Request to stop. 380 // The ARC instance has started to run. Request to stop.
416 StopArcInstance(); 381 StopArcInstance();
417 return; 382 return;
418 } 383 }
419 OnStopped(ArcBridgeService::StopReason::SHUTDOWN); 384 OnStopped(ArcBridgeService::StopReason::SHUTDOWN);
420 return; 385 return;
421 } 386 }
422 387
423 if (!success) { 388 if (!success) {
424 LOG(ERROR) << "Failed to start ARC instance"; 389 LOG(ERROR) << "Failed to start ARC instance";
425 OnStopped(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE); 390 OnStopped(error == kArcLowDiskError
391 ? ArcBridgeService::StopReason::LOW_DISK_SPACE
392 : ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE);
426 return; 393 return;
427 } 394 }
428 395
429 VLOG(2) << "ARC instance is successfully started. Connecting Mojo..."; 396 VLOG(2) << "ARC instance is successfully started. Connecting Mojo...";
430 state_ = State::CONNECTING_MOJO; 397 state_ = State::CONNECTING_MOJO;
431 398
432 // Prepare a pipe so that AcceptInstanceConnection can be interrupted on 399 // Prepare a pipe so that AcceptInstanceConnection can be interrupted on
433 // Stop(). 400 // Stop().
434 base::ScopedFD cancel_fd; 401 base::ScopedFD cancel_fd;
435 if (!CreatePipe(&cancel_fd, &accept_cancel_pipe_)) { 402 if (!CreatePipe(&cancel_fd, &accept_cancel_pipe_)) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 if (stop_requested_) 500 if (stop_requested_)
534 return; 501 return;
535 502
536 stop_requested_ = true; 503 stop_requested_ = true;
537 arc_bridge_host_.reset(); 504 arc_bridge_host_.reset();
538 switch (state_) { 505 switch (state_) {
539 case State::NOT_STARTED: 506 case State::NOT_STARTED:
540 OnStopped(ArcBridgeService::StopReason::SHUTDOWN); 507 OnStopped(ArcBridgeService::StopReason::SHUTDOWN);
541 return; 508 return;
542 509
543 case State::CHECKING_DISK_SPACE:
544 case State::CREATING_SOCKET: 510 case State::CREATING_SOCKET:
545 case State::STARTING_INSTANCE: 511 case State::STARTING_INSTANCE:
546 // Before starting the ARC instance, we do nothing here. 512 // Before starting the ARC instance, we do nothing here.
547 // At some point, a callback will be invoked on UI thread, 513 // At some point, a callback will be invoked on UI thread,
548 // and stopping procedure will be run there. 514 // and stopping procedure will be run there.
549 // On Chrome shutdown, it is not the case because the message loop is 515 // On Chrome shutdown, it is not the case because the message loop is
550 // already stopped here. Practically, it is not a problem because; 516 // already stopped here. Practically, it is not a problem because;
551 // - On disk space checking or on socket creating, it is ok to simply 517 // - On disk space checking or on socket creating, it is ok to simply
552 // ignore such cases, because we no-longer continue the bootstrap 518 // ignore such cases, because we no-longer continue the bootstrap
553 // procedure. 519 // procedure.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 void ArcBridgeBootstrap::RemoveObserver(Observer* observer) { 603 void ArcBridgeBootstrap::RemoveObserver(Observer* observer) {
638 observer_list_.RemoveObserver(observer); 604 observer_list_.RemoveObserver(observer);
639 } 605 }
640 606
641 // static 607 // static
642 std::unique_ptr<ArcBridgeBootstrap> ArcBridgeBootstrap::Create() { 608 std::unique_ptr<ArcBridgeBootstrap> ArcBridgeBootstrap::Create() {
643 return base::MakeUnique<ArcBridgeBootstrapImpl>(); 609 return base::MakeUnique<ArcBridgeBootstrapImpl>();
644 } 610 }
645 611
646 } // namespace arc 612 } // namespace arc
OLDNEW
« chromeos/dbus/session_manager_client.cc ('K') | « chromeos/dbus/session_manager_client.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698