You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2014/08/02 04:59:27 UTC

[1/9] TS-2977: move traffic_manager

Repository: trafficserver
Updated Branches:
  refs/heads/master f098175e9 -> c936bc514


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/Main.cc
----------------------------------------------------------------------
diff --git a/mgmt/Main.cc b/mgmt/Main.cc
deleted file mode 100644
index 5f285c5..0000000
--- a/mgmt/Main.cc
+++ /dev/null
@@ -1,1214 +0,0 @@
-/** @file
-
-  Entry point to the traffic manager.
-
-  @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.
- */
-
-#include "ink_config.h"
-#include "ink_platform.h"
-#include "ink_sys_control.h"
-
-#include "Main.h"
-#include "MgmtUtils.h"
-#include "WebMgmtUtils.h"
-#include "WebIntrMain.h"
-#include "WebOverview.h"
-#include "FileManager.h"
-#include "I_Layout.h"
-#include "I_Version.h"
-#include "ink_syslog.h"
-#include "ink_lockfile.h"
-#include "Diags.h"
-#include "DiagsConfig.h"
-#include "URL.h"
-#include "MIME.h"
-#include "HTTP.h"
-
-// Needs LibRecordsConfigInit()
-#include "RecordsConfig.h"
-
-
-
-#include "StatProcessor.h"
-#include "P_RecLocal.h"
-#include "P_RecCore.h"
-
-#if TS_USE_POSIX_CAP
-#include <sys/capability.h>
-#endif
-#include <grp.h>
-
-#define FD_THROTTLE_HEADROOM (128 + 64) // TODO: consolidate with THROTTLE_FD_HEADROOM
-#define DIAGS_LOG_FILENAME "manager.log"
-
-#if defined(freebsd)
-extern "C" int getpwnam_r(const char *name, struct passwd *result, char *buffer, size_t buflen, struct passwd **resptr);
-#endif
-
-static void extractConfigInfo(char *mgmt_path, const char *recs_conf, char *userName, int *fds_throttle);
-
-LocalManager *lmgmt = NULL;
-FileManager *configFiles;
-
-StatProcessor *statProcessor;   // Statistics Processors
-AppVersionInfo appVersionInfo;  // Build info for this application
-
-static inkcoreapi DiagsConfig *diagsConfig;
-static char debug_tags[1024] = "";
-static char action_tags[1024] = "";
-static bool proxy_on = true;
-
-char mgmt_path[PATH_NAME_MAX + 1];
-
-// By default, set the current directory as base
-static const char *recs_conf = "records.config";
-
-static int fds_limit;
-
-// TODO: Use positive instead negative selection
-//       Thsis should just be #if defined(solaris)
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-static void SignalHandler(int sig, siginfo_t * t, void *f);
-static void SignalAlrmHandler(int sig, siginfo_t * t, void *f);
-#else
-static void SignalHandler(int sig);
-static void SignalAlrmHandler(int sig);
-#endif
-
-static volatile int sigHupNotifier = 0;
-static volatile int sigUsr2Notifier = 0;
-static void SigChldHandler(int sig);
-
-static void
-check_lockfile()
-{
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  char lockfile[PATH_NAME_MAX];
-  int err;
-  pid_t holding_pid;
-
-  //////////////////////////////////////
-  // test for presence of server lock //
-  //////////////////////////////////////
-  Layout::relative_to(lockfile, sizeof(lockfile), rundir, SERVER_LOCK);
-  Lockfile server_lockfile(lockfile);
-  err = server_lockfile.Open(&holding_pid);
-  if (err == 1) {
-    server_lockfile.Close();    // no server running
-  } else {
-    char *reason = strerror(-err);
-    if (err == 0) {
-      // TODO: Add PID_FMT_T instead duplicating code just for printing
-#if defined(solaris)
-      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, (int)holding_pid);
-#else
-      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, holding_pid);
-#endif
-      mgmt_elog(stderr, 0, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, holding_pid);
-    } else {
-      fprintf(stderr, "FATAL: Can't open server lockfile '%s' (%s)\n", lockfile, (reason ? reason : "Unknown Reason"));
-      mgmt_elog(stderr, 0, "FATAL: Can't open server lockfile '%s' (%s)\n",
-                lockfile, (reason ? reason : "Unknown Reason"));
-    }
-    exit(1);
-  }
-
-  ///////////////////////////////////////////
-  // try to get the exclusive manager lock //
-  ///////////////////////////////////////////
-  Layout::relative_to(lockfile, sizeof(lockfile), rundir, MANAGER_LOCK);
-  Lockfile manager_lockfile(lockfile);
-  err = manager_lockfile.Get(&holding_pid);
-  if (err != 1) {
-    char *reason = strerror(-err);
-    fprintf(stderr, "FATAL: Can't acquire manager lockfile '%s'", lockfile);
-    mgmt_elog(stderr, 0, "FATAL: Can't acquire manager lockfile '%s'", lockfile);
-    if (err == 0) {
-#if defined(solaris)
-      fprintf(stderr, " (Lock file held by process ID %d)\n", (int)holding_pid);
-#else
-      fprintf(stderr, " (Lock file held by process ID %d)\n", holding_pid);
-#endif
-      mgmt_elog(stderr, 0, " (Lock file held by process ID %d)\n", holding_pid);
-    } else if (reason) {
-      fprintf(stderr, " (%s)\n", reason);
-      mgmt_elog(stderr, 0, " (%s)\n", reason);
-    } else {
-      fprintf(stderr, "\n");
-    }
-    exit(1);
-
-    fprintf(stderr, "unable to acquire manager lock [%d]\n", -err);
-    exit(1);
-  }
-}
-
-
-static void
-initSignalHandlers()
-{
-  struct sigaction sigHandler, sigChldHandler, sigAlrmHandler;
-  sigset_t sigsToBlock;
-
-  // Set up the signal handler
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigHandler.sa_handler = NULL;
-  sigHandler.sa_sigaction = SignalHandler;
-#else
-  sigHandler.sa_handler = SignalHandler;
-#endif
-  sigemptyset(&sigHandler.sa_mask);
-
-  // We want the handler to remain in place on
-  //  SIGHUP to avoid any races with the signals
-  //  coming too quickly.  Also restart systems calls
-  //  after the signal since not all calls are wrapped
-  //  to check errno for EINTR
-  sigHandler.sa_flags = SA_RESTART;
-  sigaction(SIGHUP, &sigHandler, NULL);
-  sigaction(SIGUSR2, &sigHandler, NULL);
-
-  // Don't block the signal on entry to the signal
-  //   handler so we can reissue it and get a core
-  //   file in the appropriate circumstances
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigHandler.sa_flags = SA_RESETHAND | SA_SIGINFO;
-#else
-  sigHandler.sa_flags = SA_RESETHAND;
-#endif
-  sigaction(SIGINT, &sigHandler, NULL);
-  sigaction(SIGQUIT, &sigHandler, NULL);
-  sigaction(SIGILL, &sigHandler, NULL);
-  sigaction(SIGBUS, &sigHandler, NULL);
-  sigaction(SIGSEGV, &sigHandler, NULL);
-  sigaction(SIGTERM, &sigHandler, NULL);
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigAlrmHandler.sa_handler = NULL;
-  sigAlrmHandler.sa_sigaction = SignalAlrmHandler;
-#else
-  sigAlrmHandler.sa_handler = SignalAlrmHandler;
-#endif
-
-  sigemptyset(&sigAlrmHandler.sa_mask);
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigAlrmHandler.sa_flags = SA_SIGINFO;
-#else
-  sigAlrmHandler.sa_flags = 0;
-#endif
-  sigaction(SIGALRM, &sigAlrmHandler, NULL);
-
-  // Block the delivery of any signals we are not catching
-  //
-  //  except for SIGALARM since we use it
-  //    to break out of deadlock on semaphore
-  //    we share with the proxy
-  //
-  sigfillset(&sigsToBlock);
-  sigdelset(&sigsToBlock, SIGHUP);
-  sigdelset(&sigsToBlock, SIGUSR2);
-  sigdelset(&sigsToBlock, SIGINT);
-  sigdelset(&sigsToBlock, SIGQUIT);
-  sigdelset(&sigsToBlock, SIGILL);
-  sigdelset(&sigsToBlock, SIGABRT);
-  sigdelset(&sigsToBlock, SIGBUS);
-  sigdelset(&sigsToBlock, SIGSEGV);
-  sigdelset(&sigsToBlock, SIGTERM);
-  sigdelset(&sigsToBlock, SIGALRM);
-  ink_thread_sigsetmask(SIG_SETMASK, &sigsToBlock, NULL);
-
-  // Set up the SIGCHLD handler so we do not get into
-  //   a problem with Solaris 2.6 and strange waitpid()
-  //   behavior
-  sigChldHandler.sa_handler = SigChldHandler;
-  sigChldHandler.sa_flags = SA_RESTART;
-  sigemptyset(&sigChldHandler.sa_mask);
-  sigaction(SIGCHLD, &sigChldHandler, NULL);
-}
-
-#if defined(linux)
-#include <sys/prctl.h>
-#endif
-static int
-setup_coredump()
-{
-#if defined(linux)
-#ifndef PR_SET_DUMPABLE
-#define PR_SET_DUMPABLE 4       /* Ugly, but we cannot compile with 2.2.x otherwise.
-                                   Should be removed when we compile only on 2.4.x */
-#endif
-  prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
-#endif  // linux check
-  return 0;
-}
-
-static void
-init_dirs()
-{
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-
-  if (access(Layout::get()->sysconfdir, R_OK) == -1) {
-    mgmt_elog(0, "unable to access() config dir '%s': %d, %s\n", Layout::get()->sysconfdir, errno, strerror(errno));
-    mgmt_elog(0, "please set the 'TS_ROOT' environment variable\n");
-    _exit(1);
-  }
-
-  if (access(rundir, R_OK) == -1) {
-    mgmt_elog(0, "unable to access() local state dir '%s': %d, %s\n", (const char *)rundir, errno, strerror(errno));
-    mgmt_elog(0, "please set 'proxy.config.local_state_dir'\n");
-    _exit(1);
-  }
-}
-
-static void
-chdir_root()
-{
-  const char * prefix = Layout::get()->prefix;
-
-  if (chdir(prefix) < 0) {
-    mgmt_elog(0, "unable to change to root directory \"%s\" [%d '%s']\n", prefix, errno, strerror(errno));
-    mgmt_elog(0, " please set correct path in env variable TS_ROOT \n");
-    exit(1);
-  } else {
-    mgmt_log("[TrafficManager] using root directory '%s'\n", prefix);
-  }
-}
-
-
-static void
-set_process_limits(int fds_throttle)
-{
-  struct rlimit lim;
-
-  // Set needed rlimits (root)
-  ink_max_out_rlimit(RLIMIT_NOFILE, true, false);
-  ink_max_out_rlimit(RLIMIT_STACK, true, true);
-  ink_max_out_rlimit(RLIMIT_DATA, true, true);
-  ink_max_out_rlimit(RLIMIT_FSIZE, true, false);
-#ifdef RLIMIT_RSS
-  ink_max_out_rlimit(RLIMIT_RSS, true, true);
-#endif
-
-#if defined(linux)
-  float file_max_pct = 0.9;
-  FILE *fd;
-
-  if ((fd = fopen("/proc/sys/fs/file-max","r"))) {
-    ATS_UNUSED_RETURN(fscanf(fd, "%lu", &lim.rlim_max));
-    fclose(fd);
-    REC_ReadConfigFloat(file_max_pct, "proxy.config.system.file_max_pct");
-    lim.rlim_cur = lim.rlim_max = static_cast<rlim_t>(lim.rlim_max * file_max_pct);
-    if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
-      fds_limit = (int) lim.rlim_cur;
-      syslog(LOG_NOTICE, "NOTE: RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
-    } else {
-      syslog(LOG_NOTICE, "NOTE: Unable to set RLIMIT_NOFILE(%d):cur(%d),max(%d)", RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
-    }
-  } else {
-    syslog(LOG_NOTICE, "NOTE: Unable to open /proc/sys/fs/file-max");
-  }
-#endif // linux
-
-  if (!getrlimit(RLIMIT_NOFILE, &lim)) {
-    if (fds_throttle > (int) (lim.rlim_cur + FD_THROTTLE_HEADROOM)) {
-      lim.rlim_cur = (lim.rlim_max = (rlim_t) fds_throttle);
-      if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
-        fds_limit = (int) lim.rlim_cur;
-	syslog(LOG_NOTICE, "NOTE: RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
-      }
-    }
-  }
-
-}
-
-#if TS_HAS_WCCP
-static void
-Errata_Logger(ts::Errata const& err) {
-  size_t n;
-  static size_t const SIZE = 4096;
-  char buff[SIZE];
-  if (err.size()) {
-    ts::Errata::Code code = err.top().getCode();
-    n = err.write(buff, SIZE, 1, 0, 2, "> ");
-    // strip trailing newlines.
-    while (n && (buff[n-1] == '\n' || buff[n-1] == '\r'))
-      buff[--n] = 0;
-    // log it.
-    if (code > 1) mgmt_elog(0, "[WCCP]%s", buff);
-    else if (code > 0) mgmt_log("[WCCP]%s", buff);
-    else Debug("WCCP", "%s", buff);
-  }
-}
-
-static void
-Init_Errata_Logging() {
-  ts::Errata::registerSink(&Errata_Logger);
-}
-#endif
-
-int
-main(int argc, char **argv)
-{
-  // Before accessing file system initialize Layout engine
-  Layout::create();
-  ink_strlcpy(mgmt_path, Layout::get()->sysconfdir, sizeof(mgmt_path));
-
-  // change the directory to the "root" directory
-  chdir_root();
-
-  // Line buffer standard output & standard error
-  int status;
-  status = setvbuf(stdout, NULL, _IOLBF, 0);
-  if (status != 0)
-    perror("WARNING: can't line buffer stdout");
-  status = setvbuf(stderr, NULL, _IOLBF, 0);
-  if (status != 0)
-    perror("WARNING: can't line buffer stderr");
-
-  bool found = false;
-  int just_started = 0;
-  int cluster_mcport = -1, cluster_rsport = -1;
-  // TODO: This seems completely incomplete, disabled for now
-  //  int dump_config = 0, dump_process = 0, dump_node = 0, dump_cluster = 0, dump_local = 0;
-  char* proxy_port = 0;
-  int proxy_backdoor = -1;
-  char *envVar = NULL, *group_addr = NULL, *tsArgs = NULL;
-  bool log_to_syslog = true;
-  char userToRunAs[80];
-  int  fds_throttle = -1;
-  time_t ticker;
-  ink_thread webThrId;
-
-
-  // Set up the application version info
-  appVersionInfo.setup(PACKAGE_NAME,"traffic_manager", PACKAGE_VERSION,
-                       __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
-  initSignalHandlers();
-
-  // Process Environment Variables
-  if ((envVar = getenv("MGMT_ACONF_PORT")) != NULL) {
-    aconf_port_arg = atoi(envVar);
-  }
-
-  if ((envVar = getenv("MGMT_CLUSTER_MC_PORT")) != NULL) {
-    cluster_mcport = atoi(envVar);
-  }
-
-  if ((envVar = getenv("MGMT_CLUSTER_RS_PORT")) != NULL) {
-    cluster_rsport = atoi(envVar);
-  }
-
-  if ((envVar = getenv("MGMT_GROUP_ADDR")) != NULL) {
-    group_addr = envVar;
-  }
-
-  for (int i = 1; i < argc; i++) {      /* Process command line args */
-
-    if (argv[i][0] == '-') {
-      if ((strcmp(argv[i], "-version") == 0) || (strcmp(argv[i], "-V") == 0)) {
-        fprintf(stderr, "%s\n", appVersionInfo.FullVersionInfoStr);
-        exit(0);
-      } else if (strcmp(argv[i], "-proxyOff") == 0) {
-        proxy_on = false;
-      } else if (strcmp(argv[i], "-nosyslog") == 0) {
-        log_to_syslog = false;
-      } else {
-        // The rest of the options require an argument in the form of -<Flag> <val>
-        if ((i + 1) < argc) {
-
-          if (strcmp(argv[i], "-aconfPort") == 0) {
-            ++i;
-            aconf_port_arg = atoi(argv[i]);
-          } else if (strcmp(argv[i], "-clusterMCPort") == 0) {
-            ++i;
-            cluster_mcport = atoi(argv[i]);
-          } else if (strcmp(argv[i], "-groupAddr") == 0) {
-            ++i;
-            group_addr = argv[i];
-          } else if (strcmp(argv[i], "-clusterRSPort") == 0) {
-            ++i;
-            cluster_rsport = atoi(argv[i]);
-#if TS_USE_DIAGS
-          } else if (strcmp(argv[i], "-debug") == 0) {
-            ++i;
-            ink_strlcpy(debug_tags, argv[i], sizeof(debug_tags));
-          } else if (strcmp(argv[i], "-action") == 0) {
-            ++i;
-            ink_strlcpy(action_tags, argv[i], sizeof(debug_tags));
-#endif
-          } else if (strcmp(argv[i], "-path") == 0) {
-            ++i;
-            //bugfixed by YTS Team, yamsat(id-59703)
-            if ((strlen(argv[i]) > PATH_NAME_MAX)) {
-              fprintf(stderr, "\n   Path exceeded the maximum allowed characters.\n");
-              exit(1);
-            }
-
-            ink_strlcpy(mgmt_path, argv[i], sizeof(mgmt_path));
-            /*
-               } else if(strcmp(argv[i], "-lmConf") == 0) {
-               ++i;
-               lm_conf = argv[i];
-             */
-          } else if (strcmp(argv[i], "-recordsConf") == 0) {
-            ++i;
-            recs_conf = argv[i];
-            // TODO: This seems completely incomplete, disabled for now
-#if 0
-          } else if (strcmp(argv[i], "-printRecords") == 0) {
-            ++i;
-            while (i < argc && argv[i][0] != '-') {
-              if (strcasecmp(argv[i], "config") == 0) {
-                dump_config = 1;
-              } else if (strcasecmp(argv[i], "process") == 0) {
-                dump_process = 1;
-              } else if (strcasecmp(argv[i], "node") == 0) {
-                dump_node = 1;
-              } else if (strcasecmp(argv[i], "cluster") == 0) {
-                dump_cluster = 1;
-              } else if (strcasecmp(argv[i], "local") == 0) {
-                dump_local = 1;
-              } else if (strcasecmp(argv[i], "all") == 0) {
-                dump_config = dump_node = dump_process = dump_cluster = dump_local = 1;
-              }
-              ++i;
-            }
-            --i;
-#endif
-          } else if (strcmp(argv[i], "-tsArgs") == 0) {
-            int size_of_args = 0, j = (++i);
-            while (j < argc) {
-              size_of_args += 1;
-              size_of_args += strlen((argv[j++]));
-            }
-            tsArgs = (char *)ats_malloc(size_of_args + 1);
-
-            j = 0;
-            while (i < argc) {
-              snprintf(&tsArgs[j], ((size_of_args + 1) - j), " %s", argv[i]);
-              j += strlen(argv[i]) + 1;
-              ++i;
-            }
-          } else if (strcmp(argv[i], "-proxyPort") == 0) {
-            ++i;
-            proxy_port = argv[i];
-          } else if (strcmp(argv[i], "-proxyBackDoor") == 0) {
-            ++i;
-            proxy_backdoor = atoi(argv[i]);
-          } else {
-            printUsage();
-          }
-        } else {
-          printUsage();
-        }
-      }
-    }
-  }
-
-
-  // Bootstrap with LOG_DAEMON until we've read our configuration
-  if (log_to_syslog) {
-    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, LOG_DAEMON);
-    mgmt_use_syslog();
-    syslog(LOG_NOTICE, "NOTE: --- Manager Starting ---");
-    syslog(LOG_NOTICE, "NOTE: Manager Version: %s", appVersionInfo.FullVersionInfoStr);
-  }
-
-  // Bootstrap the Diags facility so that we can use it while starting
-  //  up the manager
-  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, false);
-  diags = diagsConfig->diags;
-  diags->prefix_str = "Manager ";
-
-  RecLocalInit();
-  LibRecordsConfigInit();
-  RecordsConfigOverrideFromEnvironment();
-
-  init_dirs();// setup critical directories, needs LibRecords
-
-  // Get the config info we need while we are still root
-  extractConfigInfo(mgmt_path, recs_conf, userToRunAs, &fds_throttle);
-
-  set_process_limits(fds_throttle); // as root
-  runAsUser(userToRunAs);
-  setup_coredump();
-  check_lockfile();
-
-  url_init();
-  mime_init();
-  http_init();
-
-
-#if TS_HAS_WCCP
-  Init_Errata_Logging();
-#endif
-  ts_host_res_global_init();
-  ts_session_protocol_well_known_name_indices_init();
-  lmgmt = new LocalManager(proxy_on);
-  RecLocalInitMessage();
-  lmgmt->initAlarm();
-
-  if (diags) {
-    delete diagsConfig;
-    // diagsConfig->reconfigure_diags(); INKqa11968
-    /*
-       delete diags;
-       diags = new Diags(debug_tags,action_tags);
-     */
-  }
-  // INKqa11968: need to set up callbacks and diags data structures
-  // using configuration in records.config
-  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, true);
-  diags = diagsConfig->diags;
-  RecSetDiags(diags);
-  diags->prefix_str = "Manager ";
-
-  if (is_debug_tag_set("diags"))
-    diags->dump();
-  diags->cleanup_func = mgmt_cleanup;
-
-  // Setup the exported manager version records.
-  RecSetRecordString("proxy.node.version.manager.short", appVersionInfo.VersionStr);
-  RecSetRecordString("proxy.node.version.manager.long", appVersionInfo.FullVersionInfoStr);
-  RecSetRecordString("proxy.node.version.manager.build_number", appVersionInfo.BldNumStr);
-  RecSetRecordString("proxy.node.version.manager.build_time", appVersionInfo.BldTimeStr);
-  RecSetRecordString("proxy.node.version.manager.build_date", appVersionInfo.BldDateStr);
-  RecSetRecordString("proxy.node.version.manager.build_machine", appVersionInfo.BldMachineStr);
-  RecSetRecordString("proxy.node.version.manager.build_person", appVersionInfo.BldPersonStr);
-//    RecSetRecordString("proxy.node.version.manager.build_compile_flags",
-//                       appVersionInfo.BldCompileFlagsStr);
-
-  if (log_to_syslog) {
-    char sys_var[] = "proxy.config.syslog_facility";
-    char *facility_str = NULL;
-    int facility_int;
-    facility_str = REC_readString(sys_var, &found);
-    ink_assert(found);
-
-    if (!found) {
-      mgmt_elog(0, "Could not read %s.  Defaulting to DAEMON\n", sys_var);
-      facility_int = LOG_DAEMON;
-    } else {
-      facility_int = facility_string_to_int(facility_str);
-      ats_free(facility_str);
-      if (facility_int < 0) {
-        mgmt_elog(0, "Bad syslog facility specified.  Defaulting to DAEMON\n");
-        facility_int = LOG_DAEMON;
-      }
-    }
-
-    // NOTE: do NOT call closelog() here.  Solaris gets confused
-    //   and some how it hoses later calls to readdir_r.
-    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, facility_int);
-
-    lmgmt->syslog_facility = facility_int;
-  } else {
-    lmgmt->syslog_facility = -1;
-  }
-
-  // Find out our hostname so we can use it as part of the initialization
-  setHostnameVar();
-
-  // Create the data structure for overview page
-  //   Do this before the rest of the set up since it needs
-  //   to created to handle any alarms thrown by later
-  //   initialization
-  overviewGenerator = new overviewPage();
-
-  // Initialize the Config Object bindings before
-  //   starting any other threads
-  configFiles = new FileManager();
-  initializeRegistry();
-  configFiles->registerCallback(fileUpdated);
-
-  // RecLocal's 'sync_thr' depends on 'configFiles', so we can't
-  // stat the 'sync_thr' until 'configFiles' has been initialized.
-  RecLocalStart();
-
-  /* Update cmd line overrides/environmental overrides/etc */
-  if (tsArgs) {                 /* Passed command line args for proxy */
-    ats_free(lmgmt->proxy_options);
-    lmgmt->proxy_options = tsArgs;
-    mgmt_log(stderr, "[main] Traffic Server Args: '%s'\n", lmgmt->proxy_options);
-  }
-  if (proxy_port) {
-    HttpProxyPort::loadValue(lmgmt->m_proxy_ports, proxy_port);
-  }
-
-  if (proxy_backdoor != -1) {
-    RecSetRecordInt("proxy.config.process_manager.mgmt_port", proxy_backdoor);
-  }
-
-  if (cluster_rsport == -1) {
-    cluster_rsport = REC_readInteger("proxy.config.cluster.rsport", &found);
-    ink_assert(found);
-  }
-
-  if (cluster_mcport == -1) {
-    cluster_mcport = REC_readInteger("proxy.config.cluster.mcport", &found);
-    ink_assert(found);
-  }
-
-  if (!group_addr) {
-    group_addr = REC_readString("proxy.config.cluster.mc_group_addr", &found);
-    ink_assert(found);
-  }
-
-  in_addr_t min_ip = inet_network("224.0.0.255");
-  in_addr_t max_ip = inet_network("239.255.255.255");
-  in_addr_t group_addr_ip = inet_network(group_addr);
-
-  if (!(min_ip < group_addr_ip && group_addr_ip < max_ip)) {
-    mgmt_fatal(0, "[TrafficManager] Multi-Cast group addr '%s' is not in the permitted range of %s\n",
-               group_addr, "224.0.1.0 - 239.255.255.255");
-  }
-
-  /* TODO: Do we really need to init cluster communication? */
-  lmgmt->initCCom(cluster_mcport, group_addr, cluster_rsport);       /* Setup cluster communication */
-
-  lmgmt->initMgmtProcessServer();       /* Setup p-to-p process server */
-
-
-  // Now that we know our cluster ip address, add the
-  //   UI record for this machine
-  overviewGenerator->addSelfRecord();
-
-  lmgmt->listenForProxy();
-
-  //
-  // As listenForProxy() may change/restore euid, we should put
-  // the creation of webIntr_main thread after it. So that we
-  // can keep a consistent euid when create mgmtapi/eventapi unix
-  // sockets in webIntr_main thread.
-  //
-  webThrId = ink_thread_create(webIntr_main, NULL);     /* Spin web agent thread */
-  Debug("lm", "Created Web Agent thread (%"  PRId64 ")", (int64_t)webThrId);
-
-  ticker = time(NULL);
-  mgmt_log("[TrafficManager] Setup complete\n");
-
-  statProcessor = new StatProcessor();
-
-  for (;;) {
-    lmgmt->processEventQueue();
-    lmgmt->pollMgmtProcessServer();
-
-    // Check for a SIGHUP
-    if (sigHupNotifier != 0) {
-      mgmt_log(stderr, "[main] Reading Configuration Files due to SIGHUP\n");
-      configFiles->rereadConfig();
-      lmgmt->signalEvent(MGMT_EVENT_PLUGIN_CONFIG_UPDATE, "*");
-      sigHupNotifier = 0;
-      mgmt_log(stderr, "[main] Reading Configuration Files Reread\n");
-    }
-    // Check for SIGUSR2
-    if (sigUsr2Notifier != 0) {
-      ink_stack_trace_dump();
-      sigUsr2Notifier = 0;
-    }
-
-    lmgmt->ccom->generateClusterDelta();
-
-    if (lmgmt->run_proxy && lmgmt->processRunning()) {
-      lmgmt->ccom->sendSharedData();
-      lmgmt->virt_map->lt_runGambit();
-    } else {
-      if (!lmgmt->run_proxy) {  /* Down if we are not going to start another immed. */
-        /* Proxy is not up, so no addrs should be */
-        lmgmt->virt_map->downOurAddrs();
-      }
-
-      /* Proxy is not up, but we should still exchange config and alarm info */
-      lmgmt->ccom->sendSharedData(false);
-    }
-
-    lmgmt->ccom->checkPeers(&ticker);
-    overviewGenerator->checkForUpdates();
-
-    if (statProcessor) {
-      statProcessor->processStat();
-    }
-
-    if (lmgmt->mgmt_shutdown_outstanding == true) {
-      lmgmt->mgmtShutdown(true);
-      _exit(0);
-    }
-
-    if (lmgmt->run_proxy && !lmgmt->processRunning()) { /* Make sure we still have a proxy up */
-      if (lmgmt->startProxy())
-        just_started = 0;
-      else
-        just_started++;
-    } else {                    /* Give the proxy a chance to fire up */
-      just_started++;
-    }
-
-    /* This will catch the case were the proxy dies before it can connect to manager */
-    if (lmgmt->proxy_launch_outstanding && !lmgmt->processRunning() && just_started >= 120) {
-      just_started = 0;
-      lmgmt->proxy_launch_outstanding = false;
-      if (lmgmt->proxy_launch_pid != -1) {
-        int res;
-        kill(lmgmt->proxy_launch_pid, 9);
-        waitpid(lmgmt->proxy_launch_pid, &res, 0);
-        if (WIFSIGNALED(res)) {
-          int sig = WTERMSIG(res);
-#ifdef NEED_PSIGNAL
-          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d\n", sig);
-#else
-          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d: %s\n", sig, strsignal(sig));
-#endif /* NEED_PSIGNAL */
-        }
-      }
-      mgmt_log(stderr, "[main] Proxy launch failed, retrying...\n");
-    }
-
-  }
-
-  if (statProcessor) {
-    delete(statProcessor);
-  }
-
-#ifndef MGMT_SERVICE
-  return 0;
-#endif
-
-}                               /* End main */
-
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-static void
-SignalAlrmHandler(int /* sig ATS_UNUSED */, siginfo_t * t, void * /* c ATS_UNUSED */)
-#else
-static void
-SignalAlrmHandler(int /* sig ATS_UNUSED */)
-#endif
-{
-  /*
-     fprintf(stderr, "[TrafficManager] ==> SIGALRM received\n");
-     mgmt_elog(stderr, 0, "[TrafficManager] ==> SIGALRM received\n");
-   */
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  if (t) {
-    if (t->si_code <= 0) {
-#if defined(solaris)
-      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", (int)t->si_pid, t->si_uid);
-#else
-      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", t->si_pid, t->si_uid);
-#endif
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", t->si_pid, t->si_uid);
-    } else {
-      fprintf(stderr, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", t->si_code);
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", t->si_code);
-    }
-  }
-#endif
-
-  return;
-}
-
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-static void
-SignalHandler(int sig, siginfo_t * t, void *c)
-#else
-static void
-SignalHandler(int sig)
-#endif
-{
-  static int clean = 0;
-  int status;
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  if (t) {
-    if (t->si_code <= 0) {
-#if defined(solaris)
-      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, (int)t->si_pid, t->si_uid);
-#else
-      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, t->si_pid, t->si_uid);
-#endif
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, t->si_pid, t->si_uid);
-    } else {
-      fprintf(stderr, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", sig, t->si_code);
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", sig, t->si_code);
-    }
-  }
-#endif
-
-
-  if (sig == SIGHUP) {
-    sigHupNotifier = 1;
-    return;
-  }
-
-  if (sig == SIGUSR2) {
-    sigUsr2Notifier = 1;
-    return;
-  }
-  fprintf(stderr, "[TrafficManager] ==> Cleaning up and reissuing signal #%d\n", sig);
-  mgmt_elog(stderr, 0, "[TrafficManager] ==> Cleaning up and reissuing signal #%d\n", sig);
-
-  if (lmgmt && !clean) {
-    clean = 1;
-    if (lmgmt->watched_process_pid != -1) {
-
-      if (sig == SIGTERM || sig == SIGINT) {
-        kill(lmgmt->watched_process_pid, sig);
-        waitpid(lmgmt->watched_process_pid, &status, 0);
-      }
-    }
-    lmgmt->mgmtCleanup();
-  }
-
-  switch (sig) {
-  case SIGQUIT:
-  case SIGILL:
-  case SIGTRAP:
-#if !defined(linux)
-  case SIGEMT:
-  case SIGSYS:
-#endif
-  case SIGFPE:
-  case SIGBUS:
-  case SIGSEGV:
-  case SIGXCPU:
-  case SIGXFSZ:
-    abort();
-  default:
-    fprintf(stderr, "[TrafficManager] ==> signal #%d\n", sig);
-    mgmt_elog(stderr, 0, "[TrafficManager] ==> signal #%d\n", sig);
-    _exit(sig);
-  }
-  fprintf(stderr, "[TrafficManager] ==> signal2 #%d\n", sig);
-  mgmt_elog(stderr, 0, "[TrafficManager] ==> signal2 #%d\n", sig);
-  _exit(sig);
-}                               /* End SignalHandler */
-
-
-// void SigChldHandler(int sig)
-//
-//   An empty handler needed so that we catch SIGCHLD
-//    With Solaris 2.6, ignoring sig child changes the behavior
-//    of waitpid() so that if there are no unwaited children,
-//    waitpid() blocks until all child are transformed into
-//    zombies which is bad for us
-//
-static void
-SigChldHandler(int /* sig ATS_UNUSED */)
-{
-}
-
-void
-printUsage()
-{
-  fprintf(stderr, "----------------------------------------------------------------------------\n");
-  fprintf(stderr, " Traffic Manager Usage: (all args are optional)\n");
-  fprintf(stderr, "\n");
-  fprintf(stderr, "   traffic_manager [options]\n");
-  fprintf(stderr, "     -proxyPort     <port>  Port to have proxy listen on, overrides records.config.\n");
-  /* Function is currently #ifdef'ed out so no reason to advertise
-     fprintf(stderr,
-     "     -proxyBackdoor <port>  Port to put proxy mgmt port on.\n");
-   */
-  /* Commented out because this option is used for debugging only.
-     fprintf(stderr,
-     "     -noProxy               Do not launch the proxy process.\n");
-   */
-  fprintf(stderr, "     -tsArgs        [...]   Args to proxy, everything till eol is passed.\n");
-  fprintf(stderr, "     -webPort       <port>  Port for web interface.\n");
-  /*
-     fprintf(stderr,
-     "     -graphPort     <port>  Port for dynamic graphs.\n");
-   */
-  fprintf(stderr, "     -clusterPort   <port>  Cluster Multicast port\n");
-  fprintf(stderr, "     -groupAddr     <addr>  Cluster Multicast group, example: \"225.0.0.37\".\n");
-  fprintf(stderr, "     -clusterRSPort <port>  Cluster Multicast port.\n");
-  fprintf(stderr, "     -path          <path>  Root path for config files.\n");
-  /*
-     fprintf(stderr,
-     "     -lmConf        <fname> Local Management config file.\n");
-   */
-  fprintf(stderr, "     -recordsConf   <fname> General config file.\n");
-  // TODO: This seems completely incomplete, disabled for now
-  // fprintf(stderr, "     -printRecords  [...]   Print flags, default all are off.\n");
-  fprintf(stderr, "     -debug         <tags>  Enable the given debug tags\n");
-  fprintf(stderr, "     -action        <tags>  Enable the given action tags.\n");
-  fprintf(stderr, "     -version or -V         Print version id and exit.\n");
-  fprintf(stderr, "\n");
-  fprintf(stderr, "   [...] can be one+ of: [config process node cluster local all]\n");
-  fprintf(stderr, "----------------------------------------------------------------------------\n");
-  exit(0);
-}                               /* End printUsage */
-
-void
-fileUpdated(char *fname, bool incVersion)
-{
-  if (strcmp(fname, "cluster.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cluster.cluster_configuration");
-
-  } else if (strcmp(fname, "remap.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.url_remap.filename");
-
-  } else if (strcmp(fname, "socks.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.socks.socks_config_file");
-
-  } else if (strcmp(fname, "records.config") == 0) {
-    lmgmt->signalFileChange("records.config", incVersion);
-
-  } else if (strcmp(fname, "cache.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cache.control.filename");
-
-  } else if (strcmp(fname, "parent.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.http.parent_proxy.file");
-
-  } else if (strcmp(fname, "ip_allow.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cache.ip_allow.filename");
-  } else if (strcmp(fname, "vaddrs.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] vaddrs.config updated\n");
-    lmgmt->virt_map->lt_readAListFile(fname);
-
-  } else if (strcmp(fname, "storage.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] storage.config changed, need restart auto-rebuild mode\n");
-
-  } else if (strcmp(fname, "proxy.pac") == 0) {
-    mgmt_log(stderr, "[fileUpdated] proxy.pac file has been modified\n");
-
-  } else if (strcmp(fname, "icp.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.icp.icp_configuration");
-
-  } else if (strcmp(fname, "update.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.update.update_configuration");
-
-  } else if (strcmp(fname, "volume.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] volume.config changed, need restart\n");
-
-  } else if (strcmp(fname, "hosting.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cache.hosting_filename");
-
-  } else if (strcmp(fname, "log_hosts.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.log.hosts_config_file");
-
-  } else if (strcmp(fname, "logs_xml.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.log.xml_config_file");
-
-  } else if (strcmp(fname, "splitdns.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.dns.splitdns.filename");
-
-  } else if (strcmp(fname, "plugin.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] plugin.config file has been modified\n");
-
-  } else if (strcmp(fname, "ssl_multicert.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.ssl.server.multicert.filename");
-
-  } else if (strcmp(fname, "proxy.config.body_factory.template_sets_dir") == 0) {
-    lmgmt->signalFileChange("proxy.config.body_factory.template_sets_dir");
-
-  } else if (strcmp(fname, "stats.config.xml") == 0) {
-    if (statProcessor) {
-      statProcessor->rereadConfig();
-    }
-    mgmt_log(stderr, "[fileUpdated] stats.config.xml file has been modified\n");
-  } else if (strcmp(fname, "congestion.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.http.congestion_control.filename");
-  } else if (strcmp(fname, "prefetch.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.prefetch.config_file");
-  } else {
-    mgmt_elog(stderr, 0, "[fileUpdated] Unknown config file updated '%s'\n", fname);
-
-  }
-  return;
-}                               /* End fileUpdate */
-
-#if TS_USE_POSIX_CAP
-/** Restore capabilities after user id change.
-    This manipulates LINUX capabilities so that this process
-    can perform certain privileged operations even if it is
-    no longer running as a privilege user.
-
-    @internal
-    I tried using
-    @code
-    prctl(PR_SET_KEEPCAPS, 1);
-    @endcode
-    but that had no effect even though the call reported success.
-    Only explicit capability manipulation was effective.
-
-    It does not appear to be necessary to set the capabilities on the
-    executable if originally run as root. That may be needed if
-    started as a user without that capability.
- */
-
-int
-restoreCapabilities() {
-  int zret = 0; // return value.
-  cap_t cap_set = cap_get_proc(); // current capabilities
-  // Make a list of the capabilities we want turned on.
-  cap_value_t cap_list[] = {
-    CAP_NET_ADMIN, ///< Set socket transparency.
-    CAP_NET_BIND_SERVICE, ///< Low port (e.g. 80) binding.
-    CAP_IPC_LOCK ///< Lock IPC objects.
-  };
-  static int const CAP_COUNT = sizeof(cap_list)/sizeof(*cap_list);
-
-  cap_set_flag(cap_set, CAP_EFFECTIVE, CAP_COUNT, cap_list, CAP_SET);
-  zret = cap_set_proc(cap_set);
-  cap_free(cap_set);
-  return zret;
-}
-#endif
-
-//  void runAsUser(...)
-//
-//  If we are root, switched to user to run as
-//    specified in records.config
-//
-//  If we are not root, do nothing
-//
-void
-runAsUser(char *userName)
-{
-  uid_t uid, euid;
-  struct passwd *result;
-  const int bufSize = 1024;
-  char buf[bufSize];
-
-  uid = getuid();
-  euid = geteuid();
-
-  if (uid == 0 || euid == 0) {
-
-    /* Figure out what user we should run as */
-
-    Debug("lm", "[runAsUser] Attempting to run as user '%s'\n", userName);
-
-
-    if (userName == NULL || userName[0] == '\0') {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: proxy.config.admin.user_id is not set\n");
-      _exit(1);
-    }
-
-    struct passwd passwdInfo;
-    struct passwd *ppasswd = NULL;
-    result = NULL;
-    int res;
-    if (*userName == '#') {
-      int uuid = atoi(userName + 1);
-      if (uuid == -1)
-        uuid = (int)uid;
-      res = getpwuid_r((uid_t)uuid, &passwdInfo, buf, bufSize, &ppasswd);
-    }
-    else {
-      res = getpwnam_r(&userName[0], &passwdInfo, buf, bufSize, &ppasswd);
-    }
-
-    if (!res && ppasswd) {
-      result = ppasswd;
-    }
-
-    if (result == NULL) {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to get info about user %s : %s\n", userName, strerror(errno));
-      _exit(1);
-    }
-
-    if (setegid(result->pw_gid) != 0 || seteuid(result->pw_uid) != 0) {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to switch to user %s : %s\n", userName, strerror(errno));
-      _exit(1);
-    }
-
-    uid = getuid();
-    euid = geteuid();
-
-
-    Debug("lm", "[runAsUser] Running with uid: '%d' euid: '%d'\n", uid, euid);
-
-    if (uid != result->pw_uid && euid != result->pw_uid) {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Failed to switch to user %s\n", userName);
-      _exit(1);
-    }
-
-    // setup supplementary groups if it is not set.
-    if (0 == getgroups(0, NULL)) {
-      initgroups(&userName[0],result->pw_gid);
-    }
-
-#if TS_USE_POSIX_CAP
-    if (0 != restoreCapabilities()) {
-      mgmt_elog(stderr, 0, "[runAsUser] Error: Failed to restore capabilities after switch to user %s.\n", userName);
-    }
-#endif
-
-  }
-}                               /* End runAsUser() */
-
-
-//  void extractConfigInfo(...)
-//
-//  We need to get certain records.config values while we are
-//   root.  We can not use LMRecords to get them because the constructor
-//   for LMRecords creates the mgmt DBM and we do not want that to
-//   be owned as root.  This function extracts that info from
-//   records.config
-//
-//
-void
-extractConfigInfo(char *mgmt_path, const char *recs_conf, char *userName, int *fds_throttle)
-{
-  char file[1024];
-  bool useridFound = false;
-  bool throttleFound = false;
-
-  /* Figure out what user we should run as */
-  if (mgmt_path && recs_conf) {
-    FILE *fin;
-    snprintf(file, sizeof(file), "%s/%s.shadow", mgmt_path, recs_conf);
-    if (!(fin = fopen(file, "r"))) {
-      ink_filepath_make(file, sizeof(file), mgmt_path, recs_conf);
-      if (!(fin = fopen(file, "r"))) {
-        mgmt_elog(stderr, errno, "[extractConfigInfo] Unable to open config file(%s)\n", file);
-        _exit(1);
-      }
-    }
-    // Get 'user id' and 'network connections throttle limit'
-    while (((!useridFound) || (!throttleFound)) && fgets(file, 1024, fin)) {
-      if (strstr(file, "CONFIG proxy.config.admin.user_id STRING")) {
-        //coverity[secure_coding]
-        if ((sscanf(file, "CONFIG proxy.config.admin.user_id STRING %1023s\n", userName) == 1) &&
-            strcmp(userName, "NULL") != 0) {
-          useridFound = true;
-        }
-      } else if (strstr(file, "CONFIG proxy.config.net.connections_throttle INT")) {
-        if ((sscanf(file, "CONFIG proxy.config.net.connections_throttle INT %d\n", fds_throttle) == 1)) {
-          throttleFound = true;
-        }
-      }
-
-    }
-    fclose(fin);
-  } else {
-    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: unable to access records file\n");
-    _exit(1);
-  }
-
-  if (useridFound == false) {
-    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: proxy.config.admin.user_id is not set\n");
-    _exit(1);
-  }
-
-}                               /* End extractConfigInfo() */

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/Main.h
----------------------------------------------------------------------
diff --git a/mgmt/Main.h b/mgmt/Main.h
deleted file mode 100644
index ec37226..0000000
--- a/mgmt/Main.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-#ifndef _MAIN_H_
-#define _MAIN_H_
-
-#include "FileManager.h"
-#include "I_Version.h"
-
-// TODO: consolidate location of these defaults
-#define DEFAULT_ROOT_DIRECTORY            PREFIX
-#define DEFAULT_LOCAL_STATE_DIRECTORY     "var/trafficserver"
-#define DEFAULT_SYSTEM_CONFIG_DIRECTORY   "etc/trafficserver"
-#define DEFAULT_LOG_DIRECTORY             "var/log/trafficserver"
-
-void MgmtShutdown(int status);
-void fileUpdated(char *fname, bool incVersion);
-void runAsUser(char *userName);
-void printUsage(void);
-
-extern FileManager *configFiles;
-//extern overviewPage *overviewGenerator;
-extern AppVersionInfo appVersionInfo;
-
-// Global strings
-extern char mgmt_path[];
-
-// Global variable to replace ifdef MGMT_LAUNCH_PROXY so that
-// we can turn on/off proxy launch at runtime to facilitate
-// manager only testing.
-extern bool mgmt_launch_proxy;
-
-#endif /* _MAIN_H_ */

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/Makefile.am
----------------------------------------------------------------------
diff --git a/mgmt/Makefile.am b/mgmt/Makefile.am
index 8241ab8..2b69cce 100644
--- a/mgmt/Makefile.am
+++ b/mgmt/Makefile.am
@@ -19,29 +19,9 @@
 
 SUBDIRS = cluster utils web2 stats api
 
-# This is for traffic_manager only (local manager)
-AM_CPPFLAGS = $(ink_with_modules_local) \
-  $(iocore_include_dirs) \
-  -I$(top_srcdir)/lib/records \
-  -I$(top_srcdir)/lib/ts \
-  -I$(top_srcdir)/proxy \
-  -I$(top_srcdir)/proxy/hdrs \
-  -I$(top_srcdir)/proxy/shared \
-  -I$(top_srcdir)/mgmt \
-  -I$(top_srcdir)/mgmt/api/include \
-  -I$(top_srcdir)/mgmt/cluster \
-  -I$(top_srcdir)/mgmt/stats \
-  -I$(top_srcdir)/mgmt/utils \
-  -I$(top_srcdir)/mgmt/web2 \
-  -I$(top_srcdir)/lib \
-  -I$(top_builddir)/lib
-
-noinst_LIBRARIES = libmgmt_p.a
+noinst_LIBRARIES = libmgmt_p.a libmgmt_lm.a
 
-bin_PROGRAMS = traffic_manager
-
-# Compile this for "process manager"
-libmgmt_p_a_CPPFLAGS = \
+AM_CPPFLAGS = \
   $(iocore_include_dirs) \
   -I$(top_srcdir)/mgmt/api/include \
   -I$(top_srcdir)/mgmt/cluster \
@@ -66,8 +46,7 @@ libmgmt_p_a_SOURCES = \
   RecordsConfig.cc \
   RecordsConfig.h
 
-traffic_manager_SOURCES = \
-  AddConfigFilesHere.cc \
+libmgmt_lm_a_SOURCES = \
   Alarms.cc \
   Alarms.h \
   BaseManager.cc \
@@ -76,8 +55,6 @@ traffic_manager_SOURCES = \
   FileManager.h \
   LocalManager.cc \
   LocalManager.h \
-  Main.cc \
-  Main.h \
   MgmtDefs.h \
   MultiFile.cc \
   MultiFile.h \
@@ -86,29 +63,3 @@ traffic_manager_SOURCES = \
   Rollback.cc \
   Rollback.h
 
-traffic_manager_LDFLAGS = @EXTRA_CXX_LDFLAGS@ @EXPAT_LDFLAGS@ @LIBTOOL_LINK_FLAGS@
-traffic_manager_LDADD = \
-  cluster/libcluster.a \
-  stats/libstats.a \
-  web2/libweb.a \
-  api/libmgmtapilocal.a \
-  api/libtsmgmtshare.la \
-  utils/libutils_lm.a \
-  $(top_builddir)/proxy/hdrs/libhdrs.a \
-  $(top_builddir)/lib/records/libreclocal.a \
-  $(top_builddir)/lib/ts/libtsutil.la \
-  $(top_builddir)/iocore/eventsystem/libinkevent.a \
-  $(top_builddir)/proxy/shared/liberror.a \
-  $(top_builddir)/proxy/shared/libdiagsconfig.a \
-  @LIBRESOLV@ @LIBEXPAT@ @LIBPCRE@ @LIBTCL@ @LIBCAP@ @HWLOC_LIBS@ \
-  -lm
-
-# Must do it this way or the dependencies aren't detected.
-if BUILD_WCCP
-traffic_manager_LDADD += \
-  $(top_builddir)/lib/wccp/libwccp.a \
-  $(top_builddir)/lib/tsconfig/libtsconfig.la
-endif
-
-traffic_manager_LDADD += @OPENSSL_LIBS@
-

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/Rollback.cc
----------------------------------------------------------------------
diff --git a/mgmt/Rollback.cc b/mgmt/Rollback.cc
index 4489a18..3ed09b3 100644
--- a/mgmt/Rollback.cc
+++ b/mgmt/Rollback.cc
@@ -31,6 +31,7 @@
 #include "MgmtSocket.h"
 #include "ink_cap.h"
 #include "I_Layout.h"
+#include "FileManager.h"
 
 #define MAX_VERSION_DIGITS 11
 #define DEFAULT_BACKUPS 2
@@ -44,7 +45,7 @@ const char *RollbackStrings[] = { "Rollback Ok",
 };
 
 Rollback::Rollback(const char *baseFileName, bool root_access_needed_)
-  : root_access_needed(root_access_needed_)
+  : configFiles(NULL), root_access_needed(root_access_needed_)
 {
   version_t highestSeen;        // the highest backup version
   ExpandingArray existVer(25, true);    // Exsisting versions
@@ -535,7 +536,7 @@ Rollback::internalUpdate(textBuffer * buf, version_t newVersion, bool notifyChan
   returnCode = OK_ROLLBACK;
 
   // Post the change to the config file manager
-  if (notifyChange) {
+  if (notifyChange && configFiles) {
     configFiles->fileChanged(fileName, incVersion);
   }
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/Rollback.h
----------------------------------------------------------------------
diff --git a/mgmt/Rollback.h b/mgmt/Rollback.h
index 7b877a0..5382343 100644
--- a/mgmt/Rollback.h
+++ b/mgmt/Rollback.h
@@ -38,6 +38,8 @@
 #include "TextBuffer.h"
 #include "List.h"
 
+class FileManager;
+
 #define ACTIVE_VERSION 0
 #define INVALID_VERSION -1
 
@@ -200,6 +202,8 @@ public:
     return fileName;
   };
 
+  FileManager * configFiles; // Manager to notify on an update.
+
 private:
   Rollback(const Rollback &);
   int openFile(version_t version, int oflags, int *errnoPtr = NULL);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/api/CoreAPI.cc
----------------------------------------------------------------------
diff --git a/mgmt/api/CoreAPI.cc b/mgmt/api/CoreAPI.cc
index a27ed09..1ca1fc3 100644
--- a/mgmt/api/CoreAPI.cc
+++ b/mgmt/api/CoreAPI.cc
@@ -30,7 +30,6 @@
  ***************************************************************************/
 
 #include "ink_platform.h"
-#include "Main.h"
 #include "MgmtUtils.h"
 #include "LocalManager.h"
 #include "FileManager.h"
@@ -50,6 +49,8 @@
 // global variable
 CallbackTable *local_event_callbacks;
 
+extern FileManager *configFiles; // global in traffic_manager
+
 /*-------------------------------------------------------------------------
  * Init
  *-------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/api/TSControlMain.cc
----------------------------------------------------------------------
diff --git a/mgmt/api/TSControlMain.cc b/mgmt/api/TSControlMain.cc
index 71e7ad0..bfbe91e 100644
--- a/mgmt/api/TSControlMain.cc
+++ b/mgmt/api/TSControlMain.cc
@@ -32,7 +32,6 @@
 
 #include "libts.h"
 #include "LocalManager.h"
-#include "Main.h"
 #include "MgmtUtils.h"
 #include "MgmtSocket.h"
 #include "TSControlMain.h"

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/cluster/ClusterCom.cc
----------------------------------------------------------------------
diff --git a/mgmt/cluster/ClusterCom.cc b/mgmt/cluster/ClusterCom.cc
index fceb0dc..c538235 100644
--- a/mgmt/cluster/ClusterCom.cc
+++ b/mgmt/cluster/ClusterCom.cc
@@ -38,30 +38,31 @@
 #include "TextBuffer.h"
 #include "MgmtSocket.h"
 
-#include "Main.h"
 #include "LocalManager.h"
 #include "ClusterCom.h"
 #include "MgmtUtils.h"
 #include "WebMgmtUtils.h"
 #include "MgmtHashTable.h"
+#include "FileManager.h"
+
+static bool checkBackDoor(int req_fd, char *message);
 
 int MultiCastMessages = 0;
 long LastHighestDelta = -1L;
 
-
-void *
+static void *
 drainIncomingChannel_broadcast(void *arg)
 {
   char message[61440];
   fd_set fdlist;
-  void *ret = arg;
+  ClusterCom * ccom = (ClusterCom *)arg;
 
   time_t t;
   time_t last_multicast_receive_time = time(NULL);
   struct timeval tv;
 
   /* Avert race condition, thread spun during constructor */
-  while (!lmgmt->ccom || !lmgmt->ccom->init) {
+  while (lmgmt->ccom != ccom || !lmgmt->ccom->init) {
     mgmt_sleep_sec(1);
   }
 
@@ -71,34 +72,34 @@ drainIncomingChannel_broadcast(void *arg)
     // linux: set tv.tv_set in select() loop, since linux's select()
     // will update tv with the amount of time not slept (most other
     // implementations do not do this)
-    tv.tv_sec = lmgmt->ccom->mc_poll_timeout;             // interface not-responding timeout
+    tv.tv_sec = ccom->mc_poll_timeout;             // interface not-responding timeout
     tv.tv_usec = 0;
 
     memset(message, 0, 61440);
     FD_ZERO(&fdlist);
 
-    if (lmgmt->ccom->cluster_type != NO_CLUSTER) {
-      if (lmgmt->ccom->receive_fd > 0) {
-        FD_SET(lmgmt->ccom->receive_fd, &fdlist);       /* Multicast fd */
+    if (ccom->cluster_type != NO_CLUSTER) {
+      if (ccom->receive_fd > 0) {
+        FD_SET(ccom->receive_fd, &fdlist);       /* Multicast fd */
       }
     }
 
     mgmt_select(FD_SETSIZE, &fdlist, NULL, NULL, &tv);
 
-    if (lmgmt->ccom->cluster_type != NO_CLUSTER) {
+    if (ccom->cluster_type != NO_CLUSTER) {
       // Multicast timeout considerations
-      if ((lmgmt->ccom->receive_fd < 0) || !FD_ISSET(lmgmt->ccom->receive_fd, &fdlist)) {
+      if ((ccom->receive_fd < 0) || !FD_ISSET(ccom->receive_fd, &fdlist)) {
         t = time(NULL);
         if ((t - last_multicast_receive_time) > (tv.tv_sec - 1)) {
           // Timeout on multicast receive channel, reset channel.
-          if (lmgmt->ccom->receive_fd > 0) {
-            close(lmgmt->ccom->receive_fd);
+          if (ccom->receive_fd > 0) {
+            close(ccom->receive_fd);
           }
-          lmgmt->ccom->receive_fd = -1;
+          ccom->receive_fd = -1;
           Debug("ccom", "Timeout, resetting multicast receive channel");
           if (lmgmt->ccom->establishReceiveChannel(0)) {
             Debug("ccom", "establishReceiveChannel failed");
-            lmgmt->ccom->receive_fd = -1;
+            ccom->receive_fd = -1;
           }
           last_multicast_receive_time = t;      // next action at next interval
         }
@@ -108,14 +109,15 @@ drainIncomingChannel_broadcast(void *arg)
     }
 
     /* Broadcast message */
-    if (lmgmt->ccom->cluster_type != NO_CLUSTER &&
-        lmgmt->ccom->receive_fd > 0 &&
-        FD_ISSET(lmgmt->ccom->receive_fd, &fdlist) &&
-        (lmgmt->ccom->receiveIncomingMessage(message, 61440) > 0)) {
-      lmgmt->ccom->handleMultiCastMessage(message);
+    if (ccom->cluster_type != NO_CLUSTER &&
+        ccom->receive_fd > 0 &&
+        FD_ISSET(ccom->receive_fd, &fdlist) &&
+        (ccom->receiveIncomingMessage(message, 61440) > 0)) {
+      ccom->handleMultiCastMessage(message);
     }
   }
-  return ret;
+
+  return NULL;
 }                               /* End drainIncomingChannel */
 
 /*
@@ -129,7 +131,7 @@ drainIncomingChannel(void *arg)
 {
   char message[61440];
   fd_set fdlist;
-  void *ret = arg;
+  ClusterCom * ccom = (ClusterCom *)arg;
   struct sockaddr_in cli_addr;
 
   // Fix for INKqa07688: There was a problem at Genuity where if you
@@ -162,7 +164,7 @@ drainIncomingChannel(void *arg)
   struct timeval tv;
 
   /* Avert race condition, thread spun during constructor */
-  while (!lmgmt->ccom || !lmgmt->ccom->init) {
+  while (lmgmt->ccom != ccom || !lmgmt->ccom->init) {
     mgmt_sleep_sec(1);
   }
 
@@ -172,22 +174,22 @@ drainIncomingChannel(void *arg)
     // linux: set tv.tv_set in select() loop, since linux's select()
     // will update tv with the amount of time not slept (most other
     // implementations do not do this)
-    tv.tv_sec = lmgmt->ccom->mc_poll_timeout;             // interface not-responding timeout
+    tv.tv_sec = ccom->mc_poll_timeout;             // interface not-responding timeout
     tv.tv_usec = 0;
 
     memset(message, 0, 61440);
     FD_ZERO(&fdlist);
 
-    if (lmgmt->ccom->cluster_type != NO_CLUSTER) {
-      FD_SET(lmgmt->ccom->reliable_server_fd, &fdlist);   /* TCP Server fd */
+    if (ccom->cluster_type != NO_CLUSTER) {
+      FD_SET(ccom->reliable_server_fd, &fdlist);   /* TCP Server fd */
     }
 
     mgmt_select(FD_SETSIZE, &fdlist, NULL, NULL, &tv);
 
-    if (FD_ISSET(lmgmt->ccom->reliable_server_fd, &fdlist)) {
+    if (FD_ISSET(ccom->reliable_server_fd, &fdlist)) {
       /* Reliable(TCP) request */
       int clilen = sizeof(cli_addr);
-      int req_fd = mgmt_accept(lmgmt->ccom->reliable_server_fd, (struct sockaddr *) &cli_addr, &clilen);
+      int req_fd = mgmt_accept(ccom->reliable_server_fd, (struct sockaddr *) &cli_addr, &clilen);
       if (req_fd < 0) {
         mgmt_elog(stderr, errno, "[drainIncomingChannel] error accepting " "reliable connection\n");
         continue;
@@ -199,7 +201,7 @@ drainIncomingChannel(void *arg)
       }
 
       // In no cluster mode, the rsport should not be listening.
-      ink_release_assert(lmgmt->ccom->cluster_type != NO_CLUSTER);
+      ink_release_assert(ccom->cluster_type != NO_CLUSTER);
 
       /* Handle Request */
       if (mgmt_readline(req_fd, message, 61440) > 0) {
@@ -227,13 +229,13 @@ drainIncomingChannel(void *arg)
 
           mgmt_log("[drainIncomingChannel] Got unmap request: '%s'\n", message);
 
-          ink_mutex_acquire(&(lmgmt->ccom->mutex));   /* Grab the lock */
+          ink_mutex_acquire(&(ccom->mutex));   /* Grab the lock */
           if (lmgmt->virt_map->rl_unmap(msg_ip)) {    /* Requires lock */
             msg = "unmap: done";
           } else {
             msg = "unmap: failed";
           }
-          ink_mutex_release(&(lmgmt->ccom->mutex));   /* Release the lock */
+          ink_mutex_release(&(ccom->mutex));   /* Release the lock */
 
           mgmt_writeline(req_fd, msg, strlen(msg));
 
@@ -254,13 +256,13 @@ drainIncomingChannel(void *arg)
 
           if (lmgmt->run_proxy) {
 
-            ink_mutex_acquire(&(lmgmt->ccom->mutex)); /* Grab the lock */
+            ink_mutex_acquire(&(ccom->mutex)); /* Grab the lock */
             if (lmgmt->virt_map->rl_map(msg_ip)) {    /* Requires the lock */
               msg = "map: done";
             } else {
               msg = "map: failed";
             }
-            ink_mutex_release(&(lmgmt->ccom->mutex)); /* Release the lock */
+            ink_mutex_release(&(ccom->mutex)); /* Release the lock */
           } else {
             msg = "map: failed";
           }
@@ -286,7 +288,7 @@ drainIncomingChannel(void *arg)
             continue;
           }
 
-          if (configFiles->getRollbackObj(fname, &rb) &&
+          if (ccom->configFiles->getRollbackObj(fname, &rb) &&
               (rb->getCurrentVersion() == ver) && (rb->getVersion(ver, &buff) == OK_ROLLBACK)) {
             size_t bytes_written = 0;
             stat = true;
@@ -337,7 +339,8 @@ drainIncomingChannel(void *arg)
       close_socket(req_fd);
     }
   }
-  return ret;
+
+  return NULL;
 }                               /* End drainIncomingChannel */
 
 
@@ -479,8 +482,8 @@ ClusterCom::ClusterCom(unsigned long oip, char *host, int mcport, char *group, i
   mismatchLog = ink_hash_table_create(InkHashTableKeyType_String);
 
   if (cluster_type != NO_CLUSTER) {
-    ink_thread_create(drainIncomingChannel_broadcast, 0);   /* Spin drainer thread */
-    ink_thread_create(drainIncomingChannel, 0);   /* Spin drainer thread */
+    ink_thread_create(drainIncomingChannel_broadcast, this);   /* Spin drainer thread */
+    ink_thread_create(drainIncomingChannel, this);   /* Spin drainer thread */
   }
   return;
 }                               /* End ClusterCom::ClusterCom */
@@ -500,6 +503,10 @@ ClusterCom::checkPeers(time_t * ticker)
   InkHashTableEntry *entry;
   InkHashTableIteratorState iterator_state;
 
+  // Hack in the file manager in case the rollback needs to send a notification. This is definitely
+  // a hack, but it helps break the dependency on global FileManager in traffic_manager.
+  cluster_file_rb->configFiles = configFiles;
+
   if (cluster_type == NO_CLUSTER)
     return;
 
@@ -1373,7 +1380,7 @@ ClusterCom::sendSharedData(bool send_proxy_heart_beat)
   memset(message, 0, 61440);
   resolved_addr.s_addr = our_ip;
   ink_strlcpy(addr, inet_ntoa(resolved_addr), sizeof(addr));
-  lmgmt->alarm_keeper->constructAlarmMessage(addr, message, 61440);
+  lmgmt->alarm_keeper->constructAlarmMessage(appVersionInfo, addr, message, 61440);
   sendOutgoingMessage(message, strlen(message));
 
   /*
@@ -1416,7 +1423,7 @@ ClusterCom::constructSharedGenericPacket(char *message, int max, RecT packet_typ
 
   /* Insert the standard packet header */
   resolved_addr.s_addr = our_ip;
-  running_sum = constructSharedPacketHeader(message, inet_ntoa(resolved_addr), max);
+  running_sum = constructSharedPacketHeader(appVersionInfo, message, inet_ntoa(resolved_addr), max);
 
   if (packet_type == RECT_NODE) {
     ink_strlcpy(&message[running_sum], "type: stat\n", (max - running_sum));
@@ -1527,14 +1534,14 @@ ClusterCom::constructSharedStatPacket(char *message, int max)
  *   Inserts that information.  Returns the nubmer of bytes inserted
  */
 int
-ClusterCom::constructSharedPacketHeader(char *message, char *ip, int max)
+ClusterCom::constructSharedPacketHeader(const AppVersionInfo& version, char *message, char *ip, int max)
 {
   int running_sum = 0;
 
   /* Insert the IP Address of this node */
   /* Insert the name of this cluster for cluster-identification of mc packets */
   /* Insert the Traffic Server verison */
-  snprintf(message, max, "ip: %s\ncluster: %s\ntsver: %s\n", ip, lmgmt->proxy_name, appVersionInfo.VersionStr);
+  snprintf(message, max, "ip: %s\ncluster: %s\ntsver: %s\n", ip, lmgmt->proxy_name, version.VersionStr);
   running_sum = strlen(message);
   ink_release_assert(running_sum < max);
 
@@ -1558,7 +1565,7 @@ ClusterCom::constructSharedFilePacket(char *message, int max)
 
   /* Insert the standard packet header */
   resolved_addr.s_addr = our_ip;
-  running_sum = constructSharedPacketHeader(message, inet_ntoa(resolved_addr), max);
+  running_sum = constructSharedPacketHeader(appVersionInfo, message, inet_ntoa(resolved_addr), max);
 
   ink_strlcpy(&message[running_sum], "type: files\n", (max - running_sum));
   running_sum += strlen("type: files\n");

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/cluster/ClusterCom.h
----------------------------------------------------------------------
diff --git a/mgmt/cluster/ClusterCom.h b/mgmt/cluster/ClusterCom.h
index 4dda298..fa10c87 100644
--- a/mgmt/cluster/ClusterCom.h
+++ b/mgmt/cluster/ClusterCom.h
@@ -44,8 +44,11 @@
 
 #include "ink_platform.h"
 #include "P_RecDefs.h"
+#include "I_Version.h"
 #include "Rollback.h"
 
+class FileManager;
+
 #define CLUSTER_MSG_SHUTDOWN_MANAGER  1000
 #define CLUSTER_MSG_SHUTDOWN_PROCESS  1001
 #define CLUSTER_MSG_RESTART_PROCESS   1002
@@ -86,10 +89,6 @@ typedef struct _cluster_peer_info
 
 } ClusterPeerInfo;
 
-void *drainIncomingChannel(void *arg);
-bool checkBackDoor(int req_fd, char *message);
-
-
 class ClusterCom
 {
 public:
@@ -115,7 +114,8 @@ public:
   void constructSharedGenericPacket(char *message, int max, RecT packet_type);
   void constructSharedStatPacket(char *message, int max);
   void constructSharedFilePacket(char *message, int max);
-  static int constructSharedPacketHeader(char *message, char *ip, int max);
+
+  static int constructSharedPacketHeader(const AppVersionInfo& version, char *message, char *ip, int max);
 
   bool sendClusterMessage(int msg_type, const char *args = NULL);
   bool sendOutgoingMessage(char *buf, int len);
@@ -147,6 +147,7 @@ public:
   unsigned long our_ip;
   char our_host[1024];
 
+  AppVersionInfo appVersionInfo;
   char sys_name[MAX_NODE_SYSINFO_STRING];
   char sys_release[MAX_NODE_SYSINFO_STRING];
 
@@ -167,6 +168,7 @@ public:
 
   char cluster_conf[1024];
   Rollback *cluster_file_rb;
+  FileManager *configFiles;
 
   int cluster_port;
   int reliable_server_port;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/cluster/VMap.cc
----------------------------------------------------------------------
diff --git a/mgmt/cluster/VMap.cc b/mgmt/cluster/VMap.cc
index 0a56286..2261f88 100644
--- a/mgmt/cluster/VMap.cc
+++ b/mgmt/cluster/VMap.cc
@@ -30,7 +30,6 @@
  */
 #include "ink_platform.h"
 
-#include "Main.h"
 #include "LocalManager.h"
 #include "VMap.h"
 #include "MgmtUtils.h"
@@ -776,7 +775,7 @@ VMap::lt_constructVMapMessage(char *ip, char *message, int max)
     return;
   }
   // Insert the standard mcast packet header
-  n = ClusterCom::constructSharedPacketHeader(message, ip, max);
+  n = ClusterCom::constructSharedPacketHeader(appVersionInfo, message, ip, max);
 
   if (!((n + (int) strlen("type: vmap\n")) < max)) {
     if (max >= 1) {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/cluster/VMap.h
----------------------------------------------------------------------
diff --git a/mgmt/cluster/VMap.h b/mgmt/cluster/VMap.h
index 1860720..099e2ca 100644
--- a/mgmt/cluster/VMap.h
+++ b/mgmt/cluster/VMap.h
@@ -91,6 +91,8 @@ public:
   char vip_conf[PATH_NAME_MAX];
   char absolute_vipconf_binary[PATH_NAME_MAX];
 
+  AppVersionInfo appVersionInfo;
+
   int enabled;
   bool turning_off;             /* are we turning off VIP but haven't down'd the addr? */
   /* map_init has never been used, remove it to avoid coverity complain */

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/stats/StatProcessor.cc
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatProcessor.cc b/mgmt/stats/StatProcessor.cc
index 000209e..24cbaa9 100644
--- a/mgmt/stats/StatProcessor.cc
+++ b/mgmt/stats/StatProcessor.cc
@@ -32,6 +32,7 @@
 
 #include "ink_config.h"
 #include "StatProcessor.h"
+#include "FileManager.h"
 
 #define STAT_CONFIG_FILE "stats.config.xml"
 
@@ -179,14 +180,14 @@ charDataHandler(void * /* userData ATS_UNUSED */, const xmlchar * name, int /* l
 }
 
 
-StatProcessor::StatProcessor():m_lmgmt(NULL), m_overviewGenerator(NULL)
+StatProcessor::StatProcessor(FileManager * configFiles):m_lmgmt(NULL), m_overviewGenerator(NULL)
 {
-  rereadConfig();
+  rereadConfig(configFiles);
 }
 
 
 void
-StatProcessor::rereadConfig()
+StatProcessor::rereadConfig(FileManager * configFiles)
 {
   textBuffer *fileContent = NULL;
   Rollback *fileRB = NULL;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/stats/StatProcessor.h
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatProcessor.h b/mgmt/stats/StatProcessor.h
index 5a3f37d..71dab2f 100644
--- a/mgmt/stats/StatProcessor.h
+++ b/mgmt/stats/StatProcessor.h
@@ -65,12 +65,12 @@ class StatProcessor
 {
 public:
 
-  StatProcessor();
+  explicit StatProcessor(FileManager * configFiles);
   ~StatProcessor();
 
   // Member Fuctions
   unsigned short processStat();
-  void rereadConfig();
+  void rereadConfig(FileManager * configFiles);
 
   LocalManager *m_lmgmt;
   overviewPage *m_overviewGenerator;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/utils/WebMgmtUtils.cc
----------------------------------------------------------------------
diff --git a/mgmt/utils/WebMgmtUtils.cc b/mgmt/utils/WebMgmtUtils.cc
index ed82b09..df7f6e6 100644
--- a/mgmt/utils/WebMgmtUtils.cc
+++ b/mgmt/utils/WebMgmtUtils.cc
@@ -25,6 +25,7 @@
 #include "LocalManager.h"
 #include "MgmtUtils.h"
 #include "WebMgmtUtils.h"
+#include "MultiFile.h"
 
 #ifdef HAVE_PCRE_PCRE_H
 #include <pcre/pcre.h>

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/web2/WebHttpMessage.cc
----------------------------------------------------------------------
diff --git a/mgmt/web2/WebHttpMessage.cc b/mgmt/web2/WebHttpMessage.cc
index 9a7336b..57664bd 100644
--- a/mgmt/web2/WebHttpMessage.cc
+++ b/mgmt/web2/WebHttpMessage.cc
@@ -31,7 +31,6 @@
 #include "TextBuffer.h"
 #include "MIME.h"
 #include "I_Version.h"
-#include "Main.h"
 
 /****************************************************************************
  *
@@ -460,7 +459,7 @@ httpResponse::writeHdr(SocketInfo socketD)
   // Record Server Name
   hdr.copyFrom(serverStr, strlen(serverStr));
   hdr.copyFrom(managerStr, strlen(managerStr));
-  hdr.copyFrom(appVersionInfo.VersionStr, strlen(appVersionInfo.VersionStr));
+  // XXX hdr.copyFrom(appVersionInfo.VersionStr, strlen(appVersionInfo.VersionStr));
   hdr.copyFrom("\r\n", 2);
 
   // Record refresh


[3/9] git commit: TS-2977: rename traffic_manager Main.cc

Posted by jp...@apache.org.
TS-2977: rename traffic_manager Main.cc

Rename traffic_manager's Main.cc to traffic_manager.cc. Remove
Main.h, retaining just the 2 or 3 things from it that are used.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ab8c0cd2
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ab8c0cd2
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ab8c0cd2

Branch: refs/heads/master
Commit: ab8c0cd21a0ab6e832e969f006ace578661c4d47
Parents: ff716f2
Author: James Peach <jp...@apache.org>
Authored: Thu Jul 31 14:20:39 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Aug 1 19:55:45 2014 -0700

----------------------------------------------------------------------
 cmd/traffic_manager/AddConfigFilesHere.cc |    4 +-
 cmd/traffic_manager/Main.cc               | 1198 -----------------------
 cmd/traffic_manager/Main.h                |   53 --
 cmd/traffic_manager/Makefile.am           |    3 +-
 cmd/traffic_manager/StatType.h            |    1 -
 cmd/traffic_manager/traffic_manager.cc    | 1202 ++++++++++++++++++++++++
 6 files changed, 1206 insertions(+), 1255 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/AddConfigFilesHere.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/AddConfigFilesHere.cc b/cmd/traffic_manager/AddConfigFilesHere.cc
index cc6d169..bfed735 100644
--- a/cmd/traffic_manager/AddConfigFilesHere.cc
+++ b/cmd/traffic_manager/AddConfigFilesHere.cc
@@ -22,10 +22,12 @@
  */
 
 #include "ink_platform.h"
-#include "Main.h"
 #include "MgmtUtils.h"
 #include "ConfigParse.h"
 #include "Diags.h"
+#include "FileManager.h"
+
+extern FileManager *configFiles;
 
 /****************************************************************************
  *

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/Main.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Main.cc b/cmd/traffic_manager/Main.cc
deleted file mode 100644
index 8d80a24..0000000
--- a/cmd/traffic_manager/Main.cc
+++ /dev/null
@@ -1,1198 +0,0 @@
-/** @file
-
-  Entry point to the traffic manager.
-
-  @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.
- */
-
-#include "libts.h"
-#include "ink_sys_control.h"
-
-#include "Main.h"
-#include "MgmtUtils.h"
-#include "WebMgmtUtils.h"
-#include "WebIntrMain.h"
-#include "WebOverview.h"
-#include "ClusterCom.h"
-#include "VMap.h"
-#include "FileManager.h"
-#include "I_Layout.h"
-#include "I_Version.h"
-#include "Diags.h"
-#include "DiagsConfig.h"
-#include "URL.h"
-#include "MIME.h"
-#include "HTTP.h"
-
-// Needs LibRecordsConfigInit()
-#include "RecordsConfig.h"
-
-#include "StatProcessor.h"
-#include "P_RecLocal.h"
-#include "P_RecCore.h"
-
-#if TS_USE_POSIX_CAP
-#include <sys/capability.h>
-#endif
-#include <grp.h>
-
-#define FD_THROTTLE_HEADROOM (128 + 64) // TODO: consolidate with THROTTLE_FD_HEADROOM
-#define DIAGS_LOG_FILENAME "manager.log"
-
-#if defined(freebsd)
-extern "C" int getpwnam_r(const char *name, struct passwd *result, char *buffer, size_t buflen, struct passwd **resptr);
-#endif
-
-static void extractConfigInfo(char *mgmt_path, const char *recs_conf, char *userName, int *fds_throttle);
-
-LocalManager *lmgmt = NULL;
-FileManager *configFiles;
-
-StatProcessor *statProcessor;   // Statistics Processors
-AppVersionInfo appVersionInfo;  // Build info for this application
-
-static inkcoreapi DiagsConfig *diagsConfig;
-static char debug_tags[1024] = "";
-static char action_tags[1024] = "";
-static bool proxy_on = true;
-
-char mgmt_path[PATH_NAME_MAX + 1];
-
-// By default, set the current directory as base
-static const char *recs_conf = "records.config";
-
-static int fds_limit;
-
-// TODO: Use positive instead negative selection
-//       Thsis should just be #if defined(solaris)
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-static void SignalHandler(int sig, siginfo_t * t, void *f);
-static void SignalAlrmHandler(int sig, siginfo_t * t, void *f);
-#else
-static void SignalHandler(int sig);
-static void SignalAlrmHandler(int sig);
-#endif
-
-static volatile int sigHupNotifier = 0;
-static volatile int sigUsr2Notifier = 0;
-static void SigChldHandler(int sig);
-
-static void
-check_lockfile()
-{
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  char lockfile[PATH_NAME_MAX];
-  int err;
-  pid_t holding_pid;
-
-  //////////////////////////////////////
-  // test for presence of server lock //
-  //////////////////////////////////////
-  Layout::relative_to(lockfile, sizeof(lockfile), rundir, SERVER_LOCK);
-  Lockfile server_lockfile(lockfile);
-  err = server_lockfile.Open(&holding_pid);
-  if (err == 1) {
-    server_lockfile.Close();    // no server running
-  } else {
-    char *reason = strerror(-err);
-    if (err == 0) {
-      // TODO: Add PID_FMT_T instead duplicating code just for printing
-#if defined(solaris)
-      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, (int)holding_pid);
-#else
-      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, holding_pid);
-#endif
-      mgmt_elog(stderr, 0, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, holding_pid);
-    } else {
-      fprintf(stderr, "FATAL: Can't open server lockfile '%s' (%s)\n", lockfile, (reason ? reason : "Unknown Reason"));
-      mgmt_elog(stderr, 0, "FATAL: Can't open server lockfile '%s' (%s)\n",
-                lockfile, (reason ? reason : "Unknown Reason"));
-    }
-    exit(1);
-  }
-
-  ///////////////////////////////////////////
-  // try to get the exclusive manager lock //
-  ///////////////////////////////////////////
-  Layout::relative_to(lockfile, sizeof(lockfile), rundir, MANAGER_LOCK);
-  Lockfile manager_lockfile(lockfile);
-  err = manager_lockfile.Get(&holding_pid);
-  if (err != 1) {
-    char *reason = strerror(-err);
-    fprintf(stderr, "FATAL: Can't acquire manager lockfile '%s'", lockfile);
-    mgmt_elog(stderr, 0, "FATAL: Can't acquire manager lockfile '%s'", lockfile);
-    if (err == 0) {
-#if defined(solaris)
-      fprintf(stderr, " (Lock file held by process ID %d)\n", (int)holding_pid);
-#else
-      fprintf(stderr, " (Lock file held by process ID %d)\n", holding_pid);
-#endif
-      mgmt_elog(stderr, 0, " (Lock file held by process ID %d)\n", holding_pid);
-    } else if (reason) {
-      fprintf(stderr, " (%s)\n", reason);
-      mgmt_elog(stderr, 0, " (%s)\n", reason);
-    } else {
-      fprintf(stderr, "\n");
-    }
-    exit(1);
-
-    fprintf(stderr, "unable to acquire manager lock [%d]\n", -err);
-    exit(1);
-  }
-}
-
-static void
-initSignalHandlers()
-{
-  struct sigaction sigHandler, sigChldHandler, sigAlrmHandler;
-  sigset_t sigsToBlock;
-
-  // Set up the signal handler
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigHandler.sa_handler = NULL;
-  sigHandler.sa_sigaction = SignalHandler;
-#else
-  sigHandler.sa_handler = SignalHandler;
-#endif
-  sigemptyset(&sigHandler.sa_mask);
-
-  // We want the handler to remain in place on
-  //  SIGHUP to avoid any races with the signals
-  //  coming too quickly.  Also restart systems calls
-  //  after the signal since not all calls are wrapped
-  //  to check errno for EINTR
-  sigHandler.sa_flags = SA_RESTART;
-  sigaction(SIGHUP, &sigHandler, NULL);
-  sigaction(SIGUSR2, &sigHandler, NULL);
-
-  // Don't block the signal on entry to the signal
-  //   handler so we can reissue it and get a core
-  //   file in the appropriate circumstances
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigHandler.sa_flags = SA_RESETHAND | SA_SIGINFO;
-#else
-  sigHandler.sa_flags = SA_RESETHAND;
-#endif
-  sigaction(SIGINT, &sigHandler, NULL);
-  sigaction(SIGQUIT, &sigHandler, NULL);
-  sigaction(SIGILL, &sigHandler, NULL);
-  sigaction(SIGBUS, &sigHandler, NULL);
-  sigaction(SIGSEGV, &sigHandler, NULL);
-  sigaction(SIGTERM, &sigHandler, NULL);
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigAlrmHandler.sa_handler = NULL;
-  sigAlrmHandler.sa_sigaction = SignalAlrmHandler;
-#else
-  sigAlrmHandler.sa_handler = SignalAlrmHandler;
-#endif
-
-  sigemptyset(&sigAlrmHandler.sa_mask);
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  sigAlrmHandler.sa_flags = SA_SIGINFO;
-#else
-  sigAlrmHandler.sa_flags = 0;
-#endif
-  sigaction(SIGALRM, &sigAlrmHandler, NULL);
-
-  // Block the delivery of any signals we are not catching
-  //
-  //  except for SIGALARM since we use it
-  //    to break out of deadlock on semaphore
-  //    we share with the proxy
-  //
-  sigfillset(&sigsToBlock);
-  sigdelset(&sigsToBlock, SIGHUP);
-  sigdelset(&sigsToBlock, SIGUSR2);
-  sigdelset(&sigsToBlock, SIGINT);
-  sigdelset(&sigsToBlock, SIGQUIT);
-  sigdelset(&sigsToBlock, SIGILL);
-  sigdelset(&sigsToBlock, SIGABRT);
-  sigdelset(&sigsToBlock, SIGBUS);
-  sigdelset(&sigsToBlock, SIGSEGV);
-  sigdelset(&sigsToBlock, SIGTERM);
-  sigdelset(&sigsToBlock, SIGALRM);
-  ink_thread_sigsetmask(SIG_SETMASK, &sigsToBlock, NULL);
-
-  // Set up the SIGCHLD handler so we do not get into
-  //   a problem with Solaris 2.6 and strange waitpid()
-  //   behavior
-  sigChldHandler.sa_handler = SigChldHandler;
-  sigChldHandler.sa_flags = SA_RESTART;
-  sigemptyset(&sigChldHandler.sa_mask);
-  sigaction(SIGCHLD, &sigChldHandler, NULL);
-}
-
-#if defined(linux)
-#include <sys/prctl.h>
-#endif
-static int
-setup_coredump()
-{
-#if defined(linux)
-#ifndef PR_SET_DUMPABLE
-#define PR_SET_DUMPABLE 4       /* Ugly, but we cannot compile with 2.2.x otherwise.
-                                   Should be removed when we compile only on 2.4.x */
-#endif
-  prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
-#endif  // linux check
-  return 0;
-}
-
-static void
-init_dirs()
-{
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-
-  if (access(Layout::get()->sysconfdir, R_OK) == -1) {
-    mgmt_elog(0, "unable to access() config dir '%s': %d, %s\n", Layout::get()->sysconfdir, errno, strerror(errno));
-    mgmt_elog(0, "please set the 'TS_ROOT' environment variable\n");
-    _exit(1);
-  }
-
-  if (access(rundir, R_OK) == -1) {
-    mgmt_elog(0, "unable to access() local state dir '%s': %d, %s\n", (const char *)rundir, errno, strerror(errno));
-    mgmt_elog(0, "please set 'proxy.config.local_state_dir'\n");
-    _exit(1);
-  }
-}
-
-static void
-chdir_root()
-{
-  const char * prefix = Layout::get()->prefix;
-
-  if (chdir(prefix) < 0) {
-    mgmt_elog(0, "unable to change to root directory \"%s\" [%d '%s']\n", prefix, errno, strerror(errno));
-    mgmt_elog(0, " please set correct path in env variable TS_ROOT \n");
-    exit(1);
-  } else {
-    mgmt_log("[TrafficManager] using root directory '%s'\n", prefix);
-  }
-}
-
-static void
-set_process_limits(int fds_throttle)
-{
-  struct rlimit lim;
-
-  // Set needed rlimits (root)
-  ink_max_out_rlimit(RLIMIT_NOFILE, true, false);
-  ink_max_out_rlimit(RLIMIT_STACK, true, true);
-  ink_max_out_rlimit(RLIMIT_DATA, true, true);
-  ink_max_out_rlimit(RLIMIT_FSIZE, true, false);
-#ifdef RLIMIT_RSS
-  ink_max_out_rlimit(RLIMIT_RSS, true, true);
-#endif
-
-#if defined(linux)
-  float file_max_pct = 0.9;
-  FILE *fd;
-
-  if ((fd = fopen("/proc/sys/fs/file-max","r"))) {
-    ATS_UNUSED_RETURN(fscanf(fd, "%lu", &lim.rlim_max));
-    fclose(fd);
-    REC_ReadConfigFloat(file_max_pct, "proxy.config.system.file_max_pct");
-    lim.rlim_cur = lim.rlim_max = static_cast<rlim_t>(lim.rlim_max * file_max_pct);
-    if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
-      fds_limit = (int) lim.rlim_cur;
-      syslog(LOG_NOTICE, "NOTE: RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
-    } else {
-      syslog(LOG_NOTICE, "NOTE: Unable to set RLIMIT_NOFILE(%d):cur(%d),max(%d)", RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
-    }
-  } else {
-    syslog(LOG_NOTICE, "NOTE: Unable to open /proc/sys/fs/file-max");
-  }
-#endif // linux
-
-  if (!getrlimit(RLIMIT_NOFILE, &lim)) {
-    if (fds_throttle > (int) (lim.rlim_cur + FD_THROTTLE_HEADROOM)) {
-      lim.rlim_cur = (lim.rlim_max = (rlim_t) fds_throttle);
-      if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
-        fds_limit = (int) lim.rlim_cur;
-	syslog(LOG_NOTICE, "NOTE: RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
-      }
-    }
-  }
-
-}
-
-#if TS_HAS_WCCP
-static void
-Errata_Logger(ts::Errata const& err) {
-  size_t n;
-  static size_t const SIZE = 4096;
-  char buff[SIZE];
-  if (err.size()) {
-    ts::Errata::Code code = err.top().getCode();
-    n = err.write(buff, SIZE, 1, 0, 2, "> ");
-    // strip trailing newlines.
-    while (n && (buff[n-1] == '\n' || buff[n-1] == '\r'))
-      buff[--n] = 0;
-    // log it.
-    if (code > 1) mgmt_elog(0, "[WCCP]%s", buff);
-    else if (code > 0) mgmt_log("[WCCP]%s", buff);
-    else Debug("WCCP", "%s", buff);
-  }
-}
-
-static void
-Init_Errata_Logging() {
-  ts::Errata::registerSink(&Errata_Logger);
-}
-#endif
-
-int
-main(int argc, char **argv)
-{
-  // Before accessing file system initialize Layout engine
-  Layout::create();
-  ink_strlcpy(mgmt_path, Layout::get()->sysconfdir, sizeof(mgmt_path));
-
-  // change the directory to the "root" directory
-  chdir_root();
-
-  // Line buffer standard output & standard error
-  int status;
-  status = setvbuf(stdout, NULL, _IOLBF, 0);
-  if (status != 0)
-    perror("WARNING: can't line buffer stdout");
-  status = setvbuf(stderr, NULL, _IOLBF, 0);
-  if (status != 0)
-    perror("WARNING: can't line buffer stderr");
-
-  bool found = false;
-  int just_started = 0;
-  int cluster_mcport = -1, cluster_rsport = -1;
-  // TODO: This seems completely incomplete, disabled for now
-  //  int dump_config = 0, dump_process = 0, dump_node = 0, dump_cluster = 0, dump_local = 0;
-  char* proxy_port = 0;
-  int proxy_backdoor = -1;
-  char *envVar = NULL, *group_addr = NULL, *tsArgs = NULL;
-  bool log_to_syslog = true;
-  char userToRunAs[80];
-  int  fds_throttle = -1;
-  time_t ticker;
-  ink_thread webThrId;
-
-  // Set up the application version info
-  appVersionInfo.setup(PACKAGE_NAME,"traffic_manager", PACKAGE_VERSION,
-                       __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
-  initSignalHandlers();
-
-  // Process Environment Variables
-  if ((envVar = getenv("MGMT_ACONF_PORT")) != NULL) {
-    aconf_port_arg = atoi(envVar);
-  }
-
-  if ((envVar = getenv("MGMT_CLUSTER_MC_PORT")) != NULL) {
-    cluster_mcport = atoi(envVar);
-  }
-
-  if ((envVar = getenv("MGMT_CLUSTER_RS_PORT")) != NULL) {
-    cluster_rsport = atoi(envVar);
-  }
-
-  if ((envVar = getenv("MGMT_GROUP_ADDR")) != NULL) {
-    group_addr = envVar;
-  }
-
-  for (int i = 1; i < argc; i++) {      /* Process command line args */
-
-    if (argv[i][0] == '-') {
-      if ((strcmp(argv[i], "-version") == 0) || (strcmp(argv[i], "-V") == 0)) {
-        fprintf(stderr, "%s\n", appVersionInfo.FullVersionInfoStr);
-        exit(0);
-      } else if (strcmp(argv[i], "-proxyOff") == 0) {
-        proxy_on = false;
-      } else if (strcmp(argv[i], "-nosyslog") == 0) {
-        log_to_syslog = false;
-      } else {
-        // The rest of the options require an argument in the form of -<Flag> <val>
-        if ((i + 1) < argc) {
-
-          if (strcmp(argv[i], "-aconfPort") == 0) {
-            ++i;
-            aconf_port_arg = atoi(argv[i]);
-          } else if (strcmp(argv[i], "-clusterMCPort") == 0) {
-            ++i;
-            cluster_mcport = atoi(argv[i]);
-          } else if (strcmp(argv[i], "-groupAddr") == 0) {
-            ++i;
-            group_addr = argv[i];
-          } else if (strcmp(argv[i], "-clusterRSPort") == 0) {
-            ++i;
-            cluster_rsport = atoi(argv[i]);
-#if TS_USE_DIAGS
-          } else if (strcmp(argv[i], "-debug") == 0) {
-            ++i;
-            ink_strlcpy(debug_tags, argv[i], sizeof(debug_tags));
-          } else if (strcmp(argv[i], "-action") == 0) {
-            ++i;
-            ink_strlcpy(action_tags, argv[i], sizeof(debug_tags));
-#endif
-          } else if (strcmp(argv[i], "-path") == 0) {
-            ++i;
-            //bugfixed by YTS Team, yamsat(id-59703)
-            if ((strlen(argv[i]) > PATH_NAME_MAX)) {
-              fprintf(stderr, "\n   Path exceeded the maximum allowed characters.\n");
-              exit(1);
-            }
-
-            ink_strlcpy(mgmt_path, argv[i], sizeof(mgmt_path));
-            /*
-               } else if(strcmp(argv[i], "-lmConf") == 0) {
-               ++i;
-               lm_conf = argv[i];
-             */
-          } else if (strcmp(argv[i], "-recordsConf") == 0) {
-            ++i;
-            recs_conf = argv[i];
-            // TODO: This seems completely incomplete, disabled for now
-#if 0
-          } else if (strcmp(argv[i], "-printRecords") == 0) {
-            ++i;
-            while (i < argc && argv[i][0] != '-') {
-              if (strcasecmp(argv[i], "config") == 0) {
-                dump_config = 1;
-              } else if (strcasecmp(argv[i], "process") == 0) {
-                dump_process = 1;
-              } else if (strcasecmp(argv[i], "node") == 0) {
-                dump_node = 1;
-              } else if (strcasecmp(argv[i], "cluster") == 0) {
-                dump_cluster = 1;
-              } else if (strcasecmp(argv[i], "local") == 0) {
-                dump_local = 1;
-              } else if (strcasecmp(argv[i], "all") == 0) {
-                dump_config = dump_node = dump_process = dump_cluster = dump_local = 1;
-              }
-              ++i;
-            }
-            --i;
-#endif
-          } else if (strcmp(argv[i], "-tsArgs") == 0) {
-            int size_of_args = 0, j = (++i);
-            while (j < argc) {
-              size_of_args += 1;
-              size_of_args += strlen((argv[j++]));
-            }
-            tsArgs = (char *)ats_malloc(size_of_args + 1);
-
-            j = 0;
-            while (i < argc) {
-              snprintf(&tsArgs[j], ((size_of_args + 1) - j), " %s", argv[i]);
-              j += strlen(argv[i]) + 1;
-              ++i;
-            }
-          } else if (strcmp(argv[i], "-proxyPort") == 0) {
-            ++i;
-            proxy_port = argv[i];
-          } else if (strcmp(argv[i], "-proxyBackDoor") == 0) {
-            ++i;
-            proxy_backdoor = atoi(argv[i]);
-          } else {
-            printUsage();
-          }
-        } else {
-          printUsage();
-        }
-      }
-    }
-  }
-
-  // Bootstrap with LOG_DAEMON until we've read our configuration
-  if (log_to_syslog) {
-    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, LOG_DAEMON);
-    mgmt_use_syslog();
-    syslog(LOG_NOTICE, "NOTE: --- Manager Starting ---");
-    syslog(LOG_NOTICE, "NOTE: Manager Version: %s", appVersionInfo.FullVersionInfoStr);
-  }
-
-  // Bootstrap the Diags facility so that we can use it while starting
-  //  up the manager
-  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, false);
-  diags = diagsConfig->diags;
-  diags->prefix_str = "Manager ";
-
-  RecLocalInit();
-  LibRecordsConfigInit();
-  RecordsConfigOverrideFromEnvironment();
-
-  init_dirs();// setup critical directories, needs LibRecords
-
-  // Get the config info we need while we are still root
-  extractConfigInfo(mgmt_path, recs_conf, userToRunAs, &fds_throttle);
-
-  set_process_limits(fds_throttle); // as root
-  runAsUser(userToRunAs);
-  setup_coredump();
-  check_lockfile();
-
-  url_init();
-  mime_init();
-  http_init();
-
-#if TS_HAS_WCCP
-  Init_Errata_Logging();
-#endif
-  ts_host_res_global_init();
-  ts_session_protocol_well_known_name_indices_init();
-  lmgmt = new LocalManager(proxy_on);
-  RecLocalInitMessage();
-  lmgmt->initAlarm();
-
-  if (diags) {
-    delete diagsConfig;
-    // diagsConfig->reconfigure_diags(); INKqa11968
-    /*
-       delete diags;
-       diags = new Diags(debug_tags,action_tags);
-     */
-  }
-  // INKqa11968: need to set up callbacks and diags data structures
-  // using configuration in records.config
-  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, true);
-  diags = diagsConfig->diags;
-  RecSetDiags(diags);
-  diags->prefix_str = "Manager ";
-
-  if (is_debug_tag_set("diags"))
-    diags->dump();
-  diags->cleanup_func = mgmt_cleanup;
-
-  // Setup the exported manager version records.
-  RecSetRecordString("proxy.node.version.manager.short", appVersionInfo.VersionStr);
-  RecSetRecordString("proxy.node.version.manager.long", appVersionInfo.FullVersionInfoStr);
-  RecSetRecordString("proxy.node.version.manager.build_number", appVersionInfo.BldNumStr);
-  RecSetRecordString("proxy.node.version.manager.build_time", appVersionInfo.BldTimeStr);
-  RecSetRecordString("proxy.node.version.manager.build_date", appVersionInfo.BldDateStr);
-  RecSetRecordString("proxy.node.version.manager.build_machine", appVersionInfo.BldMachineStr);
-  RecSetRecordString("proxy.node.version.manager.build_person", appVersionInfo.BldPersonStr);
-//    RecSetRecordString("proxy.node.version.manager.build_compile_flags",
-//                       appVersionInfo.BldCompileFlagsStr);
-
-  if (log_to_syslog) {
-    char sys_var[] = "proxy.config.syslog_facility";
-    char *facility_str = NULL;
-    int facility_int;
-    facility_str = REC_readString(sys_var, &found);
-    ink_assert(found);
-
-    if (!found) {
-      mgmt_elog(0, "Could not read %s.  Defaulting to DAEMON\n", sys_var);
-      facility_int = LOG_DAEMON;
-    } else {
-      facility_int = facility_string_to_int(facility_str);
-      ats_free(facility_str);
-      if (facility_int < 0) {
-        mgmt_elog(0, "Bad syslog facility specified.  Defaulting to DAEMON\n");
-        facility_int = LOG_DAEMON;
-      }
-    }
-
-    // NOTE: do NOT call closelog() here.  Solaris gets confused
-    //   and some how it hoses later calls to readdir_r.
-    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, facility_int);
-
-    lmgmt->syslog_facility = facility_int;
-  } else {
-    lmgmt->syslog_facility = -1;
-  }
-
-  // Find out our hostname so we can use it as part of the initialization
-  setHostnameVar();
-
-  // Create the data structure for overview page
-  //   Do this before the rest of the set up since it needs
-  //   to created to handle any alarms thrown by later
-  //   initialization
-  overviewGenerator = new overviewPage();
-
-  // Initialize the Config Object bindings before
-  //   starting any other threads
-  lmgmt->configFiles = configFiles = new FileManager();
-  initializeRegistry();
-  configFiles->registerCallback(fileUpdated);
-
-  // RecLocal's 'sync_thr' depends on 'configFiles', so we can't
-  // stat the 'sync_thr' until 'configFiles' has been initialized.
-  RecLocalStart(configFiles);
-
-  /* Update cmd line overrides/environmental overrides/etc */
-  if (tsArgs) {                 /* Passed command line args for proxy */
-    ats_free(lmgmt->proxy_options);
-    lmgmt->proxy_options = tsArgs;
-    mgmt_log(stderr, "[main] Traffic Server Args: '%s'\n", lmgmt->proxy_options);
-  }
-  if (proxy_port) {
-    HttpProxyPort::loadValue(lmgmt->m_proxy_ports, proxy_port);
-  }
-
-  if (proxy_backdoor != -1) {
-    RecSetRecordInt("proxy.config.process_manager.mgmt_port", proxy_backdoor);
-  }
-
-  if (cluster_rsport == -1) {
-    cluster_rsport = REC_readInteger("proxy.config.cluster.rsport", &found);
-    ink_assert(found);
-  }
-
-  if (cluster_mcport == -1) {
-    cluster_mcport = REC_readInteger("proxy.config.cluster.mcport", &found);
-    ink_assert(found);
-  }
-
-  if (!group_addr) {
-    group_addr = REC_readString("proxy.config.cluster.mc_group_addr", &found);
-    ink_assert(found);
-  }
-
-  in_addr_t min_ip = inet_network("224.0.0.255");
-  in_addr_t max_ip = inet_network("239.255.255.255");
-  in_addr_t group_addr_ip = inet_network(group_addr);
-
-  if (!(min_ip < group_addr_ip && group_addr_ip < max_ip)) {
-    mgmt_fatal(0, "[TrafficManager] Multi-Cast group addr '%s' is not in the permitted range of %s\n",
-               group_addr, "224.0.1.0 - 239.255.255.255");
-  }
-
-  /* TODO: Do we really need to init cluster communication? */
-  lmgmt->initCCom(appVersionInfo, configFiles, cluster_mcport, group_addr, cluster_rsport);       /* Setup cluster communication */
-
-  lmgmt->initMgmtProcessServer();       /* Setup p-to-p process server */
-
-  // Now that we know our cluster ip address, add the
-  //   UI record for this machine
-  overviewGenerator->addSelfRecord();
-
-  lmgmt->listenForProxy();
-
-  //
-  // As listenForProxy() may change/restore euid, we should put
-  // the creation of webIntr_main thread after it. So that we
-  // can keep a consistent euid when create mgmtapi/eventapi unix
-  // sockets in webIntr_main thread.
-  //
-  webThrId = ink_thread_create(webIntr_main, NULL);     /* Spin web agent thread */
-  Debug("lm", "Created Web Agent thread (%"  PRId64 ")", (int64_t)webThrId);
-
-  ticker = time(NULL);
-  mgmt_log("[TrafficManager] Setup complete\n");
-
-  statProcessor = new StatProcessor(configFiles);
-
-  for (;;) {
-    lmgmt->processEventQueue();
-    lmgmt->pollMgmtProcessServer();
-
-    // Check for a SIGHUP
-    if (sigHupNotifier != 0) {
-      mgmt_log(stderr, "[main] Reading Configuration Files due to SIGHUP\n");
-      configFiles->rereadConfig();
-      lmgmt->signalEvent(MGMT_EVENT_PLUGIN_CONFIG_UPDATE, "*");
-      sigHupNotifier = 0;
-      mgmt_log(stderr, "[main] Reading Configuration Files Reread\n");
-    }
-    // Check for SIGUSR2
-    if (sigUsr2Notifier != 0) {
-      ink_stack_trace_dump();
-      sigUsr2Notifier = 0;
-    }
-
-    lmgmt->ccom->generateClusterDelta();
-
-    if (lmgmt->run_proxy && lmgmt->processRunning()) {
-      lmgmt->ccom->sendSharedData();
-      lmgmt->virt_map->lt_runGambit();
-    } else {
-      if (!lmgmt->run_proxy) {  /* Down if we are not going to start another immed. */
-        /* Proxy is not up, so no addrs should be */
-        lmgmt->virt_map->downOurAddrs();
-      }
-
-      /* Proxy is not up, but we should still exchange config and alarm info */
-      lmgmt->ccom->sendSharedData(false);
-    }
-
-    lmgmt->ccom->checkPeers(&ticker);
-    overviewGenerator->checkForUpdates();
-
-    if (statProcessor) {
-      statProcessor->processStat();
-    }
-
-    if (lmgmt->mgmt_shutdown_outstanding == true) {
-      lmgmt->mgmtShutdown(true);
-      _exit(0);
-    }
-
-    if (lmgmt->run_proxy && !lmgmt->processRunning()) { /* Make sure we still have a proxy up */
-      if (lmgmt->startProxy())
-        just_started = 0;
-      else
-        just_started++;
-    } else {                    /* Give the proxy a chance to fire up */
-      just_started++;
-    }
-
-    /* This will catch the case were the proxy dies before it can connect to manager */
-    if (lmgmt->proxy_launch_outstanding && !lmgmt->processRunning() && just_started >= 120) {
-      just_started = 0;
-      lmgmt->proxy_launch_outstanding = false;
-      if (lmgmt->proxy_launch_pid != -1) {
-        int res;
-        kill(lmgmt->proxy_launch_pid, 9);
-        waitpid(lmgmt->proxy_launch_pid, &res, 0);
-        if (WIFSIGNALED(res)) {
-          int sig = WTERMSIG(res);
-#ifdef NEED_PSIGNAL
-          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d\n", sig);
-#else
-          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d: %s\n", sig, strsignal(sig));
-#endif /* NEED_PSIGNAL */
-        }
-      }
-      mgmt_log(stderr, "[main] Proxy launch failed, retrying...\n");
-    }
-
-  }
-
-  if (statProcessor) {
-    delete(statProcessor);
-  }
-
-#ifndef MGMT_SERVICE
-  return 0;
-#endif
-
-}                               /* End main */
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-static void
-SignalAlrmHandler(int /* sig ATS_UNUSED */, siginfo_t * t, void * /* c ATS_UNUSED */)
-#else
-static void
-SignalAlrmHandler(int /* sig ATS_UNUSED */)
-#endif
-{
-  /*
-     fprintf(stderr, "[TrafficManager] ==> SIGALRM received\n");
-     mgmt_elog(stderr, 0, "[TrafficManager] ==> SIGALRM received\n");
-   */
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  if (t) {
-    if (t->si_code <= 0) {
-#if defined(solaris)
-      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", (int)t->si_pid, t->si_uid);
-#else
-      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", t->si_pid, t->si_uid);
-#endif
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", t->si_pid, t->si_uid);
-    } else {
-      fprintf(stderr, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", t->si_code);
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", t->si_code);
-    }
-  }
-#endif
-
-  return;
-}
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-static void
-SignalHandler(int sig, siginfo_t * t, void *c)
-#else
-static void
-SignalHandler(int sig)
-#endif
-{
-  static int clean = 0;
-  int status;
-
-#if !defined(linux) && !defined(freebsd) && !defined(darwin)
-  if (t) {
-    if (t->si_code <= 0) {
-#if defined(solaris)
-      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, (int)t->si_pid, t->si_uid);
-#else
-      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, t->si_pid, t->si_uid);
-#endif
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, t->si_pid, t->si_uid);
-    } else {
-      fprintf(stderr, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", sig, t->si_code);
-      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", sig, t->si_code);
-    }
-  }
-#endif
-
-  if (sig == SIGHUP) {
-    sigHupNotifier = 1;
-    return;
-  }
-
-  if (sig == SIGUSR2) {
-    sigUsr2Notifier = 1;
-    return;
-  }
-  fprintf(stderr, "[TrafficManager] ==> Cleaning up and reissuing signal #%d\n", sig);
-  mgmt_elog(stderr, 0, "[TrafficManager] ==> Cleaning up and reissuing signal #%d\n", sig);
-
-  if (lmgmt && !clean) {
-    clean = 1;
-    if (lmgmt->watched_process_pid != -1) {
-
-      if (sig == SIGTERM || sig == SIGINT) {
-        kill(lmgmt->watched_process_pid, sig);
-        waitpid(lmgmt->watched_process_pid, &status, 0);
-      }
-    }
-    lmgmt->mgmtCleanup();
-  }
-
-  switch (sig) {
-  case SIGQUIT:
-  case SIGILL:
-  case SIGTRAP:
-#if !defined(linux)
-  case SIGEMT:
-  case SIGSYS:
-#endif
-  case SIGFPE:
-  case SIGBUS:
-  case SIGSEGV:
-  case SIGXCPU:
-  case SIGXFSZ:
-    abort();
-  default:
-    fprintf(stderr, "[TrafficManager] ==> signal #%d\n", sig);
-    mgmt_elog(stderr, 0, "[TrafficManager] ==> signal #%d\n", sig);
-    _exit(sig);
-  }
-  fprintf(stderr, "[TrafficManager] ==> signal2 #%d\n", sig);
-  mgmt_elog(stderr, 0, "[TrafficManager] ==> signal2 #%d\n", sig);
-  _exit(sig);
-}                               /* End SignalHandler */
-
-// void SigChldHandler(int sig)
-//
-//   An empty handler needed so that we catch SIGCHLD
-//    With Solaris 2.6, ignoring sig child changes the behavior
-//    of waitpid() so that if there are no unwaited children,
-//    waitpid() blocks until all child are transformed into
-//    zombies which is bad for us
-//
-static void
-SigChldHandler(int /* sig ATS_UNUSED */)
-{
-}
-
-void
-printUsage()
-{
-  fprintf(stderr, "----------------------------------------------------------------------------\n");
-  fprintf(stderr, " Traffic Manager Usage: (all args are optional)\n");
-  fprintf(stderr, "\n");
-  fprintf(stderr, "   traffic_manager [options]\n");
-  fprintf(stderr, "     -proxyPort     <port>  Port to have proxy listen on, overrides records.config.\n");
-  /* Function is currently #ifdef'ed out so no reason to advertise
-     fprintf(stderr,
-     "     -proxyBackdoor <port>  Port to put proxy mgmt port on.\n");
-   */
-  /* Commented out because this option is used for debugging only.
-     fprintf(stderr,
-     "     -noProxy               Do not launch the proxy process.\n");
-   */
-  fprintf(stderr, "     -tsArgs        [...]   Args to proxy, everything till eol is passed.\n");
-  fprintf(stderr, "     -webPort       <port>  Port for web interface.\n");
-  /*
-     fprintf(stderr,
-     "     -graphPort     <port>  Port for dynamic graphs.\n");
-   */
-  fprintf(stderr, "     -clusterPort   <port>  Cluster Multicast port\n");
-  fprintf(stderr, "     -groupAddr     <addr>  Cluster Multicast group, example: \"225.0.0.37\".\n");
-  fprintf(stderr, "     -clusterRSPort <port>  Cluster Multicast port.\n");
-  fprintf(stderr, "     -path          <path>  Root path for config files.\n");
-  /*
-     fprintf(stderr,
-     "     -lmConf        <fname> Local Management config file.\n");
-   */
-  fprintf(stderr, "     -recordsConf   <fname> General config file.\n");
-  // TODO: This seems completely incomplete, disabled for now
-  // fprintf(stderr, "     -printRecords  [...]   Print flags, default all are off.\n");
-  fprintf(stderr, "     -debug         <tags>  Enable the given debug tags\n");
-  fprintf(stderr, "     -action        <tags>  Enable the given action tags.\n");
-  fprintf(stderr, "     -version or -V         Print version id and exit.\n");
-  fprintf(stderr, "\n");
-  fprintf(stderr, "   [...] can be one+ of: [config process node cluster local all]\n");
-  fprintf(stderr, "----------------------------------------------------------------------------\n");
-  exit(0);
-}                               /* End printUsage */
-
-void
-fileUpdated(char *fname, bool incVersion)
-{
-  if (strcmp(fname, "cluster.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cluster.cluster_configuration");
-
-  } else if (strcmp(fname, "remap.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.url_remap.filename");
-
-  } else if (strcmp(fname, "socks.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.socks.socks_config_file");
-
-  } else if (strcmp(fname, "records.config") == 0) {
-    lmgmt->signalFileChange("records.config", incVersion);
-
-  } else if (strcmp(fname, "cache.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cache.control.filename");
-
-  } else if (strcmp(fname, "parent.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.http.parent_proxy.file");
-
-  } else if (strcmp(fname, "ip_allow.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cache.ip_allow.filename");
-  } else if (strcmp(fname, "vaddrs.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] vaddrs.config updated\n");
-    lmgmt->virt_map->lt_readAListFile(fname);
-
-  } else if (strcmp(fname, "storage.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] storage.config changed, need restart auto-rebuild mode\n");
-
-  } else if (strcmp(fname, "proxy.pac") == 0) {
-    mgmt_log(stderr, "[fileUpdated] proxy.pac file has been modified\n");
-
-  } else if (strcmp(fname, "icp.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.icp.icp_configuration");
-
-  } else if (strcmp(fname, "update.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.update.update_configuration");
-
-  } else if (strcmp(fname, "volume.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] volume.config changed, need restart\n");
-
-  } else if (strcmp(fname, "hosting.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.cache.hosting_filename");
-
-  } else if (strcmp(fname, "log_hosts.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.log.hosts_config_file");
-
-  } else if (strcmp(fname, "logs_xml.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.log.xml_config_file");
-
-  } else if (strcmp(fname, "splitdns.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.dns.splitdns.filename");
-
-  } else if (strcmp(fname, "plugin.config") == 0) {
-    mgmt_log(stderr, "[fileUpdated] plugin.config file has been modified\n");
-
-  } else if (strcmp(fname, "ssl_multicert.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.ssl.server.multicert.filename");
-
-  } else if (strcmp(fname, "proxy.config.body_factory.template_sets_dir") == 0) {
-    lmgmt->signalFileChange("proxy.config.body_factory.template_sets_dir");
-
-  } else if (strcmp(fname, "stats.config.xml") == 0) {
-    if (statProcessor) {
-      statProcessor->rereadConfig(configFiles);
-    }
-    mgmt_log(stderr, "[fileUpdated] stats.config.xml file has been modified\n");
-  } else if (strcmp(fname, "congestion.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.http.congestion_control.filename");
-  } else if (strcmp(fname, "prefetch.config") == 0) {
-    lmgmt->signalFileChange("proxy.config.prefetch.config_file");
-  } else {
-    mgmt_elog(stderr, 0, "[fileUpdated] Unknown config file updated '%s'\n", fname);
-
-  }
-  return;
-}                               /* End fileUpdate */
-
-#if TS_USE_POSIX_CAP
-/** Restore capabilities after user id change.
-    This manipulates LINUX capabilities so that this process
-    can perform certain privileged operations even if it is
-    no longer running as a privilege user.
-
-    @internal
-    I tried using
-    @code
-    prctl(PR_SET_KEEPCAPS, 1);
-    @endcode
-    but that had no effect even though the call reported success.
-    Only explicit capability manipulation was effective.
-
-    It does not appear to be necessary to set the capabilities on the
-    executable if originally run as root. That may be needed if
-    started as a user without that capability.
- */
-
-int
-restoreCapabilities() {
-  int zret = 0; // return value.
-  cap_t cap_set = cap_get_proc(); // current capabilities
-  // Make a list of the capabilities we want turned on.
-  cap_value_t cap_list[] = {
-    CAP_NET_ADMIN, ///< Set socket transparency.
-    CAP_NET_BIND_SERVICE, ///< Low port (e.g. 80) binding.
-    CAP_IPC_LOCK ///< Lock IPC objects.
-  };
-  static int const CAP_COUNT = sizeof(cap_list)/sizeof(*cap_list);
-
-  cap_set_flag(cap_set, CAP_EFFECTIVE, CAP_COUNT, cap_list, CAP_SET);
-  zret = cap_set_proc(cap_set);
-  cap_free(cap_set);
-  return zret;
-}
-#endif
-
-//  void runAsUser(...)
-//
-//  If we are root, switched to user to run as
-//    specified in records.config
-//
-//  If we are not root, do nothing
-//
-void
-runAsUser(char *userName)
-{
-  uid_t uid, euid;
-  struct passwd *result;
-  const int bufSize = 1024;
-  char buf[bufSize];
-
-  uid = getuid();
-  euid = geteuid();
-
-  if (uid == 0 || euid == 0) {
-
-    /* Figure out what user we should run as */
-
-    Debug("lm", "[runAsUser] Attempting to run as user '%s'\n", userName);
-
-    if (userName == NULL || userName[0] == '\0') {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: proxy.config.admin.user_id is not set\n");
-      _exit(1);
-    }
-
-    struct passwd passwdInfo;
-    struct passwd *ppasswd = NULL;
-    result = NULL;
-    int res;
-    if (*userName == '#') {
-      int uuid = atoi(userName + 1);
-      if (uuid == -1)
-        uuid = (int)uid;
-      res = getpwuid_r((uid_t)uuid, &passwdInfo, buf, bufSize, &ppasswd);
-    }
-    else {
-      res = getpwnam_r(&userName[0], &passwdInfo, buf, bufSize, &ppasswd);
-    }
-
-    if (!res && ppasswd) {
-      result = ppasswd;
-    }
-
-    if (result == NULL) {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to get info about user %s : %s\n", userName, strerror(errno));
-      _exit(1);
-    }
-
-    if (setegid(result->pw_gid) != 0 || seteuid(result->pw_uid) != 0) {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to switch to user %s : %s\n", userName, strerror(errno));
-      _exit(1);
-    }
-
-    uid = getuid();
-    euid = geteuid();
-
-    Debug("lm", "[runAsUser] Running with uid: '%d' euid: '%d'\n", uid, euid);
-
-    if (uid != result->pw_uid && euid != result->pw_uid) {
-      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Failed to switch to user %s\n", userName);
-      _exit(1);
-    }
-
-    // setup supplementary groups if it is not set.
-    if (0 == getgroups(0, NULL)) {
-      initgroups(&userName[0],result->pw_gid);
-    }
-
-#if TS_USE_POSIX_CAP
-    if (0 != restoreCapabilities()) {
-      mgmt_elog(stderr, 0, "[runAsUser] Error: Failed to restore capabilities after switch to user %s.\n", userName);
-    }
-#endif
-
-  }
-}                               /* End runAsUser() */
-
-//  void extractConfigInfo(...)
-//
-//  We need to get certain records.config values while we are
-//   root.  We can not use LMRecords to get them because the constructor
-//   for LMRecords creates the mgmt DBM and we do not want that to
-//   be owned as root.  This function extracts that info from
-//   records.config
-//
-//
-void
-extractConfigInfo(char *mgmt_path, const char *recs_conf, char *userName, int *fds_throttle)
-{
-  char file[1024];
-  bool useridFound = false;
-  bool throttleFound = false;
-
-  /* Figure out what user we should run as */
-  if (mgmt_path && recs_conf) {
-    FILE *fin;
-    snprintf(file, sizeof(file), "%s/%s.shadow", mgmt_path, recs_conf);
-    if (!(fin = fopen(file, "r"))) {
-      ink_filepath_make(file, sizeof(file), mgmt_path, recs_conf);
-      if (!(fin = fopen(file, "r"))) {
-        mgmt_elog(stderr, errno, "[extractConfigInfo] Unable to open config file(%s)\n", file);
-        _exit(1);
-      }
-    }
-    // Get 'user id' and 'network connections throttle limit'
-    while (((!useridFound) || (!throttleFound)) && fgets(file, 1024, fin)) {
-      if (strstr(file, "CONFIG proxy.config.admin.user_id STRING")) {
-        //coverity[secure_coding]
-        if ((sscanf(file, "CONFIG proxy.config.admin.user_id STRING %1023s\n", userName) == 1) &&
-            strcmp(userName, "NULL") != 0) {
-          useridFound = true;
-        }
-      } else if (strstr(file, "CONFIG proxy.config.net.connections_throttle INT")) {
-        if ((sscanf(file, "CONFIG proxy.config.net.connections_throttle INT %d\n", fds_throttle) == 1)) {
-          throttleFound = true;
-        }
-      }
-
-    }
-    fclose(fin);
-  } else {
-    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: unable to access records file\n");
-    _exit(1);
-  }
-
-  if (useridFound == false) {
-    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: proxy.config.admin.user_id is not set\n");
-    _exit(1);
-  }
-
-}                               /* End extractConfigInfo() */

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/Main.h
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Main.h b/cmd/traffic_manager/Main.h
deleted file mode 100644
index ec37226..0000000
--- a/cmd/traffic_manager/Main.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-#ifndef _MAIN_H_
-#define _MAIN_H_
-
-#include "FileManager.h"
-#include "I_Version.h"
-
-// TODO: consolidate location of these defaults
-#define DEFAULT_ROOT_DIRECTORY            PREFIX
-#define DEFAULT_LOCAL_STATE_DIRECTORY     "var/trafficserver"
-#define DEFAULT_SYSTEM_CONFIG_DIRECTORY   "etc/trafficserver"
-#define DEFAULT_LOG_DIRECTORY             "var/log/trafficserver"
-
-void MgmtShutdown(int status);
-void fileUpdated(char *fname, bool incVersion);
-void runAsUser(char *userName);
-void printUsage(void);
-
-extern FileManager *configFiles;
-//extern overviewPage *overviewGenerator;
-extern AppVersionInfo appVersionInfo;
-
-// Global strings
-extern char mgmt_path[];
-
-// Global variable to replace ifdef MGMT_LAUNCH_PROXY so that
-// we can turn on/off proxy launch at runtime to facilitate
-// manager only testing.
-extern bool mgmt_launch_proxy;
-
-#endif /* _MAIN_H_ */

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/Makefile.am
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Makefile.am b/cmd/traffic_manager/Makefile.am
index 6ba9bfd..97d6a41 100644
--- a/cmd/traffic_manager/Makefile.am
+++ b/cmd/traffic_manager/Makefile.am
@@ -34,8 +34,7 @@ AM_CPPFLAGS = \
 
 traffic_manager_SOURCES = \
   AddConfigFilesHere.cc \
-  Main.cc \
-  Main.h \
+  traffic_manager.cc \
   StatProcessor.cc \
   StatProcessor.h \
   StatType.cc \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/StatType.h
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/StatType.h b/cmd/traffic_manager/StatType.h
index 673e1e7..03e8f7a 100644
--- a/cmd/traffic_manager/StatType.h
+++ b/cmd/traffic_manager/StatType.h
@@ -34,7 +34,6 @@
 #define	_STATTYPE_H_
 
 #include "StatXML.h"
-#include "Main.h"               // Debug()
 #include "WebMgmtUtils.h"
 
 #define BYTES_TO_MBIT_SCALE (8/1000000.0)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ab8c0cd2/cmd/traffic_manager/traffic_manager.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/traffic_manager.cc b/cmd/traffic_manager/traffic_manager.cc
new file mode 100644
index 0000000..a45e246
--- /dev/null
+++ b/cmd/traffic_manager/traffic_manager.cc
@@ -0,0 +1,1202 @@
+/** @file
+
+  Entry point to the traffic manager.
+
+  @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.
+ */
+
+#include "libts.h"
+#include "ink_sys_control.h"
+
+#include "MgmtUtils.h"
+#include "WebMgmtUtils.h"
+#include "WebIntrMain.h"
+#include "WebOverview.h"
+#include "ClusterCom.h"
+#include "VMap.h"
+#include "FileManager.h"
+#include "I_Layout.h"
+#include "I_Version.h"
+#include "Diags.h"
+#include "DiagsConfig.h"
+#include "URL.h"
+#include "MIME.h"
+#include "HTTP.h"
+
+// Needs LibRecordsConfigInit()
+#include "RecordsConfig.h"
+
+#include "StatProcessor.h"
+#include "P_RecLocal.h"
+#include "P_RecCore.h"
+
+#if TS_USE_POSIX_CAP
+#include <sys/capability.h>
+#endif
+#include <grp.h>
+
+#define FD_THROTTLE_HEADROOM (128 + 64) // TODO: consolidate with THROTTLE_FD_HEADROOM
+#define DIAGS_LOG_FILENAME "manager.log"
+
+// These globals are still referenced directly by management API.
+LocalManager *lmgmt = NULL;
+FileManager *configFiles;
+
+static void fileUpdated(char *fname, bool incVersion);
+static void runAsUser(char *userName);
+static void printUsage(void);
+
+#if defined(freebsd)
+extern "C" int getpwnam_r(const char *name, struct passwd *result, char *buffer, size_t buflen, struct passwd **resptr);
+#endif
+
+static void extractConfigInfo(char *mgmt_path, const char *recs_conf, char *userName, int *fds_throttle);
+
+static StatProcessor *statProcessor;   // Statistics Processors
+static AppVersionInfo appVersionInfo;  // Build info for this application
+
+static inkcoreapi DiagsConfig *diagsConfig;
+static char debug_tags[1024] = "";
+static char action_tags[1024] = "";
+static bool proxy_on = true;
+
+static char mgmt_path[PATH_NAME_MAX + 1];
+
+// By default, set the current directory as base
+static const char *recs_conf = "records.config";
+
+static int fds_limit;
+
+// TODO: Use positive instead negative selection
+//       Thsis should just be #if defined(solaris)
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+static void SignalHandler(int sig, siginfo_t * t, void *f);
+static void SignalAlrmHandler(int sig, siginfo_t * t, void *f);
+#else
+static void SignalHandler(int sig);
+static void SignalAlrmHandler(int sig);
+#endif
+
+static volatile int sigHupNotifier = 0;
+static volatile int sigUsr2Notifier = 0;
+static void SigChldHandler(int sig);
+
+static void
+check_lockfile()
+{
+  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+  char lockfile[PATH_NAME_MAX];
+  int err;
+  pid_t holding_pid;
+
+  //////////////////////////////////////
+  // test for presence of server lock //
+  //////////////////////////////////////
+  Layout::relative_to(lockfile, sizeof(lockfile), rundir, SERVER_LOCK);
+  Lockfile server_lockfile(lockfile);
+  err = server_lockfile.Open(&holding_pid);
+  if (err == 1) {
+    server_lockfile.Close();    // no server running
+  } else {
+    char *reason = strerror(-err);
+    if (err == 0) {
+      // TODO: Add PID_FMT_T instead duplicating code just for printing
+#if defined(solaris)
+      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, (int)holding_pid);
+#else
+      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, holding_pid);
+#endif
+      mgmt_elog(stderr, 0, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, holding_pid);
+    } else {
+      fprintf(stderr, "FATAL: Can't open server lockfile '%s' (%s)\n", lockfile, (reason ? reason : "Unknown Reason"));
+      mgmt_elog(stderr, 0, "FATAL: Can't open server lockfile '%s' (%s)\n",
+                lockfile, (reason ? reason : "Unknown Reason"));
+    }
+    exit(1);
+  }
+
+  ///////////////////////////////////////////
+  // try to get the exclusive manager lock //
+  ///////////////////////////////////////////
+  Layout::relative_to(lockfile, sizeof(lockfile), rundir, MANAGER_LOCK);
+  Lockfile manager_lockfile(lockfile);
+  err = manager_lockfile.Get(&holding_pid);
+  if (err != 1) {
+    char *reason = strerror(-err);
+    fprintf(stderr, "FATAL: Can't acquire manager lockfile '%s'", lockfile);
+    mgmt_elog(stderr, 0, "FATAL: Can't acquire manager lockfile '%s'", lockfile);
+    if (err == 0) {
+#if defined(solaris)
+      fprintf(stderr, " (Lock file held by process ID %d)\n", (int)holding_pid);
+#else
+      fprintf(stderr, " (Lock file held by process ID %d)\n", holding_pid);
+#endif
+      mgmt_elog(stderr, 0, " (Lock file held by process ID %d)\n", holding_pid);
+    } else if (reason) {
+      fprintf(stderr, " (%s)\n", reason);
+      mgmt_elog(stderr, 0, " (%s)\n", reason);
+    } else {
+      fprintf(stderr, "\n");
+    }
+    exit(1);
+
+    fprintf(stderr, "unable to acquire manager lock [%d]\n", -err);
+    exit(1);
+  }
+}
+
+static void
+initSignalHandlers()
+{
+  struct sigaction sigHandler, sigChldHandler, sigAlrmHandler;
+  sigset_t sigsToBlock;
+
+  // Set up the signal handler
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigHandler.sa_handler = NULL;
+  sigHandler.sa_sigaction = SignalHandler;
+#else
+  sigHandler.sa_handler = SignalHandler;
+#endif
+  sigemptyset(&sigHandler.sa_mask);
+
+  // We want the handler to remain in place on
+  //  SIGHUP to avoid any races with the signals
+  //  coming too quickly.  Also restart systems calls
+  //  after the signal since not all calls are wrapped
+  //  to check errno for EINTR
+  sigHandler.sa_flags = SA_RESTART;
+  sigaction(SIGHUP, &sigHandler, NULL);
+  sigaction(SIGUSR2, &sigHandler, NULL);
+
+  // Don't block the signal on entry to the signal
+  //   handler so we can reissue it and get a core
+  //   file in the appropriate circumstances
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigHandler.sa_flags = SA_RESETHAND | SA_SIGINFO;
+#else
+  sigHandler.sa_flags = SA_RESETHAND;
+#endif
+  sigaction(SIGINT, &sigHandler, NULL);
+  sigaction(SIGQUIT, &sigHandler, NULL);
+  sigaction(SIGILL, &sigHandler, NULL);
+  sigaction(SIGBUS, &sigHandler, NULL);
+  sigaction(SIGSEGV, &sigHandler, NULL);
+  sigaction(SIGTERM, &sigHandler, NULL);
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigAlrmHandler.sa_handler = NULL;
+  sigAlrmHandler.sa_sigaction = SignalAlrmHandler;
+#else
+  sigAlrmHandler.sa_handler = SignalAlrmHandler;
+#endif
+
+  sigemptyset(&sigAlrmHandler.sa_mask);
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigAlrmHandler.sa_flags = SA_SIGINFO;
+#else
+  sigAlrmHandler.sa_flags = 0;
+#endif
+  sigaction(SIGALRM, &sigAlrmHandler, NULL);
+
+  // Block the delivery of any signals we are not catching
+  //
+  //  except for SIGALARM since we use it
+  //    to break out of deadlock on semaphore
+  //    we share with the proxy
+  //
+  sigfillset(&sigsToBlock);
+  sigdelset(&sigsToBlock, SIGHUP);
+  sigdelset(&sigsToBlock, SIGUSR2);
+  sigdelset(&sigsToBlock, SIGINT);
+  sigdelset(&sigsToBlock, SIGQUIT);
+  sigdelset(&sigsToBlock, SIGILL);
+  sigdelset(&sigsToBlock, SIGABRT);
+  sigdelset(&sigsToBlock, SIGBUS);
+  sigdelset(&sigsToBlock, SIGSEGV);
+  sigdelset(&sigsToBlock, SIGTERM);
+  sigdelset(&sigsToBlock, SIGALRM);
+  ink_thread_sigsetmask(SIG_SETMASK, &sigsToBlock, NULL);
+
+  // Set up the SIGCHLD handler so we do not get into
+  //   a problem with Solaris 2.6 and strange waitpid()
+  //   behavior
+  sigChldHandler.sa_handler = SigChldHandler;
+  sigChldHandler.sa_flags = SA_RESTART;
+  sigemptyset(&sigChldHandler.sa_mask);
+  sigaction(SIGCHLD, &sigChldHandler, NULL);
+}
+
+#if defined(linux)
+#include <sys/prctl.h>
+#endif
+static int
+setup_coredump()
+{
+#if defined(linux)
+#ifndef PR_SET_DUMPABLE
+#define PR_SET_DUMPABLE 4       /* Ugly, but we cannot compile with 2.2.x otherwise.
+                                   Should be removed when we compile only on 2.4.x */
+#endif
+  prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+#endif  // linux check
+  return 0;
+}
+
+static void
+init_dirs()
+{
+  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+
+  if (access(Layout::get()->sysconfdir, R_OK) == -1) {
+    mgmt_elog(0, "unable to access() config dir '%s': %d, %s\n", Layout::get()->sysconfdir, errno, strerror(errno));
+    mgmt_elog(0, "please set the 'TS_ROOT' environment variable\n");
+    _exit(1);
+  }
+
+  if (access(rundir, R_OK) == -1) {
+    mgmt_elog(0, "unable to access() local state dir '%s': %d, %s\n", (const char *)rundir, errno, strerror(errno));
+    mgmt_elog(0, "please set 'proxy.config.local_state_dir'\n");
+    _exit(1);
+  }
+}
+
+static void
+chdir_root()
+{
+  const char * prefix = Layout::get()->prefix;
+
+  if (chdir(prefix) < 0) {
+    mgmt_elog(0, "unable to change to root directory \"%s\" [%d '%s']\n", prefix, errno, strerror(errno));
+    mgmt_elog(0, " please set correct path in env variable TS_ROOT \n");
+    exit(1);
+  } else {
+    mgmt_log("[TrafficManager] using root directory '%s'\n", prefix);
+  }
+}
+
+static void
+set_process_limits(int fds_throttle)
+{
+  struct rlimit lim;
+
+  // Set needed rlimits (root)
+  ink_max_out_rlimit(RLIMIT_NOFILE, true, false);
+  ink_max_out_rlimit(RLIMIT_STACK, true, true);
+  ink_max_out_rlimit(RLIMIT_DATA, true, true);
+  ink_max_out_rlimit(RLIMIT_FSIZE, true, false);
+#ifdef RLIMIT_RSS
+  ink_max_out_rlimit(RLIMIT_RSS, true, true);
+#endif
+
+#if defined(linux)
+  float file_max_pct = 0.9;
+  FILE *fd;
+
+  if ((fd = fopen("/proc/sys/fs/file-max","r"))) {
+    ATS_UNUSED_RETURN(fscanf(fd, "%lu", &lim.rlim_max));
+    fclose(fd);
+    REC_ReadConfigFloat(file_max_pct, "proxy.config.system.file_max_pct");
+    lim.rlim_cur = lim.rlim_max = static_cast<rlim_t>(lim.rlim_max * file_max_pct);
+    if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
+      fds_limit = (int) lim.rlim_cur;
+      syslog(LOG_NOTICE, "NOTE: RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
+    } else {
+      syslog(LOG_NOTICE, "NOTE: Unable to set RLIMIT_NOFILE(%d):cur(%d),max(%d)", RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
+    }
+  } else {
+    syslog(LOG_NOTICE, "NOTE: Unable to open /proc/sys/fs/file-max");
+  }
+#endif // linux
+
+  if (!getrlimit(RLIMIT_NOFILE, &lim)) {
+    if (fds_throttle > (int) (lim.rlim_cur + FD_THROTTLE_HEADROOM)) {
+      lim.rlim_cur = (lim.rlim_max = (rlim_t) fds_throttle);
+      if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
+        fds_limit = (int) lim.rlim_cur;
+	syslog(LOG_NOTICE, "NOTE: RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
+      }
+    }
+  }
+
+}
+
+#if TS_HAS_WCCP
+static void
+Errata_Logger(ts::Errata const& err) {
+  size_t n;
+  static size_t const SIZE = 4096;
+  char buff[SIZE];
+  if (err.size()) {
+    ts::Errata::Code code = err.top().getCode();
+    n = err.write(buff, SIZE, 1, 0, 2, "> ");
+    // strip trailing newlines.
+    while (n && (buff[n-1] == '\n' || buff[n-1] == '\r'))
+      buff[--n] = 0;
+    // log it.
+    if (code > 1) mgmt_elog(0, "[WCCP]%s", buff);
+    else if (code > 0) mgmt_log("[WCCP]%s", buff);
+    else Debug("WCCP", "%s", buff);
+  }
+}
+
+static void
+Init_Errata_Logging() {
+  ts::Errata::registerSink(&Errata_Logger);
+}
+#endif
+
+int
+main(int argc, char **argv)
+{
+  // Before accessing file system initialize Layout engine
+  Layout::create();
+  ink_strlcpy(mgmt_path, Layout::get()->sysconfdir, sizeof(mgmt_path));
+
+  // change the directory to the "root" directory
+  chdir_root();
+
+  // Line buffer standard output & standard error
+  int status;
+  status = setvbuf(stdout, NULL, _IOLBF, 0);
+  if (status != 0)
+    perror("WARNING: can't line buffer stdout");
+  status = setvbuf(stderr, NULL, _IOLBF, 0);
+  if (status != 0)
+    perror("WARNING: can't line buffer stderr");
+
+  bool found = false;
+  int just_started = 0;
+  int cluster_mcport = -1, cluster_rsport = -1;
+  // TODO: This seems completely incomplete, disabled for now
+  //  int dump_config = 0, dump_process = 0, dump_node = 0, dump_cluster = 0, dump_local = 0;
+  char* proxy_port = 0;
+  int proxy_backdoor = -1;
+  char *envVar = NULL, *group_addr = NULL, *tsArgs = NULL;
+  bool log_to_syslog = true;
+  char userToRunAs[80];
+  int  fds_throttle = -1;
+  time_t ticker;
+  ink_thread webThrId;
+
+  // Set up the application version info
+  appVersionInfo.setup(PACKAGE_NAME,"traffic_manager", PACKAGE_VERSION,
+                       __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
+  initSignalHandlers();
+
+  // Process Environment Variables
+  if ((envVar = getenv("MGMT_ACONF_PORT")) != NULL) {
+    aconf_port_arg = atoi(envVar);
+  }
+
+  if ((envVar = getenv("MGMT_CLUSTER_MC_PORT")) != NULL) {
+    cluster_mcport = atoi(envVar);
+  }
+
+  if ((envVar = getenv("MGMT_CLUSTER_RS_PORT")) != NULL) {
+    cluster_rsport = atoi(envVar);
+  }
+
+  if ((envVar = getenv("MGMT_GROUP_ADDR")) != NULL) {
+    group_addr = envVar;
+  }
+
+  for (int i = 1; i < argc; i++) {      /* Process command line args */
+
+    if (argv[i][0] == '-') {
+      if ((strcmp(argv[i], "-version") == 0) || (strcmp(argv[i], "-V") == 0)) {
+        fprintf(stderr, "%s\n", appVersionInfo.FullVersionInfoStr);
+        exit(0);
+      } else if (strcmp(argv[i], "-proxyOff") == 0) {
+        proxy_on = false;
+      } else if (strcmp(argv[i], "-nosyslog") == 0) {
+        log_to_syslog = false;
+      } else {
+        // The rest of the options require an argument in the form of -<Flag> <val>
+        if ((i + 1) < argc) {
+
+          if (strcmp(argv[i], "-aconfPort") == 0) {
+            ++i;
+            aconf_port_arg = atoi(argv[i]);
+          } else if (strcmp(argv[i], "-clusterMCPort") == 0) {
+            ++i;
+            cluster_mcport = atoi(argv[i]);
+          } else if (strcmp(argv[i], "-groupAddr") == 0) {
+            ++i;
+            group_addr = argv[i];
+          } else if (strcmp(argv[i], "-clusterRSPort") == 0) {
+            ++i;
+            cluster_rsport = atoi(argv[i]);
+#if TS_USE_DIAGS
+          } else if (strcmp(argv[i], "-debug") == 0) {
+            ++i;
+            ink_strlcpy(debug_tags, argv[i], sizeof(debug_tags));
+          } else if (strcmp(argv[i], "-action") == 0) {
+            ++i;
+            ink_strlcpy(action_tags, argv[i], sizeof(debug_tags));
+#endif
+          } else if (strcmp(argv[i], "-path") == 0) {
+            ++i;
+            //bugfixed by YTS Team, yamsat(id-59703)
+            if ((strlen(argv[i]) > PATH_NAME_MAX)) {
+              fprintf(stderr, "\n   Path exceeded the maximum allowed characters.\n");
+              exit(1);
+            }
+
+            ink_strlcpy(mgmt_path, argv[i], sizeof(mgmt_path));
+            /*
+               } else if(strcmp(argv[i], "-lmConf") == 0) {
+               ++i;
+               lm_conf = argv[i];
+             */
+          } else if (strcmp(argv[i], "-recordsConf") == 0) {
+            ++i;
+            recs_conf = argv[i];
+            // TODO: This seems completely incomplete, disabled for now
+#if 0
+          } else if (strcmp(argv[i], "-printRecords") == 0) {
+            ++i;
+            while (i < argc && argv[i][0] != '-') {
+              if (strcasecmp(argv[i], "config") == 0) {
+                dump_config = 1;
+              } else if (strcasecmp(argv[i], "process") == 0) {
+                dump_process = 1;
+              } else if (strcasecmp(argv[i], "node") == 0) {
+                dump_node = 1;
+              } else if (strcasecmp(argv[i], "cluster") == 0) {
+                dump_cluster = 1;
+              } else if (strcasecmp(argv[i], "local") == 0) {
+                dump_local = 1;
+              } else if (strcasecmp(argv[i], "all") == 0) {
+                dump_config = dump_node = dump_process = dump_cluster = dump_local = 1;
+              }
+              ++i;
+            }
+            --i;
+#endif
+          } else if (strcmp(argv[i], "-tsArgs") == 0) {
+            int size_of_args = 0, j = (++i);
+            while (j < argc) {
+              size_of_args += 1;
+              size_of_args += strlen((argv[j++]));
+            }
+            tsArgs = (char *)ats_malloc(size_of_args + 1);
+
+            j = 0;
+            while (i < argc) {
+              snprintf(&tsArgs[j], ((size_of_args + 1) - j), " %s", argv[i]);
+              j += strlen(argv[i]) + 1;
+              ++i;
+            }
+          } else if (strcmp(argv[i], "-proxyPort") == 0) {
+            ++i;
+            proxy_port = argv[i];
+          } else if (strcmp(argv[i], "-proxyBackDoor") == 0) {
+            ++i;
+            proxy_backdoor = atoi(argv[i]);
+          } else {
+            printUsage();
+          }
+        } else {
+          printUsage();
+        }
+      }
+    }
+  }
+
+  // Bootstrap with LOG_DAEMON until we've read our configuration
+  if (log_to_syslog) {
+    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, LOG_DAEMON);
+    mgmt_use_syslog();
+    syslog(LOG_NOTICE, "NOTE: --- Manager Starting ---");
+    syslog(LOG_NOTICE, "NOTE: Manager Version: %s", appVersionInfo.FullVersionInfoStr);
+  }
+
+  // Bootstrap the Diags facility so that we can use it while starting
+  //  up the manager
+  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, false);
+  diags = diagsConfig->diags;
+  diags->prefix_str = "Manager ";
+
+  RecLocalInit();
+  LibRecordsConfigInit();
+  RecordsConfigOverrideFromEnvironment();
+
+  init_dirs();// setup critical directories, needs LibRecords
+
+  // Get the config info we need while we are still root
+  extractConfigInfo(mgmt_path, recs_conf, userToRunAs, &fds_throttle);
+
+  set_process_limits(fds_throttle); // as root
+  runAsUser(userToRunAs);
+  setup_coredump();
+  check_lockfile();
+
+  url_init();
+  mime_init();
+  http_init();
+
+#if TS_HAS_WCCP
+  Init_Errata_Logging();
+#endif
+  ts_host_res_global_init();
+  ts_session_protocol_well_known_name_indices_init();
+  lmgmt = new LocalManager(proxy_on);
+  RecLocalInitMessage();
+  lmgmt->initAlarm();
+
+  if (diags) {
+    delete diagsConfig;
+    // diagsConfig->reconfigure_diags(); INKqa11968
+    /*
+       delete diags;
+       diags = new Diags(debug_tags,action_tags);
+     */
+  }
+  // INKqa11968: need to set up callbacks and diags data structures
+  // using configuration in records.config
+  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, true);
+  diags = diagsConfig->diags;
+  RecSetDiags(diags);
+  diags->prefix_str = "Manager ";
+
+  if (is_debug_tag_set("diags"))
+    diags->dump();
+  diags->cleanup_func = mgmt_cleanup;
+
+  // Setup the exported manager version records.
+  RecSetRecordString("proxy.node.version.manager.short", appVersionInfo.VersionStr);
+  RecSetRecordString("proxy.node.version.manager.long", appVersionInfo.FullVersionInfoStr);
+  RecSetRecordString("proxy.node.version.manager.build_number", appVersionInfo.BldNumStr);
+  RecSetRecordString("proxy.node.version.manager.build_time", appVersionInfo.BldTimeStr);
+  RecSetRecordString("proxy.node.version.manager.build_date", appVersionInfo.BldDateStr);
+  RecSetRecordString("proxy.node.version.manager.build_machine", appVersionInfo.BldMachineStr);
+  RecSetRecordString("proxy.node.version.manager.build_person", appVersionInfo.BldPersonStr);
+//    RecSetRecordString("proxy.node.version.manager.build_compile_flags",
+//                       appVersionInfo.BldCompileFlagsStr);
+
+  if (log_to_syslog) {
+    char sys_var[] = "proxy.config.syslog_facility";
+    char *facility_str = NULL;
+    int facility_int;
+    facility_str = REC_readString(sys_var, &found);
+    ink_assert(found);
+
+    if (!found) {
+      mgmt_elog(0, "Could not read %s.  Defaulting to DAEMON\n", sys_var);
+      facility_int = LOG_DAEMON;
+    } else {
+      facility_int = facility_string_to_int(facility_str);
+      ats_free(facility_str);
+      if (facility_int < 0) {
+        mgmt_elog(0, "Bad syslog facility specified.  Defaulting to DAEMON\n");
+        facility_int = LOG_DAEMON;
+      }
+    }
+
+    // NOTE: do NOT call closelog() here.  Solaris gets confused
+    //   and some how it hoses later calls to readdir_r.
+    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, facility_int);
+
+    lmgmt->syslog_facility = facility_int;
+  } else {
+    lmgmt->syslog_facility = -1;
+  }
+
+  // Find out our hostname so we can use it as part of the initialization
+  setHostnameVar();
+
+  // Create the data structure for overview page
+  //   Do this before the rest of the set up since it needs
+  //   to created to handle any alarms thrown by later
+  //   initialization
+  overviewGenerator = new overviewPage();
+
+  // Initialize the Config Object bindings before
+  //   starting any other threads
+  lmgmt->configFiles = configFiles = new FileManager();
+  initializeRegistry();
+  configFiles->registerCallback(fileUpdated);
+
+  // RecLocal's 'sync_thr' depends on 'configFiles', so we can't
+  // stat the 'sync_thr' until 'configFiles' has been initialized.
+  RecLocalStart(configFiles);
+
+  /* Update cmd line overrides/environmental overrides/etc */
+  if (tsArgs) {                 /* Passed command line args for proxy */
+    ats_free(lmgmt->proxy_options);
+    lmgmt->proxy_options = tsArgs;
+    mgmt_log(stderr, "[main] Traffic Server Args: '%s'\n", lmgmt->proxy_options);
+  }
+  if (proxy_port) {
+    HttpProxyPort::loadValue(lmgmt->m_proxy_ports, proxy_port);
+  }
+
+  if (proxy_backdoor != -1) {
+    RecSetRecordInt("proxy.config.process_manager.mgmt_port", proxy_backdoor);
+  }
+
+  if (cluster_rsport == -1) {
+    cluster_rsport = REC_readInteger("proxy.config.cluster.rsport", &found);
+    ink_assert(found);
+  }
+
+  if (cluster_mcport == -1) {
+    cluster_mcport = REC_readInteger("proxy.config.cluster.mcport", &found);
+    ink_assert(found);
+  }
+
+  if (!group_addr) {
+    group_addr = REC_readString("proxy.config.cluster.mc_group_addr", &found);
+    ink_assert(found);
+  }
+
+  in_addr_t min_ip = inet_network("224.0.0.255");
+  in_addr_t max_ip = inet_network("239.255.255.255");
+  in_addr_t group_addr_ip = inet_network(group_addr);
+
+  if (!(min_ip < group_addr_ip && group_addr_ip < max_ip)) {
+    mgmt_fatal(0, "[TrafficManager] Multi-Cast group addr '%s' is not in the permitted range of %s\n",
+               group_addr, "224.0.1.0 - 239.255.255.255");
+  }
+
+  /* TODO: Do we really need to init cluster communication? */
+  lmgmt->initCCom(appVersionInfo, configFiles, cluster_mcport, group_addr, cluster_rsport);       /* Setup cluster communication */
+
+  lmgmt->initMgmtProcessServer();       /* Setup p-to-p process server */
+
+  // Now that we know our cluster ip address, add the
+  //   UI record for this machine
+  overviewGenerator->addSelfRecord();
+
+  lmgmt->listenForProxy();
+
+  //
+  // As listenForProxy() may change/restore euid, we should put
+  // the creation of webIntr_main thread after it. So that we
+  // can keep a consistent euid when create mgmtapi/eventapi unix
+  // sockets in webIntr_main thread.
+  //
+  webThrId = ink_thread_create(webIntr_main, NULL);     /* Spin web agent thread */
+  Debug("lm", "Created Web Agent thread (%"  PRId64 ")", (int64_t)webThrId);
+
+  ticker = time(NULL);
+  mgmt_log("[TrafficManager] Setup complete\n");
+
+  statProcessor = new StatProcessor(configFiles);
+
+  for (;;) {
+    lmgmt->processEventQueue();
+    lmgmt->pollMgmtProcessServer();
+
+    // Check for a SIGHUP
+    if (sigHupNotifier != 0) {
+      mgmt_log(stderr, "[main] Reading Configuration Files due to SIGHUP\n");
+      configFiles->rereadConfig();
+      lmgmt->signalEvent(MGMT_EVENT_PLUGIN_CONFIG_UPDATE, "*");
+      sigHupNotifier = 0;
+      mgmt_log(stderr, "[main] Reading Configuration Files Reread\n");
+    }
+    // Check for SIGUSR2
+    if (sigUsr2Notifier != 0) {
+      ink_stack_trace_dump();
+      sigUsr2Notifier = 0;
+    }
+
+    lmgmt->ccom->generateClusterDelta();
+
+    if (lmgmt->run_proxy && lmgmt->processRunning()) {
+      lmgmt->ccom->sendSharedData();
+      lmgmt->virt_map->lt_runGambit();
+    } else {
+      if (!lmgmt->run_proxy) {  /* Down if we are not going to start another immed. */
+        /* Proxy is not up, so no addrs should be */
+        lmgmt->virt_map->downOurAddrs();
+      }
+
+      /* Proxy is not up, but we should still exchange config and alarm info */
+      lmgmt->ccom->sendSharedData(false);
+    }
+
+    lmgmt->ccom->checkPeers(&ticker);
+    overviewGenerator->checkForUpdates();
+
+    if (statProcessor) {
+      statProcessor->processStat();
+    }
+
+    if (lmgmt->mgmt_shutdown_outstanding == true) {
+      lmgmt->mgmtShutdown(true);
+      _exit(0);
+    }
+
+    if (lmgmt->run_proxy && !lmgmt->processRunning()) { /* Make sure we still have a proxy up */
+      if (lmgmt->startProxy())
+        just_started = 0;
+      else
+        just_started++;
+    } else {                    /* Give the proxy a chance to fire up */
+      just_started++;
+    }
+
+    /* This will catch the case were the proxy dies before it can connect to manager */
+    if (lmgmt->proxy_launch_outstanding && !lmgmt->processRunning() && just_started >= 120) {
+      just_started = 0;
+      lmgmt->proxy_launch_outstanding = false;
+      if (lmgmt->proxy_launch_pid != -1) {
+        int res;
+        kill(lmgmt->proxy_launch_pid, 9);
+        waitpid(lmgmt->proxy_launch_pid, &res, 0);
+        if (WIFSIGNALED(res)) {
+          int sig = WTERMSIG(res);
+#ifdef NEED_PSIGNAL
+          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d\n", sig);
+#else
+          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d: %s\n", sig, strsignal(sig));
+#endif /* NEED_PSIGNAL */
+        }
+      }
+      mgmt_log(stderr, "[main] Proxy launch failed, retrying...\n");
+    }
+
+  }
+
+  if (statProcessor) {
+    delete(statProcessor);
+  }
+
+#ifndef MGMT_SERVICE
+  return 0;
+#endif
+
+}                               /* End main */
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+static void
+SignalAlrmHandler(int /* sig ATS_UNUSED */, siginfo_t * t, void * /* c ATS_UNUSED */)
+#else
+static void
+SignalAlrmHandler(int /* sig ATS_UNUSED */)
+#endif
+{
+  /*
+     fprintf(stderr, "[TrafficManager] ==> SIGALRM received\n");
+     mgmt_elog(stderr, 0, "[TrafficManager] ==> SIGALRM received\n");
+   */
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  if (t) {
+    if (t->si_code <= 0) {
+#if defined(solaris)
+      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", (int)t->si_pid, t->si_uid);
+#else
+      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", t->si_pid, t->si_uid);
+#endif
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", t->si_pid, t->si_uid);
+    } else {
+      fprintf(stderr, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", t->si_code);
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", t->si_code);
+    }
+  }
+#endif
+
+  return;
+}
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+static void
+SignalHandler(int sig, siginfo_t * t, void *c)
+#else
+static void
+SignalHandler(int sig)
+#endif
+{
+  static int clean = 0;
+  int status;
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  if (t) {
+    if (t->si_code <= 0) {
+#if defined(solaris)
+      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, (int)t->si_pid, t->si_uid);
+#else
+      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, t->si_pid, t->si_uid);
+#endif
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, t->si_pid, t->si_uid);
+    } else {
+      fprintf(stderr, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", sig, t->si_code);
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", sig, t->si_code);
+    }
+  }
+#endif
+
+  if (sig == SIGHUP) {
+    sigHupNotifier = 1;
+    return;
+  }
+
+  if (sig == SIGUSR2) {
+    sigUsr2Notifier = 1;
+    return;
+  }
+  fprintf(stderr, "[TrafficManager] ==> Cleaning up and reissuing signal #%d\n", sig);
+  mgmt_elog(stderr, 0, "[TrafficManager] ==> Cleaning up and reissuing signal #%d\n", sig);
+
+  if (lmgmt && !clean) {
+    clean = 1;
+    if (lmgmt->watched_process_pid != -1) {
+
+      if (sig == SIGTERM || sig == SIGINT) {
+        kill(lmgmt->watched_process_pid, sig);
+        waitpid(lmgmt->watched_process_pid, &status, 0);
+      }
+    }
+    lmgmt->mgmtCleanup();
+  }
+
+  switch (sig) {
+  case SIGQUIT:
+  case SIGILL:
+  case SIGTRAP:
+#if !defined(linux)
+  case SIGEMT:
+  case SIGSYS:
+#endif
+  case SIGFPE:
+  case SIGBUS:
+  case SIGSEGV:
+  case SIGXCPU:
+  case SIGXFSZ:
+    abort();
+  default:
+    fprintf(stderr, "[TrafficManager] ==> signal #%d\n", sig);
+    mgmt_elog(stderr, 0, "[TrafficManager] ==> signal #%d\n", sig);
+    _exit(sig);
+  }
+  fprintf(stderr, "[TrafficManager] ==> signal2 #%d\n", sig);
+  mgmt_elog(stderr, 0, "[TrafficManager] ==> signal2 #%d\n", sig);
+  _exit(sig);
+}                               /* End SignalHandler */
+
+// void SigChldHandler(int sig)
+//
+//   An empty handler needed so that we catch SIGCHLD
+//    With Solaris 2.6, ignoring sig child changes the behavior
+//    of waitpid() so that if there are no unwaited children,
+//    waitpid() blocks until all child are transformed into
+//    zombies which is bad for us
+//
+static void
+SigChldHandler(int /* sig ATS_UNUSED */)
+{
+}
+
+void
+printUsage()
+{
+  fprintf(stderr, "----------------------------------------------------------------------------\n");
+  fprintf(stderr, " Traffic Manager Usage: (all args are optional)\n");
+  fprintf(stderr, "\n");
+  fprintf(stderr, "   traffic_manager [options]\n");
+  fprintf(stderr, "     -proxyPort     <port>  Port to have proxy listen on, overrides records.config.\n");
+  /* Function is currently #ifdef'ed out so no reason to advertise
+     fprintf(stderr,
+     "     -proxyBackdoor <port>  Port to put proxy mgmt port on.\n");
+   */
+  /* Commented out because this option is used for debugging only.
+     fprintf(stderr,
+     "     -noProxy               Do not launch the proxy process.\n");
+   */
+  fprintf(stderr, "     -tsArgs        [...]   Args to proxy, everything till eol is passed.\n");
+  fprintf(stderr, "     -webPort       <port>  Port for web interface.\n");
+  /*
+     fprintf(stderr,
+     "     -graphPort     <port>  Port for dynamic graphs.\n");
+   */
+  fprintf(stderr, "     -clusterPort   <port>  Cluster Multicast port\n");
+  fprintf(stderr, "     -groupAddr     <addr>  Cluster Multicast group, example: \"225.0.0.37\".\n");
+  fprintf(stderr, "     -clusterRSPort <port>  Cluster Multicast port.\n");
+  fprintf(stderr, "     -path          <path>  Root path for config files.\n");
+  /*
+     fprintf(stderr,
+     "     -lmConf        <fname> Local Management config file.\n");
+   */
+  fprintf(stderr, "     -recordsConf   <fname> General config file.\n");
+  // TODO: This seems completely incomplete, disabled for now
+  // fprintf(stderr, "     -printRecords  [...]   Print flags, default all are off.\n");
+  fprintf(stderr, "     -debug         <tags>  Enable the given debug tags\n");
+  fprintf(stderr, "     -action        <tags>  Enable the given action tags.\n");
+  fprintf(stderr, "     -version or -V         Print version id and exit.\n");
+  fprintf(stderr, "\n");
+  fprintf(stderr, "   [...] can be one+ of: [config process node cluster local all]\n");
+  fprintf(stderr, "----------------------------------------------------------------------------\n");
+  exit(0);
+}                               /* End printUsage */
+
+void
+fileUpdated(char *fname, bool incVersion)
+{
+  if (strcmp(fname, "cluster.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cluster.cluster_configuration");
+
+  } else if (strcmp(fname, "remap.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.url_remap.filename");
+
+  } else if (strcmp(fname, "socks.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.socks.socks_config_file");
+
+  } else if (strcmp(fname, "records.config") == 0) {
+    lmgmt->signalFileChange("records.config", incVersion);
+
+  } else if (strcmp(fname, "cache.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cache.control.filename");
+
+  } else if (strcmp(fname, "parent.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.http.parent_proxy.file");
+
+  } else if (strcmp(fname, "ip_allow.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cache.ip_allow.filename");
+  } else if (strcmp(fname, "vaddrs.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] vaddrs.config updated\n");
+    lmgmt->virt_map->lt_readAListFile(fname);
+
+  } else if (strcmp(fname, "storage.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] storage.config changed, need restart auto-rebuild mode\n");
+
+  } else if (strcmp(fname, "proxy.pac") == 0) {
+    mgmt_log(stderr, "[fileUpdated] proxy.pac file has been modified\n");
+
+  } else if (strcmp(fname, "icp.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.icp.icp_configuration");
+
+  } else if (strcmp(fname, "update.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.update.update_configuration");
+
+  } else if (strcmp(fname, "volume.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] volume.config changed, need restart\n");
+
+  } else if (strcmp(fname, "hosting.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cache.hosting_filename");
+
+  } else if (strcmp(fname, "log_hosts.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.log.hosts_config_file");
+
+  } else if (strcmp(fname, "logs_xml.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.log.xml_config_file");
+
+  } else if (strcmp(fname, "splitdns.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.dns.splitdns.filename");
+
+  } else if (strcmp(fname, "plugin.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] plugin.config file has been modified\n");
+
+  } else if (strcmp(fname, "ssl_multicert.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.ssl.server.multicert.filename");
+
+  } else if (strcmp(fname, "proxy.config.body_factory.template_sets_dir") == 0) {
+    lmgmt->signalFileChange("proxy.config.body_factory.template_sets_dir");
+
+  } else if (strcmp(fname, "stats.config.xml") == 0) {
+    if (statProcessor) {
+      statProcessor->rereadConfig(configFiles);
+    }
+    mgmt_log(stderr, "[fileUpdated] stats.config.xml file has been modified\n");
+  } else if (strcmp(fname, "congestion.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.http.congestion_control.filename");
+  } else if (strcmp(fname, "prefetch.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.prefetch.config_file");
+  } else {
+    mgmt_elog(stderr, 0, "[fileUpdated] Unknown config file updated '%s'\n", fname);
+
+  }
+  return;
+}                               /* End fileUpdate */
+
+#if TS_USE_POSIX_CAP
+/** Restore capabilities after user id change.
+    This manipulates LINUX capabilities so that this process
+    can perform certain privileged operations even if it is
+    no longer running as a privilege user.
+
+    @internal
+    I tried using
+    @code
+    prctl(PR_SET_KEEPCAPS, 1);
+    @endcode
+    but that had no effect even though the call reported success.
+    Only explicit capability manipulation was effective.
+
+    It does not appear to be necessary to set the capabilities on the
+    executable if originally run as root. That may be needed if
+    started as a user without that capability.
+ */
+
+int
+restoreCapabilities() {
+  int zret = 0; // return value.
+  cap_t cap_set = cap_get_proc(); // current capabilities
+  // Make a list of the capabilities we want turned on.
+  cap_value_t cap_list[] = {
+    CAP_NET_ADMIN, ///< Set socket transparency.
+    CAP_NET_BIND_SERVICE, ///< Low port (e.g. 80) binding.
+    CAP_IPC_LOCK ///< Lock IPC objects.
+  };
+  static int const CAP_COUNT = sizeof(cap_list)/sizeof(*cap_list);
+
+  cap_set_flag(cap_set, CAP_EFFECTIVE, CAP_COUNT, cap_list, CAP_SET);
+  zret = cap_set_proc(cap_set);
+  cap_free(cap_set);
+  return zret;
+}
+#endif
+
+//  void runAsUser(...)
+//
+//  If we are root, switched to user to run as
+//    specified in records.config
+//
+//  If we are not root, do nothing
+//
+void
+runAsUser(char *userName)
+{
+  uid_t uid, euid;
+  struct passwd *result;
+  const int bufSize = 1024;
+  char buf[bufSize];
+
+  uid = getuid();
+  euid = geteuid();
+
+  if (uid == 0 || euid == 0) {
+
+    /* Figure out what user we should run as */
+
+    Debug("lm", "[runAsUser] Attempting to run as user '%s'\n", userName);
+
+    if (userName == NULL || userName[0] == '\0') {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: proxy.config.admin.user_id is not set\n");
+      _exit(1);
+    }
+
+    struct passwd passwdInfo;
+    struct passwd *ppasswd = NULL;
+    result = NULL;
+    int res;
+    if (*userName == '#') {
+      int uuid = atoi(userName + 1);
+      if (uuid == -1)
+        uuid = (int)uid;
+      res = getpwuid_r((uid_t)uuid, &passwdInfo, buf, bufSize, &ppasswd);
+    }
+    else {
+      res = getpwnam_r(&userName[0], &passwdInfo, buf, bufSize, &ppasswd);
+    }
+
+    if (!res && ppasswd) {
+      result = ppasswd;
+    }
+
+    if (result == NULL) {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to get info about user %s : %s\n", userName, strerror(errno));
+      _exit(1);
+    }
+
+    if (setegid(result->pw_gid) != 0 || seteuid(result->pw_uid) != 0) {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to switch to user %s : %s\n", userName, strerror(errno));
+      _exit(1);
+    }
+
+    uid = getuid();
+    euid = geteuid();
+
+    Debug("lm", "[runAsUser] Running with uid: '%d' euid: '%d'\n", uid, euid);
+
+    if (uid != result->pw_uid && euid != result->pw_uid) {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Failed to switch to user %s\n", userName);
+      _exit(1);
+    }
+
+    // setup supplementary groups if it is not set.
+    if (0 == getgroups(0, NULL)) {
+      initgroups(&userName[0],result->pw_gid);
+    }
+
+#if TS_USE_POSIX_CAP
+    if (0 != restoreCapabilities()) {
+      mgmt_elog(stderr, 0, "[runAsUser] Error: Failed to restore capabilities after switch to user %s.\n", userName);
+    }
+#endif
+
+  }
+}                               /* End runAsUser() */
+
+//  void extractConfigInfo(...)
+//
+//  We need to get certain records.config values while we are
+//   root.  We can not use LMRecords to get them because the constructor
+//   for LMRecords creates the mgmt DBM and we do not want that to
+//   be owned as root.  This function extracts that info from
+//   records.config
+//
+//
+void
+extractConfigInfo(char *mgmt_path, const char *recs_conf, char *userName, int *fds_throttle)
+{
+  char file[1024];
+  bool useridFound = false;
+  bool throttleFound = false;
+
+  /* Figure out what user we should run as */
+  if (mgmt_path && recs_conf) {
+    FILE *fin;
+    snprintf(file, sizeof(file), "%s/%s.shadow", mgmt_path, recs_conf);
+    if (!(fin = fopen(file, "r"))) {
+      ink_filepath_make(file, sizeof(file), mgmt_path, recs_conf);
+      if (!(fin = fopen(file, "r"))) {
+        mgmt_elog(stderr, errno, "[extractConfigInfo] Unable to open config file(%s)\n", file);
+        _exit(1);
+      }
+    }
+    // Get 'user id' and 'network connections throttle limit'
+    while (((!useridFound) || (!throttleFound)) && fgets(file, 1024, fin)) {
+      if (strstr(file, "CONFIG proxy.config.admin.user_id STRING")) {
+        //coverity[secure_coding]
+        if ((sscanf(file, "CONFIG proxy.config.admin.user_id STRING %1023s\n", userName) == 1) &&
+            strcmp(userName, "NULL") != 0) {
+          useridFound = true;
+        }
+      } else if (strstr(file, "CONFIG proxy.config.net.connections_throttle INT")) {
+        if ((sscanf(file, "CONFIG proxy.config.net.connections_throttle INT %d\n", fds_throttle) == 1)) {
+          throttleFound = true;
+        }
+      }
+
+    }
+    fclose(fin);
+  } else {
+    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: unable to access records file\n");
+    _exit(1);
+  }
+
+  if (useridFound == false) {
+    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: proxy.config.admin.user_id is not set\n");
+    _exit(1);
+  }
+
+}                               /* End extractConfigInfo() */


[2/9] git commit: TS-2977: move traffic_manager

Posted by jp...@apache.org.
TS-2977: move traffic_manager

Move traffic_manager to the cmd subdirectory. The local manager
implementation is tightly coupled to traffic_manager, so break that
as much as we can by passing globals down.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/93f46af2
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/93f46af2
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/93f46af2

Branch: refs/heads/master
Commit: 93f46af23d40c0bc0ae369523212165590d587d3
Parents: f098175
Author: James Peach <jp...@apache.org>
Authored: Wed Jul 30 14:36:28 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Aug 1 19:55:44 2014 -0700

----------------------------------------------------------------------
 .gitignore                                |    2 +-
 cmd/Makefile.am                           |    6 +-
 cmd/traffic_manager/AddConfigFilesHere.cc |   89 ++
 cmd/traffic_manager/Main.cc               | 1199 +++++++++++++++++++++++
 cmd/traffic_manager/Main.h                |   53 ++
 cmd/traffic_manager/Makefile.am           |   67 ++
 configure.ac                              |    1 +
 lib/records/I_RecLocal.h                  |    4 +-
 lib/records/RecLocal.cc                   |   17 +-
 mgmt/AddConfigFilesHere.cc                |   89 --
 mgmt/Alarms.cc                            |    4 +-
 mgmt/Alarms.h                             |    3 +-
 mgmt/FileManager.cc                       |    1 +
 mgmt/LocalManager.cc                      |   14 +-
 mgmt/LocalManager.h                       |    9 +-
 mgmt/Main.cc                              | 1214 ------------------------
 mgmt/Main.h                               |   53 --
 mgmt/Makefile.am                          |   55 +-
 mgmt/Rollback.cc                          |    5 +-
 mgmt/Rollback.h                           |    4 +
 mgmt/api/CoreAPI.cc                       |    3 +-
 mgmt/api/TSControlMain.cc                 |    1 -
 mgmt/cluster/ClusterCom.cc                |   91 +-
 mgmt/cluster/ClusterCom.h                 |   12 +-
 mgmt/cluster/VMap.cc                      |    3 +-
 mgmt/cluster/VMap.h                       |    2 +
 mgmt/stats/StatProcessor.cc               |    7 +-
 mgmt/stats/StatProcessor.h                |    4 +-
 mgmt/utils/WebMgmtUtils.cc                |    1 +
 mgmt/web2/WebHttpMessage.cc               |    3 +-
 30 files changed, 1523 insertions(+), 1493 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 60de08e..1dd1b3e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,7 @@ cmd/traffic_line/traffic_line
 cmd/traffic_shell/traffic_shell
 cmd/traffic_cop/traffic_cop
 cmd/traffic_top/traffic_top
+cmd/traffic_manager/traffic_manager
 
 lib/ts/ink_autoconf.h
 lib/ts/ink_config.h
@@ -86,7 +87,6 @@ mgmt/tools/traffic_time_config
 mgmt/tools/traffic_vip_config
 mgmt/api/api_cli_remote
 mgmt/tools/shmem_clean
-mgmt/traffic_manager
 proxy/traffic_logcat
 proxy/traffic_logstats
 proxy/traffic_sac

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/cmd/Makefile.am
----------------------------------------------------------------------
diff --git a/cmd/Makefile.am b/cmd/Makefile.am
index 58a8a68..ad51e76 100644
--- a/cmd/Makefile.am
+++ b/cmd/Makefile.am
@@ -15,4 +15,8 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-SUBDIRS = traffic_top traffic_cop traffic_line
+SUBDIRS = \
+  traffic_cop \
+  traffic_line \
+  traffic_manager \
+  traffic_top

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/cmd/traffic_manager/AddConfigFilesHere.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/AddConfigFilesHere.cc b/cmd/traffic_manager/AddConfigFilesHere.cc
new file mode 100644
index 0000000..cc6d169
--- /dev/null
+++ b/cmd/traffic_manager/AddConfigFilesHere.cc
@@ -0,0 +1,89 @@
+/** @file
+
+  A brief file description
+
+  @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.
+ */
+
+#include "ink_platform.h"
+#include "Main.h"
+#include "MgmtUtils.h"
+#include "ConfigParse.h"
+#include "Diags.h"
+
+/****************************************************************************
+ *
+ *  AddConfigFilesHere.cc - Structs for config files and
+ *
+ *
+ ****************************************************************************/
+
+void
+testcall(char *foo, bool /* incVersion */)
+{
+  Debug("lm", "Received Callback that %s has changed\n", foo);
+}
+
+
+//
+// initializeRegistry()
+//
+// Code to initialze of registry of objects that represent
+//   Web Editable configuration files
+//
+// thread-safe: NO!  - Should only be executed once from the main
+//                     web interface thread, before any child
+//                     threads have been spawned
+void
+initializeRegistry()
+{
+  static int run_already = 0;
+
+  if (run_already == 0) {
+    run_already = 1;
+  } else {
+    ink_assert(!"Configuration Object Registry Initialized More than Once");
+  }
+
+  // NOTE: Logic that controls which files are not sync'd around the
+  // cluster is located in ClusterCom::constructSharedFilePacket
+
+  configFiles->addFile("log_hosts.config", false);
+  configFiles->addFile("logs_xml.config", false);
+  configFiles->addFile("storage.config", false);
+  configFiles->addFile("socks.config", false);
+  configFiles->addFile("proxy.pac", false);
+  configFiles->addFile("records.config", false);
+  configFiles->addFile("vaddrs.config", false);
+  configFiles->addFile("cache.config", false);
+  configFiles->addFile("icp.config", false);
+  configFiles->addFile("ip_allow.config", false);
+  configFiles->addFile("parent.config", false);
+  configFiles->addFile("remap.config", false);
+  configFiles->addFile("update.config", false);
+  configFiles->addFile("volume.config", false);
+  configFiles->addFile("hosting.config", false);
+  configFiles->addFile("congestion.config", false);
+  configFiles->addFile("plugin.config", false);
+  configFiles->addFile("splitdns.config", false);
+  configFiles->addFile("ssl_multicert.config", false);
+  configFiles->addFile("stats.config.xml", false);
+  configFiles->addFile("prefetch.config", false);
+  configFiles->registerCallback(testcall);
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/cmd/traffic_manager/Main.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Main.cc b/cmd/traffic_manager/Main.cc
new file mode 100644
index 0000000..d54eb94
--- /dev/null
+++ b/cmd/traffic_manager/Main.cc
@@ -0,0 +1,1199 @@
+/** @file
+
+  Entry point to the traffic manager.
+
+  @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.
+ */
+
+#include "ink_config.h"
+#include "ink_platform.h"
+#include "ink_sys_control.h"
+
+#include "Main.h"
+#include "MgmtUtils.h"
+#include "WebMgmtUtils.h"
+#include "WebIntrMain.h"
+#include "WebOverview.h"
+#include "FileManager.h"
+#include "I_Layout.h"
+#include "I_Version.h"
+#include "ink_syslog.h"
+#include "ink_lockfile.h"
+#include "Diags.h"
+#include "DiagsConfig.h"
+#include "URL.h"
+#include "MIME.h"
+#include "HTTP.h"
+
+// Needs LibRecordsConfigInit()
+#include "RecordsConfig.h"
+
+#include "StatProcessor.h"
+#include "P_RecLocal.h"
+#include "P_RecCore.h"
+
+#if TS_USE_POSIX_CAP
+#include <sys/capability.h>
+#endif
+#include <grp.h>
+
+#define FD_THROTTLE_HEADROOM (128 + 64) // TODO: consolidate with THROTTLE_FD_HEADROOM
+#define DIAGS_LOG_FILENAME "manager.log"
+
+#if defined(freebsd)
+extern "C" int getpwnam_r(const char *name, struct passwd *result, char *buffer, size_t buflen, struct passwd **resptr);
+#endif
+
+static void extractConfigInfo(char *mgmt_path, const char *recs_conf, char *userName, int *fds_throttle);
+
+LocalManager *lmgmt = NULL;
+FileManager *configFiles;
+
+StatProcessor *statProcessor;   // Statistics Processors
+AppVersionInfo appVersionInfo;  // Build info for this application
+
+static inkcoreapi DiagsConfig *diagsConfig;
+static char debug_tags[1024] = "";
+static char action_tags[1024] = "";
+static bool proxy_on = true;
+
+char mgmt_path[PATH_NAME_MAX + 1];
+
+// By default, set the current directory as base
+static const char *recs_conf = "records.config";
+
+static int fds_limit;
+
+// TODO: Use positive instead negative selection
+//       Thsis should just be #if defined(solaris)
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+static void SignalHandler(int sig, siginfo_t * t, void *f);
+static void SignalAlrmHandler(int sig, siginfo_t * t, void *f);
+#else
+static void SignalHandler(int sig);
+static void SignalAlrmHandler(int sig);
+#endif
+
+static volatile int sigHupNotifier = 0;
+static volatile int sigUsr2Notifier = 0;
+static void SigChldHandler(int sig);
+
+static void
+check_lockfile()
+{
+  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+  char lockfile[PATH_NAME_MAX];
+  int err;
+  pid_t holding_pid;
+
+  //////////////////////////////////////
+  // test for presence of server lock //
+  //////////////////////////////////////
+  Layout::relative_to(lockfile, sizeof(lockfile), rundir, SERVER_LOCK);
+  Lockfile server_lockfile(lockfile);
+  err = server_lockfile.Open(&holding_pid);
+  if (err == 1) {
+    server_lockfile.Close();    // no server running
+  } else {
+    char *reason = strerror(-err);
+    if (err == 0) {
+      // TODO: Add PID_FMT_T instead duplicating code just for printing
+#if defined(solaris)
+      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, (int)holding_pid);
+#else
+      fprintf(stderr, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, holding_pid);
+#endif
+      mgmt_elog(stderr, 0, "FATAL: Lockfile '%s' says server already running as PID %d\n", lockfile, holding_pid);
+    } else {
+      fprintf(stderr, "FATAL: Can't open server lockfile '%s' (%s)\n", lockfile, (reason ? reason : "Unknown Reason"));
+      mgmt_elog(stderr, 0, "FATAL: Can't open server lockfile '%s' (%s)\n",
+                lockfile, (reason ? reason : "Unknown Reason"));
+    }
+    exit(1);
+  }
+
+  ///////////////////////////////////////////
+  // try to get the exclusive manager lock //
+  ///////////////////////////////////////////
+  Layout::relative_to(lockfile, sizeof(lockfile), rundir, MANAGER_LOCK);
+  Lockfile manager_lockfile(lockfile);
+  err = manager_lockfile.Get(&holding_pid);
+  if (err != 1) {
+    char *reason = strerror(-err);
+    fprintf(stderr, "FATAL: Can't acquire manager lockfile '%s'", lockfile);
+    mgmt_elog(stderr, 0, "FATAL: Can't acquire manager lockfile '%s'", lockfile);
+    if (err == 0) {
+#if defined(solaris)
+      fprintf(stderr, " (Lock file held by process ID %d)\n", (int)holding_pid);
+#else
+      fprintf(stderr, " (Lock file held by process ID %d)\n", holding_pid);
+#endif
+      mgmt_elog(stderr, 0, " (Lock file held by process ID %d)\n", holding_pid);
+    } else if (reason) {
+      fprintf(stderr, " (%s)\n", reason);
+      mgmt_elog(stderr, 0, " (%s)\n", reason);
+    } else {
+      fprintf(stderr, "\n");
+    }
+    exit(1);
+
+    fprintf(stderr, "unable to acquire manager lock [%d]\n", -err);
+    exit(1);
+  }
+}
+
+static void
+initSignalHandlers()
+{
+  struct sigaction sigHandler, sigChldHandler, sigAlrmHandler;
+  sigset_t sigsToBlock;
+
+  // Set up the signal handler
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigHandler.sa_handler = NULL;
+  sigHandler.sa_sigaction = SignalHandler;
+#else
+  sigHandler.sa_handler = SignalHandler;
+#endif
+  sigemptyset(&sigHandler.sa_mask);
+
+  // We want the handler to remain in place on
+  //  SIGHUP to avoid any races with the signals
+  //  coming too quickly.  Also restart systems calls
+  //  after the signal since not all calls are wrapped
+  //  to check errno for EINTR
+  sigHandler.sa_flags = SA_RESTART;
+  sigaction(SIGHUP, &sigHandler, NULL);
+  sigaction(SIGUSR2, &sigHandler, NULL);
+
+  // Don't block the signal on entry to the signal
+  //   handler so we can reissue it and get a core
+  //   file in the appropriate circumstances
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigHandler.sa_flags = SA_RESETHAND | SA_SIGINFO;
+#else
+  sigHandler.sa_flags = SA_RESETHAND;
+#endif
+  sigaction(SIGINT, &sigHandler, NULL);
+  sigaction(SIGQUIT, &sigHandler, NULL);
+  sigaction(SIGILL, &sigHandler, NULL);
+  sigaction(SIGBUS, &sigHandler, NULL);
+  sigaction(SIGSEGV, &sigHandler, NULL);
+  sigaction(SIGTERM, &sigHandler, NULL);
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigAlrmHandler.sa_handler = NULL;
+  sigAlrmHandler.sa_sigaction = SignalAlrmHandler;
+#else
+  sigAlrmHandler.sa_handler = SignalAlrmHandler;
+#endif
+
+  sigemptyset(&sigAlrmHandler.sa_mask);
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  sigAlrmHandler.sa_flags = SA_SIGINFO;
+#else
+  sigAlrmHandler.sa_flags = 0;
+#endif
+  sigaction(SIGALRM, &sigAlrmHandler, NULL);
+
+  // Block the delivery of any signals we are not catching
+  //
+  //  except for SIGALARM since we use it
+  //    to break out of deadlock on semaphore
+  //    we share with the proxy
+  //
+  sigfillset(&sigsToBlock);
+  sigdelset(&sigsToBlock, SIGHUP);
+  sigdelset(&sigsToBlock, SIGUSR2);
+  sigdelset(&sigsToBlock, SIGINT);
+  sigdelset(&sigsToBlock, SIGQUIT);
+  sigdelset(&sigsToBlock, SIGILL);
+  sigdelset(&sigsToBlock, SIGABRT);
+  sigdelset(&sigsToBlock, SIGBUS);
+  sigdelset(&sigsToBlock, SIGSEGV);
+  sigdelset(&sigsToBlock, SIGTERM);
+  sigdelset(&sigsToBlock, SIGALRM);
+  ink_thread_sigsetmask(SIG_SETMASK, &sigsToBlock, NULL);
+
+  // Set up the SIGCHLD handler so we do not get into
+  //   a problem with Solaris 2.6 and strange waitpid()
+  //   behavior
+  sigChldHandler.sa_handler = SigChldHandler;
+  sigChldHandler.sa_flags = SA_RESTART;
+  sigemptyset(&sigChldHandler.sa_mask);
+  sigaction(SIGCHLD, &sigChldHandler, NULL);
+}
+
+#if defined(linux)
+#include <sys/prctl.h>
+#endif
+static int
+setup_coredump()
+{
+#if defined(linux)
+#ifndef PR_SET_DUMPABLE
+#define PR_SET_DUMPABLE 4       /* Ugly, but we cannot compile with 2.2.x otherwise.
+                                   Should be removed when we compile only on 2.4.x */
+#endif
+  prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+#endif  // linux check
+  return 0;
+}
+
+static void
+init_dirs()
+{
+  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+
+  if (access(Layout::get()->sysconfdir, R_OK) == -1) {
+    mgmt_elog(0, "unable to access() config dir '%s': %d, %s\n", Layout::get()->sysconfdir, errno, strerror(errno));
+    mgmt_elog(0, "please set the 'TS_ROOT' environment variable\n");
+    _exit(1);
+  }
+
+  if (access(rundir, R_OK) == -1) {
+    mgmt_elog(0, "unable to access() local state dir '%s': %d, %s\n", (const char *)rundir, errno, strerror(errno));
+    mgmt_elog(0, "please set 'proxy.config.local_state_dir'\n");
+    _exit(1);
+  }
+}
+
+static void
+chdir_root()
+{
+  const char * prefix = Layout::get()->prefix;
+
+  if (chdir(prefix) < 0) {
+    mgmt_elog(0, "unable to change to root directory \"%s\" [%d '%s']\n", prefix, errno, strerror(errno));
+    mgmt_elog(0, " please set correct path in env variable TS_ROOT \n");
+    exit(1);
+  } else {
+    mgmt_log("[TrafficManager] using root directory '%s'\n", prefix);
+  }
+}
+
+static void
+set_process_limits(int fds_throttle)
+{
+  struct rlimit lim;
+
+  // Set needed rlimits (root)
+  ink_max_out_rlimit(RLIMIT_NOFILE, true, false);
+  ink_max_out_rlimit(RLIMIT_STACK, true, true);
+  ink_max_out_rlimit(RLIMIT_DATA, true, true);
+  ink_max_out_rlimit(RLIMIT_FSIZE, true, false);
+#ifdef RLIMIT_RSS
+  ink_max_out_rlimit(RLIMIT_RSS, true, true);
+#endif
+
+#if defined(linux)
+  float file_max_pct = 0.9;
+  FILE *fd;
+
+  if ((fd = fopen("/proc/sys/fs/file-max","r"))) {
+    ATS_UNUSED_RETURN(fscanf(fd, "%lu", &lim.rlim_max));
+    fclose(fd);
+    REC_ReadConfigFloat(file_max_pct, "proxy.config.system.file_max_pct");
+    lim.rlim_cur = lim.rlim_max = static_cast<rlim_t>(lim.rlim_max * file_max_pct);
+    if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
+      fds_limit = (int) lim.rlim_cur;
+      syslog(LOG_NOTICE, "NOTE: RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
+    } else {
+      syslog(LOG_NOTICE, "NOTE: Unable to set RLIMIT_NOFILE(%d):cur(%d),max(%d)", RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
+    }
+  } else {
+    syslog(LOG_NOTICE, "NOTE: Unable to open /proc/sys/fs/file-max");
+  }
+#endif // linux
+
+  if (!getrlimit(RLIMIT_NOFILE, &lim)) {
+    if (fds_throttle > (int) (lim.rlim_cur + FD_THROTTLE_HEADROOM)) {
+      lim.rlim_cur = (lim.rlim_max = (rlim_t) fds_throttle);
+      if (!setrlimit(RLIMIT_NOFILE, &lim) && !getrlimit(RLIMIT_NOFILE, &lim)) {
+        fds_limit = (int) lim.rlim_cur;
+	syslog(LOG_NOTICE, "NOTE: RLIMIT_NOFILE(%d):cur(%d),max(%d)",RLIMIT_NOFILE, (int)lim.rlim_cur, (int)lim.rlim_max);
+      }
+    }
+  }
+
+}
+
+#if TS_HAS_WCCP
+static void
+Errata_Logger(ts::Errata const& err) {
+  size_t n;
+  static size_t const SIZE = 4096;
+  char buff[SIZE];
+  if (err.size()) {
+    ts::Errata::Code code = err.top().getCode();
+    n = err.write(buff, SIZE, 1, 0, 2, "> ");
+    // strip trailing newlines.
+    while (n && (buff[n-1] == '\n' || buff[n-1] == '\r'))
+      buff[--n] = 0;
+    // log it.
+    if (code > 1) mgmt_elog(0, "[WCCP]%s", buff);
+    else if (code > 0) mgmt_log("[WCCP]%s", buff);
+    else Debug("WCCP", "%s", buff);
+  }
+}
+
+static void
+Init_Errata_Logging() {
+  ts::Errata::registerSink(&Errata_Logger);
+}
+#endif
+
+int
+main(int argc, char **argv)
+{
+  // Before accessing file system initialize Layout engine
+  Layout::create();
+  ink_strlcpy(mgmt_path, Layout::get()->sysconfdir, sizeof(mgmt_path));
+
+  // change the directory to the "root" directory
+  chdir_root();
+
+  // Line buffer standard output & standard error
+  int status;
+  status = setvbuf(stdout, NULL, _IOLBF, 0);
+  if (status != 0)
+    perror("WARNING: can't line buffer stdout");
+  status = setvbuf(stderr, NULL, _IOLBF, 0);
+  if (status != 0)
+    perror("WARNING: can't line buffer stderr");
+
+  bool found = false;
+  int just_started = 0;
+  int cluster_mcport = -1, cluster_rsport = -1;
+  // TODO: This seems completely incomplete, disabled for now
+  //  int dump_config = 0, dump_process = 0, dump_node = 0, dump_cluster = 0, dump_local = 0;
+  char* proxy_port = 0;
+  int proxy_backdoor = -1;
+  char *envVar = NULL, *group_addr = NULL, *tsArgs = NULL;
+  bool log_to_syslog = true;
+  char userToRunAs[80];
+  int  fds_throttle = -1;
+  time_t ticker;
+  ink_thread webThrId;
+
+  // Set up the application version info
+  appVersionInfo.setup(PACKAGE_NAME,"traffic_manager", PACKAGE_VERSION,
+                       __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
+  initSignalHandlers();
+
+  // Process Environment Variables
+  if ((envVar = getenv("MGMT_ACONF_PORT")) != NULL) {
+    aconf_port_arg = atoi(envVar);
+  }
+
+  if ((envVar = getenv("MGMT_CLUSTER_MC_PORT")) != NULL) {
+    cluster_mcport = atoi(envVar);
+  }
+
+  if ((envVar = getenv("MGMT_CLUSTER_RS_PORT")) != NULL) {
+    cluster_rsport = atoi(envVar);
+  }
+
+  if ((envVar = getenv("MGMT_GROUP_ADDR")) != NULL) {
+    group_addr = envVar;
+  }
+
+  for (int i = 1; i < argc; i++) {      /* Process command line args */
+
+    if (argv[i][0] == '-') {
+      if ((strcmp(argv[i], "-version") == 0) || (strcmp(argv[i], "-V") == 0)) {
+        fprintf(stderr, "%s\n", appVersionInfo.FullVersionInfoStr);
+        exit(0);
+      } else if (strcmp(argv[i], "-proxyOff") == 0) {
+        proxy_on = false;
+      } else if (strcmp(argv[i], "-nosyslog") == 0) {
+        log_to_syslog = false;
+      } else {
+        // The rest of the options require an argument in the form of -<Flag> <val>
+        if ((i + 1) < argc) {
+
+          if (strcmp(argv[i], "-aconfPort") == 0) {
+            ++i;
+            aconf_port_arg = atoi(argv[i]);
+          } else if (strcmp(argv[i], "-clusterMCPort") == 0) {
+            ++i;
+            cluster_mcport = atoi(argv[i]);
+          } else if (strcmp(argv[i], "-groupAddr") == 0) {
+            ++i;
+            group_addr = argv[i];
+          } else if (strcmp(argv[i], "-clusterRSPort") == 0) {
+            ++i;
+            cluster_rsport = atoi(argv[i]);
+#if TS_USE_DIAGS
+          } else if (strcmp(argv[i], "-debug") == 0) {
+            ++i;
+            ink_strlcpy(debug_tags, argv[i], sizeof(debug_tags));
+          } else if (strcmp(argv[i], "-action") == 0) {
+            ++i;
+            ink_strlcpy(action_tags, argv[i], sizeof(debug_tags));
+#endif
+          } else if (strcmp(argv[i], "-path") == 0) {
+            ++i;
+            //bugfixed by YTS Team, yamsat(id-59703)
+            if ((strlen(argv[i]) > PATH_NAME_MAX)) {
+              fprintf(stderr, "\n   Path exceeded the maximum allowed characters.\n");
+              exit(1);
+            }
+
+            ink_strlcpy(mgmt_path, argv[i], sizeof(mgmt_path));
+            /*
+               } else if(strcmp(argv[i], "-lmConf") == 0) {
+               ++i;
+               lm_conf = argv[i];
+             */
+          } else if (strcmp(argv[i], "-recordsConf") == 0) {
+            ++i;
+            recs_conf = argv[i];
+            // TODO: This seems completely incomplete, disabled for now
+#if 0
+          } else if (strcmp(argv[i], "-printRecords") == 0) {
+            ++i;
+            while (i < argc && argv[i][0] != '-') {
+              if (strcasecmp(argv[i], "config") == 0) {
+                dump_config = 1;
+              } else if (strcasecmp(argv[i], "process") == 0) {
+                dump_process = 1;
+              } else if (strcasecmp(argv[i], "node") == 0) {
+                dump_node = 1;
+              } else if (strcasecmp(argv[i], "cluster") == 0) {
+                dump_cluster = 1;
+              } else if (strcasecmp(argv[i], "local") == 0) {
+                dump_local = 1;
+              } else if (strcasecmp(argv[i], "all") == 0) {
+                dump_config = dump_node = dump_process = dump_cluster = dump_local = 1;
+              }
+              ++i;
+            }
+            --i;
+#endif
+          } else if (strcmp(argv[i], "-tsArgs") == 0) {
+            int size_of_args = 0, j = (++i);
+            while (j < argc) {
+              size_of_args += 1;
+              size_of_args += strlen((argv[j++]));
+            }
+            tsArgs = (char *)ats_malloc(size_of_args + 1);
+
+            j = 0;
+            while (i < argc) {
+              snprintf(&tsArgs[j], ((size_of_args + 1) - j), " %s", argv[i]);
+              j += strlen(argv[i]) + 1;
+              ++i;
+            }
+          } else if (strcmp(argv[i], "-proxyPort") == 0) {
+            ++i;
+            proxy_port = argv[i];
+          } else if (strcmp(argv[i], "-proxyBackDoor") == 0) {
+            ++i;
+            proxy_backdoor = atoi(argv[i]);
+          } else {
+            printUsage();
+          }
+        } else {
+          printUsage();
+        }
+      }
+    }
+  }
+
+  // Bootstrap with LOG_DAEMON until we've read our configuration
+  if (log_to_syslog) {
+    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, LOG_DAEMON);
+    mgmt_use_syslog();
+    syslog(LOG_NOTICE, "NOTE: --- Manager Starting ---");
+    syslog(LOG_NOTICE, "NOTE: Manager Version: %s", appVersionInfo.FullVersionInfoStr);
+  }
+
+  // Bootstrap the Diags facility so that we can use it while starting
+  //  up the manager
+  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, false);
+  diags = diagsConfig->diags;
+  diags->prefix_str = "Manager ";
+
+  RecLocalInit();
+  LibRecordsConfigInit();
+  RecordsConfigOverrideFromEnvironment();
+
+  init_dirs();// setup critical directories, needs LibRecords
+
+  // Get the config info we need while we are still root
+  extractConfigInfo(mgmt_path, recs_conf, userToRunAs, &fds_throttle);
+
+  set_process_limits(fds_throttle); // as root
+  runAsUser(userToRunAs);
+  setup_coredump();
+  check_lockfile();
+
+  url_init();
+  mime_init();
+  http_init();
+
+#if TS_HAS_WCCP
+  Init_Errata_Logging();
+#endif
+  ts_host_res_global_init();
+  ts_session_protocol_well_known_name_indices_init();
+  lmgmt = new LocalManager(proxy_on);
+  RecLocalInitMessage();
+  lmgmt->initAlarm();
+
+  if (diags) {
+    delete diagsConfig;
+    // diagsConfig->reconfigure_diags(); INKqa11968
+    /*
+       delete diags;
+       diags = new Diags(debug_tags,action_tags);
+     */
+  }
+  // INKqa11968: need to set up callbacks and diags data structures
+  // using configuration in records.config
+  diagsConfig = new DiagsConfig(DIAGS_LOG_FILENAME, debug_tags, action_tags, true);
+  diags = diagsConfig->diags;
+  RecSetDiags(diags);
+  diags->prefix_str = "Manager ";
+
+  if (is_debug_tag_set("diags"))
+    diags->dump();
+  diags->cleanup_func = mgmt_cleanup;
+
+  // Setup the exported manager version records.
+  RecSetRecordString("proxy.node.version.manager.short", appVersionInfo.VersionStr);
+  RecSetRecordString("proxy.node.version.manager.long", appVersionInfo.FullVersionInfoStr);
+  RecSetRecordString("proxy.node.version.manager.build_number", appVersionInfo.BldNumStr);
+  RecSetRecordString("proxy.node.version.manager.build_time", appVersionInfo.BldTimeStr);
+  RecSetRecordString("proxy.node.version.manager.build_date", appVersionInfo.BldDateStr);
+  RecSetRecordString("proxy.node.version.manager.build_machine", appVersionInfo.BldMachineStr);
+  RecSetRecordString("proxy.node.version.manager.build_person", appVersionInfo.BldPersonStr);
+//    RecSetRecordString("proxy.node.version.manager.build_compile_flags",
+//                       appVersionInfo.BldCompileFlagsStr);
+
+  if (log_to_syslog) {
+    char sys_var[] = "proxy.config.syslog_facility";
+    char *facility_str = NULL;
+    int facility_int;
+    facility_str = REC_readString(sys_var, &found);
+    ink_assert(found);
+
+    if (!found) {
+      mgmt_elog(0, "Could not read %s.  Defaulting to DAEMON\n", sys_var);
+      facility_int = LOG_DAEMON;
+    } else {
+      facility_int = facility_string_to_int(facility_str);
+      ats_free(facility_str);
+      if (facility_int < 0) {
+        mgmt_elog(0, "Bad syslog facility specified.  Defaulting to DAEMON\n");
+        facility_int = LOG_DAEMON;
+      }
+    }
+
+    // NOTE: do NOT call closelog() here.  Solaris gets confused
+    //   and some how it hoses later calls to readdir_r.
+    openlog("traffic_manager", LOG_PID | LOG_NDELAY | LOG_NOWAIT, facility_int);
+
+    lmgmt->syslog_facility = facility_int;
+  } else {
+    lmgmt->syslog_facility = -1;
+  }
+
+  // Find out our hostname so we can use it as part of the initialization
+  setHostnameVar();
+
+  // Create the data structure for overview page
+  //   Do this before the rest of the set up since it needs
+  //   to created to handle any alarms thrown by later
+  //   initialization
+  overviewGenerator = new overviewPage();
+
+  // Initialize the Config Object bindings before
+  //   starting any other threads
+  lmgmt->configFiles = configFiles = new FileManager();
+  initializeRegistry();
+  configFiles->registerCallback(fileUpdated);
+
+  // RecLocal's 'sync_thr' depends on 'configFiles', so we can't
+  // stat the 'sync_thr' until 'configFiles' has been initialized.
+  RecLocalStart(configFiles);
+
+  /* Update cmd line overrides/environmental overrides/etc */
+  if (tsArgs) {                 /* Passed command line args for proxy */
+    ats_free(lmgmt->proxy_options);
+    lmgmt->proxy_options = tsArgs;
+    mgmt_log(stderr, "[main] Traffic Server Args: '%s'\n", lmgmt->proxy_options);
+  }
+  if (proxy_port) {
+    HttpProxyPort::loadValue(lmgmt->m_proxy_ports, proxy_port);
+  }
+
+  if (proxy_backdoor != -1) {
+    RecSetRecordInt("proxy.config.process_manager.mgmt_port", proxy_backdoor);
+  }
+
+  if (cluster_rsport == -1) {
+    cluster_rsport = REC_readInteger("proxy.config.cluster.rsport", &found);
+    ink_assert(found);
+  }
+
+  if (cluster_mcport == -1) {
+    cluster_mcport = REC_readInteger("proxy.config.cluster.mcport", &found);
+    ink_assert(found);
+  }
+
+  if (!group_addr) {
+    group_addr = REC_readString("proxy.config.cluster.mc_group_addr", &found);
+    ink_assert(found);
+  }
+
+  in_addr_t min_ip = inet_network("224.0.0.255");
+  in_addr_t max_ip = inet_network("239.255.255.255");
+  in_addr_t group_addr_ip = inet_network(group_addr);
+
+  if (!(min_ip < group_addr_ip && group_addr_ip < max_ip)) {
+    mgmt_fatal(0, "[TrafficManager] Multi-Cast group addr '%s' is not in the permitted range of %s\n",
+               group_addr, "224.0.1.0 - 239.255.255.255");
+  }
+
+  /* TODO: Do we really need to init cluster communication? */
+  lmgmt->initCCom(appVersionInfo, configFiles, cluster_mcport, group_addr, cluster_rsport);       /* Setup cluster communication */
+
+  lmgmt->initMgmtProcessServer();       /* Setup p-to-p process server */
+
+  // Now that we know our cluster ip address, add the
+  //   UI record for this machine
+  overviewGenerator->addSelfRecord();
+
+  lmgmt->listenForProxy();
+
+  //
+  // As listenForProxy() may change/restore euid, we should put
+  // the creation of webIntr_main thread after it. So that we
+  // can keep a consistent euid when create mgmtapi/eventapi unix
+  // sockets in webIntr_main thread.
+  //
+  webThrId = ink_thread_create(webIntr_main, NULL);     /* Spin web agent thread */
+  Debug("lm", "Created Web Agent thread (%"  PRId64 ")", (int64_t)webThrId);
+
+  ticker = time(NULL);
+  mgmt_log("[TrafficManager] Setup complete\n");
+
+  statProcessor = new StatProcessor(configFiles);
+
+  for (;;) {
+    lmgmt->processEventQueue();
+    lmgmt->pollMgmtProcessServer();
+
+    // Check for a SIGHUP
+    if (sigHupNotifier != 0) {
+      mgmt_log(stderr, "[main] Reading Configuration Files due to SIGHUP\n");
+      configFiles->rereadConfig();
+      lmgmt->signalEvent(MGMT_EVENT_PLUGIN_CONFIG_UPDATE, "*");
+      sigHupNotifier = 0;
+      mgmt_log(stderr, "[main] Reading Configuration Files Reread\n");
+    }
+    // Check for SIGUSR2
+    if (sigUsr2Notifier != 0) {
+      ink_stack_trace_dump();
+      sigUsr2Notifier = 0;
+    }
+
+    lmgmt->ccom->generateClusterDelta();
+
+    if (lmgmt->run_proxy && lmgmt->processRunning()) {
+      lmgmt->ccom->sendSharedData();
+      lmgmt->virt_map->lt_runGambit();
+    } else {
+      if (!lmgmt->run_proxy) {  /* Down if we are not going to start another immed. */
+        /* Proxy is not up, so no addrs should be */
+        lmgmt->virt_map->downOurAddrs();
+      }
+
+      /* Proxy is not up, but we should still exchange config and alarm info */
+      lmgmt->ccom->sendSharedData(false);
+    }
+
+    lmgmt->ccom->checkPeers(&ticker);
+    overviewGenerator->checkForUpdates();
+
+    if (statProcessor) {
+      statProcessor->processStat();
+    }
+
+    if (lmgmt->mgmt_shutdown_outstanding == true) {
+      lmgmt->mgmtShutdown(true);
+      _exit(0);
+    }
+
+    if (lmgmt->run_proxy && !lmgmt->processRunning()) { /* Make sure we still have a proxy up */
+      if (lmgmt->startProxy())
+        just_started = 0;
+      else
+        just_started++;
+    } else {                    /* Give the proxy a chance to fire up */
+      just_started++;
+    }
+
+    /* This will catch the case were the proxy dies before it can connect to manager */
+    if (lmgmt->proxy_launch_outstanding && !lmgmt->processRunning() && just_started >= 120) {
+      just_started = 0;
+      lmgmt->proxy_launch_outstanding = false;
+      if (lmgmt->proxy_launch_pid != -1) {
+        int res;
+        kill(lmgmt->proxy_launch_pid, 9);
+        waitpid(lmgmt->proxy_launch_pid, &res, 0);
+        if (WIFSIGNALED(res)) {
+          int sig = WTERMSIG(res);
+#ifdef NEED_PSIGNAL
+          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d\n", sig);
+#else
+          mgmt_log(stderr, "[main] Proxy terminated due to Sig %d: %s\n", sig, strsignal(sig));
+#endif /* NEED_PSIGNAL */
+        }
+      }
+      mgmt_log(stderr, "[main] Proxy launch failed, retrying...\n");
+    }
+
+  }
+
+  if (statProcessor) {
+    delete(statProcessor);
+  }
+
+#ifndef MGMT_SERVICE
+  return 0;
+#endif
+
+}                               /* End main */
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+static void
+SignalAlrmHandler(int /* sig ATS_UNUSED */, siginfo_t * t, void * /* c ATS_UNUSED */)
+#else
+static void
+SignalAlrmHandler(int /* sig ATS_UNUSED */)
+#endif
+{
+  /*
+     fprintf(stderr, "[TrafficManager] ==> SIGALRM received\n");
+     mgmt_elog(stderr, 0, "[TrafficManager] ==> SIGALRM received\n");
+   */
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  if (t) {
+    if (t->si_code <= 0) {
+#if defined(solaris)
+      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", (int)t->si_pid, t->si_uid);
+#else
+      fprintf(stderr, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", t->si_pid, t->si_uid);
+#endif
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Alarm from pid: %d uid: %d\n", t->si_pid, t->si_uid);
+    } else {
+      fprintf(stderr, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", t->si_code);
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Alarm Reason: %d\n", t->si_code);
+    }
+  }
+#endif
+
+  return;
+}
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+static void
+SignalHandler(int sig, siginfo_t * t, void *c)
+#else
+static void
+SignalHandler(int sig)
+#endif
+{
+  static int clean = 0;
+  int status;
+
+#if !defined(linux) && !defined(freebsd) && !defined(darwin)
+  if (t) {
+    if (t->si_code <= 0) {
+#if defined(solaris)
+      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, (int)t->si_pid, t->si_uid);
+#else
+      fprintf(stderr, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, t->si_pid, t->si_uid);
+#endif
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> User Sig %d from pid: %d uid: %d\n", sig, t->si_pid, t->si_uid);
+    } else {
+      fprintf(stderr, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", sig, t->si_code);
+      mgmt_elog(stderr, 0, "[TrafficManager] ==> Kernel Sig %d; Reason: %d\n", sig, t->si_code);
+    }
+  }
+#endif
+
+  if (sig == SIGHUP) {
+    sigHupNotifier = 1;
+    return;
+  }
+
+  if (sig == SIGUSR2) {
+    sigUsr2Notifier = 1;
+    return;
+  }
+  fprintf(stderr, "[TrafficManager] ==> Cleaning up and reissuing signal #%d\n", sig);
+  mgmt_elog(stderr, 0, "[TrafficManager] ==> Cleaning up and reissuing signal #%d\n", sig);
+
+  if (lmgmt && !clean) {
+    clean = 1;
+    if (lmgmt->watched_process_pid != -1) {
+
+      if (sig == SIGTERM || sig == SIGINT) {
+        kill(lmgmt->watched_process_pid, sig);
+        waitpid(lmgmt->watched_process_pid, &status, 0);
+      }
+    }
+    lmgmt->mgmtCleanup();
+  }
+
+  switch (sig) {
+  case SIGQUIT:
+  case SIGILL:
+  case SIGTRAP:
+#if !defined(linux)
+  case SIGEMT:
+  case SIGSYS:
+#endif
+  case SIGFPE:
+  case SIGBUS:
+  case SIGSEGV:
+  case SIGXCPU:
+  case SIGXFSZ:
+    abort();
+  default:
+    fprintf(stderr, "[TrafficManager] ==> signal #%d\n", sig);
+    mgmt_elog(stderr, 0, "[TrafficManager] ==> signal #%d\n", sig);
+    _exit(sig);
+  }
+  fprintf(stderr, "[TrafficManager] ==> signal2 #%d\n", sig);
+  mgmt_elog(stderr, 0, "[TrafficManager] ==> signal2 #%d\n", sig);
+  _exit(sig);
+}                               /* End SignalHandler */
+
+// void SigChldHandler(int sig)
+//
+//   An empty handler needed so that we catch SIGCHLD
+//    With Solaris 2.6, ignoring sig child changes the behavior
+//    of waitpid() so that if there are no unwaited children,
+//    waitpid() blocks until all child are transformed into
+//    zombies which is bad for us
+//
+static void
+SigChldHandler(int /* sig ATS_UNUSED */)
+{
+}
+
+void
+printUsage()
+{
+  fprintf(stderr, "----------------------------------------------------------------------------\n");
+  fprintf(stderr, " Traffic Manager Usage: (all args are optional)\n");
+  fprintf(stderr, "\n");
+  fprintf(stderr, "   traffic_manager [options]\n");
+  fprintf(stderr, "     -proxyPort     <port>  Port to have proxy listen on, overrides records.config.\n");
+  /* Function is currently #ifdef'ed out so no reason to advertise
+     fprintf(stderr,
+     "     -proxyBackdoor <port>  Port to put proxy mgmt port on.\n");
+   */
+  /* Commented out because this option is used for debugging only.
+     fprintf(stderr,
+     "     -noProxy               Do not launch the proxy process.\n");
+   */
+  fprintf(stderr, "     -tsArgs        [...]   Args to proxy, everything till eol is passed.\n");
+  fprintf(stderr, "     -webPort       <port>  Port for web interface.\n");
+  /*
+     fprintf(stderr,
+     "     -graphPort     <port>  Port for dynamic graphs.\n");
+   */
+  fprintf(stderr, "     -clusterPort   <port>  Cluster Multicast port\n");
+  fprintf(stderr, "     -groupAddr     <addr>  Cluster Multicast group, example: \"225.0.0.37\".\n");
+  fprintf(stderr, "     -clusterRSPort <port>  Cluster Multicast port.\n");
+  fprintf(stderr, "     -path          <path>  Root path for config files.\n");
+  /*
+     fprintf(stderr,
+     "     -lmConf        <fname> Local Management config file.\n");
+   */
+  fprintf(stderr, "     -recordsConf   <fname> General config file.\n");
+  // TODO: This seems completely incomplete, disabled for now
+  // fprintf(stderr, "     -printRecords  [...]   Print flags, default all are off.\n");
+  fprintf(stderr, "     -debug         <tags>  Enable the given debug tags\n");
+  fprintf(stderr, "     -action        <tags>  Enable the given action tags.\n");
+  fprintf(stderr, "     -version or -V         Print version id and exit.\n");
+  fprintf(stderr, "\n");
+  fprintf(stderr, "   [...] can be one+ of: [config process node cluster local all]\n");
+  fprintf(stderr, "----------------------------------------------------------------------------\n");
+  exit(0);
+}                               /* End printUsage */
+
+void
+fileUpdated(char *fname, bool incVersion)
+{
+  if (strcmp(fname, "cluster.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cluster.cluster_configuration");
+
+  } else if (strcmp(fname, "remap.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.url_remap.filename");
+
+  } else if (strcmp(fname, "socks.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.socks.socks_config_file");
+
+  } else if (strcmp(fname, "records.config") == 0) {
+    lmgmt->signalFileChange("records.config", incVersion);
+
+  } else if (strcmp(fname, "cache.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cache.control.filename");
+
+  } else if (strcmp(fname, "parent.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.http.parent_proxy.file");
+
+  } else if (strcmp(fname, "ip_allow.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cache.ip_allow.filename");
+  } else if (strcmp(fname, "vaddrs.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] vaddrs.config updated\n");
+    lmgmt->virt_map->lt_readAListFile(fname);
+
+  } else if (strcmp(fname, "storage.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] storage.config changed, need restart auto-rebuild mode\n");
+
+  } else if (strcmp(fname, "proxy.pac") == 0) {
+    mgmt_log(stderr, "[fileUpdated] proxy.pac file has been modified\n");
+
+  } else if (strcmp(fname, "icp.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.icp.icp_configuration");
+
+  } else if (strcmp(fname, "update.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.update.update_configuration");
+
+  } else if (strcmp(fname, "volume.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] volume.config changed, need restart\n");
+
+  } else if (strcmp(fname, "hosting.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.cache.hosting_filename");
+
+  } else if (strcmp(fname, "log_hosts.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.log.hosts_config_file");
+
+  } else if (strcmp(fname, "logs_xml.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.log.xml_config_file");
+
+  } else if (strcmp(fname, "splitdns.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.dns.splitdns.filename");
+
+  } else if (strcmp(fname, "plugin.config") == 0) {
+    mgmt_log(stderr, "[fileUpdated] plugin.config file has been modified\n");
+
+  } else if (strcmp(fname, "ssl_multicert.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.ssl.server.multicert.filename");
+
+  } else if (strcmp(fname, "proxy.config.body_factory.template_sets_dir") == 0) {
+    lmgmt->signalFileChange("proxy.config.body_factory.template_sets_dir");
+
+  } else if (strcmp(fname, "stats.config.xml") == 0) {
+    if (statProcessor) {
+      statProcessor->rereadConfig(configFiles);
+    }
+    mgmt_log(stderr, "[fileUpdated] stats.config.xml file has been modified\n");
+  } else if (strcmp(fname, "congestion.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.http.congestion_control.filename");
+  } else if (strcmp(fname, "prefetch.config") == 0) {
+    lmgmt->signalFileChange("proxy.config.prefetch.config_file");
+  } else {
+    mgmt_elog(stderr, 0, "[fileUpdated] Unknown config file updated '%s'\n", fname);
+
+  }
+  return;
+}                               /* End fileUpdate */
+
+#if TS_USE_POSIX_CAP
+/** Restore capabilities after user id change.
+    This manipulates LINUX capabilities so that this process
+    can perform certain privileged operations even if it is
+    no longer running as a privilege user.
+
+    @internal
+    I tried using
+    @code
+    prctl(PR_SET_KEEPCAPS, 1);
+    @endcode
+    but that had no effect even though the call reported success.
+    Only explicit capability manipulation was effective.
+
+    It does not appear to be necessary to set the capabilities on the
+    executable if originally run as root. That may be needed if
+    started as a user without that capability.
+ */
+
+int
+restoreCapabilities() {
+  int zret = 0; // return value.
+  cap_t cap_set = cap_get_proc(); // current capabilities
+  // Make a list of the capabilities we want turned on.
+  cap_value_t cap_list[] = {
+    CAP_NET_ADMIN, ///< Set socket transparency.
+    CAP_NET_BIND_SERVICE, ///< Low port (e.g. 80) binding.
+    CAP_IPC_LOCK ///< Lock IPC objects.
+  };
+  static int const CAP_COUNT = sizeof(cap_list)/sizeof(*cap_list);
+
+  cap_set_flag(cap_set, CAP_EFFECTIVE, CAP_COUNT, cap_list, CAP_SET);
+  zret = cap_set_proc(cap_set);
+  cap_free(cap_set);
+  return zret;
+}
+#endif
+
+//  void runAsUser(...)
+//
+//  If we are root, switched to user to run as
+//    specified in records.config
+//
+//  If we are not root, do nothing
+//
+void
+runAsUser(char *userName)
+{
+  uid_t uid, euid;
+  struct passwd *result;
+  const int bufSize = 1024;
+  char buf[bufSize];
+
+  uid = getuid();
+  euid = geteuid();
+
+  if (uid == 0 || euid == 0) {
+
+    /* Figure out what user we should run as */
+
+    Debug("lm", "[runAsUser] Attempting to run as user '%s'\n", userName);
+
+    if (userName == NULL || userName[0] == '\0') {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: proxy.config.admin.user_id is not set\n");
+      _exit(1);
+    }
+
+    struct passwd passwdInfo;
+    struct passwd *ppasswd = NULL;
+    result = NULL;
+    int res;
+    if (*userName == '#') {
+      int uuid = atoi(userName + 1);
+      if (uuid == -1)
+        uuid = (int)uid;
+      res = getpwuid_r((uid_t)uuid, &passwdInfo, buf, bufSize, &ppasswd);
+    }
+    else {
+      res = getpwnam_r(&userName[0], &passwdInfo, buf, bufSize, &ppasswd);
+    }
+
+    if (!res && ppasswd) {
+      result = ppasswd;
+    }
+
+    if (result == NULL) {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to get info about user %s : %s\n", userName, strerror(errno));
+      _exit(1);
+    }
+
+    if (setegid(result->pw_gid) != 0 || seteuid(result->pw_uid) != 0) {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Unable to switch to user %s : %s\n", userName, strerror(errno));
+      _exit(1);
+    }
+
+    uid = getuid();
+    euid = geteuid();
+
+    Debug("lm", "[runAsUser] Running with uid: '%d' euid: '%d'\n", uid, euid);
+
+    if (uid != result->pw_uid && euid != result->pw_uid) {
+      mgmt_elog(stderr, 0, "[runAsUser] Fatal Error: Failed to switch to user %s\n", userName);
+      _exit(1);
+    }
+
+    // setup supplementary groups if it is not set.
+    if (0 == getgroups(0, NULL)) {
+      initgroups(&userName[0],result->pw_gid);
+    }
+
+#if TS_USE_POSIX_CAP
+    if (0 != restoreCapabilities()) {
+      mgmt_elog(stderr, 0, "[runAsUser] Error: Failed to restore capabilities after switch to user %s.\n", userName);
+    }
+#endif
+
+  }
+}                               /* End runAsUser() */
+
+//  void extractConfigInfo(...)
+//
+//  We need to get certain records.config values while we are
+//   root.  We can not use LMRecords to get them because the constructor
+//   for LMRecords creates the mgmt DBM and we do not want that to
+//   be owned as root.  This function extracts that info from
+//   records.config
+//
+//
+void
+extractConfigInfo(char *mgmt_path, const char *recs_conf, char *userName, int *fds_throttle)
+{
+  char file[1024];
+  bool useridFound = false;
+  bool throttleFound = false;
+
+  /* Figure out what user we should run as */
+  if (mgmt_path && recs_conf) {
+    FILE *fin;
+    snprintf(file, sizeof(file), "%s/%s.shadow", mgmt_path, recs_conf);
+    if (!(fin = fopen(file, "r"))) {
+      ink_filepath_make(file, sizeof(file), mgmt_path, recs_conf);
+      if (!(fin = fopen(file, "r"))) {
+        mgmt_elog(stderr, errno, "[extractConfigInfo] Unable to open config file(%s)\n", file);
+        _exit(1);
+      }
+    }
+    // Get 'user id' and 'network connections throttle limit'
+    while (((!useridFound) || (!throttleFound)) && fgets(file, 1024, fin)) {
+      if (strstr(file, "CONFIG proxy.config.admin.user_id STRING")) {
+        //coverity[secure_coding]
+        if ((sscanf(file, "CONFIG proxy.config.admin.user_id STRING %1023s\n", userName) == 1) &&
+            strcmp(userName, "NULL") != 0) {
+          useridFound = true;
+        }
+      } else if (strstr(file, "CONFIG proxy.config.net.connections_throttle INT")) {
+        if ((sscanf(file, "CONFIG proxy.config.net.connections_throttle INT %d\n", fds_throttle) == 1)) {
+          throttleFound = true;
+        }
+      }
+
+    }
+    fclose(fin);
+  } else {
+    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: unable to access records file\n");
+    _exit(1);
+  }
+
+  if (useridFound == false) {
+    mgmt_elog(stderr, 0, "[extractConfigInfo] Fatal Error: proxy.config.admin.user_id is not set\n");
+    _exit(1);
+  }
+
+}                               /* End extractConfigInfo() */

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/cmd/traffic_manager/Main.h
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Main.h b/cmd/traffic_manager/Main.h
new file mode 100644
index 0000000..ec37226
--- /dev/null
+++ b/cmd/traffic_manager/Main.h
@@ -0,0 +1,53 @@
+/** @file
+
+  A brief file description
+
+  @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.
+ */
+
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+#include "FileManager.h"
+#include "I_Version.h"
+
+// TODO: consolidate location of these defaults
+#define DEFAULT_ROOT_DIRECTORY            PREFIX
+#define DEFAULT_LOCAL_STATE_DIRECTORY     "var/trafficserver"
+#define DEFAULT_SYSTEM_CONFIG_DIRECTORY   "etc/trafficserver"
+#define DEFAULT_LOG_DIRECTORY             "var/log/trafficserver"
+
+void MgmtShutdown(int status);
+void fileUpdated(char *fname, bool incVersion);
+void runAsUser(char *userName);
+void printUsage(void);
+
+extern FileManager *configFiles;
+//extern overviewPage *overviewGenerator;
+extern AppVersionInfo appVersionInfo;
+
+// Global strings
+extern char mgmt_path[];
+
+// Global variable to replace ifdef MGMT_LAUNCH_PROXY so that
+// we can turn on/off proxy launch at runtime to facilitate
+// manager only testing.
+extern bool mgmt_launch_proxy;
+
+#endif /* _MAIN_H_ */

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/cmd/traffic_manager/Makefile.am
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Makefile.am b/cmd/traffic_manager/Makefile.am
new file mode 100644
index 0000000..3b65181
--- /dev/null
+++ b/cmd/traffic_manager/Makefile.am
@@ -0,0 +1,67 @@
+#
+#  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.
+
+bin_PROGRAMS = traffic_manager
+
+AM_CPPFLAGS = \
+  $(iocore_include_dirs) \
+  -I$(top_srcdir)/lib/records \
+  -I$(top_srcdir)/lib/ts \
+  -I$(top_srcdir)/proxy \
+  -I$(top_srcdir)/proxy/hdrs \
+  -I$(top_srcdir)/proxy/shared \
+  -I$(top_srcdir)/mgmt \
+  -I$(top_srcdir)/mgmt/api/include \
+  -I$(top_srcdir)/mgmt/cluster \
+  -I$(top_srcdir)/mgmt/stats \
+  -I$(top_srcdir)/mgmt/utils \
+  -I$(top_srcdir)/mgmt/web2 \
+  -I$(top_srcdir)/lib \
+  -I$(top_builddir)/lib
+#
+traffic_manager_SOURCES = \
+  AddConfigFilesHere.cc \
+  Main.cc \
+  Main.h
+
+traffic_manager_LDFLAGS = @EXTRA_CXX_LDFLAGS@ @EXPAT_LDFLAGS@ @LIBTOOL_LINK_FLAGS@
+traffic_manager_LDADD = \
+  $(top_builddir)/mgmt/libmgmt_lm.a \
+  $(top_builddir)/mgmt/cluster/libcluster.a \
+  $(top_builddir)/mgmt/stats/libstats.a \
+  $(top_builddir)/mgmt/web2/libweb.a \
+  $(top_builddir)/mgmt/api/libmgmtapilocal.a \
+  $(top_builddir)/mgmt/api/libtsmgmtshare.la \
+  $(top_builddir)/mgmt/utils/libutils_lm.a \
+  $(top_builddir)/proxy/hdrs/libhdrs.a \
+  $(top_builddir)/lib/records/libreclocal.a \
+  $(top_builddir)/lib/ts/libtsutil.la \
+  $(top_builddir)/iocore/eventsystem/libinkevent.a \
+  $(top_builddir)/proxy/shared/liberror.a \
+  $(top_builddir)/proxy/shared/libdiagsconfig.a \
+  @LIBRESOLV@ @LIBEXPAT@ @LIBPCRE@ @LIBTCL@ @LIBCAP@ @HWLOC_LIBS@ \
+  -lm
+
+# Must do it this way or the dependencies aren't detected.
+if BUILD_WCCP
+traffic_manager_LDADD += \
+  $(top_builddir)/lib/wccp/libwccp.a \
+  $(top_builddir)/lib/tsconfig/libtsconfig.la
+endif
+
+traffic_manager_LDADD += @OPENSSL_LIBS@
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 75ca84b..192b967 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1863,6 +1863,7 @@ AC_CONFIG_FILES([
   cmd/Makefile
   cmd/traffic_cop/Makefile
   cmd/traffic_line/Makefile
+  cmd/traffic_manager/Makefile
   cmd/traffic_top/Makefile
   doc/Doxyfile
   doc/Makefile

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/lib/records/I_RecLocal.h
----------------------------------------------------------------------
diff --git a/lib/records/I_RecLocal.h b/lib/records/I_RecLocal.h
index 89c2313..8af8c33 100644
--- a/lib/records/I_RecLocal.h
+++ b/lib/records/I_RecLocal.h
@@ -26,12 +26,14 @@
 
 #include "I_RecCore.h"
 
+class FileManager;
+
 //-------------------------------------------------------------------------
 // Initialization
 //-------------------------------------------------------------------------
 
 int RecLocalInit(Diags * diags = NULL);
 int RecLocalInitMessage();
-int RecLocalStart();
+int RecLocalStart(FileManager *);
 
 #endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/lib/records/RecLocal.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecLocal.cc b/lib/records/RecLocal.cc
index 9dab6b1..f3ab11a 100644
--- a/lib/records/RecLocal.cc
+++ b/lib/records/RecLocal.cc
@@ -30,6 +30,7 @@
 #include "P_RecUtils.h"
 #include "P_RecFile.h"
 #include "LocalManager.h"
+#include "FileManager.h"
 
 static bool g_initialized = false;
 static bool g_message_initialized = false;
@@ -56,20 +57,14 @@ i_am_the_record_owner(RecT rec_type)
 }
 
 //-------------------------------------------------------------------------
-//
-// REC_BUILD_MGMT IMPLEMENTATION
-//
-//-------------------------------------------------------------------------
-#include "Main.h"
-
-
-//-------------------------------------------------------------------------
 // sync_thr
 //-------------------------------------------------------------------------
 static void *
-sync_thr(void * /* data */)
+sync_thr(void * data)
 {
   textBuffer *tb = new textBuffer(65536);
+  FileManager * configFiles = (FileManager *)data;
+
   Rollback *rb;
   bool inc_version;
   bool written;
@@ -177,9 +172,9 @@ RecLocalInitMessage()
 // RecLocalStart
 //-------------------------------------------------------------------------
 int
-RecLocalStart()
+RecLocalStart(FileManager * configFiles)
 {
-  ink_thread_create(sync_thr, NULL);
+  ink_thread_create(sync_thr, configFiles);
   ink_thread_create(config_update_thr, NULL);
 
   return REC_ERR_OKAY;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/AddConfigFilesHere.cc
----------------------------------------------------------------------
diff --git a/mgmt/AddConfigFilesHere.cc b/mgmt/AddConfigFilesHere.cc
deleted file mode 100644
index cc6d169..0000000
--- a/mgmt/AddConfigFilesHere.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-#include "ink_platform.h"
-#include "Main.h"
-#include "MgmtUtils.h"
-#include "ConfigParse.h"
-#include "Diags.h"
-
-/****************************************************************************
- *
- *  AddConfigFilesHere.cc - Structs for config files and
- *
- *
- ****************************************************************************/
-
-void
-testcall(char *foo, bool /* incVersion */)
-{
-  Debug("lm", "Received Callback that %s has changed\n", foo);
-}
-
-
-//
-// initializeRegistry()
-//
-// Code to initialze of registry of objects that represent
-//   Web Editable configuration files
-//
-// thread-safe: NO!  - Should only be executed once from the main
-//                     web interface thread, before any child
-//                     threads have been spawned
-void
-initializeRegistry()
-{
-  static int run_already = 0;
-
-  if (run_already == 0) {
-    run_already = 1;
-  } else {
-    ink_assert(!"Configuration Object Registry Initialized More than Once");
-  }
-
-  // NOTE: Logic that controls which files are not sync'd around the
-  // cluster is located in ClusterCom::constructSharedFilePacket
-
-  configFiles->addFile("log_hosts.config", false);
-  configFiles->addFile("logs_xml.config", false);
-  configFiles->addFile("storage.config", false);
-  configFiles->addFile("socks.config", false);
-  configFiles->addFile("proxy.pac", false);
-  configFiles->addFile("records.config", false);
-  configFiles->addFile("vaddrs.config", false);
-  configFiles->addFile("cache.config", false);
-  configFiles->addFile("icp.config", false);
-  configFiles->addFile("ip_allow.config", false);
-  configFiles->addFile("parent.config", false);
-  configFiles->addFile("remap.config", false);
-  configFiles->addFile("update.config", false);
-  configFiles->addFile("volume.config", false);
-  configFiles->addFile("hosting.config", false);
-  configFiles->addFile("congestion.config", false);
-  configFiles->addFile("plugin.config", false);
-  configFiles->addFile("splitdns.config", false);
-  configFiles->addFile("ssl_multicert.config", false);
-  configFiles->addFile("stats.config.xml", false);
-  configFiles->addFile("prefetch.config", false);
-  configFiles->registerCallback(testcall);
-}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/Alarms.cc
----------------------------------------------------------------------
diff --git a/mgmt/Alarms.cc b/mgmt/Alarms.cc
index 32df682..b44930f 100644
--- a/mgmt/Alarms.cc
+++ b/mgmt/Alarms.cc
@@ -388,7 +388,7 @@ Alarms::clearUnSeen(char *ip)
  * takes the current list of local alarms and builds an alarm message.
  */
 void
-Alarms::constructAlarmMessage(char *ip, char *message, int max)
+Alarms::constructAlarmMessage(const AppVersionInfo& version, char *ip, char *message, int max)
 {
   int n = 0, bsum = 0;
   char buf[4096];
@@ -399,7 +399,7 @@ Alarms::constructAlarmMessage(char *ip, char *message, int max)
     return;
   }
   // Insert the standard mcast packet header
-  n = ClusterCom::constructSharedPacketHeader(message, ip, max);
+  n = ClusterCom::constructSharedPacketHeader(version, message, ip, max);
 
   ink_mutex_acquire(&mutex);
   if (!((n + (int) strlen("type: alarm\n")) < max)) {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/Alarms.h
----------------------------------------------------------------------
diff --git a/mgmt/Alarms.h b/mgmt/Alarms.h
index f3fc546..640b524 100644
--- a/mgmt/Alarms.h
+++ b/mgmt/Alarms.h
@@ -41,6 +41,7 @@
 #include "ink_hash_table.h"
 #include "ink_mutex.h"
 
+class AppVersionInfo;
 
 /***********************************************************************
  *
@@ -114,7 +115,7 @@ public:
   void signalAlarm(alarm_t t, const char * desc, const char * ip = NULL);
   void resolveAlarm(alarm_t a, char *ip = NULL);
 
-  void constructAlarmMessage(char *ip, char *message, int max);
+  void constructAlarmMessage(const AppVersionInfo& version,  char *ip, char *message, int max);
   void resetSeenFlag(char *ip);
   void clearUnSeen(char *ip);
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/FileManager.cc
----------------------------------------------------------------------
diff --git a/mgmt/FileManager.cc b/mgmt/FileManager.cc
index fbdb688..5daf441 100644
--- a/mgmt/FileManager.cc
+++ b/mgmt/FileManager.cc
@@ -152,6 +152,7 @@ FileManager::addFile(const char *baseFileName, bool root_access_needed)
   fileBinding *newBind = new fileBinding;
 
   newBind->rb = new Rollback(baseFileName, root_access_needed);
+  newBind->rb->configFiles = this;
 
   ink_mutex_acquire(&accessLock);
   ink_hash_table_insert(bindings, baseFileName, newBind);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/LocalManager.cc
----------------------------------------------------------------------
diff --git a/mgmt/LocalManager.cc b/mgmt/LocalManager.cc
index 169396d..d6930e1 100644
--- a/mgmt/LocalManager.cc
+++ b/mgmt/LocalManager.cc
@@ -30,6 +30,7 @@
 #include "LocalManager.h"
 #include "MgmtSocket.h"
 #include "ink_cap.h"
+#include "FileManager.h"
 
 #if TS_USE_POSIX_CAP
 #include <sys/capability.h>
@@ -196,7 +197,7 @@ LocalManager::processRunning()
 }
 
 LocalManager::LocalManager(bool proxy_on)
-  : BaseManager(), run_proxy(proxy_on)
+  : BaseManager(), run_proxy(proxy_on), configFiles(NULL)
 {
   bool found;
   ats_scoped_str rundir(RecConfigReadRuntimeDir());
@@ -300,7 +301,7 @@ LocalManager::initAlarm()
  *   Function initializes cluster communication structure held by local manager.
  */
 void
-LocalManager::initCCom(int mcport, char *addr, int rsport)
+LocalManager::initCCom(const AppVersionInfo& version, FileManager * configFiles, int mcport, char *addr, int rsport)
 {
   ats_scoped_str rundir(RecConfigReadRuntimeDir());
   bool found;
@@ -350,6 +351,12 @@ LocalManager::initCCom(int mcport, char *addr, int rsport)
 
   ccom = new ClusterCom(ats_ip4_addr_cast(&cluster_ip), hostname, mcport, addr, rsport, rundir);
   virt_map = new VMap(intrName, ats_ip4_addr_cast(&cluster_ip), &lmgmt->ccom->mutex);
+
+  ccom->appVersionInfo = version;
+  ccom->configFiles = configFiles;
+
+  virt_map->appVersionInfo = version;
+
   virt_map->downAddrs();        // Just to be safe
   ccom->establishChannels();
   ats_free(intrName);
@@ -721,9 +728,8 @@ LocalManager::sendMgmtMsgToProcesses(MgmtMessageHdr * mh)
       mgmt_elog(stderr, 0, "[LocalManager:sendMgmtMsgToProcesses] Unknown file change: '%s'\n", data_raw);
     }
     ink_assert(found);
-    if (!(configFiles->getRollbackObj(fname, &rb)) &&
+    if (!(configFiles && configFiles->getRollbackObj(fname, &rb)) &&
         (strcmp(data_raw, "proxy.config.cluster.cluster_configuration") != 0) &&
-        (strcmp(data_raw, "proxy.config.arm.acl_filename_master") != 0) &&
         (strcmp(data_raw, "proxy.config.body_factory.template_sets_dir") != 0)) {
       mgmt_elog(stderr, 0, "[LocalManager::sendMgmtMsgToProcesses] "
                 "Invalid 'data_raw' for MGMT_EVENT_CONFIG_FILE_UPDATE\n");

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/93f46af2/mgmt/LocalManager.h
----------------------------------------------------------------------
diff --git a/mgmt/LocalManager.h b/mgmt/LocalManager.h
index a92d38f..785cbc0 100644
--- a/mgmt/LocalManager.h
+++ b/mgmt/LocalManager.h
@@ -34,7 +34,6 @@
 #ifndef _LOCAL_MANAGER_H
 #define _LOCAL_MANAGER_H
 
-#include "Main.h"
 #include "Alarms.h"
 #include "BaseManager.h"
 #include "ClusterCom.h"
@@ -44,10 +43,12 @@
 #include <wccp/Wccp.h>
 #endif
 
+class FileManager;
+
 class LocalManager: public BaseManager
 {
 public:
-  LocalManager(bool proxy_on);
+  explicit LocalManager(bool proxy_on);
 
   ~LocalManager()
   {
@@ -62,7 +63,7 @@ public:
   };
 
   void initAlarm();
-  void initCCom(int mcport, char *addr, int rsport);
+  void initCCom(const AppVersionInfo& version, FileManager * files, int mcport, char *addr, int rsport);
   void initMgmtProcessServer();
   void pollMgmtProcessServer();
   void handleMgmtMsgFromProcesses(MgmtMessageHdr * mh);
@@ -133,6 +134,7 @@ public:
 
   Alarms *alarm_keeper;
   VMap *virt_map;
+  FileManager *configFiles;
 
   ClusterCom *ccom;
 
@@ -149,5 +151,4 @@ private:
 
 extern LocalManager *lmgmt;
 
-
 #endif /* _LOCAL_MANAGER_H */


Re: [9/9] git commit: TS-2977: CHANGES

Posted by Igor Galić <i....@brainsware.org>.
\o/ kudos for landing this!

----- Original Message -----
> TS-2977: CHANGES
> 
> 
> Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
> Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/c936bc51
> Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/c936bc51
> Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/c936bc51
> 
> Branch: refs/heads/master
> Commit: c936bc514500173bd2075888062eb8618899947e
> Parents: ab8c0cd
> Author: James Peach <jp...@apache.org>
> Authored: Fri Aug 1 19:58:54 2014 -0700
> Committer: James Peach <jp...@apache.org>
> Committed: Fri Aug 1 19:58:54 2014 -0700
> 
> ----------------------------------------------------------------------
>  CHANGES | 2 ++
>  1 file changed, 2 insertions(+)
> ----------------------------------------------------------------------
> 
> 
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c936bc51/CHANGES
> ----------------------------------------------------------------------
> diff --git a/CHANGES b/CHANGES
> index 02b7f60..68141cc 100644
> --- a/CHANGES
> +++ b/CHANGES
> @@ -1,6 +1,8 @@
>                                                           -*- coding: utf-8
>                                                           -*-
>  Changes with Apache Traffic Server 5.1.0
>  
> +  *) [TS-2977] Move traffic_manager under the cmd subdirectory.
> +
>    *) [TS-2971] Authproxy plugin has inconsistent debug symbol.
>  
>    *) [TS-2976] Perform some librecords build cleanup.
> 
> 

-- 
Igor Galić

Tel: +43 (0) 664 886 22 883
Mail: i.galic@brainsware.org
URL: http://brainsware.org/
GPG: 8716 7A9F 989B ABD5 100F  4008 F266 55D6 2998 1641


[9/9] git commit: TS-2977: CHANGES

Posted by jp...@apache.org.
TS-2977: CHANGES


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/c936bc51
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/c936bc51
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/c936bc51

Branch: refs/heads/master
Commit: c936bc514500173bd2075888062eb8618899947e
Parents: ab8c0cd
Author: James Peach <jp...@apache.org>
Authored: Fri Aug 1 19:58:54 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Aug 1 19:58:54 2014 -0700

----------------------------------------------------------------------
 CHANGES | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c936bc51/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 02b7f60..68141cc 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache Traffic Server 5.1.0
 
+  *) [TS-2977] Move traffic_manager under the cmd subdirectory.
+
   *) [TS-2971] Authproxy plugin has inconsistent debug symbol.
 
   *) [TS-2976] Perform some librecords build cleanup.


[7/9] git commit: TS-2977: move the stats processor to traffic_manager

Posted by jp...@apache.org.
TS-2977: move the stats processor to traffic_manager


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/9e6d233f
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/9e6d233f
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/9e6d233f

Branch: refs/heads/master
Commit: 9e6d233fe647863adb7b093cd6643739f73c7c8e
Parents: 7386583
Author: James Peach <jp...@apache.org>
Authored: Thu Jul 31 10:53:44 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Aug 1 19:55:45 2014 -0700

----------------------------------------------------------------------
 cmd/traffic_manager/Makefile.am      |   10 +-
 cmd/traffic_manager/StatProcessor.cc |  359 +++++++++
 cmd/traffic_manager/StatProcessor.h  |   94 +++
 cmd/traffic_manager/StatType.cc      | 1199 +++++++++++++++++++++++++++++
 cmd/traffic_manager/StatType.h       |  231 ++++++
 cmd/traffic_manager/StatXML.cc       |   82 ++
 cmd/traffic_manager/StatXML.h        |   47 ++
 cmd/traffic_manager/stats.txt        |  236 ++++++
 configure.ac                         |    1 -
 mgmt/Makefile.am                     |    2 +-
 mgmt/stats/Makefile.am               |   40 -
 mgmt/stats/StatProcessor.cc          |  359 ---------
 mgmt/stats/StatProcessor.h           |   94 ---
 mgmt/stats/StatType.cc               | 1199 -----------------------------
 mgmt/stats/StatType.h                |  231 ------
 mgmt/stats/StatXML.cc                |   82 --
 mgmt/stats/StatXML.h                 |   47 --
 mgmt/stats/spec                      |  236 ------
 18 files changed, 2256 insertions(+), 2293 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/cmd/traffic_manager/Makefile.am
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Makefile.am b/cmd/traffic_manager/Makefile.am
index 1bb5614..e547f1d 100644
--- a/cmd/traffic_manager/Makefile.am
+++ b/cmd/traffic_manager/Makefile.am
@@ -27,7 +27,6 @@ AM_CPPFLAGS = \
   -I$(top_srcdir)/mgmt \
   -I$(top_srcdir)/mgmt/api/include \
   -I$(top_srcdir)/mgmt/cluster \
-  -I$(top_srcdir)/mgmt/stats \
   -I$(top_srcdir)/mgmt/utils \
   -I$(top_srcdir)/mgmt/web2 \
   -I$(top_srcdir)/lib \
@@ -36,13 +35,18 @@ AM_CPPFLAGS = \
 traffic_manager_SOURCES = \
   AddConfigFilesHere.cc \
   Main.cc \
-  Main.h
+  Main.h \
+  StatProcessor.cc \
+  StatProcessor.h \
+  StatType.cc \
+  StatType.h \
+  StatXML.cc \
+  StatXML.h
 
 traffic_manager_LDFLAGS = @EXTRA_CXX_LDFLAGS@ @EXPAT_LDFLAGS@ @LIBTOOL_LINK_FLAGS@
 traffic_manager_LDADD = \
   $(top_builddir)/mgmt/libmgmt_lm.a \
   $(top_builddir)/mgmt/cluster/libcluster.a \
-  $(top_builddir)/mgmt/stats/libstats.a \
   $(top_builddir)/mgmt/web2/libweb.a \
   $(top_builddir)/mgmt/api/libmgmtapilocal.a \
   $(top_builddir)/mgmt/api/libtsmgmtshare.la \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/cmd/traffic_manager/StatProcessor.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/StatProcessor.cc b/cmd/traffic_manager/StatProcessor.cc
new file mode 100644
index 0000000..24cbaa9
--- /dev/null
+++ b/cmd/traffic_manager/StatProcessor.cc
@@ -0,0 +1,359 @@
+/** @file
+
+  A brief file description
+
+  @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.
+ */
+
+/***************************************/
+/****************************************************************************
+ *
+ *  StatProcessor.cc - Functions for computing node and cluster stat
+ *                          aggregation
+ *
+ *
+ ****************************************************************************/
+
+#include "ink_config.h"
+#include "StatProcessor.h"
+#include "FileManager.h"
+
+#define STAT_CONFIG_FILE "stats.config.xml"
+
+StatObjectList statObjectList;
+StatXMLTag currentTag = INVALID_TAG;
+StatObject *statObject = NULL;
+char *exprContent = NULL;
+static unsigned statCount = 0;  // global statistics object counter
+bool nodeVar;
+bool sumClusterVar;
+
+// These helpers are used to work around the unsigned char'iness of xmlchar when
+// using libxml2. We don't have any tags (now) which uses UTF8.
+static int
+xml_atoi(const xmlchar *nptr)
+{
+  return atoi((const char*)nptr);
+}
+
+static double
+xml_atof(const xmlchar *nptr)
+{
+  return atof((const char*)nptr);
+}
+
+static int
+xml_strcmp(const xmlchar *s1, const char *s2)
+{
+  return strcmp((const char *)s1, s2);
+}
+
+
+static void
+elementStart(void * /* userData ATS_UNUSED */, const xmlchar *name, const xmlchar **atts)
+{
+  int i = 0;
+
+  if (!xml_strcmp(name, "ink:statistics"))
+    currentTag = ROOT_TAG;
+  else if (!xml_strcmp(name, "statistics"))
+    currentTag = STAT_TAG;
+  else if (!xml_strcmp(name, "destination"))
+    currentTag = DST_TAG;
+  else if (!xml_strcmp(name, "expression"))
+    currentTag = EXPR_TAG;
+  else
+    currentTag = INVALID_TAG;
+
+  switch (currentTag) {
+  case STAT_TAG:
+    statObject = new StatObject(++statCount);
+    Debug(MODULE_INIT, "\nStat #: ----------------------- %d -----------------------\n", statCount);
+
+    if (atts)
+     for (i = 0; atts[i]; i += 2) {
+      ink_assert(atts[i + 1]);    // Attribute comes in pairs, hopefully.
+
+      if (!xml_strcmp(atts[i], "minimum")) {
+        statObject->m_stats_min = (MgmtFloat) xml_atof(atts[i + 1]);
+        statObject->m_has_min = true;
+      } else if (!xml_strcmp(atts[i], "maximum")) {
+        statObject->m_stats_max = (MgmtFloat) xml_atof(atts[i + 1]);
+        statObject->m_has_max = true;
+      } else if (!xml_strcmp(atts[i], "interval")) {
+        statObject->m_update_interval = (ink_hrtime) xml_atoi(atts[i + 1]);
+      } else if (!xml_strcmp(atts[i], "debug")) {
+        statObject->m_debug = (atts[i + 1] && atts[i + 1][0] == '1');
+      }
+
+      Debug(MODULE_INIT, "\tDESTINTATION w/ attribute: %s -> %s\n", atts[i], atts[i + 1]);
+    }
+    break;
+
+  case EXPR_TAG:
+    exprContent = (char*)ats_malloc(BUFSIZ * 10);
+    memset(exprContent, 0, BUFSIZ * 10);
+    break;
+
+  case DST_TAG:
+    nodeVar = true;
+    sumClusterVar = true;       // Should only be used with cluster variable
+
+    if (atts)
+     for (i = 0; atts[i]; i += 2) {
+      ink_assert(atts[i + 1]);    // Attribute comes in pairs, hopefully.
+      if (!xml_strcmp(atts[i], "scope")) {
+        nodeVar = (!xml_strcmp(atts[i + 1], "node") ? true : false);
+      } else if (!xml_strcmp(atts[i], "operation")) {
+        sumClusterVar = (!xml_strcmp(atts[i + 1], "sum") ? true : false);
+      }
+
+      Debug(MODULE_INIT, "\tDESTINTATION w/ attribute: %s -> %s\n", atts[i], atts[i + 1]);
+    }
+
+    break;
+
+  case INVALID_TAG:
+    Debug(MODULE_INIT, "==========================================>%s<=\n", name);
+    break;
+
+  default:
+    break;
+  }
+}
+
+
+static void
+elementEnd(void * /* userData ATS_UNUSED */, const xmlchar */* name ATS_UNUSED */)
+{
+  switch (currentTag) {
+  case STAT_TAG:
+    statObjectList.enqueue(statObject);
+    currentTag = ROOT_TAG;
+    break;
+
+  case EXPR_TAG:
+    statObject->assignExpr(exprContent); // This hands over ownership of exprContent
+    // fall through
+
+  default:
+    currentTag = STAT_TAG;
+    break;
+  }
+}
+
+
+static void
+charDataHandler(void * /* userData ATS_UNUSED */, const xmlchar * name, int /* len ATS_UNUSED */)
+{
+  if (currentTag != EXPR_TAG && currentTag != DST_TAG) {
+    return;
+  }
+
+  char content[BUFSIZ * 10];
+  if (XML_extractContent((const char*)name, content, BUFSIZ * 10) == 0) {
+    return;
+  }
+
+  if (currentTag == EXPR_TAG) {
+    ink_strlcat(exprContent, content, BUFSIZ * 10); // see above for the size
+
+  } else {
+    statObject->assignDst(content, nodeVar, sumClusterVar);
+  }
+}
+
+
+StatProcessor::StatProcessor(FileManager * configFiles):m_lmgmt(NULL), m_overviewGenerator(NULL)
+{
+  rereadConfig(configFiles);
+}
+
+
+void
+StatProcessor::rereadConfig(FileManager * configFiles)
+{
+  textBuffer *fileContent = NULL;
+  Rollback *fileRB = NULL;
+  char *fileBuffer = NULL;
+  version_t fileVersion;
+  int fileLen;
+
+  statObjectList.clean();
+  statCount = 0;                // reset statistics counter
+
+  int ret = configFiles->getRollbackObj(STAT_CONFIG_FILE, &fileRB);
+  if (!ret) {
+    Debug(MODULE_INIT, " Can't get Rollback for file: %s\n", STAT_CONFIG_FILE);
+  }
+  fileVersion = fileRB->getCurrentVersion();
+  fileRB->getVersion(fileVersion, &fileContent);
+  fileBuffer = fileContent->bufPtr();
+  fileLen = strlen(fileBuffer);
+
+#if HAVE_LIBEXPAT
+  /*
+   * Start the XML Praser -- the package used is EXPAT
+   */
+  XML_Parser parser = XML_ParserCreate(NULL);
+  XML_SetUserData(parser, NULL);
+  XML_SetElementHandler(parser, elementStart, elementEnd);
+  XML_SetCharacterDataHandler(parser, charDataHandler);
+
+  /*
+   * Substiture every newline with a space to get around
+   * the SetCharacterDataHandler problem.
+   */
+  char *newlinePtr;
+  while ((newlinePtr = strchr(fileBuffer, '\n')) != NULL || (newlinePtr = strchr(fileBuffer, '\r')) != NULL) {
+    *newlinePtr = ' ';
+  }
+
+  /*
+   * Parse the input file according to XML standard.
+   * Print error if we encounter any
+   */
+  int status = XML_Parse(parser, fileBuffer, fileLen, true);
+  if (!status) {
+    mgmt_log(stderr, "%s at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+  }
+
+  /*
+   * Cleaning upt
+   */
+  XML_ParserFree(parser);
+#else
+  /* Parse XML with libxml2 */
+  xmlSAXHandler sax;
+  memset(&sax, 0, sizeof(xmlSAXHandler));
+  sax.startElement = elementStart;
+  sax.endElement = elementEnd;
+  sax.characters = charDataHandler;
+  sax.initialized = 1;
+  xmlParserCtxtPtr parser = xmlCreatePushParserCtxt(&sax, NULL, NULL, 0, NULL);
+
+  int status = xmlParseChunk(parser, fileBuffer, fileLen, 1);
+  if (status != 0) {
+    xmlErrorPtr errptr = xmlCtxtGetLastError(parser);
+    mgmt_log(stderr, "%s at %s:%d\n", errptr->message, errptr->file, errptr->line);
+  }
+  xmlFreeParserCtxt(parser);
+#endif
+
+
+  delete fileContent;
+
+  Debug(MODULE_INIT, "\n\n---------- END OF PARSING & INITIALIZING ---------\n\n");
+}
+
+
+StatProcessor::~StatProcessor()
+{
+
+  Debug(MODULE_INIT, "[StatProcessor] Destructing Statistics Processor\n");
+
+}
+
+
+void
+setTest()
+{
+  char var_name[64];
+
+  for (int i = 1; i <= 5; i++) {
+    memset(var_name, 0, 64);
+    snprintf(var_name, sizeof(var_name), "proxy.node.stats.test%d", i);
+    if (i == 4) {
+      MgmtFloat tmp;
+      varFloatFromName("proxy.node.stats.test4", &tmp);
+      varSetFloat(var_name, tmp + 1, true);
+    } else {
+      varSetFloat(var_name, i, true);
+    }
+  }
+}
+
+
+void
+verifyTest()
+{
+  MgmtFloat tmp1, tmp2;
+
+  // 1. simple copy
+  varFloatFromName("proxy.node.stats.test1", &tmp1);
+  varFloatFromName("proxy.node.stats.test2", &tmp2);
+  if (tmp1 == tmp2) {
+    Debug(MODULE_INIT, "PASS -- simple copy");
+  } else {
+    Debug(MODULE_INIT, "FAIL -- simple copy");
+  }
+
+  // 2. simple interval
+  varFloatFromName("proxy.node.stats.test3", &tmp2);
+  if (tmp2 >= 10) {
+    Debug(MODULE_INIT, "PASS -- simple interval & constant");
+  } else {
+    Debug(MODULE_INIT, "FAIL -- simple interval & constant %f", tmp2);
+  }
+
+  // 3. delta
+  varFloatFromName("proxy.node.stats.test4", &tmp2);
+  if ((tmp2 > 150) && (tmp2 < 250)) {
+    Debug(MODULE_INIT, "PASS -- delta");
+  } else {
+    Debug(MODULE_INIT, "FAIL -- delta %f", tmp2);
+  }
+}
+
+
+/**
+ * Updating the statistics NOW.
+ **/
+unsigned short
+StatProcessor::processStat()
+{
+  unsigned short result = 0;
+
+  Debug(MODULE_INIT, "[StatProcessor] Processing Statistics....\n");
+
+//    setTest();
+  statObjectList.Eval();
+//    verifyTest();
+
+  return (result);
+}
+
+
+/**
+ * ExpressionEval
+ * --------------
+ *
+ */
+RecData
+ExpressionEval(char *exprString)
+{
+  RecDataT result_type;
+  StatObject statObject;
+
+  char content[BUFSIZ * 10];
+  XML_extractContent(exprString, content, BUFSIZ * 10);
+
+  statObject.assignExpr(content);
+  return statObject.NodeStatEval(&result_type, false);
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/cmd/traffic_manager/StatProcessor.h
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/StatProcessor.h b/cmd/traffic_manager/StatProcessor.h
new file mode 100644
index 0000000..71dab2f
--- /dev/null
+++ b/cmd/traffic_manager/StatProcessor.h
@@ -0,0 +1,94 @@
+/** @file
+
+  A brief file description
+
+  @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.
+ */
+
+#ifndef _STAT_PROCESSOR_H_
+#define _STAT_PROCESSOR_H_
+
+/****************************************************************************
+ *
+ *  StatProcessor.h - Functions for computing node and cluster stat
+ *                          aggregation
+ *
+ *
+ ****************************************************************************/
+
+#include "ink_platform.h"
+#include <stdarg.h>
+#include "MgmtUtils.h"
+#include "MgmtDefs.h"
+#include "WebMgmtUtils.h"
+#include "ink_hrtime.h"
+#include "LocalManager.h"
+#include "WebOverview.h"
+
+#define _HEADER
+#define _D(x)
+#define _FOOTER
+#include "DynamicStats.h"
+#include "StatType.h"
+
+#if HAVE_LIBEXPAT
+#include "expat.h"
+typedef XML_Char xmlchar;
+#elif HAVE_LIBXML2
+#include <libxml/parser.h>
+#include <libxml/SAX.h>
+typedef xmlChar xmlchar;
+#else
+# error "No XML parser - please configure expat or libxml2"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+class StatProcessor
+{
+public:
+
+  explicit StatProcessor(FileManager * configFiles);
+  ~StatProcessor();
+
+  // Member Fuctions
+  unsigned short processStat();
+  void rereadConfig(FileManager * configFiles);
+
+  LocalManager *m_lmgmt;
+  overviewPage *m_overviewGenerator;
+};
+
+
+/**
+ * External expression evaluation API.
+ *
+ * INPUT: an expression string, e.g.:
+ * "(proxy.node.user_agent_total_bytes-proxy.node.origin_server_total_bytes)
+ *  / proxy.node.user_agent_total_bytes"
+ *
+ * RETURN: the resulting value of the expression.
+ * NOTE: it returns -9999.0 if there is an error.
+ *
+ */
+
+RecData ExpressionEval(char *);
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/cmd/traffic_manager/StatType.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/StatType.cc b/cmd/traffic_manager/StatType.cc
new file mode 100644
index 0000000..1c51b95
--- /dev/null
+++ b/cmd/traffic_manager/StatType.cc
@@ -0,0 +1,1199 @@
+/** @file
+
+  A brief file description
+
+  @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.
+ */
+
+/***************************************/
+/****************************************************************************
+ *
+ *  StatType.cc - Functions for computing node and cluster stat
+ *                          aggregation
+ *
+ *
+ ****************************************************************************/
+
+#include "ink_config.h"
+#include "StatType.h"
+#include "MgmtUtils.h"
+#include "ink_hrtime.h"
+#include "WebOverview.h"
+
+bool StatError = false;         // global error flag
+bool StatDebug = false;         // global debug flag
+
+/**
+ * StatExprToken()
+ * ---------------
+ */
+StatExprToken::StatExprToken()
+  : m_arith_symbol('\0'),
+    m_token_name(NULL),
+    m_token_type(RECD_NULL),
+    m_sum_var(false), m_node_var(true)
+{
+  RecDataClear(RECD_NULL, &m_token_value);
+  RecDataClear(RECD_NULL, &m_token_value_max);
+  RecDataClear(RECD_NULL, &m_token_value_min);
+  memset(&m_token_value_delta, 0, sizeof(m_token_value_delta));
+}
+
+
+/**
+ * StatExprToken::copy()
+ * ---------------------
+ */
+void
+StatExprToken::copy(const StatExprToken & source)
+{
+  m_arith_symbol = source.m_arith_symbol;
+
+  if (source.m_token_name != NULL) {
+    m_token_name = ats_strdup(source.m_token_name);
+  }
+
+  m_token_type = source.m_token_type;
+  m_token_value = source.m_token_value;
+  m_token_value_min = source.m_token_value_min;
+  m_token_value_max = source.m_token_value_max;
+
+  if (source.m_token_value_delta) {
+    m_token_value_delta = new StatDataSamples();
+    m_token_value_delta->previous_time = source.m_token_value_delta->previous_time;
+    m_token_value_delta->current_time = source.m_token_value_delta->current_time;
+    m_token_value_delta->previous_value = source.m_token_value_delta->previous_value;
+    m_token_value_delta->current_value = source.m_token_value_delta->current_value;
+  }
+
+  m_node_var = source.m_node_var;
+  m_sum_var = source.m_sum_var;
+}
+
+
+/**
+ * StatExprToken::assignTokenName()
+ * --------------------------------
+ *  Assign the token name. If the token is a predefined constant,
+ *  assign the value as well. Also, assign the token type as well.
+ */
+void
+StatExprToken::assignTokenName(const char *name)
+{
+
+  if (isdigit(name[0])) {
+    // numerical constant
+    m_token_name = ats_strdup("CONSTANT");
+    m_token_type = RECD_CONST;
+  } else {
+    m_token_name = ats_strdup(name);
+    assignTokenType();
+  }
+
+  switch (m_token_type) {
+  case RECD_INT:
+  case RECD_COUNTER:
+  case RECD_FLOAT:
+    break;
+  case RECD_CONST:
+    // assign pre-defined constant in here
+    // constant will be stored as RecFloat type.
+    if (!strcmp(m_token_name, "CONSTANT")) {
+      m_token_value.rec_float = (RecFloat) atof(name);
+    } else if (!strcmp(m_token_name, "$BYTES_TO_MB_SCALE")) {
+      m_token_value.rec_float = (RecFloat) BYTES_TO_MB_SCALE;
+    } else if (!strcmp(m_token_name, "$MBIT_TO_KBIT_SCALE")) {
+      m_token_value.rec_float = (RecFloat) MBIT_TO_KBIT_SCALE;
+    } else if (!strcmp(m_token_name, "$SECOND_TO_MILLISECOND_SCALE")) {
+      m_token_value.rec_float = (RecFloat) SECOND_TO_MILLISECOND_SCALE;
+    } else if (!strcmp(m_token_name, "$PCT_TO_INTPCT_SCALE")) {
+      m_token_value.rec_float = (RecFloat) PCT_TO_INTPCT_SCALE;
+    } else if (!strcmp(m_token_name, "$HRTIME_SECOND")) {
+      m_token_value.rec_float = (RecFloat) HRTIME_SECOND;
+    } else if (!strcmp(m_token_name, "$BYTES_TO_MBIT_SCALE")) {
+      m_token_value.rec_float = (RecFloat) BYTES_TO_MBIT_SCALE;
+    } else {
+      mgmt_log(stderr, "[StatPro] ERROR: Undefined constant: %s\n", m_token_name);
+      StatError = true;
+    }
+  case RECD_FX:
+  default:
+    break;
+  }
+}
+
+
+/**
+ * assignTokenType()
+ * -----------------
+ * Assign the proper token type based on the token name.
+ * Do some token type conversion if necessary. Return true
+ * if the token type is recognizable; false otherwise.
+ */
+bool StatExprToken::assignTokenType()
+{
+  ink_assert(m_token_name != NULL);
+  m_token_type = varType(m_token_name);
+
+  if (m_token_name[0] == '$') {
+    m_token_type = RECD_CONST;
+  } else if (m_token_name[0] == '_') {
+    m_token_type = RECD_FX;
+  }
+
+  if (m_token_value_delta) {
+    m_token_value_delta->data_type = m_token_type;
+  }
+
+  // I'm guessing here that we want to check if we're still RECD_NULL,
+  // it used to be INVALID, which is not in the m_token_type's enum. /leif
+  return (m_token_type != RECD_NULL);
+}
+
+
+void
+StatExprToken::clean()
+{
+  ats_free(m_token_name);
+  delete m_token_value_delta;
+}
+
+
+/**
+ * FOR DEBUGGING ONLY
+ * Print the token according to its type in a human-readable format. :)
+ */
+void
+StatExprToken::print(const char *prefix)
+{
+  if (m_token_name != NULL) {
+    printf("%s\t%s\n", prefix, m_token_name);
+  } else {
+    printf("%s\t%c\n", prefix, m_arith_symbol);
+  }
+}
+
+
+/**
+ * StatExprToken::precedence()
+ * ---------------------------
+ * Return the binary operator precedence. The higher returning value,
+ * the higher the precedence value.
+ */
+short
+StatExprToken::precedence()
+{
+  switch (m_arith_symbol) {
+  case '(':
+    return 4;
+  case '^':                    // fall through
+  case '!':
+    return 3;
+  case '*':                    // fall through
+  case '/':
+    return 2;
+  case '+':                    // fall through
+  case '-':
+    return 1;
+  default:
+    return -1;
+  }
+}
+
+
+/**
+ * StatExprToken::statVarSet()
+ * ---------------------------
+ * This method is responsible for ensuring the assigning value
+ * fall within the min. and max. bound. If it's smaller than min.
+ * or larger than max, then the error value is assigned. If no
+ * error value is assigned, either min. or max. is assigned.
+ */
+bool StatExprToken::statVarSet(RecDataT type, RecData value)
+{
+  RecData converted_value;
+
+  if (StatError) {
+    /* fix this after librecords is done
+       mgmt_log(stderr,
+       "[StatPro] ERROR in a statistics aggregation operations\n");
+     */
+    RecData err_value;
+    RecDataClear(m_token_type, &err_value);
+    return varSetData(m_token_type, m_token_name, err_value);
+  }
+
+  /*
+   * do conversion if necessary.
+   */
+  if (m_token_type != type) {
+    switch (m_token_type) {
+    case RECD_INT:
+    case RECD_COUNTER:
+      if (type == RECD_NULL)
+        converted_value = value;
+      else if (type == RECD_INT || type == RECD_COUNTER || type == RECD_FX)
+        converted_value.rec_int = value.rec_int;
+      else if (type == RECD_FLOAT || type == RECD_CONST)
+        converted_value.rec_int = (RecInt)value.rec_float;
+      else
+        Fatal("%s, invalid value type:%d\n", m_token_name, type);
+      break;
+    case RECD_FLOAT:
+      if (type == RECD_NULL)
+        converted_value = value;
+      else if (type == RECD_INT || type == RECD_COUNTER || type == RECD_FX)
+        converted_value.rec_float = (RecFloat)value.rec_int;
+      else if (type == RECD_FLOAT || type == RECD_CONST)
+        converted_value.rec_float = value.rec_float;
+      else
+        Fatal("%s, invalid value type:%d\n", m_token_name, type);
+      break;
+    default:
+      Fatal("%s, unsupported token type:%d\n", m_token_name, m_token_type);
+    }
+  } else {
+    converted_value = value;
+  }
+
+  if (RecDataCmp(m_token_type, converted_value, m_token_value_min) < 0) {
+    value = m_token_value_min;
+  }
+  else if (RecDataCmp(m_token_type, converted_value, m_token_value_max) > 0) {
+    value = m_token_value_max;
+  }
+
+  return varSetData(m_token_type, m_token_name, converted_value);
+}
+
+
+/***********************************************************************
+					    	 StatExprList
+ **********************************************************************/
+
+/**
+ * StatExprList::StatExprList()
+ * ----------------------------
+ */
+StatExprList::StatExprList()
+ : m_size(0)
+{
+}
+
+
+/**
+ * StatExprList::clean()
+ * ---------------------
+ */
+void
+StatExprList::clean()
+{
+  StatExprToken *temp = NULL;
+
+  while ((temp = m_tokenList.dequeue())) {
+    delete(temp);
+    m_size -= 1;
+  }
+  ink_assert(m_size == 0);
+}
+
+
+void
+StatExprList::enqueue(StatExprToken * entry)
+{
+  ink_assert(entry);
+  m_tokenList.enqueue(entry);
+  m_size += 1;
+}
+
+
+void
+StatExprList::push(StatExprToken * entry)
+{
+  ink_assert(entry);
+  m_tokenList.push(entry);
+  m_size += 1;
+}
+
+
+StatExprToken *
+StatExprList::dequeue()
+{
+  if (m_size == 0) {
+    return NULL;
+  }
+  m_size -= 1;
+  return (StatExprToken *) m_tokenList.dequeue();
+}
+
+
+StatExprToken *
+StatExprList::pop()
+{
+  if (m_size == 0) {
+    return NULL;
+  }
+  m_size -= 1;
+  return m_tokenList.pop();
+}
+
+
+StatExprToken *
+StatExprList::top()
+{
+  if (m_size == 0) {
+    return NULL;
+  }
+  return m_tokenList.head;
+}
+
+
+StatExprToken *
+StatExprList::first()
+{
+  if (m_size == 0) {
+    return NULL;
+  }
+  return m_tokenList.head;
+}
+
+
+StatExprToken *
+StatExprList::next(StatExprToken * current)
+{
+  if (!current) {
+    return NULL;
+  }
+  return (current->link).next;
+}
+
+
+/**
+ * StatExprList::print()
+ * ---------------------
+ *  Print the token in the expression in a human-readable format. :)
+ */
+void
+StatExprList::print(const char *prefix)
+{
+  for (StatExprToken * token = first(); token; token = next(token)) {
+    token->print(prefix);
+  }
+}
+
+
+/**
+ * StatExprToken::count()
+ * ----------------------
+ * Counts the number of token in the expression list and return it.
+ */
+unsigned
+StatExprList::count()
+{
+  return m_size;
+}
+
+
+/***********************************************************************
+ 					    	     StatObject
+ **********************************************************************/
+
+
+/**
+ * StatObject::StatObject()
+ * ------------------------
+ */
+
+StatObject::StatObject()
+ : m_id(1),
+   m_debug(false),
+   m_expr_string(NULL),
+   m_node_dest(NULL),
+   m_cluster_dest(NULL),
+   m_expression(NULL),
+   m_postfix(NULL),
+   m_last_update(-1),
+   m_current_time(-1), m_update_interval(-1),
+   m_stats_max(FLT_MAX), m_stats_min(FLT_MIN),
+   m_has_max(false), m_has_min(false), m_has_delta(false)
+{
+}
+
+
+StatObject::StatObject(unsigned identifier)
+  : m_id(identifier),
+    m_debug(false),
+    m_expr_string(NULL),
+    m_node_dest(NULL),
+    m_cluster_dest(NULL),
+    m_expression(NULL),
+    m_postfix(NULL),
+    m_last_update(-1),
+    m_current_time(-1), m_update_interval(-1),
+    m_stats_max(FLT_MAX), m_stats_min(FLT_MIN),
+    m_has_max(false), m_has_min(false), m_has_delta(false)
+{
+}
+
+
+/**
+ * StatObject::clean()
+ * -------------------
+ */
+void
+StatObject::clean()
+{
+  ats_free(m_expr_string);
+  delete m_node_dest;
+  delete m_cluster_dest;
+  delete m_postfix;
+}
+
+
+/**
+ * StatObject::assignDst()
+ * -----------------------
+ */
+void
+StatObject::assignDst(const char *str, bool m_node_var, bool m_sum_var)
+{
+  if (StatDebug) {
+    Debug(MODULE_INIT, "DESTINTATION: %s\n", str);
+  }
+
+  StatExprToken *statToken = new StatExprToken();
+
+  statToken->assignTokenName(str);
+  statToken->m_node_var = m_node_var;
+  statToken->m_sum_var = m_sum_var;
+
+  // The type of dst token should be always not NULL
+  if (statToken->m_token_type == RECD_NULL) {
+    Fatal("token:%s, invalid token type!", statToken->m_token_name);
+  }
+
+  // Set max/min value
+  if (m_has_max)
+    RecDataSetFromFloat(statToken->m_token_type, &statToken->m_token_value_max,
+                        m_stats_max);
+  else
+    RecDataSetMax(statToken->m_token_type, &statToken->m_token_value_max);
+
+  if (m_has_min)
+    RecDataSetFromFloat(statToken->m_token_type, &statToken->m_token_value_min,
+                        m_stats_min);
+  else
+    RecDataSetMin(statToken->m_token_type, &statToken->m_token_value_min);
+
+  if (m_node_var) {
+    ink_assert(m_node_dest == NULL);
+    m_node_dest = statToken;
+  } else {
+    ink_assert(m_cluster_dest == NULL);
+    m_cluster_dest = statToken;
+  }
+}
+
+
+/**
+ * StatObject::assignExpr()
+ * ------------------------
+ */
+void
+StatObject::assignExpr(char *str)
+{
+  StatExprToken *statToken = NULL;
+
+  if (StatDebug) {
+    Debug(MODULE_INIT, "EXPRESSION: %s\n", str);
+  }
+  ink_assert(m_expr_string == NULL);
+  // We take ownership here
+  m_expr_string = str;
+
+  Tokenizer exprTok(" ");
+  exprTok.Initialize(str);
+  tok_iter_state exprTok_state;
+  const char *token = exprTok.iterFirst(&exprTok_state);
+
+  ink_assert(m_expression == NULL);
+  m_expression = new StatExprList();
+
+  while (token) {
+
+    statToken = new StatExprToken();
+
+    if (isOperator(token[0])) {
+
+      statToken->m_arith_symbol = token[0];
+      ink_assert(statToken->m_token_name == NULL);
+
+      if (StatDebug) {
+        Debug(MODULE_INIT, "\toperator: ->%c<-\n", statToken->m_arith_symbol);
+      }
+
+    } else {
+
+      ink_assert(statToken->m_arith_symbol == '\0');
+
+      // delta
+      if (token[0] == '#') {
+
+        token += 1;             // skip '#'
+        statToken->m_token_value_delta = new StatDataSamples();
+        statToken->m_token_value_delta->previous_time = (ink_hrtime) 0;
+        statToken->m_token_value_delta->current_time = (ink_hrtime) 0;
+        statToken->m_token_value_delta->data_type = RECD_NULL;
+        RecDataClear(RECD_NULL, &statToken->m_token_value_delta->previous_value);
+        RecDataClear(RECD_NULL, &statToken->m_token_value_delta->current_value);
+
+      }
+
+      statToken->assignTokenName(token);
+
+      if (StatDebug) {
+        Debug(MODULE_INIT, "\toperand:  ->%s<-\n", token);
+      }
+
+    }
+
+    token = exprTok.iterNext(&exprTok_state);
+    m_expression->enqueue(statToken);
+
+  }
+
+  infix2postfix();
+
+}
+
+
+/**
+ * StatObject::infix2postfix()
+ * ---------------------------
+ * Takes the infix "expression" and convert it to a postfix for future
+ * evaluation.
+ *
+ * SIDE EFFECT: consume all token in "expression"
+ */
+void
+StatObject::infix2postfix()
+{
+  StatExprList stack;
+  StatExprToken *tempToken = NULL;
+  StatExprToken *curToken = NULL;
+  m_postfix = new StatExprList();
+
+  while (m_expression->top()) {
+    curToken = m_expression->dequeue();
+
+    if (!isOperator(curToken->m_arith_symbol)) {
+      //printf("I2P~: enqueue %s\n", curToken->m_token_name);
+      m_postfix->enqueue(curToken);
+
+    } else {
+      ink_assert(curToken->m_arith_symbol != '\0');
+
+      if (curToken->m_arith_symbol == '(') {
+        stack.push(curToken);
+      } else if (curToken->m_arith_symbol == ')') {
+        tempToken = (StatExprToken *) stack.pop();
+
+        while (tempToken->m_arith_symbol != '(') {
+          //printf("I2P@: enqueue %c\n", tempToken->m_arith_symbol);
+          m_postfix->enqueue(tempToken);
+          tempToken = (StatExprToken *) stack.pop();
+        }
+
+        // Free up memory for ')'
+        delete(curToken);
+        delete(tempToken);
+
+      } else {
+        if (stack.count() == 0) {
+          stack.push(curToken);
+        } else {
+          tempToken = (StatExprToken *) stack.top();
+
+          while ((tempToken->m_arith_symbol != '(') && (tempToken->precedence() >= curToken->precedence())) {
+            tempToken = (StatExprToken *) stack.pop();  // skip the (
+            //printf("I2P$: enqueue %c\n", tempToken->m_arith_symbol);
+            m_postfix->enqueue(tempToken);
+            if (stack.count() == 0) {
+              break;
+            }
+            tempToken = (StatExprToken *) stack.top();
+          }                     // while
+
+          stack.push(curToken);
+        }
+      }
+    }
+  }
+
+  while (stack.count() > 0) {
+    tempToken = (StatExprToken *) stack.pop();
+    //printf("I2P?: enqueue %c\n", tempToken->m_arith_symbol);
+    m_postfix->enqueue(tempToken);
+  }
+
+  // dump infix expression
+  delete(m_expression);
+  m_expression = NULL;
+}
+
+
+/**
+ * StatObject::NodeStatEval()
+ * --------------------------
+ *
+ *
+ */
+RecData StatObject::NodeStatEval(RecDataT *result_type, bool cluster)
+{
+  StatExprList stack;
+  StatExprToken *left = NULL;
+  StatExprToken *right = NULL;
+  StatExprToken *result = NULL;
+  StatExprToken *curToken = NULL;
+  RecData tempValue;
+  RecDataClear(RECD_NULL, &tempValue);
+
+  *result_type = RECD_NULL;
+
+  /* Express checkout lane -- Stat. object with on 1 source variable */
+  if (m_postfix->count() == 1) {
+    StatExprToken * src = m_postfix->top();
+
+    // in librecords, not all statistics are register at initialization
+    // must assign proper type if it is undefined.
+    if (src->m_token_type == RECD_NULL) {
+      src->assignTokenType();
+    }
+
+    *result_type = src->m_token_type;
+    if (src->m_token_type == RECD_CONST) {
+      tempValue = src->m_token_value;
+    } else if (src->m_token_value_delta) {
+      tempValue = src->m_token_value_delta->diff_value(src->m_token_name);
+    } else if (!cluster) {
+      if (!varDataFromName(src->m_token_type, src->m_token_name, &tempValue)) {
+        RecDataClear(src->m_token_type, &tempValue);
+      }
+    } else {
+      if (!overviewGenerator->varClusterDataFromName(src->m_token_type,
+                                                     src->m_token_name,
+                                                     &tempValue)) {
+        RecDataClear(src->m_token_type, &tempValue);
+      }
+    }
+  } else {
+
+    /* standard postfix evaluation */
+    for (StatExprToken * token = m_postfix->first(); token; token = m_postfix->next(token)) {
+      /* carbon-copy the token. */
+      curToken = new StatExprToken();
+      curToken->copy(*token);
+
+      if (!isOperator(curToken->m_arith_symbol)) {
+        stack.push(curToken);
+      } else {
+        ink_assert(isOperator(curToken->m_arith_symbol));
+        right = stack.pop();
+        left = stack.pop();
+
+        if (left->m_token_type == RECD_NULL) {
+          left->assignTokenType();
+        }
+        if (right->m_token_type == RECD_NULL) {
+          right->assignTokenType();
+        }
+
+        result = StatBinaryEval(left, curToken->m_arith_symbol, right, cluster);
+
+        stack.push(result);
+        delete(curToken);
+        delete(left);
+        delete(right);
+      }
+    }
+
+    /* should only be 1 value left on stack -- the resulting value */
+    if (stack.count() > 1) {
+      stack.print("\t");
+      ink_assert(false);
+    }
+
+    *result_type = stack.top()->m_token_type;
+    tempValue = stack.top()->m_token_value;
+  }
+
+  return tempValue;
+
+}
+
+
+/**
+ * StatObject::ClusterStatEval()
+ * -----------------------------
+ *
+ *
+ */
+RecData StatObject::ClusterStatEval(RecDataT *result_type)
+{
+  /* Sanity check */
+  ink_assert(m_cluster_dest && !m_cluster_dest->m_node_var);
+
+  // what is this?
+  if ((m_node_dest == NULL) || (m_cluster_dest->m_sum_var == false)) {
+    return NodeStatEval(result_type, true);
+  } else {
+    RecData tempValue;
+
+    if (!overviewGenerator->varClusterDataFromName(m_node_dest->m_token_type,
+                                                   m_node_dest->m_token_name,
+                                                   &tempValue)) {
+      *result_type = RECD_NULL;
+      RecDataClear(*result_type, &tempValue);
+    }
+
+    return (tempValue);
+  }
+}
+
+
+/**
+ * StatObject::setTokenValue()
+ * ---------------------------
+ * The logic of the following code segment is the following.
+ * The objective is to extract the appropriate right->m_token_value.
+ * If 'right' is an intermediate value, nothing to do.
+ * If m_token_type is RECD_CONST, nothing to do.
+ * If m_token_type is RECD_FX, right->m_token_value is the diff. in time.
+ * If m_token_type is either RECD_INT or RECD_FLOAT, it can either
+ * by a cluster variable or a node variable.
+ *     If it is a cluster variable, just use varClusterFloatFromName
+ *     to set right->m_token_value.
+ *     If it is a node variable, then it can either be a variable
+ *     with delta. To determine whether it has a delta, simply search
+ *     the m_token_name in the delta list. If found then it has delta.
+ *     If it has delta then use the delta's diff. in value,
+ *     otherwise simply set right->m_token_value with varFloatFromName.
+ */
+void
+StatObject::setTokenValue(StatExprToken * token, bool cluster)
+{
+  if (token->m_token_name) {
+    // it is NOT an intermediate value
+
+    switch (token->m_token_type) {
+    case RECD_CONST:
+      break;
+
+    case RECD_FX:
+      // only support time function
+      // use rec_int to store time value
+      token->m_token_value.rec_int = (m_current_time - m_last_update);
+      break;
+
+    case RECD_INT:             // fallthought
+    case RECD_COUNTER:
+    case RECD_FLOAT:
+      if (cluster) {
+        if (!overviewGenerator->varClusterDataFromName(token->m_token_type,
+                                                       token->m_token_name,
+                                                       &(token->m_token_value)))
+        {
+          RecDataClear(token->m_token_type, &token->m_token_value);
+        }
+      } else {
+        if (token->m_token_value_delta) {
+          token->m_token_value =
+            token->m_token_value_delta->diff_value(token->m_token_name);
+        } else {
+          if (!varDataFromName(token->m_token_type, token->m_token_name,
+                               &(token->m_token_value))) {
+            RecDataClear(token->m_token_type, &token->m_token_value);
+          }
+        }                       // delta?
+      }                         // cluster?
+      break;
+
+    default:
+      if (StatDebug) {
+        Debug(MODULE, "Unrecognized token \"%s\" of type %d.\n",
+              token->m_token_name, token->m_token_type);
+      }
+    }                           // switch
+  }                             // m_token_name?
+}
+
+
+/**
+ * StatObject::StatBinaryEval()
+ * ------------------------
+ * Take the left token, the right token, an binary operation and perform an
+ * arithmatic operations on them. This function is responsible for getting the
+ * correct value from:
+ * - (1) node variable
+ * - (2) node variable with a delta structure
+ * - (3) cluster variable
+ * - (4) an immediate value
+ */
+StatExprToken *StatObject::StatBinaryEval(StatExprToken * left, char op,
+                                          StatExprToken * right, bool cluster)
+{
+  RecData l, r;
+  StatExprToken *result = new StatExprToken();
+  result->m_token_type = RECD_INT;
+
+  if (left->m_token_type == RECD_NULL
+      && right->m_token_type == RECD_NULL) {
+    return result;
+  }
+
+  if (left->m_token_type != RECD_NULL) {
+    setTokenValue(left, cluster);
+    result->m_token_type = left->m_token_type;
+  }
+
+  if (right->m_token_type != RECD_NULL) {
+    setTokenValue(right, cluster);
+    switch (result->m_token_type) {
+    case RECD_NULL:
+      result->m_token_type = right->m_token_type;
+      break;
+    case RECD_FX:
+    case RECD_INT:
+    case RECD_COUNTER:
+      /*
+       * When types of left and right are different, select RECD_FLOAT
+       * as result type. It's may lead to loss of precision when do
+       * conversion, be careful!
+       */
+      if (right->m_token_type == RECD_FLOAT
+          || right->m_token_type == RECD_CONST) {
+        result->m_token_type = right->m_token_type;
+      }
+      break;
+    case RECD_CONST:
+    case RECD_FLOAT:
+      break;
+    default:
+      Fatal("Unexpected RecData Type:%d", result->m_token_type);
+      break;
+    }
+  }
+
+  /*
+   * We should make the operands with the same type before calculating.
+   */
+  RecDataClear(RECD_NULL, &l);
+  RecDataClear(RECD_NULL, &r);
+
+  if (left->m_token_type == right->m_token_type ) {
+    l = left->m_token_value;
+    r = right->m_token_value;
+  } else if (result->m_token_type != left->m_token_type) {
+    if (left->m_token_type != RECD_NULL) {
+      ink_assert(result->m_token_type == RECD_FLOAT
+                 || result->m_token_type == RECD_CONST);
+
+      l.rec_float = (RecFloat)left->m_token_value.rec_int;
+    }
+    r = right->m_token_value;
+    ink_assert(result->m_token_type == right->m_token_type);
+  } else {
+    l = left->m_token_value;
+    if (right->m_token_type != RECD_NULL) {
+      ink_assert(result->m_token_type == RECD_FLOAT
+                 || result->m_token_type == RECD_CONST);
+
+      r.rec_float = (RecFloat)right->m_token_value.rec_int;
+    }
+    ink_assert(result->m_token_type == left->m_token_type);
+  }
+
+  /*
+   * Start to calculate
+   */
+  switch (op) {
+  case '+':
+    result->m_token_value = RecDataAdd(result->m_token_type, l, r);
+    break;
+
+  case '-':
+    result->m_token_value = RecDataSub(result->m_token_type, l, r);
+    break;
+
+  case '*':
+    result->m_token_value = RecDataMul(result->m_token_type, l, r);
+    break;
+
+  case '/':
+    RecData recTmp;
+    RecDataClear(RECD_NULL, &recTmp);
+
+    /*
+     * Force the type of result to be RecFloat on div operation
+     */
+    if (result->m_token_type != RECD_FLOAT && result->m_token_type != RECD_CONST) {
+      RecFloat t;
+
+      result->m_token_type = RECD_FLOAT;
+
+      t = (RecFloat)l.rec_int;
+      l.rec_float = t;
+
+      t = (RecFloat)r.rec_int;
+      r.rec_float = t;
+    }
+
+    if (RecDataCmp(result->m_token_type, r, recTmp)) {
+      result->m_token_value = RecDataDiv(result->m_token_type, l, r);
+    }
+    break;
+
+  default:
+    // should never reach here
+    StatError = true;
+  }
+
+  return (result);
+}
+
+
+/***********************************************************************
+ 					    	   StatObjectList
+ **********************************************************************/
+
+StatObjectList::StatObjectList()
+ : m_size(0)
+{
+}
+
+
+void
+StatObjectList::clean()
+{
+  StatObject *temp = NULL;
+
+  while ((temp = m_statList.dequeue())) {
+    m_size -= 1;
+    delete(temp);
+  }
+
+  ink_assert(m_size == 0);
+}
+
+
+void
+StatObjectList::enqueue(StatObject * object)
+{
+  for (StatExprToken * token = object->m_postfix->first(); token; token = object->m_postfix->next(token)) {
+    if (token->m_token_value_delta) {
+      object->m_has_delta = true;
+      break;
+    }
+  }
+
+  m_statList.enqueue(object);
+  m_size += 1;
+}
+
+
+StatObject *
+StatObjectList::first()
+{
+  return m_statList.head;
+}
+
+
+StatObject *
+StatObjectList::next(StatObject * current)
+{
+  return (current->link).next;
+}
+
+
+/**
+ * StatObjectList::Eval()
+ * ----------------------
+ * The statisitic processor entry point to perform the calculation.
+ */
+short
+StatObjectList::Eval()
+{
+  RecData tempValue;
+  RecData result;
+  RecDataT result_type;
+  ink_hrtime threshold = 0;
+  ink_hrtime delta = 0;
+  short count = 0;
+
+  RecDataClear(RECD_NULL, &tempValue);
+  RecDataClear(RECD_NULL, &result);
+
+  for (StatObject * object = first(); object; object = next(object)) {
+    StatError = false;
+    StatDebug = object->m_debug;
+
+    if (StatDebug) {
+      Debug(MODULE, "\n##### %d #####\n", object->m_id);
+    }
+
+    if (object->m_update_interval <= 0) {
+      // non-time statistics
+      object->m_current_time = ink_get_hrtime_internal();
+
+      if (object->m_node_dest) {
+        result = object->NodeStatEval(&result_type, false);
+        object->m_node_dest->statVarSet(result_type, result);
+      }
+
+      if (object->m_cluster_dest) {
+        result = object->ClusterStatEval(&result_type);
+        object->m_cluster_dest->statVarSet(result_type, result);
+      }
+
+      object->m_last_update = object->m_current_time;
+    } else {
+      // timed statisitics
+      object->m_current_time = ink_get_hrtime_internal();
+
+      threshold = object->m_update_interval * HRTIME_SECOND;
+      delta = object->m_current_time - object->m_last_update;
+
+      if (StatDebug) {
+        Debug(MODULE, "\tUPDATE:%" PRId64 " THRESHOLD:%" PRId64 ", DELTA:%" PRId64 "\n", object->m_update_interval, threshold, delta);
+      }
+
+      /* Should we do the calculation? */
+      if ((delta > threshold) ||        /* sufficient elapsed time? */
+          (object->m_last_update == -1) ||      /*       first time?       */
+          (object->m_last_update > object->m_current_time)) {   /*wrapped */
+
+        if (StatDebug) {
+          if (delta > threshold) {
+            Debug(MODULE, "\t\tdelta > threshold IS TRUE!\n");
+          }
+          if (object->m_last_update == -1) {
+            Debug(MODULE, "\t\tm_last_update = -1 IS TRUE!\n");
+          }
+          if (object->m_last_update > object->m_current_time) {
+            Debug(MODULE, "\t\tm_last_update > m_current_time IS TRUE\n");
+          }
+        }
+
+        if (!object->m_has_delta) {
+
+          if (StatDebug) {
+            Debug(MODULE, "\tEVAL: Simple time-condition.\n");
+          }
+
+          if (object->m_node_dest) {
+            result = object->NodeStatEval(&result_type, false);
+            object->m_node_dest->statVarSet(result_type, result);
+          }
+
+          if (object->m_cluster_dest) {
+            result = object->ClusterStatEval(&result_type);
+            object->m_cluster_dest->statVarSet(result_type, result);
+          }
+
+          object->m_last_update = object->m_current_time;
+        } else {
+          /* has delta */
+          if (StatDebug) {
+            Debug(MODULE, "\tEVAL: Complicated time-condition.\n");
+          }
+          // scroll old values
+          for (StatExprToken * token = object->m_postfix->first(); token; token = object->m_expression->next(token)) {
+
+            // in librecords, not all statistics are register at initialization
+            // must assign proper type if it is undefined.
+            if (!isOperator(token->m_arith_symbol) && token->m_token_type == RECD_NULL) {
+              token->assignTokenType();
+            }
+
+            if (token->m_token_value_delta) {
+              if (!varDataFromName(token->m_token_type, token->m_token_name,
+                                   &tempValue)) {
+                RecDataClear(RECD_NULL, &tempValue);
+              }
+
+              token->m_token_value_delta->previous_time = token->m_token_value_delta->current_time;
+              token->m_token_value_delta->previous_value = token->m_token_value_delta->current_value;
+              token->m_token_value_delta->current_time = object->m_current_time;
+              token->m_token_value_delta->current_value = tempValue;
+            }
+          }
+
+          if (delta > threshold) {
+            if (object->m_node_dest) {
+              result = object->NodeStatEval(&result_type, false);
+              object->m_node_dest->statVarSet(result_type, result);
+            }
+
+            if (object->m_cluster_dest) {
+              result = object->ClusterStatEval(&result_type);
+              object->m_cluster_dest->statVarSet(result_type, result);
+            }
+
+            object->m_last_update = object->m_current_time;
+          } else {
+            if (StatDebug) {
+              Debug(MODULE, "\tEVAL: Timer not expired, do nothing\n");
+            }
+          }
+        }                       /* delta? */
+      } else {
+        if (StatDebug) {
+          Debug(MODULE, "\tEVAL: Timer not expired, nor 1st time, nor wrapped, SORRY!\n");
+        }
+      }                         /* timed event */
+    }
+    count += 1;
+  }                             /* for */
+
+  return count;
+}                               /* Eval() */
+
+
+/**
+ * StatObjectList::print()
+ * --------------------------
+ * Print the list of of statistics object in a human-readable format. :)
+ */
+void
+StatObjectList::print(const char *prefix)
+{
+  for (StatObject * object = first(); object; object = next(object)) {
+    if (StatDebug) {
+      Debug(MODULE, "\n%sSTAT OBJECT#: %d\n", prefix, object->m_id);
+    }
+
+    if (object->m_expression) {
+      object->m_expression->print("\t");
+    }
+
+    if (object->m_postfix) {
+      object->m_postfix->print("\t");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/cmd/traffic_manager/StatType.h
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/StatType.h b/cmd/traffic_manager/StatType.h
new file mode 100644
index 0000000..673e1e7
--- /dev/null
+++ b/cmd/traffic_manager/StatType.h
@@ -0,0 +1,231 @@
+/** @file
+
+  A brief file description
+
+  @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.
+ */
+
+/***************************************/
+/****************************************************************************
+ *
+ *  StatType.h - Functions for computing node and cluster stat
+ *                          aggregation
+ *
+ *
+ ****************************************************************************/
+
+#ifndef _STATTYPE_H_
+#define	_STATTYPE_H_
+
+#include "StatXML.h"
+#include "Main.h"               // Debug()
+#include "WebMgmtUtils.h"
+
+#define BYTES_TO_MBIT_SCALE (8/1000000.0)
+
+/* Structs used in Average Statistics calculations */
+struct StatDataSamples
+{
+  ink_hrtime previous_time;
+  ink_hrtime current_time;
+  RecDataT data_type;
+  RecData previous_value;
+  RecData current_value;
+
+  RecData diff_value(const char *name)
+  {
+    RecData tmp;
+
+    if (data_type == RECD_NULL) {
+      data_type = varType(name);
+    }
+
+    if (data_type != RECD_NULL)
+      return RecDataSub(data_type, current_value, previous_value);
+    else {
+      RecDataClear(RECD_NULL, &tmp);
+      return tmp;
+    }
+  }
+  ink_hrtime diff_time()
+  {
+    return (current_time - previous_time);
+  }
+};
+
+// Urgly workaround -- no optimization in HPUX
+#if defined(hpux)
+#define inline
+#endif
+
+#define MODULE      "StatPro"   // Statistics processor debug tag
+#define MODULE_INIT "StatProInit"       // Statistics processor debug tag
+
+/***************************************************************
+ *                       StatExprToken
+ * a statistics expression token can either be a binary operator,
+ * name '+', '-', '*', '/', or parenthesis '(', ')' or a TS variable.
+ * In the former case, the arithSymbol stores the operator or
+ * paranthesis; otherwise arithSymbol is '/0';
+ ***************************************************************/
+class StatExprToken
+{
+
+public:
+
+  char m_arith_symbol;
+  char *m_token_name;
+  RecDataT m_token_type;
+  RecData m_token_value;
+  RecData m_token_value_max;
+  RecData m_token_value_min;
+  StatDataSamples *m_token_value_delta;
+  bool m_sum_var;
+  bool m_node_var;
+
+  // Member Functions
+  void assignTokenName(const char *);
+  bool assignTokenType();
+  void print(const char *);
+  short precedence();
+  void copy(const StatExprToken &);
+
+  LINK(StatExprToken, link);
+  StatExprToken();
+  inline ~ StatExprToken()
+  {
+    clean();
+  };
+  void clean();
+
+  bool statVarSet(RecDataT, RecData);
+};
+
+
+/**
+ * StatExprList
+ *   simply a list of StatExprToken.
+ **/
+class StatExprList
+{
+
+public:
+
+  StatExprList();
+  inline ~ StatExprList()
+  {
+    clean();
+  };
+  void clean();
+
+  void enqueue(StatExprToken *);
+  void push(StatExprToken *);
+  StatExprToken *dequeue();
+  StatExprToken *pop();
+  StatExprToken *top();
+  StatExprToken *first();
+  StatExprToken *next(StatExprToken *);
+  unsigned count();
+  void print(const char *);
+
+private:
+
+  size_t m_size;
+  Queue<StatExprToken> m_tokenList;
+};
+
+/***************************************************************
+ *                        StatObject
+ * Each entry in the statistics XML file is represented by a
+ * StatObject.
+ ***************************************************************/
+class StatObject
+{
+
+public:
+
+  unsigned m_id;
+  bool m_debug;
+  char *m_expr_string;          /* for debugging using only */
+  StatExprToken *m_node_dest;
+  StatExprToken *m_cluster_dest;
+  StatExprList *m_expression;
+  StatExprList *m_postfix;
+  ink_hrtime m_last_update;
+  ink_hrtime m_current_time;
+  ink_hrtime m_update_interval;
+  RecFloat m_stats_max;
+  RecFloat m_stats_min;
+  bool m_has_max;
+  bool m_has_min;
+  bool m_has_delta;
+  LINK(StatObject, link);
+
+  // Member functions
+  StatObject();
+  StatObject(unsigned);
+  inline ~ StatObject()
+  {
+    clean();
+  };
+  void clean();
+  void assignDst(const char *, bool, bool);
+  void assignExpr(char *);
+
+  StatExprToken *StatBinaryEval(StatExprToken *, char, StatExprToken *, bool cluster = false);
+  RecData NodeStatEval(RecDataT *result_type, bool cluster);
+  RecData ClusterStatEval(RecDataT *result_type);
+  void setTokenValue(StatExprToken *, bool cluster = false);
+
+private:
+
+  void infix2postfix();
+};
+
+
+/**
+ * StatObjectList
+ *    simply a list of StatObject.
+ **/
+class StatObjectList
+{
+
+public:
+
+  // Member functions
+  StatObjectList();
+  inline ~ StatObjectList()
+  {
+    clean();
+  };
+  void clean();
+  void enqueue(StatObject * object);
+  StatObject *first();
+  StatObject *next(StatObject * current);
+  void print(const char *prefix = "");
+  short Eval();                 // return the number of statistics object processed
+
+  size_t m_size;
+
+private:
+
+  Queue<StatObject> m_statList;
+};
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/cmd/traffic_manager/StatXML.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/StatXML.cc b/cmd/traffic_manager/StatXML.cc
new file mode 100644
index 0000000..277b84a
--- /dev/null
+++ b/cmd/traffic_manager/StatXML.cc
@@ -0,0 +1,82 @@
+/** @file
+
+  A brief file description
+
+  @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.
+ */
+
+#include "ink_config.h"
+#include "StatXML.h"
+#include <stdlib.h>
+#include <ctype.h>
+
+//
+// Extract the text between a pair of XML tag and returns the length
+// of the extracted text.
+//
+unsigned short
+XML_extractContent(const char *name, char *content, size_t result_len)
+{
+
+  char c;
+  int contentIndex = 0;
+
+  memset(content, 0, result_len);
+  for (unsigned short nameIndex = 0; name[nameIndex] != '<'; nameIndex += 1) {
+    c = name[nameIndex];
+
+    if (isspace(c)) {
+      continue;
+    }
+
+    if (isOperator(c)) {
+      content[contentIndex++] = ' ';
+      content[contentIndex++] = c;
+      content[contentIndex++] = ' ';
+    } else {
+      content[contentIndex++] = c;
+    }
+  }
+
+  return (strlen(content));
+
+}
+
+
+//
+// Returns true  if 'c'is an operator (in our definition),
+//         false otherwise
+//
+bool
+isOperator(char c)
+{
+
+  switch (c) {
+  case '+':
+  case '-':
+  case '*':
+  case '/':
+  case '(':
+  case ')':
+    return true;
+  default:
+    return false;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/cmd/traffic_manager/StatXML.h
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/StatXML.h b/cmd/traffic_manager/StatXML.h
new file mode 100644
index 0000000..b31063b
--- /dev/null
+++ b/cmd/traffic_manager/StatXML.h
@@ -0,0 +1,47 @@
+/** @file
+
+  A brief file description
+
+  @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.
+ */
+
+
+#ifndef _STATXML_H_
+#define	_STATXML_H_
+
+#include "WebMgmtUtils.h"
+#include "List.h"
+
+typedef enum
+{
+  INVALID_TAG = -1,
+  ROOT_TAG,
+  STAT_TAG,
+  DST_TAG,
+  EXPR_TAG
+} StatXMLTag;
+
+/***************************************************************
+ *                      General Methods
+ ***************************************************************/
+bool isOperator(char);
+int XML_getContent(const char *, int, char *, StatXMLTag);
+unsigned short XML_extractContent(const char *, char *, size_t);
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/cmd/traffic_manager/stats.txt
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/stats.txt b/cmd/traffic_manager/stats.txt
new file mode 100644
index 0000000..97bdb90
--- /dev/null
+++ b/cmd/traffic_manager/stats.txt
@@ -0,0 +1,236 @@
+//-----------------------------------------------------------------------------
+//
+// Statistics Processor
+//
+// Last Update: 04/11/2001
+//
+//-----------------------------------------------------------------------------
+// -*- coding: utf-8 -*-
+//
+// 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.
+
+
+//-----------------------------------------------------------------------------
+// Design
+//-----------------------------------------------------------------------------
+
+This statistics processor is a Cougar II (Tsunami) feature. 
+It is designed to replace the StatAggregate.cc and portion of WebOverview.cc 
+for scalability, maintainability, and ability to customize reasons.
+
+The statistics processor aggregate/calculate traffic server statistics based
+on a XML-based configuration file. At the processor's initialization, the 
+configuration file is read and parsed. Each set of calculation is then stored
+as a C++ object, called StatObject; and each StatObject is linked into a list,
+called StatObjectList.
+
+The mgmt/traffic_manager threads will invoke the StatObjectList->Eval() to
+perform the statistics aggregation and calculation within its event loop. As
+Eval() is call, each StatObject in StatObjectList is evaluated.
+
+Recall: StatAggregate.cc aggregates/calculates/copies proxy.process.* TS
+variables to proxy.node.* variables. Similarly, WebOverview.cc aggregate
+proxy.node.* variables to their corresponding proxy.cluster.* variable.
+
+So there are two types of calculations in the statistics processor: NodeEval
+and ClusterEval. As their names imply, they aggregate node-based statistics
+and clsuter-based statistics, respectively. We call the different basis of 
+statistics aggregation as "scope". (See "Destination Attributes")
+
+In the cluster-based statistics, the aggregation is further divided into two
+types: sum and re-calculate. Sum refers calculating the proxy.cluster.* 
+variable by simply summing all required proxy.node.* variables from nodes in
+the cluster. Re-calculate refers to summing all proxy.nodes.* variables that 
+are used in the process of calculation before performing the calculation. 
+An analogy would be, summing all open connection in the cluster vs. the 
+average hit rate in the cluster.
+
+//-----------------------------------------------------------------------------
+// Destination Attributes
+//-----------------------------------------------------------------------------
+	
+	"scope" 
+	- "node"
+	- "cluster"
+
+	"operation"
+	- "sum"
+		summing the corresponding node variable across all nodes in the cluster.
+	- "re-calculate"
+		
+
+	"define"
+	- "custom"
+	- "built-in"
+
+//-----------------------------------------------------------------------------
+// Predefined Constants and Functions
+//-----------------------------------------------------------------------------
+	
+	Predefined Constants
+
+	. BYTES_TO_MB_SCALE (1/(1024*1024.0))
+	  - convert bytes to mega-bytes
+
+	. MBIT_TO_KBIT_SCALE (1000.0)
+	  - convert mega-bits to kilo-bits
+
+	. SECOND_TO_MILLISECOND_SCALE (1000.0)
+	  - convert seconds to milliseconds
+
+	. PCT_TO_INTPCT_SCALE (100.0)
+	  - convert ratios to percentage
+
+	. HRTIME_SECOND
+	  - converting milli-seconds to seconds
+
+	. BYTES_TO_MBIT_SCALE (8/1000000.0)
+	  - convert bytes to mega-bits
+
+	Predefined Functions
+	. DIFFTIME
+	  - the number of milliseconds since last update. Usually used in 
+        combination of HRTIME_SECOND which computes the number of seconds
+        since last update.
+
+//-----------------------------------------------------------------------------
+// Unit test plan
+//-----------------------------------------------------------------------------
+
+The statistics processor is designed to replace StatAggregate.cc and part of
+the WebOverview. The first thing to test StatProcessor is to comment the 
+aggregateNodeRecords() and doClusterAg() calls from mgmt/Main.cc.
+
+The next step is to replace the above function calls with StatProcessor::
+processStat().
+
+This statistics processor is a rather complicated module in traffic manager.
+Hence it can't be easily tested. We divided the test into multiple sections.
+
+1) Node-based Simple Aggregation
+	- simply performs those aggregation that are node-based and the aggregation
+      is performed every time statProcess() is invoked.
+	  E.g.: hit rate = doc. hit / doc. served.
+
+2) Node-based Time-Delta Aggregation
+	- performs those aggregation that are node-based but the operation is only
+      perform in a regular interval AND one of more variables in the 
+      calculation is obtained by calculating the difference between the last
+      updated value and the current value. E.g. average connections per second
+      is calculated by subtracting the 10 seconds ago connection count from the
+      current connection count and divide the quotient by 10.
+
+Repeat the about 2 testes with cluster-based variables. So, we have, at least,
+4 test cases.
+
+Developing a PASS/FAIL unit test that will test the statistics processor is not 
+cost-efficient. The approach we are going to use is to display the input value
+and the output value before and after the calculation is done.
+
+Let's subdivide the testes in two stages:
+
+Stage 1 : Synthetic Data
+------------------------
+We control the testing environment by setting the input values. This will test
+the correctness of the statistics processor in a controlled environment. PASS/
+FAIL is determined by matching the input/output values.
+
+Stage 2 : Load Data
+-------------------
+Submitting network traffic through traffic server with load tools like jtest and
+ftest, dumps the statistics to a text file, periodically and examines the
+resulting values
+
+//-----------------------------------------------------------------------------
+// For QA Engineer
+//-----------------------------------------------------------------------------
+The most concerning question for QA engineers is "how can I tell if the 
+Statistics Processor is working correctly?"
+
+Recall, the new Statistics Processor is meant to replace the StatAggregate.cc
+and part of the WebOverview.cc. In essence, you should not see any apparent
+change.
+
+If you ever see a value of -9999.0 (or -9999), then there is an error in
+computing that value.
+
+
+<expr>
+    - %d
+    - %f
+    - %k
+
+<dst>
+    - specifies the variable that stores that result value.
+    - ATTRIBUTE: type
+        built-in: variables that are built-in/defined in traffic server
+        custom: variables that are introducted to be temporary storage or
+                variables that are introdcuted by the client.
+    - default attributes:
+	type = built-in  
+
+<src>
+    - variable need to computer the <dst>
+    - ATTRIBUTE: type
+	node: this is a proxy.node.* variables
+	cluster: the is a proxy.node.* variables but summing over all
+                 nodes in the cluster.
+    - default attributes:
+	type = node
+
+<min>
+    - specifics what is the smallest possible value for <dst>. For values
+      smaller than <min>, the <defualt> is used.
+
+<max>
+    - specifics what is the largest possible value for <dst>. For values
+      larger than <max>, the <defualt> is used.
+
+<default>
+    - specifics what value to be assigned to <dst> is the result <dst>
+      value is smaller then <min> or larger then <max>
+
+RULES: (some of these are enfored by the DTD anyways)
+- all operator and operand in <expr> MUST BE separated by a single space.
+- the order of the tags matters
+- the order of each entry matters
+- each statistics entry has have at most 1 <dst>
+
+
+DEFINED CONSTANT (in alphabetical order)
+* _BYTES_TO_MB_SCALE
+	* Origin: utils/WebMgmtUtils.h
+	* Value:  (1/(1024*1024.0))
+
+*  _HRTIME_SECOND
+	* Origin:
+	* Value: 
+
+*  _MBIT_TO_KBIT_SCALE
+	* Origin: utils/WebMgmtUtils.h
+	* Value:  (1000.0);
+
+*  _PCT_TO_INTPCT_SCALE
+	* Origin: utils/WebMgmtUtils.h
+	* Value:  (100.0);
+
+*  _SECOND_TO_MILLISECOND_SCALE
+	* Origin: utils/WebMgmtUtils.h
+	* Value:  (1000.0);
+
+
+            __DIFFTIME

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 192b967..0915270 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1890,7 +1890,6 @@ AC_CONFIG_FILES([
   mgmt/api/Makefile
   mgmt/api/include/Makefile
   mgmt/cluster/Makefile
-  mgmt/stats/Makefile
   mgmt/utils/Makefile
   mgmt/web2/Makefile
   plugins/Makefile

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/Makefile.am
----------------------------------------------------------------------
diff --git a/mgmt/Makefile.am b/mgmt/Makefile.am
index 2b69cce..e76f70d 100644
--- a/mgmt/Makefile.am
+++ b/mgmt/Makefile.am
@@ -17,7 +17,7 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-SUBDIRS = cluster utils web2 stats api
+SUBDIRS = cluster utils web2 api
 
 noinst_LIBRARIES = libmgmt_p.a libmgmt_lm.a
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/Makefile.am
----------------------------------------------------------------------
diff --git a/mgmt/stats/Makefile.am b/mgmt/stats/Makefile.am
deleted file mode 100644
index cc6c0c0..0000000
--- a/mgmt/stats/Makefile.am
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Makefile.am for the Enterprise Management module.
-#
-#  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.
-
-AM_CPPFLAGS = \
-  -I$(top_srcdir)/lib/records \
-  -I$(top_srcdir)/lib/ts \
-  -I$(top_srcdir)/mgmt \
-  -I$(top_srcdir)/mgmt/cluster \
-  -I$(top_srcdir)/mgmt/utils \
-  -I$(top_srcdir)/mgmt/api/include \
-  -I$(top_srcdir)/mgmt/web2 \
-  -I$(top_srcdir)/proxy \
-  -I$(top_srcdir)/lib \
-  -I$(top_builddir)/lib
-
-noinst_LIBRARIES = libstats.a
-
-libstats_a_SOURCES = \
-  StatProcessor.cc \
-  StatProcessor.h \
-  StatType.cc \
-  StatType.h \
-  StatXML.cc \
-  StatXML.h

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/StatProcessor.cc
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatProcessor.cc b/mgmt/stats/StatProcessor.cc
deleted file mode 100644
index 24cbaa9..0000000
--- a/mgmt/stats/StatProcessor.cc
+++ /dev/null
@@ -1,359 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-/***************************************/
-/****************************************************************************
- *
- *  StatProcessor.cc - Functions for computing node and cluster stat
- *                          aggregation
- *
- *
- ****************************************************************************/
-
-#include "ink_config.h"
-#include "StatProcessor.h"
-#include "FileManager.h"
-
-#define STAT_CONFIG_FILE "stats.config.xml"
-
-StatObjectList statObjectList;
-StatXMLTag currentTag = INVALID_TAG;
-StatObject *statObject = NULL;
-char *exprContent = NULL;
-static unsigned statCount = 0;  // global statistics object counter
-bool nodeVar;
-bool sumClusterVar;
-
-// These helpers are used to work around the unsigned char'iness of xmlchar when
-// using libxml2. We don't have any tags (now) which uses UTF8.
-static int
-xml_atoi(const xmlchar *nptr)
-{
-  return atoi((const char*)nptr);
-}
-
-static double
-xml_atof(const xmlchar *nptr)
-{
-  return atof((const char*)nptr);
-}
-
-static int
-xml_strcmp(const xmlchar *s1, const char *s2)
-{
-  return strcmp((const char *)s1, s2);
-}
-
-
-static void
-elementStart(void * /* userData ATS_UNUSED */, const xmlchar *name, const xmlchar **atts)
-{
-  int i = 0;
-
-  if (!xml_strcmp(name, "ink:statistics"))
-    currentTag = ROOT_TAG;
-  else if (!xml_strcmp(name, "statistics"))
-    currentTag = STAT_TAG;
-  else if (!xml_strcmp(name, "destination"))
-    currentTag = DST_TAG;
-  else if (!xml_strcmp(name, "expression"))
-    currentTag = EXPR_TAG;
-  else
-    currentTag = INVALID_TAG;
-
-  switch (currentTag) {
-  case STAT_TAG:
-    statObject = new StatObject(++statCount);
-    Debug(MODULE_INIT, "\nStat #: ----------------------- %d -----------------------\n", statCount);
-
-    if (atts)
-     for (i = 0; atts[i]; i += 2) {
-      ink_assert(atts[i + 1]);    // Attribute comes in pairs, hopefully.
-
-      if (!xml_strcmp(atts[i], "minimum")) {
-        statObject->m_stats_min = (MgmtFloat) xml_atof(atts[i + 1]);
-        statObject->m_has_min = true;
-      } else if (!xml_strcmp(atts[i], "maximum")) {
-        statObject->m_stats_max = (MgmtFloat) xml_atof(atts[i + 1]);
-        statObject->m_has_max = true;
-      } else if (!xml_strcmp(atts[i], "interval")) {
-        statObject->m_update_interval = (ink_hrtime) xml_atoi(atts[i + 1]);
-      } else if (!xml_strcmp(atts[i], "debug")) {
-        statObject->m_debug = (atts[i + 1] && atts[i + 1][0] == '1');
-      }
-
-      Debug(MODULE_INIT, "\tDESTINTATION w/ attribute: %s -> %s\n", atts[i], atts[i + 1]);
-    }
-    break;
-
-  case EXPR_TAG:
-    exprContent = (char*)ats_malloc(BUFSIZ * 10);
-    memset(exprContent, 0, BUFSIZ * 10);
-    break;
-
-  case DST_TAG:
-    nodeVar = true;
-    sumClusterVar = true;       // Should only be used with cluster variable
-
-    if (atts)
-     for (i = 0; atts[i]; i += 2) {
-      ink_assert(atts[i + 1]);    // Attribute comes in pairs, hopefully.
-      if (!xml_strcmp(atts[i], "scope")) {
-        nodeVar = (!xml_strcmp(atts[i + 1], "node") ? true : false);
-      } else if (!xml_strcmp(atts[i], "operation")) {
-        sumClusterVar = (!xml_strcmp(atts[i + 1], "sum") ? true : false);
-      }
-
-      Debug(MODULE_INIT, "\tDESTINTATION w/ attribute: %s -> %s\n", atts[i], atts[i + 1]);
-    }
-
-    break;
-
-  case INVALID_TAG:
-    Debug(MODULE_INIT, "==========================================>%s<=\n", name);
-    break;
-
-  default:
-    break;
-  }
-}
-
-
-static void
-elementEnd(void * /* userData ATS_UNUSED */, const xmlchar */* name ATS_UNUSED */)
-{
-  switch (currentTag) {
-  case STAT_TAG:
-    statObjectList.enqueue(statObject);
-    currentTag = ROOT_TAG;
-    break;
-
-  case EXPR_TAG:
-    statObject->assignExpr(exprContent); // This hands over ownership of exprContent
-    // fall through
-
-  default:
-    currentTag = STAT_TAG;
-    break;
-  }
-}
-
-
-static void
-charDataHandler(void * /* userData ATS_UNUSED */, const xmlchar * name, int /* len ATS_UNUSED */)
-{
-  if (currentTag != EXPR_TAG && currentTag != DST_TAG) {
-    return;
-  }
-
-  char content[BUFSIZ * 10];
-  if (XML_extractContent((const char*)name, content, BUFSIZ * 10) == 0) {
-    return;
-  }
-
-  if (currentTag == EXPR_TAG) {
-    ink_strlcat(exprContent, content, BUFSIZ * 10); // see above for the size
-
-  } else {
-    statObject->assignDst(content, nodeVar, sumClusterVar);
-  }
-}
-
-
-StatProcessor::StatProcessor(FileManager * configFiles):m_lmgmt(NULL), m_overviewGenerator(NULL)
-{
-  rereadConfig(configFiles);
-}
-
-
-void
-StatProcessor::rereadConfig(FileManager * configFiles)
-{
-  textBuffer *fileContent = NULL;
-  Rollback *fileRB = NULL;
-  char *fileBuffer = NULL;
-  version_t fileVersion;
-  int fileLen;
-
-  statObjectList.clean();
-  statCount = 0;                // reset statistics counter
-
-  int ret = configFiles->getRollbackObj(STAT_CONFIG_FILE, &fileRB);
-  if (!ret) {
-    Debug(MODULE_INIT, " Can't get Rollback for file: %s\n", STAT_CONFIG_FILE);
-  }
-  fileVersion = fileRB->getCurrentVersion();
-  fileRB->getVersion(fileVersion, &fileContent);
-  fileBuffer = fileContent->bufPtr();
-  fileLen = strlen(fileBuffer);
-
-#if HAVE_LIBEXPAT
-  /*
-   * Start the XML Praser -- the package used is EXPAT
-   */
-  XML_Parser parser = XML_ParserCreate(NULL);
-  XML_SetUserData(parser, NULL);
-  XML_SetElementHandler(parser, elementStart, elementEnd);
-  XML_SetCharacterDataHandler(parser, charDataHandler);
-
-  /*
-   * Substiture every newline with a space to get around
-   * the SetCharacterDataHandler problem.
-   */
-  char *newlinePtr;
-  while ((newlinePtr = strchr(fileBuffer, '\n')) != NULL || (newlinePtr = strchr(fileBuffer, '\r')) != NULL) {
-    *newlinePtr = ' ';
-  }
-
-  /*
-   * Parse the input file according to XML standard.
-   * Print error if we encounter any
-   */
-  int status = XML_Parse(parser, fileBuffer, fileLen, true);
-  if (!status) {
-    mgmt_log(stderr, "%s at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
-  }
-
-  /*
-   * Cleaning upt
-   */
-  XML_ParserFree(parser);
-#else
-  /* Parse XML with libxml2 */
-  xmlSAXHandler sax;
-  memset(&sax, 0, sizeof(xmlSAXHandler));
-  sax.startElement = elementStart;
-  sax.endElement = elementEnd;
-  sax.characters = charDataHandler;
-  sax.initialized = 1;
-  xmlParserCtxtPtr parser = xmlCreatePushParserCtxt(&sax, NULL, NULL, 0, NULL);
-
-  int status = xmlParseChunk(parser, fileBuffer, fileLen, 1);
-  if (status != 0) {
-    xmlErrorPtr errptr = xmlCtxtGetLastError(parser);
-    mgmt_log(stderr, "%s at %s:%d\n", errptr->message, errptr->file, errptr->line);
-  }
-  xmlFreeParserCtxt(parser);
-#endif
-
-
-  delete fileContent;
-
-  Debug(MODULE_INIT, "\n\n---------- END OF PARSING & INITIALIZING ---------\n\n");
-}
-
-
-StatProcessor::~StatProcessor()
-{
-
-  Debug(MODULE_INIT, "[StatProcessor] Destructing Statistics Processor\n");
-
-}
-
-
-void
-setTest()
-{
-  char var_name[64];
-
-  for (int i = 1; i <= 5; i++) {
-    memset(var_name, 0, 64);
-    snprintf(var_name, sizeof(var_name), "proxy.node.stats.test%d", i);
-    if (i == 4) {
-      MgmtFloat tmp;
-      varFloatFromName("proxy.node.stats.test4", &tmp);
-      varSetFloat(var_name, tmp + 1, true);
-    } else {
-      varSetFloat(var_name, i, true);
-    }
-  }
-}
-
-
-void
-verifyTest()
-{
-  MgmtFloat tmp1, tmp2;
-
-  // 1. simple copy
-  varFloatFromName("proxy.node.stats.test1", &tmp1);
-  varFloatFromName("proxy.node.stats.test2", &tmp2);
-  if (tmp1 == tmp2) {
-    Debug(MODULE_INIT, "PASS -- simple copy");
-  } else {
-    Debug(MODULE_INIT, "FAIL -- simple copy");
-  }
-
-  // 2. simple interval
-  varFloatFromName("proxy.node.stats.test3", &tmp2);
-  if (tmp2 >= 10) {
-    Debug(MODULE_INIT, "PASS -- simple interval & constant");
-  } else {
-    Debug(MODULE_INIT, "FAIL -- simple interval & constant %f", tmp2);
-  }
-
-  // 3. delta
-  varFloatFromName("proxy.node.stats.test4", &tmp2);
-  if ((tmp2 > 150) && (tmp2 < 250)) {
-    Debug(MODULE_INIT, "PASS -- delta");
-  } else {
-    Debug(MODULE_INIT, "FAIL -- delta %f", tmp2);
-  }
-}
-
-
-/**
- * Updating the statistics NOW.
- **/
-unsigned short
-StatProcessor::processStat()
-{
-  unsigned short result = 0;
-
-  Debug(MODULE_INIT, "[StatProcessor] Processing Statistics....\n");
-
-//    setTest();
-  statObjectList.Eval();
-//    verifyTest();
-
-  return (result);
-}
-
-
-/**
- * ExpressionEval
- * --------------
- *
- */
-RecData
-ExpressionEval(char *exprString)
-{
-  RecDataT result_type;
-  StatObject statObject;
-
-  char content[BUFSIZ * 10];
-  XML_extractContent(exprString, content, BUFSIZ * 10);
-
-  statObject.assignExpr(content);
-  return statObject.NodeStatEval(&result_type, false);
-}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/StatProcessor.h
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatProcessor.h b/mgmt/stats/StatProcessor.h
deleted file mode 100644
index 71dab2f..0000000
--- a/mgmt/stats/StatProcessor.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-#ifndef _STAT_PROCESSOR_H_
-#define _STAT_PROCESSOR_H_
-
-/****************************************************************************
- *
- *  StatProcessor.h - Functions for computing node and cluster stat
- *                          aggregation
- *
- *
- ****************************************************************************/
-
-#include "ink_platform.h"
-#include <stdarg.h>
-#include "MgmtUtils.h"
-#include "MgmtDefs.h"
-#include "WebMgmtUtils.h"
-#include "ink_hrtime.h"
-#include "LocalManager.h"
-#include "WebOverview.h"
-
-#define _HEADER
-#define _D(x)
-#define _FOOTER
-#include "DynamicStats.h"
-#include "StatType.h"
-
-#if HAVE_LIBEXPAT
-#include "expat.h"
-typedef XML_Char xmlchar;
-#elif HAVE_LIBXML2
-#include <libxml/parser.h>
-#include <libxml/SAX.h>
-typedef xmlChar xmlchar;
-#else
-# error "No XML parser - please configure expat or libxml2"
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-class StatProcessor
-{
-public:
-
-  explicit StatProcessor(FileManager * configFiles);
-  ~StatProcessor();
-
-  // Member Fuctions
-  unsigned short processStat();
-  void rereadConfig(FileManager * configFiles);
-
-  LocalManager *m_lmgmt;
-  overviewPage *m_overviewGenerator;
-};
-
-
-/**
- * External expression evaluation API.
- *
- * INPUT: an expression string, e.g.:
- * "(proxy.node.user_agent_total_bytes-proxy.node.origin_server_total_bytes)
- *  / proxy.node.user_agent_total_bytes"
- *
- * RETURN: the resulting value of the expression.
- * NOTE: it returns -9999.0 if there is an error.
- *
- */
-
-RecData ExpressionEval(char *);
-
-#endif


[6/9] TS-2977: move the stats processor to traffic_manager

Posted by jp...@apache.org.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/StatType.cc
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatType.cc b/mgmt/stats/StatType.cc
deleted file mode 100644
index 1c51b95..0000000
--- a/mgmt/stats/StatType.cc
+++ /dev/null
@@ -1,1199 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-/***************************************/
-/****************************************************************************
- *
- *  StatType.cc - Functions for computing node and cluster stat
- *                          aggregation
- *
- *
- ****************************************************************************/
-
-#include "ink_config.h"
-#include "StatType.h"
-#include "MgmtUtils.h"
-#include "ink_hrtime.h"
-#include "WebOverview.h"
-
-bool StatError = false;         // global error flag
-bool StatDebug = false;         // global debug flag
-
-/**
- * StatExprToken()
- * ---------------
- */
-StatExprToken::StatExprToken()
-  : m_arith_symbol('\0'),
-    m_token_name(NULL),
-    m_token_type(RECD_NULL),
-    m_sum_var(false), m_node_var(true)
-{
-  RecDataClear(RECD_NULL, &m_token_value);
-  RecDataClear(RECD_NULL, &m_token_value_max);
-  RecDataClear(RECD_NULL, &m_token_value_min);
-  memset(&m_token_value_delta, 0, sizeof(m_token_value_delta));
-}
-
-
-/**
- * StatExprToken::copy()
- * ---------------------
- */
-void
-StatExprToken::copy(const StatExprToken & source)
-{
-  m_arith_symbol = source.m_arith_symbol;
-
-  if (source.m_token_name != NULL) {
-    m_token_name = ats_strdup(source.m_token_name);
-  }
-
-  m_token_type = source.m_token_type;
-  m_token_value = source.m_token_value;
-  m_token_value_min = source.m_token_value_min;
-  m_token_value_max = source.m_token_value_max;
-
-  if (source.m_token_value_delta) {
-    m_token_value_delta = new StatDataSamples();
-    m_token_value_delta->previous_time = source.m_token_value_delta->previous_time;
-    m_token_value_delta->current_time = source.m_token_value_delta->current_time;
-    m_token_value_delta->previous_value = source.m_token_value_delta->previous_value;
-    m_token_value_delta->current_value = source.m_token_value_delta->current_value;
-  }
-
-  m_node_var = source.m_node_var;
-  m_sum_var = source.m_sum_var;
-}
-
-
-/**
- * StatExprToken::assignTokenName()
- * --------------------------------
- *  Assign the token name. If the token is a predefined constant,
- *  assign the value as well. Also, assign the token type as well.
- */
-void
-StatExprToken::assignTokenName(const char *name)
-{
-
-  if (isdigit(name[0])) {
-    // numerical constant
-    m_token_name = ats_strdup("CONSTANT");
-    m_token_type = RECD_CONST;
-  } else {
-    m_token_name = ats_strdup(name);
-    assignTokenType();
-  }
-
-  switch (m_token_type) {
-  case RECD_INT:
-  case RECD_COUNTER:
-  case RECD_FLOAT:
-    break;
-  case RECD_CONST:
-    // assign pre-defined constant in here
-    // constant will be stored as RecFloat type.
-    if (!strcmp(m_token_name, "CONSTANT")) {
-      m_token_value.rec_float = (RecFloat) atof(name);
-    } else if (!strcmp(m_token_name, "$BYTES_TO_MB_SCALE")) {
-      m_token_value.rec_float = (RecFloat) BYTES_TO_MB_SCALE;
-    } else if (!strcmp(m_token_name, "$MBIT_TO_KBIT_SCALE")) {
-      m_token_value.rec_float = (RecFloat) MBIT_TO_KBIT_SCALE;
-    } else if (!strcmp(m_token_name, "$SECOND_TO_MILLISECOND_SCALE")) {
-      m_token_value.rec_float = (RecFloat) SECOND_TO_MILLISECOND_SCALE;
-    } else if (!strcmp(m_token_name, "$PCT_TO_INTPCT_SCALE")) {
-      m_token_value.rec_float = (RecFloat) PCT_TO_INTPCT_SCALE;
-    } else if (!strcmp(m_token_name, "$HRTIME_SECOND")) {
-      m_token_value.rec_float = (RecFloat) HRTIME_SECOND;
-    } else if (!strcmp(m_token_name, "$BYTES_TO_MBIT_SCALE")) {
-      m_token_value.rec_float = (RecFloat) BYTES_TO_MBIT_SCALE;
-    } else {
-      mgmt_log(stderr, "[StatPro] ERROR: Undefined constant: %s\n", m_token_name);
-      StatError = true;
-    }
-  case RECD_FX:
-  default:
-    break;
-  }
-}
-
-
-/**
- * assignTokenType()
- * -----------------
- * Assign the proper token type based on the token name.
- * Do some token type conversion if necessary. Return true
- * if the token type is recognizable; false otherwise.
- */
-bool StatExprToken::assignTokenType()
-{
-  ink_assert(m_token_name != NULL);
-  m_token_type = varType(m_token_name);
-
-  if (m_token_name[0] == '$') {
-    m_token_type = RECD_CONST;
-  } else if (m_token_name[0] == '_') {
-    m_token_type = RECD_FX;
-  }
-
-  if (m_token_value_delta) {
-    m_token_value_delta->data_type = m_token_type;
-  }
-
-  // I'm guessing here that we want to check if we're still RECD_NULL,
-  // it used to be INVALID, which is not in the m_token_type's enum. /leif
-  return (m_token_type != RECD_NULL);
-}
-
-
-void
-StatExprToken::clean()
-{
-  ats_free(m_token_name);
-  delete m_token_value_delta;
-}
-
-
-/**
- * FOR DEBUGGING ONLY
- * Print the token according to its type in a human-readable format. :)
- */
-void
-StatExprToken::print(const char *prefix)
-{
-  if (m_token_name != NULL) {
-    printf("%s\t%s\n", prefix, m_token_name);
-  } else {
-    printf("%s\t%c\n", prefix, m_arith_symbol);
-  }
-}
-
-
-/**
- * StatExprToken::precedence()
- * ---------------------------
- * Return the binary operator precedence. The higher returning value,
- * the higher the precedence value.
- */
-short
-StatExprToken::precedence()
-{
-  switch (m_arith_symbol) {
-  case '(':
-    return 4;
-  case '^':                    // fall through
-  case '!':
-    return 3;
-  case '*':                    // fall through
-  case '/':
-    return 2;
-  case '+':                    // fall through
-  case '-':
-    return 1;
-  default:
-    return -1;
-  }
-}
-
-
-/**
- * StatExprToken::statVarSet()
- * ---------------------------
- * This method is responsible for ensuring the assigning value
- * fall within the min. and max. bound. If it's smaller than min.
- * or larger than max, then the error value is assigned. If no
- * error value is assigned, either min. or max. is assigned.
- */
-bool StatExprToken::statVarSet(RecDataT type, RecData value)
-{
-  RecData converted_value;
-
-  if (StatError) {
-    /* fix this after librecords is done
-       mgmt_log(stderr,
-       "[StatPro] ERROR in a statistics aggregation operations\n");
-     */
-    RecData err_value;
-    RecDataClear(m_token_type, &err_value);
-    return varSetData(m_token_type, m_token_name, err_value);
-  }
-
-  /*
-   * do conversion if necessary.
-   */
-  if (m_token_type != type) {
-    switch (m_token_type) {
-    case RECD_INT:
-    case RECD_COUNTER:
-      if (type == RECD_NULL)
-        converted_value = value;
-      else if (type == RECD_INT || type == RECD_COUNTER || type == RECD_FX)
-        converted_value.rec_int = value.rec_int;
-      else if (type == RECD_FLOAT || type == RECD_CONST)
-        converted_value.rec_int = (RecInt)value.rec_float;
-      else
-        Fatal("%s, invalid value type:%d\n", m_token_name, type);
-      break;
-    case RECD_FLOAT:
-      if (type == RECD_NULL)
-        converted_value = value;
-      else if (type == RECD_INT || type == RECD_COUNTER || type == RECD_FX)
-        converted_value.rec_float = (RecFloat)value.rec_int;
-      else if (type == RECD_FLOAT || type == RECD_CONST)
-        converted_value.rec_float = value.rec_float;
-      else
-        Fatal("%s, invalid value type:%d\n", m_token_name, type);
-      break;
-    default:
-      Fatal("%s, unsupported token type:%d\n", m_token_name, m_token_type);
-    }
-  } else {
-    converted_value = value;
-  }
-
-  if (RecDataCmp(m_token_type, converted_value, m_token_value_min) < 0) {
-    value = m_token_value_min;
-  }
-  else if (RecDataCmp(m_token_type, converted_value, m_token_value_max) > 0) {
-    value = m_token_value_max;
-  }
-
-  return varSetData(m_token_type, m_token_name, converted_value);
-}
-
-
-/***********************************************************************
-					    	 StatExprList
- **********************************************************************/
-
-/**
- * StatExprList::StatExprList()
- * ----------------------------
- */
-StatExprList::StatExprList()
- : m_size(0)
-{
-}
-
-
-/**
- * StatExprList::clean()
- * ---------------------
- */
-void
-StatExprList::clean()
-{
-  StatExprToken *temp = NULL;
-
-  while ((temp = m_tokenList.dequeue())) {
-    delete(temp);
-    m_size -= 1;
-  }
-  ink_assert(m_size == 0);
-}
-
-
-void
-StatExprList::enqueue(StatExprToken * entry)
-{
-  ink_assert(entry);
-  m_tokenList.enqueue(entry);
-  m_size += 1;
-}
-
-
-void
-StatExprList::push(StatExprToken * entry)
-{
-  ink_assert(entry);
-  m_tokenList.push(entry);
-  m_size += 1;
-}
-
-
-StatExprToken *
-StatExprList::dequeue()
-{
-  if (m_size == 0) {
-    return NULL;
-  }
-  m_size -= 1;
-  return (StatExprToken *) m_tokenList.dequeue();
-}
-
-
-StatExprToken *
-StatExprList::pop()
-{
-  if (m_size == 0) {
-    return NULL;
-  }
-  m_size -= 1;
-  return m_tokenList.pop();
-}
-
-
-StatExprToken *
-StatExprList::top()
-{
-  if (m_size == 0) {
-    return NULL;
-  }
-  return m_tokenList.head;
-}
-
-
-StatExprToken *
-StatExprList::first()
-{
-  if (m_size == 0) {
-    return NULL;
-  }
-  return m_tokenList.head;
-}
-
-
-StatExprToken *
-StatExprList::next(StatExprToken * current)
-{
-  if (!current) {
-    return NULL;
-  }
-  return (current->link).next;
-}
-
-
-/**
- * StatExprList::print()
- * ---------------------
- *  Print the token in the expression in a human-readable format. :)
- */
-void
-StatExprList::print(const char *prefix)
-{
-  for (StatExprToken * token = first(); token; token = next(token)) {
-    token->print(prefix);
-  }
-}
-
-
-/**
- * StatExprToken::count()
- * ----------------------
- * Counts the number of token in the expression list and return it.
- */
-unsigned
-StatExprList::count()
-{
-  return m_size;
-}
-
-
-/***********************************************************************
- 					    	     StatObject
- **********************************************************************/
-
-
-/**
- * StatObject::StatObject()
- * ------------------------
- */
-
-StatObject::StatObject()
- : m_id(1),
-   m_debug(false),
-   m_expr_string(NULL),
-   m_node_dest(NULL),
-   m_cluster_dest(NULL),
-   m_expression(NULL),
-   m_postfix(NULL),
-   m_last_update(-1),
-   m_current_time(-1), m_update_interval(-1),
-   m_stats_max(FLT_MAX), m_stats_min(FLT_MIN),
-   m_has_max(false), m_has_min(false), m_has_delta(false)
-{
-}
-
-
-StatObject::StatObject(unsigned identifier)
-  : m_id(identifier),
-    m_debug(false),
-    m_expr_string(NULL),
-    m_node_dest(NULL),
-    m_cluster_dest(NULL),
-    m_expression(NULL),
-    m_postfix(NULL),
-    m_last_update(-1),
-    m_current_time(-1), m_update_interval(-1),
-    m_stats_max(FLT_MAX), m_stats_min(FLT_MIN),
-    m_has_max(false), m_has_min(false), m_has_delta(false)
-{
-}
-
-
-/**
- * StatObject::clean()
- * -------------------
- */
-void
-StatObject::clean()
-{
-  ats_free(m_expr_string);
-  delete m_node_dest;
-  delete m_cluster_dest;
-  delete m_postfix;
-}
-
-
-/**
- * StatObject::assignDst()
- * -----------------------
- */
-void
-StatObject::assignDst(const char *str, bool m_node_var, bool m_sum_var)
-{
-  if (StatDebug) {
-    Debug(MODULE_INIT, "DESTINTATION: %s\n", str);
-  }
-
-  StatExprToken *statToken = new StatExprToken();
-
-  statToken->assignTokenName(str);
-  statToken->m_node_var = m_node_var;
-  statToken->m_sum_var = m_sum_var;
-
-  // The type of dst token should be always not NULL
-  if (statToken->m_token_type == RECD_NULL) {
-    Fatal("token:%s, invalid token type!", statToken->m_token_name);
-  }
-
-  // Set max/min value
-  if (m_has_max)
-    RecDataSetFromFloat(statToken->m_token_type, &statToken->m_token_value_max,
-                        m_stats_max);
-  else
-    RecDataSetMax(statToken->m_token_type, &statToken->m_token_value_max);
-
-  if (m_has_min)
-    RecDataSetFromFloat(statToken->m_token_type, &statToken->m_token_value_min,
-                        m_stats_min);
-  else
-    RecDataSetMin(statToken->m_token_type, &statToken->m_token_value_min);
-
-  if (m_node_var) {
-    ink_assert(m_node_dest == NULL);
-    m_node_dest = statToken;
-  } else {
-    ink_assert(m_cluster_dest == NULL);
-    m_cluster_dest = statToken;
-  }
-}
-
-
-/**
- * StatObject::assignExpr()
- * ------------------------
- */
-void
-StatObject::assignExpr(char *str)
-{
-  StatExprToken *statToken = NULL;
-
-  if (StatDebug) {
-    Debug(MODULE_INIT, "EXPRESSION: %s\n", str);
-  }
-  ink_assert(m_expr_string == NULL);
-  // We take ownership here
-  m_expr_string = str;
-
-  Tokenizer exprTok(" ");
-  exprTok.Initialize(str);
-  tok_iter_state exprTok_state;
-  const char *token = exprTok.iterFirst(&exprTok_state);
-
-  ink_assert(m_expression == NULL);
-  m_expression = new StatExprList();
-
-  while (token) {
-
-    statToken = new StatExprToken();
-
-    if (isOperator(token[0])) {
-
-      statToken->m_arith_symbol = token[0];
-      ink_assert(statToken->m_token_name == NULL);
-
-      if (StatDebug) {
-        Debug(MODULE_INIT, "\toperator: ->%c<-\n", statToken->m_arith_symbol);
-      }
-
-    } else {
-
-      ink_assert(statToken->m_arith_symbol == '\0');
-
-      // delta
-      if (token[0] == '#') {
-
-        token += 1;             // skip '#'
-        statToken->m_token_value_delta = new StatDataSamples();
-        statToken->m_token_value_delta->previous_time = (ink_hrtime) 0;
-        statToken->m_token_value_delta->current_time = (ink_hrtime) 0;
-        statToken->m_token_value_delta->data_type = RECD_NULL;
-        RecDataClear(RECD_NULL, &statToken->m_token_value_delta->previous_value);
-        RecDataClear(RECD_NULL, &statToken->m_token_value_delta->current_value);
-
-      }
-
-      statToken->assignTokenName(token);
-
-      if (StatDebug) {
-        Debug(MODULE_INIT, "\toperand:  ->%s<-\n", token);
-      }
-
-    }
-
-    token = exprTok.iterNext(&exprTok_state);
-    m_expression->enqueue(statToken);
-
-  }
-
-  infix2postfix();
-
-}
-
-
-/**
- * StatObject::infix2postfix()
- * ---------------------------
- * Takes the infix "expression" and convert it to a postfix for future
- * evaluation.
- *
- * SIDE EFFECT: consume all token in "expression"
- */
-void
-StatObject::infix2postfix()
-{
-  StatExprList stack;
-  StatExprToken *tempToken = NULL;
-  StatExprToken *curToken = NULL;
-  m_postfix = new StatExprList();
-
-  while (m_expression->top()) {
-    curToken = m_expression->dequeue();
-
-    if (!isOperator(curToken->m_arith_symbol)) {
-      //printf("I2P~: enqueue %s\n", curToken->m_token_name);
-      m_postfix->enqueue(curToken);
-
-    } else {
-      ink_assert(curToken->m_arith_symbol != '\0');
-
-      if (curToken->m_arith_symbol == '(') {
-        stack.push(curToken);
-      } else if (curToken->m_arith_symbol == ')') {
-        tempToken = (StatExprToken *) stack.pop();
-
-        while (tempToken->m_arith_symbol != '(') {
-          //printf("I2P@: enqueue %c\n", tempToken->m_arith_symbol);
-          m_postfix->enqueue(tempToken);
-          tempToken = (StatExprToken *) stack.pop();
-        }
-
-        // Free up memory for ')'
-        delete(curToken);
-        delete(tempToken);
-
-      } else {
-        if (stack.count() == 0) {
-          stack.push(curToken);
-        } else {
-          tempToken = (StatExprToken *) stack.top();
-
-          while ((tempToken->m_arith_symbol != '(') && (tempToken->precedence() >= curToken->precedence())) {
-            tempToken = (StatExprToken *) stack.pop();  // skip the (
-            //printf("I2P$: enqueue %c\n", tempToken->m_arith_symbol);
-            m_postfix->enqueue(tempToken);
-            if (stack.count() == 0) {
-              break;
-            }
-            tempToken = (StatExprToken *) stack.top();
-          }                     // while
-
-          stack.push(curToken);
-        }
-      }
-    }
-  }
-
-  while (stack.count() > 0) {
-    tempToken = (StatExprToken *) stack.pop();
-    //printf("I2P?: enqueue %c\n", tempToken->m_arith_symbol);
-    m_postfix->enqueue(tempToken);
-  }
-
-  // dump infix expression
-  delete(m_expression);
-  m_expression = NULL;
-}
-
-
-/**
- * StatObject::NodeStatEval()
- * --------------------------
- *
- *
- */
-RecData StatObject::NodeStatEval(RecDataT *result_type, bool cluster)
-{
-  StatExprList stack;
-  StatExprToken *left = NULL;
-  StatExprToken *right = NULL;
-  StatExprToken *result = NULL;
-  StatExprToken *curToken = NULL;
-  RecData tempValue;
-  RecDataClear(RECD_NULL, &tempValue);
-
-  *result_type = RECD_NULL;
-
-  /* Express checkout lane -- Stat. object with on 1 source variable */
-  if (m_postfix->count() == 1) {
-    StatExprToken * src = m_postfix->top();
-
-    // in librecords, not all statistics are register at initialization
-    // must assign proper type if it is undefined.
-    if (src->m_token_type == RECD_NULL) {
-      src->assignTokenType();
-    }
-
-    *result_type = src->m_token_type;
-    if (src->m_token_type == RECD_CONST) {
-      tempValue = src->m_token_value;
-    } else if (src->m_token_value_delta) {
-      tempValue = src->m_token_value_delta->diff_value(src->m_token_name);
-    } else if (!cluster) {
-      if (!varDataFromName(src->m_token_type, src->m_token_name, &tempValue)) {
-        RecDataClear(src->m_token_type, &tempValue);
-      }
-    } else {
-      if (!overviewGenerator->varClusterDataFromName(src->m_token_type,
-                                                     src->m_token_name,
-                                                     &tempValue)) {
-        RecDataClear(src->m_token_type, &tempValue);
-      }
-    }
-  } else {
-
-    /* standard postfix evaluation */
-    for (StatExprToken * token = m_postfix->first(); token; token = m_postfix->next(token)) {
-      /* carbon-copy the token. */
-      curToken = new StatExprToken();
-      curToken->copy(*token);
-
-      if (!isOperator(curToken->m_arith_symbol)) {
-        stack.push(curToken);
-      } else {
-        ink_assert(isOperator(curToken->m_arith_symbol));
-        right = stack.pop();
-        left = stack.pop();
-
-        if (left->m_token_type == RECD_NULL) {
-          left->assignTokenType();
-        }
-        if (right->m_token_type == RECD_NULL) {
-          right->assignTokenType();
-        }
-
-        result = StatBinaryEval(left, curToken->m_arith_symbol, right, cluster);
-
-        stack.push(result);
-        delete(curToken);
-        delete(left);
-        delete(right);
-      }
-    }
-
-    /* should only be 1 value left on stack -- the resulting value */
-    if (stack.count() > 1) {
-      stack.print("\t");
-      ink_assert(false);
-    }
-
-    *result_type = stack.top()->m_token_type;
-    tempValue = stack.top()->m_token_value;
-  }
-
-  return tempValue;
-
-}
-
-
-/**
- * StatObject::ClusterStatEval()
- * -----------------------------
- *
- *
- */
-RecData StatObject::ClusterStatEval(RecDataT *result_type)
-{
-  /* Sanity check */
-  ink_assert(m_cluster_dest && !m_cluster_dest->m_node_var);
-
-  // what is this?
-  if ((m_node_dest == NULL) || (m_cluster_dest->m_sum_var == false)) {
-    return NodeStatEval(result_type, true);
-  } else {
-    RecData tempValue;
-
-    if (!overviewGenerator->varClusterDataFromName(m_node_dest->m_token_type,
-                                                   m_node_dest->m_token_name,
-                                                   &tempValue)) {
-      *result_type = RECD_NULL;
-      RecDataClear(*result_type, &tempValue);
-    }
-
-    return (tempValue);
-  }
-}
-
-
-/**
- * StatObject::setTokenValue()
- * ---------------------------
- * The logic of the following code segment is the following.
- * The objective is to extract the appropriate right->m_token_value.
- * If 'right' is an intermediate value, nothing to do.
- * If m_token_type is RECD_CONST, nothing to do.
- * If m_token_type is RECD_FX, right->m_token_value is the diff. in time.
- * If m_token_type is either RECD_INT or RECD_FLOAT, it can either
- * by a cluster variable or a node variable.
- *     If it is a cluster variable, just use varClusterFloatFromName
- *     to set right->m_token_value.
- *     If it is a node variable, then it can either be a variable
- *     with delta. To determine whether it has a delta, simply search
- *     the m_token_name in the delta list. If found then it has delta.
- *     If it has delta then use the delta's diff. in value,
- *     otherwise simply set right->m_token_value with varFloatFromName.
- */
-void
-StatObject::setTokenValue(StatExprToken * token, bool cluster)
-{
-  if (token->m_token_name) {
-    // it is NOT an intermediate value
-
-    switch (token->m_token_type) {
-    case RECD_CONST:
-      break;
-
-    case RECD_FX:
-      // only support time function
-      // use rec_int to store time value
-      token->m_token_value.rec_int = (m_current_time - m_last_update);
-      break;
-
-    case RECD_INT:             // fallthought
-    case RECD_COUNTER:
-    case RECD_FLOAT:
-      if (cluster) {
-        if (!overviewGenerator->varClusterDataFromName(token->m_token_type,
-                                                       token->m_token_name,
-                                                       &(token->m_token_value)))
-        {
-          RecDataClear(token->m_token_type, &token->m_token_value);
-        }
-      } else {
-        if (token->m_token_value_delta) {
-          token->m_token_value =
-            token->m_token_value_delta->diff_value(token->m_token_name);
-        } else {
-          if (!varDataFromName(token->m_token_type, token->m_token_name,
-                               &(token->m_token_value))) {
-            RecDataClear(token->m_token_type, &token->m_token_value);
-          }
-        }                       // delta?
-      }                         // cluster?
-      break;
-
-    default:
-      if (StatDebug) {
-        Debug(MODULE, "Unrecognized token \"%s\" of type %d.\n",
-              token->m_token_name, token->m_token_type);
-      }
-    }                           // switch
-  }                             // m_token_name?
-}
-
-
-/**
- * StatObject::StatBinaryEval()
- * ------------------------
- * Take the left token, the right token, an binary operation and perform an
- * arithmatic operations on them. This function is responsible for getting the
- * correct value from:
- * - (1) node variable
- * - (2) node variable with a delta structure
- * - (3) cluster variable
- * - (4) an immediate value
- */
-StatExprToken *StatObject::StatBinaryEval(StatExprToken * left, char op,
-                                          StatExprToken * right, bool cluster)
-{
-  RecData l, r;
-  StatExprToken *result = new StatExprToken();
-  result->m_token_type = RECD_INT;
-
-  if (left->m_token_type == RECD_NULL
-      && right->m_token_type == RECD_NULL) {
-    return result;
-  }
-
-  if (left->m_token_type != RECD_NULL) {
-    setTokenValue(left, cluster);
-    result->m_token_type = left->m_token_type;
-  }
-
-  if (right->m_token_type != RECD_NULL) {
-    setTokenValue(right, cluster);
-    switch (result->m_token_type) {
-    case RECD_NULL:
-      result->m_token_type = right->m_token_type;
-      break;
-    case RECD_FX:
-    case RECD_INT:
-    case RECD_COUNTER:
-      /*
-       * When types of left and right are different, select RECD_FLOAT
-       * as result type. It's may lead to loss of precision when do
-       * conversion, be careful!
-       */
-      if (right->m_token_type == RECD_FLOAT
-          || right->m_token_type == RECD_CONST) {
-        result->m_token_type = right->m_token_type;
-      }
-      break;
-    case RECD_CONST:
-    case RECD_FLOAT:
-      break;
-    default:
-      Fatal("Unexpected RecData Type:%d", result->m_token_type);
-      break;
-    }
-  }
-
-  /*
-   * We should make the operands with the same type before calculating.
-   */
-  RecDataClear(RECD_NULL, &l);
-  RecDataClear(RECD_NULL, &r);
-
-  if (left->m_token_type == right->m_token_type ) {
-    l = left->m_token_value;
-    r = right->m_token_value;
-  } else if (result->m_token_type != left->m_token_type) {
-    if (left->m_token_type != RECD_NULL) {
-      ink_assert(result->m_token_type == RECD_FLOAT
-                 || result->m_token_type == RECD_CONST);
-
-      l.rec_float = (RecFloat)left->m_token_value.rec_int;
-    }
-    r = right->m_token_value;
-    ink_assert(result->m_token_type == right->m_token_type);
-  } else {
-    l = left->m_token_value;
-    if (right->m_token_type != RECD_NULL) {
-      ink_assert(result->m_token_type == RECD_FLOAT
-                 || result->m_token_type == RECD_CONST);
-
-      r.rec_float = (RecFloat)right->m_token_value.rec_int;
-    }
-    ink_assert(result->m_token_type == left->m_token_type);
-  }
-
-  /*
-   * Start to calculate
-   */
-  switch (op) {
-  case '+':
-    result->m_token_value = RecDataAdd(result->m_token_type, l, r);
-    break;
-
-  case '-':
-    result->m_token_value = RecDataSub(result->m_token_type, l, r);
-    break;
-
-  case '*':
-    result->m_token_value = RecDataMul(result->m_token_type, l, r);
-    break;
-
-  case '/':
-    RecData recTmp;
-    RecDataClear(RECD_NULL, &recTmp);
-
-    /*
-     * Force the type of result to be RecFloat on div operation
-     */
-    if (result->m_token_type != RECD_FLOAT && result->m_token_type != RECD_CONST) {
-      RecFloat t;
-
-      result->m_token_type = RECD_FLOAT;
-
-      t = (RecFloat)l.rec_int;
-      l.rec_float = t;
-
-      t = (RecFloat)r.rec_int;
-      r.rec_float = t;
-    }
-
-    if (RecDataCmp(result->m_token_type, r, recTmp)) {
-      result->m_token_value = RecDataDiv(result->m_token_type, l, r);
-    }
-    break;
-
-  default:
-    // should never reach here
-    StatError = true;
-  }
-
-  return (result);
-}
-
-
-/***********************************************************************
- 					    	   StatObjectList
- **********************************************************************/
-
-StatObjectList::StatObjectList()
- : m_size(0)
-{
-}
-
-
-void
-StatObjectList::clean()
-{
-  StatObject *temp = NULL;
-
-  while ((temp = m_statList.dequeue())) {
-    m_size -= 1;
-    delete(temp);
-  }
-
-  ink_assert(m_size == 0);
-}
-
-
-void
-StatObjectList::enqueue(StatObject * object)
-{
-  for (StatExprToken * token = object->m_postfix->first(); token; token = object->m_postfix->next(token)) {
-    if (token->m_token_value_delta) {
-      object->m_has_delta = true;
-      break;
-    }
-  }
-
-  m_statList.enqueue(object);
-  m_size += 1;
-}
-
-
-StatObject *
-StatObjectList::first()
-{
-  return m_statList.head;
-}
-
-
-StatObject *
-StatObjectList::next(StatObject * current)
-{
-  return (current->link).next;
-}
-
-
-/**
- * StatObjectList::Eval()
- * ----------------------
- * The statisitic processor entry point to perform the calculation.
- */
-short
-StatObjectList::Eval()
-{
-  RecData tempValue;
-  RecData result;
-  RecDataT result_type;
-  ink_hrtime threshold = 0;
-  ink_hrtime delta = 0;
-  short count = 0;
-
-  RecDataClear(RECD_NULL, &tempValue);
-  RecDataClear(RECD_NULL, &result);
-
-  for (StatObject * object = first(); object; object = next(object)) {
-    StatError = false;
-    StatDebug = object->m_debug;
-
-    if (StatDebug) {
-      Debug(MODULE, "\n##### %d #####\n", object->m_id);
-    }
-
-    if (object->m_update_interval <= 0) {
-      // non-time statistics
-      object->m_current_time = ink_get_hrtime_internal();
-
-      if (object->m_node_dest) {
-        result = object->NodeStatEval(&result_type, false);
-        object->m_node_dest->statVarSet(result_type, result);
-      }
-
-      if (object->m_cluster_dest) {
-        result = object->ClusterStatEval(&result_type);
-        object->m_cluster_dest->statVarSet(result_type, result);
-      }
-
-      object->m_last_update = object->m_current_time;
-    } else {
-      // timed statisitics
-      object->m_current_time = ink_get_hrtime_internal();
-
-      threshold = object->m_update_interval * HRTIME_SECOND;
-      delta = object->m_current_time - object->m_last_update;
-
-      if (StatDebug) {
-        Debug(MODULE, "\tUPDATE:%" PRId64 " THRESHOLD:%" PRId64 ", DELTA:%" PRId64 "\n", object->m_update_interval, threshold, delta);
-      }
-
-      /* Should we do the calculation? */
-      if ((delta > threshold) ||        /* sufficient elapsed time? */
-          (object->m_last_update == -1) ||      /*       first time?       */
-          (object->m_last_update > object->m_current_time)) {   /*wrapped */
-
-        if (StatDebug) {
-          if (delta > threshold) {
-            Debug(MODULE, "\t\tdelta > threshold IS TRUE!\n");
-          }
-          if (object->m_last_update == -1) {
-            Debug(MODULE, "\t\tm_last_update = -1 IS TRUE!\n");
-          }
-          if (object->m_last_update > object->m_current_time) {
-            Debug(MODULE, "\t\tm_last_update > m_current_time IS TRUE\n");
-          }
-        }
-
-        if (!object->m_has_delta) {
-
-          if (StatDebug) {
-            Debug(MODULE, "\tEVAL: Simple time-condition.\n");
-          }
-
-          if (object->m_node_dest) {
-            result = object->NodeStatEval(&result_type, false);
-            object->m_node_dest->statVarSet(result_type, result);
-          }
-
-          if (object->m_cluster_dest) {
-            result = object->ClusterStatEval(&result_type);
-            object->m_cluster_dest->statVarSet(result_type, result);
-          }
-
-          object->m_last_update = object->m_current_time;
-        } else {
-          /* has delta */
-          if (StatDebug) {
-            Debug(MODULE, "\tEVAL: Complicated time-condition.\n");
-          }
-          // scroll old values
-          for (StatExprToken * token = object->m_postfix->first(); token; token = object->m_expression->next(token)) {
-
-            // in librecords, not all statistics are register at initialization
-            // must assign proper type if it is undefined.
-            if (!isOperator(token->m_arith_symbol) && token->m_token_type == RECD_NULL) {
-              token->assignTokenType();
-            }
-
-            if (token->m_token_value_delta) {
-              if (!varDataFromName(token->m_token_type, token->m_token_name,
-                                   &tempValue)) {
-                RecDataClear(RECD_NULL, &tempValue);
-              }
-
-              token->m_token_value_delta->previous_time = token->m_token_value_delta->current_time;
-              token->m_token_value_delta->previous_value = token->m_token_value_delta->current_value;
-              token->m_token_value_delta->current_time = object->m_current_time;
-              token->m_token_value_delta->current_value = tempValue;
-            }
-          }
-
-          if (delta > threshold) {
-            if (object->m_node_dest) {
-              result = object->NodeStatEval(&result_type, false);
-              object->m_node_dest->statVarSet(result_type, result);
-            }
-
-            if (object->m_cluster_dest) {
-              result = object->ClusterStatEval(&result_type);
-              object->m_cluster_dest->statVarSet(result_type, result);
-            }
-
-            object->m_last_update = object->m_current_time;
-          } else {
-            if (StatDebug) {
-              Debug(MODULE, "\tEVAL: Timer not expired, do nothing\n");
-            }
-          }
-        }                       /* delta? */
-      } else {
-        if (StatDebug) {
-          Debug(MODULE, "\tEVAL: Timer not expired, nor 1st time, nor wrapped, SORRY!\n");
-        }
-      }                         /* timed event */
-    }
-    count += 1;
-  }                             /* for */
-
-  return count;
-}                               /* Eval() */
-
-
-/**
- * StatObjectList::print()
- * --------------------------
- * Print the list of of statistics object in a human-readable format. :)
- */
-void
-StatObjectList::print(const char *prefix)
-{
-  for (StatObject * object = first(); object; object = next(object)) {
-    if (StatDebug) {
-      Debug(MODULE, "\n%sSTAT OBJECT#: %d\n", prefix, object->m_id);
-    }
-
-    if (object->m_expression) {
-      object->m_expression->print("\t");
-    }
-
-    if (object->m_postfix) {
-      object->m_postfix->print("\t");
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/StatType.h
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatType.h b/mgmt/stats/StatType.h
deleted file mode 100644
index 673e1e7..0000000
--- a/mgmt/stats/StatType.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-/***************************************/
-/****************************************************************************
- *
- *  StatType.h - Functions for computing node and cluster stat
- *                          aggregation
- *
- *
- ****************************************************************************/
-
-#ifndef _STATTYPE_H_
-#define	_STATTYPE_H_
-
-#include "StatXML.h"
-#include "Main.h"               // Debug()
-#include "WebMgmtUtils.h"
-
-#define BYTES_TO_MBIT_SCALE (8/1000000.0)
-
-/* Structs used in Average Statistics calculations */
-struct StatDataSamples
-{
-  ink_hrtime previous_time;
-  ink_hrtime current_time;
-  RecDataT data_type;
-  RecData previous_value;
-  RecData current_value;
-
-  RecData diff_value(const char *name)
-  {
-    RecData tmp;
-
-    if (data_type == RECD_NULL) {
-      data_type = varType(name);
-    }
-
-    if (data_type != RECD_NULL)
-      return RecDataSub(data_type, current_value, previous_value);
-    else {
-      RecDataClear(RECD_NULL, &tmp);
-      return tmp;
-    }
-  }
-  ink_hrtime diff_time()
-  {
-    return (current_time - previous_time);
-  }
-};
-
-// Urgly workaround -- no optimization in HPUX
-#if defined(hpux)
-#define inline
-#endif
-
-#define MODULE      "StatPro"   // Statistics processor debug tag
-#define MODULE_INIT "StatProInit"       // Statistics processor debug tag
-
-/***************************************************************
- *                       StatExprToken
- * a statistics expression token can either be a binary operator,
- * name '+', '-', '*', '/', or parenthesis '(', ')' or a TS variable.
- * In the former case, the arithSymbol stores the operator or
- * paranthesis; otherwise arithSymbol is '/0';
- ***************************************************************/
-class StatExprToken
-{
-
-public:
-
-  char m_arith_symbol;
-  char *m_token_name;
-  RecDataT m_token_type;
-  RecData m_token_value;
-  RecData m_token_value_max;
-  RecData m_token_value_min;
-  StatDataSamples *m_token_value_delta;
-  bool m_sum_var;
-  bool m_node_var;
-
-  // Member Functions
-  void assignTokenName(const char *);
-  bool assignTokenType();
-  void print(const char *);
-  short precedence();
-  void copy(const StatExprToken &);
-
-  LINK(StatExprToken, link);
-  StatExprToken();
-  inline ~ StatExprToken()
-  {
-    clean();
-  };
-  void clean();
-
-  bool statVarSet(RecDataT, RecData);
-};
-
-
-/**
- * StatExprList
- *   simply a list of StatExprToken.
- **/
-class StatExprList
-{
-
-public:
-
-  StatExprList();
-  inline ~ StatExprList()
-  {
-    clean();
-  };
-  void clean();
-
-  void enqueue(StatExprToken *);
-  void push(StatExprToken *);
-  StatExprToken *dequeue();
-  StatExprToken *pop();
-  StatExprToken *top();
-  StatExprToken *first();
-  StatExprToken *next(StatExprToken *);
-  unsigned count();
-  void print(const char *);
-
-private:
-
-  size_t m_size;
-  Queue<StatExprToken> m_tokenList;
-};
-
-/***************************************************************
- *                        StatObject
- * Each entry in the statistics XML file is represented by a
- * StatObject.
- ***************************************************************/
-class StatObject
-{
-
-public:
-
-  unsigned m_id;
-  bool m_debug;
-  char *m_expr_string;          /* for debugging using only */
-  StatExprToken *m_node_dest;
-  StatExprToken *m_cluster_dest;
-  StatExprList *m_expression;
-  StatExprList *m_postfix;
-  ink_hrtime m_last_update;
-  ink_hrtime m_current_time;
-  ink_hrtime m_update_interval;
-  RecFloat m_stats_max;
-  RecFloat m_stats_min;
-  bool m_has_max;
-  bool m_has_min;
-  bool m_has_delta;
-  LINK(StatObject, link);
-
-  // Member functions
-  StatObject();
-  StatObject(unsigned);
-  inline ~ StatObject()
-  {
-    clean();
-  };
-  void clean();
-  void assignDst(const char *, bool, bool);
-  void assignExpr(char *);
-
-  StatExprToken *StatBinaryEval(StatExprToken *, char, StatExprToken *, bool cluster = false);
-  RecData NodeStatEval(RecDataT *result_type, bool cluster);
-  RecData ClusterStatEval(RecDataT *result_type);
-  void setTokenValue(StatExprToken *, bool cluster = false);
-
-private:
-
-  void infix2postfix();
-};
-
-
-/**
- * StatObjectList
- *    simply a list of StatObject.
- **/
-class StatObjectList
-{
-
-public:
-
-  // Member functions
-  StatObjectList();
-  inline ~ StatObjectList()
-  {
-    clean();
-  };
-  void clean();
-  void enqueue(StatObject * object);
-  StatObject *first();
-  StatObject *next(StatObject * current);
-  void print(const char *prefix = "");
-  short Eval();                 // return the number of statistics object processed
-
-  size_t m_size;
-
-private:
-
-  Queue<StatObject> m_statList;
-};
-
-#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/StatXML.cc
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatXML.cc b/mgmt/stats/StatXML.cc
deleted file mode 100644
index 277b84a..0000000
--- a/mgmt/stats/StatXML.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-#include "ink_config.h"
-#include "StatXML.h"
-#include <stdlib.h>
-#include <ctype.h>
-
-//
-// Extract the text between a pair of XML tag and returns the length
-// of the extracted text.
-//
-unsigned short
-XML_extractContent(const char *name, char *content, size_t result_len)
-{
-
-  char c;
-  int contentIndex = 0;
-
-  memset(content, 0, result_len);
-  for (unsigned short nameIndex = 0; name[nameIndex] != '<'; nameIndex += 1) {
-    c = name[nameIndex];
-
-    if (isspace(c)) {
-      continue;
-    }
-
-    if (isOperator(c)) {
-      content[contentIndex++] = ' ';
-      content[contentIndex++] = c;
-      content[contentIndex++] = ' ';
-    } else {
-      content[contentIndex++] = c;
-    }
-  }
-
-  return (strlen(content));
-
-}
-
-
-//
-// Returns true  if 'c'is an operator (in our definition),
-//         false otherwise
-//
-bool
-isOperator(char c)
-{
-
-  switch (c) {
-  case '+':
-  case '-':
-  case '*':
-  case '/':
-  case '(':
-  case ')':
-    return true;
-  default:
-    return false;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/StatXML.h
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatXML.h b/mgmt/stats/StatXML.h
deleted file mode 100644
index b31063b..0000000
--- a/mgmt/stats/StatXML.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-
-#ifndef _STATXML_H_
-#define	_STATXML_H_
-
-#include "WebMgmtUtils.h"
-#include "List.h"
-
-typedef enum
-{
-  INVALID_TAG = -1,
-  ROOT_TAG,
-  STAT_TAG,
-  DST_TAG,
-  EXPR_TAG
-} StatXMLTag;
-
-/***************************************************************
- *                      General Methods
- ***************************************************************/
-bool isOperator(char);
-int XML_getContent(const char *, int, char *, StatXMLTag);
-unsigned short XML_extractContent(const char *, char *, size_t);
-
-#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/spec
----------------------------------------------------------------------
diff --git a/mgmt/stats/spec b/mgmt/stats/spec
deleted file mode 100644
index 97bdb90..0000000
--- a/mgmt/stats/spec
+++ /dev/null
@@ -1,236 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Statistics Processor
-//
-// Last Update: 04/11/2001
-//
-//-----------------------------------------------------------------------------
-// -*- coding: utf-8 -*-
-//
-// 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.
-
-
-//-----------------------------------------------------------------------------
-// Design
-//-----------------------------------------------------------------------------
-
-This statistics processor is a Cougar II (Tsunami) feature. 
-It is designed to replace the StatAggregate.cc and portion of WebOverview.cc 
-for scalability, maintainability, and ability to customize reasons.
-
-The statistics processor aggregate/calculate traffic server statistics based
-on a XML-based configuration file. At the processor's initialization, the 
-configuration file is read and parsed. Each set of calculation is then stored
-as a C++ object, called StatObject; and each StatObject is linked into a list,
-called StatObjectList.
-
-The mgmt/traffic_manager threads will invoke the StatObjectList->Eval() to
-perform the statistics aggregation and calculation within its event loop. As
-Eval() is call, each StatObject in StatObjectList is evaluated.
-
-Recall: StatAggregate.cc aggregates/calculates/copies proxy.process.* TS
-variables to proxy.node.* variables. Similarly, WebOverview.cc aggregate
-proxy.node.* variables to their corresponding proxy.cluster.* variable.
-
-So there are two types of calculations in the statistics processor: NodeEval
-and ClusterEval. As their names imply, they aggregate node-based statistics
-and clsuter-based statistics, respectively. We call the different basis of 
-statistics aggregation as "scope". (See "Destination Attributes")
-
-In the cluster-based statistics, the aggregation is further divided into two
-types: sum and re-calculate. Sum refers calculating the proxy.cluster.* 
-variable by simply summing all required proxy.node.* variables from nodes in
-the cluster. Re-calculate refers to summing all proxy.nodes.* variables that 
-are used in the process of calculation before performing the calculation. 
-An analogy would be, summing all open connection in the cluster vs. the 
-average hit rate in the cluster.
-
-//-----------------------------------------------------------------------------
-// Destination Attributes
-//-----------------------------------------------------------------------------
-	
-	"scope" 
-	- "node"
-	- "cluster"
-
-	"operation"
-	- "sum"
-		summing the corresponding node variable across all nodes in the cluster.
-	- "re-calculate"
-		
-
-	"define"
-	- "custom"
-	- "built-in"
-
-//-----------------------------------------------------------------------------
-// Predefined Constants and Functions
-//-----------------------------------------------------------------------------
-	
-	Predefined Constants
-
-	. BYTES_TO_MB_SCALE (1/(1024*1024.0))
-	  - convert bytes to mega-bytes
-
-	. MBIT_TO_KBIT_SCALE (1000.0)
-	  - convert mega-bits to kilo-bits
-
-	. SECOND_TO_MILLISECOND_SCALE (1000.0)
-	  - convert seconds to milliseconds
-
-	. PCT_TO_INTPCT_SCALE (100.0)
-	  - convert ratios to percentage
-
-	. HRTIME_SECOND
-	  - converting milli-seconds to seconds
-
-	. BYTES_TO_MBIT_SCALE (8/1000000.0)
-	  - convert bytes to mega-bits
-
-	Predefined Functions
-	. DIFFTIME
-	  - the number of milliseconds since last update. Usually used in 
-        combination of HRTIME_SECOND which computes the number of seconds
-        since last update.
-
-//-----------------------------------------------------------------------------
-// Unit test plan
-//-----------------------------------------------------------------------------
-
-The statistics processor is designed to replace StatAggregate.cc and part of
-the WebOverview. The first thing to test StatProcessor is to comment the 
-aggregateNodeRecords() and doClusterAg() calls from mgmt/Main.cc.
-
-The next step is to replace the above function calls with StatProcessor::
-processStat().
-
-This statistics processor is a rather complicated module in traffic manager.
-Hence it can't be easily tested. We divided the test into multiple sections.
-
-1) Node-based Simple Aggregation
-	- simply performs those aggregation that are node-based and the aggregation
-      is performed every time statProcess() is invoked.
-	  E.g.: hit rate = doc. hit / doc. served.
-
-2) Node-based Time-Delta Aggregation
-	- performs those aggregation that are node-based but the operation is only
-      perform in a regular interval AND one of more variables in the 
-      calculation is obtained by calculating the difference between the last
-      updated value and the current value. E.g. average connections per second
-      is calculated by subtracting the 10 seconds ago connection count from the
-      current connection count and divide the quotient by 10.
-
-Repeat the about 2 testes with cluster-based variables. So, we have, at least,
-4 test cases.
-
-Developing a PASS/FAIL unit test that will test the statistics processor is not 
-cost-efficient. The approach we are going to use is to display the input value
-and the output value before and after the calculation is done.
-
-Let's subdivide the testes in two stages:
-
-Stage 1 : Synthetic Data
-------------------------
-We control the testing environment by setting the input values. This will test
-the correctness of the statistics processor in a controlled environment. PASS/
-FAIL is determined by matching the input/output values.
-
-Stage 2 : Load Data
--------------------
-Submitting network traffic through traffic server with load tools like jtest and
-ftest, dumps the statistics to a text file, periodically and examines the
-resulting values
-
-//-----------------------------------------------------------------------------
-// For QA Engineer
-//-----------------------------------------------------------------------------
-The most concerning question for QA engineers is "how can I tell if the 
-Statistics Processor is working correctly?"
-
-Recall, the new Statistics Processor is meant to replace the StatAggregate.cc
-and part of the WebOverview.cc. In essence, you should not see any apparent
-change.
-
-If you ever see a value of -9999.0 (or -9999), then there is an error in
-computing that value.
-
-
-<expr>
-    - %d
-    - %f
-    - %k
-
-<dst>
-    - specifies the variable that stores that result value.
-    - ATTRIBUTE: type
-        built-in: variables that are built-in/defined in traffic server
-        custom: variables that are introducted to be temporary storage or
-                variables that are introdcuted by the client.
-    - default attributes:
-	type = built-in  
-
-<src>
-    - variable need to computer the <dst>
-    - ATTRIBUTE: type
-	node: this is a proxy.node.* variables
-	cluster: the is a proxy.node.* variables but summing over all
-                 nodes in the cluster.
-    - default attributes:
-	type = node
-
-<min>
-    - specifics what is the smallest possible value for <dst>. For values
-      smaller than <min>, the <defualt> is used.
-
-<max>
-    - specifics what is the largest possible value for <dst>. For values
-      larger than <max>, the <defualt> is used.
-
-<default>
-    - specifics what value to be assigned to <dst> is the result <dst>
-      value is smaller then <min> or larger then <max>
-
-RULES: (some of these are enfored by the DTD anyways)
-- all operator and operand in <expr> MUST BE separated by a single space.
-- the order of the tags matters
-- the order of each entry matters
-- each statistics entry has have at most 1 <dst>
-
-
-DEFINED CONSTANT (in alphabetical order)
-* _BYTES_TO_MB_SCALE
-	* Origin: utils/WebMgmtUtils.h
-	* Value:  (1/(1024*1024.0))
-
-*  _HRTIME_SECOND
-	* Origin:
-	* Value: 
-
-*  _MBIT_TO_KBIT_SCALE
-	* Origin: utils/WebMgmtUtils.h
-	* Value:  (1000.0);
-
-*  _PCT_TO_INTPCT_SCALE
-	* Origin: utils/WebMgmtUtils.h
-	* Value:  (100.0);
-
-*  _SECOND_TO_MILLISECOND_SCALE
-	* Origin: utils/WebMgmtUtils.h
-	* Value:  (1000.0);
-
-
-            __DIFFTIME


[5/9] git commit: TS-2977: minimize web2 and cluster in the headers search path

Posted by jp...@apache.org.
TS-2977: minimize web2 and cluster in the headers search path


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ff716f21
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ff716f21
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ff716f21

Branch: refs/heads/master
Commit: ff716f219a86284fb980ba2ed05c41105ce274ef
Parents: 1bba62b
Author: James Peach <jp...@apache.org>
Authored: Thu Jul 31 13:48:17 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Aug 1 19:55:45 2014 -0700

----------------------------------------------------------------------
 cmd/traffic_manager/Main.cc          |  7 +++----
 cmd/traffic_manager/StatProcessor.cc |  2 +-
 lib/records/Makefile.am              |  2 --
 mgmt/Alarms.cc                       |  2 +-
 mgmt/LocalManager.cc                 | 14 ++++++++++++++
 mgmt/LocalManager.h                  | 17 +++--------------
 mgmt/api/CoreAPI.cc                  |  3 ++-
 mgmt/cluster/ClusterCom.cc           |  1 +
 mgmt/cluster/Makefile.am             |  1 -
 mgmt/cluster/VMap.cc                 |  1 +
 mgmt/utils/Makefile.am               |  2 --
 mgmt/web2/WebOverview.cc             |  2 +-
 proxy/shared/Makefile.am             |  2 --
 13 files changed, 27 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/cmd/traffic_manager/Main.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Main.cc b/cmd/traffic_manager/Main.cc
index d54eb94..8d80a24 100644
--- a/cmd/traffic_manager/Main.cc
+++ b/cmd/traffic_manager/Main.cc
@@ -21,8 +21,7 @@
   limitations under the License.
  */
 
-#include "ink_config.h"
-#include "ink_platform.h"
+#include "libts.h"
 #include "ink_sys_control.h"
 
 #include "Main.h"
@@ -30,11 +29,11 @@
 #include "WebMgmtUtils.h"
 #include "WebIntrMain.h"
 #include "WebOverview.h"
+#include "ClusterCom.h"
+#include "VMap.h"
 #include "FileManager.h"
 #include "I_Layout.h"
 #include "I_Version.h"
-#include "ink_syslog.h"
-#include "ink_lockfile.h"
 #include "Diags.h"
 #include "DiagsConfig.h"
 #include "URL.h"

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/cmd/traffic_manager/StatProcessor.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/StatProcessor.cc b/cmd/traffic_manager/StatProcessor.cc
index 24cbaa9..3fd670e 100644
--- a/cmd/traffic_manager/StatProcessor.cc
+++ b/cmd/traffic_manager/StatProcessor.cc
@@ -30,7 +30,7 @@
  *
  ****************************************************************************/
 
-#include "ink_config.h"
+#include "libts.h"
 #include "StatProcessor.h"
 #include "FileManager.h"
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/lib/records/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/records/Makefile.am b/lib/records/Makefile.am
index 744194c..e3b74cf 100644
--- a/lib/records/Makefile.am
+++ b/lib/records/Makefile.am
@@ -20,8 +20,6 @@ AM_CPPFLAGS = \
   -I$(top_srcdir)/iocore/eventsystem \
   -I$(top_srcdir)/iocore/utils \
   -I$(top_srcdir)/mgmt \
-  -I$(top_srcdir)/mgmt/cluster \
-  -I$(top_srcdir)/mgmt/web2 \
   -I$(top_srcdir)/mgmt/api/include \
   -I$(top_srcdir)/mgmt/utils \
   -I$(top_srcdir)/lib \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/mgmt/Alarms.cc
----------------------------------------------------------------------
diff --git a/mgmt/Alarms.cc b/mgmt/Alarms.cc
index b44930f..aed1537 100644
--- a/mgmt/Alarms.cc
+++ b/mgmt/Alarms.cc
@@ -24,11 +24,11 @@
 
 #include "libts.h"
 #include "LocalManager.h"
+#include "ClusterCom.h"
 #include "MgmtUtils.h"
 #include "Alarms.h"
 #include "Diags.h"
 
-
 #include "P_RecCore.h"
 
 const char *alarmText[] = {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/mgmt/LocalManager.cc
----------------------------------------------------------------------
diff --git a/mgmt/LocalManager.cc b/mgmt/LocalManager.cc
index d6930e1..885b054 100644
--- a/mgmt/LocalManager.cc
+++ b/mgmt/LocalManager.cc
@@ -31,6 +31,8 @@
 #include "MgmtSocket.h"
 #include "ink_cap.h"
 #include "FileManager.h"
+#include "ClusterCom.h"
+#include "VMap.h"
 
 #if TS_USE_POSIX_CAP
 #include <sys/capability.h>
@@ -290,6 +292,18 @@ LocalManager::LocalManager(bool proxy_on)
   return;
 }
 
+LocalManager::~LocalManager()
+{
+  delete alarm_keeper;
+  delete virt_map;
+  delete ccom;
+  ats_free(absolute_proxy_binary);
+  ats_free(proxy_name);
+  ats_free(proxy_binary);
+  ats_free(proxy_options);
+  ats_free(env_prep);
+}
+
 void
 LocalManager::initAlarm()
 {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/mgmt/LocalManager.h
----------------------------------------------------------------------
diff --git a/mgmt/LocalManager.h b/mgmt/LocalManager.h
index 785cbc0..a001646 100644
--- a/mgmt/LocalManager.h
+++ b/mgmt/LocalManager.h
@@ -36,31 +36,20 @@
 
 #include "Alarms.h"
 #include "BaseManager.h"
-#include "ClusterCom.h"
-#include "VMap.h"
 #include <records/I_RecHttp.h>
 #if TS_HAS_WCCP
 #include <wccp/Wccp.h>
 #endif
 
 class FileManager;
+class ClusterCom;
+class VMap;
 
 class LocalManager: public BaseManager
 {
 public:
   explicit LocalManager(bool proxy_on);
-
-  ~LocalManager()
-  {
-    delete alarm_keeper;
-    delete virt_map;
-    delete ccom;
-    ats_free(absolute_proxy_binary);
-    ats_free(proxy_name);
-    ats_free(proxy_binary);
-    ats_free(proxy_options);
-    ats_free(env_prep);
-  };
+  ~LocalManager();
 
   void initAlarm();
   void initCCom(const AppVersionInfo& version, FileManager * files, int mcport, char *addr, int rsport);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/mgmt/api/CoreAPI.cc
----------------------------------------------------------------------
diff --git a/mgmt/api/CoreAPI.cc b/mgmt/api/CoreAPI.cc
index 1ca1fc3..57ff3d2 100644
--- a/mgmt/api/CoreAPI.cc
+++ b/mgmt/api/CoreAPI.cc
@@ -29,9 +29,10 @@
  *
  ***************************************************************************/
 
-#include "ink_platform.h"
+#include "libts.h"
 #include "MgmtUtils.h"
 #include "LocalManager.h"
+#include "ClusterCom.h"
 #include "FileManager.h"
 #include "Rollback.h"
 #include "WebMgmtUtils.h"

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/mgmt/cluster/ClusterCom.cc
----------------------------------------------------------------------
diff --git a/mgmt/cluster/ClusterCom.cc b/mgmt/cluster/ClusterCom.cc
index c538235..6293a37 100644
--- a/mgmt/cluster/ClusterCom.cc
+++ b/mgmt/cluster/ClusterCom.cc
@@ -40,6 +40,7 @@
 
 #include "LocalManager.h"
 #include "ClusterCom.h"
+#include "VMap.h"
 #include "MgmtUtils.h"
 #include "WebMgmtUtils.h"
 #include "MgmtHashTable.h"

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/mgmt/cluster/Makefile.am
----------------------------------------------------------------------
diff --git a/mgmt/cluster/Makefile.am b/mgmt/cluster/Makefile.am
index 51d63a0..cae4ec7 100644
--- a/mgmt/cluster/Makefile.am
+++ b/mgmt/cluster/Makefile.am
@@ -23,7 +23,6 @@ AM_CPPFLAGS = \
   -I$(top_srcdir)/mgmt \
   -I$(top_srcdir)/mgmt/api/include \
   -I$(top_srcdir)/mgmt/utils \
-  -I$(top_srcdir)/mgmt/web2 \
   -I$(top_srcdir)/lib \
   -I$(top_builddir)/lib
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/mgmt/cluster/VMap.cc
----------------------------------------------------------------------
diff --git a/mgmt/cluster/VMap.cc b/mgmt/cluster/VMap.cc
index 2261f88..993f44b 100644
--- a/mgmt/cluster/VMap.cc
+++ b/mgmt/cluster/VMap.cc
@@ -32,6 +32,7 @@
 
 #include "LocalManager.h"
 #include "VMap.h"
+#include "ClusterCom.h"
 #include "MgmtUtils.h"
 #include "P_RecLocal.h"
 #include "I_Layout.h"

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/mgmt/utils/Makefile.am
----------------------------------------------------------------------
diff --git a/mgmt/utils/Makefile.am b/mgmt/utils/Makefile.am
index 46b6673..8321221 100644
--- a/mgmt/utils/Makefile.am
+++ b/mgmt/utils/Makefile.am
@@ -22,8 +22,6 @@ AM_CPPFLAGS = \
   -I$(top_srcdir)/mgmt \
   -I$(top_srcdir)/mgmt/api \
   -I$(top_srcdir)/mgmt/api/include \
-  -I$(top_srcdir)/mgmt/cluster \
-  -I$(top_srcdir)/mgmt/web2 \
   -I$(top_srcdir)/lib/tsconfig \
   -I$(top_srcdir)/proxy \
   -I$(top_srcdir)/lib/records \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/mgmt/web2/WebOverview.cc
----------------------------------------------------------------------
diff --git a/mgmt/web2/WebOverview.cc b/mgmt/web2/WebOverview.cc
index 3084eb8..95e6330 100644
--- a/mgmt/web2/WebOverview.cc
+++ b/mgmt/web2/WebOverview.cc
@@ -28,7 +28,7 @@
  *
  ****************************************************************************/
 
-#include "ink_platform.h"
+#include "libts.h"
 
 #include "WebOverview.h"
 #include "WebGlobals.h"

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ff716f21/proxy/shared/Makefile.am
----------------------------------------------------------------------
diff --git a/proxy/shared/Makefile.am b/proxy/shared/Makefile.am
index 2db77e7..ca79f60 100644
--- a/proxy/shared/Makefile.am
+++ b/proxy/shared/Makefile.am
@@ -29,10 +29,8 @@ AM_CPPFLAGS = \
   -I$(top_srcdir)/lib/records \
   -I$(top_srcdir)/lib/ts \
   -I$(top_srcdir)/mgmt \
-  -I$(top_srcdir)/mgmt/web2 \
   -I$(top_srcdir)/mgmt/api \
   -I$(top_srcdir)/mgmt/api/include \
-  -I$(top_srcdir)/mgmt/cluster \
   -I$(top_srcdir)/mgmt/utils \
   -I$(top_srcdir) \
   -I$(top_srcdir)/proxy/api/ts \


[4/9] git commit: TS-2977: apply library naming conventions to librecords

Posted by jp...@apache.org.
TS-2977: apply library naming conventions to librecords

Everywhere else "foo_lm.a" is the local manager variant, and "foo_p.a"
is the process manager variant. Make librecords follow the same
pattern.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/73865831
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/73865831
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/73865831

Branch: refs/heads/master
Commit: 7386583197067f7a64de8f39bf0f10a59516c8fd
Parents: 93f46af
Author: James Peach <jp...@apache.org>
Authored: Thu Jul 31 10:52:32 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Aug 1 19:55:45 2014 -0700

----------------------------------------------------------------------
 cmd/traffic_cop/Makefile.am     |  2 +-
 cmd/traffic_manager/Makefile.am |  4 +--
 iocore/aio/Makefile.am          |  2 +-
 iocore/eventsystem/Makefile.am  |  2 +-
 lib/records/Makefile.am         | 62 ++++++++++++------------------------
 lib/records/RecProcess.cc       |  2 +-
 lib/records/test_RecProcess.i   |  2 +-
 proxy/Makefile.am               | 10 +++---
 8 files changed, 33 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/73865831/cmd/traffic_cop/Makefile.am
----------------------------------------------------------------------
diff --git a/cmd/traffic_cop/Makefile.am b/cmd/traffic_cop/Makefile.am
index 653d4e7..cd7085b 100644
--- a/cmd/traffic_cop/Makefile.am
+++ b/cmd/traffic_cop/Makefile.am
@@ -36,5 +36,5 @@ traffic_cop_LDADD = \
   $(top_builddir)/mgmt/api/libtsmgmtshare.la \
   $(top_builddir)/mgmt/api/libtsmgmt.la \
   $(top_builddir)/lib/ts/libtsutil.la \
-  $(top_builddir)/lib/records/librec4cop.a \
+  $(top_builddir)/lib/records/librecords_cop.a \
   @LIBRESOLV@ @OPENSSL_LIBS@

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/73865831/cmd/traffic_manager/Makefile.am
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Makefile.am b/cmd/traffic_manager/Makefile.am
index 3b65181..1bb5614 100644
--- a/cmd/traffic_manager/Makefile.am
+++ b/cmd/traffic_manager/Makefile.am
@@ -32,7 +32,7 @@ AM_CPPFLAGS = \
   -I$(top_srcdir)/mgmt/web2 \
   -I$(top_srcdir)/lib \
   -I$(top_builddir)/lib
-#
+
 traffic_manager_SOURCES = \
   AddConfigFilesHere.cc \
   Main.cc \
@@ -48,7 +48,7 @@ traffic_manager_LDADD = \
   $(top_builddir)/mgmt/api/libtsmgmtshare.la \
   $(top_builddir)/mgmt/utils/libutils_lm.a \
   $(top_builddir)/proxy/hdrs/libhdrs.a \
-  $(top_builddir)/lib/records/libreclocal.a \
+  $(top_builddir)/lib/records/librecords_lm.a \
   $(top_builddir)/lib/ts/libtsutil.la \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
   $(top_builddir)/proxy/shared/liberror.a \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/73865831/iocore/aio/Makefile.am
----------------------------------------------------------------------
diff --git a/iocore/aio/Makefile.am b/iocore/aio/Makefile.am
index db25e37..51adaa2 100644
--- a/iocore/aio/Makefile.am
+++ b/iocore/aio/Makefile.am
@@ -50,7 +50,7 @@ test_AIO_CXXFLAGS = \
 
 test_AIO_LDADD = \
   libinkaio.a \
-  $(top_builddir)/lib/records/librecprocess.a \
+  $(top_builddir)/lib/records/librecords_p.a \
   $(top_builddir)/mgmt/libmgmt_p.a \
   $(top_builddir)/mgmt/utils/libutils_p.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/73865831/iocore/eventsystem/Makefile.am
----------------------------------------------------------------------
diff --git a/iocore/eventsystem/Makefile.am b/iocore/eventsystem/Makefile.am
index cfa77e1..ce1a432 100644
--- a/iocore/eventsystem/Makefile.am
+++ b/iocore/eventsystem/Makefile.am
@@ -84,7 +84,7 @@ test_CXXFLAGS = \
 
 test_LDADD = \
   libinkevent.a \
-  $(top_builddir)/lib/records/librecprocess.a \
+  $(top_builddir)/lib/records/librecords_p.a \
   $(top_builddir)/mgmt/libmgmt_p.a \
   $(top_builddir)/mgmt/utils/libutils_p.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/73865831/lib/records/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/records/Makefile.am b/lib/records/Makefile.am
index c291ac2..744194c 100644
--- a/lib/records/Makefile.am
+++ b/lib/records/Makefile.am
@@ -28,67 +28,47 @@ AM_CPPFLAGS = \
   -I$(top_builddir)/lib \
   -I$(top_srcdir)/lib/ts
 
-noinst_LIBRARIES = libreclocal.a librecprocess.a librec4cop.a
+noinst_LIBRARIES = librecords_lm.a librecords_p.a librecords_cop.a
 
-libreclocal_a_SOURCES = \
+librecords_COMMON = \
   I_RecAlarms.h \
   I_RecCore.h \
   I_RecDefs.h \
   I_RecEvents.h \
-  I_RecLocal.h \
+  I_RecHttp.h \
   I_RecMutex.h \
   I_RecSignals.h \
-  P_RecFile.h \
-  P_RecCore.h \
   P_RecCore.cc \
+  P_RecCore.h \
   P_RecDefs.h \
-  P_RecLocal.h \
+  P_RecFile.h \
+  P_RecFile.h \
   P_RecMessage.h \
   P_RecTree.h \
   P_RecUtils.h \
-  P_RecFile.h \
-  RecFile.cc \
+  RecConfigParse.cc \
   RecCore.cc \
-  RecLocal.cc \
+  RecDebug.cc \
+  RecFile.cc \
+  RecHttp.cc \
   RecMessage.cc \
   RecMutex.cc \
   RecTree.cc \
-  I_RecHttp.h \
-  RecHttp.cc \
-  RecUtils.cc \
-  RecDebug.cc \
-  RecConfigParse.cc
+  RecUtils.cc
 
-librecprocess_a_SOURCES = \
-  I_RecAlarms.h \
-  I_RecCore.h \
-  I_RecDefs.h \
-  I_RecEvents.h \
-  I_RecMutex.h \
+librecords_lm_a_SOURCES = \
+  $(librecords_COMMON) \
+  I_RecLocal.h \
+  P_RecLocal.h \
+  RecLocal.cc
+
+librecords_p_a_SOURCES = \
+  $(librecords_COMMON) \
   I_RecProcess.h \
-  I_RecSignals.h \
-  P_RecFile.h \
-  P_RecCore.h \
-  P_RecCore.cc \
-  P_RecDefs.h \
-  P_RecMessage.h \
   P_RecProcess.h \
-  P_RecTree.h \
-  P_RecUtils.h \
-  P_RecFile.h \
-  RecFile.cc \
-  RecCore.cc \
-  RecMessage.cc \
-  RecMutex.cc \
-  RecProcess.cc \
-  RecTree.cc \
-  I_RecHttp.h \
-  RecHttp.cc \
-  RecUtils.cc \
-  RecDebug.cc \
-  RecConfigParse.cc
+  RecProcess.cc
 
-librec4cop_a_SOURCES = \
+librecords_cop_a_SOURCES = \
   RecConfigParse.cc \
   RecFile.cc \
   RecDebug.cc

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/73865831/lib/records/RecProcess.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecProcess.cc b/lib/records/RecProcess.cc
index 079cea2..3d39d80 100644
--- a/lib/records/RecProcess.cc
+++ b/lib/records/RecProcess.cc
@@ -47,7 +47,7 @@ static Event *config_update_cont_event;
 static Event *sync_cont_event;
 
 //-------------------------------------------------------------------------
-// i_am_the_record_owner, only used for librecprocess.a
+// i_am_the_record_owner, only used for librecords_p.a
 //-------------------------------------------------------------------------
 bool
 i_am_the_record_owner(RecT rec_type)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/73865831/lib/records/test_RecProcess.i
----------------------------------------------------------------------
diff --git a/lib/records/test_RecProcess.i b/lib/records/test_RecProcess.i
index d56353a..efa286b 100644
--- a/lib/records/test_RecProcess.i
+++ b/lib/records/test_RecProcess.i
@@ -1,6 +1,6 @@
 /** @file
 
-  A small test and sample program for librecprocess.a
+  A small test and sample program for librecords_p.a
 
   @section license License
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/73865831/proxy/Makefile.am
----------------------------------------------------------------------
diff --git a/proxy/Makefile.am b/proxy/Makefile.am
index cb6bcad..2a3d346 100644
--- a/proxy/Makefile.am
+++ b/proxy/Makefile.am
@@ -217,7 +217,7 @@ traffic_server_LDADD = \
   $(top_builddir)/iocore/aio/libinkaio.a \
   $(top_builddir)/iocore/net/libinknet.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
-  $(top_builddir)/lib/records/librecprocess.a \
+  $(top_builddir)/lib/records/librecords_p.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
   $(which_libts) \
   @HWLOC_LIBS@ \
@@ -252,7 +252,7 @@ traffic_logcat_LDADD = \
   shared/libxml.a \
   $(top_builddir)/mgmt/utils/libutils_p.a \
   $(top_builddir)/mgmt/libmgmt_p.a \
-  $(top_builddir)/lib/records/librecprocess.a \
+  $(top_builddir)/lib/records/librecords_p.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
   $(top_builddir)/lib/ts/libtsutil.la \
   @LIBRESOLV@ @LIBPCRE@ @OPENSSL_LIBS@ @LIBTCL@ @HWLOC_LIBS@ \
@@ -268,7 +268,7 @@ traffic_logstats_LDADD = \
   shared/libxml.a \
   $(top_builddir)/mgmt/utils/libutils_p.a \
   $(top_builddir)/mgmt/libmgmt_p.a \
-  $(top_builddir)/lib/records/librecprocess.a \
+  $(top_builddir)/lib/records/librecords_p.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
   $(top_builddir)/lib/ts/libtsutil.la \
   @LIBRESOLV@ @LIBPCRE@ @OPENSSL_LIBS@ @LIBTCL@ @HWLOC_LIBS@ \
@@ -328,7 +328,7 @@ traffic_sac_LDADD = \
   $(top_builddir)/iocore/aio/libinkaio.a \
   $(top_builddir)/iocore/net/libinknet.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
-  $(top_builddir)/lib/records/librecprocess.a \
+  $(top_builddir)/lib/records/librecords_p.a \
   $(top_builddir)/lib/ts/libtsutil.la \
   @LIBRESOLV@ @LIBPCRE@ @OPENSSL_LIBS@ @LIBTCL@ @HWLOC_LIBS@ \
   @LIBEXPAT@ @LIBDEMANGLE@ @LIBZ@ @LIBLZMA@ @LIBPROFILER@ @SPDYLAY_LIBS@ -lm
@@ -340,7 +340,7 @@ endif
 
 test_xml_parser_SOURCES = test_xml_parser.cc
 test_xml_parser_LDADD = \
-  $(top_builddir)/lib/records/librecprocess.a \
+  $(top_builddir)/lib/records/librecords_p.a \
   $(top_builddir)/mgmt/libmgmt_p.a \
   $(top_builddir)/mgmt/utils/libutils_p.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \


[8/9] git commit: TS-2977: incorporate libutils into libmgmt

Posted by jp...@apache.org.
TS-2977: incorporate libutils into libmgmt

Simplify the link topology by incorporating libutils into libmgmt.
Management clients don't need to know the gory details.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/1bba62b6
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/1bba62b6
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/1bba62b6

Branch: refs/heads/master
Commit: 1bba62b68cad0cfb5bba8d6d4c1b735f80408e88
Parents: 9e6d233
Author: James Peach <jp...@apache.org>
Authored: Thu Jul 31 13:27:50 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Aug 1 19:55:45 2014 -0700

----------------------------------------------------------------------
 cmd/traffic_manager/Makefile.am |  4 +---
 iocore/aio/Makefile.am          |  3 +--
 iocore/eventsystem/Makefile.am  |  5 ++---
 mgmt/Makefile.am                | 27 ++++++++++++++++-----------
 mgmt/cluster/Makefile.am        |  4 ++--
 mgmt/utils/Makefile.am          |  6 +++---
 proxy/Makefile.am               | 15 +++++----------
 7 files changed, 30 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1bba62b6/cmd/traffic_manager/Makefile.am
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/Makefile.am b/cmd/traffic_manager/Makefile.am
index e547f1d..6ba9bfd 100644
--- a/cmd/traffic_manager/Makefile.am
+++ b/cmd/traffic_manager/Makefile.am
@@ -45,12 +45,10 @@ traffic_manager_SOURCES = \
 
 traffic_manager_LDFLAGS = @EXTRA_CXX_LDFLAGS@ @EXPAT_LDFLAGS@ @LIBTOOL_LINK_FLAGS@
 traffic_manager_LDADD = \
-  $(top_builddir)/mgmt/libmgmt_lm.a \
-  $(top_builddir)/mgmt/cluster/libcluster.a \
+  $(top_builddir)/mgmt/libmgmt_lm.la \
   $(top_builddir)/mgmt/web2/libweb.a \
   $(top_builddir)/mgmt/api/libmgmtapilocal.a \
   $(top_builddir)/mgmt/api/libtsmgmtshare.la \
-  $(top_builddir)/mgmt/utils/libutils_lm.a \
   $(top_builddir)/proxy/hdrs/libhdrs.a \
   $(top_builddir)/lib/records/librecords_lm.a \
   $(top_builddir)/lib/ts/libtsutil.la \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1bba62b6/iocore/aio/Makefile.am
----------------------------------------------------------------------
diff --git a/iocore/aio/Makefile.am b/iocore/aio/Makefile.am
index 51adaa2..6972946 100644
--- a/iocore/aio/Makefile.am
+++ b/iocore/aio/Makefile.am
@@ -51,8 +51,7 @@ test_AIO_CXXFLAGS = \
 test_AIO_LDADD = \
   libinkaio.a \
   $(top_builddir)/lib/records/librecords_p.a \
-  $(top_builddir)/mgmt/libmgmt_p.a \
-  $(top_builddir)/mgmt/utils/libutils_p.a \
+  $(top_builddir)/mgmt/libmgmt_p.la \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
   $(top_builddir)/lib/ts/libtsutil.la \
   $(top_builddir)/proxy/shared/libUglyLogStubs.a \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1bba62b6/iocore/eventsystem/Makefile.am
----------------------------------------------------------------------
diff --git a/iocore/eventsystem/Makefile.am b/iocore/eventsystem/Makefile.am
index ce1a432..ba01782 100644
--- a/iocore/eventsystem/Makefile.am
+++ b/iocore/eventsystem/Makefile.am
@@ -67,7 +67,7 @@ libinkevent_a_SOURCES = \
   Thread.cc \
   UnixEThread.cc \
   UnixEvent.cc \
-  UnixEventProcessor.cc 
+  UnixEventProcessor.cc
 
 check_PROGRAMS = test_Buffer test_Event
 
@@ -85,8 +85,7 @@ test_CXXFLAGS = \
 test_LDADD = \
   libinkevent.a \
   $(top_builddir)/lib/records/librecords_p.a \
-  $(top_builddir)/mgmt/libmgmt_p.a \
-  $(top_builddir)/mgmt/utils/libutils_p.a \
+  $(top_builddir)/mgmt/libmgmt_p.la \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
   $(top_builddir)/lib/ts/libtsutil.la \
   $(top_builddir)/proxy/shared/libUglyLogStubs.a \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1bba62b6/mgmt/Makefile.am
----------------------------------------------------------------------
diff --git a/mgmt/Makefile.am b/mgmt/Makefile.am
index e76f70d..ce477e1 100644
--- a/mgmt/Makefile.am
+++ b/mgmt/Makefile.am
@@ -19,7 +19,7 @@
 
 SUBDIRS = cluster utils web2 api
 
-noinst_LIBRARIES = libmgmt_p.a libmgmt_lm.a
+noinst_LTLIBRARIES = libmgmt_p.la libmgmt_lm.la
 
 AM_CPPFLAGS = \
   $(iocore_include_dirs) \
@@ -35,31 +35,36 @@ AM_CPPFLAGS = \
   -I$(top_srcdir)/lib \
   -I$(top_builddir)/lib
 
-libmgmt_p_a_SOURCES = \
+libmgmt_COMMON = \
   BaseManager.cc \
   BaseManager.h \
   MgmtDefs.h \
+  RecordsConfig.cc \
+  RecordsConfig.h
+
+libmgmt_p_la_SOURCES = \
+  $(libmgmt_COMMON) \
   ProcessManager.cc \
   ProcessManager.h \
   ProxyConfig.cc \
-  ProxyConfig.h \
-  RecordsConfig.cc \
-  RecordsConfig.h
+  ProxyConfig.h
 
-libmgmt_lm_a_SOURCES = \
+libmgmt_lm_la_SOURCES = \
+  $(libmgmt_COMMON) \
   Alarms.cc \
   Alarms.h \
-  BaseManager.cc \
-  BaseManager.h \
   FileManager.cc \
   FileManager.h \
   LocalManager.cc \
   LocalManager.h \
-  MgmtDefs.h \
   MultiFile.cc \
   MultiFile.h \
-  RecordsConfig.cc \
-  RecordsConfig.h \
   Rollback.cc \
   Rollback.h
 
+libmgmt_lm_la_LIBADD = \
+  cluster/libcluster.la \
+  utils/libutils_lm.la
+
+libmgmt_p_la_LIBADD = \
+  utils/libutils_p.la

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1bba62b6/mgmt/cluster/Makefile.am
----------------------------------------------------------------------
diff --git a/mgmt/cluster/Makefile.am b/mgmt/cluster/Makefile.am
index c33b045..51d63a0 100644
--- a/mgmt/cluster/Makefile.am
+++ b/mgmt/cluster/Makefile.am
@@ -27,9 +27,9 @@ AM_CPPFLAGS = \
   -I$(top_srcdir)/lib \
   -I$(top_builddir)/lib
 
-noinst_LIBRARIES = libcluster.a
+noinst_LTLIBRARIES = libcluster.la
 
-libcluster_a_SOURCES = \
+libcluster_la_SOURCES = \
   ClusterCom.cc \
   ClusterCom.h \
   VMap.cc \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1bba62b6/mgmt/utils/Makefile.am
----------------------------------------------------------------------
diff --git a/mgmt/utils/Makefile.am b/mgmt/utils/Makefile.am
index 388217a..46b6673 100644
--- a/mgmt/utils/Makefile.am
+++ b/mgmt/utils/Makefile.am
@@ -34,9 +34,9 @@ AM_CPPFLAGS = \
 # header files used by other libraries
 EXTRA_DIST = MgmtHashTable.h MgmtSocket.h
 
-noinst_LIBRARIES = libutils_lm.a libutils_p.a
+noinst_LTLIBRARIES = libutils_lm.la libutils_p.la
 
-libutils_lm_a_SOURCES = \
+libutils_lm_la_SOURCES = \
   ExpandingArray.cc \
   ExpandingArray.h \
   MgmtLocalCleanup.cc \
@@ -45,7 +45,7 @@ libutils_lm_a_SOURCES = \
   WebMgmtUtils.cc \
   WebMgmtUtils.h
 
-libutils_p_a_SOURCES = \
+libutils_p_la_SOURCES = \
   MgmtProcessCleanup.cc \
   MgmtUtils.cc \
   MgmtUtils.h

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1bba62b6/proxy/Makefile.am
----------------------------------------------------------------------
diff --git a/proxy/Makefile.am b/proxy/Makefile.am
index 2a3d346..091502b 100644
--- a/proxy/Makefile.am
+++ b/proxy/Makefile.am
@@ -205,8 +205,7 @@ traffic_server_LDADD = \
   shared/libdiagsconfig.a  \
   shared/libsignals.a \
   shared/libxml.a \
-  $(top_builddir)/mgmt/utils/libutils_p.a \
-  $(top_builddir)/mgmt/libmgmt_p.a \
+  $(top_builddir)/mgmt/libmgmt_p.la \
   $(top_builddir)/iocore/utils/libinkutils.a \
   $(top_builddir)/iocore/cluster/libinkcluster.a \
   $(top_builddir)/iocore/dns/libinkdns.a \
@@ -250,8 +249,7 @@ traffic_logcat_LDADD = \
   shared/libUglyLogStubs.a \
   shared/libsignals.a \
   shared/libxml.a \
-  $(top_builddir)/mgmt/utils/libutils_p.a \
-  $(top_builddir)/mgmt/libmgmt_p.a \
+  $(top_builddir)/mgmt/libmgmt_p.la \
   $(top_builddir)/lib/records/librecords_p.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
   $(top_builddir)/lib/ts/libtsutil.la \
@@ -266,8 +264,7 @@ traffic_logstats_LDADD = \
   shared/libUglyLogStubs.a \
   shared/libsignals.a \
   shared/libxml.a \
-  $(top_builddir)/mgmt/utils/libutils_p.a \
-  $(top_builddir)/mgmt/libmgmt_p.a \
+  $(top_builddir)/mgmt/libmgmt_p.la \
   $(top_builddir)/lib/records/librecords_p.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
   $(top_builddir)/lib/ts/libtsutil.la \
@@ -317,8 +314,7 @@ traffic_sac_LDADD = \
   shared/liberror.a \
   shared/libsignals.a \
   shared/libxml.a \
-  $(top_builddir)/mgmt/utils/libutils_p.a \
-  $(top_builddir)/mgmt/libmgmt_p.a \
+  $(top_builddir)/mgmt/libmgmt_p.la \
   $(top_builddir)/iocore/cluster/libinkcluster.a \
   $(top_builddir)/iocore/dns/libinkdns.a \
   $(top_builddir)/iocore/hostdb/libinkhostdb.a \
@@ -340,9 +336,8 @@ endif
 
 test_xml_parser_SOURCES = test_xml_parser.cc
 test_xml_parser_LDADD = \
+  $(top_builddir)/mgmt/libmgmt_p.la \
   $(top_builddir)/lib/records/librecords_p.a \
-  $(top_builddir)/mgmt/libmgmt_p.a \
-  $(top_builddir)/mgmt/utils/libutils_p.a \
   $(top_builddir)/iocore/eventsystem/libinkevent.a \
   $(top_builddir)/lib/ts/libtsutil.la \
   shared/libsignals.a \