1 // Copyright 2014 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 5 // On Linux, when the user tries to launch a second copy of chrome, we check 6 // for a socket in the user's profile directory. If the socket file is open we 7 // send a message to the first chrome browser process with the current 8 // directory and second process command line flags. The second process then 9 // exits. 10 // 11 // Because many networked filesystem implementations do not support unix domain 12 // sockets, we create the socket in a temporary directory and create a symlink 13 // in the profile. This temporary directory is no longer bound to the profile, 14 // and may disappear across a reboot or login to a separate session. To bind 15 // them, we store a unique cookie in the profile directory, which must also be 16 // present in the remote directory to connect. The cookie is checked both before 17 // and after the connection. /tmp is sticky, and different Chrome sessions use 18 // different cookies. Thus, a matching cookie before and after means the 19 // connection was to a directory with a valid cookie. 20 // 21 // We also have a lock file, which is a symlink to a non-existent destination. 22 // The destination is a string containing the hostname and process id of 23 // chrome's browser process, eg. "SingletonLock -> example.com-9156". When the 24 // first copy of chrome exits it will delete the lock file on shutdown, so that 25 // a different instance on a different host may then use the profile directory. 26 // 27 // If writing to the socket fails, the hostname in the lock is checked to see if 28 // another instance is running a different host using a shared filesystem (nfs, 29 // etc.) If the hostname differs an error is displayed and the second process 30 // exits. Otherwise the first process (if any) is killed and the second process 31 // starts as normal. 32 // 33 // When the second process sends the current directory and command line flags to 34 // the first process, it waits for an ACK message back from the first process 35 // for a certain time. If there is no ACK message back in time, then the first 36 // process will be considered as hung for some reason. The second process then 37 // retrieves the process id from the symbol link and kills it by sending 38 // SIGKILL. Then the second process starts as normal. 39 40 #include "chrome/browser/process_singleton.h" 41 42 #include <errno.h> 43 #include <fcntl.h> 44 #include <signal.h> 45 #include <sys/socket.h> 46 #include <sys/stat.h> 47 #include <sys/types.h> 48 #include <sys/un.h> 49 #include <unistd.h> 50 51 #include <cstring> 52 #include <set> 53 #include <string> 54 55 #include "base/base_paths.h" 56 #include "base/basictypes.h" 57 #include "base/bind.h" 58 #include "base/command_line.h" 59 #include "base/files/file_path.h" 60 #include "base/files/file_util.h" 61 #include "base/logging.h" 62 #include "base/message_loop/message_loop.h" 63 #include "base/path_service.h" 64 #include "base/posix/eintr_wrapper.h" 65 #include "base/rand_util.h" 66 #include "base/safe_strerror_posix.h" 67 #include "base/sequenced_task_runner_helpers.h" 68 #include "base/stl_util.h" 69 #include "base/strings/string_number_conversions.h" 70 #include "base/strings/string_split.h" 71 #include "base/strings/string_util.h" 72 #include "base/strings/stringprintf.h" 73 #include "base/strings/sys_string_conversions.h" 74 #include "base/strings/utf_string_conversions.h" 75 #include "base/threading/platform_thread.h" 76 #include "base/time/time.h" 77 #include "base/timer/timer.h" 78 #include "chrome/common/chrome_constants.h" 79 #include "chrome/grit/chromium_strings.h" 80 #include "chrome/grit/generated_resources.h" 81 #include "content/public/browser/browser_thread.h" 82 #include "net/base/net_util.h" 83 #include "ui/base/l10n/l10n_util.h" 84 85 #if defined(OS_LINUX) 86 #include "chrome/browser/ui/process_singleton_dialog_linux.h" 87 #endif 88 89 #if defined(TOOLKIT_VIEWS) && defined(OS_LINUX) && !defined(OS_CHROMEOS) 90 #include "ui/views/linux_ui/linux_ui.h" 91 #endif 92 93 using content::BrowserThread; 94 95 namespace { 96 97 // Timeout for the current browser process to respond. 20 seconds should be 98 // enough. 99 const int kTimeoutInSeconds = 20; 100 // Number of retries to notify the browser. 20 retries over 20 seconds = 1 try 101 // per second. 102 const int kRetryAttempts = 20; 103 static bool g_disable_prompt; 104 const char kStartToken[] = "START"; 105 const char kACKToken[] = "ACK"; 106 const char kShutdownToken[] = "SHUTDOWN"; 107 const char kTokenDelimiter = '\0'; 108 const int kMaxMessageLength = 32 * 1024; 109 const int kMaxACKMessageLength = arraysize(kShutdownToken) - 1; 110 111 const char kLockDelimiter = '-'; 112 113 // Set a file descriptor to be non-blocking. 114 // Return 0 on success, -1 on failure. 115 int SetNonBlocking(int fd) { 116 int flags = fcntl(fd, F_GETFL, 0); 117 if (-1 == flags) 118 return flags; 119 if (flags & O_NONBLOCK) 120 return 0; 121 return fcntl(fd, F_SETFL, flags | O_NONBLOCK); 122 } 123 124 // Set the close-on-exec bit on a file descriptor. 125 // Returns 0 on success, -1 on failure. 126 int SetCloseOnExec(int fd) { 127 int flags = fcntl(fd, F_GETFD, 0); 128 if (-1 == flags) 129 return flags; 130 if (flags & FD_CLOEXEC) 131 return 0; 132 return fcntl(fd, F_SETFD, flags | FD_CLOEXEC); 133 } 134 135 // Close a socket and check return value. 136 void CloseSocket(int fd) { 137 int rv = IGNORE_EINTR(close(fd)); 138 DCHECK_EQ(0, rv) << "Error closing socket: " << safe_strerror(errno); 139 } 140 141 // Write a message to a socket fd. 142 bool WriteToSocket(int fd, const char *message, size_t length) { 143 DCHECK(message); 144 DCHECK(length); 145 size_t bytes_written = 0; 146 do { 147 ssize_t rv = HANDLE_EINTR( 148 write(fd, message + bytes_written, length - bytes_written)); 149 if (rv < 0) { 150 if (errno == EAGAIN || errno == EWOULDBLOCK) { 151 // The socket shouldn't block, we're sending so little data. Just give 152 // up here, since NotifyOtherProcess() doesn't have an asynchronous api. 153 LOG(ERROR) << "ProcessSingleton would block on write(), so it gave up."; 154 return false; 155 } 156 PLOG(ERROR) << "write() failed"; 157 return false; 158 } 159 bytes_written += rv; 160 } while (bytes_written < length); 161 162 return true; 163 } 164 165 struct timeval TimeDeltaToTimeVal(const base::TimeDelta& delta) { 166 struct timeval result; 167 result.tv_sec = delta.InSeconds(); 168 result.tv_usec = delta.InMicroseconds() % base::Time::kMicrosecondsPerSecond; 169 return result; 170 } 171 172 // Wait a socket for read for a certain timeout. 173 // Returns -1 if error occurred, 0 if timeout reached, > 0 if the socket is 174 // ready for read. 175 int WaitSocketForRead(int fd, const base::TimeDelta& timeout) { 176 fd_set read_fds; 177 struct timeval tv = TimeDeltaToTimeVal(timeout); 178 179 FD_ZERO(&read_fds); 180 FD_SET(fd, &read_fds); 181 182 return HANDLE_EINTR(select(fd + 1, &read_fds, NULL, NULL, &tv)); 183 } 184 185 // Read a message from a socket fd, with an optional timeout. 186 // If |timeout| <= 0 then read immediately. 187 // Return number of bytes actually read, or -1 on error. 188 ssize_t ReadFromSocket(int fd, 189 char* buf, 190 size_t bufsize, 191 const base::TimeDelta& timeout) { 192 if (timeout > base::TimeDelta()) { 193 int rv = WaitSocketForRead(fd, timeout); 194 if (rv <= 0) 195 return rv; 196 } 197 198 size_t bytes_read = 0; 199 do { 200 ssize_t rv = HANDLE_EINTR(read(fd, buf + bytes_read, bufsize - bytes_read)); 201 if (rv < 0) { 202 if (errno != EAGAIN && errno != EWOULDBLOCK) { 203 PLOG(ERROR) << "read() failed"; 204 return rv; 205 } else { 206 // It would block, so we just return what has been read. 207 return bytes_read; 208 } 209 } else if (!rv) { 210 // No more data to read. 211 return bytes_read; 212 } else { 213 bytes_read += rv; 214 } 215 } while (bytes_read < bufsize); 216 217 return bytes_read; 218 } 219 220 // Set up a sockaddr appropriate for messaging. 221 void SetupSockAddr(const std::string& path, struct sockaddr_un* addr) { 222 addr->sun_family = AF_UNIX; 223 CHECK(path.length() < arraysize(addr->sun_path)) 224 << "Socket path too long: " << path; 225 base::strlcpy(addr->sun_path, path.c_str(), arraysize(addr->sun_path)); 226 } 227 228 // Set up a socket appropriate for messaging. 229 int SetupSocketOnly() { 230 int sock = socket(PF_UNIX, SOCK_STREAM, 0); 231 PCHECK(sock >= 0) << "socket() failed"; 232 233 int rv = SetNonBlocking(sock); 234 DCHECK_EQ(0, rv) << "Failed to make non-blocking socket."; 235 rv = SetCloseOnExec(sock); 236 DCHECK_EQ(0, rv) << "Failed to set CLOEXEC on socket."; 237 238 return sock; 239 } 240 241 // Set up a socket and sockaddr appropriate for messaging. 242 void SetupSocket(const std::string& path, int* sock, struct sockaddr_un* addr) { 243 *sock = SetupSocketOnly(); 244 SetupSockAddr(path, addr); 245 } 246 247 // Read a symbolic link, return empty string if given path is not a symbol link. 248 base::FilePath ReadLink(const base::FilePath& path) { 249 base::FilePath target; 250 if (!base::ReadSymbolicLink(path, &target)) { 251 // The only errno that should occur is ENOENT. 252 if (errno != 0 && errno != ENOENT) 253 PLOG(ERROR) << "readlink(" << path.value() << ") failed"; 254 } 255 return target; 256 } 257 258 // Unlink a path. Return true on success. 259 bool UnlinkPath(const base::FilePath& path) { 260 int rv = unlink(path.value().c_str()); 261 if (rv < 0 && errno != ENOENT) 262 PLOG(ERROR) << "Failed to unlink " << path.value(); 263 264 return rv == 0; 265 } 266 267 // Create a symlink. Returns true on success. 268 bool SymlinkPath(const base::FilePath& target, const base::FilePath& path) { 269 if (!base::CreateSymbolicLink(target, path)) { 270 // Double check the value in case symlink suceeded but we got an incorrect 271 // failure due to NFS packet loss & retry. 272 int saved_errno = errno; 273 if (ReadLink(path) != target) { 274 // If we failed to create the lock, most likely another instance won the 275 // startup race. 276 errno = saved_errno; 277 PLOG(ERROR) << "Failed to create " << path.value(); 278 return false; 279 } 280 } 281 return true; 282 } 283 284 // Extract the hostname and pid from the lock symlink. 285 // Returns true if the lock existed. 286 bool ParseLockPath(const base::FilePath& path, 287 std::string* hostname, 288 int* pid) { 289 std::string real_path = ReadLink(path).value(); 290 if (real_path.empty()) 291 return false; 292 293 std::string::size_type pos = real_path.rfind(kLockDelimiter); 294 295 // If the path is not a symbolic link, or doesn't contain what we expect, 296 // bail. 297 if (pos == std::string::npos) { 298 *hostname = ""; 299 *pid = -1; 300 return true; 301 } 302 303 *hostname = real_path.substr(0, pos); 304 305 const std::string& pid_str = real_path.substr(pos + 1); 306 if (!base::StringToInt(pid_str, pid)) 307 *pid = -1; 308 309 return true; 310 } 311 312 // Returns true if the user opted to unlock the profile. 313 bool DisplayProfileInUseError(const base::FilePath& lock_path, 314 const std::string& hostname, 315 int pid) { 316 base::string16 error = l10n_util::GetStringFUTF16( 317 IDS_PROFILE_IN_USE_POSIX, 318 base::IntToString16(pid), 319 base::ASCIIToUTF16(hostname)); 320 LOG(ERROR) << error; 321 322 if (g_disable_prompt) 323 return false; 324 325 #if defined(OS_LINUX) 326 base::string16 relaunch_button_text = l10n_util::GetStringUTF16( 327 IDS_PROFILE_IN_USE_LINUX_RELAUNCH); 328 return ShowProcessSingletonDialog(error, relaunch_button_text); 329 #elif defined(OS_MACOSX) 330 // On Mac, always usurp the lock. 331 return true; 332 #endif 333 334 NOTREACHED(); 335 return false; 336 } 337 338 bool IsChromeProcess(pid_t pid) { 339 base::FilePath other_chrome_path(base::GetProcessExecutablePath(pid)); 340 return (!other_chrome_path.empty() && 341 other_chrome_path.BaseName() == 342 base::FilePath(chrome::kBrowserProcessExecutableName)); 343 } 344 345 // A helper class to hold onto a socket. 346 class ScopedSocket { 347 public: 348 ScopedSocket() : fd_(-1) { Reset(); } 349 ~ScopedSocket() { Close(); } 350 int fd() { return fd_; } 351 void Reset() { 352 Close(); 353 fd_ = SetupSocketOnly(); 354 } 355 void Close() { 356 if (fd_ >= 0) 357 CloseSocket(fd_); 358 fd_ = -1; 359 } 360 private: 361 int fd_; 362 }; 363 364 // Returns a random string for uniquifying profile connections. 365 std::string GenerateCookie() { 366 return base::Uint64ToString(base::RandUint64()); 367 } 368 369 bool CheckCookie(const base::FilePath& path, const base::FilePath& cookie) { 370 return (cookie == ReadLink(path)); 371 } 372 373 bool ConnectSocket(ScopedSocket* socket, 374 const base::FilePath& socket_path, 375 const base::FilePath& cookie_path) { 376 base::FilePath socket_target; 377 if (base::ReadSymbolicLink(socket_path, &socket_target)) { 378 // It's a symlink. Read the cookie. 379 base::FilePath cookie = ReadLink(cookie_path); 380 if (cookie.empty()) 381 return false; 382 base::FilePath remote_cookie = socket_target.DirName(). 383 Append(chrome::kSingletonCookieFilename); 384 // Verify the cookie before connecting. 385 if (!CheckCookie(remote_cookie, cookie)) 386 return false; 387 // Now we know the directory was (at that point) created by the profile 388 // owner. Try to connect. 389 sockaddr_un addr; 390 SetupSockAddr(socket_target.value(), &addr); 391 int ret = HANDLE_EINTR(connect(socket->fd(), 392 reinterpret_cast<sockaddr*>(&addr), 393 sizeof(addr))); 394 if (ret != 0) 395 return false; 396 // Check the cookie again. We only link in /tmp, which is sticky, so, if the 397 // directory is still correct, it must have been correct in-between when we 398 // connected. POSIX, sadly, lacks a connectat(). 399 if (!CheckCookie(remote_cookie, cookie)) { 400 socket->Reset(); 401 return false; 402 } 403 // Success! 404 return true; 405 } else if (errno == EINVAL) { 406 // It exists, but is not a symlink (or some other error we detect 407 // later). Just connect to it directly; this is an older version of Chrome. 408 sockaddr_un addr; 409 SetupSockAddr(socket_path.value(), &addr); 410 int ret = HANDLE_EINTR(connect(socket->fd(), 411 reinterpret_cast<sockaddr*>(&addr), 412 sizeof(addr))); 413 return (ret == 0); 414 } else { 415 // File is missing, or other error. 416 if (errno != ENOENT) 417 PLOG(ERROR) << "readlink failed"; 418 return false; 419 } 420 } 421 422 #if defined(OS_MACOSX) 423 bool ReplaceOldSingletonLock(const base::FilePath& symlink_content, 424 const base::FilePath& lock_path) { 425 // Try taking an flock(2) on the file. Failure means the lock is taken so we 426 // should quit. 427 base::ScopedFD lock_fd(HANDLE_EINTR( 428 open(lock_path.value().c_str(), O_RDWR | O_CREAT | O_SYMLINK, 0644))); 429 if (!lock_fd.is_valid()) { 430 PLOG(ERROR) << "Could not open singleton lock"; 431 return false; 432 } 433 434 int rc = HANDLE_EINTR(flock(lock_fd.get(), LOCK_EX | LOCK_NB)); 435 if (rc == -1) { 436 if (errno == EWOULDBLOCK) { 437 LOG(ERROR) << "Singleton lock held by old process."; 438 } else { 439 PLOG(ERROR) << "Error locking singleton lock"; 440 } 441 return false; 442 } 443 444 // Successfully taking the lock means we can replace it with the a new symlink 445 // lock. We never flock() the lock file from now on. I.e. we assume that an 446 // old version of Chrome will not run with the same user data dir after this 447 // version has run. 448 if (!base::DeleteFile(lock_path, false)) { 449 PLOG(ERROR) << "Could not delete old singleton lock."; 450 return false; 451 } 452 453 return SymlinkPath(symlink_content, lock_path); 454 } 455 #endif // defined(OS_MACOSX) 456 457 } // namespace 458 459 /////////////////////////////////////////////////////////////////////////////// 460 // ProcessSingleton::LinuxWatcher 461 // A helper class for a Linux specific implementation of the process singleton. 462 // This class sets up a listener on the singleton socket and handles parsing 463 // messages that come in on the singleton socket. 464 class ProcessSingleton::LinuxWatcher 465 : public base::MessageLoopForIO::Watcher, 466 public base::MessageLoop::DestructionObserver, 467 public base::RefCountedThreadSafe<ProcessSingleton::LinuxWatcher, 468 BrowserThread::DeleteOnIOThread> { 469 public: 470 // A helper class to read message from an established socket. 471 class SocketReader : public base::MessageLoopForIO::Watcher { 472 public: 473 SocketReader(ProcessSingleton::LinuxWatcher* parent, 474 base::MessageLoop* ui_message_loop, 475 int fd) 476 : parent_(parent), 477 ui_message_loop_(ui_message_loop), 478 fd_(fd), 479 bytes_read_(0) { 480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 481 // Wait for reads. 482 base::MessageLoopForIO::current()->WatchFileDescriptor( 483 fd, true, base::MessageLoopForIO::WATCH_READ, &fd_reader_, this); 484 // If we haven't completed in a reasonable amount of time, give up. 485 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kTimeoutInSeconds), 486 this, &SocketReader::CleanupAndDeleteSelf); 487 } 488 489 virtual ~SocketReader() { 490 CloseSocket(fd_); 491 } 492 493 // MessageLoopForIO::Watcher impl. 494 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; 495 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE { 496 // SocketReader only watches for accept (read) events. 497 NOTREACHED(); 498 } 499 500 // Finish handling the incoming message by optionally sending back an ACK 501 // message and removing this SocketReader. 502 void FinishWithACK(const char *message, size_t length); 503 504 private: 505 void CleanupAndDeleteSelf() { 506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 507 508 parent_->RemoveSocketReader(this); 509 // We're deleted beyond this point. 510 } 511 512 base::MessageLoopForIO::FileDescriptorWatcher fd_reader_; 513 514 // The ProcessSingleton::LinuxWatcher that owns us. 515 ProcessSingleton::LinuxWatcher* const parent_; 516 517 // A reference to the UI message loop. 518 base::MessageLoop* const ui_message_loop_; 519 520 // The file descriptor we're reading. 521 const int fd_; 522 523 // Store the message in this buffer. 524 char buf_[kMaxMessageLength]; 525 526 // Tracks the number of bytes we've read in case we're getting partial 527 // reads. 528 size_t bytes_read_; 529 530 base::OneShotTimer<SocketReader> timer_; 531 532 DISALLOW_COPY_AND_ASSIGN(SocketReader); 533 }; 534 535 // We expect to only be constructed on the UI thread. 536 explicit LinuxWatcher(ProcessSingleton* parent) 537 : ui_message_loop_(base::MessageLoop::current()), 538 parent_(parent) { 539 } 540 541 // Start listening for connections on the socket. This method should be 542 // called from the IO thread. 543 void StartListening(int socket); 544 545 // This method determines if we should use the same process and if we should, 546 // opens a new browser tab. This runs on the UI thread. 547 // |reader| is for sending back ACK message. 548 void HandleMessage(const std::string& current_dir, 549 const std::vector<std::string>& argv, 550 SocketReader* reader); 551 552 // MessageLoopForIO::Watcher impl. These run on the IO thread. 553 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; 554 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE { 555 // ProcessSingleton only watches for accept (read) events. 556 NOTREACHED(); 557 } 558 559 // MessageLoop::DestructionObserver 560 virtual void WillDestroyCurrentMessageLoop() OVERRIDE { 561 fd_watcher_.StopWatchingFileDescriptor(); 562 } 563 564 private: 565 friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>; 566 friend class base::DeleteHelper<ProcessSingleton::LinuxWatcher>; 567 568 virtual ~LinuxWatcher() { 569 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 570 STLDeleteElements(&readers_); 571 572 base::MessageLoopForIO* ml = base::MessageLoopForIO::current(); 573 ml->RemoveDestructionObserver(this); 574 } 575 576 // Removes and deletes the SocketReader. 577 void RemoveSocketReader(SocketReader* reader); 578 579 base::MessageLoopForIO::FileDescriptorWatcher fd_watcher_; 580 581 // A reference to the UI message loop (i.e., the message loop we were 582 // constructed on). 583 base::MessageLoop* ui_message_loop_; 584 585 // The ProcessSingleton that owns us. 586 ProcessSingleton* const parent_; 587 588 std::set<SocketReader*> readers_; 589 590 DISALLOW_COPY_AND_ASSIGN(LinuxWatcher); 591 }; 592 593 void ProcessSingleton::LinuxWatcher::OnFileCanReadWithoutBlocking(int fd) { 594 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 595 // Accepting incoming client. 596 sockaddr_un from; 597 socklen_t from_len = sizeof(from); 598 int connection_socket = HANDLE_EINTR(accept( 599 fd, reinterpret_cast<sockaddr*>(&from), &from_len)); 600 if (-1 == connection_socket) { 601 PLOG(ERROR) << "accept() failed"; 602 return; 603 } 604 int rv = SetNonBlocking(connection_socket); 605 DCHECK_EQ(0, rv) << "Failed to make non-blocking socket."; 606 SocketReader* reader = new SocketReader(this, 607 ui_message_loop_, 608 connection_socket); 609 readers_.insert(reader); 610 } 611 612 void ProcessSingleton::LinuxWatcher::StartListening(int socket) { 613 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 614 // Watch for client connections on this socket. 615 base::MessageLoopForIO* ml = base::MessageLoopForIO::current(); 616 ml->AddDestructionObserver(this); 617 ml->WatchFileDescriptor(socket, true, base::MessageLoopForIO::WATCH_READ, 618 &fd_watcher_, this); 619 } 620 621 void ProcessSingleton::LinuxWatcher::HandleMessage( 622 const std::string& current_dir, const std::vector<std::string>& argv, 623 SocketReader* reader) { 624 DCHECK(ui_message_loop_ == base::MessageLoop::current()); 625 DCHECK(reader); 626 627 if (parent_->notification_callback_.Run(CommandLine(argv), 628 base::FilePath(current_dir))) { 629 // Send back "ACK" message to prevent the client process from starting up. 630 reader->FinishWithACK(kACKToken, arraysize(kACKToken) - 1); 631 } else { 632 LOG(WARNING) << "Not handling interprocess notification as browser" 633 " is shutting down"; 634 // Send back "SHUTDOWN" message, so that the client process can start up 635 // without killing this process. 636 reader->FinishWithACK(kShutdownToken, arraysize(kShutdownToken) - 1); 637 return; 638 } 639 } 640 641 void ProcessSingleton::LinuxWatcher::RemoveSocketReader(SocketReader* reader) { 642 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 643 DCHECK(reader); 644 readers_.erase(reader); 645 delete reader; 646 } 647 648 /////////////////////////////////////////////////////////////////////////////// 649 // ProcessSingleton::LinuxWatcher::SocketReader 650 // 651 652 void ProcessSingleton::LinuxWatcher::SocketReader::OnFileCanReadWithoutBlocking( 653 int fd) { 654 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 655 DCHECK_EQ(fd, fd_); 656 while (bytes_read_ < sizeof(buf_)) { 657 ssize_t rv = HANDLE_EINTR( 658 read(fd, buf_ + bytes_read_, sizeof(buf_) - bytes_read_)); 659 if (rv < 0) { 660 if (errno != EAGAIN && errno != EWOULDBLOCK) { 661 PLOG(ERROR) << "read() failed"; 662 CloseSocket(fd); 663 return; 664 } else { 665 // It would block, so we just return and continue to watch for the next 666 // opportunity to read. 667 return; 668 } 669 } else if (!rv) { 670 // No more data to read. It's time to process the message. 671 break; 672 } else { 673 bytes_read_ += rv; 674 } 675 } 676 677 // Validate the message. The shortest message is kStartToken\0x\0x 678 const size_t kMinMessageLength = arraysize(kStartToken) + 4; 679 if (bytes_read_ < kMinMessageLength) { 680 buf_[bytes_read_] = 0; 681 LOG(ERROR) << "Invalid socket message (wrong length):" << buf_; 682 CleanupAndDeleteSelf(); 683 return; 684 } 685 686 std::string str(buf_, bytes_read_); 687 std::vector<std::string> tokens; 688 base::SplitString(str, kTokenDelimiter, &tokens); 689 690 if (tokens.size() < 3 || tokens[0] != kStartToken) { 691 LOG(ERROR) << "Wrong message format: " << str; 692 CleanupAndDeleteSelf(); 693 return; 694 } 695 696 // Stop the expiration timer to prevent this SocketReader object from being 697 // terminated unexpectly. 698 timer_.Stop(); 699 700 std::string current_dir = tokens[1]; 701 // Remove the first two tokens. The remaining tokens should be the command 702 // line argv array. 703 tokens.erase(tokens.begin()); 704 tokens.erase(tokens.begin()); 705 706 // Return to the UI thread to handle opening a new browser tab. 707 ui_message_loop_->PostTask(FROM_HERE, base::Bind( 708 &ProcessSingleton::LinuxWatcher::HandleMessage, 709 parent_, 710 current_dir, 711 tokens, 712 this)); 713 fd_reader_.StopWatchingFileDescriptor(); 714 715 // LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader 716 // object by invoking SocketReader::FinishWithACK(). 717 } 718 719 void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK( 720 const char *message, size_t length) { 721 if (message && length) { 722 // Not necessary to care about the return value. 723 WriteToSocket(fd_, message, length); 724 } 725 726 if (shutdown(fd_, SHUT_WR) < 0) 727 PLOG(ERROR) << "shutdown() failed"; 728 729 BrowserThread::PostTask( 730 BrowserThread::IO, 731 FROM_HERE, 732 base::Bind(&ProcessSingleton::LinuxWatcher::RemoveSocketReader, 733 parent_, 734 this)); 735 // We will be deleted once the posted RemoveSocketReader task runs. 736 } 737 738 /////////////////////////////////////////////////////////////////////////////// 739 // ProcessSingleton 740 // 741 ProcessSingleton::ProcessSingleton( 742 const base::FilePath& user_data_dir, 743 const NotificationCallback& notification_callback) 744 : notification_callback_(notification_callback), 745 current_pid_(base::GetCurrentProcId()), 746 watcher_(new LinuxWatcher(this)) { 747 socket_path_ = user_data_dir.Append(chrome::kSingletonSocketFilename); 748 lock_path_ = user_data_dir.Append(chrome::kSingletonLockFilename); 749 cookie_path_ = user_data_dir.Append(chrome::kSingletonCookieFilename); 750 751 kill_callback_ = base::Bind(&ProcessSingleton::KillProcess, 752 base::Unretained(this)); 753 } 754 755 ProcessSingleton::~ProcessSingleton() { 756 } 757 758 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { 759 return NotifyOtherProcessWithTimeout( 760 *CommandLine::ForCurrentProcess(), 761 kRetryAttempts, 762 base::TimeDelta::FromSeconds(kTimeoutInSeconds), 763 true); 764 } 765 766 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout( 767 const CommandLine& cmd_line, 768 int retry_attempts, 769 const base::TimeDelta& timeout, 770 bool kill_unresponsive) { 771 DCHECK_GE(retry_attempts, 0); 772 DCHECK_GE(timeout.InMicroseconds(), 0); 773 774 base::TimeDelta sleep_interval = timeout / retry_attempts; 775 776 ScopedSocket socket; 777 for (int retries = 0; retries <= retry_attempts; ++retries) { 778 // Try to connect to the socket. 779 if (ConnectSocket(&socket, socket_path_, cookie_path_)) 780 break; 781 782 // If we're in a race with another process, they may be in Create() and have 783 // created the lock but not attached to the socket. So we check if the 784 // process with the pid from the lockfile is currently running and is a 785 // chrome browser. If so, we loop and try again for |timeout|. 786 787 std::string hostname; 788 int pid; 789 if (!ParseLockPath(lock_path_, &hostname, &pid)) { 790 // No lockfile exists. 791 return PROCESS_NONE; 792 } 793 794 if (hostname.empty()) { 795 // Invalid lockfile. 796 UnlinkPath(lock_path_); 797 return PROCESS_NONE; 798 } 799 800 if (hostname != net::GetHostName() && !IsChromeProcess(pid)) { 801 // Locked by process on another host. If the user selected to unlock 802 // the profile, try to continue; otherwise quit. 803 if (DisplayProfileInUseError(lock_path_, hostname, pid)) { 804 UnlinkPath(lock_path_); 805 return PROCESS_NONE; 806 } 807 return PROFILE_IN_USE; 808 } 809 810 if (!IsChromeProcess(pid)) { 811 // Orphaned lockfile (no process with pid, or non-chrome process.) 812 UnlinkPath(lock_path_); 813 return PROCESS_NONE; 814 } 815 816 if (IsSameChromeInstance(pid)) { 817 // Orphaned lockfile (pid is part of same chrome instance we are, even 818 // though we haven't tried to create a lockfile yet). 819 UnlinkPath(lock_path_); 820 return PROCESS_NONE; 821 } 822 823 if (retries == retry_attempts) { 824 // Retries failed. Kill the unresponsive chrome process and continue. 825 if (!kill_unresponsive || !KillProcessByLockPath()) 826 return PROFILE_IN_USE; 827 return PROCESS_NONE; 828 } 829 830 base::PlatformThread::Sleep(sleep_interval); 831 } 832 833 timeval socket_timeout = TimeDeltaToTimeVal(timeout); 834 setsockopt(socket.fd(), 835 SOL_SOCKET, 836 SO_SNDTIMEO, 837 &socket_timeout, 838 sizeof(socket_timeout)); 839 840 // Found another process, prepare our command line 841 // format is "START\0<current dir>\0<argv[0]>\0...\0<argv[n]>". 842 std::string to_send(kStartToken); 843 to_send.push_back(kTokenDelimiter); 844 845 base::FilePath current_dir; 846 if (!PathService::Get(base::DIR_CURRENT, ¤t_dir)) 847 return PROCESS_NONE; 848 to_send.append(current_dir.value()); 849 850 const std::vector<std::string>& argv = cmd_line.argv(); 851 for (std::vector<std::string>::const_iterator it = argv.begin(); 852 it != argv.end(); ++it) { 853 to_send.push_back(kTokenDelimiter); 854 to_send.append(*it); 855 } 856 857 // Send the message 858 if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) { 859 // Try to kill the other process, because it might have been dead. 860 if (!kill_unresponsive || !KillProcessByLockPath()) 861 return PROFILE_IN_USE; 862 return PROCESS_NONE; 863 } 864 865 if (shutdown(socket.fd(), SHUT_WR) < 0) 866 PLOG(ERROR) << "shutdown() failed"; 867 868 // Read ACK message from the other process. It might be blocked for a certain 869 // timeout, to make sure the other process has enough time to return ACK. 870 char buf[kMaxACKMessageLength + 1]; 871 ssize_t len = ReadFromSocket(socket.fd(), buf, kMaxACKMessageLength, timeout); 872 873 // Failed to read ACK, the other process might have been frozen. 874 if (len <= 0) { 875 if (!kill_unresponsive || !KillProcessByLockPath()) 876 return PROFILE_IN_USE; 877 return PROCESS_NONE; 878 } 879 880 buf[len] = '\0'; 881 if (strncmp(buf, kShutdownToken, arraysize(kShutdownToken) - 1) == 0) { 882 // The other process is shutting down, it's safe to start a new process. 883 return PROCESS_NONE; 884 } else if (strncmp(buf, kACKToken, arraysize(kACKToken) - 1) == 0) { 885 #if defined(TOOLKIT_VIEWS) && defined(OS_LINUX) && !defined(OS_CHROMEOS) 886 // Likely NULL in unit tests. 887 views::LinuxUI* linux_ui = views::LinuxUI::instance(); 888 if (linux_ui) 889 linux_ui->NotifyWindowManagerStartupComplete(); 890 #endif 891 892 // Assume the other process is handling the request. 893 return PROCESS_NOTIFIED; 894 } 895 896 NOTREACHED() << "The other process returned unknown message: " << buf; 897 return PROCESS_NOTIFIED; 898 } 899 900 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() { 901 return NotifyOtherProcessWithTimeoutOrCreate( 902 *CommandLine::ForCurrentProcess(), 903 kRetryAttempts, 904 base::TimeDelta::FromSeconds(kTimeoutInSeconds)); 905 } 906 907 ProcessSingleton::NotifyResult 908 ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate( 909 const CommandLine& command_line, 910 int retry_attempts, 911 const base::TimeDelta& timeout) { 912 NotifyResult result = NotifyOtherProcessWithTimeout( 913 command_line, retry_attempts, timeout, true); 914 if (result != PROCESS_NONE) 915 return result; 916 if (Create()) 917 return PROCESS_NONE; 918 // If the Create() failed, try again to notify. (It could be that another 919 // instance was starting at the same time and managed to grab the lock before 920 // we did.) 921 // This time, we don't want to kill anything if we aren't successful, since we 922 // aren't going to try to take over the lock ourselves. 923 result = NotifyOtherProcessWithTimeout( 924 command_line, retry_attempts, timeout, false); 925 if (result != PROCESS_NONE) 926 return result; 927 928 return LOCK_ERROR; 929 } 930 931 void ProcessSingleton::OverrideCurrentPidForTesting(base::ProcessId pid) { 932 current_pid_ = pid; 933 } 934 935 void ProcessSingleton::OverrideKillCallbackForTesting( 936 const base::Callback<void(int)>& callback) { 937 kill_callback_ = callback; 938 } 939 940 void ProcessSingleton::DisablePromptForTesting() { 941 g_disable_prompt = true; 942 } 943 944 bool ProcessSingleton::Create() { 945 int sock; 946 sockaddr_un addr; 947 948 // The symlink lock is pointed to the hostname and process id, so other 949 // processes can find it out. 950 base::FilePath symlink_content(base::StringPrintf( 951 "%s%c%u", 952 net::GetHostName().c_str(), 953 kLockDelimiter, 954 current_pid_)); 955 956 // Create symbol link before binding the socket, to ensure only one instance 957 // can have the socket open. 958 if (!SymlinkPath(symlink_content, lock_path_)) { 959 // TODO(jackhou): Remove this case once this code is stable on Mac. 960 // http://crbug.com/367612 961 #if defined(OS_MACOSX) 962 // On Mac, an existing non-symlink lock file means the lock could be held by 963 // the old process singleton code. If we can successfully replace the lock, 964 // continue as normal. 965 if (base::IsLink(lock_path_) || 966 !ReplaceOldSingletonLock(symlink_content, lock_path_)) { 967 return false; 968 } 969 #else 970 // If we failed to create the lock, most likely another instance won the 971 // startup race. 972 return false; 973 #endif 974 } 975 976 // Create the socket file somewhere in /tmp which is usually mounted as a 977 // normal filesystem. Some network filesystems (notably AFS) are screwy and 978 // do not support Unix domain sockets. 979 if (!socket_dir_.CreateUniqueTempDir()) { 980 LOG(ERROR) << "Failed to create socket directory."; 981 return false; 982 } 983 984 // Check that the directory was created with the correct permissions. 985 int dir_mode = 0; 986 CHECK(base::GetPosixFilePermissions(socket_dir_.path(), &dir_mode) && 987 dir_mode == base::FILE_PERMISSION_USER_MASK) 988 << "Temp directory mode is not 700: " << std::oct << dir_mode; 989 990 // Setup the socket symlink and the two cookies. 991 base::FilePath socket_target_path = 992 socket_dir_.path().Append(chrome::kSingletonSocketFilename); 993 base::FilePath cookie(GenerateCookie()); 994 base::FilePath remote_cookie_path = 995 socket_dir_.path().Append(chrome::kSingletonCookieFilename); 996 UnlinkPath(socket_path_); 997 UnlinkPath(cookie_path_); 998 if (!SymlinkPath(socket_target_path, socket_path_) || 999 !SymlinkPath(cookie, cookie_path_) || 1000 !SymlinkPath(cookie, remote_cookie_path)) { 1001 // We've already locked things, so we can't have lost the startup race, 1002 // but something doesn't like us. 1003 LOG(ERROR) << "Failed to create symlinks."; 1004 if (!socket_dir_.Delete()) 1005 LOG(ERROR) << "Encountered a problem when deleting socket directory."; 1006 return false; 1007 } 1008 1009 SetupSocket(socket_target_path.value(), &sock, &addr); 1010 1011 if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) { 1012 PLOG(ERROR) << "Failed to bind() " << socket_target_path.value(); 1013 CloseSocket(sock); 1014 return false; 1015 } 1016 1017 if (listen(sock, 5) < 0) 1018 NOTREACHED() << "listen failed: " << safe_strerror(errno); 1019 1020 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::IO)); 1021 BrowserThread::PostTask( 1022 BrowserThread::IO, 1023 FROM_HERE, 1024 base::Bind(&ProcessSingleton::LinuxWatcher::StartListening, 1025 watcher_.get(), 1026 sock)); 1027 1028 return true; 1029 } 1030 1031 void ProcessSingleton::Cleanup() { 1032 UnlinkPath(socket_path_); 1033 UnlinkPath(cookie_path_); 1034 UnlinkPath(lock_path_); 1035 } 1036 1037 bool ProcessSingleton::IsSameChromeInstance(pid_t pid) { 1038 pid_t cur_pid = current_pid_; 1039 while (pid != cur_pid) { 1040 pid = base::GetParentProcessId(pid); 1041 if (pid < 0) 1042 return false; 1043 if (!IsChromeProcess(pid)) 1044 return false; 1045 } 1046 return true; 1047 } 1048 1049 bool ProcessSingleton::KillProcessByLockPath() { 1050 std::string hostname; 1051 int pid; 1052 ParseLockPath(lock_path_, &hostname, &pid); 1053 1054 if (!hostname.empty() && hostname != net::GetHostName()) { 1055 return DisplayProfileInUseError(lock_path_, hostname, pid); 1056 } 1057 UnlinkPath(lock_path_); 1058 1059 if (IsSameChromeInstance(pid)) 1060 return true; 1061 1062 if (pid > 0) { 1063 kill_callback_.Run(pid); 1064 return true; 1065 } 1066 1067 LOG(ERROR) << "Failed to extract pid from path: " << lock_path_.value(); 1068 return true; 1069 } 1070 1071 void ProcessSingleton::KillProcess(int pid) { 1072 // TODO(james.su (at) gmail.com): Is SIGKILL ok? 1073 int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL); 1074 // ESRCH = No Such Process (can happen if the other process is already in 1075 // progress of shutting down and finishes before we try to kill it). 1076 DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: " 1077 << safe_strerror(errno); 1078 } 1079