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 \