int main(int argc, char **argv) { PtpClock *ptpClock; Integer16 ret; TimingService *ts; startupInProgress = TRUE; /** * 将所选择的时间服务器及其他服务器信息存储到@timingDomain */ memset(&timingDomain, 0, sizeof(timingDomain)); timingDomainSetup(&timingDomain); timingDomain.electionLeft = 10; /* Initialize run time options with command line arguments */ /** * 初始化配置,存储在结构体@rtOpts中 */ if (!(ptpClock = ptpdStartup(argc, argv, &ret, &rtOpts))) { if (ret != 0 && !rtOpts.checkConfigOnly) ERROR(USER_DESCRIPTION" startup failed\n"); return ret; } /** * 设置同个时间域中选举时间服务器的最大延迟,防止抖动 */ timingDomain.electionDelay = rtOpts.electionDelay; /* configure PTP TimeService */ timingDomain.services[0] = &ptpClock->timingService; ts = timingDomain.services[0]; strncpy(ts->id, "PTP0", TIMINGSERVICE_MAX_DESC); ts->dataSet.priority1 = rtOpts.preferNTP; ts->dataSet.type = TIMINGSERVICE_PTP; ts->config = &rtOpts; ts->controller = ptpClock; ts->timeout = rtOpts.idleTimeout; ts->updateInterval = 1; ts->holdTime = rtOpts.ntpOptions.failoverTimeout; timingDomain.serviceCount = 1; if (rtOpts.ntpOptions.enableEngine) { ntpSetup(&rtOpts, ptpClock); } else { timingDomain.serviceCount = 1; timingDomain.services[1] = NULL; } timingDomain.init(&timingDomain); /** * 定义协议的各状态更新时间为1个时间单位,即一个US_TIMER_INTERVAL(62500us) */ timingDomain.updateInterval = 1; startupInProgress = FALSE; /* global variable for message(), please see comment on top of this file */ G_ptpClock = ptpClock; /* do the protocol engine */ /** * 进入基于状态机的协议实现,无限循环 */ protocol(&rtOpts, ptpClock); /* forever loop.. */ /* this also calls ptpd shutdown */ timingDomain.shutdown(&timingDomain); NOTIFY("Self shutdown\n"); return 1; }
void restartSubsystems(RunTimeOpts *rtOpts, PtpClock *ptpClock) { DBG("RestartSubsystems: %d\n",rtOpts->restartSubsystems); /* So far, PTP_INITIALIZING is required for both network and protocol restart */ if((rtOpts->restartSubsystems & PTPD_RESTART_PROTOCOL) || (rtOpts->restartSubsystems & PTPD_RESTART_NETWORK)) { if(rtOpts->restartSubsystems & PTPD_RESTART_NETWORK) { NOTIFY("Applying network configuration: going into PTP_INITIALIZING\n"); } /* These parameters have to be passed to ptpClock before re-init */ ptpClock->clockQuality.clockClass = rtOpts->clockQuality.clockClass; ptpClock->slaveOnly = rtOpts->slaveOnly; ptpClock->disabled = rtOpts->portDisabled; if(rtOpts->restartSubsystems & PTPD_RESTART_PROTOCOL) { INFO("Applying protocol configuration: going into %s\n", ptpClock->disabled ? "PTP_DISABLED" : "PTP_INITIALIZING"); } /* Move back to primary interface only during configuration changes. */ ptpClock->runningBackupInterface = FALSE; toState(ptpClock->disabled ? PTP_DISABLED : PTP_INITIALIZING, rtOpts, ptpClock); } else { /* Nothing happens here for now - SIGHUP handler does this anyway */ if(rtOpts->restartSubsystems & PTPD_UPDATE_DATASETS) { NOTIFY("Applying PTP engine configuration: updating datasets\n"); updateDatasets(ptpClock, rtOpts); }} /* Nothing happens here for now - SIGHUP handler does this anyway */ if(rtOpts->restartSubsystems & PTPD_RESTART_LOGGING) { NOTIFY("Applying logging configuration: restarting logging\n"); } if(rtOpts->restartSubsystems & PTPD_RESTART_ACLS) { NOTIFY("Applying access control list configuration\n"); /* re-compile ACLs */ freeIpv4AccessList(&ptpClock->netPath.timingAcl); freeIpv4AccessList(&ptpClock->netPath.managementAcl); if(rtOpts->timingAclEnabled) { ptpClock->netPath.timingAcl=createIpv4AccessList(rtOpts->timingAclPermitText, rtOpts->timingAclDenyText, rtOpts->timingAclOrder); } if(rtOpts->managementAclEnabled) { ptpClock->netPath.managementAcl=createIpv4AccessList(rtOpts->managementAclPermitText, rtOpts->managementAclDenyText, rtOpts->managementAclOrder); } } #ifdef PTPD_STATISTICS /* Reinitialising the outlier filter containers */ if(rtOpts->restartSubsystems & PTPD_RESTART_FILTERS) { NOTIFY("Applying filter configuration: re-initialising filters\n"); freeDoubleMovingStatFilter(&ptpClock->filterMS); freeDoubleMovingStatFilter(&ptpClock->filterSM); ptpClock->oFilterMS.shutdown(&ptpClock->oFilterMS); ptpClock->oFilterSM.shutdown(&ptpClock->oFilterSM); outlierFilterSetup(&ptpClock->oFilterMS); outlierFilterSetup(&ptpClock->oFilterSM); ptpClock->oFilterMS.init(&ptpClock->oFilterMS,&rtOpts->oFilterMSConfig, "delayMS"); ptpClock->oFilterSM.init(&ptpClock->oFilterSM,&rtOpts->oFilterSMConfig, "delaySM"); if(rtOpts->filterMSOpts.enabled) { ptpClock->filterMS = createDoubleMovingStatFilter(&rtOpts->filterMSOpts,"delayMS"); } if(rtOpts->filterSMOpts.enabled) { ptpClock->filterSM = createDoubleMovingStatFilter(&rtOpts->filterSMOpts, "delaySM"); } } #endif /* PTPD_STATISTICS */ ptpClock->timingService.reloadRequested = TRUE; if(rtOpts->restartSubsystems & PTPD_RESTART_NTPENGINE && timingDomain.serviceCount > 1) { ptpClock->ntpControl.timingService.shutdown(&ptpClock->ntpControl.timingService); } if((rtOpts->restartSubsystems & PTPD_RESTART_NTPENGINE) || (rtOpts->restartSubsystems & PTPD_RESTART_NTPCONFIG)) { ntpSetup(rtOpts, ptpClock); } if((rtOpts->restartSubsystems & PTPD_RESTART_NTPENGINE) && rtOpts->ntpOptions.enableEngine) { timingServiceSetup(&ptpClock->ntpControl.timingService); ptpClock->ntpControl.timingService.init(&ptpClock->ntpControl.timingService); } ptpClock->timingService.dataSet.priority1 = rtOpts->preferNTP; timingDomain.electionDelay = rtOpts->electionDelay; if(timingDomain.electionLeft > timingDomain.electionDelay) { timingDomain.electionLeft = timingDomain.electionDelay; } timingDomain.services[0]->holdTime = rtOpts->ntpOptions.failoverTimeout; if(timingDomain.services[0]->holdTimeLeft > timingDomain.services[0]->holdTime) { timingDomain.services[0]->holdTimeLeft = rtOpts->ntpOptions.failoverTimeout; } ptpClock->timingService.timeout = rtOpts->idleTimeout; /* Update PI servo parameters */ setupPIservo(&ptpClock->servo, rtOpts); /* Config changes don't require subsystem restarts - acknowledge it */ if(rtOpts->restartSubsystems == PTPD_RESTART_NONE) { NOTIFY("Applying configuration\n"); } if(rtOpts->restartSubsystems != -1) rtOpts->restartSubsystems = 0; }