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