rippled
Sustain.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/basics/Sustain.h>
21 #include <ripple/basics/safe_cast.h>
22 #include <ripple/beast/core/CurrentThreadName.h>
23 #include <boost/format.hpp>
24 
25 // For Sustain Linux variants
26 // VFALCO TODO Rewrite Sustain to use beast::Process
27 #ifdef __linux__
28 #include <sys/prctl.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <unistd.h>
32 #endif
33 #ifdef __FreeBSD__
34 #include <sys/types.h>
35 #include <sys/wait.h>
36 #endif
37 
38 namespace ripple {
39 
40 #ifdef __unix__
41 
42 static auto const sleepBeforeWaiting = 10;
43 static auto const sleepBetweenWaits = 1;
44 
45 static pid_t pManager = safe_cast<pid_t>(0);
46 static pid_t pChild = safe_cast<pid_t>(0);
47 
48 static void
49 pass_signal(int a)
50 {
51  kill(pChild, a);
52 }
53 
54 static void
55 stop_manager(int)
56 {
57  kill(pChild, SIGINT);
58  _exit(0);
59 }
60 
61 bool
63 {
64  return true;
65 }
66 
69 {
70  if (getppid() != pManager)
71  return "";
72 
73  kill(pManager, SIGHUP);
74  return "Terminating monitor";
75 }
76 
77 static bool
78 checkChild(pid_t pid, int options)
79 {
80  int i;
81 
82  if (waitpid(pChild, &i, options) == -1)
83  return false;
84 
85  return kill(pChild, 0) == 0;
86 }
87 
89 DoSustain()
90 {
91  pManager = getpid();
92  signal(SIGINT, stop_manager);
93  signal(SIGHUP, stop_manager);
94  signal(SIGUSR1, pass_signal);
95  signal(SIGUSR2, pass_signal);
96 
97  // Number of times the child has exited in less than
98  // 15 seconds.
99  int fastExit = 0;
100 
101  for (auto childCount = 1;; ++childCount)
102  {
103  pChild = fork();
104 
105  if (pChild == -1)
106  _exit(0);
107 
108  auto cc = std::to_string(childCount);
109  if (pChild == 0)
110  {
111  beast::setCurrentThreadName("rippled: main");
112  signal(SIGINT, SIG_DFL);
113  signal(SIGHUP, SIG_DFL);
114  signal(SIGUSR1, SIG_DFL);
115  signal(SIGUSR2, SIG_DFL);
116  return "Launching child " + cc;
117  }
118 
119  beast::setCurrentThreadName(("rippled: #" + cc).c_str());
120 
121  sleep(sleepBeforeWaiting);
122 
123  // If the child has already terminated count this
124  // as a fast exit and an indication that something
125  // went wrong:
126  if (!checkChild(pChild, WNOHANG))
127  {
128  if (++fastExit == 5)
129  _exit(0);
130  }
131  else
132  {
133  fastExit = 0;
134 
135  while (checkChild(pChild, 0))
136  sleep(sleepBetweenWaits);
137 
138  (void)rename("core", ("core." + std::to_string(pChild)).c_str());
139  }
140  }
141 }
142 
143 #else
144 
145 bool
147 {
148  return false;
149 }
150 
153 {
154  return "";
155 }
156 
159 {
160  return "";
161 }
162 
163 #endif
164 
165 } // namespace ripple
std::string
STL class.
ripple::HaveSustain
bool HaveSustain()
Definition: Sustain.cpp:146
std::to_string
T to_string(T... args)
std::signal
T signal(T... args)
beast::setCurrentThreadName
void setCurrentThreadName(std::string_view name)
Changes the name of the caller thread.
Definition: CurrentThreadName.cpp:119
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::StopSustain
std::string StopSustain()
Definition: Sustain.cpp:158
ripple::DoSustain
std::string DoSustain()
Definition: Sustain.cpp:152
std::rename
T rename(T... args)