refactor(daemon): More helpful and less noisy logging
This commit is contained in:
parent
e8ea9f53ee
commit
16517ca541
6 changed files with 69 additions and 61 deletions
|
|
@ -350,6 +350,8 @@ void ArchDaemonWindows::setStatus(DWORD state, DWORD step, DWORD waitHint)
|
||||||
{
|
{
|
||||||
assert(s_daemon != NULL);
|
assert(s_daemon != NULL);
|
||||||
|
|
||||||
|
LOG_DEBUG("setting service status: state=%d, step=%d, waitHint=%d", state, step, waitHint);
|
||||||
|
|
||||||
SERVICE_STATUS status;
|
SERVICE_STATUS status;
|
||||||
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
|
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
|
||||||
status.dwCurrentState = state;
|
status.dwCurrentState = state;
|
||||||
|
|
|
||||||
|
|
@ -55,20 +55,20 @@ void DaemonApp::saveLogLevel(const QString &logLevel) const
|
||||||
// saves setting for next time the daemon starts.
|
// saves setting for next time the daemon starts.
|
||||||
ARCH->setting("LogLevel", logLevel.toStdString());
|
ARCH->setting("LogLevel", logLevel.toStdString());
|
||||||
} catch (XArch &e) {
|
} catch (XArch &e) {
|
||||||
LOG((CLOG_ERR "failed to save log level setting: %s", e.what()));
|
LOG_ERR("failed to save log level setting: %s", e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonApp::setElevate(bool elevate)
|
void DaemonApp::setElevate(bool elevate)
|
||||||
{
|
{
|
||||||
LOG((CLOG_DEBUG "elevate value changed: %s", elevate ? "yes" : "no"));
|
LOG_DEBUG("elevate value changed: %s", elevate ? "yes" : "no");
|
||||||
m_elevate = elevate;
|
m_elevate = elevate;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// saves setting for next time the daemon starts.
|
// saves setting for next time the daemon starts.
|
||||||
ARCH->setting("Elevate", std::string(elevate ? "1" : "0"));
|
ARCH->setting("Elevate", std::string(elevate ? "1" : "0"));
|
||||||
} catch (XArch &e) {
|
} catch (XArch &e) {
|
||||||
LOG((CLOG_ERR "failed to save elevate setting: %s", e.what()));
|
LOG_ERR("failed to save elevate setting: %s", e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,7 +81,7 @@ void DaemonApp::setCommand(const QString &command)
|
||||||
// saves setting for next time the daemon starts.
|
// saves setting for next time the daemon starts.
|
||||||
ARCH->setting("Command", command.toStdString());
|
ARCH->setting("Command", command.toStdString());
|
||||||
} catch (XArch &e) {
|
} catch (XArch &e) {
|
||||||
LOG((CLOG_ERR "failed to save command setting: %s", e.what()));
|
LOG_ERR("failed to save command setting: %s", e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,21 +230,22 @@ int DaemonApp::mainLoop()
|
||||||
|
|
||||||
LOG_INFO("daemon is running");
|
LOG_INFO("daemon is running");
|
||||||
m_events.loop();
|
m_events.loop();
|
||||||
LOG_INFO("daemon is stopping");
|
|
||||||
} catch (std::exception &e) { // NOSONAR - Catching all exceptions
|
} catch (std::exception &e) { // NOSONAR - Catching all exceptions
|
||||||
LOG((CLOG_CRIT "daemon error: %s", e.what()));
|
LOG((CLOG_CRIT "daemon error: %s", e.what()));
|
||||||
} catch (...) { // NOSONAR - Catching remaining exceptions
|
} catch (...) { // NOSONAR - Catching remaining exceptions
|
||||||
LOG((CLOG_CRIT "daemon unknown error"));
|
LOG((CLOG_CRIT "daemon unknown error"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_INFO("daemon is stopping");
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
try {
|
try {
|
||||||
LOG_DEBUG("stopping process watchdog");
|
LOG_DEBUG("stopping process watchdog");
|
||||||
m_pWatchdog->stop();
|
m_pWatchdog->stop();
|
||||||
} catch (std::exception &e) { // NOSONAR - Catching all exceptions
|
} catch (std::exception &e) { // NOSONAR - Catching all exceptions
|
||||||
LOG((CLOG_CRIT "stop watchdog error: %s", e.what()));
|
LOG((CLOG_CRIT "daemon stop watchdog error: %s", e.what()));
|
||||||
} catch (...) { // NOSONAR - Catching remaining exceptions
|
} catch (...) { // NOSONAR - Catching remaining exceptions
|
||||||
LOG((CLOG_CRIT "stop watchdog unknown error"));
|
LOG((CLOG_CRIT "daemon stop watchdog unknown error"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ void CoreProcess::daemonIpcClientConnected()
|
||||||
m_daemonFileTail->deleteLater();
|
m_daemonFileTail->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
qInfo() << "daemon log path:" << logPath;
|
qDebug() << "daemon log path:" << logPath;
|
||||||
m_daemonFileTail = new FileTail(logPath, this);
|
m_daemonFileTail = new FileTail(logPath, this);
|
||||||
connect(m_daemonFileTail, &FileTail::newLine, this, &CoreProcess::handleLogLines);
|
connect(m_daemonFileTail, &FileTail::newLine, this, &CoreProcess::handleLogLines);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,21 +27,21 @@ DaemonIpcClient::DaemonIpcClient(QObject *parent)
|
||||||
|
|
||||||
bool DaemonIpcClient::connectToServer()
|
bool DaemonIpcClient::connectToServer()
|
||||||
{
|
{
|
||||||
qInfo("connecting to daemon ipc");
|
qDebug() << "daemon ipc client connecting to server:" << kDaemonIpcName;
|
||||||
|
|
||||||
m_socket->connectToServer(kDaemonIpcName);
|
m_socket->connectToServer(kDaemonIpcName);
|
||||||
if (!m_socket->waitForConnected(kTimeout)) {
|
if (!m_socket->waitForConnected(kTimeout)) {
|
||||||
qWarning() << "ipc client failed to connect to server:" << kDaemonIpcName;
|
qWarning() << "daemon ipc client failed to connect";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sendMessage("hello", "hello", false)) {
|
if (!sendMessage("hello", "hello", false)) {
|
||||||
qWarning() << "ipc client failed to send hello";
|
qWarning() << "daemon ipc client failed to send hello";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_connected = true;
|
m_connected = true;
|
||||||
qInfo() << "ipc client connected to server:" << kDaemonIpcName;
|
qDebug() << "daemon ipc client connected";
|
||||||
Q_EMIT connected();
|
Q_EMIT connected();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -49,17 +49,17 @@ bool DaemonIpcClient::connectToServer()
|
||||||
|
|
||||||
void DaemonIpcClient::handleDisconnected()
|
void DaemonIpcClient::handleDisconnected()
|
||||||
{
|
{
|
||||||
qWarning() << "ipc client disconnected from server";
|
qWarning() << "daemon ipc client disconnected from server";
|
||||||
m_connected = false;
|
m_connected = false;
|
||||||
|
|
||||||
if (!connectToServer()) {
|
if (!connectToServer()) {
|
||||||
qWarning() << "ipc client failed to reconnect to server";
|
qWarning() << "daemon ipc client failed to reconnect to server";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonIpcClient::handleErrorOccurred()
|
void DaemonIpcClient::handleErrorOccurred()
|
||||||
{
|
{
|
||||||
qWarning() << "ipc client error:" << m_socket->errorString();
|
qWarning() << "daemon ipc client error:" << m_socket->errorString();
|
||||||
m_connected = false;
|
m_connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,49 +73,49 @@ bool DaemonIpcClient::sendMessage(const QString &message, const QString &expectA
|
||||||
QByteArray messageData = message.toUtf8() + "\n";
|
QByteArray messageData = message.toUtf8() + "\n";
|
||||||
m_socket->write(messageData);
|
m_socket->write(messageData);
|
||||||
if (!m_socket->waitForBytesWritten(kTimeout)) {
|
if (!m_socket->waitForBytesWritten(kTimeout)) {
|
||||||
qWarning() << "ipc client failed to write command";
|
qWarning() << "daemon ipc client failed to write command";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!expectAck.isEmpty()) {
|
if (!expectAck.isEmpty()) {
|
||||||
qDebug() << "ipc client waiting for ack: " << expectAck;
|
qDebug() << "daemon ipc client waiting for ack: " << expectAck;
|
||||||
|
|
||||||
if (!m_socket->waitForReadyRead(kTimeout)) {
|
if (!m_socket->waitForReadyRead(kTimeout)) {
|
||||||
qWarning() << "ipc client failed to read response";
|
qWarning() << "daemon ipc client failed to read response";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray response = m_socket->readAll();
|
QByteArray response = m_socket->readAll();
|
||||||
if (response.isEmpty()) {
|
if (response.isEmpty()) {
|
||||||
qWarning() << "ipc client got empty response";
|
qWarning() << "daemon ipc client got empty response";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString responseData = QString::fromUtf8(response);
|
QString responseData = QString::fromUtf8(response);
|
||||||
if (responseData.isEmpty()) {
|
if (responseData.isEmpty()) {
|
||||||
qWarning() << "ipc client failed to convert response to string";
|
qWarning() << "daemon ipc client failed to convert response to string";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseData != expectAck + "\n") {
|
if (responseData != expectAck + "\n") {
|
||||||
qWarning() << "ipc client got unexpected response: " << responseData;
|
qWarning() << "daemon ipc client got unexpected response: " << responseData;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "ipc client sent message: " << messageData;
|
qDebug() << "daemon ipc client sent message: " << messageData;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DaemonIpcClient::keepAlive()
|
bool DaemonIpcClient::keepAlive()
|
||||||
{
|
{
|
||||||
if (!isConnected() && !connectToServer()) {
|
if (!isConnected() && !connectToServer()) {
|
||||||
qWarning() << "ipc client keep alive failed to connect";
|
qWarning() << "daemon ipc client keep alive failed to connect";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sendMessage("noop")) {
|
if (!sendMessage("noop")) {
|
||||||
qWarning() << "ipc client keep alive ping failed";
|
qWarning() << "daemon ipc client keep alive ping failed";
|
||||||
m_connected = false;
|
m_connected = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -164,31 +164,31 @@ QString DaemonIpcClient::requestLogPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_socket->waitForReadyRead(kTimeout)) {
|
if (!m_socket->waitForReadyRead(kTimeout)) {
|
||||||
qWarning() << "ipc client failed to read log path response";
|
qWarning() << "daemon ipc client failed to read log path response";
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray response = m_socket->readAll();
|
QByteArray response = m_socket->readAll();
|
||||||
if (response.isEmpty()) {
|
if (response.isEmpty()) {
|
||||||
qWarning() << "ipc client got empty log path response";
|
qWarning() << "daemon ipc client got empty log path response";
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString responseData = QString::fromUtf8(response);
|
QString responseData = QString::fromUtf8(response);
|
||||||
if (responseData.isEmpty()) {
|
if (responseData.isEmpty()) {
|
||||||
qWarning() << "ipc client failed to convert log path response to string";
|
qWarning() << "daemon ipc client failed to convert log path response to string";
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trimming removes newline from end of message.
|
// Trimming removes newline from end of message.
|
||||||
QStringList parts = responseData.trimmed().split("=");
|
QStringList parts = responseData.trimmed().split("=");
|
||||||
if (parts.size() != 2) {
|
if (parts.size() != 2) {
|
||||||
qWarning() << "ipc client got invalid log path response: " << responseData;
|
qWarning() << "daemon ipc client got invalid log path response: " << responseData;
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parts[0] != "logPath") {
|
if (parts[0] != "logPath") {
|
||||||
qWarning() << "ipc client got unexpected log path response: " << responseData;
|
qWarning() << "daemon ipc client got unexpected log path response: " << responseData;
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ DWORD MSWindowsProcess::waitForExit()
|
||||||
{
|
{
|
||||||
const auto kMaxWaitMilliseconds = 10000;
|
const auto kMaxWaitMilliseconds = 10000;
|
||||||
|
|
||||||
LOG_INFO("waiting for process to exit, pid: %lu", m_info.dwProcessId);
|
LOG_DEBUG("waiting for process to exit, pid: %lu", m_info.dwProcessId);
|
||||||
if (WaitForSingleObject(m_info.hProcess, kMaxWaitMilliseconds) != WAIT_OBJECT_0) {
|
if (WaitForSingleObject(m_info.hProcess, kMaxWaitMilliseconds) != WAIT_OBJECT_0) {
|
||||||
LOG_ERR("process did not exit within the expected time");
|
LOG_ERR("process did not exit within the expected time");
|
||||||
TerminateProcess(m_info.hProcess, 1);
|
TerminateProcess(m_info.hProcess, 1);
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ HANDLE openProcessForKill(const PROCESSENTRY32 &entry)
|
||||||
|
|
||||||
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
|
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
LOG((CLOG_ERR "could not open process handle for kill"));
|
LOG_ERR("could not open process handle for kill");
|
||||||
throw XArch(new XArchEvalWindows);
|
throw XArch(new XArchEvalWindows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,15 +101,15 @@ void MSWindowsWatchdog::stop()
|
||||||
m_running = false;
|
m_running = false;
|
||||||
|
|
||||||
if (!m_mainThread->wait(kThreadWaitSeconds)) {
|
if (!m_mainThread->wait(kThreadWaitSeconds)) {
|
||||||
LOG((CLOG_WARN "could not stop main thread"));
|
LOG_WARN("could not stop main thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_outputThread->wait(kThreadWaitSeconds)) {
|
if (!m_outputThread->wait(kThreadWaitSeconds)) {
|
||||||
LOG((CLOG_WARN "could not stop output thread"));
|
LOG_WARN("could not stop output thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_sasThread->wait(kThreadWaitSeconds)) {
|
if (!m_sasThread->wait(kThreadWaitSeconds)) {
|
||||||
LOG((CLOG_WARN "could not stop sas thread"));
|
LOG_WARN("could not stop sas thread");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,11 +121,11 @@ MSWindowsWatchdog::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES s
|
||||||
BOOL tokenRet = OpenProcessToken(process, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, &sourceToken);
|
BOOL tokenRet = OpenProcessToken(process, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, &sourceToken);
|
||||||
|
|
||||||
if (!tokenRet) {
|
if (!tokenRet) {
|
||||||
LOG((CLOG_ERR "could not open token, process handle: %d", process));
|
LOG_ERR("could not open token, process handle: %d", process);
|
||||||
throw XArch(new XArchEvalWindows());
|
throw XArch(new XArchEvalWindows());
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG((CLOG_DEBUG "got token %i, duplicating", sourceToken));
|
LOG_DEBUG("got token %i, duplicating", sourceToken);
|
||||||
|
|
||||||
HANDLE newToken;
|
HANDLE newToken;
|
||||||
BOOL duplicateRet = DuplicateTokenEx(
|
BOOL duplicateRet = DuplicateTokenEx(
|
||||||
|
|
@ -133,11 +133,11 @@ MSWindowsWatchdog::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES s
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!duplicateRet) {
|
if (!duplicateRet) {
|
||||||
LOG((CLOG_ERR "could not duplicate token %i", sourceToken));
|
LOG_ERR("could not duplicate token %i", sourceToken);
|
||||||
throw XArch(new XArchEvalWindows());
|
throw XArch(new XArchEvalWindows());
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG((CLOG_DEBUG "duplicated, new token: %i", newToken));
|
LOG_DEBUG("duplicated, new token: %i", newToken);
|
||||||
return newToken;
|
return newToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,7 +152,7 @@ MSWindowsWatchdog::getUserToken(LPSECURITY_ATTRIBUTES security, bool elevatedTok
|
||||||
// and so would be unusable with the new elevated process taking focus.
|
// and so would be unusable with the new elevated process taking focus.
|
||||||
if (elevatedToken || m_session.isProcessInSession("logonui.exe", nullptr)) {
|
if (elevatedToken || m_session.isProcessInSession("logonui.exe", nullptr)) {
|
||||||
|
|
||||||
LOG((CLOG_DEBUG "getting elevated token, %s", (elevatedToken ? "elevation required" : "at login screen")));
|
LOG_DEBUG("getting elevated token, %s", (elevatedToken ? "elevation required" : "at login screen"));
|
||||||
|
|
||||||
HANDLE process;
|
HANDLE process;
|
||||||
if (!m_session.isProcessInSession("winlogon.exe", &process)) {
|
if (!m_session.isProcessInSession("winlogon.exe", &process)) {
|
||||||
|
|
@ -167,7 +167,7 @@ MSWindowsWatchdog::getUserToken(LPSECURITY_ATTRIBUTES security, bool elevatedTok
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG((CLOG_DEBUG "getting non-elevated token"));
|
LOG_DEBUG("getting non-elevated token");
|
||||||
return m_session.getUserToken(security);
|
return m_session.getUserToken(security);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -178,6 +178,7 @@ void MSWindowsWatchdog::mainLoop(void *)
|
||||||
|
|
||||||
LOG_DEBUG("starting watchdog main loop");
|
LOG_DEBUG("starting watchdog main loop");
|
||||||
while (m_running) {
|
while (m_running) {
|
||||||
|
LOG_DEBUG3("locking process state mutex in watchdog main loop");
|
||||||
std::unique_lock lock(m_processStateMutex);
|
std::unique_lock lock(m_processStateMutex);
|
||||||
|
|
||||||
if (!m_command.empty() && !m_foreground && m_session.hasChanged()) {
|
if (!m_command.empty() && !m_foreground && m_session.hasChanged()) {
|
||||||
|
|
@ -190,11 +191,11 @@ void MSWindowsWatchdog::mainLoop(void *)
|
||||||
using enum ProcessState;
|
using enum ProcessState;
|
||||||
|
|
||||||
case Idle:
|
case Idle:
|
||||||
LOG_DEBUG3("watchdog: process idle");
|
LOG_DEBUG3("watchdog process state idle");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StartScheduled: {
|
case StartScheduled: {
|
||||||
LOG_DEBUG3("watchdog: process start scheduled");
|
LOG_DEBUG3("watchdog process start scheduled");
|
||||||
if (m_nextStartTime.has_value() && m_nextStartTime.value() <= ARCH->time()) {
|
if (m_nextStartTime.has_value() && m_nextStartTime.value() <= ARCH->time()) {
|
||||||
LOG_DEBUG("start time reached, queueing process start");
|
LOG_DEBUG("start time reached, queueing process start");
|
||||||
m_processState = StartPending;
|
m_processState = StartPending;
|
||||||
|
|
@ -202,7 +203,7 @@ void MSWindowsWatchdog::mainLoop(void *)
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case StartPending: {
|
case StartPending: {
|
||||||
LOG_INFO("daemon starting new process");
|
LOG_DEBUG("watchdog starting new process");
|
||||||
try {
|
try {
|
||||||
startProcess();
|
startProcess();
|
||||||
m_startFailures = 0;
|
m_startFailures = 0;
|
||||||
|
|
@ -217,15 +218,15 @@ void MSWindowsWatchdog::mainLoop(void *)
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Running: {
|
case Running: {
|
||||||
LOG_DEBUG3("watchdog: process running");
|
LOG_DEBUG3("watchdog process in running state");
|
||||||
if (!isProcessRunning()) {
|
if (!isProcessRunning()) {
|
||||||
LOG((CLOG_WARN "detected application not running, pid=%d", m_process->info().dwProcessId));
|
LOG_WARN("detected application not running, pid=%d", m_process->info().dwProcessId);
|
||||||
m_processState = StartPending;
|
m_processState = StartPending;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case StopPending: {
|
case StopPending: {
|
||||||
LOG_INFO("stopping running process");
|
LOG_DEBUG("watchdog stopping current process");
|
||||||
if (m_process != nullptr) {
|
if (m_process != nullptr) {
|
||||||
m_process->shutdown();
|
m_process->shutdown();
|
||||||
m_process.reset();
|
m_process.reset();
|
||||||
|
|
@ -237,16 +238,18 @@ void MSWindowsWatchdog::mainLoop(void *)
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG3("unlocking process state mutex in watchdog main loop");
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
// Sleep for only 100ms rather than 1 second so that the service can shut down faster.
|
// Sleep for only 100ms rather than 1 second so that the service can shut down faster.
|
||||||
|
LOG_DEBUG3("watchdog main loop sleeping");
|
||||||
ARCH->sleep(0.1);
|
ARCH->sleep(0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("watchdog main loop finished");
|
LOG_DEBUG("watchdog main loop finished");
|
||||||
|
|
||||||
if (m_process != nullptr) {
|
if (m_process != nullptr) {
|
||||||
LOG((CLOG_DEBUG "terminated running process on exit"));
|
LOG_DEBUG("terminated running process on exit");
|
||||||
m_process->shutdown();
|
m_process->shutdown();
|
||||||
m_process.reset();
|
m_process.reset();
|
||||||
}
|
}
|
||||||
|
|
@ -272,7 +275,7 @@ void MSWindowsWatchdog::startProcess()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_process != nullptr) {
|
if (m_process != nullptr) {
|
||||||
LOG((CLOG_DEBUG "closing existing process to make way for new one"));
|
LOG_DEBUG("closing existing process to make way for new one");
|
||||||
m_process->shutdown();
|
m_process->shutdown();
|
||||||
m_process.reset();
|
m_process.reset();
|
||||||
}
|
}
|
||||||
|
|
@ -305,14 +308,13 @@ void MSWindowsWatchdog::startProcess()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!createRet) {
|
if (!createRet) {
|
||||||
LOG((CLOG_CRIT "could not launch command"));
|
|
||||||
DWORD exitCode = 0;
|
DWORD exitCode = 0;
|
||||||
GetExitCodeProcess(m_process->info().hProcess, &exitCode);
|
GetExitCodeProcess(m_process->info().hProcess, &exitCode);
|
||||||
LOG((CLOG_ERR "exit code: %d", exitCode));
|
LOG_ERR("daemon failed to run command, exit code: %d", exitCode);
|
||||||
throw XArch(new XArchEvalWindows);
|
throw XArch(new XArchEvalWindows);
|
||||||
} else {
|
} else {
|
||||||
// Wait for program to fail. This needs to be 1 second, as the process may take some time to fail.
|
// Wait for program to fail. This needs to be 1 second, as the process may take some time to fail.
|
||||||
LOG_DEBUG("waiting for process start result");
|
LOG_DEBUG("watchdog waiting for process start result");
|
||||||
ARCH->sleep(1);
|
ARCH->sleep(1);
|
||||||
|
|
||||||
if (!isProcessRunning()) {
|
if (!isProcessRunning()) {
|
||||||
|
|
@ -320,19 +322,20 @@ void MSWindowsWatchdog::startProcess()
|
||||||
throw XArch("process immediately stopped");
|
throw XArch("process immediately stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG((CLOG_DEBUG "started core process from daemon"));
|
LOG_DEBUG("started core process from watchdog");
|
||||||
LOG(
|
LOG_DEBUG2(
|
||||||
(CLOG_DEBUG2 "process info, session=%i, elevated: %s, command=%s", m_session.getActiveSessionId(),
|
"process info, session=%i, elevated=%s, command: %s", //
|
||||||
m_elevateProcess ? "yes" : "no", m_command.c_str())
|
m_session.getActiveSessionId(), m_elevateProcess ? "yes" : "no", m_command.c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSWindowsWatchdog::setProcessConfig(const std::string_view &command, bool elevate)
|
void MSWindowsWatchdog::setProcessConfig(const std::string_view &command, bool elevate)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("updating watchdog process config");
|
LOG_DEBUG1("locking process state mutex for watchdog config change");
|
||||||
std::lock_guard lock(m_processStateMutex);
|
std::lock_guard lock(m_processStateMutex);
|
||||||
|
|
||||||
|
LOG_DEBUG("setting watchdog process config");
|
||||||
m_command = command;
|
m_command = command;
|
||||||
m_elevateProcess = elevate;
|
m_elevateProcess = elevate;
|
||||||
|
|
||||||
|
|
@ -390,7 +393,7 @@ void MSWindowsWatchdog::shutdownExistingProcesses()
|
||||||
// first we need to take a snapshot of the running processes
|
// first we need to take a snapshot of the running processes
|
||||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, kAllProcesses);
|
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, kAllProcesses);
|
||||||
if (snapshot == INVALID_HANDLE_VALUE) {
|
if (snapshot == INVALID_HANDLE_VALUE) {
|
||||||
LOG((CLOG_ERR "could not get process snapshot"));
|
LOG_ERR("could not get process snapshot");
|
||||||
throw XArch(new XArchEvalWindows);
|
throw XArch(new XArchEvalWindows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -401,7 +404,7 @@ void MSWindowsWatchdog::shutdownExistingProcesses()
|
||||||
// unlikely we can go any further
|
// unlikely we can go any further
|
||||||
BOOL gotEntry = Process32First(snapshot, &entry);
|
BOOL gotEntry = Process32First(snapshot, &entry);
|
||||||
if (!gotEntry) {
|
if (!gotEntry) {
|
||||||
LOG((CLOG_ERR "could not get first process entry"));
|
LOG_ERR("could not get first process entry");
|
||||||
throw XArch(new XArchEvalWindows);
|
throw XArch(new XArchEvalWindows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -409,7 +412,7 @@ void MSWindowsWatchdog::shutdownExistingProcesses()
|
||||||
while (gotEntry) {
|
while (gotEntry) {
|
||||||
|
|
||||||
if (HANDLE handle = openProcessForKill(entry); handle != nullptr) {
|
if (HANDLE handle = openProcessForKill(entry); handle != nullptr) {
|
||||||
LOG((CLOG_INFO "shutting down process, name=%s, pid=%d", entry.szExeFile, entry.th32ProcessID));
|
LOG_DEBUG("shutting down process, name=%s, pid=%d", entry.szExeFile, entry.th32ProcessID);
|
||||||
deskflow::platform::MSWindowsProcess::shutdown(handle, entry.th32ProcessID);
|
deskflow::platform::MSWindowsProcess::shutdown(handle, entry.th32ProcessID);
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
}
|
}
|
||||||
|
|
@ -422,7 +425,7 @@ void MSWindowsWatchdog::shutdownExistingProcesses()
|
||||||
if (err != ERROR_NO_MORE_FILES) {
|
if (err != ERROR_NO_MORE_FILES) {
|
||||||
|
|
||||||
// only worry about error if it's not the end of the snapshot
|
// only worry about error if it's not the end of the snapshot
|
||||||
LOG((CLOG_ERR "could not get next process entry"));
|
LOG_ERR("could not get next process entry");
|
||||||
throw XArch(new XArchEvalWindows);
|
throw XArch(new XArchEvalWindows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -558,13 +561,15 @@ void MSWindowsWatchdog::initSasFunc()
|
||||||
|
|
||||||
void MSWindowsWatchdog::sasLoop(void *) // NOSONAR - Thread entry point signature
|
void MSWindowsWatchdog::sasLoop(void *) // NOSONAR - Thread entry point signature
|
||||||
{
|
{
|
||||||
|
LOG_DEBUG3("watchdog creating sas event");
|
||||||
|
|
||||||
if (m_sendSasFunc == nullptr) {
|
if (m_sendSasFunc == nullptr) {
|
||||||
throw XArch("SendSAS function not initialized");
|
throw XArch("SendSAS function not initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (m_running) {
|
while (m_running) {
|
||||||
if (m_processState != ProcessState::Running) {
|
if (m_processState != ProcessState::Running) {
|
||||||
LOG_DEBUG2("watchdog: not running, skipping SendSAS");
|
LOG_DEBUG2("watchdog not running, skipping SendSAS");
|
||||||
ARCH->sleep(1);
|
ARCH->sleep(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue