[ChromeDriver] Disable /dev/shm usage when needed
Automatically add --disable-dev-shm-usage switch to ChromeDriver command
line on Linux when /dev/shm is not accessible.
Bug: chromedriver:2782, b/124440075
Change-Id: I7322094d7da4e6b1a02fa3092b50ba4dbbc6fa7b
Reviewed-on: https://chromium-review.googlesource.com/c/1478187
Reviewed-by: Caleb Rouleau <crouleau@chromium.org>
Commit-Queue: John Chen <johnchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#633558}
diff --git a/chrome/test/chromedriver/server/chromedriver_server.cc b/chrome/test/chromedriver/server/chromedriver_server.cc
index 77cc701..43921dc 100644
--- a/chrome/test/chromedriver/server/chromedriver_server.cc
+++ b/chrome/test/chromedriver/server/chromedriver_server.cc
@@ -96,6 +96,27 @@
return true;
}
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// Ensure that there is a writable shared memory directory. We use
+// network::SimpleURLLoader to connect to Chrome, and it calls
+// base::subtle::PlatformSharedMemoryRegion::Create to get a shared memory
+// region. network::SimpleURLLoader would fail if the shared memory directory is
+// not accessible. We work around this issue by adding --disable-dev-shm-usage
+// to command line, to use an alternative directory for shared memory.
+// See https://crbug.com/chromedriver/2782.
+void EnsureSharedMemory(base::CommandLine* cmd_line) {
+ if (!cmd_line->HasSwitch("disable-dev-shm-usage")) {
+ base::FilePath directory;
+ if (GetShmemTempDir(false, &directory) &&
+ access(directory.value().c_str(), W_OK | X_OK) < 0) {
+ VLOG(0) << directory
+ << " not writable, adding --disable-dev-shm-usage switch";
+ cmd_line->AppendSwitch("disable-dev-shm-usage");
+ }
+ }
+}
+#endif
+
class HttpServer : public net::HttpServer::Delegate {
public:
explicit HttpServer(const HttpRequestHandlerFunc& handle_request_func)
@@ -383,31 +404,35 @@
std::string options;
const char* const kOptionAndDescriptions[] = {
"port=PORT",
- "port to listen on",
+ "port to listen on",
"adb-port=PORT",
- "adb server port",
+ "adb server port",
"log-path=FILE",
- "write server log to file instead of stderr, "
- "increases log level to INFO",
+ "write server log to file instead of stderr, "
+ "increases log level to INFO",
"log-level=LEVEL",
- "set log level: ALL, DEBUG, INFO, WARNING, "
- "SEVERE, OFF",
+ "set log level: ALL, DEBUG, INFO, WARNING, SEVERE, OFF",
"verbose",
- "log verbosely (equivalent to --log-level=ALL)",
+ "log verbosely (equivalent to --log-level=ALL)",
"silent",
- "log nothing (equivalent to --log-level=OFF)",
+ "log nothing (equivalent to --log-level=OFF)",
"append-log",
- "append log file instead of rewriting",
+ "append log file instead of rewriting",
"replayable",
- "(experimental) log verbosely and don't truncate long "
- "strings so that the log can be replayed.",
+ "(experimental) log verbosely and don't truncate long "
+ "strings so that the log can be replayed.",
"version",
- "print the version number and exit",
+ "print the version number and exit",
"url-base",
- "base URL path prefix for commands, e.g. wd/url",
+ "base URL path prefix for commands, e.g. wd/url",
"whitelisted-ips",
- "comma-separated whitelist of remote IP addresses "
- "which are allowed to connect to ChromeDriver",
+ "comma-separated whitelist of remote IP addresses "
+ "which are allowed to connect to ChromeDriver",
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ "disable-dev-shm-usage",
+ "do not use /dev/shm "
+ "(add this switch if seeing errors related to shared memory)",
+#endif
};
for (size_t i = 0; i < base::size(kOptionAndDescriptions) - 1; i += 2) {
options += base::StringPrintf(
@@ -499,6 +524,10 @@
return 1;
}
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ EnsureSharedMemory(cmd_line);
+#endif
+
mojo::core::Init();
base::TaskScheduler::CreateAndStartWithDefaultParams("ChromeDriver");