mirror of
https://bitbucket.org/anguist/ntpa
synced 2025-10-05 18:41:13 +00:00
Reload configuration & bugfixes
This commit is contained in:
27
INSTALL
27
INSTALL
@ -21,7 +21,7 @@ Windows
|
||||
|
||||
Download a copy of ntpq and ntpdc. Make sure .NET is installed and
|
||||
the required MySQL Server is accessible. Download and install MySQL
|
||||
if needed.
|
||||
if needed. Minor adjustments might be needed to get the code running.
|
||||
|
||||
|
||||
Install
|
||||
@ -44,33 +44,22 @@ Touch /var/log/ntpa.log and adjust pid file location if needed.
|
||||
|
||||
Configuration
|
||||
|
||||
In ntpa.conf Hostname must point to a name or IP reachable by ntpq.
|
||||
ConfigFile must must point to ntp.conf. ConfigFile is only needed
|
||||
when generating graphs and pages. Adjust the values of HostName and
|
||||
ConfigFile settings accordingly.
|
||||
|
||||
Set database user name and password in the top of ntpa.conf. Leave the
|
||||
Create setting to 1 if you want all tables and data created automatically.
|
||||
Be sure the user you entered in ntpa.conf exists in your MySQL database.
|
||||
|
||||
If you want to generate graphs and pages then also copy ntp.conf from
|
||||
NTP host to the machine running ntpa and add timeserver ID from
|
||||
support.ntp.org. Search using google.com with f.x.
|
||||
"ntp1.innolan.net" site:support.ntp.org
|
||||
For servers not registered on support.ntp.org just add 10000 and above.
|
||||
See ntp.conf in examples on how to add time server IDs.
|
||||
Then later you can use phpMyAdmin, MySQL Workbench or similar to adjust
|
||||
the auto generated values.
|
||||
|
||||
Set Hostname to point at a name or an IP address reachable by ntpq. If
|
||||
you want to generate graphs and pages also copy ntp.conf from the NTP host
|
||||
to the machine running ntpa and set ConfigFile to point at this file.
|
||||
|
||||
Configuration can be validated with the validation tool:
|
||||
# mono ntpav.exe /etc/ntpa.conf
|
||||
|
||||
Use phpMyAdmin, MySQL Workbench or similar to adjust auto generated
|
||||
values in the database.
|
||||
|
||||
Start ntpa and watch the data arriving in MySQL tables.
|
||||
To start ntpa use:
|
||||
# mono ntpa.exe
|
||||
|
||||
The log file contains errors and other clues for debugging.
|
||||
Look in the log file for errors and other clues when debugging.
|
||||
|
||||
To stop ntpa use kill. Find the process id in the log file.
|
||||
# kill 72354
|
||||
|
@ -102,7 +102,7 @@ namespace Ntp.Analyzer.Cli
|
||||
|
||||
try {
|
||||
Main main = new Main (configFile, pid, name);
|
||||
main.Start ();
|
||||
main.Run ();
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine (e.Message);
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ namespace Ntp.Analyzer.Data
|
||||
/// </summary>
|
||||
public sealed class DataFace
|
||||
{
|
||||
private static readonly DataFace instance = new DataFace ();
|
||||
private static DataFace instance = new DataFace ();
|
||||
private readonly Object locker = new Object ();
|
||||
private readonly LogBase log;
|
||||
private NtpConfCache ntpConfigCache;
|
||||
@ -52,6 +52,11 @@ namespace Ntp.Analyzer.Data
|
||||
log = DataConnection.Log;
|
||||
}
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
instance = new DataFace ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Singleton instance.
|
||||
/// </summary>
|
||||
|
@ -101,8 +101,10 @@ namespace Ntp.Analyzer.Data.Static
|
||||
|
||||
protected void AddItem (T item)
|
||||
{
|
||||
items.Add (item.Id, item);
|
||||
hasContent = true;
|
||||
lock (Locker) {
|
||||
items.Add (item.Id, item);
|
||||
hasContent = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected void Open ()
|
||||
|
@ -30,7 +30,7 @@ namespace Ntp.Analyzer.Log
|
||||
{
|
||||
public class ActivityLog : LogBase, IEnumerable<String>
|
||||
{
|
||||
public ActivityLog ()
|
||||
internal ActivityLog ()
|
||||
{
|
||||
activity = new List<string> (2001);
|
||||
}
|
||||
@ -43,6 +43,15 @@ namespace Ntp.Analyzer.Log
|
||||
activity.Clear ();
|
||||
}
|
||||
|
||||
public override void Refresh ()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Close ()
|
||||
{
|
||||
activity.Clear ();
|
||||
}
|
||||
|
||||
public override void WriteLine (string text, Severity severity)
|
||||
{
|
||||
string severityText;
|
||||
|
@ -32,6 +32,10 @@ namespace Ntp.Analyzer.Log
|
||||
{
|
||||
public abstract void Initialize();
|
||||
|
||||
public abstract void Close();
|
||||
|
||||
public abstract void Refresh();
|
||||
|
||||
public abstract void WriteLine(string text, Severity severity);
|
||||
|
||||
public abstract void WriteLine(Exception exception, Severity severity);
|
||||
|
@ -30,9 +30,36 @@ namespace Ntp.Analyzer.Log
|
||||
{
|
||||
public static class LogFactory
|
||||
{
|
||||
private static List<LogBase> logs = new List<LogBase>();
|
||||
|
||||
public static void RefreshLogs()
|
||||
{
|
||||
foreach (LogBase log in logs)
|
||||
log.Refresh ();
|
||||
}
|
||||
|
||||
public static void Cleanup()
|
||||
{
|
||||
foreach (LogBase log in logs)
|
||||
log.Close ();
|
||||
|
||||
logs.Clear ();
|
||||
}
|
||||
|
||||
public static ActivityLog CreateActivityLog()
|
||||
{
|
||||
return new ActivityLog ();
|
||||
}
|
||||
|
||||
public static LogGroup CreateGroupLog()
|
||||
{
|
||||
return new LogGroup ();
|
||||
}
|
||||
|
||||
public static LogBase CreateLog(LogConfiguration config)
|
||||
{
|
||||
TextLog log = new TextLog(config.File, config.Treshold);
|
||||
logs.Add (log);
|
||||
return log;
|
||||
}
|
||||
|
||||
@ -46,6 +73,8 @@ namespace Ntp.Analyzer.Log
|
||||
group.Add(log);
|
||||
}
|
||||
|
||||
logs.Add (group);
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ namespace Ntp.Analyzer.Log
|
||||
{
|
||||
private readonly List<LogBase> logs;
|
||||
|
||||
public LogGroup()
|
||||
internal LogGroup()
|
||||
{
|
||||
logs = new List<LogBase>();
|
||||
}
|
||||
@ -44,6 +44,18 @@ namespace Ntp.Analyzer.Log
|
||||
log.Initialize();
|
||||
}
|
||||
|
||||
public override void Refresh ()
|
||||
{
|
||||
foreach (LogBase log in logs)
|
||||
log.Refresh();
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
foreach (LogBase log in logs)
|
||||
log.Close();
|
||||
}
|
||||
|
||||
public override void WriteLine(string text, Severity severity)
|
||||
{
|
||||
foreach (LogBase log in logs)
|
||||
|
@ -39,7 +39,7 @@ namespace Ntp.Analyzer.Log
|
||||
private bool initialized;
|
||||
private TextWriter writer;
|
||||
|
||||
public TextLog(string file, Severity treshold, string timeFormat)
|
||||
internal TextLog(string file, Severity treshold, string timeFormat)
|
||||
{
|
||||
this.file = file;
|
||||
this.treshold = treshold;
|
||||
@ -47,7 +47,7 @@ namespace Ntp.Analyzer.Log
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
public TextLog(string file, Severity treshold)
|
||||
internal TextLog(string file, Severity treshold)
|
||||
: this(file, treshold, "yyyy-MM-dd HH:mm:ss")
|
||||
{
|
||||
}
|
||||
@ -58,6 +58,12 @@ namespace Ntp.Analyzer.Log
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
public override void Refresh ()
|
||||
{
|
||||
Close ();
|
||||
Initialize ();
|
||||
}
|
||||
|
||||
public override void WriteLine(string text, Severity severity)
|
||||
{
|
||||
if (!initialized)
|
||||
@ -120,7 +126,7 @@ namespace Ntp.Analyzer.Log
|
||||
WriteLine(exception.StackTrace, severity);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
public override void Close()
|
||||
{
|
||||
writer.Close();
|
||||
initialized = false;
|
||||
|
@ -66,6 +66,7 @@ namespace Ntp.Analyzer.Process
|
||||
this.version = VersionInfo.Number;
|
||||
}
|
||||
|
||||
private static bool firstrun = true;
|
||||
private readonly string version;
|
||||
private readonly string configFile;
|
||||
private readonly int pid;
|
||||
@ -89,6 +90,10 @@ namespace Ntp.Analyzer.Process
|
||||
get { return nodes; }
|
||||
}
|
||||
|
||||
public List<Listener> Listeners {
|
||||
get { return listeners; }
|
||||
}
|
||||
|
||||
public bool Ready {
|
||||
get { return ready; }
|
||||
}
|
||||
@ -116,6 +121,7 @@ namespace Ntp.Analyzer.Process
|
||||
}
|
||||
|
||||
ready = proceed;
|
||||
firstrun = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -156,14 +162,15 @@ namespace Ntp.Analyzer.Process
|
||||
// Create log.
|
||||
try {
|
||||
log = LogFactory.CreateLog (config.Log);
|
||||
log.Initialize();
|
||||
log.Initialize ();
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine ("Cannot create log file. " + ex.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize log.
|
||||
log.WriteLine ("NTP Analyzer " + version + " started.", Severity.Notice);
|
||||
if (firstrun)
|
||||
log.WriteLine ("NTP Analyzer " + version + " started.", Severity.Notice);
|
||||
log.WriteLine ("Using configuration: " + configFile, Severity.Notice);
|
||||
log.WriteLine ("Running with pid: " + pid, Severity.Notice);
|
||||
log.WriteLine ("Instance name: " + name, Severity.Notice);
|
||||
@ -193,6 +200,7 @@ namespace Ntp.Analyzer.Process
|
||||
DataConnection.InitializeString = config.Database.InitializeConnectionString;
|
||||
DataConnection.Initialize = config.Database.Initialize;
|
||||
DataConnection.Log = log;
|
||||
DataFace.Reset ();
|
||||
|
||||
// Initialize database tables
|
||||
if (config.Database.Initialize) {
|
||||
@ -245,7 +253,7 @@ namespace Ntp.Analyzer.Process
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.WriteLine ("Could not populating all data into tables.", Severity.Error);
|
||||
log.WriteLine ("Could not populate tables with data.", Severity.Error);
|
||||
log.WriteLine (e.Message, Severity.Debug);
|
||||
log.WriteLine (e, Severity.Trace);
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
using Ntp.Process;
|
||||
using Ntp.Analyzer.Log;
|
||||
using Ntp.Monitor.Server;
|
||||
|
||||
namespace Ntp.Analyzer.Process
|
||||
{
|
||||
@ -41,17 +43,25 @@ namespace Ntp.Analyzer.Process
|
||||
private readonly int pid;
|
||||
private readonly string name;
|
||||
|
||||
public void Start ()
|
||||
public void Run ()
|
||||
{
|
||||
Initializer i = new Initializer (configFile, pid, name);
|
||||
i.Run ();
|
||||
bool reload = true;
|
||||
while (reload) {
|
||||
Initializer i = new Initializer (configFile, pid, name);
|
||||
i.Run ();
|
||||
|
||||
if (!i.Ready) {
|
||||
return;
|
||||
if (!i.Ready)
|
||||
return;
|
||||
|
||||
Cluster c = new Cluster (name, i.Scheduler, i.Nodes, i.Log);
|
||||
c.Activate ();
|
||||
reload = c.Reload;
|
||||
|
||||
foreach (Listener l in i.Listeners)
|
||||
l.Close ();
|
||||
|
||||
LogFactory.Cleanup ();
|
||||
}
|
||||
|
||||
Cluster c = new Cluster (name, i.Scheduler, i.Nodes, i.Log);
|
||||
c.Activate ();
|
||||
}
|
||||
}
|
||||
}
|
@ -45,11 +45,13 @@ namespace Ntp.Monitor.Server
|
||||
IPAddress address = IPAddress.Parse (ip);
|
||||
endPoint = new IPEndPoint (address, port);
|
||||
this.log = log;
|
||||
this.shuttingDown = false;
|
||||
}
|
||||
|
||||
private readonly IPEndPoint endPoint;
|
||||
private readonly LogBase log;
|
||||
private Socket listenSocket;
|
||||
private bool shuttingDown;
|
||||
|
||||
/// <summary>
|
||||
/// Open this listener.
|
||||
@ -78,6 +80,7 @@ namespace Ntp.Monitor.Server
|
||||
/// </summary>
|
||||
public void Close ()
|
||||
{
|
||||
shuttingDown = true;
|
||||
listenSocket.Close ();
|
||||
}
|
||||
|
||||
@ -103,9 +106,11 @@ namespace Ntp.Monitor.Server
|
||||
ReceiveCallback,
|
||||
req);
|
||||
} catch (Exception ex) {
|
||||
log.WriteLine ("Unexpected error in listener " + this.ToString (), Severity.Error);
|
||||
log.WriteLine (ex.Message, Severity.Debug);
|
||||
log.WriteLine (ex, Severity.Trace);
|
||||
if (!shuttingDown) {
|
||||
log.WriteLine ("Unexpected error in listener " + this.ToString (), Severity.Error);
|
||||
log.WriteLine (ex.Message, Severity.Debug);
|
||||
log.WriteLine (ex, Severity.Trace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,7 @@
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Ntp.Analyzer.Log;
|
||||
using Ntp.System;
|
||||
@ -46,6 +44,7 @@ namespace Ntp.Process
|
||||
this.scheduler = scheduler;
|
||||
this.peers = peers;
|
||||
this.log = log;
|
||||
this.reload = false;
|
||||
waitHandle = new EventWaitHandle (false, EventResetMode.AutoReset);
|
||||
}
|
||||
|
||||
@ -54,25 +53,28 @@ namespace Ntp.Process
|
||||
private readonly IEnumerable<IRequest> peers;
|
||||
private readonly LogBase log;
|
||||
private readonly EventWaitHandle waitHandle;
|
||||
private bool reload;
|
||||
private bool run;
|
||||
|
||||
public bool Reload {
|
||||
get { return reload; }
|
||||
}
|
||||
|
||||
public void Activate ()
|
||||
{
|
||||
log.WriteLine ("Starting cluster module.", Severity.Info);
|
||||
bool activated = true;
|
||||
if (peers.Count () != 0) {
|
||||
log.WriteLine ("Starting cluster module.", Severity.Info);
|
||||
}
|
||||
|
||||
Thread killSwitch = new Thread (KillSwitch);
|
||||
killSwitch.Start ();
|
||||
Thread signalHandler = new Thread (SignalHandler);
|
||||
signalHandler.Start ();
|
||||
run = true;
|
||||
|
||||
// TODO: Move to public scope (ApplicationState)
|
||||
bool activated = true;
|
||||
|
||||
while (run) {
|
||||
|
||||
bool otherActive = false;
|
||||
|
||||
foreach (IRequest request in peers) {
|
||||
|
||||
try {
|
||||
string answer = request.Send ("ping");
|
||||
|
||||
@ -94,8 +96,6 @@ namespace Ntp.Process
|
||||
}
|
||||
|
||||
if (!otherActive) {
|
||||
//log.WriteLine ("No other nodes active. Activting node.", Severity.Debug);
|
||||
|
||||
try {
|
||||
scheduler.RunOneCycle ();
|
||||
} catch (Exception e) {
|
||||
@ -105,28 +105,57 @@ namespace Ntp.Process
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
log.WriteLine ("Other node active. Going to fallback mode.", Severity.Debug);
|
||||
waitHandle.WaitOne (10000);
|
||||
}
|
||||
|
||||
// This node is now active and no longer "activated"
|
||||
activated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void KillSwitch ()
|
||||
public void SignalHandler ()
|
||||
{
|
||||
try {
|
||||
InterLock.Wait (name, log);
|
||||
waitHandle.Set ();
|
||||
scheduler.WaitHandle.Set ();
|
||||
run = false;
|
||||
} catch (Exception e) {
|
||||
log.WriteLine ("Error in mutux.", Severity.Error);
|
||||
log.WriteLine (e.ToString (), Severity.Error);
|
||||
log.WriteLine (e, Severity.Trace);
|
||||
}
|
||||
bool loop = true;
|
||||
|
||||
log.WriteLine ("Closing down.", Severity.Notice);
|
||||
while (loop) {
|
||||
try {
|
||||
switch (InterProcess.Wait (name, log)) {
|
||||
case InterProcess.Signal.Exit:
|
||||
loop = false;
|
||||
run = false;
|
||||
waitHandle.Set ();
|
||||
scheduler.WaitHandle.Set ();
|
||||
log.WriteLine ("Closing down.", Severity.Notice);
|
||||
break;
|
||||
case InterProcess.Signal.Reload:
|
||||
reload = true;
|
||||
loop = false;
|
||||
run = false;
|
||||
waitHandle.Set ();
|
||||
scheduler.WaitHandle.Set ();
|
||||
log.WriteLine ("Reloading configuration.", Severity.Notice);
|
||||
break;
|
||||
case InterProcess.Signal.Refresh:
|
||||
LogFactory.RefreshLogs ();
|
||||
log.WriteLine ("Restarting logging module.", Severity.Notice);
|
||||
break;
|
||||
case InterProcess.Signal.Error:
|
||||
log.WriteLine ("Error in inter process communication.", Severity.Error);
|
||||
loop = false;
|
||||
run = false;
|
||||
break;
|
||||
default:
|
||||
log.WriteLine ("Unexpected InterProcess signal.", Severity.Error);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.WriteLine ("Error in signal handler.", Severity.Error);
|
||||
log.WriteLine (e.ToString (), Severity.Error);
|
||||
log.WriteLine (e, Severity.Trace);
|
||||
loop = false;
|
||||
run = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -53,9 +53,9 @@ namespace Ntp.Process
|
||||
|
||||
schedule = new List<ScheduledJob> ();
|
||||
jobs = new List<Job> ();
|
||||
activityLog = new ActivityLog ();
|
||||
activityLog = LogFactory.CreateActivityLog ();
|
||||
|
||||
LogGroup logGroup = new LogGroup ();
|
||||
LogGroup logGroup = LogFactory.CreateGroupLog ();
|
||||
logGroup.Add (log);
|
||||
logGroup.Add (activityLog);
|
||||
|
||||
|
@ -1,91 +0,0 @@
|
||||
//
|
||||
// InterLock.cs
|
||||
//
|
||||
// Author:
|
||||
// Carsten Sonne Larsen <cs@innolan.dk>
|
||||
//
|
||||
// Copyright (c) 2016 Carsten Sonne Larsen
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
using Ntp.Analyzer.Log;
|
||||
|
||||
#if __MonoCS__
|
||||
using Mono.Unix;
|
||||
using Mono.Unix.Native;
|
||||
#else
|
||||
using System.Threading;
|
||||
#endif
|
||||
|
||||
namespace Ntp.System
|
||||
{
|
||||
public static class InterLock
|
||||
{
|
||||
#if __MonoCS__
|
||||
public static bool Wait (string name, LogBase log)
|
||||
{
|
||||
UnixSignal[] signals = new UnixSignal[]{
|
||||
new UnixSignal (Signum.SIGTERM)
|
||||
};
|
||||
|
||||
try {
|
||||
UnixSignal.WaitAny (signals, -1);
|
||||
log.WriteLine ("Received kill signal.", Severity.Notice);
|
||||
} catch (Exception e) {
|
||||
log.WriteLine ("Error in Signum handling.", Severity.Error);
|
||||
log.WriteLine (e, Severity.Trace);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
public static bool Release (string name, LogBase log)
|
||||
{
|
||||
try {
|
||||
EventWaitHandle handle = EventWaitHandle.OpenExisting (name);
|
||||
handle.Set ();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.WriteLine ("Error in mutex handling.", Severity.Error);
|
||||
log.WriteLine (e, Severity.Trace);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Wait (string name, LogBase log)
|
||||
{
|
||||
try {
|
||||
EventWaitHandle handle = new EventWaitHandle (
|
||||
false, EventResetMode.ManualReset,
|
||||
name);
|
||||
handle.WaitOne ();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.WriteLine ("Error in mutex handling.", Severity.Error);
|
||||
log.WriteLine (e, Severity.Trace);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
130
Ntp.System/InterProcess.cs
Normal file
130
Ntp.System/InterProcess.cs
Normal file
@ -0,0 +1,130 @@
|
||||
//
|
||||
// InterLock.cs
|
||||
//
|
||||
// Author:
|
||||
// Carsten Sonne Larsen <cs@innolan.dk>
|
||||
//
|
||||
// Copyright (c) 2016 Carsten Sonne Larsen
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
using Ntp.Analyzer.Log;
|
||||
|
||||
#if __MonoCS__
|
||||
using Mono.Unix;
|
||||
using Mono.Unix.Native;
|
||||
#else
|
||||
using System.Threading;
|
||||
#endif
|
||||
|
||||
namespace Ntp.System
|
||||
{
|
||||
public static class InterProcess
|
||||
{
|
||||
public enum Signal
|
||||
{
|
||||
Error = 0,
|
||||
Exit,
|
||||
Refresh,
|
||||
Reload
|
||||
}
|
||||
|
||||
#if __MonoCS__
|
||||
public static Signal Wait (string name, LogBase log)
|
||||
{
|
||||
UnixSignal[] signals = new UnixSignal[] {
|
||||
new UnixSignal (Signum.SIGTERM),
|
||||
new UnixSignal (Signum.SIGQUIT),
|
||||
new UnixSignal (Signum.SIGINT),
|
||||
new UnixSignal (Signum.SIGHUP),
|
||||
new UnixSignal (Signum.SIGUSR1)
|
||||
};
|
||||
|
||||
int sig = 0;
|
||||
while (true) {
|
||||
try {
|
||||
sig = UnixSignal.WaitAny (signals, -1);
|
||||
} catch (Exception e) {
|
||||
log.WriteLine ("Error in Signum handling.", Severity.Error);
|
||||
log.WriteLine (e, Severity.Trace);
|
||||
return Signal.Error;
|
||||
}
|
||||
|
||||
if (sig >= 0 && sig < signals.Length) {
|
||||
Signum signal = signals [sig].Signum;
|
||||
|
||||
switch (signal) {
|
||||
case Signum.SIGINT:
|
||||
log.WriteLine ("Interrupted.", Severity.Notice);
|
||||
return Signal.Exit;
|
||||
case Signum.SIGTERM:
|
||||
log.WriteLine ("Received kill signal.", Severity.Notice);
|
||||
return Signal.Exit;
|
||||
case Signum.SIGQUIT:
|
||||
log.WriteLine ("Received quit signal.", Severity.Notice);
|
||||
return Signal.Exit;
|
||||
case Signum.SIGHUP:
|
||||
log.WriteLine ("Received log restart signal.", Severity.Debug);
|
||||
return Signal.Refresh;
|
||||
case Signum.SIGUSR1:
|
||||
log.WriteLine ("Received reload config signal.", Severity.Debug);
|
||||
return Signal.Reload;
|
||||
default:
|
||||
log.WriteLine ("Unknown signal received.", Severity.Warn);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
log.WriteLine ("Unknown signal received.", Severity.Warn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
public static bool Release (string name, LogBase log)
|
||||
{
|
||||
try {
|
||||
EventWaitHandle handle = EventWaitHandle.OpenExisting (name);
|
||||
handle.Set ();
|
||||
return Signal.Exit;
|
||||
} catch (Exception e) {
|
||||
log.WriteLine ("Error in mutex handling.", Severity.Error);
|
||||
log.WriteLine (e, Severity.Trace);
|
||||
return Signal.Error;
|
||||
}
|
||||
}
|
||||
|
||||
public static Signal Wait (string name, LogBase log)
|
||||
{
|
||||
try {
|
||||
EventWaitHandle handle = new EventWaitHandle (
|
||||
false, EventResetMode.ManualReset,
|
||||
name);
|
||||
handle.WaitOne ();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.WriteLine ("Error in mutex handling.", Severity.Error);
|
||||
log.WriteLine (e, Severity.Trace);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
@ -41,10 +41,10 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ShellCommand.cs" />
|
||||
<Compile Include="InterLock.cs" />
|
||||
<Compile Include="ProcessInfo.cs" />
|
||||
<Compile Include="Options.cs" />
|
||||
<Compile Include="VersionInfo.cs" />
|
||||
<Compile Include="InterProcess.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
15
script/ntpa
15
script/ntpa
@ -24,6 +24,9 @@ rcvar=${name}_enable
|
||||
|
||||
start_cmd="ntpa_start"
|
||||
stop_cmd="ntpa_stop"
|
||||
reload_cmd="ntpa_reload"
|
||||
|
||||
extra_commands="reload"
|
||||
|
||||
load_rc_config ${name}
|
||||
|
||||
@ -42,6 +45,18 @@ ntpa_start()
|
||||
fi
|
||||
}
|
||||
|
||||
ntpa_reload()
|
||||
{
|
||||
if [ ! -f ${pidfile} ]; then
|
||||
_run_rc_notrunning
|
||||
return 1
|
||||
else
|
||||
echo "Reloading ${name}."
|
||||
rc_pid=`cat ${pidfile}`
|
||||
kill -USR1 $rc_pid
|
||||
fi
|
||||
}
|
||||
|
||||
ntpa_stop()
|
||||
{
|
||||
if [ ! -f ${pidfile} ]; then
|
||||
|
Reference in New Issue
Block a user