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

Side by Side Diff: chrome/nacl/nacl_fork_delegate_linux.cc

Issue 8342017: Add UMA reports for Linux nacl_helper startup status (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/common/nacl_fork_delegate_linux.h" 5 #include "chrome/common/nacl_fork_delegate_linux.h"
6 6
7 #include <signal.h> 7 #include <signal.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <sys/socket.h> 9 #include <sys/socket.h>
10 10
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/eintr_wrapper.h" 13 #include "base/eintr_wrapper.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/file_path.h" 15 #include "base/file_path.h"
16 #include "base/path_service.h" 16 #include "base/path_service.h"
17 #include "base/process_util.h" 17 #include "base/process_util.h"
18 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 18 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
19 #include "content/common/unix_domain_socket_posix.h" 19 #include "content/common/unix_domain_socket_posix.h"
20 #include "content/common/zygote_fork_delegate_linux.h" 20 #include "content/common/zygote_fork_delegate_linux.h"
21 #include "chrome/common/chrome_paths.h" 21 #include "chrome/common/chrome_paths.h"
22 #include "chrome/common/chrome_switches.h" 22 #include "chrome/common/chrome_switches.h"
23 #include "chrome/common/nacl_helper_linux.h" 23 #include "chrome/common/nacl_helper_linux.h"
24 24
25 NaClForkDelegate::NaClForkDelegate() 25 NaClForkDelegate::NaClForkDelegate()
26 : ready_(false), 26 : status_(kNaClHelperUnused),
27 sandboxed_(false), 27 sandboxed_(false),
28 fd_(-1) {} 28 fd_(-1) {}
29 29
30 const char kNaClHelperAtZero[] = "--at-zero"; 30 const char kNaClHelperAtZero[] = "--at-zero";
31 31
32 void NaClForkDelegate::Init(const bool sandboxed, 32 void NaClForkDelegate::Init(const bool sandboxed,
33 const int browserdesc, 33 const int browserdesc,
34 const int sandboxdesc) { 34 const int sandboxdesc) {
35 VLOG(1) << "NaClForkDelegate::Init()"; 35 VLOG(1) << "NaClForkDelegate::Init()";
36 int fds[2]; 36 int fds[2];
37 37
38 sandboxed_ = sandboxed; 38 sandboxed_ = sandboxed;
39 // Confirm a couple hard-wired assumptions. 39 // Confirm a couple hard-wired assumptions.
40 // The NaCl constants are from chrome/nacl/nacl_linux_helper.h 40 // The NaCl constants are from chrome/nacl/nacl_linux_helper.h
41 DCHECK(kNaClBrowserDescriptor == browserdesc); 41 DCHECK(kNaClBrowserDescriptor == browserdesc);
42 DCHECK(kNaClSandboxDescriptor == sandboxdesc); 42 DCHECK(kNaClSandboxDescriptor == sandboxdesc);
43 43
44 CHECK(socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds) == 0); 44 CHECK(socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds) == 0);
45 base::file_handle_mapping_vector fds_to_map; 45 base::file_handle_mapping_vector fds_to_map;
46 fds_to_map.push_back(std::make_pair(fds[1], kNaClZygoteDescriptor)); 46 fds_to_map.push_back(std::make_pair(fds[1], kNaClZygoteDescriptor));
47 fds_to_map.push_back(std::make_pair(sandboxdesc, kNaClSandboxDescriptor)); 47 fds_to_map.push_back(std::make_pair(sandboxdesc, kNaClSandboxDescriptor));
48 ready_ = false;
49 FilePath helper_exe; 48 FilePath helper_exe;
50 FilePath helper_bootstrap_exe; 49 FilePath helper_bootstrap_exe;
51 if (PathService::Get(chrome::FILE_NACL_HELPER, &helper_exe) && 50 if (!PathService::Get(chrome::FILE_NACL_HELPER, &helper_exe)) {
52 PathService::Get(chrome::FILE_NACL_HELPER_BOOTSTRAP, 51 status_ = kNaClHelperMissing;
53 &helper_bootstrap_exe) && 52 } else if (!PathService::Get(chrome::FILE_NACL_HELPER_BOOTSTRAP,
54 !RunningOnValgrind()) { 53 &helper_bootstrap_exe)) {
54 status_ = kNaClHelperBootstrapMissing;
55 } else if (RunningOnValgrind()) {
56 status_ = kNaClHelperValgrind;
57 } else {
58 status_ = kNaClHelperLaunchFailed;
55 CommandLine cmd_line(helper_bootstrap_exe); 59 CommandLine cmd_line(helper_bootstrap_exe);
56 cmd_line.AppendArgPath(helper_exe); 60 cmd_line.AppendArgPath(helper_exe);
57 cmd_line.AppendArgNative(kNaClHelperAtZero); 61 cmd_line.AppendArgNative(kNaClHelperAtZero);
58 base::LaunchOptions options; 62 base::LaunchOptions options;
59 options.fds_to_remap = &fds_to_map; 63 options.fds_to_remap = &fds_to_map;
60 options.clone_flags = CLONE_FS | SIGCHLD; 64 options.clone_flags = CLONE_FS | SIGCHLD;
61 ready_ = base::LaunchProcess(cmd_line.argv(), options, NULL); 65 if (base::LaunchProcess(cmd_line.argv(), options, NULL))
agl 2011/10/19 16:17:27 This looks so much like a bug that I strongly urge
Roland McGrath 2011/10/19 18:34:15 Done.
66 status_ = kNaClHelperAckFailed;
62 // parent and error cases are handled below 67 // parent and error cases are handled below
63 } 68 }
64 if (HANDLE_EINTR(close(fds[1])) != 0) 69 if (HANDLE_EINTR(close(fds[1])) != 0)
65 LOG(ERROR) << "close(fds[1]) failed"; 70 LOG(ERROR) << "close(fds[1]) failed";
66 if (ready_) { 71 if (status_ == kNaClHelperAckFailed) {
67 const ssize_t kExpectedLength = strlen(kNaClHelperStartupAck); 72 const ssize_t kExpectedLength = strlen(kNaClHelperStartupAck);
68 char buf[kExpectedLength]; 73 char buf[kExpectedLength];
69 74
70 // Wait for ack from nacl_helper, indicating it is ready to help 75 // Wait for ack from nacl_helper, indicating it is ready to help
71 const ssize_t nread = HANDLE_EINTR(read(fds[0], buf, sizeof(buf))); 76 const ssize_t nread = HANDLE_EINTR(read(fds[0], buf, sizeof(buf)));
72 if (nread == kExpectedLength && 77 if (nread == kExpectedLength &&
73 memcmp(buf, kNaClHelperStartupAck, nread) == 0) { 78 memcmp(buf, kNaClHelperStartupAck, nread) == 0) {
74 // all is well 79 // all is well
80 status_ = kNaClHelperSuccess;
75 fd_ = fds[0]; 81 fd_ = fds[0];
76 return; 82 return;
77 } 83 }
78 LOG(ERROR) << "Bad NaCl helper startup ack (" << nread << " bytes)"; 84 LOG(ERROR) << "Bad NaCl helper startup ack (" << nread << " bytes)";
79 } 85 }
80 // TODO(bradchen): Make this LOG(ERROR) when the NaCl helper 86 // TODO(bradchen): Make this LOG(ERROR) when the NaCl helper
81 // becomes the default. 87 // becomes the default.
82 ready_ = false;
83 fd_ = -1; 88 fd_ = -1;
84 if (HANDLE_EINTR(close(fds[0])) != 0) 89 if (HANDLE_EINTR(close(fds[0])) != 0)
85 LOG(ERROR) << "close(fds[0]) failed"; 90 LOG(ERROR) << "close(fds[0]) failed";
86 } 91 }
87 92
93 void NaClForkDelegate::InitialUMA(std::string* uma_name,
94 int* uma_sample,
95 int* uma_boundary_value) {
96 *uma_name = "NaCl.Client.Helper.InitState";
97 *uma_sample = status_;
98 *uma_boundary_value = kNaClHelperStatusBoundary;
99 }
100
88 NaClForkDelegate::~NaClForkDelegate() { 101 NaClForkDelegate::~NaClForkDelegate() {
89 // side effect of close: delegate process will terminate 102 // side effect of close: delegate process will terminate
90 if (ready_) { 103 if (status_ == kNaClHelperSuccess) {
91 if (HANDLE_EINTR(close(fd_)) != 0) 104 if (HANDLE_EINTR(close(fd_)) != 0)
92 LOG(ERROR) << "close(fd_) failed"; 105 LOG(ERROR) << "close(fd_) failed";
93 } 106 }
94 } 107 }
95 108
96 bool NaClForkDelegate::CanHelp(const std::string& process_type) { 109 bool NaClForkDelegate::CanHelp(const std::string& process_type,
97 return (process_type == switches::kNaClLoaderProcess && ready_); 110 std::string* uma_name,
111 int* uma_sample,
112 int* uma_boundary_value) {
113 if (process_type != switches::kNaClLoaderProcess)
114 return false;
115 *uma_name = "NaCl.Client.Helper.StateOnFork";
116 *uma_sample = status_;
117 *uma_boundary_value = kNaClHelperStatusBoundary;
118 return status_ == kNaClHelperSuccess;
98 } 119 }
99 120
100 pid_t NaClForkDelegate::Fork(const std::vector<int>& fds) { 121 pid_t NaClForkDelegate::Fork(const std::vector<int>& fds) {
101 base::ProcessId naclchild; 122 base::ProcessId naclchild;
102 VLOG(1) << "NaClForkDelegate::Fork"; 123 VLOG(1) << "NaClForkDelegate::Fork";
103 124
104 DCHECK(fds.size() == kNaClParentFDIndex + 1); 125 DCHECK(fds.size() == kNaClParentFDIndex + 1);
105 if (!UnixDomainSocket::SendMsg(fd_, kNaClForkRequest, 126 if (!UnixDomainSocket::SendMsg(fd_, kNaClForkRequest,
106 strlen(kNaClForkRequest), fds)) { 127 strlen(kNaClForkRequest), fds)) {
107 LOG(ERROR) << "NaClForkDelegate::Fork: SendMsg failed"; 128 LOG(ERROR) << "NaClForkDelegate::Fork: SendMsg failed";
(...skipping 10 matching lines...) Expand all
118 139
119 bool NaClForkDelegate::AckChild(const int fd, 140 bool NaClForkDelegate::AckChild(const int fd,
120 const std::string& channel_switch) { 141 const std::string& channel_switch) {
121 int nwritten = HANDLE_EINTR(write(fd, channel_switch.c_str(), 142 int nwritten = HANDLE_EINTR(write(fd, channel_switch.c_str(),
122 channel_switch.length())); 143 channel_switch.length()));
123 if (nwritten != static_cast<int>(channel_switch.length())) { 144 if (nwritten != static_cast<int>(channel_switch.length())) {
124 return false; 145 return false;
125 } 146 }
126 return true; 147 return true;
127 } 148 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698