cmdmon: add selectdata command
Add a command to report selection-specific data.
This commit is contained in:
parent
39a462496a
commit
03541f3626
8 changed files with 335 additions and 4 deletions
33
candm.h
33
candm.h
|
@ -106,7 +106,8 @@
|
|||
#define REQ_RESET_SOURCES 66
|
||||
#define REQ_AUTH_DATA 67
|
||||
#define REQ_CLIENT_ACCESSES_BY_INDEX3 68
|
||||
#define N_REQUEST_TYPES 69
|
||||
#define REQ_SELECT_DATA 69
|
||||
#define N_REQUEST_TYPES 70
|
||||
|
||||
/* Structure used to exchange timespecs independent of time_t size */
|
||||
typedef struct {
|
||||
|
@ -360,6 +361,11 @@ typedef struct {
|
|||
int32_t EOR;
|
||||
} REQ_AuthData;
|
||||
|
||||
typedef struct {
|
||||
uint32_t index;
|
||||
int32_t EOR;
|
||||
} REQ_SelectData;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#define PKT_TYPE_CMD_REQUEST 1
|
||||
|
@ -464,6 +470,7 @@ typedef struct {
|
|||
REQ_NTPData ntp_data;
|
||||
REQ_NTPSourceName ntp_source_name;
|
||||
REQ_AuthData auth_data;
|
||||
REQ_SelectData select_data;
|
||||
} data; /* Command specific parameters */
|
||||
|
||||
/* Padding used to prevent traffic amplification. It only defines the
|
||||
|
@ -504,7 +511,8 @@ typedef struct {
|
|||
#define RPY_AUTH_DATA 20
|
||||
#define RPY_CLIENT_ACCESSES_BY_INDEX3 21
|
||||
#define RPY_SERVER_STATS2 22
|
||||
#define N_REPLY_TYPES 23
|
||||
#define RPY_SELECT_DATA 23
|
||||
#define N_REPLY_TYPES 24
|
||||
|
||||
/* Status codes */
|
||||
#define STT_SUCCESS 0
|
||||
|
@ -744,6 +752,26 @@ typedef struct {
|
|||
int32_t EOR;
|
||||
} RPY_AuthData;
|
||||
|
||||
#define RPY_SD_OPTION_NOSELECT 0x1
|
||||
#define RPY_SD_OPTION_PREFER 0x2
|
||||
#define RPY_SD_OPTION_TRUST 0x4
|
||||
#define RPY_SD_OPTION_REQUIRE 0x8
|
||||
|
||||
typedef struct {
|
||||
uint32_t ref_id;
|
||||
IPAddr ip_addr;
|
||||
uint8_t state_char;
|
||||
uint8_t authentication;
|
||||
uint8_t pad[2];
|
||||
uint16_t conf_options;
|
||||
uint16_t eff_options;
|
||||
uint32_t last_sample_ago;
|
||||
Float score;
|
||||
Float lo_limit;
|
||||
Float hi_limit;
|
||||
int32_t EOR;
|
||||
} RPY_SelectData;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version;
|
||||
uint8_t pkt_type;
|
||||
|
@ -775,6 +803,7 @@ typedef struct {
|
|||
RPY_NTPData ntp_data;
|
||||
RPY_NTPSourceName ntp_source_name;
|
||||
RPY_AuthData auth_data;
|
||||
RPY_SelectData select_data;
|
||||
} data; /* Reply specific parameters */
|
||||
|
||||
} CMD_Reply;
|
||||
|
|
86
client.c
86
client.c
|
@ -1209,6 +1209,7 @@ give_help(void)
|
|||
"Time sources:\0\0"
|
||||
"sources [-a] [-v]\0Display information about current sources\0"
|
||||
"sourcestats [-a] [-v]\0Display statistics about collected measurements\0"
|
||||
"selectdata [-a] [-v]\0Display information about source selection\0"
|
||||
"reselect\0Force reselecting synchronisation source\0"
|
||||
"reselectdist <dist>\0Modify reselection distance\0"
|
||||
"\0\0"
|
||||
|
@ -1303,6 +1304,7 @@ enum {
|
|||
TAB_COMPLETE_RESET_OPTS,
|
||||
TAB_COMPLETE_SOURCES_OPTS,
|
||||
TAB_COMPLETE_SOURCESTATS_OPTS,
|
||||
TAB_COMPLETE_SELECTDATA_OPTS,
|
||||
TAB_COMPLETE_MAX_INDEX
|
||||
};
|
||||
|
||||
|
@ -1319,7 +1321,7 @@ command_name_generator(const char *text, int state)
|
|||
"manual", "maxdelay", "maxdelaydevratio", "maxdelayratio", "maxpoll",
|
||||
"maxupdateskew", "minpoll", "minstratum", "ntpdata", "offline", "online", "onoffline",
|
||||
"polltarget", "quit", "refresh", "rekey", "reselect", "reselectdist", "reset",
|
||||
"retries", "rtcdata", "serverstats", "settime", "shutdown", "smoothing",
|
||||
"retries", "rtcdata", "selectdata", "serverstats", "settime", "shutdown", "smoothing",
|
||||
"smoothtime", "sourcename", "sources", "sourcestats",
|
||||
"timeout", "tracking", "trimrtc", "waitsync", "writertc",
|
||||
NULL
|
||||
|
@ -1327,6 +1329,7 @@ command_name_generator(const char *text, int state)
|
|||
const char *add_options[] = { "peer", "pool", "server", NULL };
|
||||
const char *manual_options[] = { "on", "off", "delete", "list", "reset", NULL };
|
||||
const char *reset_options[] = { "sources", NULL };
|
||||
const char *selectdata_options[] = { "-a", "-v", NULL };
|
||||
const char *sources_options[] = { "-a", "-v", NULL };
|
||||
const char *sourcestats_options[] = { "-a", "-v", NULL };
|
||||
static int list_index, len;
|
||||
|
@ -1335,6 +1338,7 @@ command_name_generator(const char *text, int state)
|
|||
names[TAB_COMPLETE_ADD_OPTS] = add_options;
|
||||
names[TAB_COMPLETE_MANUAL_OPTS] = manual_options;
|
||||
names[TAB_COMPLETE_RESET_OPTS] = reset_options;
|
||||
names[TAB_COMPLETE_SELECTDATA_OPTS] = selectdata_options;
|
||||
names[TAB_COMPLETE_SOURCES_OPTS] = sources_options;
|
||||
names[TAB_COMPLETE_SOURCESTATS_OPTS] = sourcestats_options;
|
||||
|
||||
|
@ -1368,6 +1372,8 @@ command_name_completion(const char *text, int start, int end)
|
|||
tab_complete_index = TAB_COMPLETE_MANUAL_OPTS;
|
||||
} else if (!strcmp(first, "reset ")) {
|
||||
tab_complete_index = TAB_COMPLETE_RESET_OPTS;
|
||||
} else if (!strcmp(first, "selectdata ")) {
|
||||
tab_complete_index = TAB_COMPLETE_SELECTDATA_OPTS;
|
||||
} else if (!strcmp(first, "sources ")) {
|
||||
tab_complete_index = TAB_COMPLETE_SOURCES_OPTS;
|
||||
} else if (!strcmp(first, "sourcestats ")) {
|
||||
|
@ -2557,6 +2563,81 @@ process_cmd_ntpdata(char *line)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
process_cmd_selectdata(char *line)
|
||||
{
|
||||
CMD_Request request;
|
||||
CMD_Reply reply;
|
||||
uint32_t i, n_sources;
|
||||
int all, verbose, conf_options, eff_options;
|
||||
char name[256];
|
||||
IPAddr ip_addr;
|
||||
|
||||
parse_sources_options(line, &all, &verbose);
|
||||
|
||||
request.command = htons(REQ_N_SOURCES);
|
||||
if (!request_reply(&request, &reply, RPY_N_SOURCES, 0))
|
||||
return 0;
|
||||
|
||||
n_sources = ntohl(reply.data.n_sources.n_sources);
|
||||
|
||||
if (verbose) {
|
||||
printf( " .-- State: N - noselect, M - missing samples, d/D - large distance,\n");
|
||||
printf( " / ~ - jittery, w/W - waits for others, T - not trusted,\n");
|
||||
printf( "| x - falseticker, P - not preferred, U - waits for update,\n");
|
||||
printf( "| S - stale, O - orphan, + - combined, * - best.\n");
|
||||
printf( "| Effective options ------. (N - noselect, P - prefer\n");
|
||||
printf( "| Configured options -. \\ T - trust, R - require)\n");
|
||||
printf( "| Auth. enabled (Y/N) -. \\ \\ Offset interval --.\n");
|
||||
printf( "| | | | |\n");
|
||||
}
|
||||
|
||||
print_header("S Name/IP Address Auth COpts EOpts Last Score Interval ");
|
||||
|
||||
/* "S NNNNNNNNNNNNNNNNNNNNNNNNN A OOOO- OOOO- LLLL SSSSS LLLLLLL LLLLLLL" */
|
||||
|
||||
for (i = 0; i < n_sources; i++) {
|
||||
request.command = htons(REQ_SELECT_DATA);
|
||||
request.data.source_data.index = htonl(i);
|
||||
if (!request_reply(&request, &reply, RPY_SELECT_DATA, 0))
|
||||
return 0;
|
||||
|
||||
UTI_IPNetworkToHost(&reply.data.select_data.ip_addr, &ip_addr);
|
||||
if (!all && ip_addr.family == IPADDR_ID)
|
||||
continue;
|
||||
|
||||
format_name(name, sizeof (name), 25, ip_addr.family == IPADDR_UNSPEC,
|
||||
ntohl(reply.data.select_data.ref_id), 1, &ip_addr);
|
||||
|
||||
conf_options = ntohs(reply.data.select_data.conf_options);
|
||||
eff_options = ntohs(reply.data.select_data.eff_options);
|
||||
|
||||
print_report("%c %-25s %c %c%c%c%c%c %c%c%c%c%c %I %5.1f %+S %+S\n",
|
||||
reply.data.select_data.state_char,
|
||||
name,
|
||||
reply.data.select_data.authentication ? 'Y' : 'N',
|
||||
conf_options & RPY_SD_OPTION_NOSELECT ? 'N' : '-',
|
||||
conf_options & RPY_SD_OPTION_PREFER ? 'P' : '-',
|
||||
conf_options & RPY_SD_OPTION_TRUST ? 'T' : '-',
|
||||
conf_options & RPY_SD_OPTION_REQUIRE ? 'R' : '-',
|
||||
'-',
|
||||
eff_options & RPY_SD_OPTION_NOSELECT ? 'N' : '-',
|
||||
eff_options & RPY_SD_OPTION_PREFER ? 'P' : '-',
|
||||
eff_options & RPY_SD_OPTION_TRUST ? 'T' : '-',
|
||||
eff_options & RPY_SD_OPTION_REQUIRE ? 'R' : '-',
|
||||
'-',
|
||||
(unsigned long)ntohl(reply.data.select_data.last_sample_ago),
|
||||
UTI_FloatNetworkToHost(reply.data.select_data.score),
|
||||
UTI_FloatNetworkToHost(reply.data.select_data.lo_limit),
|
||||
UTI_FloatNetworkToHost(reply.data.select_data.hi_limit),
|
||||
REPORT_END);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
process_cmd_serverstats(char *line)
|
||||
{
|
||||
|
@ -3272,6 +3353,9 @@ process_line(char *line)
|
|||
} else if (!strcmp(command, "rtcdata")) {
|
||||
do_normal_submit = 0;
|
||||
ret = process_cmd_rtcreport(line);
|
||||
} else if (!strcmp(command, "selectdata")) {
|
||||
do_normal_submit = 0;
|
||||
ret = process_cmd_selectdata(line);
|
||||
} else if (!strcmp(command, "serverstats")) {
|
||||
do_normal_submit = 0;
|
||||
ret = process_cmd_serverstats(line);
|
||||
|
|
42
cmdmon.c
42
cmdmon.c
|
@ -138,6 +138,7 @@ static const char permissions[] = {
|
|||
PERMIT_AUTH, /* RESET_SOURCES */
|
||||
PERMIT_AUTH, /* AUTH_DATA */
|
||||
PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX3 */
|
||||
PERMIT_AUTH, /* SELECT_DATA */
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
|
@ -1282,6 +1283,43 @@ handle_auth_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
tx_message->data.auth_data.nak = htons(report.nak);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static uint16_t
|
||||
convert_select_options(int options)
|
||||
{
|
||||
return (options & SRC_SELECT_PREFER ? RPY_SD_OPTION_PREFER : 0) |
|
||||
(options & SRC_SELECT_NOSELECT ? RPY_SD_OPTION_NOSELECT : 0) |
|
||||
(options & SRC_SELECT_TRUST ? RPY_SD_OPTION_TRUST : 0) |
|
||||
(options & SRC_SELECT_REQUIRE ? RPY_SD_OPTION_REQUIRE : 0);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
handle_select_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
RPT_SelectReport report;
|
||||
|
||||
if (!SRC_GetSelectReport(ntohl(rx_message->data.select_data.index), &report)) {
|
||||
tx_message->status = htons(STT_NOSUCHSOURCE);
|
||||
return;
|
||||
}
|
||||
|
||||
tx_message->reply = htons(RPY_SELECT_DATA);
|
||||
|
||||
tx_message->data.select_data.ref_id = htonl(report.ref_id);
|
||||
UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.select_data.ip_addr);
|
||||
tx_message->data.select_data.state_char = report.state_char;
|
||||
tx_message->data.select_data.authentication = report.authentication;
|
||||
tx_message->data.select_data.conf_options = htons(convert_select_options(report.conf_options));
|
||||
tx_message->data.select_data.eff_options = htons(convert_select_options(report.eff_options));
|
||||
tx_message->data.select_data.last_sample_ago = htonl(report.last_sample_ago);
|
||||
tx_message->data.select_data.score = UTI_FloatHostToNetwork(report.score);
|
||||
tx_message->data.select_data.hi_limit = UTI_FloatHostToNetwork(report.hi_limit);
|
||||
tx_message->data.select_data.lo_limit = UTI_FloatHostToNetwork(report.lo_limit);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* Read a packet and process it */
|
||||
|
||||
|
@ -1668,6 +1706,10 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
|
|||
handle_auth_data(&rx_message, &tx_message);
|
||||
break;
|
||||
|
||||
case REQ_SELECT_DATA:
|
||||
handle_select_data(&rx_message, &tx_message);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_LOG("Unhandled command %d", rx_command);
|
||||
tx_message.status = htons(STT_FAILED);
|
||||
|
|
|
@ -414,6 +414,92 @@ This is the estimated offset of the source.
|
|||
*Std Dev*:::
|
||||
This is the estimated sample standard deviation.
|
||||
|
||||
[[selectdata]]*selectdata* [*-a*] [*-v*]::
|
||||
The *selectdata* command displays information specific to the selection of time
|
||||
sources. If the *-a* option is specified, all sources are displayed, including
|
||||
those that do not have a known address yet. With the *-v* option, extra caption
|
||||
lines are shown as a reminder of the meanings of the columns.
|
||||
+
|
||||
An example of the output is shown below.
|
||||
+
|
||||
----
|
||||
S Name/IP Address Auth COpts EOpts Last Score Interval
|
||||
====================================================================
|
||||
D foo.example.net Y ----- --TR- 4 1.0 -61ms +62ms
|
||||
* bar.example.net N ----- ----- 0 1.0 -6846us +7305us
|
||||
+ baz.example.net N ----- ----- 10 1.0 -7381us +7355us
|
||||
----
|
||||
+
|
||||
The columns are as follows:
|
||||
+
|
||||
*S*:::
|
||||
This column indicates the state of the source after the last source selection.
|
||||
It is similar to the state reported by the *sources* command, but more
|
||||
states are reported.
|
||||
:::
|
||||
The following states indicate the source is not considered selectable for
|
||||
synchronisation:
|
||||
* _N_ - has the *noselect* option.
|
||||
* _M_ - does not have enough measurements.
|
||||
* _d_ - has a root distance larger than the maximum distance (configured by the
|
||||
<<chrony.conf.adoc#maxdistance,*maxdistance*>> directive).
|
||||
* _~_ - has a jitter larger than the maximum jitter (configured by the
|
||||
<<chrony.conf.adoc#maxjitter,*maxjitter*>> directive).
|
||||
* _w_ - waits for other sources to get out of the _M_ state.
|
||||
* _S_ - has older measurements than other sources.
|
||||
* _O_ - has a stratum equal or larger than the orphan stratum (configured by
|
||||
the <<chrony.conf.adoc#local,*local*>> directive).
|
||||
* _T_ - does not fully agree with sources that have the *trust* option.
|
||||
* _x_ - does not agree with other sources (falseticker).
|
||||
:::
|
||||
The following states indicate the source is considered selectable, but it is
|
||||
not currently used for synchronisation:
|
||||
* _W_ - waits for other sources to be selectable (required by the
|
||||
<<chrony.conf.adoc#minsources,*minsources*>> directive, or
|
||||
the *require* option of another source).
|
||||
* _P_ - another selectable source is preferred due to the *prefer* option.
|
||||
* _U_ - waits for a new measurement (after selecting a different best source).
|
||||
* _D_ - has, or recently had, a root distance which is too large to be combined
|
||||
with other sources (configured by the
|
||||
<<chrony.conf.adoc#combinelimit,*combinelimit*>> directive).
|
||||
:::
|
||||
The following states indicate the source is used for synchronisation of the
|
||||
local clock:
|
||||
* _+_ - combined with the best source.
|
||||
* _*_ - selected as the best source to update the reference data (e.g. root
|
||||
delay, root dispersion).
|
||||
*Name/IP address*:::
|
||||
This column shows the name or IP address of the source if it is an NTP server,
|
||||
or the reference ID if it is a reference clock.
|
||||
*Auth*:::
|
||||
This column indicites whether an authentication mechanism is enabled for the
|
||||
source. _Y_ means yes and _N_ means no.
|
||||
*COpts*:::
|
||||
This column displays the configured selection options of the source.
|
||||
* _N_ indicates the *noselect* option.
|
||||
* _P_ indicates the *prefer* option.
|
||||
* _T_ indicates the *trust* option.
|
||||
* _R_ indicates the *require* option.
|
||||
*EOpts*:::
|
||||
This column displays the current effective selection options of the source,
|
||||
which can be different from the configured options due to the authentication
|
||||
selection mode (configured by the
|
||||
<<chrony.conf.adoc#authselmode,*authselmode*>> directive). The symbols are the
|
||||
same as in the *COpts* column.
|
||||
*Last*:::
|
||||
This column displays how long ago was the last measurement of the source made
|
||||
when the selection was performed.
|
||||
*Score*:::
|
||||
This column displays the current score against the source in the _*_ state. The
|
||||
scoring system avoids frequent reselection when multiple sources have a similar
|
||||
root distance. A value larger than 1 indicates this source was better than the
|
||||
_*_ source in recent selections. If the score reaches 10, the best source will
|
||||
be reselected and the scores will be reset to 1.
|
||||
*Interval*:::
|
||||
This column displays the lower and upper endpoint of the interval which was
|
||||
expected to contain the true offset of the local clock considering the root
|
||||
distance at the time of the selection.
|
||||
|
||||
[[reselect]]*reselect*::
|
||||
To avoid excessive switching between sources, *chronyd* can stay synchronised
|
||||
to a source even when it is not currently the best one among the available
|
||||
|
|
|
@ -126,6 +126,7 @@ static const struct request_length request_lengths[] = {
|
|||
REQ_LENGTH_ENTRY(auth_data, auth_data), /* AUTH_DATA */
|
||||
REQ_LENGTH_ENTRY(client_accesses_by_index,
|
||||
client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX3 */
|
||||
REQ_LENGTH_ENTRY(select_data, select_data), /* SELECT_DATA */
|
||||
};
|
||||
|
||||
static const uint16_t reply_lengths[] = {
|
||||
|
@ -152,6 +153,7 @@ static const uint16_t reply_lengths[] = {
|
|||
RPY_LENGTH_ENTRY(auth_data), /* AUTH_DATA */
|
||||
RPY_LENGTH_ENTRY(client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX3 */
|
||||
RPY_LENGTH_ENTRY(server_stats), /* SERVER_STATS2 */
|
||||
RPY_LENGTH_ENTRY(select_data), /* SELECT_DATA */
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
|
|
13
reports.h
13
reports.h
|
@ -178,4 +178,17 @@ typedef struct {
|
|||
int nak;
|
||||
} RPT_AuthReport;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ref_id;
|
||||
IPAddr ip_addr;
|
||||
char state_char;
|
||||
int authentication;
|
||||
int conf_options;
|
||||
int eff_options;
|
||||
uint32_t last_sample_ago;
|
||||
double score;
|
||||
double lo_limit;
|
||||
double hi_limit;
|
||||
} RPT_SelectReport;
|
||||
|
||||
#endif /* GOT_REPORTS_H */
|
||||
|
|
74
sources.c
74
sources.c
|
@ -316,6 +316,8 @@ SRC_ResetInstance(SRC_Instance instance)
|
|||
instance->leap = LEAP_Unsynchronised;
|
||||
instance->leap_vote = 0;
|
||||
|
||||
memset(&instance->sel_info, 0, sizeof (instance->sel_info));
|
||||
|
||||
SST_ResetInstance(instance->stats);
|
||||
}
|
||||
|
||||
|
@ -1509,6 +1511,78 @@ SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timespec
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static char
|
||||
get_status_char(SRC_Status status)
|
||||
{
|
||||
switch (status) {
|
||||
case SRC_UNSELECTABLE:
|
||||
return 'N';
|
||||
case SRC_BAD_STATS:
|
||||
return 'M';
|
||||
case SRC_BAD_DISTANCE:
|
||||
return 'd';
|
||||
case SRC_JITTERY:
|
||||
return '~';
|
||||
case SRC_WAITS_STATS:
|
||||
return 'w';
|
||||
case SRC_STALE:
|
||||
return 'S';
|
||||
case SRC_ORPHAN:
|
||||
return 'O';
|
||||
case SRC_UNTRUSTED:
|
||||
return 'T';
|
||||
case SRC_FALSETICKER:
|
||||
return 'x';
|
||||
case SRC_WAITS_SOURCES:
|
||||
return 'W';
|
||||
case SRC_NONPREFERRED:
|
||||
return 'P';
|
||||
case SRC_WAITS_UPDATE:
|
||||
return 'U';
|
||||
case SRC_DISTANT:
|
||||
return 'D';
|
||||
case SRC_OUTLIER:
|
||||
return 'L';
|
||||
case SRC_UNSELECTED:
|
||||
return '+';
|
||||
case SRC_SELECTED:
|
||||
return '*';
|
||||
default:
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
SRC_GetSelectReport(int index, RPT_SelectReport *report)
|
||||
{
|
||||
SRC_Instance inst;
|
||||
|
||||
if (index >= n_sources || index < 0)
|
||||
return 0;
|
||||
|
||||
inst = sources[index];
|
||||
|
||||
report->ref_id = inst->ref_id;
|
||||
if (inst->ip_addr)
|
||||
report->ip_addr = *inst->ip_addr;
|
||||
else
|
||||
report->ip_addr.family = IPADDR_UNSPEC;
|
||||
report->state_char = get_status_char(inst->status);
|
||||
report->authentication = inst->authenticated;
|
||||
report->conf_options = inst->conf_sel_options;
|
||||
report->eff_options = inst->sel_options;
|
||||
report->last_sample_ago = inst->sel_info.last_sample_ago;
|
||||
report->score = inst->sel_score;
|
||||
report->lo_limit = inst->sel_info.lo_limit;
|
||||
report->hi_limit = inst->sel_info.hi_limit;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
SRC_Type
|
||||
SRC_GetType(int index)
|
||||
{
|
||||
|
|
|
@ -130,9 +130,10 @@ extern int SRC_IsSyncPeer(SRC_Instance inst);
|
|||
extern int SRC_IsReachable(SRC_Instance inst);
|
||||
extern int SRC_ReadNumberOfSources(void);
|
||||
extern int SRC_ActiveSources(void);
|
||||
extern int SRC_ReportSource(int index, RPT_SourceReport *report, struct timespec *now);
|
||||
|
||||
extern int SRC_ReportSource(int index, RPT_SourceReport *report, struct timespec *now);
|
||||
extern int SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timespec *now);
|
||||
extern int SRC_GetSelectReport(int index, RPT_SelectReport *report);
|
||||
|
||||
extern SRC_Type SRC_GetType(int index);
|
||||
|
||||
|
|
Loading…
Reference in a new issue