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/safe_cast.h>
21 #include <ripple/basics/Sustain.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/types.h>
29 #include <sys/prctl.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 pass_signal (int a)
49 {
50  kill (pChild, a);
51 }
52 
53 static void stop_manager (int)
54 {
55  kill (pChild, SIGINT);
56  _exit (0);
57 }
58 
59 bool HaveSustain ()
60 {
61  return true;
62 }
63 
65 {
66  if (getppid () != pManager)
67  return "";
68 
69  kill (pManager, SIGHUP);
70  return "Terminating monitor";
71 }
72 
73 static
74 bool checkChild(pid_t pid, int options)
75 {
76  int i;
77 
78  if (waitpid (pChild, &i, options) == -1)
79  return false;
80 
81  return kill (pChild, 0) == 0;
82 }
83 
85 {
86  pManager = getpid ();
87  signal (SIGINT, stop_manager);
88  signal (SIGHUP, stop_manager);
89  signal (SIGUSR1, pass_signal);
90  signal (SIGUSR2, pass_signal);
91 
92  // Number of times the child has exited in less than
93  // 15 seconds.
94  int fastExit = 0;
95 
96  for (auto childCount = 1; ; ++childCount)
97  {
98  pChild = fork ();
99 
100  if (pChild == -1)
101  _exit (0);
102 
103  auto cc = std::to_string (childCount);
104  if (pChild == 0)
105  {
106  beast::setCurrentThreadName ("rippled: main");
107  signal (SIGINT, SIG_DFL);
108  signal (SIGHUP, SIG_DFL);
109  signal (SIGUSR1, SIG_DFL);
110  signal (SIGUSR2, SIG_DFL);
111  return "Launching child " + cc;
112  }
113 
114  beast::setCurrentThreadName (("rippled: #" + cc).c_str());
115 
116  sleep (sleepBeforeWaiting);
117 
118  // If the child has already terminated count this
119  // as a fast exit and an indication that something
120  // went wrong:
121  if (!checkChild (pChild, WNOHANG))
122  {
123  if (++fastExit == 5)
124  _exit (0);
125  }
126  else
127  {
128  fastExit = 0;
129 
130  while (checkChild (pChild, 0))
131  sleep(sleepBetweenWaits);
132 
133  (void)rename ("core",
134  ("core." + std::to_string(pChild)).c_str());
135  }
136  }
137 }
138 
139 #else
140 
141 bool HaveSustain ()
142 {
143  return false;
144 }
145 
147 {
148  return "";
149 }
150 
152 {
153  return "";
154 }
155 
156 #endif
157 
158 } // ripple
std::string
STL class.
ripple::HaveSustain
bool HaveSustain()
Definition: Sustain.cpp:141
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:113
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:151
ripple::DoSustain
std::string DoSustain()
Definition: Sustain.cpp:146