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

Side by Side Diff: content/zygote/zygote_linux.cc

Issue 23123011: Zygote: small cleanup (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 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
« no previous file with comments | « content/zygote/zygote_linux.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/zygote/zygote_linux.h" 5 #include "content/zygote/zygote_linux.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <string.h> 8 #include <string.h>
9 #include <sys/socket.h> 9 #include <sys/socket.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 #endif 92 #endif
93 } 93 }
94 94
95 for (;;) { 95 for (;;) {
96 // This function call can return multiple times, once per fork(). 96 // This function call can return multiple times, once per fork().
97 if (HandleRequestFromBrowser(kBrowserDescriptor)) 97 if (HandleRequestFromBrowser(kBrowserDescriptor))
98 return true; 98 return true;
99 } 99 }
100 } 100 }
101 101
102 bool Zygote::GetProcessInfo(base::ProcessHandle pid,
103 ZygoteProcessInfo* process_info) {
104 DCHECK(process_info);
105 const ZygoteProcessMap::const_iterator it = process_info_map_.find(pid);
106 if (it == process_info_map_.end()) {
107 return false;
108 }
109 *process_info = it->second;
110 return true;
111 }
112
102 bool Zygote::UsingSUIDSandbox() const { 113 bool Zygote::UsingSUIDSandbox() const {
103 return sandbox_flags_ & kSandboxLinuxSUID; 114 return sandbox_flags_ & kSandboxLinuxSUID;
104 } 115 }
105 116
106 bool Zygote::HandleRequestFromBrowser(int fd) { 117 bool Zygote::HandleRequestFromBrowser(int fd) {
107 std::vector<int> fds; 118 std::vector<int> fds;
108 char buf[kZygoteMaxMessageLength]; 119 char buf[kZygoteMaxMessageLength];
109 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds); 120 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds);
110 121
111 if (len == 0 || (len == -1 && errno == ECONNRESET)) { 122 if (len == 0 || (len == -1 && errno == ECONNRESET)) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 void Zygote::HandleReapRequest(int fd, 170 void Zygote::HandleReapRequest(int fd,
160 const Pickle& pickle, 171 const Pickle& pickle,
161 PickleIterator iter) { 172 PickleIterator iter) {
162 base::ProcessId child; 173 base::ProcessId child;
163 174
164 if (!pickle.ReadInt(&iter, &child)) { 175 if (!pickle.ReadInt(&iter, &child)) {
165 LOG(WARNING) << "Error parsing reap request from browser"; 176 LOG(WARNING) << "Error parsing reap request from browser";
166 return; 177 return;
167 } 178 }
168 179
169 if (process_info_map_.find(child) == process_info_map_.end()) { 180 ZygoteProcessInfo child_info;
170 // TODO(jln): test on more bots and add a DCHECK. 181 if (!GetProcessInfo(child, &child_info)) {
171 LOG(ERROR) << "Child not found!"; 182 LOG(ERROR) << "Child not found!";
183 NOTREACHED();
172 return; 184 return;
173 } 185 }
174 const base::ProcessId actual_child = process_info_map_[child].internal_pid; 186
175 const bool started_from_helper = 187 if (!child_info.started_from_helper) {
176 process_info_map_[child].started_from_helper;
177 if (!started_from_helper) {
178 // TODO(jln): this old code is completely broken. See crbug.com/274855. 188 // TODO(jln): this old code is completely broken. See crbug.com/274855.
179 base::EnsureProcessTerminated(actual_child); 189 base::EnsureProcessTerminated(child_info.internal_pid);
180 } else { 190 } else {
181 // For processes from the helper, send a GetTerminationStatus request 191 // For processes from the helper, send a GetTerminationStatus request
182 // with known_dead set to true. 192 // with known_dead set to true.
183 // This is not perfect, as the process may be killed instantly, but is 193 // This is not perfect, as the process may be killed instantly, but is
184 // better than ignoring the request. 194 // better than ignoring the request.
185 base::TerminationStatus status; 195 base::TerminationStatus status;
186 int exit_code; 196 int exit_code;
187 bool got_termination_status = 197 bool got_termination_status =
188 GetTerminationStatus(child, true /* known_dead */, &status, &exit_code); 198 GetTerminationStatus(child, true /* known_dead */, &status, &exit_code);
189 DCHECK(got_termination_status); 199 DCHECK(got_termination_status);
190 } 200 }
191 process_info_map_.erase(child); 201 process_info_map_.erase(child);
192 } 202 }
193 203
194 bool Zygote::GetTerminationStatus(base::ProcessHandle real_pid, 204 bool Zygote::GetTerminationStatus(base::ProcessHandle real_pid,
195 bool known_dead, 205 bool known_dead,
196 base::TerminationStatus* status, 206 base::TerminationStatus* status,
197 int* exit_code) { 207 int* exit_code) {
198 // Do we know about this child? 208
199 if (process_info_map_.find(real_pid) == process_info_map_.end()) { 209 ZygoteProcessInfo child_info;
200 // TODO(jln): test on more bots and add a DCHECK. 210 if (!GetProcessInfo(real_pid, &child_info)) {
201 LOG(ERROR) << "Zygote::GetTerminationStatus for unknown PID " 211 LOG(ERROR) << "Zygote::GetTerminationStatus for unknown PID "
202 << real_pid; 212 << real_pid;
213 NOTREACHED();
203 return false; 214 return false;
204 } 215 }
205 // We know about |real_pid|. 216 // We know about |real_pid|.
206 const base::ProcessHandle child = 217 const base::ProcessHandle child = child_info.internal_pid;
207 process_info_map_[real_pid].internal_pid; 218 if (child_info.started_from_helper) {
208 const bool started_from_helper =
209 process_info_map_[real_pid].started_from_helper;
210 if (started_from_helper) {
211 // Let the helper handle the request. 219 // Let the helper handle the request.
212 DCHECK(helper_); 220 DCHECK(helper_);
213 if (!helper_->GetTerminationStatus(child, known_dead, status, exit_code)) { 221 if (!helper_->GetTerminationStatus(child, known_dead, status, exit_code)) {
214 return false; 222 return false;
215 } 223 }
216 } else { 224 } else {
217 // Handle the request directly. 225 // Handle the request directly.
218 if (known_dead) { 226 if (known_dead) {
219 // If we know that the process is already dead and the kernel is cleaning 227 // If we know that the process is already dead and the kernel is cleaning
220 // it up, we do want to wait until it becomes a zombie and not risk 228 // it up, we do want to wait until it becomes a zombie and not risk
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 } 262 }
255 263
256 base::TerminationStatus status; 264 base::TerminationStatus status;
257 int exit_code; 265 int exit_code;
258 266
259 bool got_termination_status = 267 bool got_termination_status =
260 GetTerminationStatus(child_requested, known_dead, &status, &exit_code); 268 GetTerminationStatus(child_requested, known_dead, &status, &exit_code);
261 if (!got_termination_status) { 269 if (!got_termination_status) {
262 // Assume that if we can't find the child in the sandbox, then 270 // Assume that if we can't find the child in the sandbox, then
263 // it terminated normally. 271 // it terminated normally.
264 // TODO(jln): add a DCHECK. 272 NOTREACHED();
265 status = base::TERMINATION_STATUS_NORMAL_TERMINATION; 273 status = base::TERMINATION_STATUS_NORMAL_TERMINATION;
266 exit_code = RESULT_CODE_NORMAL_EXIT; 274 exit_code = RESULT_CODE_NORMAL_EXIT;
267 } 275 }
268 276
269 Pickle write_pickle; 277 Pickle write_pickle;
270 write_pickle.WriteInt(static_cast<int>(status)); 278 write_pickle.WriteInt(static_cast<int>(status));
271 write_pickle.WriteInt(exit_code); 279 write_pickle.WriteInt(exit_code);
272 ssize_t written = 280 ssize_t written =
273 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())); 281 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size()));
274 if (written != static_cast<ssize_t>(write_pickle.size())) 282 if (written != static_cast<ssize_t>(write_pickle.size()))
275 PLOG(ERROR) << "write"; 283 PLOG(ERROR) << "write";
276 } 284 }
277 285
278 int Zygote::ForkWithRealPid(const std::string& process_type, 286 int Zygote::ForkWithRealPid(const std::string& process_type,
279 std::vector<int>& fds, 287 std::vector<int>& fds,
280 const std::string& channel_switch, 288 const std::string& channel_switch,
281 std::string* uma_name, 289 std::string* uma_name,
282 int* uma_sample, 290 int* uma_sample,
283 int* uma_boundary_value) { 291 int* uma_boundary_value) {
284 const bool use_helper = (helper_ && helper_->CanHelp(process_type, 292 const bool use_helper = (helper_ && helper_->CanHelp(process_type,
285 uma_name, 293 uma_name,
286 uma_sample, 294 uma_sample,
287 uma_boundary_value)); 295 uma_boundary_value));
288 // TODO(jln): this shortcut is silly and does nothing but make the code
289 // harder to follow and to test. Get rid of it.
290 if (!(use_helper || UsingSUIDSandbox())) {
Mark Seaborn 2013/08/21 17:49:33 I assume you've tested the removal of this by runn
jln (very slow on Chromium) 2013/08/21 19:22:32 Yes, that was tested. We still have a few bots wit
291 pid_t pid = fork();
292 if (pid > 0) {
293 process_info_map_[pid].internal_pid = pid;
294 process_info_map_[pid].started_from_helper = use_helper;
295 }
296 return pid;
297 }
298
299 int dummy_fd; 296 int dummy_fd;
300 ino_t dummy_inode; 297 ino_t dummy_inode;
301 int pipe_fds[2] = { -1, -1 }; 298 int pipe_fds[2] = { -1, -1 };
302 base::ProcessId pid = 0; 299 base::ProcessId pid = 0;
303 300
304 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0); 301 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0);
305 if (dummy_fd < 0) { 302 if (dummy_fd < 0) {
306 LOG(ERROR) << "Failed to create dummy FD"; 303 LOG(ERROR) << "Failed to create dummy FD";
307 goto error; 304 goto error;
308 } 305 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 goto error; 380 goto error;
384 } 381 }
385 } else { 382 } else {
386 // If no SUID sandbox is involved then no pid translation is 383 // If no SUID sandbox is involved then no pid translation is
387 // necessary. 384 // necessary.
388 real_pid = pid; 385 real_pid = pid;
389 } 386 }
390 387
391 // Now set-up this process to be tracked by the Zygote. 388 // Now set-up this process to be tracked by the Zygote.
392 if (process_info_map_.find(real_pid) != process_info_map_.end()) { 389 if (process_info_map_.find(real_pid) != process_info_map_.end()) {
393 // TODO(jln): add DCHECK.
394 LOG(ERROR) << "Already tracking PID " << real_pid; 390 LOG(ERROR) << "Already tracking PID " << real_pid;
391 NOTREACHED();
395 } 392 }
396 process_info_map_[real_pid].internal_pid = pid; 393 process_info_map_[real_pid].internal_pid = pid;
397 process_info_map_[real_pid].started_from_helper = use_helper; 394 process_info_map_[real_pid].started_from_helper = use_helper;
398 395
399 if (use_helper) { 396 if (use_helper) {
400 if (!helper_->AckChild(pipe_fds[1], channel_switch)) { 397 if (!helper_->AckChild(pipe_fds[1], channel_switch)) {
401 LOG(ERROR) << "Failed to synchronise with zygote fork helper"; 398 LOG(ERROR) << "Failed to synchronise with zygote fork helper";
402 goto error; 399 goto error;
403 } 400 }
404 } else { 401 } else {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 PickleIterator iter) { 539 PickleIterator iter) {
543 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) != 540 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) !=
544 sizeof(sandbox_flags_)) { 541 sizeof(sandbox_flags_)) {
545 PLOG(ERROR) << "write"; 542 PLOG(ERROR) << "write";
546 } 543 }
547 544
548 return false; 545 return false;
549 } 546 }
550 547
551 } // namespace content 548 } // namespace content
OLDNEW
« no previous file with comments | « content/zygote/zygote_linux.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698