You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by so...@apache.org on 2015/08/27 19:31:09 UTC

[2/9] trafficserver git commit: TS-3650: Track configuration variable source.

TS-3650: Track configuration variable source.

(cherry picked from commit 182506526c713b51e73b5f69f2376c708af594cc)
(cherry picked from commit 1ce4abcac3c665ea74aad4266f8b6fccd3c8263d)

Conflicts:
	CHANGES
	cmd/traffic_manager/traffic_manager.cc


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

Branch: refs/heads/5.3.x
Commit: 492e7bea23cdf507f0d41b982a307a94b6fb1e72
Parents: 72efe3f
Author: Alan M. Carroll <am...@apache.org>
Authored: Fri May 29 16:09:52 2015 -0500
Committer: Phil Sorber <so...@apache.org>
Committed: Thu Aug 27 11:21:08 2015 -0600

----------------------------------------------------------------------
 CHANGES                                |  2 ++
 cmd/traffic_cop/traffic_cop.cc         |  3 +-
 cmd/traffic_ctl/config.cc              | 16 +++++++++
 cmd/traffic_manager/traffic_manager.cc | 18 +++++-----
 lib/records/I_RecCore.h                | 22 ++++++------
 lib/records/I_RecDefs.h                |  9 +++++
 lib/records/P_RecCore.cc               | 56 ++++++++++++++++-------------
 lib/records/P_RecCore.h                |  6 ++--
 lib/records/P_RecDefs.h                |  1 +
 lib/records/RecConfigParse.cc          |  4 ++-
 lib/records/RecCore.cc                 | 15 ++++++--
 lib/records/RecLocal.cc                | 14 ++++----
 mgmt/LocalManager.cc                   | 16 ++++-----
 mgmt/RecordsConfigUtils.cc             | 11 +++---
 mgmt/WebMgmtUtils.cc                   | 34 +++++++++---------
 mgmt/api/CoreAPI.cc                    |  4 +--
 mgmt/api/CoreAPIRemote.cc              |  4 ++-
 mgmt/api/NetworkMessage.cc             |  8 ++---
 mgmt/api/TSControlMain.cc              |  3 +-
 mgmt/api/include/mgmtapi.h             |  1 +
 mgmt/cluster/ClusterCom.cc             |  2 +-
 proxy/InkAPI.cc                        |  6 ++--
 proxy/Main.cc                          |  2 +-
 proxy/shared/DiagsConfig.cc            | 28 +++++++--------
 24 files changed, 170 insertions(+), 115 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 6912737..3735302 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache Traffic Server 5.3.2
 
+  *) [TS-3650] Track source of configuration values.
+
 
 Changes with Apache Traffic Server 5.3.1
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/cmd/traffic_cop/traffic_cop.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_cop/traffic_cop.cc b/cmd/traffic_cop/traffic_cop.cc
index 15a1cef..20b73b9 100644
--- a/cmd/traffic_cop/traffic_cop.cc
+++ b/cmd/traffic_cop/traffic_cop.cc
@@ -475,7 +475,8 @@ transient_error(int error, int wait_ms)
 }
 
 static void
-config_register_variable(RecT rec_type, RecDataT data_type, const char *name, const char *value, bool /* inc_version */)
+config_register_variable(RecT rec_type, RecDataT data_type, const char *name, const char *value, RecSourceT /* source */,
+                         bool /* inc_version */)
 {
   configTable[std::string(name)] = ConfigValue(rec_type, data_type, value);
 }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/cmd/traffic_ctl/config.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_ctl/config.cc b/cmd/traffic_ctl/config.cc
index ce19f3e..9b43ee8 100644
--- a/cmd/traffic_ctl/config.cc
+++ b/cmd/traffic_ctl/config.cc
@@ -117,6 +117,21 @@ rec_checkof(int rec_checktype)
   }
 }
 
+static const char *
+rec_sourceof(int rec_source)
+{
+  switch (rec_source) {
+  case REC_SOURCE_DEFAULT:
+    return "built in default";
+  case REC_SOURCE_EXPLICIT:
+    return "administratively set";
+  case REC_SOURCE_ENV:
+    return "environment";
+  default:
+    return "unknown";
+  }
+}
+
 static std::string
 timestr(time_t tm)
 {
@@ -191,6 +206,7 @@ config_describe(unsigned argc, const char **argv)
     printf("%-16s: %s\n", "Access Control ", rec_accessof(desc.rec_access));
     printf("%-16s: %s\n", "Update Type", rec_updateof(desc.rec_updatetype));
     printf("%-16s: 0x%" PRIx64 "\n", "Update Status", desc.rec_update);
+    printf("%-16s: %s\n", "Source", rec_sourceof(desc.rec_source));
 
     if (strlen(desc.rec_checkexpr)) {
       printf("%-16s: %s, '%s'\n", "Syntax Check", rec_checkof(desc.rec_checktype), desc.rec_checkexpr);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/cmd/traffic_manager/traffic_manager.cc
----------------------------------------------------------------------
diff --git a/cmd/traffic_manager/traffic_manager.cc b/cmd/traffic_manager/traffic_manager.cc
index a03c4ee..17bf9d9 100644
--- a/cmd/traffic_manager/traffic_manager.cc
+++ b/cmd/traffic_manager/traffic_manager.cc
@@ -601,15 +601,13 @@ main(int argc, char **argv)
   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);
+  RecSetRecordString("proxy.node.version.manager.short", appVersionInfo.VersionStr, REC_SOURCE_DEFAULT);
+  RecSetRecordString("proxy.node.version.manager.long", appVersionInfo.FullVersionInfoStr, REC_SOURCE_DEFAULT);
+  RecSetRecordString("proxy.node.version.manager.build_number", appVersionInfo.BldNumStr, REC_SOURCE_DEFAULT);
+  RecSetRecordString("proxy.node.version.manager.build_time", appVersionInfo.BldTimeStr, REC_SOURCE_DEFAULT);
+  RecSetRecordString("proxy.node.version.manager.build_date", appVersionInfo.BldDateStr, REC_SOURCE_DEFAULT);
+  RecSetRecordString("proxy.node.version.manager.build_machine", appVersionInfo.BldMachineStr, REC_SOURCE_DEFAULT);
+  RecSetRecordString("proxy.node.version.manager.build_person", appVersionInfo.BldPersonStr, REC_SOURCE_DEFAULT);
 
   if (log_to_syslog) {
     char sys_var[] = "proxy.config.syslog_facility";
@@ -670,7 +668,7 @@ main(int argc, char **argv)
   }
 
   if (proxy_backdoor != -1) {
-    RecSetRecordInt("proxy.config.process_manager.mgmt_port", proxy_backdoor);
+    RecSetRecordInt("proxy.config.process_manager.mgmt_port", proxy_backdoor, REC_SOURCE_DEFAULT);
   }
 
   if (cluster_rsport == -1) {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/lib/records/I_RecCore.h
----------------------------------------------------------------------
diff --git a/lib/records/I_RecCore.h b/lib/records/I_RecCore.h
index 9945cc0..a09abdf 100644
--- a/lib/records/I_RecCore.h
+++ b/lib/records/I_RecCore.h
@@ -41,7 +41,8 @@ int RecSetDiags(Diags *diags);
 //-------------------------------------------------------------------------
 // Config File Parsing
 //-------------------------------------------------------------------------
-typedef void (*RecConfigEntryCallback)(RecT rec_type, RecDataT data_type, const char *name, const char *value, bool inc_version);
+typedef void (*RecConfigEntryCallback)(RecT rec_type, RecDataT data_type, const char *name, const char *value, RecSourceT source,
+                                       bool inc_version);
 
 void RecConfigFileInit(void);
 int RecConfigFileParse(const char *path, RecConfigEntryCallback handler, bool inc_version);
@@ -106,16 +107,16 @@ int _RecRegisterStatCounter(RecT rec_type, const char *name, RecCounter data_def
 //-------------------------------------------------------------------------
 
 int RecRegisterConfigInt(RecT rec_type, const char *name, RecInt data_default, RecUpdateT update_type, RecCheckT check_type,
-                         const char *ccheck_regex, RecAccessT access_type = RECA_NULL);
+                         const char *ccheck_regex, RecSourceT source, RecAccessT access_type = RECA_NULL);
 
 int RecRegisterConfigFloat(RecT rec_type, const char *name, RecFloat data_default, RecUpdateT update_type, RecCheckT check_type,
-                           const char *check_regex, RecAccessT access_type = RECA_NULL);
+                           const char *check_regex, RecSourceT source, RecAccessT access_type = RECA_NULL);
 
 int RecRegisterConfigString(RecT rec_type, const char *name, const char *data_default, RecUpdateT update_type, RecCheckT check_type,
-                            const char *check_regex, RecAccessT access_type = RECA_NULL);
+                            const char *check_regex, RecSourceT source, RecAccessT access_type = RECA_NULL);
 
 int RecRegisterConfigCounter(RecT rec_type, const char *name, RecCounter data_default, RecUpdateT update_type, RecCheckT check_type,
-                             const char *check_regex, RecAccessT access_type = RECA_NULL);
+                             const char *check_regex, RecSourceT source, RecAccessT access_type = RECA_NULL);
 
 //-------------------------------------------------------------------------
 // Config Change Notification
@@ -145,11 +146,11 @@ int RecRegisterRawStatUpdateFunc(const char *name, RecRawStatBlock *rsb, int id,
 // already been taken out for the callback.
 
 // RecSetRecordConvert -> WebMgmtUtils.cc::varSetFromStr()
-int RecSetRecordConvert(const char *name, const RecString rec_string, bool lock = true, bool inc_version = true);
-int RecSetRecordInt(const char *name, RecInt rec_int, bool lock = true, bool inc_version = true);
-int RecSetRecordFloat(const char *name, RecFloat rec_float, bool lock = true, bool inc_version = true);
-int RecSetRecordString(const char *name, const RecString rec_string, bool lock = true, bool inc_version = true);
-int RecSetRecordCounter(const char *name, RecCounter rec_counter, bool lock = true, bool inc_version = true);
+int RecSetRecordConvert(const char *name, const RecString rec_string, RecSourceT source, bool lock = true, bool inc_version = true);
+int RecSetRecordInt(const char *name, RecInt rec_int, RecSourceT source, bool lock = true, bool inc_version = true);
+int RecSetRecordFloat(const char *name, RecFloat rec_float, RecSourceT source, bool lock = true, bool inc_version = true);
+int RecSetRecordString(const char *name, const RecString rec_string, RecSourceT source, bool lock = true, bool inc_version = true);
+int RecSetRecordCounter(const char *name, RecCounter rec_counter, RecSourceT source, bool lock = true, bool inc_version = true);
 
 int RecGetRecordInt(const char *name, RecInt *rec_int, bool lock = true);
 int RecGetRecordFloat(const char *name, RecFloat *rec_float, bool lock = true);
@@ -176,6 +177,7 @@ int RecGetRecordUpdateType(const char *name, RecUpdateT *update_type, bool lock
 int RecGetRecordCheckType(const char *name, RecCheckT *check_type, bool lock = true);
 int RecGetRecordCheckExpr(const char *name, char **check_expr, bool lock = true);
 int RecGetRecordDefaultDataString_Xmalloc(char *name, char **buf, bool lock = true);
+int RecGetRecordSource(const char *name, RecSourceT *source, bool lock = true);
 
 int RecGetRecordAccessType(const char *name, RecAccessT *secure, bool lock = true);
 int RecSetRecordAccessType(const char *name, RecAccessT secure, bool lock = true);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/lib/records/I_RecDefs.h
----------------------------------------------------------------------
diff --git a/lib/records/I_RecDefs.h b/lib/records/I_RecDefs.h
index 114153e..839bcd7 100644
--- a/lib/records/I_RecDefs.h
+++ b/lib/records/I_RecDefs.h
@@ -121,6 +121,15 @@ enum RecCheckT {
   RECC_IP    // config is an ip address
 };
 
+/// The source of the value.
+/// @internal @c REC_SOURCE_NULL is useful for a return value, I don't see using it in the actual data.
+enum RecSourceT {
+  REC_SOURCE_NULL,     ///< No source / value not set.
+  REC_SOURCE_DEFAULT,  ///< Built in default.
+  REC_SOURCE_EXPLICIT, ///< Set by administrator (config file, external API, cluster, etc.)
+  REC_SOURCE_ENV       ///< Process environment variable.
+};
+
 enum RecModeT {
   RECM_NULL,
   RECM_CLIENT,

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/lib/records/P_RecCore.cc
----------------------------------------------------------------------
diff --git a/lib/records/P_RecCore.cc b/lib/records/P_RecCore.cc
index 7a896f9..ae4d2df 100644
--- a/lib/records/P_RecCore.cc
+++ b/lib/records/P_RecCore.cc
@@ -195,9 +195,9 @@ recv_message_cb(RecMessage *msg, RecMessageT msg_type, void * /* cookie */)
     if (RecMessageUnmarshalFirst(msg, &itr, &r) != REC_ERR_FAIL) {
       do {
         if (REC_TYPE_IS_STAT(r->rec_type)) {
-          RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), &(r->stat_meta.data_raw));
+          RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), &(r->stat_meta.data_raw), REC_SOURCE_EXPLICIT);
         } else {
-          RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), NULL);
+          RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), NULL, REC_SOURCE_EXPLICIT);
         }
       } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
     }
@@ -211,7 +211,7 @@ recv_message_cb(RecMessage *msg, RecMessageT msg_type, void * /* cookie */)
         if (REC_TYPE_IS_STAT(r->rec_type)) {
           RecResetStatRecord(r->name);
         } else {
-          RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), NULL);
+          RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), NULL, REC_SOURCE_EXPLICIT);
         }
       } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
     }
@@ -225,7 +225,7 @@ recv_message_cb(RecMessage *msg, RecMessageT msg_type, void * /* cookie */)
           RecRegisterStat(r->rec_type, r->name, r->data_type, r->data_default, r->stat_meta.persist_type);
         } else if (REC_TYPE_IS_CONFIG(r->rec_type)) {
           RecRegisterConfig(r->rec_type, r->name, r->data_type, r->data_default, r->config_meta.update_type,
-                            r->config_meta.check_type, r->config_meta.check_expr, r->config_meta.access_type);
+                            r->config_meta.check_type, r->config_meta.check_expr, REC_SOURCE_EXPLICIT, r->config_meta.access_type);
         }
       } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
     }
@@ -315,7 +315,8 @@ _RecRegisterStatCounter(RecT rec_type, const char *name, RecCounter data_default
   RecRecord *r;                                                                                                                 \
   RecData my_data_default;                                                                                                      \
   my_data_default.A = data_default;                                                                                             \
-  if ((r = RecRegisterConfig(rec_type, name, B, my_data_default, update_type, check_type, check_regex, access_type)) != NULL) { \
+  if ((r = RecRegisterConfig(rec_type, name, B, my_data_default, update_type, check_type, check_regex, source, access_type)) != \
+      NULL) {                                                                                                                   \
     if (i_am_the_record_owner(r->rec_type)) {                                                                                   \
       r->sync_required = r->sync_required | REC_PEER_SYNC_REQUIRED;                                                             \
     } else {                                                                                                                    \
@@ -328,7 +329,7 @@ _RecRegisterStatCounter(RecT rec_type, const char *name, RecCounter data_default
 
 int
 RecRegisterConfigInt(RecT rec_type, const char *name, RecInt data_default, RecUpdateT update_type, RecCheckT check_type,
-                     const char *check_regex, RecAccessT access_type)
+                     const char *check_regex, RecSourceT source, RecAccessT access_type)
 {
   ink_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
   REC_REGISTER_CONFIG_XXX(rec_int, RECD_INT);
@@ -336,7 +337,7 @@ RecRegisterConfigInt(RecT rec_type, const char *name, RecInt data_default, RecUp
 
 int
 RecRegisterConfigFloat(RecT rec_type, const char *name, RecFloat data_default, RecUpdateT update_type, RecCheckT check_type,
-                       const char *check_regex, RecAccessT access_type)
+                       const char *check_regex, RecSourceT source, RecAccessT access_type)
 {
   ink_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
   REC_REGISTER_CONFIG_XXX(rec_float, RECD_FLOAT);
@@ -345,7 +346,7 @@ RecRegisterConfigFloat(RecT rec_type, const char *name, RecFloat data_default, R
 
 int
 RecRegisterConfigString(RecT rec_type, const char *name, const char *data_default_tmp, RecUpdateT update_type, RecCheckT check_type,
-                        const char *check_regex, RecAccessT access_type)
+                        const char *check_regex, RecSourceT source, RecAccessT access_type)
 {
   RecString data_default = (RecString)data_default_tmp;
   ink_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
@@ -354,7 +355,7 @@ RecRegisterConfigString(RecT rec_type, const char *name, const char *data_defaul
 
 int
 RecRegisterConfigCounter(RecT rec_type, const char *name, RecCounter data_default, RecUpdateT update_type, RecCheckT check_type,
-                         const char *check_regex, RecAccessT access_type)
+                         const char *check_regex, RecSourceT source, RecAccessT access_type)
 {
   ink_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
   REC_REGISTER_CONFIG_XXX(rec_counter, RECD_COUNTER);
@@ -365,7 +366,8 @@ RecRegisterConfigCounter(RecT rec_type, const char *name, RecCounter data_defaul
 // RecSetRecordXXX
 //-------------------------------------------------------------------------
 int
-RecSetRecord(RecT rec_type, const char *name, RecDataT data_type, RecData *data, RecRawStat *data_raw, bool lock, bool inc_version)
+RecSetRecord(RecT rec_type, const char *name, RecDataT data_type, RecData *data, RecRawStat *data_raw, RecSourceT source, bool lock,
+             bool inc_version)
 {
   int err = REC_ERR_OKAY;
   RecRecord *r1;
@@ -418,6 +420,8 @@ RecSetRecord(RecT rec_type, const char *name, RecDataT data_type, RecData *data,
         }
         if (REC_TYPE_IS_STAT(r1->rec_type) && (data_raw != NULL)) {
           r1->stat_meta.data_raw = *data_raw;
+        } else if (REC_TYPE_IS_CONFIG(r1->rec_type)) {
+          r1->config_meta.source = source;
         }
       }
       rec_mutex_release(&(r1->lock));
@@ -433,6 +437,8 @@ RecSetRecord(RecT rec_type, const char *name, RecDataT data_type, RecData *data,
       r2.data = *data;
       if (REC_TYPE_IS_STAT(r2.rec_type) && (data_raw != NULL)) {
         r2.stat_meta.data_raw = *data_raw;
+      } else if (REC_TYPE_IS_CONFIG(r2.rec_type)) {
+        r2.config_meta.source = source;
       }
       err = send_set_message(&r2);
       RecRecordFree(&r2);
@@ -451,6 +457,8 @@ RecSetRecord(RecT rec_type, const char *name, RecDataT data_type, RecData *data,
     RecDataSet(data_type, &(r1->data), data);
     if (REC_TYPE_IS_STAT(r1->rec_type) && (data_raw != NULL)) {
       r1->stat_meta.data_raw = *data_raw;
+    } else if (REC_TYPE_IS_CONFIG(r1->rec_type)) {
+      r1->config_meta.source = source;
     }
     if (i_am_the_record_owner(r1->rec_type)) {
       r1->sync_required = r1->sync_required | REC_PEER_SYNC_REQUIRED;
@@ -469,43 +477,43 @@ Ldone:
 }
 
 int
-RecSetRecordConvert(const char *name, const RecString rec_string, bool lock, bool inc_version)
+RecSetRecordConvert(const char *name, const RecString rec_string, RecSourceT source, bool lock, bool inc_version)
 {
   RecData data;
   data.rec_string = rec_string;
-  return RecSetRecord(RECT_NULL, name, RECD_NULL, &data, NULL, lock, inc_version);
+  return RecSetRecord(RECT_NULL, name, RECD_NULL, &data, NULL, source, lock, inc_version);
 }
 
 int
-RecSetRecordInt(const char *name, RecInt rec_int, bool lock, bool inc_version)
+RecSetRecordInt(const char *name, RecInt rec_int, RecSourceT source, bool lock, bool inc_version)
 {
   RecData data;
   data.rec_int = rec_int;
-  return RecSetRecord(RECT_NULL, name, RECD_INT, &data, NULL, lock, inc_version);
+  return RecSetRecord(RECT_NULL, name, RECD_INT, &data, NULL, source, lock, inc_version);
 }
 
 int
-RecSetRecordFloat(const char *name, RecFloat rec_float, bool lock, bool inc_version)
+RecSetRecordFloat(const char *name, RecFloat rec_float, RecSourceT source, bool lock, bool inc_version)
 {
   RecData data;
   data.rec_float = rec_float;
-  return RecSetRecord(RECT_NULL, name, RECD_FLOAT, &data, NULL, lock, inc_version);
+  return RecSetRecord(RECT_NULL, name, RECD_FLOAT, &data, NULL, source, lock, inc_version);
 }
 
 int
-RecSetRecordString(const char *name, const RecString rec_string, bool lock, bool inc_version)
+RecSetRecordString(const char *name, const RecString rec_string, RecSourceT source, bool lock, bool inc_version)
 {
   RecData data;
   data.rec_string = rec_string;
-  return RecSetRecord(RECT_NULL, name, RECD_STRING, &data, NULL, lock, inc_version);
+  return RecSetRecord(RECT_NULL, name, RECD_STRING, &data, NULL, source, lock, inc_version);
 }
 
 int
-RecSetRecordCounter(const char *name, RecCounter rec_counter, bool lock, bool inc_version)
+RecSetRecordCounter(const char *name, RecCounter rec_counter, RecSourceT source, bool lock, bool inc_version)
 {
   RecData data;
   data.rec_counter = rec_counter;
-  return RecSetRecord(RECT_NULL, name, RECD_COUNTER, &data, NULL, lock, inc_version);
+  return RecSetRecord(RECT_NULL, name, RECD_COUNTER, &data, NULL, source, lock, inc_version);
 }
 
 
@@ -535,7 +543,7 @@ RecReadStatsFile()
         // not registered yet. Either way, it's ok to just set the persisted value and keep going.
         if (RecGetRecordPersistenceType(r->name, &persist_type, false /* lock */) != REC_ERR_OKAY) {
           RecDebug(DL_Debug, "restoring value for persisted stat '%s'", r->name);
-          RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), &(r->stat_meta.data_raw), false);
+          RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), &(r->stat_meta.data_raw), REC_SOURCE_EXPLICIT, false);
           continue;
         }
 
@@ -554,7 +562,7 @@ RecReadStatsFile()
         }
 
         RecDebug(DL_Debug, "restoring value for persisted stat '%s'", r->name);
-        RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), &(r->stat_meta.data_raw), false);
+        RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), &(r->stat_meta.data_raw), REC_SOURCE_EXPLICIT, false);
       } while (RecMessageUnmarshalNext(m, &itr, &r) != REC_ERR_FAIL);
     }
   }
@@ -611,13 +619,13 @@ RecSyncStatsFile()
 
 // Consume a parsed record, pushing it into the records hash table.
 static void
-RecConsumeConfigEntry(RecT rec_type, RecDataT data_type, const char *name, const char *value, bool inc_version)
+RecConsumeConfigEntry(RecT rec_type, RecDataT data_type, const char *name, const char *value, RecSourceT source, bool inc_version)
 {
   RecData data;
 
   memset(&data, 0, sizeof(RecData));
   RecDataSetFromString(data_type, &data, value);
-  RecSetRecord(rec_type, name, data_type, &data, NULL, false, inc_version);
+  RecSetRecord(rec_type, name, data_type, &data, NULL, source, false, inc_version);
   RecDataClear(data_type, &data);
 }
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/lib/records/P_RecCore.h
----------------------------------------------------------------------
diff --git a/lib/records/P_RecCore.h b/lib/records/P_RecCore.h
index 6f9b6e2..6023072 100644
--- a/lib/records/P_RecCore.h
+++ b/lib/records/P_RecCore.h
@@ -60,7 +60,7 @@ int RecCoreInit(RecModeT mode_type, Diags *diags);
 RecRecord *RecRegisterStat(RecT rec_type, const char *name, RecDataT data_type, RecData data_default, RecPersistT persist_type);
 
 RecRecord *RecRegisterConfig(RecT rec_type, const char *name, RecDataT data_type, RecData data_default, RecUpdateT update_type,
-                             RecCheckT check_type, const char *check_regex, RecAccessT access_type = RECA_NULL);
+                             RecCheckT check_type, const char *check_regex, RecSourceT source, RecAccessT access_type = RECA_NULL);
 
 RecRecord *RecForceInsert(RecRecord *record);
 
@@ -68,8 +68,8 @@ RecRecord *RecForceInsert(RecRecord *record);
 // Setting/Getting
 //-------------------------------------------------------------------------
 
-int RecSetRecord(RecT rec_type, const char *name, RecDataT data_type, RecData *data, RecRawStat *raw_stat, bool lock = true,
-                 bool inc_version = true);
+int RecSetRecord(RecT rec_type, const char *name, RecDataT data_type, RecData *data, RecRawStat *raw_stat, RecSourceT source,
+                 bool lock = true, bool inc_version = true);
 
 int RecGetRecord_Xmalloc(const char *name, RecDataT data_type, RecData *data, bool lock = true);
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/lib/records/P_RecDefs.h
----------------------------------------------------------------------
diff --git a/lib/records/P_RecDefs.h b/lib/records/P_RecDefs.h
index 4e63d88..e125b1a 100644
--- a/lib/records/P_RecDefs.h
+++ b/lib/records/P_RecDefs.h
@@ -98,6 +98,7 @@ struct RecConfigMeta {
   RecCheckT check_type;
   char *check_expr;
   RecAccessT access_type;
+  RecSourceT source; ///< Source of the configuration value.
 };
 
 struct RecRecord {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/lib/records/RecConfigParse.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecConfigParse.cc b/lib/records/RecConfigParse.cc
index ce418e4..5798fb2 100644
--- a/lib/records/RecConfigParse.cc
+++ b/lib/records/RecConfigParse.cc
@@ -123,6 +123,7 @@ RecConfigFileParse(const char *path, RecConfigEntryCallback handler, bool inc_ve
   int line_num;
 
   char *rec_type_str, *name_str, *data_type_str, *data_str;
+  char const *value_str;
   RecT rec_type;
   RecDataT data_type;
 
@@ -233,7 +234,8 @@ RecConfigFileParse(const char *path, RecConfigEntryCallback handler, bool inc_ve
     }
 
     // OK, we parsed the record, send it to the handler ...
-    handler(rec_type, data_type, name_str, RecConfigOverrideFromEnvironment(name_str, data_str), inc_version);
+    value_str = RecConfigOverrideFromEnvironment(name_str, data_str);
+    handler(rec_type, data_type, name_str, value_str, value_str == data_str ? REC_SOURCE_EXPLICIT : REC_SOURCE_ENV, inc_version);
 
     // update our g_rec_config_contents_xxx
     cfe = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/lib/records/RecCore.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecCore.cc b/lib/records/RecCore.cc
index b4ccd81..fe4cbc0 100644
--- a/lib/records/RecCore.cc
+++ b/lib/records/RecCore.cc
@@ -39,7 +39,8 @@ int g_num_records = 0;
 // register_record
 //-------------------------------------------------------------------------
 static RecRecord *
-register_record(RecT rec_type, const char *name, RecDataT data_type, RecData data_default, RecPersistT persist_type)
+register_record(RecT rec_type, const char *name, RecDataT data_type, RecData data_default, RecPersistT persist_type,
+                bool *updated_p = NULL)
 {
   RecRecord *r = NULL;
 
@@ -48,6 +49,8 @@ register_record(RecT rec_type, const char *name, RecDataT data_type, RecData dat
     ink_release_assert(r->data_type == data_type);
     // Note: do not set r->data as we want to keep the previous value
     RecDataSet(r->data_type, &(r->data_default), &(data_default));
+    if (updated_p)
+      *updated_p = true;
   } else {
     if ((r = RecAlloc(rec_type, name, data_type)) == NULL) {
       return NULL;
@@ -60,6 +63,8 @@ register_record(RecT rec_type, const char *name, RecDataT data_type, RecData dat
     if (REC_TYPE_IS_STAT(r->rec_type)) {
       r->stat_meta.persist_type = persist_type;
     }
+    if (updated_p)
+      *updated_p = false;
   }
 
   // we're now registered
@@ -780,11 +785,13 @@ RecRegisterStat(RecT rec_type, const char *name, RecDataT data_type, RecData dat
 //-------------------------------------------------------------------------
 RecRecord *
 RecRegisterConfig(RecT rec_type, const char *name, RecDataT data_type, RecData data_default, RecUpdateT update_type,
-                  RecCheckT check_type, const char *check_expr, RecAccessT access_type)
+                  RecCheckT check_type, const char *check_expr, RecSourceT source, RecAccessT access_type)
 {
   RecRecord *r;
+  bool updated_p;
+
   ink_rwlock_wrlock(&g_records_rwlock);
-  if ((r = register_record(rec_type, name, data_type, data_default, RECP_NULL)) != NULL) {
+  if ((r = register_record(rec_type, name, data_type, data_default, RECP_NULL, &updated_p)) != NULL) {
     // Note: do not modify 'record->config_meta.update_required'
     r->config_meta.update_type = update_type;
     r->config_meta.check_type = check_type;
@@ -794,6 +801,8 @@ RecRegisterConfig(RecT rec_type, const char *name, RecDataT data_type, RecData d
     r->config_meta.check_expr = ats_strdup(check_expr);
     r->config_meta.update_cb_list = NULL;
     r->config_meta.access_type = access_type;
+    if (!updated_p)
+      r->config_meta.source = source;
   }
   ink_rwlock_unlock(&g_records_rwlock);
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/lib/records/RecLocal.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecLocal.cc b/lib/records/RecLocal.cc
index 8dc0dc3..0338d7a 100644
--- a/lib/records/RecLocal.cc
+++ b/lib/records/RecLocal.cc
@@ -95,7 +95,7 @@ sync_thr(void *data)
     } else {
       // If we didn't sync to disk, check whether we need to update ....
       if (configFiles->isConfigStale()) {
-        RecSetRecordInt("proxy.node.config.reconfigure_required", 1);
+        RecSetRecordInt("proxy.node.config.reconfigure_required", 1, REC_SOURCE_DEFAULT);
       }
     }
 
@@ -114,16 +114,16 @@ config_update_thr(void * /* data */)
   while (true) {
     switch (RecExecConfigUpdateCbs(REC_LOCAL_UPDATE_REQUIRED)) {
     case RECU_RESTART_TS:
-      RecSetRecordInt("proxy.node.config.restart_required.proxy", 1);
+      RecSetRecordInt("proxy.node.config.restart_required.proxy", 1, REC_SOURCE_DEFAULT);
       break;
     case RECU_RESTART_TM:
-      RecSetRecordInt("proxy.node.config.restart_required.proxy", 1);
-      RecSetRecordInt("proxy.node.config.restart_required.manager", 1);
+      RecSetRecordInt("proxy.node.config.restart_required.proxy", 1, REC_SOURCE_DEFAULT);
+      RecSetRecordInt("proxy.node.config.restart_required.manager", 1, REC_SOURCE_DEFAULT);
       break;
     case RECU_RESTART_TC:
-      RecSetRecordInt("proxy.node.config.restart_required.proxy", 1);
-      RecSetRecordInt("proxy.node.config.restart_required.manager", 1);
-      RecSetRecordInt("proxy.node.config.restart_required.cop", 1);
+      RecSetRecordInt("proxy.node.config.restart_required.proxy", 1, REC_SOURCE_DEFAULT);
+      RecSetRecordInt("proxy.node.config.restart_required.manager", 1, REC_SOURCE_DEFAULT);
+      RecSetRecordInt("proxy.node.config.restart_required.cop", 1, REC_SOURCE_DEFAULT);
       break;
     case RECU_NULL:
     case RECU_DYNAMIC:

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/mgmt/LocalManager.cc
----------------------------------------------------------------------
diff --git a/mgmt/LocalManager.cc b/mgmt/LocalManager.cc
index bd9d587..2a4fd4c 100644
--- a/mgmt/LocalManager.cc
+++ b/mgmt/LocalManager.cc
@@ -202,7 +202,7 @@ LocalManager::LocalManager(bool proxy_on) : BaseManager(), run_proxy(proxy_on),
   proxy_launch_outstanding = false;
   mgmt_shutdown_outstanding = MGMT_PENDING_NONE;
   proxy_running = 0;
-  RecSetRecordInt("proxy.node.proxy_running", 0);
+  RecSetRecordInt("proxy.node.proxy_running", 0, REC_SOURCE_DEFAULT);
   mgmt_sync_key = REC_readInteger("proxy.config.lm.sem_id", &found);
   if (!found || mgmt_sync_key <= 0) {
     mgmt_log("Bad or missing proxy.config.lm.sem_id value; using default id %d\n", MGMT_SEMID_DEFAULT);
@@ -389,7 +389,7 @@ LocalManager::initMgmtProcessServer()
   }
 
   umask(oldmask);
-  RecSetRecordInt("proxy.node.restarts.manager.start_time", manager_started_at);
+  RecSetRecordInt("proxy.node.restarts.manager.start_time", manager_started_at, REC_SOURCE_DEFAULT);
 }
 
 /*
@@ -515,7 +515,7 @@ LocalManager::pollMgmtProcessServer()
             proxy_running--;
           }
           proxy_started_at = -1;
-          RecSetRecordInt("proxy.node.proxy_running", 0);
+          RecSetRecordInt("proxy.node.proxy_running", 0, REC_SOURCE_DEFAULT);
         }
 
         num--;
@@ -540,7 +540,7 @@ LocalManager::handleMgmtMsgFromProcesses(MgmtMessageHdr *mh)
     proxy_running++;
     proxy_launch_pid = -1;
     proxy_launch_outstanding = false;
-    RecSetRecordInt("proxy.node.proxy_running", 1);
+    RecSetRecordInt("proxy.node.proxy_running", 1, REC_SOURCE_DEFAULT);
     break;
 
   case MGMT_SIGNAL_MACHINE_UP:
@@ -599,7 +599,7 @@ LocalManager::handleMgmtMsgFromProcesses(MgmtMessageHdr *mh)
     }
     switch (stype) {
     case MGMT_INT:
-      RecSetRecordInt(var_name, ink_atoi64(var_value));
+      RecSetRecordInt(var_name, ink_atoi64(var_value), REC_SOURCE_EXPLICIT);
       break;
     case MGMT_COUNTER:
     case MGMT_FLOAT:
@@ -751,7 +751,7 @@ LocalManager::sendMgmtMsgToProcesses(MgmtMessageHdr *mh)
               proxy_running--;
             }
             proxy_started_at = -1;
-            RecSetRecordInt("proxy.node.proxy_running", 0);
+            RecSetRecordInt("proxy.node.proxy_running", 0, REC_SOURCE_DEFAULT);
             // End of TS down
           } else {
             // TS is still up, but the connection is lost
@@ -917,8 +917,8 @@ LocalManager::startProxy()
     proxy_launch_outstanding = true;
     proxy_started_at = time(NULL);
     ++proxy_launch_count;
-    RecSetRecordInt("proxy.node.restarts.proxy.start_time", proxy_started_at);
-    RecSetRecordInt("proxy.node.restarts.proxy.restart_count", proxy_launch_count);
+    RecSetRecordInt("proxy.node.restarts.proxy.start_time", proxy_started_at, REC_SOURCE_DEFAULT);
+    RecSetRecordInt("proxy.node.restarts.proxy.restart_count", proxy_launch_count, REC_SOURCE_DEFAULT);
   } else {
     int res, i = 0;
     char *options[32], *last, *tok;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/mgmt/RecordsConfigUtils.cc
----------------------------------------------------------------------
diff --git a/mgmt/RecordsConfigUtils.cc b/mgmt/RecordsConfigUtils.cc
index 640fe2f..7c16503 100644
--- a/mgmt/RecordsConfigUtils.cc
+++ b/mgmt/RecordsConfigUtils.cc
@@ -42,7 +42,7 @@ override_record(const RecordElement *record, void *)
         // of the record. It sends a set message to the local manager. This can cause
         // "interesting" results if you are trying to override configuration values
         // early in startup (before we have synced with the local manager).
-        RecSetRecord(record->type, record->name, record->value_type, &data, NULL, false);
+        RecSetRecord(record->type, record->name, record->value_type, &data, NULL, REC_SOURCE_ENV, false);
         RecDataClear(record->value_type, &data);
       }
     }
@@ -83,6 +83,7 @@ initialize_record(const RecordElement *record, void *)
   if (REC_TYPE_IS_CONFIG(type)) {
     const char *value = RecConfigOverrideFromEnvironment(record->name, record->value);
     RecData data = {0};
+    RecSourceT source = value == record->value ? REC_SOURCE_DEFAULT : REC_SOURCE_ENV;
 
     // If you specify a consistency check, you have to specify a regex expression. We abort here
     // so that this breaks QA completely.
@@ -94,19 +95,19 @@ initialize_record(const RecordElement *record, void *)
 
     switch (record->value_type) {
     case RECD_INT:
-      RecRegisterConfigInt(type, record->name, data.rec_int, update, check, record->regex, access);
+      RecRegisterConfigInt(type, record->name, data.rec_int, update, check, record->regex, source, access);
       break;
 
     case RECD_FLOAT:
-      RecRegisterConfigFloat(type, record->name, data.rec_float, update, check, record->regex, access);
+      RecRegisterConfigFloat(type, record->name, data.rec_float, update, check, record->regex, source, access);
       break;
 
     case RECD_STRING:
-      RecRegisterConfigString(type, record->name, data.rec_string, update, check, record->regex, access);
+      RecRegisterConfigString(type, record->name, data.rec_string, update, check, record->regex, source, access);
       break;
 
     case RECD_COUNTER:
-      RecRegisterConfigCounter(type, record->name, data.rec_counter, update, check, record->regex, access);
+      RecRegisterConfigCounter(type, record->name, data.rec_counter, update, check, record->regex, source, access);
       break;
 
     default:

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/mgmt/WebMgmtUtils.cc
----------------------------------------------------------------------
diff --git a/mgmt/WebMgmtUtils.cc b/mgmt/WebMgmtUtils.cc
index 33ed33c..b6572e2 100644
--- a/mgmt/WebMgmtUtils.cc
+++ b/mgmt/WebMgmtUtils.cc
@@ -71,14 +71,14 @@ varSetFromStr(const char *varName, const char *value)
   switch (varDataType) {
   case RECD_INT:
     if (sscanf(value, "%" PRId64 "", &data.rec_int) == 1) {
-      RecSetRecordInt((char *)varName, data.rec_int);
+      RecSetRecordInt((char *)varName, data.rec_int, REC_SOURCE_EXPLICIT);
     } else {
       found = false;
     }
     break;
   case RECD_COUNTER:
     if (sscanf(value, "%" PRId64 "", &data.rec_counter) == 1) {
-      RecSetRecordCounter((char *)varName, data.rec_counter);
+      RecSetRecordCounter((char *)varName, data.rec_counter, REC_SOURCE_EXPLICIT);
     } else {
       found = false;
     }
@@ -86,16 +86,16 @@ varSetFromStr(const char *varName, const char *value)
   case RECD_FLOAT:
     // coverity[secure_coding]
     if (sscanf(value, "%f", &data.rec_float) == 1) {
-      RecSetRecordFloat((char *)varName, data.rec_float);
+      RecSetRecordFloat((char *)varName, data.rec_float, REC_SOURCE_EXPLICIT);
     } else {
       found = false;
     }
     break;
   case RECD_STRING:
     if (*value == '\0') {
-      RecSetRecordString((char *)varName, NULL);
+      RecSetRecordString((char *)varName, NULL, REC_SOURCE_EXPLICIT);
     } else {
-      RecSetRecordString((char *)varName, (char *)value);
+      RecSetRecordString((char *)varName, (char *)value, REC_SOURCE_EXPLICIT);
     }
     break;
   case RECD_NULL:
@@ -130,17 +130,17 @@ varSetFloat(const char *varName, RecFloat value, bool convert)
 
   switch (varDataType) {
   case RECD_FLOAT:
-    RecSetRecordFloat((char *)varName, (RecFloat)value);
+    RecSetRecordFloat((char *)varName, (RecFloat)value, REC_SOURCE_EXPLICIT);
     break;
   case RECD_INT:
     if (convert) {
       value += 0.5; // rounding up
-      RecSetRecordInt((char *)varName, (RecInt)value);
+      RecSetRecordInt((char *)varName, (RecInt)value, REC_SOURCE_EXPLICIT);
       break;
     }
   case RECD_COUNTER:
     if (convert) {
-      RecSetRecordCounter((char *)varName, (RecCounter)value);
+      RecSetRecordCounter((char *)varName, (RecCounter)value, REC_SOURCE_EXPLICIT);
       break;
     }
   case RECD_STRING:
@@ -176,16 +176,16 @@ varSetCounter(const char *varName, RecCounter value, bool convert)
 
   switch (varDataType) {
   case RECD_COUNTER:
-    RecSetRecordCounter((char *)varName, (RecCounter)value);
+    RecSetRecordCounter((char *)varName, (RecCounter)value, REC_SOURCE_EXPLICIT);
     break;
   case RECD_INT:
     if (convert) {
-      RecSetRecordInt((char *)varName, (RecInt)value);
+      RecSetRecordInt((char *)varName, (RecInt)value, REC_SOURCE_EXPLICIT);
       break;
     }
   case RECD_FLOAT:
     if (convert) {
-      RecSetRecordFloat((char *)varName, (RecFloat)value);
+      RecSetRecordFloat((char *)varName, (RecFloat)value, REC_SOURCE_EXPLICIT);
       break;
     }
   case RECD_STRING:
@@ -221,16 +221,16 @@ varSetInt(const char *varName, RecInt value, bool convert)
 
   switch (varDataType) {
   case RECD_INT:
-    RecSetRecordInt((char *)varName, (RecInt)value);
+    RecSetRecordInt((char *)varName, (RecInt)value, REC_SOURCE_EXPLICIT);
     break;
   case RECD_COUNTER:
     if (convert) {
-      RecSetRecordCounter((char *)varName, (RecCounter)value);
+      RecSetRecordCounter((char *)varName, (RecCounter)value, REC_SOURCE_EXPLICIT);
       break;
     }
   case RECD_FLOAT:
     if (convert) {
-      RecSetRecordFloat((char *)varName, (RecFloat)value);
+      RecSetRecordFloat((char *)varName, (RecFloat)value, REC_SOURCE_EXPLICIT);
       break;
     }
   case RECD_STRING:
@@ -255,13 +255,13 @@ varSetData(RecDataT varType, const char *varName, RecData value)
 
   switch (varType) {
   case RECD_INT:
-    err = RecSetRecordInt((char *)varName, value.rec_int);
+    err = RecSetRecordInt((char *)varName, value.rec_int, REC_SOURCE_EXPLICIT);
     break;
   case RECD_COUNTER:
-    err = RecSetRecordCounter((char *)varName, value.rec_counter);
+    err = RecSetRecordCounter((char *)varName, value.rec_counter, REC_SOURCE_EXPLICIT);
     break;
   case RECD_FLOAT:
-    err = RecSetRecordFloat((char *)varName, value.rec_float);
+    err = RecSetRecordFloat((char *)varName, value.rec_float, REC_SOURCE_EXPLICIT);
     break;
   default:
     Fatal("unsupport type:%d\n", varType);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/mgmt/api/CoreAPI.cc
----------------------------------------------------------------------
diff --git a/mgmt/api/CoreAPI.cc b/mgmt/api/CoreAPI.cc
index 69de7a0..48da1e2 100644
--- a/mgmt/api/CoreAPI.cc
+++ b/mgmt/api/CoreAPI.cc
@@ -413,8 +413,8 @@ Reconfigure()
 {
   configFiles->rereadConfig();                              // TM rereads
   lmgmt->signalEvent(MGMT_EVENT_PLUGIN_CONFIG_UPDATE, "*"); // TS rereads
-  RecSetRecordInt("proxy.node.config.reconfigure_time", time(NULL));
-  RecSetRecordInt("proxy.node.config.reconfigure_required", 0);
+  RecSetRecordInt("proxy.node.config.reconfigure_time", time(NULL), REC_SOURCE_DEFAULT);
+  RecSetRecordInt("proxy.node.config.reconfigure_required", 0, REC_SOURCE_DEFAULT);
 
   return TS_ERR_OKAY;
 }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/mgmt/api/CoreAPIRemote.cc
----------------------------------------------------------------------
diff --git a/mgmt/api/CoreAPIRemote.cc b/mgmt/api/CoreAPIRemote.cc
index 4a2a35a..60592ad 100644
--- a/mgmt/api/CoreAPIRemote.cc
+++ b/mgmt/api/CoreAPIRemote.cc
@@ -585,9 +585,10 @@ MgmtConfigRecordDescribe(const char *rec_name, unsigned options, TSConfigRecordD
     MgmtMarshallInt update;
     MgmtMarshallInt updatetype;
     MgmtMarshallInt checktype;
+    MgmtMarshallInt source;
 
     ret = recv_mgmt_response(reply.ptr, reply.len, RECORD_DESCRIBE_CONFIG, &err, &name, &value, &deflt, &rtype, &rclass, &version,
-                             &rsb, &order, &access, &update, &updatetype, &checktype, &expr);
+                             &rsb, &order, &access, &update, &updatetype, &checktype, &source, &expr);
 
     ats_free(reply.ptr);
 
@@ -611,6 +612,7 @@ MgmtConfigRecordDescribe(const char *rec_name, unsigned options, TSConfigRecordD
     val->rec_access = access;
     val->rec_updatetype = updatetype;
     val->rec_checktype = checktype;
+    val->rec_source = source;
 
     mgmt_record_convert_value(val->rec_type, value, val->rec_value);
     mgmt_record_convert_value(val->rec_type, deflt, val->rec_default);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/mgmt/api/NetworkMessage.cc
----------------------------------------------------------------------
diff --git a/mgmt/api/NetworkMessage.cc b/mgmt/api/NetworkMessage.cc
index 3d15861..160bed8 100644
--- a/mgmt/api/NetworkMessage.cc
+++ b/mgmt/api/NetworkMessage.cc
@@ -97,13 +97,13 @@ static const struct NetCmdOperation responses[] = {
   /* RECORD_MATCH_GET           */ {4, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING, MGMT_MARSHALL_DATA}},
   /* API_PING                   */ {0, {}}, // no reply
   /* SERVER_BACKTRACE           */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
-  /* RECORD_DESCRIBE_CONFIG     */ {14,
+  /* RECORD_DESCRIBE_CONFIG     */ {15,
                                     {MGMT_MARSHALL_INT /* status */, MGMT_MARSHALL_STRING /* name */,
                                      MGMT_MARSHALL_DATA /* value */, MGMT_MARSHALL_DATA /* default */, MGMT_MARSHALL_INT /* type */,
                                      MGMT_MARSHALL_INT /* class */, MGMT_MARSHALL_INT /* version */, MGMT_MARSHALL_INT /* rsb */,
                                      MGMT_MARSHALL_INT /* order */, MGMT_MARSHALL_INT /* access */, MGMT_MARSHALL_INT /* update */,
                                      MGMT_MARSHALL_INT /* updatetype */, MGMT_MARSHALL_INT /* checktype */,
-                                     MGMT_MARSHALL_STRING /* checkexpr */}},
+                                     MGMT_MARSHALL_INT /* source */, MGMT_MARSHALL_STRING /* checkexpr */}},
 };
 
 #define GETCMD(ops, optype, cmd)                                       \
@@ -236,11 +236,11 @@ send_mgmt_error(int fd, OpType optype, TSMgmtError error)
     return send_mgmt_response(fd, optype, &ecode, &intval, &strval, &dataval);
 
   case RECORD_DESCRIBE_CONFIG:
-    ink_release_assert(responses[optype].nfields == 14);
+    ink_release_assert(responses[optype].nfields == 15);
     return send_mgmt_response(fd, optype, &ecode, &strval /* name */, &dataval /* value */, &dataval /* default */,
                               &intval /* type */, &intval /* class */, &intval /* version */, &intval /* rsb */,
                               &intval /* order */, &intval /* access */, &intval /* update */, &intval /* updatetype */,
-                              &intval /* checktype */, &strval /* checkexpr */);
+                              &intval /* checktype */, &intval /* source */, &strval /* checkexpr */);
 
   case EVENT_REG_CALLBACK:
   case EVENT_UNREG_CALLBACK:

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/mgmt/api/TSControlMain.cc
----------------------------------------------------------------------
diff --git a/mgmt/api/TSControlMain.cc b/mgmt/api/TSControlMain.cc
index bc8537f..a771ca3 100644
--- a/mgmt/api/TSControlMain.cc
+++ b/mgmt/api/TSControlMain.cc
@@ -1025,6 +1025,7 @@ send_record_describe(const RecRecord *rec, void *ptr)
   MgmtMarshallInt rec_update = rec->config_meta.update_required;
   MgmtMarshallInt rec_updatetype = rec->config_meta.update_type;
   MgmtMarshallInt rec_checktype = rec->config_meta.check_type;
+  MgmtMarshallInt rec_source = rec->config_meta.source;
   MgmtMarshallString rec_checkexpr = rec->config_meta.check_expr;
 
   MgmtMarshallInt err = TS_ERR_OKAY;
@@ -1066,7 +1067,7 @@ send_record_describe(const RecRecord *rec, void *ptr)
 
   err = send_mgmt_response(*fderr, RECORD_DESCRIBE_CONFIG, &err, &rec_name, &rec_value, &rec_default, &rec_type, &rec_class,
                            &rec_version, &rec_rsb, &rec_order, &rec_access, &rec_update, &rec_updatetype, &rec_checktype,
-                           &rec_checkexpr);
+                           &rec_source, &rec_checkexpr);
 
 done:
   *fderr = err;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/mgmt/api/include/mgmtapi.h
----------------------------------------------------------------------
diff --git a/mgmt/api/include/mgmtapi.h b/mgmt/api/include/mgmtapi.h
index b1be9ef..f99b5c7 100644
--- a/mgmt/api/include/mgmtapi.h
+++ b/mgmt/api/include/mgmtapi.h
@@ -419,6 +419,7 @@ typedef struct {
   TSInt rec_update;     /* update_required bitmask */
   TSInt rec_updatetype; /* update type (RecUpdateT) */
   TSInt rec_checktype;  /* syntax check type (RecCheckT) */
+  TSInt rec_source;     /* source of data */
   char *rec_checkexpr;  /* syntax check expression */
 } TSConfigRecordDescription;
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/mgmt/cluster/ClusterCom.cc
----------------------------------------------------------------------
diff --git a/mgmt/cluster/ClusterCom.cc b/mgmt/cluster/ClusterCom.cc
index 1766c85..03cee45 100644
--- a/mgmt/cluster/ClusterCom.cc
+++ b/mgmt/cluster/ClusterCom.cc
@@ -2336,7 +2336,7 @@ checkBackDoor(int req_fd, char *message)
       return false;
     }
     // TODO: I think this is correct, it used to do lmgmt->record_data-> ...
-    if (RecSetRecordConvert(variable, value, true, false) == REC_ERR_OKAY) {
+    if (RecSetRecordConvert(variable, value, REC_SOURCE_EXPLICIT, true, false) == REC_ERR_OKAY) {
       ink_strlcpy(reply, "\nRecord Updated\n\n", sizeof(reply));
       mgmt_writeline(req_fd, reply, strlen(reply));
     } else {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/proxy/InkAPI.cc
----------------------------------------------------------------------
diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc
index e45cfb3..329d687 100644
--- a/proxy/InkAPI.cc
+++ b/proxy/InkAPI.cc
@@ -8559,7 +8559,8 @@ TSMgmtStringCreate(TSRecordType rec_type, const char *name, const TSMgmtString d
   if (check_regex == NULL && check_type != TS_RECORDCHECK_NULL)
     return TS_ERROR;
   if (REC_ERR_OKAY != RecRegisterConfigString((enum RecT)rec_type, name, data_default, (enum RecUpdateT)update_type,
-                                              (enum RecCheckT)check_type, check_regex, (enum RecAccessT)access_type))
+                                              (enum RecCheckT)check_type, check_regex, REC_SOURCE_EXPLICIT,
+                                              (enum RecAccessT)access_type))
     return TS_ERROR;
 
   return TS_SUCCESS;
@@ -8572,7 +8573,8 @@ TSMgmtIntCreate(TSRecordType rec_type, const char *name, TSMgmtInt data_default,
   if (check_regex == NULL && check_type != TS_RECORDCHECK_NULL)
     return TS_ERROR;
   if (REC_ERR_OKAY != RecRegisterConfigInt((enum RecT)rec_type, name, (RecInt)data_default, (enum RecUpdateT)update_type,
-                                           (enum RecCheckT)check_type, check_regex, (enum RecAccessT)access_type))
+                                           (enum RecCheckT)check_type, check_regex, REC_SOURCE_EXPLICIT,
+                                           (enum RecAccessT)access_type))
     return TS_ERROR;
 
   return TS_SUCCESS;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/proxy/Main.cc
----------------------------------------------------------------------
diff --git a/proxy/Main.cc b/proxy/Main.cc
index 393dc2d..6c17c99 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -537,7 +537,7 @@ CB_After_Cache_Init()
   }
 
   time_t cache_ready_at = time(NULL);
-  RecSetRecordInt("proxy.node.restarts.proxy.cache_ready_time", cache_ready_at);
+  RecSetRecordInt("proxy.node.restarts.proxy.cache_ready_time", cache_ready_at, REC_SOURCE_DEFAULT);
 
   // Alert the plugins the cache is initialized.
   hook = lifecycle_hooks->get(TS_LIFECYCLE_CACHE_READY_HOOK);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/492e7bea/proxy/shared/DiagsConfig.cc
----------------------------------------------------------------------
diff --git a/proxy/shared/DiagsConfig.cc b/proxy/shared/DiagsConfig.cc
index 91f1f9a..5103f4c 100644
--- a/proxy/shared/DiagsConfig.cc
+++ b/proxy/shared/DiagsConfig.cc
@@ -247,20 +247,20 @@ DiagsConfig::config_diags_norecords()
 void
 DiagsConfig::RegisterDiagConfig()
 {
-  RecRegisterConfigInt(RECT_CONFIG, "proxy.config.diags.debug.enabled", 0, RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.debug.tags", "", RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigInt(RECT_CONFIG, "proxy.config.diags.action.enabled", 0, RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.action.tags", "", RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigInt(RECT_CONFIG, "proxy.config.diags.show_location", 0, RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.diag", "L", RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.debug", "L", RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.status", "L", RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.note", "L", RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.warning", "L", RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.error", "SL", RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.fatal", "SL", RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.alert", "L", RECU_NULL, RECC_NULL, NULL);
-  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.emergency", "SL", RECU_NULL, RECC_NULL, NULL);
+  RecRegisterConfigInt(RECT_CONFIG, "proxy.config.diags.debug.enabled", 0, RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.debug.tags", "", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigInt(RECT_CONFIG, "proxy.config.diags.action.enabled", 0, RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.action.tags", "", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigInt(RECT_CONFIG, "proxy.config.diags.show_location", 0, RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.diag", "L", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.debug", "L", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.status", "L", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.note", "L", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.warning", "L", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.error", "SL", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.fatal", "SL", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.alert", "L", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
+  RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.emergency", "SL", RECU_NULL, RECC_NULL, NULL, REC_SOURCE_DEFAULT);
 }