| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #define NACL_LOG_MODULE_NAME "Plugin::ServiceRuntime" | 7 #define NACL_LOG_MODULE_NAME "Plugin::ServiceRuntime" |
| 8 | 8 |
| 9 #include "ppapi/native_client/src/trusted/plugin/service_runtime.h" | 9 #include "ppapi/native_client/src/trusted/plugin/service_runtime.h" |
| 10 | 10 |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 NaClXCondVarCtor(&cond_); | 490 NaClXCondVarCtor(&cond_); |
| 491 } | 491 } |
| 492 | 492 |
| 493 bool ServiceRuntime::LoadModule(nacl::DescWrapper* nacl_desc, | 493 bool ServiceRuntime::LoadModule(nacl::DescWrapper* nacl_desc, |
| 494 ErrorInfo* error_info) { | 494 ErrorInfo* error_info) { |
| 495 NaClLog(4, "ServiceRuntime::LoadModule" | 495 NaClLog(4, "ServiceRuntime::LoadModule" |
| 496 " (this=%p, subprocess=%p)\n", | 496 " (this=%p, subprocess=%p)\n", |
| 497 static_cast<void*>(this), | 497 static_cast<void*>(this), |
| 498 static_cast<void*>(subprocess_.get())); | 498 static_cast<void*>(subprocess_.get())); |
| 499 CHECK(nacl_desc); | 499 CHECK(nacl_desc); |
| 500 |
| 500 // Create the command channel to the sel_ldr and load the nexe from nacl_desc. | 501 // Create the command channel to the sel_ldr and load the nexe from nacl_desc. |
| 501 if (!subprocess_->SetupCommand(&command_channel_)) { | 502 if (!subprocess_->SetupCommand(&command_channel_)) { |
| 502 error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL, | 503 error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL, |
| 503 "ServiceRuntime: command channel creation failed"); | 504 "ServiceRuntime: command channel creation failed"); |
| 504 return false; | 505 return false; |
| 505 } | 506 } |
| 507 struct NaClDesc *desc = nacl_desc->desc(); |
| 508 if (NACL_VTBL(NaClDesc, desc)->typeTag != NACL_DESC_HOST_IO) |
| 509 return false; |
| 510 PP_FileHandle h = ((struct NaClDescIoDesc *) desc)->hd->d; |
| 511 uint32_t nacl_error_code; |
| 512 PP_Bool ok = plugin_->nacl_interface()->LoadModule( |
| 513 plugin_->pp_instance(), h, &nacl_error_code); |
| 514 if (ok == PP_FALSE) |
| 515 return false; |
| 506 | 516 |
| 507 if (!subprocess_->LoadModule(&command_channel_, nacl_desc)) { | 517 if (main_service_runtime_) |
| 508 error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL, | 518 plugin_->ReportSelLdrLoadStatus(nacl_error_code); |
| 509 "ServiceRuntime: load module failed"); | 519 |
| 520 if (LOAD_OK != nacl_error_code) { |
| 521 error_info->SetReport( |
| 522 ERROR_SEL_LDR_START_STATUS, |
| 523 NaClErrorString(static_cast<NaClErrorCode>(nacl_error_code))); |
| 510 return false; | 524 return false; |
| 511 } | 525 } |
| 526 |
| 527 fprintf(stderr, "LoadModule finished\n"); |
| 512 return true; | 528 return true; |
| 513 } | 529 } |
| 514 | 530 |
| 515 bool ServiceRuntime::InitReverseService(ErrorInfo* error_info) { | 531 bool ServiceRuntime::InitReverseService(ErrorInfo* error_info) { |
| 516 // Hook up the reverse service channel. We are the IMC client, but | 532 // Hook up the reverse service channel. We are the IMC client, but |
| 517 // provide SRPC service. | 533 // provide SRPC service. |
| 518 NaClDesc* out_conn_cap; | 534 NaClDesc* out_conn_cap; |
| 519 NaClSrpcResultCodes rpc_result = | 535 NaClSrpcResultCodes rpc_result = |
| 520 NaClSrpcInvokeBySignature(&command_channel_, | 536 NaClSrpcInvokeBySignature(&command_channel_, |
| 521 "reverse_setup::h", | 537 "reverse_setup::h", |
| (...skipping 23 matching lines...) Expand all Loading... |
| 545 "ServiceRuntime: starting reverse services failed"); | 561 "ServiceRuntime: starting reverse services failed"); |
| 546 return false; | 562 return false; |
| 547 } | 563 } |
| 548 return true; | 564 return true; |
| 549 } | 565 } |
| 550 | 566 |
| 551 bool ServiceRuntime::StartModule(ErrorInfo* error_info) { | 567 bool ServiceRuntime::StartModule(ErrorInfo* error_info) { |
| 552 // start the module. otherwise we cannot connect for multimedia | 568 // start the module. otherwise we cannot connect for multimedia |
| 553 // subsystem since that is handled by user-level code (not secure!) | 569 // subsystem since that is handled by user-level code (not secure!) |
| 554 // in libsrpc. | 570 // in libsrpc. |
| 555 int load_status = -1; | 571 PP_Bool ok = plugin_->nacl_interface()->StartModule(plugin_->pp_instance()); |
| 556 NaClSrpcResultCodes rpc_result = | 572 return PP_ToBool(ok); |
| 557 NaClSrpcInvokeBySignature(&command_channel_, | |
| 558 "start_module::i", | |
| 559 &load_status); | |
| 560 | |
| 561 if (NACL_SRPC_RESULT_OK != rpc_result) { | |
| 562 error_info->SetReport(ERROR_SEL_LDR_START_MODULE, | |
| 563 "ServiceRuntime: could not start nacl module"); | |
| 564 return false; | |
| 565 } | |
| 566 NaClLog(4, "ServiceRuntime::StartModule (load_status=%d)\n", | |
| 567 load_status); | |
| 568 if (main_service_runtime_) { | |
| 569 plugin_->ReportSelLdrLoadStatus(load_status); | |
| 570 } | |
| 571 if (LOAD_OK != load_status) { | |
| 572 error_info->SetReport( | |
| 573 ERROR_SEL_LDR_START_STATUS, | |
| 574 NaClErrorString(static_cast<NaClErrorCode>(load_status))); | |
| 575 return false; | |
| 576 } | |
| 577 return true; | |
| 578 } | 573 } |
| 579 | 574 |
| 580 bool ServiceRuntime::StartSelLdr(const SelLdrStartParams& params) { | 575 void ServiceRuntime::StartSelLdr(const SelLdrStartParams& params, |
| 576 PP_CompletionCallback callback) { |
| 581 NaClLog(4, "ServiceRuntime::Start\n"); | 577 NaClLog(4, "ServiceRuntime::Start\n"); |
| 582 | 578 |
| 583 nacl::scoped_ptr<SelLdrLauncherChrome> | 579 nacl::scoped_ptr<SelLdrLauncherChrome> |
| 584 tmp_subprocess(new SelLdrLauncherChrome()); | 580 tmp_subprocess(new SelLdrLauncherChrome()); |
| 585 if (NULL == tmp_subprocess.get()) { | 581 if (NULL == tmp_subprocess.get()) { |
| 586 NaClLog(LOG_ERROR, "ServiceRuntime::Start (subprocess create failed)\n"); | 582 NaClLog(LOG_ERROR, "ServiceRuntime::Start (subprocess create failed)\n"); |
| 587 if (main_service_runtime_) { | 583 if (main_service_runtime_) { |
| 588 ErrorInfo error_info; | 584 ErrorInfo error_info; |
| 589 error_info.SetReport( | 585 error_info.SetReport( |
| 590 ERROR_SEL_LDR_CREATE_LAUNCHER, | 586 ERROR_SEL_LDR_CREATE_LAUNCHER, |
| 591 "ServiceRuntime: failed to create sel_ldr launcher"); | 587 "ServiceRuntime: failed to create sel_ldr launcher"); |
| 592 plugin_->ReportLoadError(error_info); | 588 plugin_->ReportLoadError(error_info); |
| 593 } | 589 } |
| 594 return false; | 590 PP_RunCompletionCallback(&callback, PP_ERROR_FAILED); |
| 591 return; |
| 595 } | 592 } |
| 596 nacl::string error_message; | 593 tmp_subprocess->Start(plugin_->pp_instance(), |
| 597 bool started = tmp_subprocess->Start(plugin_->pp_instance(), | 594 params.url.c_str(), |
| 598 params.url.c_str(), | 595 params.uses_irt, |
| 599 params.uses_irt, | 596 params.uses_ppapi, |
| 600 params.uses_ppapi, | 597 params.enable_dev_interfaces, |
| 601 params.enable_dev_interfaces, | 598 params.enable_dyncode_syscalls, |
| 602 params.enable_dyncode_syscalls, | 599 params.enable_exception_handling, |
| 603 params.enable_exception_handling, | 600 params.enable_crash_throttling, |
| 604 params.enable_crash_throttling, | 601 &start_sel_ldr_error_message_, // FIXME: Use. |
| 605 &error_message); | 602 callback); |
| 606 if (!started) { | |
| 607 NaClLog(LOG_ERROR, "ServiceRuntime::Start (start failed)\n"); | |
| 608 if (main_service_runtime_) { | |
| 609 ErrorInfo error_info; | |
| 610 error_info.SetReportWithConsoleOnlyError( | |
| 611 ERROR_SEL_LDR_LAUNCH, | |
| 612 "ServiceRuntime: failed to start", | |
| 613 error_message); | |
| 614 plugin_->ReportLoadError(error_info); | |
| 615 } | |
| 616 return false; | |
| 617 } | |
| 618 | |
| 619 subprocess_.reset(tmp_subprocess.release()); | 603 subprocess_.reset(tmp_subprocess.release()); |
| 620 NaClLog(4, "ServiceRuntime::StartSelLdr (return 1)\n"); | |
| 621 return true; | |
| 622 } | 604 } |
| 623 | 605 |
| 624 void ServiceRuntime::WaitForSelLdrStart() { | 606 void ServiceRuntime::WaitForSelLdrStart() { |
| 625 nacl::MutexLocker take(&mu_); | 607 nacl::MutexLocker take(&mu_); |
| 626 while(!start_sel_ldr_done_) { | 608 while(!start_sel_ldr_done_) { |
| 627 NaClXCondVarWait(&cond_, &mu_); | 609 NaClXCondVarWait(&cond_, &mu_); |
| 628 } | 610 } |
| 629 } | 611 } |
| 630 | 612 |
| 631 void ServiceRuntime::SignalStartSelLdrDone() { | 613 void ServiceRuntime::SignalStartSelLdrDone() { |
| 632 nacl::MutexLocker take(&mu_); | 614 nacl::MutexLocker take(&mu_); |
| 633 start_sel_ldr_done_ = true; | 615 start_sel_ldr_done_ = true; |
| 634 NaClXCondVarSignal(&cond_); | 616 NaClXCondVarSignal(&cond_); |
| 635 } | 617 } |
| 636 | 618 |
| 637 bool ServiceRuntime::LoadNexeAndStart(nacl::DescWrapper* nacl_desc, | 619 bool ServiceRuntime::LoadNexeAndStart(nacl::DescWrapper* nacl_desc, |
| 638 const pp::CompletionCallback& crash_cb) { | 620 const pp::CompletionCallback& crash_cb) { |
| 639 NaClLog(4, "ServiceRuntime::LoadNexeAndStart (nacl_desc=%p)\n", | 621 NaClLog(4, "ServiceRuntime::LoadNexeAndStart (nacl_desc=%p)\n", |
| 640 reinterpret_cast<void*>(nacl_desc)); | 622 reinterpret_cast<void*>(nacl_desc)); |
| 641 ErrorInfo error_info; | 623 ErrorInfo error_info; |
| 642 bool ok = LoadModule(nacl_desc, &error_info) && | 624 bool ok = LoadModule(nacl_desc, &error_info) && |
| 643 InitReverseService(&error_info) && | 625 InitReverseService(&error_info); |
| 644 StartModule(&error_info); | 626 StartModule(&error_info); |
| 645 if (!ok) { | 627 if (!ok) { |
| 646 if (main_service_runtime_) { | 628 if (main_service_runtime_) { |
| 647 plugin_->ReportLoadError(error_info); | 629 plugin_->ReportLoadError(error_info); |
| 648 } | 630 } |
| 649 // On a load failure the service runtime does not crash itself to | 631 // On a load failure the service runtime does not crash itself to |
| 650 // avoid a race where the no-more-senders error on the reverse | 632 // avoid a race where the no-more-senders error on the reverse |
| 651 // channel esrvice thread might cause the crash-detection logic to | 633 // channel esrvice thread might cause the crash-detection logic to |
| 652 // kick in before the start_module RPC reply has been received. So | 634 // kick in before the start_module RPC reply has been received. So |
| 653 // we induce a service runtime crash here. We do not release | 635 // we induce a service runtime crash here. We do not release |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 | 729 |
| 748 nacl::string ServiceRuntime::GetCrashLogOutput() { | 730 nacl::string ServiceRuntime::GetCrashLogOutput() { |
| 749 if (NULL != subprocess_.get()) { | 731 if (NULL != subprocess_.get()) { |
| 750 return subprocess_->GetCrashLogOutput(); | 732 return subprocess_->GetCrashLogOutput(); |
| 751 } else { | 733 } else { |
| 752 return std::string(); | 734 return std::string(); |
| 753 } | 735 } |
| 754 } | 736 } |
| 755 | 737 |
| 756 } // namespace plugin | 738 } // namespace plugin |
| OLD | NEW |