passenger 5.1.10 → 5.1.11
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG +18 -0
- data/Rakefile +20 -17
- data/bin/passenger-install-apache2-module +14 -11
- data/build/agent.rb +45 -18
- data/build/apache2.rb +32 -16
- data/build/basics.rb +29 -40
- data/build/common_library.rb +70 -54
- data/build/cxx_tests.rb +34 -43
- data/build/integration_tests.rb +10 -10
- data/build/misc.rb +6 -6
- data/build/node_tests.rb +1 -2
- data/build/oxt_tests.rb +7 -5
- data/build/packaging.rb +11 -441
- data/build/ruby_extension.rb +1 -1
- data/build/ruby_tests.rb +1 -2
- data/build/support/cplusplus.rb +6 -5
- data/build/support/cxx_dependency_map.rb +357 -833
- data/build/support/general.rb +23 -1
- data/build/test_basics.rb +3 -28
- data/dev/ci/tests/rpm/Jenkinsfile +68 -0
- data/dev/ci/tests/rpm/run +63 -0
- data/dev/ci/tests/source-packaging/run +1 -1
- data/dev/ci/tests/source-packaging/setup +1 -1
- data/doc/{Packaging.txt.md → Packaging.md} +0 -0
- data/resources/templates/apache2/deployment_example.txt.erb +2 -2
- data/resources/templates/apache2/multiple_apache_installations_detected.txt.erb +2 -2
- data/resources/templates/nginx/deployment_example.txt.erb +1 -1
- data/resources/templates/standalone/mass_deployment_default_server.erb +2 -2
- data/resources/templates/standalone/server.erb +2 -2
- data/src/agent/AgentMain.cpp +0 -4
- data/src/agent/Core/CoreMain.cpp +88 -5
- data/src/agent/Core/SpawningKit/Spawner.h +2 -1
- data/src/agent/Shared/Fundamentals/AbortHandler.cpp +1109 -0
- data/src/agent/Shared/Fundamentals/AbortHandler.h +63 -0
- data/src/agent/Shared/Fundamentals/Implementation.cpp +7 -0
- data/src/agent/Shared/Fundamentals/Initialization.cpp +614 -0
- data/src/agent/Shared/{Base.h → Fundamentals/Initialization.h} +23 -14
- data/src/agent/Shared/Fundamentals/Utils.cpp +127 -0
- data/src/agent/Shared/Fundamentals/Utils.h +46 -0
- data/src/agent/TempDirToucher/TempDirToucherMain.cpp +1 -1
- data/src/agent/Watchdog/CoreWatcher.cpp +3 -1
- data/src/agent/Watchdog/InstanceDirToucher.cpp +90 -53
- data/src/agent/Watchdog/WatchdogMain.cpp +13 -29
- data/src/apache2_module/Hooks.cpp +4 -1
- data/src/cxx_supportlib/ConfigKit/Store.h +32 -5
- data/src/cxx_supportlib/Constants.h +1 -2
- data/src/cxx_supportlib/Crypto.cpp +2 -1
- data/src/cxx_supportlib/Hooks.h +16 -37
- data/src/cxx_supportlib/LoggingKit/Context.h +22 -0
- data/src/cxx_supportlib/LoggingKit/Forward.h +1 -0
- data/src/cxx_supportlib/LoggingKit/Implementation.cpp +106 -22
- data/src/cxx_supportlib/ProcessManagement/Ruby.cpp +106 -0
- data/src/{agent/UstRouter/FileSink.h → cxx_supportlib/ProcessManagement/Ruby.h} +23 -47
- data/src/cxx_supportlib/ProcessManagement/Spawn.cpp +199 -0
- data/src/cxx_supportlib/ProcessManagement/Spawn.h +150 -0
- data/src/cxx_supportlib/ProcessManagement/Utils.cpp +459 -0
- data/src/cxx_supportlib/ProcessManagement/Utils.h +107 -0
- data/src/cxx_supportlib/Utils.cpp +41 -561
- data/src/cxx_supportlib/Utils.h +0 -68
- data/src/cxx_supportlib/Utils/AsyncSignalSafeUtils.h +187 -0
- data/src/cxx_supportlib/Utils/ProcessMetricsCollector.h +14 -2
- data/src/cxx_supportlib/WatchdogLauncher.h +2 -12
- data/src/cxx_supportlib/oxt/dynamic_thread_group.hpp +2 -2
- data/src/cxx_supportlib/vendor-modified/jsoncpp/json-forwards.h +4 -0
- data/src/cxx_supportlib/vendor-modified/jsoncpp/json.h +16 -1
- data/src/cxx_supportlib/vendor-modified/jsoncpp/jsoncpp.cpp +12 -9
- data/src/cxx_supportlib/vendor-modified/libev/ev++.h +4 -4
- data/src/cxx_supportlib/vendor-modified/libev/ev.h +3 -3
- data/src/nginx_module/CacheLocationConfig.c +0 -75
- data/src/nginx_module/CacheLocationConfig.c.cxxcodebuilder +1 -0
- data/src/nginx_module/Configuration.c +0 -1
- data/src/nginx_module/Configuration.h +0 -1
- data/src/nginx_module/ConfigurationCommands.c +1 -1
- data/src/nginx_module/ContentHandler.c +0 -1
- data/src/nginx_module/ContentHandler.h +0 -1
- data/src/nginx_module/CreateLocationConfig.c +0 -5
- data/src/nginx_module/CreateLocationConfig.c.cxxcodebuilder +1 -0
- data/src/nginx_module/LocationConfig.h +0 -4
- data/src/nginx_module/LocationConfig.h.cxxcodebuilder +2 -1
- data/src/nginx_module/MergeLocationConfig.c +0 -12
- data/src/nginx_module/MergeLocationConfig.c.cxxcodebuilder +1 -0
- data/src/nginx_module/ngx_http_passenger_module.h +0 -1
- data/src/ruby_supportlib/phusion_passenger.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/common_library.rb +20 -11
- data/src/ruby_supportlib/phusion_passenger/config/api_call_command.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/config/reopen_logs_command.rb +0 -1
- data/src/ruby_supportlib/phusion_passenger/config/validate_install_command.rb +10 -3
- data/src/ruby_supportlib/phusion_passenger/console_text_template.rb +3 -1
- data/src/ruby_supportlib/phusion_passenger/constants.rb +0 -1
- data/src/ruby_supportlib/phusion_passenger/debug_logging.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/loader_shared_helpers.rb +32 -6
- data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +0 -1
- data/src/ruby_supportlib/phusion_passenger/packaging.rb +2 -4
- data/src/ruby_supportlib/phusion_passenger/platform_info/apache.rb +101 -20
- data/src/ruby_supportlib/phusion_passenger/platform_info/apache_detector.rb +21 -9
- data/src/ruby_supportlib/phusion_passenger/platform_info/compiler.rb +34 -31
- data/src/ruby_supportlib/phusion_passenger/platform_info/cxx_portability.rb +3 -1
- data/src/ruby_supportlib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +2 -14
- data/src/ruby_supportlib/phusion_passenger/platform_info/operating_system.rb +40 -3
- data/src/ruby_supportlib/phusion_passenger/standalone/app_finder.rb +15 -14
- data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/standalone/config_utils.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command.rb +8 -3
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command/nginx_engine.rb +19 -18
- data/src/ruby_supportlib/phusion_passenger/standalone/stop_command.rb +6 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/daemon_controller.rb +17 -1
- metadata +19 -97
- data/build/documentation.rb +0 -70
- data/doc/CloudLicensingConfiguration.html +0 -172
- data/doc/CloudLicensingConfiguration.txt.md +0 -3
- data/doc/Packaging.html +0 -488
- data/doc/Security of user switching support.idmap.txt +0 -34
- data/doc/Security of user switching support.txt +0 -197
- data/doc/ServerOptimizationGuide.html +0 -172
- data/doc/ServerOptimizationGuide.txt.md +0 -3
- data/doc/images/by_sa.png +0 -0
- data/doc/images/cloud_licensing_batch_job.png +0 -0
- data/doc/images/code_walkthrough.jpg +0 -0
- data/doc/images/direct_spawning.png +0 -0
- data/doc/images/direct_spawning.svg +0 -251
- data/doc/images/glyphicons-halflings-white.png +0 -0
- data/doc/images/glyphicons-halflings.png +0 -0
- data/doc/images/icons/README +0 -5
- data/doc/images/icons/callouts/1.png +0 -0
- data/doc/images/icons/callouts/10.png +0 -0
- data/doc/images/icons/callouts/11.png +0 -0
- data/doc/images/icons/callouts/12.png +0 -0
- data/doc/images/icons/callouts/13.png +0 -0
- data/doc/images/icons/callouts/14.png +0 -0
- data/doc/images/icons/callouts/15.png +0 -0
- data/doc/images/icons/callouts/2.png +0 -0
- data/doc/images/icons/callouts/3.png +0 -0
- data/doc/images/icons/callouts/4.png +0 -0
- data/doc/images/icons/callouts/5.png +0 -0
- data/doc/images/icons/callouts/6.png +0 -0
- data/doc/images/icons/callouts/7.png +0 -0
- data/doc/images/icons/callouts/8.png +0 -0
- data/doc/images/icons/callouts/9.png +0 -0
- data/doc/images/icons/caution.png +0 -0
- data/doc/images/icons/example.png +0 -0
- data/doc/images/icons/home.png +0 -0
- data/doc/images/icons/important.png +0 -0
- data/doc/images/icons/next.png +0 -0
- data/doc/images/icons/note.png +0 -0
- data/doc/images/icons/prev.png +0 -0
- data/doc/images/icons/tip.png +0 -0
- data/doc/images/icons/up.png +0 -0
- data/doc/images/icons/warning.png +0 -0
- data/doc/images/many_web_framework_protocols.png +0 -0
- data/doc/images/passenger_architecture.png +0 -0
- data/doc/images/passenger_architecture.svg +0 -385
- data/doc/images/passenger_architecture_overview.png +0 -0
- data/doc/images/passenger_core_architecture.png +0 -0
- data/doc/images/passenger_nodejs_architecture.svg +0 -558
- data/doc/images/phusion_banner.png +0 -0
- data/doc/images/rack.png +0 -0
- data/doc/images/smart_spawning.png +0 -0
- data/doc/images/smart_spawning.svg +0 -323
- data/doc/images/spawn_server_architecture.png +0 -0
- data/doc/images/spawn_server_architecture.svg +0 -655
- data/doc/images/spawning_preparation_work.png +0 -0
- data/doc/images/startup_sequence.png +0 -0
- data/doc/images/typical_isolated_web_application.png +0 -0
- data/doc/images/typical_isolated_web_application.svg +0 -213
- data/doc/users_guide_snippets/alternative_for_flying_passenger.txt +0 -1
- data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +0 -61
- data/doc/users_guide_snippets/appendix_a_about.txt +0 -13
- data/doc/users_guide_snippets/appendix_b_terminology.txt +0 -71
- data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +0 -36
- data/doc/users_guide_snippets/deployment_basics.txt +0 -37
- data/doc/users_guide_snippets/enterprise_only.txt +0 -1
- data/doc/users_guide_snippets/environment_variables.txt +0 -44
- data/doc/users_guide_snippets/global_queueing_explained.txt +0 -74
- data/doc/users_guide_snippets/installation.txt +0 -228
- data/doc/users_guide_snippets/installation/run_installer.txt +0 -58
- data/doc/users_guide_snippets/installation/verify_running_epilogue.txt +0 -6
- data/doc/users_guide_snippets/passenger_spawn_method.txt +0 -37
- data/doc/users_guide_snippets/rackup_specifications.txt +0 -1
- data/doc/users_guide_snippets/rvm_helper_tool.txt +0 -44
- data/doc/users_guide_snippets/since_version.txt +0 -1
- data/doc/users_guide_snippets/support_information.txt +0 -8
- data/doc/users_guide_snippets/tips.txt +0 -302
- data/doc/users_guide_snippets/troubleshooting/default.txt +0 -48
- data/doc/users_guide_snippets/troubleshooting/rails.txt +0 -59
- data/doc/users_guide_snippets/under_the_hood/page_caching_support.txt +0 -24
- data/doc/users_guide_snippets/under_the_hood/relationship_with_ruby.txt +0 -10
- data/doc/users_guide_snippets/where_to_get_support.txt +0 -9
- data/src/agent/Shared/Base.cpp +0 -1678
- data/src/agent/UstRouter/ApiServer.h +0 -292
- data/src/agent/UstRouter/Client.h +0 -112
- data/src/agent/UstRouter/Controller.h +0 -1309
- data/src/agent/UstRouter/LogSink.h +0 -145
- data/src/agent/UstRouter/OptionParser.h +0 -180
- data/src/agent/UstRouter/RemoteSender.h +0 -853
- data/src/agent/UstRouter/RemoteSink.h +0 -145
- data/src/agent/UstRouter/Transaction.h +0 -278
- data/src/agent/UstRouter/UstRouterMain.cpp +0 -681
- data/src/agent/Watchdog/UstRouterWatcher.cpp +0 -80
- data/src/ruby_supportlib/phusion_passenger/platform_info/macos.rb +0 -45
@@ -1257,6 +1257,7 @@ public:
|
|
1257
1257
|
ok = LoggingKit::context->prepareConfigChange(loggingConfig,
|
1258
1258
|
errors, req);
|
1259
1259
|
} catch (const std::exception &e) {
|
1260
|
+
ok = false;
|
1260
1261
|
fprintf(stderr, "ERROR: unable to configure logging system: %s\n", e.what());
|
1261
1262
|
}
|
1262
1263
|
if (ok) {
|
@@ -1576,6 +1577,8 @@ destroy_hooks(void *arg) {
|
|
1576
1577
|
boost::this_thread::disable_interruption di;
|
1577
1578
|
boost::this_thread::disable_syscall_interruption dsi;
|
1578
1579
|
P_DEBUG("Shutting down Phusion Passenger...");
|
1580
|
+
LoggingKit::shutdown();
|
1581
|
+
oxt::shutdown();
|
1579
1582
|
delete hooks;
|
1580
1583
|
hooks = NULL;
|
1581
1584
|
} catch (const thread_interrupted &) {
|
@@ -1609,8 +1612,8 @@ init_module(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *
|
|
1609
1612
|
*/
|
1610
1613
|
if (hooks == NULL) {
|
1611
1614
|
oxt::initialize();
|
1612
|
-
LoggingKit::initialize();
|
1613
1615
|
SystemTime::initialize();
|
1616
|
+
LoggingKit::initialize();
|
1614
1617
|
} else {
|
1615
1618
|
P_DEBUG("Restarting Phusion Passenger....");
|
1616
1619
|
delete hooks;
|
@@ -252,6 +252,16 @@ private:
|
|
252
252
|
}
|
253
253
|
|
254
254
|
public:
|
255
|
+
struct PreviewOptions {
|
256
|
+
bool filterSecrets;
|
257
|
+
bool shouldApplyInspectFilters;
|
258
|
+
|
259
|
+
PreviewOptions()
|
260
|
+
: filterSecrets(true),
|
261
|
+
shouldApplyInspectFilters()
|
262
|
+
{ }
|
263
|
+
};
|
264
|
+
|
255
265
|
Store()
|
256
266
|
: schema(NULL),
|
257
267
|
entries(0, 0),
|
@@ -352,7 +362,7 @@ public:
|
|
352
362
|
* are not passed through inspect filters.
|
353
363
|
*/
|
354
364
|
Json::Value previewUpdate(const Json::Value &updates, vector<Error> &errors,
|
355
|
-
|
365
|
+
const PreviewOptions &options = PreviewOptions()) const
|
356
366
|
{
|
357
367
|
if (!updates.isNull() && !updates.isObject()) {
|
358
368
|
errors.push_back(Error("The JSON document must be an object"));
|
@@ -360,10 +370,23 @@ public:
|
|
360
370
|
}
|
361
371
|
|
362
372
|
Json::Value result(Json::objectValue);
|
373
|
+
Store storeWithPreviewData(*this);
|
374
|
+
StringKeyTable<Entry>::Iterator p_it(storeWithPreviewData.entries);
|
363
375
|
StringKeyTable<Entry>::ConstIterator it(entries);
|
364
376
|
vector<Error> tmpErrors;
|
365
377
|
Error error;
|
366
378
|
|
379
|
+
while (*p_it != NULL) {
|
380
|
+
const HashedStaticString &key = p_it.getKey();
|
381
|
+
Entry &entry = p_it.getValue();
|
382
|
+
|
383
|
+
if (isWritable(entry) && updates.isMember(key)) {
|
384
|
+
entry.userValue = updates[key];
|
385
|
+
}
|
386
|
+
|
387
|
+
p_it.next();
|
388
|
+
}
|
389
|
+
|
367
390
|
while (*it != NULL) {
|
368
391
|
const HashedStaticString &key = it.getKey();
|
369
392
|
const Entry &entry = it.getValue();
|
@@ -376,8 +399,9 @@ public:
|
|
376
399
|
} else {
|
377
400
|
subdoc["user_value"] = entry.userValue;
|
378
401
|
}
|
402
|
+
|
379
403
|
if (entry.schemaEntry->defaultValueGetter) {
|
380
|
-
subdoc["default_value"] = entry.getDefaultValue(
|
404
|
+
subdoc["default_value"] = entry.getDefaultValue(storeWithPreviewData);
|
381
405
|
}
|
382
406
|
|
383
407
|
const Json::Value &effectiveValue =
|
@@ -400,11 +424,11 @@ public:
|
|
400
424
|
applyNormalizers(result);
|
401
425
|
}
|
402
426
|
|
403
|
-
if (shouldApplyInspectFilters) {
|
427
|
+
if (options.shouldApplyInspectFilters) {
|
404
428
|
applyInspectFilters(result);
|
405
429
|
}
|
406
430
|
|
407
|
-
if (filterSecrets) {
|
431
|
+
if (options.filterSecrets) {
|
408
432
|
doFilterSecrets(result);
|
409
433
|
}
|
410
434
|
|
@@ -423,7 +447,10 @@ public:
|
|
423
447
|
* Any keys not in `updates` do not affect existing values stored in the store.
|
424
448
|
*/
|
425
449
|
bool update(const Json::Value &updates, vector<Error> &errors) {
|
426
|
-
|
450
|
+
PreviewOptions options;
|
451
|
+
options.filterSecrets = false;
|
452
|
+
options.shouldApplyInspectFilters = false;
|
453
|
+
Json::Value preview = previewUpdate(updates, errors, options);
|
427
454
|
if (errors.empty()) {
|
428
455
|
StringKeyTable<Entry>::Iterator it(entries);
|
429
456
|
while (*it != NULL) {
|
@@ -71,7 +71,6 @@
|
|
71
71
|
#define DEFAULT_STICKY_SESSIONS_COOKIE_NAME "_passenger_route"
|
72
72
|
#define DEFAULT_UNION_STATION_GATEWAY_ADDRESS "gateway.unionstationapp.com"
|
73
73
|
#define DEFAULT_UNION_STATION_GATEWAY_PORT 443
|
74
|
-
#define DEFAULT_UST_ROUTER_LISTEN_ADDRESS "tcp://127.0.0.1:9344"
|
75
74
|
#define DEFAULT_WEB_APP_USER "nobody"
|
76
75
|
#define ENTERPRISE_URL "https://www.phusionpassenger.com/enterprise"
|
77
76
|
#define FEEDBACK_FD 3
|
@@ -83,7 +82,7 @@
|
|
83
82
|
#define PASSENGER_API_VERSION_MAJOR 0
|
84
83
|
#define PASSENGER_API_VERSION_MINOR 3
|
85
84
|
#define PASSENGER_DEFAULT_USER "nobody"
|
86
|
-
#define PASSENGER_VERSION "5.1.
|
85
|
+
#define PASSENGER_VERSION "5.1.11"
|
87
86
|
#define POOL_HELPER_THREAD_STACK_SIZE 262144
|
88
87
|
#define PROCESS_SHUTDOWN_TIMEOUT 60
|
89
88
|
#define PROCESS_SHUTDOWN_TIMEOUT_DISPLAY "1 minute"
|
@@ -294,7 +294,7 @@ CFDataRef Crypto::genIV(size_t ivSize) {
|
|
294
294
|
|
295
295
|
bool Crypto::getKeyBytes(SecKeyRef cryptokey, void **target, size_t &len) {
|
296
296
|
const CSSM_KEY *cssmKey;
|
297
|
-
CSSM_WRAP_KEY wrappedKey
|
297
|
+
CSSM_WRAP_KEY wrappedKey;
|
298
298
|
|
299
299
|
CSSM_CSP_HANDLE cspHandle = 0;
|
300
300
|
CSSM_CC_HANDLE ccHandle = 0;
|
@@ -322,6 +322,7 @@ bool Crypto::getKeyBytes(SecKeyRef cryptokey, void **target, size_t &len) {
|
|
322
322
|
&ccHandle);
|
323
323
|
if (error != CSSM_OK) { cssmPerror("CSSM_CSP_CreateSymmetricContext",error); }
|
324
324
|
|
325
|
+
memset(&wrappedKey, 0, sizeof(wrappedKey));
|
325
326
|
error = CSSM_WrapKey(ccHandle,
|
326
327
|
creds,
|
327
328
|
cssmKey,
|
data/src/cxx_supportlib/Hooks.h
CHANGED
@@ -33,16 +33,15 @@
|
|
33
33
|
#include <boost/foreach.hpp>
|
34
34
|
#include <oxt/backtrace.hpp>
|
35
35
|
|
36
|
-
#include <sys/types.h>
|
37
|
-
#include <sys/wait.h>
|
38
36
|
#include <cstdio>
|
39
37
|
#include <cerrno>
|
40
38
|
#include <cstring>
|
41
39
|
#include <cctype>
|
42
40
|
#include <stdlib.h>
|
43
|
-
#include <unistd.h>
|
44
41
|
|
45
42
|
#include <LoggingKit/LoggingKit.h>
|
43
|
+
#include <ProcessManagement/Spawn.h>
|
44
|
+
#include <ProcessManagement/Utils.h>
|
46
45
|
#include <Utils.h>
|
47
46
|
#include <Utils/StrIntUtils.h>
|
48
47
|
#include <Utils/VariantMap.h>
|
@@ -126,44 +125,24 @@ runSingleHookScript(HookScriptOptions &options, const string &command,
|
|
126
125
|
const vector< pair<string, string> > &envvars)
|
127
126
|
{
|
128
127
|
TRACE_POINT_WITH_DATA(command.c_str());
|
129
|
-
|
130
|
-
|
128
|
+
const char *commandArray[] = {
|
129
|
+
command.c_str(),
|
130
|
+
NULL
|
131
|
+
};
|
132
|
+
SubprocessInfo info;
|
131
133
|
|
132
134
|
P_INFO("Running " << options.name << " hook script: " << command);
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
disableMallocDebugging();
|
138
|
-
closeAllFileDescriptors(2);
|
139
|
-
setEnvVarsFromVector(envvars);
|
140
|
-
|
141
|
-
execlp(command.c_str(), command.c_str(), (const char * const) 0);
|
142
|
-
e = errno;
|
143
|
-
fprintf(stderr, "*** ERROR: Cannot execute %s hook script %s: %s (errno=%d)\n",
|
144
|
-
options.name.c_str(), command.c_str(), strerror(e), e);
|
145
|
-
fflush(stderr);
|
146
|
-
_exit(1);
|
147
|
-
return true; // Never reached.
|
148
|
-
|
149
|
-
} else if (pid == -1) {
|
150
|
-
e = errno;
|
151
|
-
P_ERROR("Cannot fork a process for hook script " << command <<
|
152
|
-
": " << strerror(e) << " (errno=" << e << ")");
|
153
|
-
return false;
|
154
|
-
|
155
|
-
} else if (waitpid(pid, &status, 0) == -1) {
|
156
|
-
e = errno;
|
157
|
-
P_ERROR("Unable to wait for hook script " << command <<
|
158
|
-
" (PID " << pid << "): " << strerror(e) << " (errno=" <<
|
159
|
-
e << ")");
|
135
|
+
try {
|
136
|
+
runCommand(commandArray, info, true, true, boost::bind(setEnvVarsFromVector, envvars));
|
137
|
+
} catch (const SystemException &e) {
|
138
|
+
P_ERROR("Error running hook script " << command << ": " << e.what());
|
160
139
|
return false;
|
161
|
-
|
162
|
-
} else {
|
163
|
-
P_INFO("Hook script " << command << " (PID " << pid <<
|
164
|
-
") exited with status " << WEXITSTATUS(status));
|
165
|
-
return WEXITSTATUS(status) == 0;
|
166
140
|
}
|
141
|
+
if (info.status != 0 && info.status != -2) {
|
142
|
+
P_INFO("Hook script " << command << " (PID " << info.pid <<
|
143
|
+
") exited with status " << WEXITSTATUS(info.status));
|
144
|
+
}
|
145
|
+
return info.status == 0 || info.status == -2;
|
167
146
|
}
|
168
147
|
|
169
148
|
inline bool
|
@@ -26,12 +26,16 @@
|
|
26
26
|
#ifndef _PASSENGER_LOGGING_KIT_CONTEXT_H_
|
27
27
|
#define _PASSENGER_LOGGING_KIT_CONTEXT_H_
|
28
28
|
|
29
|
+
#include <queue>
|
30
|
+
|
29
31
|
#include <oxt/macros.hpp>
|
32
|
+
#include <oxt/thread.hpp>
|
30
33
|
#include <boost/thread.hpp>
|
31
34
|
#include <boost/atomic.hpp>
|
32
35
|
#include <ConfigKit/ConfigKit.h>
|
33
36
|
#include <LoggingKit/Forward.h>
|
34
37
|
#include <LoggingKit/Config.h>
|
38
|
+
#include <Utils/SystemTime.h>
|
35
39
|
|
36
40
|
namespace Passenger {
|
37
41
|
namespace LoggingKit {
|
@@ -68,8 +72,15 @@ private:
|
|
68
72
|
ConfigKit::Store config;
|
69
73
|
boost::atomic<ConfigRealization *> configRlz;
|
70
74
|
|
75
|
+
mutable boost::mutex gcSyncher;
|
76
|
+
oxt::thread *gcThread;
|
77
|
+
boost::condition_variable gcShuttingDownCond, gcHasShutDownCond;
|
78
|
+
queue< pair<ConfigRealization *, MonotonicTimeUsec> > oldConfigs;
|
79
|
+
bool shuttingDown;
|
80
|
+
|
71
81
|
public:
|
72
82
|
Context(const Json::Value &initialConfig = Json::Value());
|
83
|
+
~Context();
|
73
84
|
ConfigKit::Store getConfig() const;
|
74
85
|
|
75
86
|
bool prepareConfigChange(const Json::Value &updates,
|
@@ -82,6 +93,17 @@ public:
|
|
82
93
|
const ConfigRealization *getConfigRealization() const {
|
83
94
|
return configRlz.load(boost::memory_order_acquire);
|
84
95
|
}
|
96
|
+
|
97
|
+
void pushOldConfigAndCreateGcThread(ConfigRealization *oldConfigRlz, MonotonicTimeUsec monotonicNow);
|
98
|
+
void gcThreadMain();
|
99
|
+
|
100
|
+
private:
|
101
|
+
pair<ConfigRealization*,MonotonicTimeUsec> peekOldConfig();
|
102
|
+
void popOldConfig(ConfigRealization *oldConfig);
|
103
|
+
bool oldConfigsExist();
|
104
|
+
void createGcThread();
|
105
|
+
void killGcThread();
|
106
|
+
void gcLockless(bool wait, boost::unique_lock<boost::mutex> &lock);
|
85
107
|
};
|
86
108
|
|
87
109
|
|
@@ -75,6 +75,7 @@ extern Context *context;
|
|
75
75
|
|
76
76
|
|
77
77
|
void initialize(const Json::Value &initialConfig = Json::Value());
|
78
|
+
void shutdown();
|
78
79
|
|
79
80
|
const char *_strdupFastStringStream(const FastStringStream<> &stream);
|
80
81
|
bool _passesLogLevel(const Context *context, Level level, const ConfigRealization **outputConfigRlz);
|
@@ -32,8 +32,10 @@
|
|
32
32
|
#include <cstring>
|
33
33
|
#include <cerrno>
|
34
34
|
#include <cassert>
|
35
|
+
#include <queue>
|
35
36
|
#include <sys/time.h>
|
36
37
|
#include <fcntl.h>
|
38
|
+
#include <utility>
|
37
39
|
#include <unistd.h>
|
38
40
|
#include <time.h>
|
39
41
|
#include <pthread.h>
|
@@ -53,6 +55,7 @@
|
|
53
55
|
#include <ConfigKit/ConfigKit.h>
|
54
56
|
#include <Utils.h>
|
55
57
|
#include <Utils/StrIntUtils.h>
|
58
|
+
#include <Utils/SystemTime.h>
|
56
59
|
|
57
60
|
namespace Passenger {
|
58
61
|
namespace LoggingKit {
|
@@ -71,6 +74,11 @@ initialize(const Json::Value &initialConfig) {
|
|
71
74
|
context = new Context(initialConfig);
|
72
75
|
}
|
73
76
|
|
77
|
+
void
|
78
|
+
shutdown() {
|
79
|
+
delete context;
|
80
|
+
context = NULL;
|
81
|
+
}
|
74
82
|
|
75
83
|
Level getLevel() {
|
76
84
|
if (OXT_LIKELY(context != NULL)) {
|
@@ -397,13 +405,32 @@ normalizeConfig(const Json::Value &effectiveValues) {
|
|
397
405
|
|
398
406
|
|
399
407
|
Context::Context(const Json::Value &initialConfig)
|
400
|
-
: config(schema, initialConfig)
|
408
|
+
: config(schema, initialConfig),
|
409
|
+
gcThread(NULL),
|
410
|
+
shuttingDown(false)
|
401
411
|
{
|
402
412
|
configRlz.store(new ConfigRealization(config));
|
403
413
|
configRlz.load()->apply(config, NULL);
|
404
414
|
configRlz.load()->finalize();
|
405
415
|
}
|
406
416
|
|
417
|
+
Context::~Context() {
|
418
|
+
boost::unique_lock<boost::mutex> l(gcSyncher);
|
419
|
+
|
420
|
+
// If a gc thread exists, tell it to shut down and
|
421
|
+
// wait until it has done so.
|
422
|
+
shuttingDown = true;
|
423
|
+
gcShuttingDownCond.notify_one();
|
424
|
+
while (gcThread != NULL) {
|
425
|
+
gcHasShutDownCond.wait(l);
|
426
|
+
}
|
427
|
+
|
428
|
+
killGcThread();
|
429
|
+
gcLockless(false, l);
|
430
|
+
|
431
|
+
delete configRlz.load();
|
432
|
+
}
|
433
|
+
|
407
434
|
ConfigKit::Store
|
408
435
|
Context::getConfig() const {
|
409
436
|
boost::lock_guard<boost::mutex> l(syncher);
|
@@ -442,6 +469,82 @@ Context::commitConfigChange(LoggingKit::ConfigChangeRequest &req) BOOST_NOEXCEPT
|
|
442
469
|
newConfigRlz->finalize();
|
443
470
|
}
|
444
471
|
|
472
|
+
pair<ConfigRealization*,MonotonicTimeUsec>
|
473
|
+
Context::peekOldConfig() {
|
474
|
+
return oldConfigs.front();
|
475
|
+
}
|
476
|
+
|
477
|
+
void
|
478
|
+
Context::popOldConfig(ConfigRealization *oldConfig) {
|
479
|
+
delete oldConfig;
|
480
|
+
oldConfigs.pop();
|
481
|
+
}
|
482
|
+
|
483
|
+
void
|
484
|
+
Context::createGcThread() {
|
485
|
+
if (gcThread == NULL) {
|
486
|
+
try {
|
487
|
+
gcThread = new oxt::thread(boost::bind(&Context::gcThreadMain, this),
|
488
|
+
"LoggingKit config garbage collector thread",
|
489
|
+
128 * 1024);
|
490
|
+
} catch (const std::exception &e) {
|
491
|
+
P_ERROR("Error spawning background thread to garbage collect"
|
492
|
+
" old LoggingKit configuration: " << e.what());
|
493
|
+
}
|
494
|
+
}
|
495
|
+
}
|
496
|
+
|
497
|
+
void
|
498
|
+
Context::pushOldConfigAndCreateGcThread(ConfigRealization *oldConfigRlz, MonotonicTimeUsec monotonicNow) {
|
499
|
+
// Garbage collect old config realization in 5 minutes.
|
500
|
+
// There is no way to cheaply find out whether oldConfigRlz
|
501
|
+
// is still being used (we don't want to resort to more atomic
|
502
|
+
// operations, or conservative garbage collection) but
|
503
|
+
// waiting 5 minutes should be good enough.
|
504
|
+
MonotonicTimeUsec gcTime = monotonicNow + 5llu * 60llu * 1000000llu;
|
505
|
+
boost::unique_lock<boost::mutex> l(gcSyncher);
|
506
|
+
oldConfigs.push(make_pair(oldConfigRlz, gcTime));
|
507
|
+
createGcThread();
|
508
|
+
}
|
509
|
+
|
510
|
+
bool
|
511
|
+
Context::oldConfigsExist() {
|
512
|
+
return !oldConfigs.empty();
|
513
|
+
}
|
514
|
+
|
515
|
+
void
|
516
|
+
Context::gcThreadMain() {
|
517
|
+
boost::unique_lock<boost::mutex> l(gcSyncher);
|
518
|
+
gcLockless(true, l);
|
519
|
+
}
|
520
|
+
|
521
|
+
void
|
522
|
+
Context::gcLockless(bool wait, boost::unique_lock<boost::mutex> &lock) {
|
523
|
+
while (!shuttingDown && oldConfigsExist()) {
|
524
|
+
pair<ConfigRealization *, MonotonicTimeUsec> p = peekOldConfig();
|
525
|
+
for (MonotonicTimeUsec now = SystemTime::getMonotonicUsecWithGranularity<SystemTime::GRAN_1SEC>();
|
526
|
+
!shuttingDown && wait && now < p.second;
|
527
|
+
now = SystemTime::getMonotonicUsecWithGranularity<SystemTime::GRAN_1SEC>())
|
528
|
+
{
|
529
|
+
// Wait until it's time to GC this config object,
|
530
|
+
// or until the destructor tells us that we're shutting down.
|
531
|
+
gcShuttingDownCond.timed_wait(lock, boost::posix_time::microseconds(p.second - now));
|
532
|
+
}
|
533
|
+
if (!shuttingDown) {
|
534
|
+
popOldConfig(p.first);
|
535
|
+
}
|
536
|
+
}
|
537
|
+
killGcThread();
|
538
|
+
}
|
539
|
+
|
540
|
+
void
|
541
|
+
Context::killGcThread() {
|
542
|
+
if (gcThread != NULL) {
|
543
|
+
delete gcThread;
|
544
|
+
gcThread = NULL;
|
545
|
+
}
|
546
|
+
gcHasShutDownCond.notify_one();
|
547
|
+
}
|
445
548
|
|
446
549
|
Json::Value
|
447
550
|
Schema::createStderrTarget() {
|
@@ -636,14 +739,6 @@ ConfigRealization::~ConfigRealization() {
|
|
636
739
|
}
|
637
740
|
}
|
638
741
|
|
639
|
-
static void
|
640
|
-
garbageCollectConfigRealization(ConfigRealization *configRlz) {
|
641
|
-
boost::this_thread::disable_interruption di;
|
642
|
-
boost::this_thread::disable_syscall_interruption dsi;
|
643
|
-
syscalls::sleep(30);
|
644
|
-
delete configRlz;
|
645
|
-
}
|
646
|
-
|
647
742
|
void
|
648
743
|
ConfigRealization::apply(const ConfigKit::Store &config, ConfigRealization *oldConfigRlz)
|
649
744
|
BOOST_NOEXCEPT_OR_NOTHROW
|
@@ -658,19 +753,8 @@ ConfigRealization::apply(const ConfigKit::Store &config, ConfigRealization *oldC
|
|
658
753
|
}
|
659
754
|
|
660
755
|
if (oldConfigRlz != NULL) {
|
661
|
-
|
662
|
-
|
663
|
-
// is still being used (we don't want to resort to more atomic
|
664
|
-
// operations, or conservative garbage collection) but
|
665
|
-
// waiting 30 seconds should be good enough.
|
666
|
-
try {
|
667
|
-
oxt::thread(boost::bind(garbageCollectConfigRealization, oldConfigRlz),
|
668
|
-
"LoggingKit config garbage collector " + toString(oldConfigRlz),
|
669
|
-
128 * 1024);
|
670
|
-
} catch (const std::exception &e) {
|
671
|
-
P_ERROR("Error spawning background thread to garbage collect"
|
672
|
-
" old LoggingKit configuration: " << e.what());
|
673
|
-
}
|
756
|
+
MonotonicTimeUsec monotonicNow = SystemTime::getMonotonicUsecWithGranularity<SystemTime::GRAN_1SEC>();
|
757
|
+
context->pushOldConfigAndCreateGcThread(oldConfigRlz, monotonicNow);
|
674
758
|
}
|
675
759
|
}
|
676
760
|
|