passenger 4.0.48 → 4.0.49
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 +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.editorconfig +36 -2
- data/.travis.yml +1 -1
- data/CHANGELOG +16 -0
- data/Rakefile +0 -1
- data/build/apache2.rb +4 -4
- data/build/common_library.rb +18 -18
- data/build/cplusplus_support.rb +2 -2
- data/build/documentation.rb +1 -1
- data/build/integration_tests.rb +12 -4
- data/build/misc.rb +12 -7
- data/build/packaging.rb +14 -14
- data/build/preprocessor.rb +10 -10
- data/build/rake_extensions.rb +11 -11
- data/build/ruby_extension.rb +2 -2
- data/dev/ci/inituidgid +24 -0
- data/dev/ci/run_jenkins.sh +57 -0
- data/dev/ci/run_rpm_tests.sh +77 -0
- data/dev/{run_travis.sh → ci/run_travis.sh} +60 -4
- data/doc/Users guide Nginx.txt +2 -2
- data/doc/users_guide_snippets/environment_variables.txt +0 -2
- data/doc/users_guide_snippets/tips.txt +20 -1
- data/ext/apache2/Bucket.cpp +18 -18
- data/ext/apache2/Bucket.h +4 -4
- data/ext/apache2/Configuration.cpp +7 -7
- data/ext/apache2/Configuration.hpp +43 -43
- data/ext/apache2/DirectoryMapper.h +5 -5
- data/ext/apache2/Hooks.cpp +142 -142
- data/ext/apache2/MergeDirConfig.cpp +40 -40
- data/ext/common/Account.h +17 -17
- data/ext/common/AccountsDatabase.h +9 -9
- data/ext/common/AgentsStarter.cpp +2 -2
- data/ext/common/AgentsStarter.h +40 -40
- data/ext/common/ApplicationPool2/Common.h +10 -6
- data/ext/common/ApplicationPool2/ComponentInfo.h +2 -2
- data/ext/common/ApplicationPool2/DirectSpawner.h +17 -17
- data/ext/common/ApplicationPool2/DummySpawner.h +5 -5
- data/ext/common/ApplicationPool2/Group.h +54 -38
- data/ext/common/ApplicationPool2/Implementation.cpp +76 -49
- data/ext/common/ApplicationPool2/Options.h +98 -91
- data/ext/common/ApplicationPool2/Pool.h +70 -69
- data/ext/common/ApplicationPool2/Process.h +21 -21
- data/ext/common/ApplicationPool2/Session.h +11 -11
- data/ext/common/ApplicationPool2/SmartSpawner.h +60 -60
- data/ext/common/ApplicationPool2/Socket.h +19 -19
- data/ext/common/ApplicationPool2/Spawner.h +64 -72
- data/ext/common/ApplicationPool2/SpawnerFactory.h +4 -4
- data/ext/common/ApplicationPool2/SuperGroup.h +41 -41
- data/ext/common/BackgroundEventLoop.cpp +1 -1
- data/ext/common/BackgroundEventLoop.h +2 -2
- data/ext/common/Constants.h +1 -1
- data/ext/common/EventedBufferedInput.h +5 -5
- data/ext/common/EventedClient.h +51 -51
- data/ext/common/EventedMessageServer.h +39 -39
- data/ext/common/EventedServer.h +32 -32
- data/ext/common/Exceptions.h +23 -23
- data/ext/common/FileDescriptor.h +18 -18
- data/ext/common/Logging.cpp +1 -1
- data/ext/common/MessageClient.h +27 -27
- data/ext/common/MessageReadersWriters.h +79 -79
- data/ext/common/MessageServer.h +59 -59
- data/ext/common/RandomGenerator.h +12 -12
- data/ext/common/ResourceLocator.h +8 -8
- data/ext/common/SafeLibev.h +54 -25
- data/ext/common/ServerInstanceDir.h +31 -31
- data/ext/common/StaticString.h +50 -48
- data/ext/common/Utils.cpp +73 -78
- data/ext/common/Utils.h +6 -6
- data/ext/common/Utils/Base64.cpp +3 -3
- data/ext/common/Utils/Base64.h +7 -7
- data/ext/common/Utils/BlockingQueue.h +9 -9
- data/ext/common/Utils/BufferedIO.h +17 -17
- data/ext/common/Utils/CachedFileStat.hpp +16 -16
- data/ext/common/Utils/Dechunker.h +25 -25
- data/ext/common/Utils/FileChangeChecker.h +10 -10
- data/ext/common/Utils/MemZeroGuard.h +5 -5
- data/ext/common/Utils/MemoryBarrier.h +1 -1
- data/ext/common/Utils/MessageIO.h +61 -61
- data/ext/common/Utils/ProcessMetricsCollector.h +40 -40
- data/ext/common/Utils/ScopeGuard.h +7 -7
- data/ext/common/Utils/SpeedMeter.h +1 -1
- data/ext/common/Utils/StrIntUtils.cpp +13 -13
- data/ext/common/Utils/StrIntUtils.h +3 -3
- data/ext/common/Utils/StringScanning.h +5 -5
- data/ext/common/Utils/SystemMetricsCollector.h +2 -2
- data/ext/common/Utils/SystemTime.h +10 -10
- data/ext/common/Utils/Template.h +2 -2
- data/ext/common/Utils/Timer.h +6 -6
- data/ext/common/Utils/VariantMap.h +29 -29
- data/ext/common/agents/Base.cpp +19 -19
- data/ext/common/agents/HelperAgent/AgentOptions.h +1 -1
- data/ext/common/agents/HelperAgent/FileBackedPipe.h +6 -6
- data/ext/common/agents/HelperAgent/Main.cpp +44 -43
- data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +29 -28
- data/ext/common/agents/HelperAgent/ScgiRequestParser.h +56 -50
- data/ext/common/agents/LoggingAgent/AdminController.h +8 -8
- data/ext/common/agents/LoggingAgent/DataStoreId.h +17 -17
- data/ext/common/agents/LoggingAgent/FilterSupport.h +167 -167
- data/ext/common/agents/LoggingAgent/LoggingServer.h +122 -122
- data/ext/common/agents/LoggingAgent/Main.cpp +7 -7
- data/ext/common/agents/LoggingAgent/RemoteSender.h +54 -54
- data/ext/common/agents/SpawnPreparer.cpp +4 -4
- data/ext/common/agents/TempDirToucher.c +2 -2
- data/ext/common/agents/Watchdog/AgentWatcher.cpp +47 -47
- data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/Main.cpp +22 -22
- data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +9 -9
- data/ext/libeio/eio.c +1 -1
- data/ext/nginx/Configuration.c +30 -30
- data/ext/nginx/Configuration.h +1 -1
- data/ext/nginx/ContentHandler.c +54 -54
- data/ext/nginx/ContentHandler.h +3 -3
- data/ext/nginx/StaticContentHandler.c +2 -2
- data/ext/nginx/ngx_http_passenger_module.c +21 -21
- data/ext/oxt/detail/backtrace_enabled.hpp +1 -1
- data/ext/oxt/detail/context.hpp +1 -1
- data/ext/oxt/detail/spin_lock_darwin.hpp +4 -4
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -3
- data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
- data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
- data/ext/oxt/dynamic_thread_group.hpp +18 -18
- data/ext/oxt/implementation.cpp +9 -8
- data/ext/oxt/macros.hpp +2 -2
- data/ext/oxt/system_calls.cpp +11 -11
- data/ext/oxt/system_calls.hpp +13 -13
- data/ext/oxt/thread.hpp +22 -14
- data/ext/ruby/passenger_native_support.c +55 -55
- data/lib/phusion_passenger.rb +24 -24
- data/lib/phusion_passenger/common_library.rb +2 -0
- data/lib/phusion_passenger/loader_shared_helpers.rb +18 -18
- data/lib/phusion_passenger/packaging.rb +9 -4
- data/lib/phusion_passenger/platform_info/apache.rb +45 -31
- data/lib/phusion_passenger/platform_info/compiler.rb +11 -11
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
- data/lib/phusion_passenger/request_handler/thread_handler.rb +8 -8
- data/lib/phusion_passenger/standalone/app_finder.rb +16 -16
- data/lib/phusion_passenger/standalone/command.rb +22 -22
- data/packaging/rpm/LICENSE.txt +19 -0
- data/packaging/rpm/Makefile +13 -0
- data/packaging/rpm/README.md +41 -0
- data/packaging/rpm/Vagrantfile +38 -0
- data/{rpm/Vagrantfile → packaging/rpm/Vagrantfile.centos} +0 -0
- data/packaging/rpm/build +170 -0
- data/packaging/rpm/create_project +41 -0
- data/packaging/rpm/git_update +88 -0
- data/packaging/rpm/image/Dockerfile +37 -0
- data/packaging/rpm/image/Gemfile +3 -0
- data/packaging/rpm/image/Gemfile.lock +12 -0
- data/packaging/rpm/image/RPM-GPG-KEY-amazon-ga +19 -0
- data/packaging/rpm/image/amazon2014-i386.cfg +96 -0
- data/packaging/rpm/image/amazon2014-x86_64.cfg +96 -0
- data/packaging/rpm/image/site-defaults.cfg +168 -0
- data/packaging/rpm/internal/build_tasks.rb +238 -0
- data/packaging/rpm/internal/dummygpg +11 -0
- data/packaging/rpm/internal/exec_build +42 -0
- data/packaging/rpm/internal/get_distro_arch +14 -0
- data/packaging/rpm/internal/get_distro_id +10 -0
- data/packaging/rpm/internal/git_update +27 -0
- data/packaging/rpm/internal/inituidgid +17 -0
- data/packaging/rpm/internal/my_init +344 -0
- data/packaging/rpm/internal/python27 +3 -0
- data/packaging/rpm/internal/repo_update +46 -0
- data/packaging/rpm/internal/setuser +26 -0
- data/packaging/rpm/internal/tracking_helper +40 -0
- data/packaging/rpm/jenkins_release +99 -0
- data/packaging/rpm/lib/build_tasks_support.rb +402 -0
- data/packaging/rpm/lib/preprocessor.rb +341 -0
- data/packaging/rpm/nginx_spec/404.html +119 -0
- data/packaging/rpm/nginx_spec/50x.html +119 -0
- data/packaging/rpm/nginx_spec/index.html +116 -0
- data/packaging/rpm/nginx_spec/nginx-auto-cc-gcc.patch +13 -0
- data/packaging/rpm/nginx_spec/nginx-logo.png +0 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade +13 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade.8 +151 -0
- data/packaging/rpm/nginx_spec/nginx.conf +131 -0
- data/packaging/rpm/nginx_spec/nginx.init +144 -0
- data/packaging/rpm/nginx_spec/nginx.logrotate +13 -0
- data/packaging/rpm/nginx_spec/nginx.service +15 -0
- data/packaging/rpm/nginx_spec/nginx.spec.template +559 -0
- data/packaging/rpm/nginx_spec/nginx.sysconfig +4 -0
- data/packaging/rpm/nginx_spec/passenger.conf +9 -0
- data/packaging/rpm/nginx_spec/poweredby.png +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/apache-passenger.conf.in +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/config.json +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.logrotate +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.spec.template +58 -31
- data/{rpm → packaging/rpm/passenger_spec}/passenger_dynamic_thread_group.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger_tests_default_config_example.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +0 -0
- data/packaging/rpm/repo_update +114 -0
- data/packaging/rpm/setup-system +60 -0
- data/packaging/rpm/shell +10 -0
- data/resources/templates/standalone/config.erb +3 -1
- data/test/config.json.rpm-automation +1 -1
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +11 -11
- data/test/cxx/ApplicationPool2/OptionsTest.cpp +5 -5
- data/test/cxx/ApplicationPool2/PoolTest.cpp +129 -89
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +15 -15
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +22 -22
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +11 -11
- data/test/cxx/ScgiRequestParserTest.cpp +75 -61
- data/test/cxx/UtilsTest.cpp +86 -85
- data/test/gdbinit.example +3 -0
- data/test/integration_tests/nginx_tests.rb +3 -3
- data/test/integration_tests/source_packaging_test.rb +3 -1
- data/test/stub/nginx/nginx.conf.erb +8 -1
- data/test/support/nginx_controller.rb +7 -7
- metadata +62 -17
- metadata.gz.asc +7 -7
- data/build/rpm.rb +0 -128
- data/dev/rpmtool +0 -21
- data/dev/test_rpm_packaging.sh +0 -28
- data/rpm/get_distro_id.py +0 -4
@@ -59,24 +59,24 @@ private:
|
|
59
59
|
string filename;
|
60
60
|
time_t lastMtime;
|
61
61
|
time_t lastCtime;
|
62
|
-
|
62
|
+
|
63
63
|
Entry(const string &filename) {
|
64
64
|
this->filename = filename;
|
65
65
|
this->lastMtime = 0;
|
66
66
|
this->lastCtime = 0;
|
67
67
|
}
|
68
68
|
};
|
69
|
-
|
69
|
+
|
70
70
|
typedef boost::shared_ptr<Entry> EntryPtr;
|
71
71
|
typedef list<EntryPtr> EntryList;
|
72
72
|
typedef map<string, EntryList::iterator> EntryMap;
|
73
|
-
|
73
|
+
|
74
74
|
CachedFileStat cstat;
|
75
75
|
mutable boost::mutex lock;
|
76
76
|
unsigned int maxSize;
|
77
77
|
EntryList entries;
|
78
78
|
EntryMap fileToEntry;
|
79
|
-
|
79
|
+
|
80
80
|
public:
|
81
81
|
/**
|
82
82
|
* Create a FileChangeChecker object.
|
@@ -88,7 +88,7 @@ public:
|
|
88
88
|
{
|
89
89
|
this->maxSize = maxSize;
|
90
90
|
}
|
91
|
-
|
91
|
+
|
92
92
|
/**
|
93
93
|
* Checks whether, since the last call to changed() with this filename,
|
94
94
|
* the file's timestamp has changed or whether the file has been created
|
@@ -119,7 +119,7 @@ public:
|
|
119
119
|
struct stat buf;
|
120
120
|
bool result, newEntry = false;
|
121
121
|
int ret;
|
122
|
-
|
122
|
+
|
123
123
|
if (it == fileToEntry.end()) {
|
124
124
|
// Filename not in file list.
|
125
125
|
// If file list is full, remove the least recently used
|
@@ -131,7 +131,7 @@ public:
|
|
131
131
|
entries.pop_back();
|
132
132
|
fileToEntry.erase(filename);
|
133
133
|
}
|
134
|
-
|
134
|
+
|
135
135
|
// Add to file list as most recently used.
|
136
136
|
entry = EntryPtr(new Entry(filename));
|
137
137
|
entries.push_front(entry);
|
@@ -140,13 +140,13 @@ public:
|
|
140
140
|
} else {
|
141
141
|
// Filename is in file list.
|
142
142
|
entry = *it->second;
|
143
|
-
|
143
|
+
|
144
144
|
// Mark this entry as most recently used.
|
145
145
|
entries.erase(it->second);
|
146
146
|
entries.push_front(entry);
|
147
147
|
fileToEntry[filename] = entries.begin();
|
148
148
|
}
|
149
|
-
|
149
|
+
|
150
150
|
ret = cstat.stat(filename, &buf, throttleRate);
|
151
151
|
if (newEntry) {
|
152
152
|
// The file's information isn't in the file list.
|
@@ -194,7 +194,7 @@ public:
|
|
194
194
|
this->maxSize = maxSize;
|
195
195
|
cstat.setMaxSize(maxSize);
|
196
196
|
}
|
197
|
-
|
197
|
+
|
198
198
|
/**
|
199
199
|
* Returns whether <tt>filename</tt> is in the internal file list.
|
200
200
|
*/
|
@@ -42,7 +42,7 @@ private:
|
|
42
42
|
void *data;
|
43
43
|
unsigned int size;
|
44
44
|
string *str;
|
45
|
-
|
45
|
+
|
46
46
|
static void securelyZeroMemory(volatile void *data, unsigned int size) {
|
47
47
|
/* We do not use memset() here because the compiler may
|
48
48
|
* optimize out memset() calls. Instead, the following
|
@@ -54,7 +54,7 @@ private:
|
|
54
54
|
*p++ = 0;
|
55
55
|
}
|
56
56
|
}
|
57
|
-
|
57
|
+
|
58
58
|
public:
|
59
59
|
/**
|
60
60
|
* Creates a new MemZeroGuard object with a memory region to zero.
|
@@ -68,7 +68,7 @@ public:
|
|
68
68
|
this->size = size;
|
69
69
|
this->str = NULL;
|
70
70
|
}
|
71
|
-
|
71
|
+
|
72
72
|
/**
|
73
73
|
* Creates a new MemoryZeroGuard object with a string to zero.
|
74
74
|
*
|
@@ -79,7 +79,7 @@ public:
|
|
79
79
|
this->size = 0;
|
80
80
|
this->str = &str;
|
81
81
|
}
|
82
|
-
|
82
|
+
|
83
83
|
/**
|
84
84
|
* Zero the data immediately. The data will still be zeroed after
|
85
85
|
* destruction of this object.
|
@@ -91,7 +91,7 @@ public:
|
|
91
91
|
securelyZeroMemory((volatile void *) str->c_str(), str->size());
|
92
92
|
}
|
93
93
|
}
|
94
|
-
|
94
|
+
|
95
95
|
~MemZeroGuard() {
|
96
96
|
zeroNow();
|
97
97
|
}
|
@@ -40,7 +40,7 @@
|
|
40
40
|
#define P_WRITE_BARRIER() \
|
41
41
|
do { __asm__ __volatile__ ("lock; addl $0,0(%%esp)" ::: "memory"); } while (false)
|
42
42
|
#endif
|
43
|
-
|
43
|
+
|
44
44
|
#elif defined(__x86_64__)
|
45
45
|
#define P_READ_BARRIER() \
|
46
46
|
do { __asm__ __volatile__ ("lfence" ::: "memory"); } while (false)
|
@@ -118,10 +118,10 @@ using namespace boost;
|
|
118
118
|
* @throws boost::thread_interrupted
|
119
119
|
*/
|
120
120
|
inline bool
|
121
|
-
readUint16(int fd, uint16_t &output, unsigned long long *timeout = NULL) {
|
122
|
-
uint16_t temp;
|
123
|
-
|
124
|
-
if (readExact(fd, &temp, sizeof(uint16_t), timeout) == sizeof(uint16_t)) {
|
121
|
+
readUint16(int fd, boost::uint16_t &output, unsigned long long *timeout = NULL) {
|
122
|
+
boost::uint16_t temp;
|
123
|
+
|
124
|
+
if (readExact(fd, &temp, sizeof(boost::uint16_t), timeout) == sizeof(boost::uint16_t)) {
|
125
125
|
output = ntohs(temp);
|
126
126
|
return true;
|
127
127
|
} else {
|
@@ -145,10 +145,10 @@ readUint16(int fd, uint16_t &output, unsigned long long *timeout = NULL) {
|
|
145
145
|
* <tt>timeout</tt> microseconds.
|
146
146
|
* @throws boost::thread_interrupted
|
147
147
|
*/
|
148
|
-
inline uint16_t
|
148
|
+
inline boost::uint16_t
|
149
149
|
readUint16(int fd, unsigned long long *timeout = NULL) {
|
150
|
-
uint16_t temp;
|
151
|
-
|
150
|
+
boost::uint16_t temp;
|
151
|
+
|
152
152
|
if (readUint16(fd, temp, timeout)) {
|
153
153
|
return temp;
|
154
154
|
} else {
|
@@ -174,10 +174,10 @@ readUint16(int fd, unsigned long long *timeout = NULL) {
|
|
174
174
|
* @throws boost::thread_interrupted
|
175
175
|
*/
|
176
176
|
inline bool
|
177
|
-
readUint32(int fd, uint32_t &output, unsigned long long *timeout = NULL) {
|
178
|
-
uint32_t temp;
|
179
|
-
|
180
|
-
if (readExact(fd, &temp, sizeof(uint32_t), timeout) == sizeof(uint32_t)) {
|
177
|
+
readUint32(int fd, boost::uint32_t &output, unsigned long long *timeout = NULL) {
|
178
|
+
boost::uint32_t temp;
|
179
|
+
|
180
|
+
if (readExact(fd, &temp, sizeof(boost::uint32_t), timeout) == sizeof(boost::uint32_t)) {
|
181
181
|
output = ntohl(temp);
|
182
182
|
return true;
|
183
183
|
} else {
|
@@ -201,10 +201,10 @@ readUint32(int fd, uint32_t &output, unsigned long long *timeout = NULL) {
|
|
201
201
|
* <tt>timeout</tt> microseconds.
|
202
202
|
* @throws boost::thread_interrupted
|
203
203
|
*/
|
204
|
-
inline uint32_t
|
204
|
+
inline boost::uint32_t
|
205
205
|
readUint32(int fd, unsigned long long *timeout = NULL) {
|
206
|
-
uint32_t temp;
|
207
|
-
|
206
|
+
boost::uint32_t temp;
|
207
|
+
|
208
208
|
if (readUint32(fd, temp, timeout)) {
|
209
209
|
return temp;
|
210
210
|
} else {
|
@@ -235,17 +235,17 @@ readUint32(int fd, unsigned long long *timeout = NULL) {
|
|
235
235
|
template<typename Collection>
|
236
236
|
inline bool
|
237
237
|
readArrayMessage(int fd, Collection &output, unsigned long long *timeout = NULL) {
|
238
|
-
uint16_t size;
|
238
|
+
boost::uint16_t size;
|
239
239
|
if (!readUint16(fd, size, timeout)) {
|
240
240
|
return false;
|
241
241
|
}
|
242
|
-
|
242
|
+
|
243
243
|
scoped_array<char> buffer(new char[size]);
|
244
244
|
MemZeroGuard g(buffer.get(), size);
|
245
245
|
if (readExact(fd, buffer.get(), size, timeout) != size) {
|
246
246
|
return false;
|
247
247
|
}
|
248
|
-
|
248
|
+
|
249
249
|
output.clear();
|
250
250
|
if (size != 0) {
|
251
251
|
string::size_type start = 0, pos;
|
@@ -278,7 +278,7 @@ readArrayMessage(int fd, Collection &output, unsigned long long *timeout = NULL)
|
|
278
278
|
inline vector<string>
|
279
279
|
readArrayMessage(int fd, unsigned long long *timeout = NULL) {
|
280
280
|
vector<string> output;
|
281
|
-
|
281
|
+
|
282
282
|
if (readArrayMessage(fd, output, timeout)) {
|
283
283
|
return output;
|
284
284
|
} else {
|
@@ -309,15 +309,15 @@ readArrayMessage(int fd, unsigned long long *timeout = NULL) {
|
|
309
309
|
*/
|
310
310
|
inline bool
|
311
311
|
readScalarMessage(int fd, string &output, unsigned int maxSize = 0, unsigned long long *timeout = NULL) {
|
312
|
-
uint32_t size;
|
312
|
+
boost::uint32_t size;
|
313
313
|
if (!readUint32(fd, size, timeout)) {
|
314
314
|
return false;
|
315
315
|
}
|
316
|
-
|
317
|
-
if (maxSize != 0 && size > (uint32_t) maxSize) {
|
316
|
+
|
317
|
+
if (maxSize != 0 && size > (boost::uint32_t) maxSize) {
|
318
318
|
throw SecurityException("The scalar message body is larger than the size limit");
|
319
319
|
}
|
320
|
-
|
320
|
+
|
321
321
|
unsigned int remaining = size;
|
322
322
|
if (OXT_UNLIKELY(!output.empty())) {
|
323
323
|
output.clear();
|
@@ -326,10 +326,10 @@ readScalarMessage(int fd, string &output, unsigned int maxSize = 0, unsigned lon
|
|
326
326
|
if (OXT_LIKELY(remaining > 0)) {
|
327
327
|
char buf[1024 * 32];
|
328
328
|
MemZeroGuard g(buf, sizeof(buf));
|
329
|
-
|
329
|
+
|
330
330
|
while (remaining > 0) {
|
331
331
|
unsigned int blockSize = min((unsigned int) sizeof(buf), remaining);
|
332
|
-
|
332
|
+
|
333
333
|
if (readExact(fd, buf, blockSize, timeout) != blockSize) {
|
334
334
|
return false;
|
335
335
|
}
|
@@ -387,9 +387,9 @@ readScalarMessage(int fd, unsigned int maxSize = 0, unsigned long long *timeout
|
|
387
387
|
* @throws boost::thread_interrupted
|
388
388
|
*/
|
389
389
|
inline void
|
390
|
-
writeUint16(int fd, uint16_t value, unsigned long long *timeout = NULL) {
|
391
|
-
uint16_t l = htons(value);
|
392
|
-
writeExact(fd, &l, sizeof(uint16_t), timeout);
|
390
|
+
writeUint16(int fd, boost::uint16_t value, unsigned long long *timeout = NULL) {
|
391
|
+
boost::uint16_t l = htons(value);
|
392
|
+
writeExact(fd, &l, sizeof(boost::uint16_t), timeout);
|
393
393
|
}
|
394
394
|
|
395
395
|
/**
|
@@ -408,9 +408,9 @@ writeUint16(int fd, uint16_t value, unsigned long long *timeout = NULL) {
|
|
408
408
|
* @throws boost::thread_interrupted
|
409
409
|
*/
|
410
410
|
inline void
|
411
|
-
writeUint32(int fd, uint32_t value, unsigned long long *timeout = NULL) {
|
412
|
-
uint32_t l = htonl(value);
|
413
|
-
writeExact(fd, &l, sizeof(uint32_t), timeout);
|
411
|
+
writeUint32(int fd, boost::uint32_t value, unsigned long long *timeout = NULL) {
|
412
|
+
boost::uint32_t l = htonl(value);
|
413
|
+
writeExact(fd, &l, sizeof(boost::uint32_t), timeout);
|
414
414
|
}
|
415
415
|
|
416
416
|
|
@@ -436,25 +436,25 @@ template<typename Collection>
|
|
436
436
|
inline void
|
437
437
|
writeArrayMessageEx(int fd, const Collection &args, unsigned long long *timeout = NULL) {
|
438
438
|
typename Collection::const_iterator it, end = args.end();
|
439
|
-
uint16_t bodySize = 0;
|
440
|
-
|
439
|
+
boost::uint16_t bodySize = 0;
|
440
|
+
|
441
441
|
for (it = args.begin(); it != end; it++) {
|
442
442
|
bodySize += it->size() + 1;
|
443
443
|
}
|
444
|
-
|
445
|
-
scoped_array<char> data(new char[sizeof(uint16_t) + bodySize]);
|
446
|
-
uint16_t header = htons(bodySize);
|
447
|
-
memcpy(data.get(), &header, sizeof(uint16_t));
|
448
|
-
|
449
|
-
char *dataEnd = data.get() + sizeof(uint16_t);
|
444
|
+
|
445
|
+
scoped_array<char> data(new char[sizeof(boost::uint16_t) + bodySize]);
|
446
|
+
boost::uint16_t header = htons(bodySize);
|
447
|
+
memcpy(data.get(), &header, sizeof(boost::uint16_t));
|
448
|
+
|
449
|
+
char *dataEnd = data.get() + sizeof(boost::uint16_t);
|
450
450
|
for (it = args.begin(); it != end; it++) {
|
451
451
|
memcpy(dataEnd, it->data(), it->size());
|
452
452
|
dataEnd += it->size();
|
453
453
|
*dataEnd = '\0';
|
454
454
|
dataEnd++;
|
455
455
|
}
|
456
|
-
|
457
|
-
writeExact(fd, data.get(), sizeof(uint16_t) + bodySize, timeout);
|
456
|
+
|
457
|
+
writeExact(fd, data.get(), sizeof(boost::uint16_t) + bodySize, timeout);
|
458
458
|
}
|
459
459
|
|
460
460
|
inline void
|
@@ -470,25 +470,25 @@ writeArrayMessage(int fd, const vector<string> &args, unsigned long long *timeou
|
|
470
470
|
inline void
|
471
471
|
writeArrayMessage(int fd, const StaticString args[], unsigned int nargs, unsigned long long *timeout = NULL) {
|
472
472
|
unsigned int i;
|
473
|
-
uint16_t bodySize = 0;
|
474
|
-
|
473
|
+
boost::uint16_t bodySize = 0;
|
474
|
+
|
475
475
|
for (i = 0; i < nargs; i++) {
|
476
476
|
bodySize += args[i].size() + 1;
|
477
477
|
}
|
478
|
-
|
479
|
-
scoped_array<char> data(new char[sizeof(uint16_t) + bodySize]);
|
480
|
-
uint16_t header = htons(bodySize);
|
481
|
-
memcpy(data.get(), &header, sizeof(uint16_t));
|
482
|
-
|
483
|
-
char *dataEnd = data.get() + sizeof(uint16_t);
|
478
|
+
|
479
|
+
scoped_array<char> data(new char[sizeof(boost::uint16_t) + bodySize]);
|
480
|
+
boost::uint16_t header = htons(bodySize);
|
481
|
+
memcpy(data.get(), &header, sizeof(boost::uint16_t));
|
482
|
+
|
483
|
+
char *dataEnd = data.get() + sizeof(boost::uint16_t);
|
484
484
|
for (i = 0; i < nargs; i++) {
|
485
485
|
memcpy(dataEnd, args[i].data(), args[i].size());
|
486
486
|
dataEnd += args[i].size();
|
487
487
|
*dataEnd = '\0';
|
488
488
|
dataEnd++;
|
489
489
|
}
|
490
|
-
|
491
|
-
writeExact(fd, data.get(), sizeof(uint16_t) + bodySize, timeout);
|
490
|
+
|
491
|
+
writeExact(fd, data.get(), sizeof(boost::uint16_t) + bodySize, timeout);
|
492
492
|
}
|
493
493
|
|
494
494
|
inline void
|
@@ -496,7 +496,7 @@ writeArrayMessageVA(int fd, const StaticString &name, va_list &ap, unsigned long
|
|
496
496
|
StaticString args[10];
|
497
497
|
unsigned int nargs = 1;
|
498
498
|
bool done = false;
|
499
|
-
|
499
|
+
|
500
500
|
args[0] = name;
|
501
501
|
do {
|
502
502
|
const char *arg = va_arg(ap, const char *);
|
@@ -507,14 +507,14 @@ writeArrayMessageVA(int fd, const StaticString &name, va_list &ap, unsigned long
|
|
507
507
|
nargs++;
|
508
508
|
}
|
509
509
|
} while (!done && nargs < sizeof(args) / sizeof(StaticString));
|
510
|
-
|
510
|
+
|
511
511
|
if (done) {
|
512
512
|
writeArrayMessage(fd, args, nargs, timeout);
|
513
513
|
} else {
|
514
514
|
// Arguments don't fit in static array. Use dynamic
|
515
515
|
// array instead.
|
516
516
|
vector<StaticString> dyn_args;
|
517
|
-
|
517
|
+
|
518
518
|
for (unsigned int i = 0; i < nargs; i++) {
|
519
519
|
dyn_args.push_back(args[i]);
|
520
520
|
}
|
@@ -526,18 +526,18 @@ writeArrayMessageVA(int fd, const StaticString &name, va_list &ap, unsigned long
|
|
526
526
|
dyn_args.push_back(arg);
|
527
527
|
}
|
528
528
|
} while (!done);
|
529
|
-
|
529
|
+
|
530
530
|
writeArrayMessage(fd, dyn_args, timeout);
|
531
531
|
}
|
532
532
|
}
|
533
533
|
|
534
534
|
struct _VaGuard {
|
535
535
|
va_list ≈
|
536
|
-
|
536
|
+
|
537
537
|
_VaGuard(va_list &_ap)
|
538
538
|
: ap(_ap)
|
539
539
|
{ }
|
540
|
-
|
540
|
+
|
541
541
|
~_VaGuard() {
|
542
542
|
va_end(ap);
|
543
543
|
}
|
@@ -583,9 +583,9 @@ writeArrayMessage(int fd, unsigned long long *timeout, const char *name, ...) {
|
|
583
583
|
*/
|
584
584
|
inline void
|
585
585
|
writeScalarMessage(int fd, const StaticString &data, unsigned long long *timeout = NULL) {
|
586
|
-
uint32_t header = htonl(data.size());
|
586
|
+
boost::uint32_t header = htonl(data.size());
|
587
587
|
StaticString buffers[2] = {
|
588
|
-
StaticString((const char *) &header, sizeof(uint32_t)),
|
588
|
+
StaticString((const char *) &header, sizeof(boost::uint32_t)),
|
589
589
|
data
|
590
590
|
};
|
591
591
|
gatheredWrite(fd, buffers, 2, timeout);
|
@@ -646,14 +646,14 @@ readFileDescriptorWithNegotiation(int fd, unsigned long long *timeout = NULL) {
|
|
646
646
|
inline void
|
647
647
|
writeFileDescriptorWithNegotiation(int fd, int fdToPass, unsigned long long *timeout = NULL) {
|
648
648
|
vector<string> args;
|
649
|
-
|
649
|
+
|
650
650
|
args = readArrayMessage(fd, timeout);
|
651
651
|
if (args.size() != 1 || args[0] != "pass IO") {
|
652
652
|
throw IOException("FD passing pre-negotiation message expected");
|
653
653
|
}
|
654
|
-
|
654
|
+
|
655
655
|
writeFileDescriptor(fd, fdToPass, timeout);
|
656
|
-
|
656
|
+
|
657
657
|
args = readArrayMessage(fd, timeout);
|
658
658
|
if (args.size() != 1 || args[0] != "got IO") {
|
659
659
|
throw IOException("FD passing post-negotiation message expected.");
|
@@ -74,7 +74,7 @@ using namespace oxt;
|
|
74
74
|
struct ProcessMetrics {
|
75
75
|
pid_t pid;
|
76
76
|
pid_t ppid;
|
77
|
-
uint8_t cpu;
|
77
|
+
boost::uint8_t cpu;
|
78
78
|
/** Resident Set Size, amount of memory in RAM. Does not include swap.
|
79
79
|
* -1 if not yet known, 0 if completely swapped out.
|
80
80
|
*/
|
@@ -96,7 +96,7 @@ struct ProcessMetrics {
|
|
96
96
|
pid_t processGroupId;
|
97
97
|
uid_t uid;
|
98
98
|
string command;
|
99
|
-
|
99
|
+
|
100
100
|
ProcessMetrics() {
|
101
101
|
pid = (pid_t) -1;
|
102
102
|
rss = -1;
|
@@ -105,11 +105,11 @@ struct ProcessMetrics {
|
|
105
105
|
swap = -1;
|
106
106
|
vmsize = -1;
|
107
107
|
}
|
108
|
-
|
108
|
+
|
109
109
|
bool isValid() const {
|
110
110
|
return pid != (pid_t) -1;
|
111
111
|
}
|
112
|
-
|
112
|
+
|
113
113
|
/**
|
114
114
|
* Returns an estimate of the "real" memory usage of a process in KB.
|
115
115
|
* We don't use the PSS here because that would mean if another
|
@@ -148,33 +148,33 @@ public:
|
|
148
148
|
size_t totalMemory(ssize_t &shared) const {
|
149
149
|
const_iterator it, end = this->end();
|
150
150
|
bool pssAndPrivateDirtyAvailable = true;
|
151
|
-
|
151
|
+
|
152
152
|
for (it = begin(); it != end && pssAndPrivateDirtyAvailable; it++) {
|
153
153
|
const ProcessMetrics &metric = it->second;
|
154
154
|
pssAndPrivateDirtyAvailable = pssAndPrivateDirtyAvailable &&
|
155
155
|
metric.pss != -1 && metric.privateDirty != -1;
|
156
156
|
}
|
157
|
-
|
157
|
+
|
158
158
|
if (pssAndPrivateDirtyAvailable) {
|
159
159
|
size_t total = 0;
|
160
160
|
size_t priv = 0;
|
161
|
-
|
161
|
+
|
162
162
|
for (it = begin(); it != end; it++) {
|
163
163
|
const ProcessMetrics &metric = it->second;
|
164
164
|
total += metric.pss;
|
165
165
|
priv += metric.privateDirty;
|
166
166
|
}
|
167
|
-
|
167
|
+
|
168
168
|
shared = total - priv;
|
169
169
|
return total;
|
170
170
|
} else {
|
171
171
|
size_t total = 0;
|
172
|
-
|
172
|
+
|
173
173
|
for (it = begin(); it != end; it++) {
|
174
174
|
const ProcessMetrics &metric = it->second;
|
175
175
|
total += metric.realMemory();
|
176
176
|
}
|
177
|
-
|
177
|
+
|
178
178
|
shared = -1;
|
179
179
|
return total;
|
180
180
|
}
|
@@ -189,7 +189,7 @@ class ProcessMetricsCollector {
|
|
189
189
|
private:
|
190
190
|
bool canMeasureRealMemory;
|
191
191
|
string psOutput;
|
192
|
-
|
192
|
+
|
193
193
|
template<typename Collection, typename ConstIterator>
|
194
194
|
ProcessMetricMap parsePsOutput(const string &output, const Collection &allowedPids) const {
|
195
195
|
ProcessMetricMap result;
|
@@ -207,11 +207,11 @@ private:
|
|
207
207
|
pids.insert(*it);
|
208
208
|
}
|
209
209
|
#endif
|
210
|
-
|
210
|
+
|
211
211
|
// Parse each line.
|
212
212
|
while (start != NULL) {
|
213
213
|
ProcessMetrics metrics;
|
214
|
-
|
214
|
+
|
215
215
|
metrics.pid = (pid_t) readNextWordAsLongLong(&start);
|
216
216
|
metrics.ppid = (pid_t) readNextWordAsLongLong(&start);
|
217
217
|
metrics.cpu = readNextWordAsInt(&start);
|
@@ -230,7 +230,7 @@ private:
|
|
230
230
|
|
231
231
|
if (pidAllowed) {
|
232
232
|
result[metrics.pid] = metrics;
|
233
|
-
|
233
|
+
|
234
234
|
start = strchr(start, '\n');
|
235
235
|
if (start != NULL) {
|
236
236
|
// Skip to beginning of next line.
|
@@ -243,7 +243,7 @@ private:
|
|
243
243
|
}
|
244
244
|
return result;
|
245
245
|
}
|
246
|
-
|
246
|
+
|
247
247
|
public:
|
248
248
|
ProcessMetricsCollector() {
|
249
249
|
#ifdef __APPLE__
|
@@ -252,12 +252,12 @@ public:
|
|
252
252
|
canMeasureRealMemory = fileExists("/proc/self/smaps");
|
253
253
|
#endif
|
254
254
|
}
|
255
|
-
|
255
|
+
|
256
256
|
/** Mock 'ps' output, used by unit tests. */
|
257
257
|
void setPsOutput(const string &data) {
|
258
258
|
this->psOutput = data;
|
259
259
|
}
|
260
|
-
|
260
|
+
|
261
261
|
/**
|
262
262
|
* Collect metrics for the given process IDs. Nonexistant PIDs are not
|
263
263
|
* included in the result.
|
@@ -273,12 +273,12 @@ public:
|
|
273
273
|
if (pids.empty()) {
|
274
274
|
return ProcessMetricMap();
|
275
275
|
}
|
276
|
-
|
276
|
+
|
277
277
|
ConstIterator it;
|
278
278
|
// The list of PIDs must follow -p without a space.
|
279
279
|
// https://groups.google.com/forum/#!topic/phusion-passenger/WKXy61nJBMA
|
280
280
|
string pidsArg = "-p";
|
281
|
-
|
281
|
+
|
282
282
|
for (it = pids.begin(); it != pids.end(); it++) {
|
283
283
|
pidsArg.append(toString(*it));
|
284
284
|
pidsArg.append(",");
|
@@ -296,7 +296,7 @@ public:
|
|
296
296
|
#else
|
297
297
|
fmtArg.append("pid,ppid,%cpu,rss,vsize,pgid,uid,command");
|
298
298
|
#endif
|
299
|
-
|
299
|
+
|
300
300
|
const char *command[] = {
|
301
301
|
"ps", fmtArg.c_str(),
|
302
302
|
#ifdef PS_SUPPORTS_MULTIPLE_PIDS
|
@@ -304,7 +304,7 @@ public:
|
|
304
304
|
#endif
|
305
305
|
NULL
|
306
306
|
};
|
307
|
-
|
307
|
+
|
308
308
|
string psOutput = this->psOutput;
|
309
309
|
if (psOutput.empty()) {
|
310
310
|
psOutput = runCommandAndCaptureOutput(command);
|
@@ -323,11 +323,11 @@ public:
|
|
323
323
|
}
|
324
324
|
return result;
|
325
325
|
}
|
326
|
-
|
326
|
+
|
327
327
|
ProcessMetricMap collect(const vector<pid_t> &pids) const {
|
328
328
|
return collect< vector<pid_t>, vector<pid_t>::const_iterator >(pids);
|
329
329
|
}
|
330
|
-
|
330
|
+
|
331
331
|
/**
|
332
332
|
* Attempt to measure various parts of a process's memory usage that may
|
333
333
|
* contribute to insight as to what its "real" memory usage might be.
|
@@ -337,7 +337,7 @@ public:
|
|
337
337
|
* sharing it.
|
338
338
|
* - The private dirty RSS.
|
339
339
|
* - Amount of memory in swap.
|
340
|
-
*
|
340
|
+
*
|
341
341
|
* At this time only OS X and recent Linux versions (>= 2.6.25) support
|
342
342
|
* measuring the proportional set size. Usually root privileges are required.
|
343
343
|
*
|
@@ -349,35 +349,35 @@ public:
|
|
349
349
|
#ifdef __APPLE__
|
350
350
|
kern_return_t ret;
|
351
351
|
mach_port_t task;
|
352
|
-
|
352
|
+
|
353
353
|
swap = -1;
|
354
|
-
|
354
|
+
|
355
355
|
ret = task_for_pid(mach_task_self(), pid, &task);
|
356
356
|
if (ret != KERN_SUCCESS) {
|
357
357
|
pss = -1;
|
358
358
|
privateDirty = -1;
|
359
359
|
return;
|
360
360
|
}
|
361
|
-
|
361
|
+
|
362
362
|
mach_vm_address_t addr = 0;
|
363
363
|
int pagesize = getpagesize();
|
364
|
-
|
364
|
+
|
365
365
|
// In bytes.
|
366
366
|
pss = 0;
|
367
367
|
privateDirty = 0;
|
368
|
-
|
368
|
+
|
369
369
|
while (true) {
|
370
370
|
mach_vm_address_t size;
|
371
371
|
vm_region_top_info_data_t info;
|
372
372
|
mach_msg_type_number_t count = VM_REGION_TOP_INFO_COUNT;
|
373
373
|
mach_port_t object_name;
|
374
|
-
|
374
|
+
|
375
375
|
ret = mach_vm_region(task, &addr, &size, VM_REGION_TOP_INFO,
|
376
376
|
(vm_region_info_t) &info, &count, &object_name);
|
377
377
|
if (ret != KERN_SUCCESS) {
|
378
378
|
break;
|
379
379
|
}
|
380
|
-
|
380
|
+
|
381
381
|
if (info.share_mode == SM_PRIVATE) {
|
382
382
|
// shared_pages_resident here means that region
|
383
383
|
// has shared memory only "shared" between 1 process.
|
@@ -391,12 +391,12 @@ public:
|
|
391
391
|
} else if (info.share_mode == SM_SHARED) {
|
392
392
|
pss += info.shared_pages_resident * pagesize / info.ref_count;
|
393
393
|
}
|
394
|
-
|
394
|
+
|
395
395
|
addr += size;
|
396
396
|
}
|
397
|
-
|
397
|
+
|
398
398
|
mach_port_deallocate(mach_task_self(), task);
|
399
|
-
|
399
|
+
|
400
400
|
// Convert result back to KB.
|
401
401
|
pss /= 1024;
|
402
402
|
privateDirty /= 1024;
|
@@ -404,7 +404,7 @@ public:
|
|
404
404
|
string smapsFilename = "/proc/";
|
405
405
|
smapsFilename.append(toString(pid));
|
406
406
|
smapsFilename.append("/smaps");
|
407
|
-
|
407
|
+
|
408
408
|
FILE *f = syscalls::fopen(smapsFilename.c_str(), "r");
|
409
409
|
if (f == NULL) {
|
410
410
|
error:
|
@@ -413,21 +413,21 @@ public:
|
|
413
413
|
swap = -1;
|
414
414
|
return;
|
415
415
|
}
|
416
|
-
|
416
|
+
|
417
417
|
StdioGuard guard(f);
|
418
418
|
bool hasPss = false;
|
419
419
|
bool hasPrivateDirty = false;
|
420
420
|
bool hasSwap = false;
|
421
|
-
|
421
|
+
|
422
422
|
// In KB.
|
423
423
|
pss = 0;
|
424
424
|
privateDirty = 0;
|
425
425
|
swap = 0;
|
426
|
-
|
426
|
+
|
427
427
|
while (!feof(f)) {
|
428
428
|
char line[1024 * 4];
|
429
429
|
const char *buf;
|
430
|
-
|
430
|
+
|
431
431
|
buf = fgets(line, sizeof(line), f);
|
432
432
|
if (buf == NULL) {
|
433
433
|
if (ferror(f)) {
|
@@ -466,7 +466,7 @@ public:
|
|
466
466
|
goto error;
|
467
467
|
}
|
468
468
|
}
|
469
|
-
|
469
|
+
|
470
470
|
if (!hasPss) {
|
471
471
|
pss = -1;
|
472
472
|
}
|