You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by du...@apache.org on 2019/06/24 14:47:41 UTC
[trafficserver] branch master updated: emergency shutdown
This is an automated email from the ASF dual-hosted git repository.
duke8253 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 5a8beee emergency shutdown
5a8beee is described below
commit 5a8beee1b971db12ae9be6d406b0c1dcd4d4981e
Author: Fei Deng <du...@gmail.com>
AuthorDate: Mon Jun 17 15:21:04 2019 -0500
emergency shutdown
---
doc/developer-guide/api/functions/TSDebug.en.rst | 17 +++++-
include/ts/ts.h | 3 ++
src/traffic_server/InkAPI.cc | 20 +++++++
tests/gold_tests/shutdown/emergency.test.py | 51 ++++++++++++++++++
tests/gold_tests/shutdown/fatal.test.py | 51 ++++++++++++++++++
tests/tools/plugins/emergency_shutdown.cc | 66 ++++++++++++++++++++++++
tests/tools/plugins/fatal_shutdown.cc | 66 ++++++++++++++++++++++++
7 files changed, 273 insertions(+), 1 deletion(-)
diff --git a/doc/developer-guide/api/functions/TSDebug.en.rst b/doc/developer-guide/api/functions/TSDebug.en.rst
index 14702c4..110131b 100644
--- a/doc/developer-guide/api/functions/TSDebug.en.rst
+++ b/doc/developer-guide/api/functions/TSDebug.en.rst
@@ -28,8 +28,10 @@ Synopsis
`#include <ts/ts.h>`
+.. function:: void TSError(const char * format, ...)
+.. function:: void TSFatal(const char * format, ...)
+.. function:: void TSEmergency(const char * format, ...)
.. function:: void TSDebug(const char * tag, const char * format, ...)
-.. function:: void TSError(const char * tag, const char * format, ...)
.. function:: int TSIsDebugTagSet(const char * tag)
.. function:: void TSDebugSpecific(int debug_flag, const char * tag, const char * format, ...)
.. function:: void TSHttpTxnDebugSet(TSHttpTxn txnp, int on)
@@ -49,6 +51,19 @@ Description
of writing the output to the C standard output, it writes output
to the Traffic Server error log.
+:func:`TSFatal` is used to shutdown Traffic Server in hopes that a clean
+restart will be able to fix the problem. It will also log a message to the
+Traffic Server error log just like :func:`TSError`.
+
+:func:`TSEmergency` is used to shutdown Traffic Server when restarting
+isn't sufficient to fix the problem, e.g. missing or corrupted files. It will
+also log a message to the Traffic Server error log just like :func:`TSError`.
+
+.. note::
+ Both :func:`TSFatal` and :func:`TSEmergency` can be called within
+ :func:`TSPluginInit`, such that Traffic Server can be shutdown promptly when
+ the plugin fails to initialize properly.
+
:func:`TSDebug` is the same as :func:`TSError` except that it only
logs the debug message if the given debug :arg:`tag` is enabled. It writes
output to the Traffic Server debug log.
diff --git a/include/ts/ts.h b/include/ts/ts.h
index 6673000..fd91b83 100644
--- a/include/ts/ts.h
+++ b/include/ts/ts.h
@@ -261,6 +261,9 @@ tsapi char *TSfgets(TSFile filep, char *buf, size_t length);
*/
tsapi void TSError(const char *fmt, ...) TS_PRINTFLIKE(1, 2);
+tsapi void TSEmergency(const char *fmt, ...) TS_PRINTFLIKE(1, 2);
+tsapi void TSFatal(const char *fmt, ...) TS_PRINTFLIKE(1, 2);
+
/* --------------------------------------------------------------------------
Assertions */
tsapi void _TSReleaseAssert(const char *txt, const char *f, int l) TS_NORETURN;
diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc
index 0480489..316282b 100644
--- a/src/traffic_server/InkAPI.cc
+++ b/src/traffic_server/InkAPI.cc
@@ -415,6 +415,26 @@ TSError(const char *fmt, ...)
va_end(args);
}
+tsapi void
+TSEmergency(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ EmergencyV(fmt, args);
+ va_end(args);
+}
+
+tsapi void
+TSFatal(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ FatalV(fmt, args);
+ va_end(args);
+}
+
// Assert in debug AND optim
void
_TSReleaseAssert(const char *text, const char *file, int line)
diff --git a/tests/gold_tests/shutdown/emergency.test.py b/tests/gold_tests/shutdown/emergency.test.py
new file mode 100644
index 0000000..ab8a6b0
--- /dev/null
+++ b/tests/gold_tests/shutdown/emergency.test.py
@@ -0,0 +1,51 @@
+'''
+'''
+# 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.
+
+
+import os
+
+Test.Summary = 'Test TSEmergency API'
+Test.ContinueOnFail = True
+
+# Define default ATS
+ts = Test.MakeATSProcess('ts')
+
+Test.testName = 'Emergency Shutdown Test'
+
+ts.Disk.records_config.update({
+ 'proxy.config.exec_thread.autoconfig': 0,
+ 'proxy.config.exec_thread.autoconfig.scale': 1.5,
+ 'proxy.config.exec_thread.limit': 16,
+ 'proxy.config.accept_threads': 1,
+ 'proxy.config.task_threads': 2,
+ 'proxy.config.diags.debug.enabled': 1,
+ 'proxy.config.diags.debug.tags': 'TSEmergency_test'
+})
+
+# Load plugin
+Test.PreparePlugin(os.path.join(Test.Variables.AtsTestToolsDir, 'plugins', 'emergency_shutdown.cc'), ts)
+
+# www.example.com Host
+tr = Test.AddTestRun()
+tr.Processes.Default.Command = 'printf "Emergency Shutdown Test"'
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.StartBefore(ts)
+ts.ReturnCode = 33
+ts.Ready = 0 # Need this to be 0 because we are testing shutdown, this is to make autest not think ats went away for a bad reason.
+ts.Streams.All = Testers.ExcludesExpression('failed to shutdown', 'should NOT contain "failed to shutdown"')
+ts.Disk.diags_log.Content = Testers.IncludesExpression('testing emergency shutdown', 'should contain "testing emergency shutdown"')
diff --git a/tests/gold_tests/shutdown/fatal.test.py b/tests/gold_tests/shutdown/fatal.test.py
new file mode 100644
index 0000000..6ba763d
--- /dev/null
+++ b/tests/gold_tests/shutdown/fatal.test.py
@@ -0,0 +1,51 @@
+'''
+'''
+# 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.
+
+
+import os
+
+Test.Summary = 'Test TSFatal API'
+Test.ContinueOnFail = True
+
+# Define default ATS
+ts = Test.MakeATSProcess('ts')
+
+Test.testName = 'Fatal Shutdown Test'
+
+ts.Disk.records_config.update({
+ 'proxy.config.exec_thread.autoconfig': 0,
+ 'proxy.config.exec_thread.autoconfig.scale': 1.5,
+ 'proxy.config.exec_thread.limit': 16,
+ 'proxy.config.accept_threads': 1,
+ 'proxy.config.task_threads': 2,
+ 'proxy.config.diags.debug.enabled': 1,
+ 'proxy.config.diags.debug.tags': 'TSFatal_test'
+})
+
+# Load plugin
+Test.PreparePlugin(os.path.join(Test.Variables.AtsTestToolsDir, 'plugins', 'fatal_shutdown.cc'), ts)
+
+# www.example.com Host
+tr = Test.AddTestRun()
+tr.Processes.Default.Command = 'printf "Fatal Shutdown Test"'
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.StartBefore(ts)
+ts.ReturnCode = 70
+ts.Ready = 0 # Need this to be 0 because we are testing shutdown, this is to make autest not think ats went away for a bad reason.
+ts.Streams.All = Testers.ExcludesExpression('failed to shutdown', 'should NOT contain "failed to shutdown"')
+ts.Disk.diags_log.Content = Testers.IncludesExpression('testing fatal shutdown', 'should contain "testing fatal shutdown"')
diff --git a/tests/tools/plugins/emergency_shutdown.cc b/tests/tools/plugins/emergency_shutdown.cc
new file mode 100644
index 0000000..9957e40
--- /dev/null
+++ b/tests/tools/plugins/emergency_shutdown.cc
@@ -0,0 +1,66 @@
+/*
+ * 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 <cstring>
+#include <stdlib.h> // for abort
+#include <ts/ts.h> // for debug
+
+// debug messages viewable by setting 'proxy.config.diags.debug.tags'
+// in 'records.config'
+
+// debug messages during one-time initialization
+static const char DEBUG_TAG[] = "TSEmergency_test";
+
+// plugin registration info
+static char plugin_name[] = "TSEmergency_test";
+static char vendor_name[] = "apache";
+static char support_email[] = "duke8253@apache.org";
+
+static int
+test_handler(TSCont contp, TSEvent event, void *edata)
+{
+ TSDebug(DEBUG_TAG, "failed to shutdown");
+ return 0;
+}
+
+static int
+LifecycleHookTracer(TSCont contp, TSEvent event, void *edata)
+{
+ if (event == TS_EVENT_LIFECYCLE_TASK_THREADS_READY) {
+ TSCont contp = TSContCreate(test_handler, TSMutexCreate());
+ TSContScheduleOnPool(contp, 500, TS_THREAD_POOL_NET);
+ TSEmergency("testing emergency shutdown");
+ }
+ return 0;
+}
+
+void
+TSPluginInit(int argc, const char *argv[])
+{
+ TSPluginRegistrationInfo info;
+
+ info.plugin_name = plugin_name;
+ info.vendor_name = vendor_name;
+ info.support_email = support_email;
+
+ if (TSPluginRegister(&info) != TS_SUCCESS) {
+ TSEmergency("[%s] plugin registration failed", plugin_name);
+ }
+
+ TSLifecycleHookAdd(TS_LIFECYCLE_TASK_THREADS_READY_HOOK, TSContCreate(LifecycleHookTracer, TSMutexCreate()));
+}
diff --git a/tests/tools/plugins/fatal_shutdown.cc b/tests/tools/plugins/fatal_shutdown.cc
new file mode 100644
index 0000000..d749008
--- /dev/null
+++ b/tests/tools/plugins/fatal_shutdown.cc
@@ -0,0 +1,66 @@
+/*
+ * 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 <cstring>
+#include <stdlib.h> // for abort
+#include <ts/ts.h> // for debug
+
+// debug messages viewable by setting 'proxy.config.diags.debug.tags'
+// in 'records.config'
+
+// debug messages during one-time initialization
+static const char DEBUG_TAG[] = "TSFatal_test";
+
+// plugin registration info
+static char plugin_name[] = "TSFatal_test";
+static char vendor_name[] = "apache";
+static char support_email[] = "duke8253@apache.org";
+
+static int
+test_handler(TSCont contp, TSEvent event, void *edata)
+{
+ TSDebug(DEBUG_TAG, "failed to shutdown");
+ return 0;
+}
+
+static int
+LifecycleHookTracer(TSCont contp, TSEvent event, void *edata)
+{
+ if (event == TS_EVENT_LIFECYCLE_TASK_THREADS_READY) {
+ TSCont contp = TSContCreate(test_handler, TSMutexCreate());
+ TSContScheduleOnPool(contp, 500, TS_THREAD_POOL_NET);
+ TSFatal("testing fatal shutdown");
+ }
+ return 0;
+}
+
+void
+TSPluginInit(int argc, const char *argv[])
+{
+ TSPluginRegistrationInfo info;
+
+ info.plugin_name = plugin_name;
+ info.vendor_name = vendor_name;
+ info.support_email = support_email;
+
+ if (TSPluginRegister(&info) != TS_SUCCESS) {
+ TSEmergency("[%s] plugin registration failed", plugin_name);
+ }
+
+ TSLifecycleHookAdd(TS_LIFECYCLE_TASK_THREADS_READY_HOOK, TSContCreate(LifecycleHookTracer, TSMutexCreate()));
+}