~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/mongo/db/initialize_server_global_state.cpp

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
*    Copyright (C) 2008 10gen Inc.
 
3
*
 
4
*    This program is free software: you can redistribute it and/or  modify
 
5
*    it under the terms of the GNU Affero General Public License, version 3,
 
6
*    as published by the Free Software Foundation.
 
7
*
 
8
*    This program is distributed in the hope that it will be useful,
 
9
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
*    GNU Affero General Public License for more details.
 
12
*
 
13
*    You should have received a copy of the GNU Affero General Public License
 
14
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
*/
 
16
 
 
17
#include "mongo/pch.h"
 
18
 
 
19
#include "mongo/db/initialize_server_global_state.h"
 
20
 
 
21
#include <boost/filesystem/operations.hpp>
 
22
 
 
23
#ifndef _WIN32
 
24
#include <sys/types.h>
 
25
#include <sys/wait.h>
 
26
#endif
 
27
 
 
28
#include "mongo/db/auth/authorization_manager.h"
 
29
#include "mongo/db/auth/security_key.h"
 
30
#include "mongo/db/cmdline.h"
 
31
#include "mongo/util/log.h"
 
32
#include "mongo/util/net/listen.h"
 
33
#include "mongo/util/processinfo.h"
 
34
 
 
35
namespace fs = boost::filesystem;
 
36
 
 
37
namespace mongo {
 
38
 
 
39
#ifndef _WIN32
 
40
    // support for exit value propagation with fork
 
41
    void launchSignal( int sig ) {
 
42
        if ( sig == SIGUSR2 ) {
 
43
            pid_t cur = getpid();
 
44
            
 
45
            if ( cur == cmdLine.parentProc || cur == cmdLine.leaderProc ) {
 
46
                // signal indicates successful start allowing us to exit
 
47
                _exit(0);
 
48
            } 
 
49
        }
 
50
    }
 
51
 
 
52
    static void setupLaunchSignals() {
 
53
        verify( signal(SIGUSR2 , launchSignal ) != SIG_ERR );
 
54
    }
 
55
 
 
56
    void CmdLine::launchOk() {
 
57
        if ( cmdLine.doFork ) {
 
58
            // killing leader will propagate to parent
 
59
            verify( kill( cmdLine.leaderProc, SIGUSR2 ) == 0 );
 
60
        }
 
61
    }
 
62
#endif
 
63
 
 
64
    bool initializeServerGlobalState(bool isMongodShutdownSpecialCase) {
 
65
 
 
66
        Listener::globalTicketHolder.resize( cmdLine.maxConns );
 
67
 
 
68
#ifndef _WIN32
 
69
        if (!fs::is_directory(cmdLine.socket)) {
 
70
            cout << cmdLine.socket << " must be a directory" << endl;
 
71
            return false;
 
72
        }
 
73
 
 
74
        if (cmdLine.doFork) {
 
75
            fassert(16447, !cmdLine.logpath.empty() || cmdLine.logWithSyslog);
 
76
 
 
77
            cout.flush();
 
78
            cerr.flush();
 
79
 
 
80
            cmdLine.parentProc = getpid();
 
81
 
 
82
            // facilitate clean exit when child starts successfully
 
83
            setupLaunchSignals();
 
84
 
 
85
            cout << "about to fork child process, waiting until server is ready for connections."
 
86
                 << endl;
 
87
 
 
88
            pid_t child1 = fork();
 
89
            if (child1 == -1) {
 
90
                cout << "ERROR: stage 1 fork() failed: " << errnoWithDescription();
 
91
                _exit(EXIT_ABRUPT);
 
92
            }
 
93
            else if (child1) {
 
94
                // this is run in the original parent process
 
95
                int pstat;
 
96
                waitpid(child1, &pstat, 0);
 
97
 
 
98
                if (WIFEXITED(pstat)) {
 
99
                    if (WEXITSTATUS(pstat)) {
 
100
                        cout << "ERROR: child process failed, exited with error number "
 
101
                             << WEXITSTATUS(pstat) << endl;
 
102
                    }
 
103
                    else {
 
104
                        cout << "child process started successfully, parent exiting" << endl;
 
105
                    }
 
106
 
 
107
                    _exit(WEXITSTATUS(pstat));
 
108
                }
 
109
 
 
110
                _exit(50);
 
111
            }
 
112
 
 
113
            if ( chdir("/") < 0 ) {
 
114
                cout << "Cant chdir() while forking server process: " << strerror(errno) << endl;
 
115
                ::_exit(-1);
 
116
            }
 
117
            setsid();
 
118
 
 
119
            cmdLine.leaderProc = getpid();
 
120
 
 
121
            pid_t child2 = fork();
 
122
            if (child2 == -1) {
 
123
                cout << "ERROR: stage 2 fork() failed: " << errnoWithDescription();
 
124
                _exit(EXIT_ABRUPT);
 
125
            }
 
126
            else if (child2) {
 
127
                // this is run in the middle process
 
128
                int pstat;
 
129
                cout << "forked process: " << child2 << endl;
 
130
                waitpid(child2, &pstat, 0);
 
131
 
 
132
                if ( WIFEXITED(pstat) ) {
 
133
                    _exit( WEXITSTATUS(pstat) );
 
134
                }
 
135
 
 
136
                _exit(51);
 
137
            }
 
138
 
 
139
            // this is run in the final child process (the server)
 
140
 
 
141
            // stdout handled in initLogging
 
142
            //fclose(stdout);
 
143
            //freopen("/dev/null", "w", stdout);
 
144
 
 
145
            fclose(stderr);
 
146
            fclose(stdin);
 
147
 
 
148
            FILE* f = freopen("/dev/null", "w", stderr);
 
149
            if ( f == NULL ) {
 
150
                cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl;
 
151
                return false;
 
152
            }
 
153
 
 
154
            f = freopen("/dev/null", "r", stdin);
 
155
            if ( f == NULL ) {
 
156
                cout << "Cant reassign stdin while forking server process: " << strerror(errno) << endl;
 
157
                return false;
 
158
            }
 
159
        }
 
160
 
 
161
        if (cmdLine.logWithSyslog) {
 
162
            StringBuilder sb;
 
163
            sb << cmdLine.binaryName << "." << cmdLine.port;
 
164
            Logstream::useSyslog( sb.str().c_str() );
 
165
        }
 
166
#endif
 
167
        if (!cmdLine.logpath.empty() && !isMongodShutdownSpecialCase) {
 
168
            fassert(16448, !cmdLine.logWithSyslog);
 
169
            string absoluteLogpath = boost::filesystem::absolute(
 
170
                    cmdLine.logpath, cmdLine.cwd).string();
 
171
            if (!initLogging(absoluteLogpath, cmdLine.logAppend)) {
 
172
                cout << "Bad logpath value: \"" << absoluteLogpath << "\"; terminating." << endl;
 
173
                return false;
 
174
            }
 
175
        }
 
176
 
 
177
        if (!cmdLine.pidFile.empty()) {
 
178
            writePidFile(cmdLine.pidFile);
 
179
        }
 
180
 
 
181
        if (!cmdLine.keyFile.empty()) {
 
182
 
 
183
            if (!setUpSecurityKey(cmdLine.keyFile)) {
 
184
                // error message printed in setUpPrivateKey
 
185
                return false;
 
186
            }
 
187
 
 
188
            noauth = false;
 
189
        }
 
190
 
 
191
        return true;
 
192
    }
 
193
 
 
194
    static void ignoreSignal( int sig ) {}
 
195
 
 
196
    void setupCoreSignals() {
 
197
#if !defined(_WIN32)
 
198
        verify( signal(SIGHUP , ignoreSignal ) != SIG_ERR );
 
199
        verify( signal(SIGUSR2, ignoreSignal ) != SIG_ERR );
 
200
#endif
 
201
    }
 
202
 
 
203
}  // namespace mongo