1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2019-2019 Bareos GmbH & Co. KG
5 
6    This program is Free Software; you can redistribute it and/or
7    modify it under the terms of version three of the GNU Affero General Public
8    License as published by the Free Software Foundation and included
9    in the file LICENSE.
10 
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14    Affero General Public License for more details.
15 
16    You should have received a copy of the GNU Affero General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19    02110-1301, USA.
20 */
21 
22 #include "watchdog_timer.h"
23 #include "include/jcr.h"
24 #include "lib/timer_thread.h"
25 #include "lib/watchdog.h"
26 
27 #include <cassert>
28 
29 static const int debuglevel = 900;
30 
WatchdogTimer(JobControlRecord * jcr)31 WatchdogTimer::WatchdogTimer(JobControlRecord* jcr)
32 {
33   timer_item = TimerThread::NewTimer();
34   timer_item->user_data = this;
35   timer_item->single_shot = true;
36   jcr_ = jcr;
37 }
38 
~WatchdogTimer()39 WatchdogTimer::~WatchdogTimer()
40 {
41   if (timer_item) { UnregisterTimer(timer_item); }
42 }
43 
Start(std::chrono::milliseconds interval)44 void WatchdogTimer::Start(std::chrono::milliseconds interval)
45 {
46   timer_item->interval = interval;
47   RegisterTimer(timer_item);
48 }
49 
Stop()50 void WatchdogTimer::Stop()
51 {
52   if (timer_item) {
53     UnregisterTimer(timer_item);
54     timer_item = nullptr;
55   }
56 }
57 
Callback(TimerThread::Timer * item)58 void BThreadWatchdog::Callback(TimerThread::Timer* item)
59 {
60   BThreadWatchdog* timer = static_cast<BThreadWatchdog*>(item->user_data);
61   if (!timer) { return; }
62 
63   if (timer->jcr_) {
64     Dmsg2(debuglevel, "killed JobId=%u Job=%s\n", timer->jcr_->JobId,
65           timer->jcr_->Job);
66   }
67 
68   pthread_kill(timer->thread_id_, TIMEOUT_SIGNAL);
69 }
70 
Init()71 void BThreadWatchdog::Init()
72 {
73   thread_id_ = pthread_self();
74   timer_item->user_callback = Callback;
75 }
76 
BThreadWatchdog(JobControlRecord * jcr)77 BThreadWatchdog::BThreadWatchdog(JobControlRecord* jcr) : WatchdogTimer(jcr)
78 {
79   // has to be started by Start(interval)
80   Init();
81 }
82 
BThreadWatchdog(std::chrono::milliseconds interval,JobControlRecord * jcr)83 BThreadWatchdog::BThreadWatchdog(std::chrono::milliseconds interval,
84                                  JobControlRecord* jcr)
85     : WatchdogTimer(jcr)
86 {
87   assert(interval != std::chrono::seconds::zero());
88 
89   Init();
90 
91   Start(interval);
92 }
93