You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by fr...@apache.org on 2016/11/08 19:15:29 UTC
[1/2] incubator-trafficcontrol git commit: TC-35: Add trafficserver
diff for trafficserver-5.3.2.ee14bbe
Repository: incubator-trafficcontrol
Updated Branches:
refs/heads/master 6c58d878a -> e15a0d475
TC-35: Add trafficserver diff for trafficserver-5.3.2.ee14bbe
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/8fb67b46
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/8fb67b46
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/8fb67b46
Branch: refs/heads/master
Commit: 8fb67b4612f7c69130078a0bad18cf863622c632
Parents: 6c58d87
Author: John Rushford <jr...@apache.org>
Authored: Tue Nov 8 11:09:15 2016 -0700
Committer: John Rushford <jr...@apache.org>
Committed: Tue Nov 8 11:09:15 2016 -0700
----------------------------------------------------------------------
.../patches/trafficserver-5.3.2-ee14bbe.diff | 673 +++++++++++++++++++
1 file changed, 673 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/8fb67b46/traffic_server/patches/trafficserver-5.3.2-ee14bbe.diff
----------------------------------------------------------------------
diff --git a/traffic_server/patches/trafficserver-5.3.2-ee14bbe.diff b/traffic_server/patches/trafficserver-5.3.2-ee14bbe.diff
new file mode 100644
index 0000000..e28e787
--- /dev/null
+++ b/traffic_server/patches/trafficserver-5.3.2-ee14bbe.diff
@@ -0,0 +1,673 @@
+diff --git a/configure.ac b/configure.ac
+index 2c79ca4..a46a43e 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1960,6 +1960,7 @@ AS_IF([test "x$enable_experimental_plugins" = xyes], [
+ plugins/experimental/hipes/Makefile
+ plugins/experimental/metalink/Makefile
+ plugins/experimental/mysql_remap/Makefile
++ plugins/experimental/money_trace/Makefile
+ plugins/experimental/regex_revalidate/Makefile
+ plugins/experimental/remap_stats/Makefile
+ plugins/experimental/s3_auth/Makefile
+diff --git a/iocore/aio/AIO.cc b/iocore/aio/AIO.cc
+index 4dd1842..5c4b217 100644
+--- a/iocore/aio/AIO.cc
++++ b/iocore/aio/AIO.cc
+@@ -187,6 +187,10 @@ struct AIOThreadInfo : public Continuation {
+ {
+ (void)event;
+ (void)e;
++#if TS_USE_HWLOC
++ hwloc_set_membind_nodeset(ink_get_topology(), hwloc_topology_get_topology_nodeset(ink_get_topology()), HWLOC_MEMBIND_INTERLEAVE,
++ HWLOC_MEMBIND_THREAD);
++#endif
+ aio_thread_main(this);
+ return EVENT_DONE;
+ }
+diff --git a/iocore/hostdb/HostDB.cc b/iocore/hostdb/HostDB.cc
+index a7f5c55..8a21a70 100644
+--- a/iocore/hostdb/HostDB.cc
++++ b/iocore/hostdb/HostDB.cc
+@@ -1470,6 +1470,12 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
+ // @c lookup_done should always return a valid value so @a r should be null @c NULL.
+ ink_assert(r && r->app.allotment.application1 == 0 && r->app.allotment.application2 == 0);
+
++ // lookup_done() returned null due to full hostdb database.
++ if (!r) {
++ Debug("hostdb", "HostDBInfo pointer 'r' is NULL");
++ failed = true;
++ }
++
+ if (rr) {
+ const int rrsize = HostDBRoundRobin::size(n, e->srv_hosts.srv_hosts_length);
+ HostDBRoundRobin *rr_data = (HostDBRoundRobin *)hostDB.alloc(&r->app.rr.offset, rrsize);
+diff --git a/mgmt/api/TSControlMain.cc b/mgmt/api/TSControlMain.cc
+index a771ca3..a3e64a4 100644
+--- a/mgmt/api/TSControlMain.cc
++++ b/mgmt/api/TSControlMain.cc
+@@ -967,7 +967,7 @@ handle_stats_reset(int fd, void *req, size_t reqlen)
+ MgmtMarshallInt err;
+
+ err = recv_mgmt_request(req, reqlen, STATS_RESET_NODE, &optype, &name);
+- if (err != TS_ERR_OKAY) {
++ if (err == TS_ERR_OKAY) {
+ err = StatsReset(optype == STATS_RESET_CLUSTER, name);
+ }
+
+diff --git a/plugins/experimental/Makefile.am b/plugins/experimental/Makefile.am
+index adb6da8..8f5d48e 100644
+--- a/plugins/experimental/Makefile.am
++++ b/plugins/experimental/Makefile.am
+@@ -33,6 +33,7 @@ SUBDIRS = \
+ healthchecks \
+ hipes \
+ metalink \
++ money_trace \
+ regex_revalidate \
+ remap_stats \
+ s3_auth \
+diff --git a/plugins/experimental/money_trace/money_trace.cc b/plugins/experimental/money_trace/money_trace.cc
+index adb8980..09f8cd4 100644
+--- a/plugins/experimental/money_trace/money_trace.cc
++++ b/plugins/experimental/money_trace/money_trace.cc
+@@ -71,7 +71,7 @@ freeTransactionData(struct txndata *txn_data)
+
+ /**
+ * The TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE event callback.
+- *
++ *
+ * If there is a cache hit only schedule a TS_HTTP_SEND_RESPONSE_HDR_HOOK
+ * continuation to send back the money trace header in the response to the
+ * client.
+@@ -79,7 +79,7 @@ freeTransactionData(struct txndata *txn_data)
+ * If there is a cache miss, a new money trace header is created and a
+ * TS_HTTP_SEND_REQUES_HDR_HOOK continuation is scheduled to add the
+ * new money trace header to the parent request.
+- */
++ */
+ static void
+ mt_cache_lookup_check(TSCont contp, TSHttpTxn txnp, struct txndata *txn_data)
+ {
+@@ -157,10 +157,10 @@ mt_check_request_header(TSHttpTxn txnp)
+
+ /**
+ * The TS_EVENT_HTTP_SEND_RESPONSE_HDR callback.
+- *
++ *
+ * Adds the money trace header received in the client request to the
+ * client response headers.
+- */
++ */
+ static void
+ mt_send_client_response(TSHttpTxn txnp, struct txndata *txn_data)
+ {
+diff --git a/plugins/experimental/url_sig/README b/plugins/experimental/url_sig/README
+index 81fdd33..e4c4ca2 100644
+--- a/plugins/experimental/url_sig/README
++++ b/plugins/experimental/url_sig/README
+@@ -84,15 +84,19 @@ Signing a URL using path parameters instead of using a query string.
+ in the request url. Any origin application query parameters then follow
+ the file part of the request and are never part of the sign string.
+
+- Path parameters are separated by a ';' in the path. The following is an
+- example signed request using the path parameter method and with an origin
+- application query string:
++ Path parameters are separated by a ';' in the path. The complete signature
++ string is base64 encoded as a single path parameter that is assinged to the
++ 'siganchor', and will appear in that path as siganchor=base64string. The
++ following is an example signed request using the path parameter method and
++ with an origin application query string:
+
+- http://ds-01.comcast.net/vod/t;E=1454013671;A=1;K=3;P=1;S=686945c15e8c4e02146af86a9fd8ee29ff432b0a/Frag10Num10.ts?appid=2&t=1
++ http://ds-01.comcast.net/vod/t;urlsig=O0U9MTQ2MzkyOTYxODtBPTE7Sz0zO1A9MTtTPTEyZDlmN2RiNjUyZWI0YmI4MWYyNmVlMjE3MzczZGE5Y2VkYTRmZGY/Frag10Num10.ts?appid=2&t=1
+
+- Note that the signing parameters are embedded in the path between the last directory part and before the file part of
+- the request. Using 'parts' in sign.pl, the signature may be signed accordingly up to S= in the above request. To
+- generate a signed url using this method, use the --pathparams option in sign.pl
++ Note that the signing string is embedded in the path between the last
++ directory part and before the file part of the request. Using 'parts' in
++ sign.pl, the signature may be signed accordingly up to S= in the above
++ request. To generate a signed url using this method, use the --pathparams
++ option in sign.pl
+
+
+
+@@ -163,7 +167,8 @@ Example
+ Authorization Denied$
+ $
+
+- Sign the URL and try it again. Run the script with appropriate params, and it will output the curl line to run:
++ Sign the URL and try it again. Run the script with appropriate params, and
++ it will output the curl line to run:
+
+ $ ./sign.pl --url http://test-remap.domain.com/ --useparts 1 --algorithm 1 --duration 60 --keyindex 3 --key DTV4Tcn046eM9BzJMeYrYpm3kbqOtBs7
+ curl -s -o /dev/null -v --max-redirs 0 'http://test-remap.domain.com/?E=1397603088&A=1&K=3&P=1&S=28d822f68ac7265db61a8441e0877a98fe1007cc'
+@@ -205,7 +210,12 @@ Example
+
+ Generating a signed URL with path parameters:
+
+- $ ./sign.pl --url "http://test-remap.domain.com/vod/t/prog_index.m3u8?appid=2&t=1" --useparts 1 --algorithm 1 --duration 86400 --keyindex 3 --key kSCE1_uBREdGI3TPnr_dXKc9f_J4ZV2f --pathparams
++ $ ./sign.pl --url "http://test-remap.domain.com/vod/t/prog_index.m3u8?appid=2&t=1" --useparts 1 --algorithm 1 --duration 86400 --keyindex 3 --key kSCE1_uBREdGI3TPnr_dXKc9f_J4ZV2f --pathparams --siganchor urlsig
+
+- curl -s -o /dev/null -v --max-redirs 0 'http://test-remap.domain.com/vod/t;E=1454015105;A=1;K=3;P=1;S=/173f2ff3667371e666fa17be6c37bfdfe6e89eccprog_index.m3u8?appid=2&t=1'
++ curl -s -o /dev/null -v --max-redirs 0 'http://test-remap.domain.com/vod/t;urlsig=O0U9MTQ2MzkyOTM4NTtBPTE7Sz0zO1A9MTtTPTIxYzk2YWRiZWZkOGJkMDFhYmM3MmZkMTEzMWVkMGM5ZmU1ZmFiMjE/prog_index.m3u8?appid=2&t=1'
+
++
++Client IP in the Signing Script
++ Below is an example of how to include client ip in the signing script
++ Works for both IPv4 and IPv6
++ --client 10.10.10.10
+diff --git a/plugins/experimental/url_sig/url_sig.c b/plugins/experimental/url_sig/url_sig.c
+index baf381f..b2b522c 100644
+--- a/plugins/experimental/url_sig/url_sig.c
++++ b/plugins/experimental/url_sig/url_sig.c
+@@ -176,9 +176,9 @@ TSRemapNewInstance(int argc, char *argv[], void **ih, char *errbuf, int errbuf_s
+ cfg->err_url = TSstrndup(value, strlen(value));
+ else
+ cfg->err_url = NULL;
+- } else if (strncmp(line, "sig_anchor", 10) == 0) {
+- cfg->sig_anchor = TSstrndup(value, strlen(value));
+- TSDebug(PLUGIN_NAME, "sig_anchor: %s", cfg->sig_anchor);
++ } else if (strncmp(line, "sig_anchor", 10) == 0) {
++ cfg->sig_anchor = TSstrndup(value, strlen(value));
++ TSDebug(PLUGIN_NAME, "sig_anchor: %s", cfg->sig_anchor);
+ } else if (strncmp(line, "excl_regex", 10) == 0) {
+ // compile and study regex
+ const char *errptr;
+@@ -317,7 +317,7 @@ urlParse(bool *https, char *anchor, char *url, char *new_path_seg, int new_path_
+ segment[numtoks] = p;
+ if (anchor != NULL && sig_anchor_seg == 0) {
+ // look for the signed anchor string.
+- if ((sig_anchor = strcasestr(segment[numtoks],anchor)) != NULL) {
++ if ((sig_anchor = strcasestr(segment[numtoks], anchor)) != NULL) {
+ // null terminate this segment just before he signing anchor, this should be a ';'.
+ *(sig_anchor - 1) = '\0';
+ if ((sig_anchor = strstr(sig_anchor, "=")) != NULL) {
+@@ -343,7 +343,7 @@ urlParse(bool *https, char *anchor, char *url, char *new_path_seg, int new_path_
+ for (i = 2; i < numtoks; i++) {
+ // if no signing anchor is found, skip the signed parameters segment.
+ if (sig_anchor == NULL && i == numtoks - 2) {
+- // the signing parameters when no signature anchor is found, should be in the
++ // the signing parameters when no signature anchor is found, should be in the
+ // last path segment so skip them.
+ continue;
+ }
+@@ -382,12 +382,12 @@ urlParse(bool *https, char *anchor, char *url, char *new_path_seg, int new_path_
+ // to be in the last path segment.
+ if (sig_anchor == NULL) {
+ if (TSBase64Decode(segment[numtoks - 2], strlen(segment[numtoks - 2]), decoded_string, sizeof(decoded_string),
+- (size_t *)&decoded_len) != TS_SUCCESS) {
++ (size_t *)&decoded_len) != TS_SUCCESS) {
+ TSDebug(PLUGIN_NAME, "Unable to decode the path parameter string.");
+ }
+ } else {
+- if (TSBase64Decode(sig_anchor, strlen(sig_anchor), decoded_string, sizeof(decoded_string),
+- (size_t *)&decoded_len) != TS_SUCCESS) {
++ if (TSBase64Decode(sig_anchor, strlen(sig_anchor), decoded_string, sizeof(decoded_string), (size_t *)&decoded_len) !=
++ TS_SUCCESS) {
+ TSDebug(PLUGIN_NAME, "Unable to decode the path parameter string.");
+ }
+ }
+@@ -412,7 +412,7 @@ urlParse(bool *https, char *anchor, char *url, char *new_path_seg, int new_path_
+ continue;
+ }
+ strncat(new_url, segment[i], strlen(segment[i]));
+- if (i < numtoks - 1) {
++ if (i < numtoks - 1) {
+ strncat(new_url, "/", 1);
+ }
+ }
+@@ -518,52 +518,52 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
+ p = strstr(query, CIP_QSTRING "=");
+ if (p != NULL) {
+ p += (strlen(CIP_QSTRING) + 1);
+- struct sockaddr const *ip = TSHttpTxnClientAddrGet(txnp);
++ struct sockaddr const *ip = TSHttpTxnClientAddrGet(txnp);
+ if (ip == NULL) {
+ TSError("Can't get client ip address.");
+ goto deny;
+ } else {
+ switch (ip->sa_family) {
+- case AF_INET:
+- TSDebug(PLUGIN_NAME, "ip->sa_family: AF_INET");
+- isClient_ipv6 = false;
+- has_path_params == false ? (pp = strstr(p, "&")) : (pp = strstr(p, ";"));
+- if ((pp - p) > INET_ADDRSTRLEN - 1 || (pp - p) < 4) {
+- err_log(url, "IP address string too long or short.");
+- goto deny;
+- }
+- strncpy(client_ipv4, p, (pp - p));
+- client_ipv4[pp - p] = '\0';
+- TSDebug(PLUGIN_NAME, "CIP: -%s-", client_ipv4);
+- inet_ntop(AF_INET, &(((struct sockaddr_in *)ip)->sin_addr), ipstr_v4, sizeof ipstr_v4);
+- TSDebug(PLUGIN_NAME, "Peer address: -%s-", ipstr_v4);
+- if (strcmp(ipstr_v4, client_ipv4) != 0) {
+- err_log(url, "Client IP doesn't match signature.");
+- goto deny;
+- }
+- break;
+- case AF_INET6:
+- TSDebug(PLUGIN_NAME, "ip->sa_family: AF_INET6");
+- isClient_ipv6 = true;
+- has_path_params == false ? (pp = strstr(p, "&")) : (pp = strstr(p, ";"));
+- if ((pp - p) > INET6_ADDRSTRLEN - 1 || (pp - p) < 4) {
+- err_log(url, "IP address string too long or short.");
+- goto deny;
+- }
+- strncpy(client_ipv6, p, (pp - p));
+- client_ipv6[pp - p] = '\0';
+- TSDebug(PLUGIN_NAME, "CIP: -%s-", client_ipv6);
+- inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)ip)->sin6_addr), ipstr_v6, sizeof ipstr_v6);
+- TSDebug(PLUGIN_NAME, "Peer address: -%s-", ipstr_v6);
+- if (strcmp(ipstr_v6, client_ipv6) != 0) {
+- err_log(url, "Client IP doesn't match signature.");
+- goto deny;
+- }
+- break;
+- default:
+- TSError("%s: Unknown address family %d", PLUGIN_NAME, ip->sa_family);
++ case AF_INET:
++ TSDebug(PLUGIN_NAME, "ip->sa_family: AF_INET");
++ isClient_ipv6 = false;
++ has_path_params == false ? (pp = strstr(p, "&")) : (pp = strstr(p, ";"));
++ if ((pp - p) > INET_ADDRSTRLEN - 1 || (pp - p) < 4) {
++ err_log(url, "IP address string too long or short.");
++ goto deny;
++ }
++ strncpy(client_ipv4, p, (pp - p));
++ client_ipv4[pp - p] = '\0';
++ TSDebug(PLUGIN_NAME, "CIP: -%s-", client_ipv4);
++ inet_ntop(AF_INET, &(((struct sockaddr_in *)ip)->sin_addr), ipstr_v4, sizeof ipstr_v4);
++ TSDebug(PLUGIN_NAME, "Peer address: -%s-", ipstr_v4);
++ if (strcmp(ipstr_v4, client_ipv4) != 0) {
++ err_log(url, "Client IP doesn't match signature.");
+ goto deny;
+- break;
++ }
++ break;
++ case AF_INET6:
++ TSDebug(PLUGIN_NAME, "ip->sa_family: AF_INET6");
++ isClient_ipv6 = true;
++ has_path_params == false ? (pp = strstr(p, "&")) : (pp = strstr(p, ";"));
++ if ((pp - p) > INET6_ADDRSTRLEN - 1 || (pp - p) < 4) {
++ err_log(url, "IP address string too long or short.");
++ goto deny;
++ }
++ strncpy(client_ipv6, p, (pp - p));
++ client_ipv6[pp - p] = '\0';
++ TSDebug(PLUGIN_NAME, "CIP: -%s-", client_ipv6);
++ inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)ip)->sin6_addr), ipstr_v6, sizeof ipstr_v6);
++ TSDebug(PLUGIN_NAME, "Peer address: -%s-", ipstr_v6);
++ if (strcmp(ipstr_v6, client_ipv6) != 0) {
++ err_log(url, "Client IP doesn't match signature.");
++ goto deny;
++ }
++ break;
++ default:
++ TSError("%s: Unknown address family %d", PLUGIN_NAME, ip->sa_family);
++ goto deny;
++ break;
+ }
+ }
+ }
+@@ -639,7 +639,7 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
+ keyindex, parts, signature);
+ } else {
+ TSDebug(PLUGIN_NAME, "Found all needed parameters: C=%s E=%d A=%d K=%d P=%s S=%s", client_ipv4, (int)expiration, algorithm,
+- keyindex, parts, signature);
++ keyindex, parts, signature);
+ }
+ /* find the string that was signed - cycle through the parts letters, adding the part of the fqdn/path if it is 1 */
+ has_path_params == false ? (p = strstr(url, "?")) : (p = strstr(url, ";"));
+diff --git a/proxy/ParentConsistentHash.cc b/proxy/ParentConsistentHash.cc
+index 1171ab9..5775e52 100644
+--- a/proxy/ParentConsistentHash.cc
++++ b/proxy/ParentConsistentHash.cc
+@@ -153,7 +153,7 @@ ParentConsistentHash::selectParent(const ParentSelectionPolicy *policy, bool fir
+ // check to see if it is retryable.
+ if (pRec && !pRec->available) {
+ Debug("parent_select", "Parent.failedAt = %u, retry = %u, xact_start = %u", (unsigned int)pRec->failedAt,
+- (unsigned int)policy->ParentRetryTime, (unsigned int)request_info->xact_start);
++ (unsigned int)policy->ParentRetryTime, (unsigned int)request_info->xact_start);
+ if ((pRec->failedAt + policy->ParentRetryTime) < request_info->xact_start) {
+ // make sure that the proper state is recorded in the result structure
+ result->last_parent = pRec->idx;
+@@ -164,7 +164,8 @@ ParentConsistentHash::selectParent(const ParentSelectionPolicy *policy, bool fir
+ } else {
+ result->r = PARENT_SPECIFIED;
+ }
+- Debug("parent_select", "Down parent %s is now retryable, pRec: %p, result->retry: %d.", pRec->hostname, pRec, result->retry);
++ Debug("parent_select", "Down parent %s is now retryable, pRec: %p, result->retry: %d.", pRec->hostname, pRec,
++ result->retry);
+ } else { // if not retryable find an available host on the primary ring.
+ last_lookup = PRIMARY;
+ fhash = chash[PRIMARY];
+@@ -206,10 +207,10 @@ ParentConsistentHash::selectParent(const ParentSelectionPolicy *policy, bool fir
+ if (now > last_unavailable) {
+ int len = 0;
+ char *request_str = url->string_get_ref(&len);
+- if(request_str) {
+- Note("No available parents for request: %*s.", len, request_str);
++ if (request_str) {
++ Note("No available parents for request: %*s.", len, request_str);
+ }
+- ink_atomic_swap(&last_unavailable, now);
++ ink_atomic_swap(&last_unavailable, now);
+ }
+ result->r = PARENT_FAIL;
+ }
+diff --git a/proxy/ParentRoundRobin.cc b/proxy/ParentRoundRobin.cc
+index c387e8c..0295324 100644
+--- a/proxy/ParentRoundRobin.cc
++++ b/proxy/ParentRoundRobin.cc
+@@ -25,6 +25,7 @@
+ ParentRoundRobin::ParentRoundRobin(ParentRecord *parent_record, ParentRR_t _round_robin_type)
+ {
+ round_robin_type = _round_robin_type;
++ latched_parent = 0;
+
+ if (is_debug_tag_set("parent_select")) {
+ switch (round_robin_type) {
+@@ -37,6 +38,9 @@ ParentRoundRobin::ParentRoundRobin(ParentRecord *parent_record, ParentRR_t _roun
+ case P_HASH_ROUND_ROBIN:
+ Debug("parent_select", "Using a round robin parent selection strategy of type P_HASH_ROUND_ROBIN.");
+ break;
++ case P_LATCHED_ROUND_ROBIN:
++ Debug("parent_select", "Using a round robin parent selection strategy of type P_LATCHED_ROUND_ROBIN.");
++ break;
+ default:
+ // should never see this, there is a problem if you do.
+ Debug("parent_select", "Using a round robin parent selection strategy of type UNKNOWN TYPE.");
+@@ -100,13 +104,16 @@ ParentRoundRobin::selectParent(const ParentSelectionPolicy *policy, bool first_c
+ case P_NO_ROUND_ROBIN:
+ cur_index = result->start_parent = 0;
+ break;
++ case P_LATCHED_ROUND_ROBIN:
++ cur_index = latched_parent;
++ break;
+ default:
+ ink_release_assert(0);
+ }
+ }
+ } else {
+ // Move to next parent due to failure
+- cur_index = (result->last_parent + 1) % result->rec->num_parents;
++ latched_parent = cur_index = (result->last_parent + 1) % result->rec->num_parents;
+
+ // Check to see if we have wrapped around
+ if ((unsigned int)cur_index == result->start_parent) {
+@@ -169,7 +176,7 @@ ParentRoundRobin::selectParent(const ParentSelectionPolicy *policy, bool first_c
+ Debug("parent_select", "Chosen parent = %s.%d", result->hostname, result->port);
+ return;
+ }
+- cur_index = (cur_index + 1) % result->rec->num_parents;
++ latched_parent = cur_index = (cur_index + 1) % result->rec->num_parents;
+ } while ((unsigned int)cur_index != result->start_parent);
+
+ if (result->rec->go_direct == true && result->rec->parent_is_proxy) {
+diff --git a/proxy/ParentRoundRobin.h b/proxy/ParentRoundRobin.h
+index 57b6832..818e26c 100644
+--- a/proxy/ParentRoundRobin.h
++++ b/proxy/ParentRoundRobin.h
+@@ -35,6 +35,7 @@
+ class ParentRoundRobin : public ParentSelectionStrategy
+ {
+ ParentRR_t round_robin_type;
++ int latched_parent;
+
+ public:
+ ParentRoundRobin(ParentRecord *_parent_record, ParentRR_t _round_robin_type);
+diff --git a/proxy/ParentSelection.cc b/proxy/ParentSelection.cc
+index 81431a8..aa3c4b6 100644
+--- a/proxy/ParentSelection.cc
++++ b/proxy/ParentSelection.cc
+@@ -436,6 +436,7 @@ ParentRecord::ProcessParents(char *val, bool isPrimary)
+ this->parents[i].hostname[tmp - current] = '\0';
+ this->parents[i].port = port;
+ this->parents[i].failedAt = 0;
++ this->parents[i].failCount = 0;
+ this->parents[i].scheme = scheme;
+ this->parents[i].idx = i;
+ this->parents[i].name = this->parents[i].hostname;
+@@ -446,6 +447,7 @@ ParentRecord::ProcessParents(char *val, bool isPrimary)
+ this->secondary_parents[i].hostname[tmp - current] = '\0';
+ this->secondary_parents[i].port = port;
+ this->secondary_parents[i].failedAt = 0;
++ this->parents[i].failCount = 0;
+ this->secondary_parents[i].scheme = scheme;
+ this->secondary_parents[i].idx = i;
+ this->secondary_parents[i].name = this->secondary_parents[i].hostname;
+@@ -543,6 +545,8 @@ ParentRecord::Init(matcher_line *line_info)
+ round_robin = P_NO_ROUND_ROBIN;
+ } else if (strcasecmp(val, "consistent_hash") == 0) {
+ round_robin = P_CONSISTENT_HASH;
++ } else if (strcasecmp(val, "latched") == 0) {
++ round_robin = P_LATCHED_ROUND_ROBIN;
+ } else {
+ round_robin = P_NO_ROUND_ROBIN;
+ errPtr = "invalid argument to round_robin directive";
+@@ -621,6 +625,7 @@ ParentRecord::Init(matcher_line *line_info)
+ case P_NO_ROUND_ROBIN:
+ case P_STRICT_ROUND_ROBIN:
+ case P_HASH_ROUND_ROBIN:
++ case P_LATCHED_ROUND_ROBIN:
+ TSDebug("parent_select", "allocating ParentRoundRobin() lookup strategy.");
+ selection_strategy = new ParentRoundRobin(this, round_robin);
+ break;
+@@ -654,6 +659,7 @@ ParentRecord::UpdateMatch(ParentResult *result, RequestData *rdata)
+ ParentRecord::~ParentRecord()
+ {
+ ats_free(parents);
++ ats_free(secondary_parents);
+ delete selection_strategy;
+ }
+
+diff --git a/proxy/ParentSelection.h b/proxy/ParentSelection.h
+index ab970c0..264dd0c 100644
+--- a/proxy/ParentSelection.h
++++ b/proxy/ParentSelection.h
+@@ -60,6 +60,7 @@ enum ParentRR_t {
+ P_STRICT_ROUND_ROBIN,
+ P_HASH_ROUND_ROBIN,
+ P_CONSISTENT_HASH,
++ P_LATCHED_ROUND_ROBIN
+ };
+
+ // struct pRecord
+diff --git a/tools/rc_admin.pl b/tools/rc_admin.pl
+new file mode 100755
+index 0000000..554e0b6
+--- /dev/null
++++ b/tools/rc_admin.pl
+@@ -0,0 +1,120 @@
++#!/usr/bin/env perl
++#
++#
++use strict;
++use warnings;
++
++use File::Copy;
++
++my %el_versions = ( "6" => 1, "7" => 1);
++my %modes = ("install" => 1, "upgrade" => 1, "uninstall" => 1);
++my %phases = ("pre-uninstall" => 1, "post-install" => 1);
++my $installdir;
++my $mode;
++my $phase;
++
++# returns the enterprise linux version.
++sub el_version {
++ my $el_version = 0;
++
++ if (`uname -r` =~ m/.+el(\d)\.x86_64/) {
++ $el_version = $1;
++ }
++ exists $el_versions{$el_version} ? return $el_version
++ : die("unsupported el_version: $el_version");
++}
++
++sub usage {
++ print STDERR "\nUsage: rc_admin.pl phase mode install_directory\n\n";
++ print "\tvalid phase arguments:\n";
++ print "\t\t'pre-uninstall' - pre uninstall phase\n";
++ print "\t\t'post-install' - post install phase\n";
++
++ print "\tvalid mode arguments:\n";
++ print "\t\t'install' or 'uninstall'\n\n";
++ exit 1;
++}
++
++if ( $#ARGV < 2 || !(exists $phases{$ARGV[0]}) || !(exists $modes{$ARGV[1]})) {
++ &usage();
++} else {
++ $phase = $ARGV[0];
++ $mode = $ARGV[1];
++ $installdir = $ARGV[2];
++}
++
++my $EL_VERSION = el_version();
++
++if (-d "$installdir/rc") {
++ chdir("$installdir/rc");
++} else {
++ die("no such directory $installdir/rc");
++}
++
++if ($phase eq "post-install") {
++ if ($EL_VERSION eq "6" && $mode eq "install") {
++ print "installing /etc/init.d/trafficserver.\n";
++ `/bin/cp trafficserver /etc/init.d/`;
++ if ($? != 0) {
++ print "Failed to copy trafficsever to /etc/init.d/ : $!";
++ } else {
++ chmod(0755, "/etc/init.d/trafficserver");
++ }
++ `/sbin/chkconfig --add trafficserver`;
++ if ($? != 0) {
++ print "Failed running /sbin/chkconfig --add trafficsever";
++ }
++
++ } elsif ("$EL_VERSION" eq "7" && $mode eq "install") {
++ print "installing /usr/lib/systemd/system/trafficserver.service.\n";
++ `/bin/cp trafficserver.service /usr/lib/systemd/system/`;
++ if ($? != 0) {
++ print "Failed to copy trafficsever.service to /usr/lib/systemd/system: $!";
++ } else {
++ chmod(0644, "/usr/lib/systemd/system/trafficserver.service");
++ }
++ `/bin/systemctl daemon-reload`;
++ if ($? != 0) {
++ print "Failed running /bin/systemctl daemon-reload";
++ }
++ `/bin/systemctl enable trafficserver`;
++ if ($? != 0) {
++ print "Failed running /bin/systemctl enable trafficsever";
++ }
++ }
++} elsif ($phase eq "pre-uninstall") {
++ print "Shutting down trafficserver.\n";
++ `/sbin/service trafficserver stop`;
++ if ($? != 0) {
++ print "Failed running /sbin/service trafficsever stop\n";
++ } else {
++ print "trafficserver has stopped.\n";
++ }
++
++ if ($mode eq "uninstall") {
++ print "disabling trafficserver.\n";
++ if ($EL_VERSION eq "6") {
++ `/sbin/chkconfig --del trafficserver`;
++ if ($? != 0) {
++ print "Failed running /sbin/chkconfig --del trafficsever";
++ } else {
++ print "trafficserver has been disabled.\n";
++ }
++ unlink("/etc/init.d/trafficserver");
++ } elsif ($EL_VERSION eq "7") {
++ `/bin/systemctl disable trafficserver`;
++ if ($? != 0) {
++ print "Failed running /sbin/systemctl disable trafficsever";
++ } else {
++ print "trafficserver has been disabled.\n";
++ }
++ unlink ("/usr/lib/systemd/system/trafficserver.service");
++ `/bin/systemctl daemon-reload`;
++ if ($? != 0) {
++ print "Failed running /bin/systemctl daemon-reload";
++ }
++ }
++ }
++}
++
++exit 0;
+diff --git a/trafficserver.spec b/trafficserver.spec
+index 9e74377..3ddb4dd 100644
+--- a/trafficserver.spec
++++ b/trafficserver.spec
+@@ -29,7 +29,6 @@ git clone git@github.comcast.com:cdneng/trafficserver.git %{name}
+ git checkout build-master
+ git checkout %{commit} .
+ autoreconf -vfi
+-#id ats &>/dev/null || /usr/sbin/useradd -u 176 -r ats -s /sbin/nologin -d /
+
+ %build
+ ./configure --prefix=%{install_prefix}/%{name} --with-user=ats --with-group=ats --with-build-number=%{release} --enable-experimental-plugins --with-max-api-stats=%{api_stats}
+@@ -42,8 +41,10 @@ make DESTDIR=$RPM_BUILD_ROOT install
+ # ..so why haven't we fixed them? VSSCDNENG-767
+
+ mkdir -p $RPM_BUILD_ROOT/opt/trafficserver/etc/trafficserver/snapshots
+-mkdir -p $RPM_BUILD_ROOT/etc/init.d
+-cp $RPM_BUILD_DIR/%{name}/rc/trafficserver $RPM_BUILD_ROOT/etc/init.d/
++mkdir -p $RPM_BUILD_ROOT/opt/trafficserver/rc
++cp $RPM_BUILD_DIR/%{name}/rc/trafficserver $RPM_BUILD_ROOT/opt/trafficserver/rc/
++cp $RPM_BUILD_DIR/%{name}/rc/trafficserver.service $RPM_BUILD_ROOT/opt/trafficserver/rc/
++cp $RPM_BUILD_DIR/%{name}/tools/rc_admin.pl $RPM_BUILD_ROOT/opt/trafficserver/rc/
+
+ %clean
+ rm -rf $RPM_BUILD_ROOT
+@@ -52,14 +53,14 @@ rm -rf $RPM_BUILD_ROOT
+ id ats &>/dev/null || /usr/sbin/useradd -u 176 -r ats -s /sbin/nologin -d /
+
+ %post
+-chkconfig --add %{name}
++/opt/trafficserver/rc/rc_admin.pl post-install install /opt/trafficserver
+
+ %preun
+-/etc/init.d/%{name} stop
+-
+ # if 0 uninstall, if 1 upgrade
+ if [ "$1" = "0" ]; then
+- chkconfig --del %{name}
++ /opt/trafficserver/rc/rc_admin.pl pre-uninstall uninstall /opt/trafficserver
++elif [ "$1" = "1" ]; then
++ /opt/trafficserver/rc/rc_admin.pl pre-uninstall upgrade /opt/trafficserver
+ fi
+
+ %postun
+@@ -72,7 +73,6 @@ fi
+
+ %files
+ %defattr(-,root,root)
+-%attr(755,-,-) /etc/init.d/trafficserver
+ %dir /opt/trafficserver
+ /opt/trafficserver/bin
+ /opt/trafficserver/include
+@@ -80,6 +80,7 @@ fi
+ /opt/trafficserver/lib64
+ /opt/trafficserver/libexec
+ /opt/trafficserver/share
++/opt/trafficserver/rc
+ %dir /opt/trafficserver/var
+ %attr(-,ats,ats) /opt/trafficserver/var/trafficserver
+ %dir /opt/trafficserver/var/log
+@@ -112,6 +113,9 @@ fi
+ %config(noreplace) %attr(644,ats,ats) /opt/trafficserver/etc/trafficserver/stats.config.xml
+
+ %changelog
++* Wed Jun 8 2016 John Rushford <john_rushford(at)cable.comcast.com>
++- Added tools/rc_admin.pl to complete rpm tasks under both Enterprise Linux 6 or 7 using either chkconfig or systemd commands.
++- Modified this spec file to use rc_admin.pl
+ * Wed Aug 7 2013 Jeff Elsloo <jeffrey_elsloo(at)cable.comcast.com>
+ - Modified to support building 3.3.x
+ - Modified to support upgrades
[2/2] incubator-trafficcontrol git commit: This closes #64
Posted by fr...@apache.org.
This closes #64
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/e15a0d47
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/e15a0d47
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/e15a0d47
Branch: refs/heads/master
Commit: e15a0d47531d599d07cde269fabd3110514589f8
Parents: 8fb67b4
Author: Eric Friedrich <ef...@cisco.com>
Authored: Tue Nov 8 14:15:01 2016 -0500
Committer: Eric Friedrich <ef...@cisco.com>
Committed: Tue Nov 8 14:15:01 2016 -0500
----------------------------------------------------------------------
----------------------------------------------------------------------