void ptpdShutdown(PtpClock * ptpClock) { extern RunTimeOpts rtOpts; netShutdown(&ptpClock->netPath); #ifdef PTPD_NTPDC ntpShutdown(&rtOpts.ntpOptions, &ptpClock->ntpControl); #endif /* PTPD_NTPDC */ free(ptpClock->foreign); /* free management messages, they can have dynamic memory allocated */ if(ptpClock->msgTmpHeader.messageType == MANAGEMENT) freeManagementTLV(&ptpClock->msgTmp.manage); freeManagementTLV(&ptpClock->outgoingManageTmp); #ifdef PTPD_SNMP snmpShutdown(); #endif /* PTPD_SNMP */ #ifdef HAVE_SYS_TIMEX_H #ifndef PTPD_STATISTICS /* Not running statistics code - write observed drift to driftfile if enabled, inform user */ if(ptpClock->slaveOnly && !ptpClock->servo.runningMaxOutput) saveDrift(ptpClock, &rtOpts, FALSE); #else /* We are running statistics code - save drift on exit only if we're not monitoring servo stability */ if(!rtOpts.servoStabilityDetection && !ptpClock->servo.runningMaxOutput) saveDrift(ptpClock, &rtOpts, FALSE); #endif /* PTPD_STATISTICS */ #endif /* HAVE_SYS_TIMEX_H */ if (rtOpts.currentConfig != NULL) dictionary_del(rtOpts.currentConfig); if(rtOpts.cliConfig != NULL) dictionary_del(rtOpts.cliConfig); FilterDestroy(ptpClock->owd_filt); FilterDestroy(ptpClock->ofm_filt); free(ptpClock); ptpClock = NULL; extern PtpClock* G_ptpClock; G_ptpClock = NULL; /* properly clean lockfile (eventough new deaemons can acquire the lock after we die) */ if(!rtOpts.ignore_daemon_lock && G_lockFilePointer != NULL) { fclose(G_lockFilePointer); } unlink(rtOpts.lockFile); if(rtOpts.statusLog.logEnabled) { /* close and remove the status file */ if(rtOpts.statusLog.logFP != NULL) fclose(rtOpts.statusLog.logFP); unlink(rtOpts.statusLog.logPath); } }
void updatePtpEngineStats (PtpClock* ptpClock, RunTimeOpts* rtOpts) { DBG("Refreshing slave engine stats counters\n"); ptpClock->slaveStats.owdMean = ptpClock->slaveStats.owdStats.meanContainer.mean; ptpClock->slaveStats.owdStdDev = ptpClock->slaveStats.owdStats.stdDev; ptpClock->slaveStats.ofmMean = ptpClock->slaveStats.ofmStats.meanContainer.mean; ptpClock->slaveStats.ofmStdDev = ptpClock->slaveStats.ofmStats.stdDev; ptpClock->slaveStats.statsCalculated = TRUE; ptpClock->servo.driftMean = ptpClock->servo.driftStats.meanContainer.mean; ptpClock->servo.driftStdDev = ptpClock->servo.driftStats.stdDev; ptpClock->servo.statsCalculated = TRUE; /* Handle the calibration delay - x periods of stats updates until servo starts */ if(rtOpts->calibrationDelay) { ++ptpClock->statsUpdates; if(!ptpClock->isCalibrated && ptpClock->statsUpdates >= rtOpts->calibrationDelay) { NOTICE("PTP engine now calibrated - enabling clock control\n"); ptpClock->isCalibrated = TRUE; ptpClock->statsUpdates = 0; } } if( (rtOpts->calibrationDelay == 0) || ptpClock->isCalibrated ) if(rtOpts->servoStabilityDetection) { ++ptpClock->servo.updateCount; if ( !ptpClock->servo.runningMaxOutput && (ptpClock->servo.driftStdDev <= ptpClock->servo.stabilityThreshold)) { /* Only update the stable period counter if we received some Sync messages since last update */ if(ptpClock->lastSyncCounter > 0) { if((ptpClock->counters.syncMessagesReceived - ptpClock->lastSyncCounter) == 0) ptpClock->servo.stableCount = 0; else ++ptpClock->servo.stableCount; } else ++ptpClock->servo.stableCount; ptpClock->lastSyncCounter = ptpClock->counters.syncMessagesReceived; } else ptpClock->servo.stableCount = 0; /* Servo considered stable - drift std dev below threshold for n measurements - saving drift*/ if(ptpClock->servo.stableCount >= ptpClock->servo.stabilityPeriod) { if(!ptpClock->servo.isStable) { NOTICE("Clock servo now stable - took %d seconds\n", rtOpts->statsUpdateInterval * ptpClock->servo.updateCount); #ifdef HAVE_SYS_TIMEX_H saveDrift(ptpClock, rtOpts, FALSE); #endif /* HAVE_SYS_TIMEX_H */ } else { #ifdef HAVE_SYS_TIMEX_H saveDrift(ptpClock, rtOpts, TRUE); #endif /* HAVE_SYS_TIMEX_H */ } ptpClock->servo.isStable = TRUE; ptpClock->servo.stableCount = 0; ptpClock->servo.updateCount = 0; } else if(ptpClock->servo.updateCount >= ptpClock->servo.stabilityTimeout) { ptpClock->servo.stableCount = 0; ptpClock->servo.updateCount = 0; if(!ptpClock->servo.isStable) { if(ptpClock->servo.runningMaxOutput) { WARNING("Clock servo not stable after %d seconds - running at maximum rate.\n", rtOpts->statsUpdateInterval * ptpClock->servo.stabilityTimeout); } else { WARNING("Clock servo not stable after %d seconds since last check. Saving current observed drift.\n", rtOpts->statsUpdateInterval * ptpClock->servo.stabilityTimeout); #ifdef HAVE_SYS_TIMEX_H saveDrift(ptpClock, rtOpts, FALSE); #endif /* HAVE_SYS_TIMEX_H */ } } else { WARNING("Clock servo no longer stable\n"); ptpClock->servo.isStable = FALSE; } } } DBG("servo stablecount: %d\n",ptpClock->servo.stableCount); resetDoublePermanentStdDev(&ptpClock->slaveStats.owdStats); resetDoublePermanentStdDev(&ptpClock->slaveStats.ofmStats); resetDoublePermanentStdDev(&ptpClock->servo.driftStats); }
void ptpdShutdown(PtpClock * ptpClock) { extern RunTimeOpts rtOpts; /* * go into DISABLED state so the FSM can call any PTP-specific shutdown actions, * such as canceling unicast transmission */ toState(PTP_DISABLED, &rtOpts, ptpClock); netShutdown(&ptpClock->netPath); free(ptpClock->foreign); /* free management and signaling messages, they can have dynamic memory allocated */ if(ptpClock->msgTmpHeader.messageType == MANAGEMENT) freeManagementTLV(&ptpClock->msgTmp.manage); freeManagementTLV(&ptpClock->outgoingManageTmp); if(ptpClock->msgTmpHeader.messageType == SIGNALING) freeSignalingTLV(&ptpClock->msgTmp.signaling); freeSignalingTLV(&ptpClock->outgoingSignalingTmp); #ifdef PTPD_SNMP snmpShutdown(); #endif /* PTPD_SNMP */ #ifndef PTPD_STATISTICS /* Not running statistics code - write observed drift to driftfile if enabled, inform user */ if(ptpClock->slaveOnly && !ptpClock->servo.runningMaxOutput) saveDrift(ptpClock, &rtOpts, FALSE); #else ptpClock->oFilterMS.shutdown(&ptpClock->oFilterMS); ptpClock->oFilterSM.shutdown(&ptpClock->oFilterSM); freeDoubleMovingStatFilter(&ptpClock->filterMS); freeDoubleMovingStatFilter(&ptpClock->filterSM); /* We are running statistics code - save drift on exit only if we're not monitoring servo stability */ if(!rtOpts.servoStabilityDetection && !ptpClock->servo.runningMaxOutput) saveDrift(ptpClock, &rtOpts, FALSE); #endif /* PTPD_STATISTICS */ if (rtOpts.currentConfig != NULL) dictionary_del(&rtOpts.currentConfig); if(rtOpts.cliConfig != NULL) dictionary_del(&rtOpts.cliConfig); timerShutdown(ptpClock->timers); free(ptpClock); ptpClock = NULL; extern PtpClock* G_ptpClock; G_ptpClock = NULL; /* properly clean lockfile (eventough new deaemons can acquire the lock after we die) */ if(!rtOpts.ignore_daemon_lock && G_lockFilePointer != NULL) { fclose(G_lockFilePointer); G_lockFilePointer = NULL; } unlink(rtOpts.lockFile); if(rtOpts.statusLog.logEnabled) { /* close and remove the status file */ if(rtOpts.statusLog.logFP != NULL) { fclose(rtOpts.statusLog.logFP); rtOpts.statusLog.logFP = NULL; } unlink(rtOpts.statusLog.logPath); } stopLogging(&rtOpts); }