You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2018/01/12 16:03:46 UTC

[trafficserver] 05/09: Added traffic_runroot feature to generate sandbox for programs to run

This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit b2b5f45e6a406f28c013bb728dfcf07512e603c2
Author: Xavier Chi <ch...@gmail.com>
AuthorDate: Fri Aug 11 16:22:32 2017 -0500

    Added traffic_runroot feature to generate sandbox for programs to run
    
    (cherry picked from commit 30c2c35e5ed1daadcf8a8db5e46760e3d7ae5325)
    
     Conflicts:
    	lib/ts/ink_args.cc
    	proxy/Main.cc
---
 cmd/traffic_cop/traffic_cop.cc           |   5 +-
 cmd/traffic_crashlog/traffic_crashlog.cc |   5 +-
 cmd/traffic_ctl/traffic_ctl.cc           |   3 +
 cmd/traffic_layout/traffic_layout.cc     |   8 +-
 cmd/traffic_manager/traffic_manager.cc   |   6 +-
 cmd/traffic_top/traffic_top.cc           |   1 +
 lib/ts/I_Layout.h                        |   6 ++
 lib/ts/Layout.cc                         |  80 ++++++++++++++++++-
 lib/ts/ink_args.cc                       |   5 +-
 lib/ts/ink_args.h                        |   4 +
 lib/ts/runroot.cc                        | 132 +++++++++++++++++++++++++++++++
 proxy/Main.cc                            |   6 +-
 proxy/logcat.cc                          |   5 +-
 proxy/logstats.cc                        |   5 +-
 14 files changed, 260 insertions(+), 11 deletions(-)

diff --git a/cmd/traffic_cop/traffic_cop.cc b/cmd/traffic_cop/traffic_cop.cc
index 10b9f4f..420702c 100644
--- a/cmd/traffic_cop/traffic_cop.cc
+++ b/cmd/traffic_cop/traffic_cop.cc
@@ -36,6 +36,7 @@
 #include "ClusterCom.h"
 #include "ts/ink_cap.h"
 #include "Cop.h"
+#include "ts/runroot.cc"
 
 #include <string>
 #include <map>
@@ -1820,7 +1821,8 @@ static const ArgumentDescription argument_descriptions[] = {
   {"stdout", 'o', "Print log messages to standard output", "F", &stdout_flag, nullptr, nullptr},
   {"stop", 's', "Send child processes SIGSTOP instead of SIGKILL", "F", &stop_flag, nullptr, nullptr},
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION()};
 
 int
 main(int /* argc */, const char *argv[])
@@ -1828,6 +1830,7 @@ main(int /* argc */, const char *argv[])
   int fd;
   appVersionInfo.setup(PACKAGE_NAME, "traffic_cop", PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
 
+  runroot_handler(argv);
   // Before accessing file system initialize Layout engine
   Layout::create();
 
diff --git a/cmd/traffic_crashlog/traffic_crashlog.cc b/cmd/traffic_crashlog/traffic_crashlog.cc
index 54b4755..c64aded 100644
--- a/cmd/traffic_crashlog/traffic_crashlog.cc
+++ b/cmd/traffic_crashlog/traffic_crashlog.cc
@@ -30,6 +30,7 @@
 #include "I_RecProcess.h"
 #include "RecordsConfig.h"
 #include "ts/BaseLogFile.h"
+#include "ts/runroot.cc"
 
 static int syslog_mode    = false;
 static int debug_mode     = false;
@@ -48,7 +49,8 @@ static const ArgumentDescription argument_descriptions[] = {
   {"syslog", '-', "Syslog after writing a crash log", "F", &syslog_mode, nullptr, nullptr},
   {"debug", '-', "Enable debugging mode", "F", &debug_mode, nullptr, nullptr},
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION()};
 
 static struct tm
 timestamp()
@@ -117,6 +119,7 @@ main(int /* argc ATS_UNUSED */, const char **argv)
     ATS_UNUSED_RETURN(seteuid(0));
   }
 
+  runroot_handler(argv);
   Layout::create();
   RecProcessInit(RECM_STAND_ALONE, nullptr /* diags */);
   LibRecordsConfigInit();
diff --git a/cmd/traffic_ctl/traffic_ctl.cc b/cmd/traffic_ctl/traffic_ctl.cc
index 59ad001..bf69fc6 100644
--- a/cmd/traffic_ctl/traffic_ctl.cc
+++ b/cmd/traffic_ctl/traffic_ctl.cc
@@ -26,6 +26,7 @@
 #include "ts/I_Layout.h"
 #include "I_RecProcess.h"
 #include "RecordsConfig.h"
+#include "ts/runroot.cc"
 
 AppVersionInfo CtrlVersionInfo;
 
@@ -223,6 +224,7 @@ main(int argc, const char **argv)
     {"debug", '-', "Enable debugging output", "F", &debug, nullptr, nullptr},
     HELP_ARGUMENT_DESCRIPTION(),
     VERSION_ARGUMENT_DESCRIPTION(),
+    RUNROOT_ARGUMENT_DESCRIPTION(),
   };
 
   const subcommand commands[] = {
@@ -253,6 +255,7 @@ main(int argc, const char **argv)
     return CtrlSubcommandUsage(nullptr, commands, countof(commands), argument_descriptions, countof(argument_descriptions));
   }
 
+  runroot_handler(argv);
   Layout::create();
   RecProcessInit(RECM_STAND_ALONE, diags);
   LibRecordsConfigInit();
diff --git a/cmd/traffic_layout/traffic_layout.cc b/cmd/traffic_layout/traffic_layout.cc
index f48befb..f22fb57 100644
--- a/cmd/traffic_layout/traffic_layout.cc
+++ b/cmd/traffic_layout/traffic_layout.cc
@@ -27,8 +27,7 @@
 #include "ts/I_Layout.h"
 #include "I_RecProcess.h"
 #include "RecordsConfig.h"
-
-#include <iostream>
+#include "ts/runroot.cc"
 
 // Command line arguments (parsing)
 struct CommandLineArgs {
@@ -45,7 +44,8 @@ const ArgumentDescription argument_descriptions[] = {
   {"json", 'j', "Produce output in JSON format (when supported)", "T", &cl.json, nullptr, nullptr},
 
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION()};
 
 // Produce output about compile time features, useful for checking how things were built, as well
 // as for our TSQA test harness.
@@ -178,6 +178,8 @@ main(int /* argc ATS_UNUSED */, const char **argv)
   // Process command line arguments and dump into variables
   process_args(&appVersionInfo, argument_descriptions, countof(argument_descriptions), argv);
 
+  runroot_handler(argv);
+
   if (cl.features) {
     produce_features(0 != cl.json);
   } else {
diff --git a/cmd/traffic_manager/traffic_manager.cc b/cmd/traffic_manager/traffic_manager.cc
index f0afcaf..d447692 100644
--- a/cmd/traffic_manager/traffic_manager.cc
+++ b/cmd/traffic_manager/traffic_manager.cc
@@ -27,6 +27,7 @@
 #include "ts/ink_sock.h"
 #include "ts/ink_args.h"
 #include "ts/ink_syslog.h"
+#include "ts/runroot.cc"
 
 #include "WebMgmtUtils.h"
 #include "WebOverview.h"
@@ -419,6 +420,8 @@ main(int argc, const char **argv)
 {
   const long MAX_LOGIN = ink_login_name_max();
 
+  runroot_handler(argv);
+
   // Before accessing file system initialize Layout engine
   Layout::create();
   mgmt_path = Layout::get()->sysconfdir.c_str();
@@ -462,7 +465,8 @@ main(int argc, const char **argv)
 #endif
     {"nosyslog", '-', "Do not log to syslog", "F", &disable_syslog, nullptr, nullptr},
     HELP_ARGUMENT_DESCRIPTION(),
-    VERSION_ARGUMENT_DESCRIPTION()
+    VERSION_ARGUMENT_DESCRIPTION(),
+    RUNROOT_ARGUMENT_DESCRIPTION()
   };
 
   // Process command line arguments and dump into variables
diff --git a/cmd/traffic_top/traffic_top.cc b/cmd/traffic_top/traffic_top.cc
index ad289fe..e217cee 100644
--- a/cmd/traffic_top/traffic_top.cc
+++ b/cmd/traffic_top/traffic_top.cc
@@ -403,6 +403,7 @@ main(int argc, const char **argv)
     {"sleep", 's', "Enable debugging output", "I", &sleep_time, nullptr, nullptr},
     HELP_ARGUMENT_DESCRIPTION(),
     VERSION_ARGUMENT_DESCRIPTION(),
+    RUNROOT_ARGUMENT_DESCRIPTION(),
   };
 
   process_args(&version, argument_descriptions, countof(argument_descriptions), argv, USAGE);
diff --git a/lib/ts/I_Layout.h b/lib/ts/I_Layout.h
index d23b07a..b742340 100644
--- a/lib/ts/I_Layout.h
+++ b/lib/ts/I_Layout.h
@@ -44,6 +44,12 @@ struct Layout {
   ~Layout();
 
   /**
+   return use runroot or not
+
+  */
+  bool check_runroot();
+
+  /**
    Return file path relative to Layout->prefix
 
   */
diff --git a/lib/ts/Layout.cc b/lib/ts/Layout.cc
index cb3c7d8..5abbffc 100644
--- a/lib/ts/Layout.cc
+++ b/lib/ts/Layout.cc
@@ -28,6 +28,10 @@
 #include "ts/ink_string.h"
 #include "ts/I_Layout.h"
 
+#include <fstream>
+#include <iostream>
+#include <unordered_map>
+
 static Layout *layout = nullptr;
 
 Layout *
@@ -108,13 +112,87 @@ Layout::relative_to(char *buf, size_t bufsz, ts::string_view dir, ts::string_vie
   }
 }
 
+bool
+Layout::check_runroot()
+{
+  std::string yaml_path = {};
+
+  if (getenv("USING_RUNROOT") == nullptr) {
+    return false;
+  } else {
+    std::string env_path = getenv("USING_RUNROOT");
+    int len              = env_path.size();
+    if ((len + 1) > PATH_NAME_MAX) {
+      ink_fatal("TS_RUNROOT environment variable is too big: %d, max %d\n", len, PATH_NAME_MAX - 1);
+    }
+    std::cout << "TS_RUNROOT initiated..." << std::endl;
+    std::ifstream file;
+    if (env_path.back() != '/') {
+      env_path.append("/");
+    }
+    yaml_path = env_path + "runroot_path.yaml";
+
+    file.open(yaml_path);
+    if (!file.good()) {
+      ink_warning("Bad env path, continue with default value");
+      return false;
+    }
+  }
+  std::ifstream yamlfile(yaml_path);
+  std::unordered_map<std::string, std::string> runroot_map;
+  std::string str;
+  while (std::getline(yamlfile, str)) {
+    int pos = str.find(':');
+    runroot_map[str.substr(0, pos)] = str.substr(pos + 2);
+  }
+  for (auto it : runroot_map) {
+    prefix        = runroot_map["prefix"];
+    exec_prefix   = runroot_map["exec_prefix"];
+    bindir        = runroot_map["bindir"];
+    sbindir       = runroot_map["sbindir"];
+    sysconfdir    = runroot_map["sysconfdir"];
+    datadir       = runroot_map["datadir"];
+    includedir    = runroot_map["includedir"];
+    libdir        = runroot_map["libdir"];
+    libexecdir    = runroot_map["libexecdir"];
+    localstatedir = runroot_map["localstatedir"];
+    runtimedir    = runroot_map["runtimedir"];
+    logdir        = runroot_map["logdir"];
+    mandir        = runroot_map["mandir"];
+    infodir       = runroot_map["infodir"];
+    cachedir      = runroot_map["cachedir"];
+  }
+
+  // // for yaml lib operations
+  // YAML::Node yamlfile = YAML::LoadFile(yaml_path);
+  // prefix              = yamlfile["prefix"].as<string>();
+  // exec_prefix         = yamlfile["exec_prefix"].as<string>();
+  // bindir              = yamlfile["bindir"].as<string>();
+  // sbindir             = yamlfile["sbindir"].as<string>();
+  // sysconfdir          = yamlfile["sysconfdir"].as<string>();
+  // datadir             = yamlfile["datadir"].as<string>();
+  // includedir          = yamlfile["includedir"].as<string>();
+  // libdir              = yamlfile["libdir"].as<string>();
+  // libexecdir          = yamlfile["libexecdir"].as<string>();
+  // localstatedir       = yamlfile["localstatedir"].as<string>();
+  // runtimedir          = yamlfile["runtimedir"].as<string>();
+  // logdir              = yamlfile["logdir"].as<string>();
+  // mandir              = yamlfile["mandir"].as<string>();
+  // infodir             = yamlfile["infodir"].as<string>();
+  // cachedir            = yamlfile["cachedir"].as<string>();
+  return true;
+}
+
 Layout::Layout(ts::string_view const _prefix)
 {
-  if (_prefix.size() != 0) {
+  if (!_prefix.empty()) {
     prefix.assign(_prefix.data(), _prefix.size());
   } else {
     std::string path;
     int len;
+    if (check_runroot()) {
+      return;
+    }
     if (getenv("TS_ROOT") != nullptr) {
       std::string env_path(getenv("TS_ROOT"));
       len = env_path.size();
diff --git a/lib/ts/ink_args.cc b/lib/ts/ink_args.cc
index 7c58592..bd973e3 100644
--- a/lib/ts/ink_args.cc
+++ b/lib/ts/ink_args.cc
@@ -218,7 +218,10 @@ process_args_ex(const AppVersionInfo *appinfo, const ArgumentDescription *argume
 
     if ((*argv)[1] == '-') {
       // Deal with long options ...
-      for (i = 0; i < n_argument_descriptions; i++)
+      for (i = 0; i < n_argument_descriptions; i++) {
+        if (!strcmp(argument_descriptions[i].name, "run-root")) {
+          break;
+        }
         if (!strcmp(argument_descriptions[i].name, (*argv) + 2)) {
           *argv += strlen(*argv) - 1;
           if (!process_arg(appinfo, argument_descriptions, n_argument_descriptions, i, &argv)) {
diff --git a/lib/ts/ink_args.h b/lib/ts/ink_args.h
index ad7ecd4..549fcdd 100644
--- a/lib/ts/ink_args.h
+++ b/lib/ts/ink_args.h
@@ -75,6 +75,10 @@ struct ArgumentDescription {
   {                                                                          \
     "help", 'h', "Print usage information", nullptr, nullptr, nullptr, usage \
   }
+#define RUNROOT_ARGUMENT_DESCRIPTION()                                                 \
+  {                                                                                    \
+    "run-root", '-', "using TS_RUNROOT as sandbox", nullptr, nullptr, nullptr, nullptr \
+  }
 
 /* Global Data
 */
diff --git a/lib/ts/runroot.cc b/lib/ts/runroot.cc
new file mode 100644
index 0000000..785e7e5
--- /dev/null
+++ b/lib/ts/runroot.cc
@@ -0,0 +1,132 @@
+/** @file
+
+  A brief file prefix
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+*/
+
+/*
+This file contains the function of the runroot handler for TS_RUNROOT
+handle the --run-root for every command or program
+
+Goal: set up an ENV variable for Layout.cc to use as TS_RUNROOT sandbox
+easy & clean
+
+Example: ./traffic_server --run-root=/path/to/sandbox
+
+Need a yaml file in the sandbox with key value pairs of all directory locations for other programs to use
+
+Directories needed in the yaml file:
+prefix, exec_prefix, includedir, localstatedir, bindir, logdir, mandir, sbindir, sysconfdir,
+datadir, libexecdir, libdir, runtimedir, infodir, cachedir.
+*/
+
+#include "ts/ink_error.h"
+
+#include <vector>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <set>
+#include <unistd.h>
+
+#define MAX_CWD_LEN 1024
+
+// the function for the checking of the yaml file in parent path
+// if found return the parent path containing the yaml file
+static std::string
+check_parent_path(const std::string &path)
+{
+  std::string whole_path = path;
+  if (whole_path.back() == '/')
+    whole_path.pop_back();
+
+  while (whole_path != "") {
+    whole_path                   = whole_path.substr(0, whole_path.find_last_of("/"));
+    std::string parent_yaml_path = whole_path + "/runroot_path.yaml";
+    std::ifstream parent_check_file;
+    parent_check_file.open(parent_yaml_path);
+    if (parent_check_file.good()) {
+      std::cout << "using parent of bin/current working dir" << std::endl;
+      return whole_path;
+    }
+  }
+  return {};
+}
+
+// handler for ts runroot
+void
+runroot_handler(const char **argv)
+{
+  std::string command = {};
+  std::string arg     = {};
+  std::string prefix  = "--run-root";
+
+  int i = 0;
+  while (argv[i]) {
+    command = argv[i];
+    if (command.substr(0, prefix.size()) == prefix) {
+      arg = command;
+      break;
+    }
+    i++;
+  }
+  if (arg.empty())
+    return;
+
+  // 1. check pass in path
+  prefix += "=";
+  if (arg.substr(0, prefix.size()) == prefix) {
+    std::ifstream yaml_checkfile;
+    std::string path = arg.substr(prefix.size(), arg.size() - 1);
+
+    if (path.back() != '/')
+      path.append("/");
+
+    std::string yaml_path = path + "runroot_path.yaml";
+    yaml_checkfile.open(yaml_path);
+    if (yaml_checkfile.good()) {
+      std::cout << "using command line path as RUNROOT" << std::endl;
+      setenv("USING_RUNROOT", path.c_str(), true);
+      return;
+    } else {
+      ink_warning("bad RUNROOT");
+    }
+  }
+  // 2. argv provided invalid/no yaml file, then check env variable
+  if (getenv("TS_RUNROOT") != nullptr) {
+    setenv("USING_RUNROOT", getenv("TS_RUNROOT"), true);
+    std::cout << "using the environment variable TS_RUNROOT" << std::endl;
+    return;
+  }
+  // 3. find parent path of bin/pwd to check
+  char cwd[MAX_CWD_LEN];
+  getcwd(cwd, sizeof(cwd));
+  std::string RealBinPath = realpath(argv[0], nullptr); // bin path
+
+  std::vector<std::string> TwoPath = {RealBinPath, cwd};
+  for (auto it : TwoPath) {
+    std::string path = check_parent_path(it);
+    if (!path.empty()) {
+      setenv("USING_RUNROOT", path.c_str(), true);
+      return;
+    }
+  }
+  std::cout << "Failed to initialize TS_RUNROOT, using default path..." << std::endl;
+}
diff --git a/proxy/Main.cc b/proxy/Main.cc
index eae8db0..b28441e 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -37,6 +37,7 @@
 #include "ts/ink_stack_trace.h"
 #include "ts/ink_syslog.h"
 #include "ts/hugepages.h"
+#include "ts/runroot.cc"
 
 #include <syslog.h>
 
@@ -219,7 +220,9 @@ static const ArgumentDescription argument_descriptions[] = {
   {"accept_mss", '-', "MSS for client connections", "I", &accept_mss, nullptr, nullptr},
   {"poll_timeout", 't', "poll timeout in milliseconds", "I", &poll_timeout, nullptr, nullptr},
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION(),
+};
 
 class SignalContinuation : public Continuation
 {
@@ -1523,6 +1526,7 @@ main(int /* argc ATS_UNUSED */, const char **argv)
   // Define the version info
   appVersionInfo.setup(PACKAGE_NAME, "traffic_server", PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
 
+  runroot_handler(argv);
   // Before accessing file system initialize Layout engine
   Layout::create();
   chdir_root(); // change directory to the install root of traffic server.
diff --git a/proxy/logcat.cc b/proxy/logcat.cc
index 590804e..98f8c82 100644
--- a/proxy/logcat.cc
+++ b/proxy/logcat.cc
@@ -24,6 +24,7 @@
 #include "ts/ink_platform.h"
 #include "ts/ink_args.h"
 #include "ts/I_Layout.h"
+#include "ts/runroot.cc"
 
 #define PROGRAM_NAME "traffic_logcat"
 #define MAX_LOGBUFFER_SIZE 65536
@@ -68,7 +69,8 @@ static const ArgumentDescription argument_descriptions[] = {
   {"overwrite_output", 'w', "Overwrite existing output file(s)", "T", &overwrite_existing_file, NULL, NULL},
   {"elf2", '2', "Convert to Extended2 Logging Format", "T", &elf2_flag, NULL, NULL},
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION()};
 
 /*
  * Gets the inode number of a given file
@@ -256,6 +258,7 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
   //
   appVersionInfo.setup(PACKAGE_NAME, PROGRAM_NAME, PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
 
+  runroot_handler(argv);
   // Before accessing file system initialize Layout engine
   Layout::create();
   // process command-line arguments
diff --git a/proxy/logstats.cc b/proxy/logstats.cc
index 8d9a1fa..35967dc 100644
--- a/proxy/logstats.cc
+++ b/proxy/logstats.cc
@@ -29,6 +29,7 @@
 #include "ts/HashFNV.h"
 #include "ts/ink_args.h"
 #include "ts/MatcherUtils.h"
+#include "ts/runroot.cc"
 
 // Includes and namespaces etc.
 #include "LogStandalone.cc"
@@ -658,7 +659,8 @@ static ArgumentDescription argument_descriptions[] = {
   {"debug_tags", 'T', "Colon-Separated Debug Tags", "S1023", &error_tags, NULL, NULL},
   {"report_per_user", 'r', "Report stats per user instead of host", "T", &cl.report_per_user, NULL, NULL},
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION()};
 
 static const char *USAGE_LINE = "Usage: " PROGRAM_NAME " [-f logfile] [-o origin[,...]] [-O originfile] [-m minhits] [-binshv]";
 
@@ -2409,6 +2411,7 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
   // build the application information structure
   appVersionInfo.setup(PACKAGE_NAME, PROGRAM_NAME, PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
 
+  runroot_handler(argv);
   // Before accessing file system initialize Layout engine
   Layout::create();
 

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.