mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
s390-tools: add lsstp utility
A small utility to display the STP information present in sysfs in a more readable way. Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
1df4d66387
commit
8b31319ddf
1
.gitignore
vendored
1
.gitignore
vendored
@@ -46,6 +46,7 @@ libutil/util_rec_example
|
||||
libutil/util_scandir_example
|
||||
libzds/libzds.a
|
||||
libvmcp/vmcp_example
|
||||
lsstp/lsstp
|
||||
mon_tools/mon_fsstatd
|
||||
mon_tools/mon_procd
|
||||
osasnmpd/osasnmpd
|
||||
|
||||
2
Makefile
2
Makefile
@@ -9,7 +9,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
||||
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
|
||||
genprotimg
|
||||
genprotimg lsstp
|
||||
|
||||
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
||||
|
||||
|
||||
18
lsstp/Makefile
Normal file
18
lsstp/Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
include ../common.mak
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
all: lsstp
|
||||
|
||||
lsstp: lsstp.o $(libs)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) \
|
||||
$(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 lsstp $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 lsstp.8 \
|
||||
$(DESTDIR)$(MANDIR)/man8
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ lsstp core
|
||||
|
||||
.PHONY: all install clean
|
||||
79
lsstp/lsstp.8
Normal file
79
lsstp/lsstp.8
Normal file
@@ -0,0 +1,79 @@
|
||||
.\" Copyright 2020 IBM Corp.
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH LSSTP 8 "Jul 2020" "s390-tools" "Linux Administrator's Manual"
|
||||
.SH NAME
|
||||
.B "lsstp "
|
||||
\- tool to show STP system information
|
||||
.SH SYNOPSIS
|
||||
.BI "lsstp "
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B lsstp
|
||||
displays information about the currenta Server Time Protocol (STP) configuration
|
||||
like Coordianted Timing Network (CTN) ID, Timing state and Leap seconds.
|
||||
.SH OUTPUT
|
||||
.TP
|
||||
.B STP online
|
||||
Whether the STP subsystem is online
|
||||
.TP
|
||||
.B CTN ID
|
||||
The ID of the Coordinated Time Network. If it can be decoded as EBCDIC it will be shown as EBCDIC String, otherwise a hexadecimal representation is shown.
|
||||
.TP
|
||||
.B CTN Type
|
||||
The type of timing network.
|
||||
.IP
|
||||
.B No CTN
|
||||
STP is not configured for attachment to a CTN.
|
||||
.IP
|
||||
.B STP-only
|
||||
STP is configured and attached to a CTN with only STP nodes.
|
||||
.IP
|
||||
.B Mixed
|
||||
STP is configured and attached to a CTN which contains both STP and External Time Reference (ETR) nodes.
|
||||
.TP
|
||||
.B Stratum
|
||||
The Stratum level of the STP clock. This indicates the number of servers in the timing path between the local STP clock and the selected primary time server.
|
||||
.TP
|
||||
.B Timing mode
|
||||
.IP
|
||||
.B Local
|
||||
The Time-of-day (TOD) clock is stepped to the local hardware oscillator and is not steered by the STP facility.
|
||||
.IP
|
||||
.B ETR
|
||||
The TOD clock is synchronized with an attached 9037 Sysplex Timer.
|
||||
.IP
|
||||
.B STP
|
||||
The TOD clock is steered by the STP facility to maintain synchronization with a Coordinated Server Time (CST).
|
||||
.IP
|
||||
.B Uninitialized
|
||||
The TOD clock is not initialized. The STP facility is allowed to perform a step adjustment to the TOD clock for synchronization.
|
||||
.TP
|
||||
.B Timing state
|
||||
The synchronization state of the STP facilty. Can be unsynchronzied, synchronized and stopped.
|
||||
.TP
|
||||
.B DST offset
|
||||
The Daylight savings time offset relative to UTC in minutes.
|
||||
.TP
|
||||
.B Timezone offset
|
||||
The offset of the local time relative to UTC in minutes.
|
||||
.TP
|
||||
.B Time offset
|
||||
The total time offset at the server. This field is only valid in mixed CTN configurations.
|
||||
.TP
|
||||
.B Active Leap seconds
|
||||
The number of Leap seconds that are currently in effect at the STP facility.
|
||||
.TP
|
||||
.B Leap second <insertion|delation> at
|
||||
If a Leap second insertion or deletetion is scheduled in the STP facility, this field will show the Day and Time of the scheduled change.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI "-v|--version"
|
||||
Print version number.
|
||||
.TP
|
||||
.BI "-h|--help"
|
||||
Print usage text.
|
||||
|
||||
.SH AUTHORS
|
||||
Sven Schnelle <svens@linux.ibm.com>
|
||||
218
lsstp/lsstp.c
Normal file
218
lsstp/lsstp.c
Normal file
@@ -0,0 +1,218 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <iconv.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "lib/util_opt.h"
|
||||
#include "lib/util_file.h"
|
||||
#include "lib/util_prg.h"
|
||||
#include "lib/util_path.h"
|
||||
|
||||
static const struct util_prg prg = {
|
||||
.desc = "Display STP system information",
|
||||
.args = "",
|
||||
.copyright_vec = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2020,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
};
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
struct stp_parms {
|
||||
uint64_t ctn_id;
|
||||
unsigned int online;
|
||||
unsigned int leap_seconds;
|
||||
int leap_seconds_diff;
|
||||
unsigned int leap_seconds_utc;
|
||||
unsigned int stratum;
|
||||
unsigned int ctn_type;
|
||||
unsigned int timing_mode;
|
||||
unsigned int timing_state;
|
||||
int dst_offset;
|
||||
int time_offset;
|
||||
int time_zone_offset;
|
||||
};
|
||||
|
||||
static int convert_ctn_id(char *in, char *out)
|
||||
{
|
||||
iconv_t ic;
|
||||
size_t inlen = sizeof(unsigned long long);
|
||||
size_t outlen = sizeof(unsigned long long);
|
||||
|
||||
ic = iconv_open("ISO-8859-1", "EBCDIC-US");
|
||||
if (ic == (iconv_t)-1) {
|
||||
warn("Could not initialize EBCDIC to ISO-8859-1 conversion table");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iconv(ic, &in, &inlen, (char **)&out, &outlen) == (size_t)-1) {
|
||||
warn("Code page translation EBCDIC to ISO-8859-1 failed");
|
||||
iconv_close(ic);
|
||||
return -1;
|
||||
}
|
||||
iconv_close(ic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *ctn_type_str(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case 0:
|
||||
return "No CTN defined";
|
||||
case 1:
|
||||
return "STP-only";
|
||||
case 2:
|
||||
return "mixed";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *tmd_to_str(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case 0:
|
||||
return "Local";
|
||||
case 1:
|
||||
return "ETR";
|
||||
case 2:
|
||||
return "STP";
|
||||
case 15:
|
||||
return "Uninitialized";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *tst_to_str(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case 0:
|
||||
return "Unsynchronized";
|
||||
case 1:
|
||||
return "Synchronized";
|
||||
case 2:
|
||||
return "Physical clock stopped";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *yesno_str(int val)
|
||||
{
|
||||
return val ? "yes" : "no";
|
||||
}
|
||||
|
||||
#define read_sysfs_attr(attr, parm, func, base) \
|
||||
do { \
|
||||
path = util_path_sysfs("devices/system/stp/%s", attr); \
|
||||
ret = func(parm, base, path); \
|
||||
if (ret) { \
|
||||
fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno)); \
|
||||
free(path); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
free(path); \
|
||||
} while (0)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct stp_parms parm = { 0 };
|
||||
char ctn_id[32] = { 0 };
|
||||
char *path;
|
||||
int ret, c;
|
||||
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
|
||||
for (;;) {
|
||||
c = util_opt_getopt_long(argc, argv);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'v':
|
||||
util_prg_print_version();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'h':
|
||||
util_prg_print_help();
|
||||
util_opt_print_help();
|
||||
exit(EXIT_SUCCESS);
|
||||
default:
|
||||
fprintf(stderr, "Try 'lsstp --help' for more information.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
read_sysfs_attr("online", &parm.online, util_file_read_ui, 10);
|
||||
if (!parm.online) {
|
||||
printf("STP disabled\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
read_sysfs_attr("ctn_id", &parm.ctn_id, util_file_read_ul, 16);
|
||||
read_sysfs_attr("ctn_type", &parm.ctn_type, util_file_read_ui, 10);
|
||||
read_sysfs_attr("stratum", &parm.stratum, util_file_read_ui, 10);
|
||||
read_sysfs_attr("leap_seconds", &parm.leap_seconds, util_file_read_ui, 10);
|
||||
read_sysfs_attr("timing_mode", &parm.timing_mode, util_file_read_ui, 10);
|
||||
read_sysfs_attr("timing_state", &parm.timing_state, util_file_read_ui, 10);
|
||||
read_sysfs_attr("dst_offset", &parm.dst_offset, util_file_read_i, 10);
|
||||
read_sysfs_attr("time_offset", &parm.time_offset, util_file_read_i, 10);
|
||||
read_sysfs_attr("time_zone_offset", &parm.time_zone_offset, util_file_read_i, 10);
|
||||
|
||||
if (convert_ctn_id((char *)&parm.ctn_id, ctn_id))
|
||||
snprintf(ctn_id, sizeof(ctn_id)-1, "%016" PRIx64, parm.ctn_id);
|
||||
|
||||
printf("STP online: %s\n"
|
||||
"CTN ID: %s\n"
|
||||
"CTN type: %s\n"
|
||||
"Stratum: %d\n"
|
||||
"Timing mode: %s\n"
|
||||
"Timing state: %s\n"
|
||||
"DST offset: %d\n"
|
||||
"Timezone offset: %d\n"
|
||||
"Time offset: %d\n"
|
||||
"Active leap seconds: %d\n",
|
||||
yesno_str(parm.online),
|
||||
ctn_id,
|
||||
ctn_type_str(parm.ctn_type),
|
||||
parm.stratum,
|
||||
tmd_to_str(parm.timing_mode),
|
||||
tst_to_str(parm.timing_state),
|
||||
parm.dst_offset,
|
||||
parm.time_zone_offset,
|
||||
parm.time_offset,
|
||||
parm.leap_seconds);
|
||||
|
||||
printf("Scheduled leap second: ");
|
||||
|
||||
path = util_path_sysfs("devices/system/stp/leap_seconds_scheduled");
|
||||
if (util_file_read_va(path, "%d,%d", &parm.leap_seconds_utc,
|
||||
&parm.leap_seconds_diff) == 2 &&
|
||||
parm.leap_seconds_diff && parm.leap_seconds_utc) {
|
||||
time_t lsoup = parm.leap_seconds_utc;
|
||||
|
||||
printf("%s at: %s UTC",
|
||||
parm.leap_seconds_diff > 0 ? "insertion" : "deletion",
|
||||
ctime(&lsoup));
|
||||
} else {
|
||||
printf("-\n");
|
||||
}
|
||||
free(path);
|
||||
return 0;
|
||||
out:
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user