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
@@ -1,145 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010-2017 Phusion Holding B.V.
|
4
|
-
*
|
5
|
-
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
|
-
* trademarks of Phusion Holding B.V.
|
7
|
-
*
|
8
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
-
* of this software and associated documentation files (the "Software"), to deal
|
10
|
-
* in the Software without restriction, including without limitation the rights
|
11
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
-
* copies of the Software, and to permit persons to whom the Software is
|
13
|
-
* furnished to do so, subject to the following conditions:
|
14
|
-
*
|
15
|
-
* The above copyright notice and this permission notice shall be included in
|
16
|
-
* all copies or substantial portions of the Software.
|
17
|
-
*
|
18
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
-
* THE SOFTWARE.
|
25
|
-
*/
|
26
|
-
#ifndef _PASSENGER_UST_ROUTER_REMOTE_SINK_H_
|
27
|
-
#define _PASSENGER_UST_ROUTER_REMOTE_SINK_H_
|
28
|
-
|
29
|
-
#include <string>
|
30
|
-
#include <cstring>
|
31
|
-
#include <ctime>
|
32
|
-
#include <ev++.h>
|
33
|
-
#include <LoggingKit/LoggingKit.h>
|
34
|
-
#include <UstRouter/LogSink.h>
|
35
|
-
#include <UstRouter/RemoteSender.h>
|
36
|
-
|
37
|
-
namespace Passenger {
|
38
|
-
namespace UstRouter {
|
39
|
-
|
40
|
-
using namespace std;
|
41
|
-
using namespace boost;
|
42
|
-
|
43
|
-
inline RemoteSender &Controller_getRemoteSender(Controller *controller);
|
44
|
-
|
45
|
-
|
46
|
-
class RemoteSink: public LogSink {
|
47
|
-
private:
|
48
|
-
bool realFlush() {
|
49
|
-
if (bufferSize > 0) {
|
50
|
-
P_DEBUG("Flushing " << inspect() << ": " << bufferSize << " bytes");
|
51
|
-
lastFlushed = ev_now(Controller_getLoop(controller));
|
52
|
-
StaticString data(buffer, bufferSize);
|
53
|
-
Controller_getRemoteSender(controller).schedule(unionStationKey,
|
54
|
-
nodeName, category, &data, 1);
|
55
|
-
bufferSize = 0;
|
56
|
-
return true;
|
57
|
-
} else {
|
58
|
-
P_DEBUG("Flushing remote sink " << inspect() << ": 0 bytes");
|
59
|
-
return false;
|
60
|
-
}
|
61
|
-
}
|
62
|
-
|
63
|
-
public:
|
64
|
-
/* RemoteSender compresses the data with zlib before sending it
|
65
|
-
* to the server. Even including Base64 and URL encoding overhead,
|
66
|
-
* this compresses the data to about 25% of its original size.
|
67
|
-
* Therefore we set a buffer capacity of a little less than 4 times
|
68
|
-
* the TCP maximum segment size so that we can send as much
|
69
|
-
* data as possible to the server in a single TCP segment.
|
70
|
-
* With the "little less" we take into account:
|
71
|
-
* - HTTPS overhead. This can be as high as 2 KB.
|
72
|
-
* - The fact that RemoteSink.append() might try to flush the
|
73
|
-
* current buffer. Observations have shown that the data
|
74
|
-
* for a request transaction is often less than 5 KB.
|
75
|
-
*/
|
76
|
-
static const unsigned int BUFFER_CAPACITY =
|
77
|
-
4 * 64 * 1024 -
|
78
|
-
16 * 1024;
|
79
|
-
|
80
|
-
string unionStationKey;
|
81
|
-
string nodeName;
|
82
|
-
string category;
|
83
|
-
char buffer[BUFFER_CAPACITY];
|
84
|
-
unsigned int bufferSize;
|
85
|
-
|
86
|
-
RemoteSink(Controller *controller, const string &_unionStationKey,
|
87
|
-
const string &_nodeName, const string &_category)
|
88
|
-
: LogSink(controller),
|
89
|
-
unionStationKey(_unionStationKey),
|
90
|
-
nodeName(_nodeName),
|
91
|
-
category(_category),
|
92
|
-
bufferSize(0)
|
93
|
-
{ }
|
94
|
-
|
95
|
-
~RemoteSink() {
|
96
|
-
// Calling non-virtual flush method
|
97
|
-
realFlush();
|
98
|
-
}
|
99
|
-
|
100
|
-
virtual bool isRemote() const {
|
101
|
-
return true;
|
102
|
-
}
|
103
|
-
|
104
|
-
virtual void append(const TransactionPtr &transaction) {
|
105
|
-
StaticString data = transaction->getBody();
|
106
|
-
LogSink::append(transaction);
|
107
|
-
if (bufferSize + data.size() > BUFFER_CAPACITY) {
|
108
|
-
StaticString data2[] = {
|
109
|
-
StaticString(buffer, bufferSize),
|
110
|
-
data
|
111
|
-
};
|
112
|
-
Controller_getRemoteSender(controller).schedule(unionStationKey,
|
113
|
-
nodeName, category, data2, 2);
|
114
|
-
lastFlushed = ev_now(Controller_getLoop(controller));
|
115
|
-
bufferSize = 0;
|
116
|
-
} else {
|
117
|
-
memcpy(buffer + bufferSize, data.data(), data.size());
|
118
|
-
bufferSize += data.size();
|
119
|
-
}
|
120
|
-
}
|
121
|
-
|
122
|
-
virtual bool flush() {
|
123
|
-
return realFlush();
|
124
|
-
}
|
125
|
-
|
126
|
-
virtual Json::Value inspectStateAsJson() const {
|
127
|
-
Json::Value doc = LogSink::inspectStateAsJson();
|
128
|
-
doc["type"] = "remote";
|
129
|
-
doc["key"] = unionStationKey;
|
130
|
-
doc["node"] = nodeName;
|
131
|
-
doc["category"] = category;
|
132
|
-
doc["buffer_size"] = byteSizeToJson(bufferSize);
|
133
|
-
return doc;
|
134
|
-
}
|
135
|
-
|
136
|
-
string inspect() const {
|
137
|
-
return "RemoteSink(key=" + unionStationKey + ", node=" + nodeName + ", category=" + category + ")";
|
138
|
-
}
|
139
|
-
};
|
140
|
-
|
141
|
-
|
142
|
-
} // namespace UstRouter
|
143
|
-
} // namespace Passenger
|
144
|
-
|
145
|
-
#endif /* _PASSENGER_UST_ROUTER_REMOTE_SINK_H_ */
|
@@ -1,278 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010-2017 Phusion Holding B.V.
|
4
|
-
*
|
5
|
-
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
|
-
* trademarks of Phusion Holding B.V.
|
7
|
-
*
|
8
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
-
* of this software and associated documentation files (the "Software"), to deal
|
10
|
-
* in the Software without restriction, including without limitation the rights
|
11
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
-
* copies of the Software, and to permit persons to whom the Software is
|
13
|
-
* furnished to do so, subject to the following conditions:
|
14
|
-
*
|
15
|
-
* The above copyright notice and this permission notice shall be included in
|
16
|
-
* all copies or substantial portions of the Software.
|
17
|
-
*
|
18
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
-
* THE SOFTWARE.
|
25
|
-
*/
|
26
|
-
#ifndef _PASSENGER_UST_ROUTER_TRANSACTION_H_
|
27
|
-
#define _PASSENGER_UST_ROUTER_TRANSACTION_H_
|
28
|
-
|
29
|
-
#include <boost/shared_ptr.hpp>
|
30
|
-
#include <boost/move/move.hpp>
|
31
|
-
#include <boost/container/string.hpp>
|
32
|
-
#include <boost/cstdint.hpp>
|
33
|
-
#include <cstdlib>
|
34
|
-
#include <cstring>
|
35
|
-
|
36
|
-
#include <ev++.h>
|
37
|
-
#include <StaticString.h>
|
38
|
-
#include <MemoryKit/palloc.h>
|
39
|
-
#include <DataStructures/LString.h>
|
40
|
-
#include <Utils/JsonUtils.h>
|
41
|
-
|
42
|
-
namespace Passenger {
|
43
|
-
namespace UstRouter {
|
44
|
-
|
45
|
-
using namespace std;
|
46
|
-
|
47
|
-
|
48
|
-
class Transaction {
|
49
|
-
private:
|
50
|
-
BOOST_MOVABLE_BUT_NOT_COPYABLE(Transaction);
|
51
|
-
|
52
|
-
unsigned int groupNameOffset;
|
53
|
-
unsigned int nodeNameOffset;
|
54
|
-
unsigned int categoryOffset;
|
55
|
-
unsigned int unionStationKeyOffset;
|
56
|
-
unsigned int filtersOffset;
|
57
|
-
|
58
|
-
unsigned short groupNameSize, nodeNameSize, filtersSize;
|
59
|
-
boost::uint8_t txnIdSize, unionStationKeySize, categorySize;
|
60
|
-
|
61
|
-
ev_tstamp createdAt;
|
62
|
-
unsigned int writeCount;
|
63
|
-
unsigned int refCount;
|
64
|
-
unsigned int bodyOffset;
|
65
|
-
bool crashProtect, discarded;
|
66
|
-
|
67
|
-
boost::container::string storage;
|
68
|
-
|
69
|
-
template<typename IntegerType1, typename IntegerType2>
|
70
|
-
void internString(const StaticString &str, IntegerType1 *offset, IntegerType2 *size) {
|
71
|
-
if (offset != NULL) {
|
72
|
-
*offset = bodyOffset;
|
73
|
-
}
|
74
|
-
storage.append(str.data(), str.size());
|
75
|
-
storage.append(1, '\0');
|
76
|
-
*size = str.size();
|
77
|
-
bodyOffset += str.size() + 1;
|
78
|
-
}
|
79
|
-
|
80
|
-
public:
|
81
|
-
Transaction(const StaticString &txnId, const StaticString &groupName,
|
82
|
-
const StaticString &nodeName, const StaticString &category,
|
83
|
-
const StaticString &unionStationKey, ev_tstamp _createdAt,
|
84
|
-
const StaticString &filters = StaticString(),
|
85
|
-
unsigned int initialCapacity = 1024 * 8)
|
86
|
-
: createdAt(_createdAt),
|
87
|
-
writeCount(0),
|
88
|
-
refCount(0),
|
89
|
-
bodyOffset(0),
|
90
|
-
crashProtect(false),
|
91
|
-
discarded(false)
|
92
|
-
{
|
93
|
-
internString(txnId, (boost::uint8_t *) NULL, &txnIdSize);
|
94
|
-
internString(groupName, &groupNameOffset, &groupNameSize);
|
95
|
-
internString(nodeName, &nodeNameOffset, &nodeNameSize);
|
96
|
-
internString(category, &categoryOffset, &categorySize);
|
97
|
-
internString(unionStationKey, &unionStationKeyOffset, &unionStationKeySize);
|
98
|
-
internString(filters, &filtersOffset, &filtersSize);
|
99
|
-
}
|
100
|
-
|
101
|
-
Transaction(BOOST_RV_REF(Transaction) other)
|
102
|
-
: groupNameOffset(other.groupNameOffset),
|
103
|
-
nodeNameOffset(other.nodeNameOffset),
|
104
|
-
categoryOffset(other.categoryOffset),
|
105
|
-
unionStationKeyOffset(other.unionStationKeyOffset),
|
106
|
-
filtersOffset(other.filtersOffset),
|
107
|
-
groupNameSize(other.groupNameSize),
|
108
|
-
nodeNameSize(other.nodeNameSize),
|
109
|
-
filtersSize(other.filtersSize),
|
110
|
-
txnIdSize(other.txnIdSize),
|
111
|
-
unionStationKeySize(other.unionStationKeySize),
|
112
|
-
categorySize(other.categorySize),
|
113
|
-
createdAt(other.createdAt),
|
114
|
-
writeCount(other.writeCount),
|
115
|
-
refCount(other.refCount),
|
116
|
-
bodyOffset(other.bodyOffset),
|
117
|
-
crashProtect(other.crashProtect),
|
118
|
-
discarded(other.discarded),
|
119
|
-
storage(boost::move(other.storage))
|
120
|
-
{
|
121
|
-
other.groupNameOffset = 0;
|
122
|
-
other.nodeNameOffset = 0;
|
123
|
-
other.categoryOffset = 0;
|
124
|
-
other.unionStationKeyOffset = 0;
|
125
|
-
other.filtersOffset = 0;
|
126
|
-
other.groupNameSize = 0;
|
127
|
-
other.nodeNameSize = 0;
|
128
|
-
other.filtersSize = 0;
|
129
|
-
other.txnIdSize = 0;
|
130
|
-
other.unionStationKeySize = 0;
|
131
|
-
other.categorySize = 0;
|
132
|
-
other.createdAt = 0;
|
133
|
-
other.writeCount = 0;
|
134
|
-
other.refCount = 0;
|
135
|
-
other.bodyOffset = 0;
|
136
|
-
other.crashProtect = false;
|
137
|
-
other.discarded = true;
|
138
|
-
}
|
139
|
-
|
140
|
-
Transaction &operator=(BOOST_RV_REF(Transaction) other) {
|
141
|
-
if (this != &other) {
|
142
|
-
groupNameOffset = other.groupNameOffset;
|
143
|
-
nodeNameOffset = other.nodeNameOffset;
|
144
|
-
categoryOffset = other.categoryOffset;
|
145
|
-
unionStationKeyOffset = other.unionStationKeyOffset;
|
146
|
-
filtersOffset = other.filtersOffset;
|
147
|
-
groupNameSize = other.groupNameSize;
|
148
|
-
nodeNameSize = other.nodeNameSize;
|
149
|
-
filtersSize = other.filtersSize;
|
150
|
-
txnIdSize = other.txnIdSize;
|
151
|
-
unionStationKeySize = other.unionStationKeySize;
|
152
|
-
categorySize = other.categorySize;
|
153
|
-
createdAt = other.createdAt;
|
154
|
-
writeCount = other.writeCount;
|
155
|
-
refCount = other.refCount;
|
156
|
-
bodyOffset = other.bodyOffset;
|
157
|
-
crashProtect = other.crashProtect;
|
158
|
-
discarded = other.discarded;
|
159
|
-
storage = boost::move(other.storage);
|
160
|
-
|
161
|
-
other.groupNameOffset = 0;
|
162
|
-
other.nodeNameOffset = 0;
|
163
|
-
other.categoryOffset = 0;
|
164
|
-
other.unionStationKeyOffset = 0;
|
165
|
-
other.filtersOffset = 0;
|
166
|
-
other.groupNameSize = 0;
|
167
|
-
other.nodeNameSize = 0;
|
168
|
-
other.filtersSize = 0;
|
169
|
-
other.txnIdSize = 0;
|
170
|
-
other.unionStationKeySize = 0;
|
171
|
-
other.categorySize = 0;
|
172
|
-
other.createdAt = 0;
|
173
|
-
other.writeCount = 0;
|
174
|
-
other.refCount = 0;
|
175
|
-
other.bodyOffset = 0;
|
176
|
-
other.crashProtect = false;
|
177
|
-
other.discarded = true;
|
178
|
-
}
|
179
|
-
return *this;
|
180
|
-
}
|
181
|
-
|
182
|
-
StaticString getTxnId() const {
|
183
|
-
return StaticString(storage.data(), txnIdSize);
|
184
|
-
}
|
185
|
-
|
186
|
-
StaticString getGroupName() const {
|
187
|
-
return StaticString(storage.data() + groupNameOffset, groupNameSize);
|
188
|
-
}
|
189
|
-
|
190
|
-
StaticString getNodeName() const {
|
191
|
-
return StaticString(storage.data() + nodeNameOffset, nodeNameSize);
|
192
|
-
}
|
193
|
-
|
194
|
-
StaticString getCategory() const {
|
195
|
-
return StaticString(storage.data() + categoryOffset, categorySize);
|
196
|
-
}
|
197
|
-
|
198
|
-
StaticString getUnionStationKey() const {
|
199
|
-
return StaticString(storage.data() + unionStationKeyOffset, unionStationKeySize);
|
200
|
-
}
|
201
|
-
|
202
|
-
StaticString getFilters() const {
|
203
|
-
return StaticString(storage.data() + filtersOffset, filtersSize);
|
204
|
-
}
|
205
|
-
|
206
|
-
StaticString getBody() const {
|
207
|
-
return StaticString(storage.data() + bodyOffset, storage.size() - bodyOffset);
|
208
|
-
}
|
209
|
-
|
210
|
-
bool crashProtectEnabled() const {
|
211
|
-
return crashProtect;
|
212
|
-
}
|
213
|
-
|
214
|
-
void enableCrashProtect(bool v) {
|
215
|
-
crashProtect = v;
|
216
|
-
}
|
217
|
-
|
218
|
-
bool isDiscarded() const {
|
219
|
-
return discarded;
|
220
|
-
}
|
221
|
-
|
222
|
-
void discard() {
|
223
|
-
discarded = true;
|
224
|
-
}
|
225
|
-
|
226
|
-
void ref() {
|
227
|
-
refCount++;
|
228
|
-
}
|
229
|
-
|
230
|
-
void unref() {
|
231
|
-
assert(refCount > 0);
|
232
|
-
refCount--;
|
233
|
-
}
|
234
|
-
|
235
|
-
unsigned int getRefCount() const {
|
236
|
-
return refCount;
|
237
|
-
}
|
238
|
-
|
239
|
-
void append(const StaticString ×tamp, const StaticString &data) {
|
240
|
-
char txnIdCopy[txnIdSize];
|
241
|
-
char writeCountStr[sizeof(unsigned int) * 2 + 1];
|
242
|
-
unsigned int writeCountStrSize = integerToHexatri(
|
243
|
-
writeCount, writeCountStr);
|
244
|
-
|
245
|
-
memcpy(txnIdCopy, getTxnId().data(), getTxnId().size());
|
246
|
-
writeCount++;
|
247
|
-
|
248
|
-
storage.append(txnIdCopy, getTxnId().size());
|
249
|
-
storage.append(1, ' ');
|
250
|
-
storage.append(timestamp.data(), timestamp.size());
|
251
|
-
storage.append(1, ' ');
|
252
|
-
storage.append(writeCountStr, writeCountStrSize);
|
253
|
-
storage.append(1, ' ');
|
254
|
-
storage.append(data.data(), data.size());
|
255
|
-
storage.append(1, '\n');
|
256
|
-
}
|
257
|
-
|
258
|
-
Json::Value inspectStateAsJson() const {
|
259
|
-
Json::Value doc;
|
260
|
-
doc["txn_id"] = getTxnId().toString();
|
261
|
-
doc["created_at"] = timeToJson(createdAt * 1000000.0);
|
262
|
-
doc["group"] = getGroupName().toString();
|
263
|
-
doc["node"] = getNodeName().toString();
|
264
|
-
doc["category"] = getCategory().toString();
|
265
|
-
doc["key"] = getUnionStationKey().toString();
|
266
|
-
doc["refcount"] = refCount;
|
267
|
-
doc["body_size"] = byteSizeToJson(getBody().size());
|
268
|
-
return doc;
|
269
|
-
}
|
270
|
-
};
|
271
|
-
|
272
|
-
typedef boost::shared_ptr<Transaction> TransactionPtr;
|
273
|
-
|
274
|
-
|
275
|
-
} // namespace UstRouter
|
276
|
-
} // namespace Passenger
|
277
|
-
|
278
|
-
#endif /* _PASSENGER_UST_ROUTER_TRANSACTION_H_ */
|
@@ -1,681 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010-2017 Phusion Holding B.V.
|
4
|
-
*
|
5
|
-
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
|
-
* trademarks of Phusion Holding B.V.
|
7
|
-
*
|
8
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
-
* of this software and associated documentation files (the "Software"), to deal
|
10
|
-
* in the Software without restriction, including without limitation the rights
|
11
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
-
* copies of the Software, and to permit persons to whom the Software is
|
13
|
-
* furnished to do so, subject to the following conditions:
|
14
|
-
*
|
15
|
-
* The above copyright notice and this permission notice shall be included in
|
16
|
-
* all copies or substantial portions of the Software.
|
17
|
-
*
|
18
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
-
* THE SOFTWARE.
|
25
|
-
*/
|
26
|
-
// Include ev++.h early to avoid macro clash on EV_ERROR.
|
27
|
-
#include <ev++.h>
|
28
|
-
|
29
|
-
#include <oxt/system_calls.hpp>
|
30
|
-
#include <oxt/backtrace.hpp>
|
31
|
-
#include <oxt/thread.hpp>
|
32
|
-
|
33
|
-
#include <sys/types.h>
|
34
|
-
#include <sys/resource.h>
|
35
|
-
#include <unistd.h>
|
36
|
-
#include <pwd.h>
|
37
|
-
#include <grp.h>
|
38
|
-
#include <cstdio>
|
39
|
-
#include <cstdlib>
|
40
|
-
#include <cstring>
|
41
|
-
#include <cerrno>
|
42
|
-
#include <algorithm>
|
43
|
-
#include <stdexcept>
|
44
|
-
#include <stdlib.h>
|
45
|
-
#include <signal.h>
|
46
|
-
|
47
|
-
#include <Shared/Base.h>
|
48
|
-
#include <Shared/ApiServerUtils.h>
|
49
|
-
#include <UstRouter/OptionParser.h>
|
50
|
-
#include <UstRouter/Controller.h>
|
51
|
-
#include <UstRouter/ApiServer.h>
|
52
|
-
|
53
|
-
#include <Exceptions.h>
|
54
|
-
#include <FileDescriptor.h>
|
55
|
-
#include <BackgroundEventLoop.h>
|
56
|
-
#include <ResourceLocator.h>
|
57
|
-
#include <Constants.h>
|
58
|
-
#include <ConfigKit/VariantMapUtils.h>
|
59
|
-
#include <Utils.h>
|
60
|
-
#include <Utils/IOUtils.h>
|
61
|
-
#include <Utils/StrIntUtils.h>
|
62
|
-
#include <Utils/MessageIO.h>
|
63
|
-
#include <Utils/VariantMap.h>
|
64
|
-
|
65
|
-
using namespace oxt;
|
66
|
-
using namespace Passenger;
|
67
|
-
|
68
|
-
|
69
|
-
/***** Constants and working objects *****/
|
70
|
-
|
71
|
-
namespace Passenger {
|
72
|
-
namespace UstRouter {
|
73
|
-
struct WorkingObjects {
|
74
|
-
FileDescriptor serverSocketFd;
|
75
|
-
vector<int> apiSockets;
|
76
|
-
ResourceLocator *resourceLocator;
|
77
|
-
ApiAccountDatabase apiAccountDatabase;
|
78
|
-
|
79
|
-
BackgroundEventLoop *bgloop;
|
80
|
-
ServerKit::Context *serverKitContext;
|
81
|
-
Controller::Schema controllerSchema;
|
82
|
-
Controller *controller;
|
83
|
-
|
84
|
-
BackgroundEventLoop *apiBgloop;
|
85
|
-
ServerKit::Context *apiServerKitContext;
|
86
|
-
ServerKit::HttpServerSchema apiServerSchema;
|
87
|
-
UstRouter::ApiServer *apiServer;
|
88
|
-
EventFd exitEvent;
|
89
|
-
EventFd allClientsDisconnectedEvent;
|
90
|
-
|
91
|
-
struct ev_signal sigintWatcher;
|
92
|
-
struct ev_signal sigtermWatcher;
|
93
|
-
struct ev_signal sigquitWatcher;
|
94
|
-
unsigned int terminationCount;
|
95
|
-
|
96
|
-
WorkingObjects()
|
97
|
-
: resourceLocator(NULL),
|
98
|
-
bgloop(NULL),
|
99
|
-
serverKitContext(NULL),
|
100
|
-
controller(NULL),
|
101
|
-
apiBgloop(NULL),
|
102
|
-
apiServerKitContext(NULL),
|
103
|
-
apiServer(NULL),
|
104
|
-
exitEvent(__FILE__, __LINE__, "WorkingObjects: exitEvent"),
|
105
|
-
allClientsDisconnectedEvent(__FILE__, __LINE__, "WorkingObjects: allClientsDisconnectedEvent"),
|
106
|
-
terminationCount(0)
|
107
|
-
{ }
|
108
|
-
};
|
109
|
-
} // namespace UstRouter
|
110
|
-
} // namespace Passenger
|
111
|
-
|
112
|
-
using namespace Passenger::UstRouter;
|
113
|
-
|
114
|
-
static VariantMap *agentsOptions;
|
115
|
-
static WorkingObjects *workingObjects;
|
116
|
-
|
117
|
-
|
118
|
-
/***** Functions *****/
|
119
|
-
|
120
|
-
static void printInfo(EV_P_ struct ev_signal *watcher, int revents);
|
121
|
-
static void printInfoInThread();
|
122
|
-
static void onTerminationSignal(EV_P_ struct ev_signal *watcher, int revents);
|
123
|
-
static void apiServerShutdownFinished(UstRouter::ApiServer *server);
|
124
|
-
static void waitForExitEvent();
|
125
|
-
|
126
|
-
void
|
127
|
-
ustRouterFeedbackFdBecameReadable(ev::io &watcher, int revents) {
|
128
|
-
/* This event indicates that the watchdog has been killed.
|
129
|
-
* In this case we'll kill all descendant
|
130
|
-
* processes and exit. There's no point in keeping this agent
|
131
|
-
* running because we can't detect when the web server exits,
|
132
|
-
* and because this agent doesn't own the server instance
|
133
|
-
* directory. As soon as passenger-status is run, the server
|
134
|
-
* instance directory will be cleaned up, making this agent's
|
135
|
-
* services inaccessible.
|
136
|
-
*/
|
137
|
-
syscalls::killpg(getpgrp(), SIGKILL);
|
138
|
-
_exit(2); // In case killpg() fails.
|
139
|
-
}
|
140
|
-
|
141
|
-
static string
|
142
|
-
findUnionStationGatewayCert(const ResourceLocator &locator,
|
143
|
-
const string &cert)
|
144
|
-
{
|
145
|
-
if (cert.empty()) {
|
146
|
-
return locator.getResourcesDir() + "/union_station_gateway.crt";
|
147
|
-
} else if (cert != "-") {
|
148
|
-
return cert;
|
149
|
-
} else {
|
150
|
-
return "";
|
151
|
-
}
|
152
|
-
}
|
153
|
-
|
154
|
-
static void
|
155
|
-
makeFileWorldReadableAndWritable(const string &path) {
|
156
|
-
int ret;
|
157
|
-
|
158
|
-
do {
|
159
|
-
ret = chmod(path.c_str(), parseModeString("u=rw,g=rw,o=rw"));
|
160
|
-
} while (ret == -1 && errno == EINTR);
|
161
|
-
}
|
162
|
-
|
163
|
-
static void
|
164
|
-
initializePrivilegedWorkingObjects() {
|
165
|
-
TRACE_POINT();
|
166
|
-
VariantMap &options = *agentsOptions;
|
167
|
-
WorkingObjects *wo = workingObjects = new WorkingObjects();
|
168
|
-
|
169
|
-
options.set("ust_router_username", "logging");
|
170
|
-
|
171
|
-
string password = options.get("ust_router_password", false);
|
172
|
-
if (password.empty()) {
|
173
|
-
password = strip(readAll(options.get("ust_router_password_file")));
|
174
|
-
options.set("ust_router_password", password);
|
175
|
-
}
|
176
|
-
|
177
|
-
vector<string> authorizations = options.getStrSet("ust_router_authorizations",
|
178
|
-
false);
|
179
|
-
string description;
|
180
|
-
|
181
|
-
UPDATE_TRACE_POINT();
|
182
|
-
foreach (description, authorizations) {
|
183
|
-
try {
|
184
|
-
wo->apiAccountDatabase.add(description);
|
185
|
-
} catch (const ArgumentException &e) {
|
186
|
-
throw std::runtime_error(e.what());
|
187
|
-
}
|
188
|
-
}
|
189
|
-
|
190
|
-
// Initialize ResourceLocator here in case passenger_root's parent
|
191
|
-
// directory is not executable by the unprivileged user.
|
192
|
-
wo->resourceLocator = new ResourceLocator(options.get("passenger_root"));
|
193
|
-
}
|
194
|
-
|
195
|
-
static void
|
196
|
-
setUlimits() {
|
197
|
-
TRACE_POINT();
|
198
|
-
VariantMap &options = *agentsOptions;
|
199
|
-
|
200
|
-
if (options.has("core_file_descriptor_ulimit")) {
|
201
|
-
unsigned int number = options.getUint("core_file_descriptor_ulimit");
|
202
|
-
struct rlimit limit;
|
203
|
-
int ret;
|
204
|
-
|
205
|
-
limit.rlim_cur = number;
|
206
|
-
limit.rlim_max = number;
|
207
|
-
do {
|
208
|
-
ret = setrlimit(RLIMIT_NOFILE, &limit);
|
209
|
-
} while (ret == -1 && errno == EINTR);
|
210
|
-
|
211
|
-
if (ret == -1) {
|
212
|
-
int e = errno;
|
213
|
-
P_ERROR("Unable to set file descriptor ulimit to " << number
|
214
|
-
<< ": " << strerror(e) << " (errno=" << e << ")");
|
215
|
-
}
|
216
|
-
}
|
217
|
-
}
|
218
|
-
|
219
|
-
static void
|
220
|
-
startListening() {
|
221
|
-
TRACE_POINT();
|
222
|
-
const VariantMap &options = *agentsOptions;
|
223
|
-
WorkingObjects *wo = workingObjects;
|
224
|
-
string address;
|
225
|
-
vector<string> apiAddresses;
|
226
|
-
|
227
|
-
address = options.get("ust_router_address");
|
228
|
-
wo->serverSocketFd.assign(createServer(address, 0, true,
|
229
|
-
__FILE__, __LINE__), NULL, 0);
|
230
|
-
P_LOG_FILE_DESCRIPTOR_PURPOSE(wo->serverSocketFd,
|
231
|
-
"Server address: " << wo->serverSocketFd);
|
232
|
-
if (getSocketAddressType(address) == SAT_UNIX) {
|
233
|
-
makeFileWorldReadableAndWritable(parseUnixSocketAddress(address));
|
234
|
-
}
|
235
|
-
|
236
|
-
UPDATE_TRACE_POINT();
|
237
|
-
apiAddresses = options.getStrSet("ust_router_api_addresses",
|
238
|
-
false);
|
239
|
-
foreach (address, apiAddresses) {
|
240
|
-
wo->apiSockets.push_back(createServer(address, 0, true,
|
241
|
-
__FILE__, __LINE__));
|
242
|
-
P_LOG_FILE_DESCRIPTOR_PURPOSE(wo->apiSockets.back(),
|
243
|
-
"Server address: " << wo->apiSockets.back());
|
244
|
-
if (getSocketAddressType(address) == SAT_UNIX) {
|
245
|
-
makeFileWorldReadableAndWritable(parseUnixSocketAddress(address));
|
246
|
-
}
|
247
|
-
}
|
248
|
-
}
|
249
|
-
|
250
|
-
static void
|
251
|
-
lowerPrivilege() {
|
252
|
-
TRACE_POINT();
|
253
|
-
const VariantMap &options = *agentsOptions;
|
254
|
-
string userName = options.get("analytics_log_user", false);
|
255
|
-
|
256
|
-
if (geteuid() == 0 && !userName.empty()) {
|
257
|
-
string groupName = options.get("analytics_log_group", false);
|
258
|
-
struct passwd *pwUser = getpwnam(userName.c_str());
|
259
|
-
gid_t gid;
|
260
|
-
|
261
|
-
if (pwUser == NULL) {
|
262
|
-
throw RuntimeException("Cannot lookup user information for user " +
|
263
|
-
userName);
|
264
|
-
}
|
265
|
-
|
266
|
-
if (groupName.empty()) {
|
267
|
-
gid = pwUser->pw_gid;
|
268
|
-
groupName = getGroupName(pwUser->pw_gid);
|
269
|
-
} else {
|
270
|
-
gid = lookupGid(groupName);
|
271
|
-
}
|
272
|
-
|
273
|
-
if (initgroups(userName.c_str(), gid) != 0) {
|
274
|
-
int e = errno;
|
275
|
-
throw SystemException("Unable to lower " SHORT_PROGRAM_NAME " UstRouter's privilege "
|
276
|
-
"to that of user '" + userName + "' and group '" + groupName +
|
277
|
-
"': cannot set supplementary groups", e);
|
278
|
-
}
|
279
|
-
if (setgid(gid) != 0) {
|
280
|
-
int e = errno;
|
281
|
-
throw SystemException("Unable to lower " SHORT_PROGRAM_NAME " UstRouter's privilege "
|
282
|
-
"to that of user '" + userName + "' and group '" + groupName +
|
283
|
-
"': cannot set group ID to " + toString(gid), e);
|
284
|
-
}
|
285
|
-
if (setuid(pwUser->pw_uid) != 0) {
|
286
|
-
int e = errno;
|
287
|
-
throw SystemException("Unable to lower " SHORT_PROGRAM_NAME " UstRouter's privilege "
|
288
|
-
"to that of user '" + userName + "' and group '" + groupName +
|
289
|
-
"': cannot set user ID to " + toString(pwUser->pw_uid), e);
|
290
|
-
}
|
291
|
-
|
292
|
-
setenv("USER", pwUser->pw_name, 1);
|
293
|
-
setenv("HOME", pwUser->pw_dir, 1);
|
294
|
-
setenv("UID", toString(gid).c_str(), 1);
|
295
|
-
}
|
296
|
-
}
|
297
|
-
|
298
|
-
static void
|
299
|
-
initializeUnprivilegedWorkingObjects() {
|
300
|
-
TRACE_POINT();
|
301
|
-
VariantMap &options = *agentsOptions;
|
302
|
-
WorkingObjects *wo = workingObjects;
|
303
|
-
int fd;
|
304
|
-
|
305
|
-
options.set("union_station_gateway_cert", findUnionStationGatewayCert(
|
306
|
-
*wo->resourceLocator, options.get("union_station_gateway_cert", false)));
|
307
|
-
|
308
|
-
UPDATE_TRACE_POINT();
|
309
|
-
wo->bgloop = new BackgroundEventLoop(true, true);
|
310
|
-
wo->serverKitContext = new ServerKit::Context(wo->bgloop->safe,
|
311
|
-
wo->bgloop->libuv_loop);
|
312
|
-
wo->controller = new Controller(wo->serverKitContext,
|
313
|
-
wo->controllerSchema,
|
314
|
-
ConfigKit::variantMapToJson(wo->controllerSchema, options));
|
315
|
-
wo->controller->initialize();
|
316
|
-
wo->controller->listen(wo->serverSocketFd);
|
317
|
-
|
318
|
-
UPDATE_TRACE_POINT();
|
319
|
-
if (!wo->apiSockets.empty()) {
|
320
|
-
wo->apiBgloop = new BackgroundEventLoop(true, true);
|
321
|
-
wo->apiServerKitContext = new ServerKit::Context(wo->apiBgloop->safe,
|
322
|
-
wo->apiBgloop->libuv_loop);
|
323
|
-
wo->apiServer = new UstRouter::ApiServer(wo->apiServerKitContext,
|
324
|
-
wo->apiServerSchema);
|
325
|
-
wo->apiServer->controller = wo->controller;
|
326
|
-
wo->apiServer->apiAccountDatabase = &wo->apiAccountDatabase;
|
327
|
-
wo->apiServer->instanceDir = options.get("instance_dir", false);
|
328
|
-
wo->apiServer->fdPassingPassword = options.get("watchdog_fd_passing_password", false);
|
329
|
-
wo->apiServer->exitEvent = &wo->exitEvent;
|
330
|
-
wo->apiServer->shutdownFinishCallback = apiServerShutdownFinished;
|
331
|
-
wo->apiServer->initialize();
|
332
|
-
foreach (fd, wo->apiSockets) {
|
333
|
-
wo->apiServer->listen(fd);
|
334
|
-
}
|
335
|
-
}
|
336
|
-
|
337
|
-
UPDATE_TRACE_POINT();
|
338
|
-
ev_signal_init(&wo->sigquitWatcher, printInfo, SIGQUIT);
|
339
|
-
ev_signal_start(wo->bgloop->libev_loop, &wo->sigquitWatcher);
|
340
|
-
ev_signal_init(&wo->sigintWatcher, onTerminationSignal, SIGINT);
|
341
|
-
ev_signal_start(wo->bgloop->libev_loop, &wo->sigintWatcher);
|
342
|
-
ev_signal_init(&wo->sigtermWatcher, onTerminationSignal, SIGTERM);
|
343
|
-
ev_signal_start(wo->bgloop->libev_loop, &wo->sigtermWatcher);
|
344
|
-
}
|
345
|
-
|
346
|
-
static void
|
347
|
-
reportInitializationInfo() {
|
348
|
-
TRACE_POINT();
|
349
|
-
if (feedbackFdAvailable()) {
|
350
|
-
P_NOTICE(SHORT_PROGRAM_NAME " UstRouter online, PID " << getpid());
|
351
|
-
writeArrayMessage(FEEDBACK_FD,
|
352
|
-
"initialized",
|
353
|
-
NULL);
|
354
|
-
} else {
|
355
|
-
vector<string> apiAddresses = agentsOptions->getStrSet("ust_router_api_addresses", false);
|
356
|
-
|
357
|
-
P_NOTICE(SHORT_PROGRAM_NAME " UstRouter online, PID " << getpid()
|
358
|
-
<< ", listening on " << agentsOptions->get("ust_router_address"));
|
359
|
-
|
360
|
-
if (!apiAddresses.empty()) {
|
361
|
-
string address;
|
362
|
-
P_NOTICE("API server listening on " << apiAddresses.size() << " socket(s):");
|
363
|
-
foreach (address, apiAddresses) {
|
364
|
-
if (startsWith(address, "tcp://")) {
|
365
|
-
address.erase(0, sizeof("tcp://") - 1);
|
366
|
-
address.insert(0, "http://");
|
367
|
-
address.append("/");
|
368
|
-
}
|
369
|
-
P_NOTICE(" * " << address);
|
370
|
-
}
|
371
|
-
}
|
372
|
-
}
|
373
|
-
}
|
374
|
-
|
375
|
-
static void
|
376
|
-
printInfo(EV_P_ struct ev_signal *watcher, int revents) {
|
377
|
-
oxt::thread(printInfoInThread, "Information printer");
|
378
|
-
}
|
379
|
-
|
380
|
-
static void
|
381
|
-
inspectControllerStateAsJson(Controller *controller, string *result) {
|
382
|
-
*result = controller->inspectStateAsJson().toStyledString();
|
383
|
-
}
|
384
|
-
|
385
|
-
static void
|
386
|
-
getMbufStats(struct MemoryKit::mbuf_pool *input, struct MemoryKit::mbuf_pool *result) {
|
387
|
-
*result = *input;
|
388
|
-
}
|
389
|
-
|
390
|
-
static void
|
391
|
-
printInfoInThread() {
|
392
|
-
TRACE_POINT();
|
393
|
-
WorkingObjects *wo = workingObjects;
|
394
|
-
|
395
|
-
cerr << "### Backtraces\n";
|
396
|
-
cerr << "\n" << oxt::thread::all_backtraces();
|
397
|
-
cerr << "\n";
|
398
|
-
cerr.flush();
|
399
|
-
|
400
|
-
string json;
|
401
|
-
cerr << "### Controller state\n";
|
402
|
-
wo->bgloop->safe->runSync(boost::bind(inspectControllerStateAsJson,
|
403
|
-
wo->controller, &json));
|
404
|
-
cerr << json;
|
405
|
-
cerr << "\n";
|
406
|
-
cerr.flush();
|
407
|
-
|
408
|
-
struct MemoryKit::mbuf_pool stats;
|
409
|
-
cerr << "### mbuf stats\n\n";
|
410
|
-
wo->bgloop->safe->runSync(boost::bind(getMbufStats,
|
411
|
-
&wo->serverKitContext->mbuf_pool,
|
412
|
-
&stats));
|
413
|
-
cerr << "nfree_mbuf_blockq : " << stats.nfree_mbuf_blockq << "\n";
|
414
|
-
cerr << "nactive_mbuf_blockq : " << stats.nactive_mbuf_blockq << "\n";
|
415
|
-
cerr << "mbuf_block_chunk_size: " << stats.mbuf_block_chunk_size << "\n";
|
416
|
-
cerr << "\n";
|
417
|
-
cerr.flush();
|
418
|
-
}
|
419
|
-
|
420
|
-
static void
|
421
|
-
onTerminationSignal(EV_P_ struct ev_signal *watcher, int revents) {
|
422
|
-
WorkingObjects *wo = workingObjects;
|
423
|
-
|
424
|
-
// Start output after '^C'
|
425
|
-
printf("\n");
|
426
|
-
|
427
|
-
wo->terminationCount++;
|
428
|
-
if (wo->terminationCount < 3) {
|
429
|
-
P_NOTICE("Signal received. Gracefully shutting down... (send signal " <<
|
430
|
-
(3 - wo->terminationCount) << " more time(s) to force shutdown)");
|
431
|
-
workingObjects->exitEvent.notify();
|
432
|
-
} else {
|
433
|
-
P_NOTICE("Signal received. Forcing shutdown.");
|
434
|
-
_exit(2);
|
435
|
-
}
|
436
|
-
}
|
437
|
-
|
438
|
-
static void
|
439
|
-
mainLoop() {
|
440
|
-
workingObjects->bgloop->start("Main event loop", 0);
|
441
|
-
if (workingObjects->apiBgloop != NULL) {
|
442
|
-
workingObjects->apiBgloop->start("API event loop", 0);
|
443
|
-
}
|
444
|
-
waitForExitEvent();
|
445
|
-
}
|
446
|
-
|
447
|
-
static void
|
448
|
-
shutdownController() {
|
449
|
-
workingObjects->controller->shutdown();
|
450
|
-
}
|
451
|
-
|
452
|
-
static void
|
453
|
-
shutdownApiServer() {
|
454
|
-
workingObjects->apiServer->shutdown();
|
455
|
-
}
|
456
|
-
|
457
|
-
static void
|
458
|
-
apiServerShutdownFinished(UstRouter::ApiServer *server) {
|
459
|
-
workingObjects->allClientsDisconnectedEvent.notify();
|
460
|
-
}
|
461
|
-
|
462
|
-
/* Wait until the watchdog closes the feedback fd (meaning it
|
463
|
-
* was killed) or until we receive an exit message.
|
464
|
-
*/
|
465
|
-
static void
|
466
|
-
waitForExitEvent() {
|
467
|
-
boost::this_thread::disable_syscall_interruption dsi;
|
468
|
-
WorkingObjects *wo = workingObjects;
|
469
|
-
fd_set fds;
|
470
|
-
int largestFd = -1;
|
471
|
-
|
472
|
-
FD_ZERO(&fds);
|
473
|
-
if (feedbackFdAvailable()) {
|
474
|
-
FD_SET(FEEDBACK_FD, &fds);
|
475
|
-
largestFd = std::max(largestFd, FEEDBACK_FD);
|
476
|
-
}
|
477
|
-
FD_SET(wo->exitEvent.fd(), &fds);
|
478
|
-
largestFd = std::max(largestFd, wo->exitEvent.fd());
|
479
|
-
|
480
|
-
TRACE_POINT();
|
481
|
-
if (syscalls::select(largestFd + 1, &fds, NULL, NULL, NULL) == -1) {
|
482
|
-
int e = errno;
|
483
|
-
throw SystemException("select() failed", e);
|
484
|
-
}
|
485
|
-
|
486
|
-
if (FD_ISSET(FEEDBACK_FD, &fds)) {
|
487
|
-
UPDATE_TRACE_POINT();
|
488
|
-
/* If the watchdog has been killed then we'll exit. There's no
|
489
|
-
* point in keeping the UstRouter running because we can't
|
490
|
-
* detect when the web server exits, and because this logging
|
491
|
-
* agent doesn't own the instance directory. As soon as
|
492
|
-
* passenger-status is run, the instance directory will be
|
493
|
-
* cleaned up, making the server inaccessible.
|
494
|
-
*/
|
495
|
-
_exit(2);
|
496
|
-
} else {
|
497
|
-
UPDATE_TRACE_POINT();
|
498
|
-
/* We received an exit command. */
|
499
|
-
P_NOTICE("Received command to shutdown gracefully. "
|
500
|
-
"Waiting until all clients have disconnected...");
|
501
|
-
wo->bgloop->safe->runLater(shutdownController);
|
502
|
-
if (wo->apiBgloop != NULL) {
|
503
|
-
wo->apiBgloop->safe->runLater(shutdownApiServer);
|
504
|
-
}
|
505
|
-
|
506
|
-
UPDATE_TRACE_POINT();
|
507
|
-
FD_ZERO(&fds);
|
508
|
-
FD_SET(wo->allClientsDisconnectedEvent.fd(), &fds);
|
509
|
-
if (syscalls::select(wo->allClientsDisconnectedEvent.fd() + 1,
|
510
|
-
&fds, NULL, NULL, NULL) == -1)
|
511
|
-
{
|
512
|
-
int e = errno;
|
513
|
-
throw SystemException("select() failed", e);
|
514
|
-
}
|
515
|
-
|
516
|
-
P_INFO("All clients have now disconnected. Proceeding with graceful shutdown");
|
517
|
-
}
|
518
|
-
}
|
519
|
-
|
520
|
-
static void
|
521
|
-
cleanup() {
|
522
|
-
TRACE_POINT();
|
523
|
-
WorkingObjects *wo = workingObjects;
|
524
|
-
|
525
|
-
P_DEBUG("Shutting down " SHORT_PROGRAM_NAME " UstRouter...");
|
526
|
-
wo->bgloop->stop();
|
527
|
-
if (wo->apiServer != NULL) {
|
528
|
-
wo->apiBgloop->stop();
|
529
|
-
delete wo->apiServer;
|
530
|
-
}
|
531
|
-
P_NOTICE(SHORT_PROGRAM_NAME " UstRouter shutdown finished");
|
532
|
-
}
|
533
|
-
|
534
|
-
static int
|
535
|
-
runUstRouter() {
|
536
|
-
TRACE_POINT();
|
537
|
-
P_NOTICE("Starting " SHORT_PROGRAM_NAME " UstRouter...");
|
538
|
-
|
539
|
-
try {
|
540
|
-
UPDATE_TRACE_POINT();
|
541
|
-
initializePrivilegedWorkingObjects();
|
542
|
-
setUlimits();
|
543
|
-
startListening();
|
544
|
-
lowerPrivilege();
|
545
|
-
initializeUnprivilegedWorkingObjects();
|
546
|
-
|
547
|
-
UPDATE_TRACE_POINT();
|
548
|
-
reportInitializationInfo();
|
549
|
-
mainLoop();
|
550
|
-
|
551
|
-
UPDATE_TRACE_POINT();
|
552
|
-
cleanup();
|
553
|
-
} catch (const tracable_exception &e) {
|
554
|
-
P_ERROR("ERROR: " << e.what() << "\n" << e.backtrace());
|
555
|
-
return 1;
|
556
|
-
} catch (const std::runtime_error &e) {
|
557
|
-
P_CRITICAL("ERROR: " << e.what());
|
558
|
-
return 1;
|
559
|
-
}
|
560
|
-
|
561
|
-
return 0;
|
562
|
-
}
|
563
|
-
|
564
|
-
|
565
|
-
/***** Entry point and command line argument parsing *****/
|
566
|
-
|
567
|
-
static void
|
568
|
-
parseOptions(int argc, const char *argv[], VariantMap &options) {
|
569
|
-
OptionParser p(ustRouterUsage);
|
570
|
-
int i = 2;
|
571
|
-
|
572
|
-
while (i < argc) {
|
573
|
-
if (parseUstRouterOption(argc, argv, i, options)) {
|
574
|
-
continue;
|
575
|
-
} else if (p.isFlag(argv[i], 'h', "--help")) {
|
576
|
-
ustRouterUsage();
|
577
|
-
exit(0);
|
578
|
-
} else {
|
579
|
-
fprintf(stderr, "ERROR: unrecognized argument %s. Please type "
|
580
|
-
"'%s ust-router --help' for usage.\n", argv[i], argv[0]);
|
581
|
-
exit(1);
|
582
|
-
}
|
583
|
-
}
|
584
|
-
}
|
585
|
-
|
586
|
-
static void
|
587
|
-
preinitialize(VariantMap &options) {
|
588
|
-
// Set log_level here so that initializeAgent() calls setLogLevel()
|
589
|
-
// and setLogFile() with the right value.
|
590
|
-
if (options.has("ust_router_log_level")) {
|
591
|
-
options.setInt("log_level", options.getInt("ust_router_log_level"));
|
592
|
-
}
|
593
|
-
if (options.has("ust_router_log_file")) {
|
594
|
-
options.setInt("debug_log_file", options.getInt("ust_router_log_file"));
|
595
|
-
}
|
596
|
-
}
|
597
|
-
|
598
|
-
static void
|
599
|
-
setAgentsOptionsDefaults() {
|
600
|
-
VariantMap &options = *agentsOptions;
|
601
|
-
|
602
|
-
options.setDefault("ust_router_address", DEFAULT_UST_ROUTER_LISTEN_ADDRESS);
|
603
|
-
options.setDefault("ust_router_default_node_name", getHostName());
|
604
|
-
}
|
605
|
-
|
606
|
-
static void
|
607
|
-
sanityCheckOptions() {
|
608
|
-
VariantMap &options = *agentsOptions;
|
609
|
-
bool ok = true;
|
610
|
-
|
611
|
-
if (!options.has("passenger_root")) {
|
612
|
-
fprintf(stderr, "ERROR: please set the --passenger-root argument.\n");
|
613
|
-
ok = false;
|
614
|
-
}
|
615
|
-
|
616
|
-
if (!options.has("ust_router_password")
|
617
|
-
&& !options.has("ust_router_password_file"))
|
618
|
-
{
|
619
|
-
fprintf(stderr, "ERROR: please set the --password-file argument.\n");
|
620
|
-
ok = false;
|
621
|
-
}
|
622
|
-
|
623
|
-
if (options.getBool("ust_router_dev_mode", false, false)) {
|
624
|
-
if (!options.has("ust_router_dump_dir")) {
|
625
|
-
fprintf(stderr, "ERROR: if development mode is enabled, you must also set the --dump-dir argument.\n");
|
626
|
-
ok = false;
|
627
|
-
} else {
|
628
|
-
FileType ft = getFileType(options.get("ust_router_dump_dir"));
|
629
|
-
if (ft != FT_DIRECTORY) {
|
630
|
-
fprintf(stderr, "ERROR: '%s' is not a valid directory.\n",
|
631
|
-
options.get("ust_router_dump_dir").c_str());
|
632
|
-
ok = false;
|
633
|
-
}
|
634
|
-
}
|
635
|
-
}
|
636
|
-
|
637
|
-
// Sanity check user accounts
|
638
|
-
string user = options.get("analytics_log_user", false);
|
639
|
-
if (!user.empty()) {
|
640
|
-
struct passwd *pwUser = getpwnam(user.c_str());
|
641
|
-
if (pwUser == NULL) {
|
642
|
-
fprintf(stderr, "ERROR: the username specified by --user, '%s', does not exist.\n",
|
643
|
-
user.c_str());
|
644
|
-
ok = false;
|
645
|
-
}
|
646
|
-
|
647
|
-
string group = options.get("analytics_log_group", false);
|
648
|
-
if (!group.empty() && lookupGid(group) == (gid_t) -1) {
|
649
|
-
fprintf(stderr, "ERROR: the group name specified by --group, '%s', does not exist.\n",
|
650
|
-
group.c_str());
|
651
|
-
ok = false;
|
652
|
-
}
|
653
|
-
} else if (options.has("analytics_log_group")) {
|
654
|
-
fprintf(stderr, "ERROR: setting --group also requires you to set --user.\n");
|
655
|
-
ok = false;
|
656
|
-
}
|
657
|
-
|
658
|
-
if (!ok) {
|
659
|
-
exit(1);
|
660
|
-
}
|
661
|
-
}
|
662
|
-
|
663
|
-
int
|
664
|
-
ustRouterMain(int argc, char *argv[]) {
|
665
|
-
agentsOptions = new VariantMap();
|
666
|
-
*agentsOptions = initializeAgent(argc, &argv, SHORT_PROGRAM_NAME " ust-router",
|
667
|
-
parseOptions, preinitialize, 2);
|
668
|
-
|
669
|
-
CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
|
670
|
-
if (code != CURLE_OK) {
|
671
|
-
P_CRITICAL("ERROR: Could not initialize libcurl: " << curl_easy_strerror(code));
|
672
|
-
exit(1);
|
673
|
-
}
|
674
|
-
|
675
|
-
setAgentsOptionsDefaults();
|
676
|
-
sanityCheckOptions();
|
677
|
-
|
678
|
-
restoreOomScore(agentsOptions);
|
679
|
-
|
680
|
-
return runUstRouter();
|
681
|
-
}
|