Compare commits

..

9 Commits

Author SHA1 Message Date
HATAYAMA Daisuke b63c88b627 man: describe "symlink" and "systemctl link" explicitly in UNIT FILE LOAD PATH
There are sometimes users who put unit files in a location that is inaccessible
when systemd starts although they are not found and thus not started because
the corresponding mount units have not activated yet.

There is already a warning for such issue in man 8 systemctl:

     link PATH...
         ...<snip>...
         The file system where
         the linked unit files are located must be accessible
         when systemd is started (e.g. anything underneath /home
         or /var is not allowed, unless those directories are
         located on the root file system).

However, it looks that it's difficult to find the warning because introductory
users typically doesn't know systemctl link.

Although there is a description in UNIT FILE LOAD PATH pointing to systemctl
link, symlink is now not explicitly mentioned there and thus users doesn't
easily get aware of they should read it.

To deal with this, let's describe "symlink" and "systemctl link" more
explicitly in UNIT FILE LOAD PATH.
2020-01-09 18:52:13 +01:00
Lennart Poettering 8ac7339648
Merge pull request #14525 from yuwata/mount-use-format-table
systemd-mount: use format-table.[ch]
2020-01-09 15:47:24 +01:00
Yu Watanabe 0ca1926ec3 bash-completion: networkctl: support --full and --lines 2020-01-09 15:43:18 +01:00
Lennart Poettering 404308486a core: be more restrictive on the dependency types we allow to be created transiently
We should allow the ones that the [Unit] section of regular unit files
may accet, but no other, in particular not the internal deps we
synthesize as reverse of explicitly configured ones, such was WantedBy=.

Fixes: #14251
2020-01-09 15:42:34 +01:00
Yu Watanabe cf57766d79 timedatectl: use format-table.[ch] 2020-01-09 15:40:50 +01:00
Yu Watanabe a5279634c0 systemd-mount: add --no-legend command line option 2020-01-09 20:16:03 +09:00
Yu Watanabe 6ae6ea55d8 systemd-mount: use format-table.[ch] 2020-01-09 20:16:03 +09:00
Yu Watanabe f93d876c80 format-table: introduce TABLE_PATH 2020-01-09 20:16:03 +09:00
Thomas Schmitt 19212f2781 udev: don't import parent ID_FS_ data on partitions
When probing partitions, we inherit important information from the parent
disk device such as ID_MODEL, and usage of such properties is seen to
be acceptable and well established.

However, we need to exclude filesystem information from the properties
that get inherited. Information about the device content should not be
passed on in this way.

For example, Linux distro install media commonly uses an ISO filesystem
plus a partition table. The ISO filesystem is detected on the main disk
device, but we should not pass down those details to the partitions,
some or all of which may be pointing at storage areas completely distinct
from the ISO filesystem.

This is particularly problematic when adding new partitions on media
set up in this way (since the new partitions are then reported to contain
the parent device's ISO filesystem), or when dealing with more unusual
hybrid ISO layouts. The inaccuracy of information here inversely affects
users of blkid and udev's persistent storage symlinks.

Exclude ID_FS_* properties from the inheritance chain to avoid these
problems.

Fixes: #14408
2020-01-09 11:20:55 +01:00
9 changed files with 264 additions and 157 deletions

View File

@ -96,6 +96,7 @@
</varlistentry>
<xi:include href="standard-options.xml" xpointer="no-pager"/>
<xi:include href="standard-options.xml" xpointer="no-legend" />
<xi:include href="standard-options.xml" xpointer="no-ask-password"/>
<varlistentry>

View File

@ -467,10 +467,12 @@
<programlisting>systemd-analyze --user unit-paths</programlisting>
</para>
<para>Moreover, additional units might be loaded into systemd ("linked") from
directories not on the unit load path. See the <command>link</command> command
for
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
<para>Moreover, additional units might be loaded into systemd from
directories not on the unit load path by creating a symlink pointing to a
unit file in the directories. You can use <command>systemctl link</command>
for this operation. See
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
for its usage and precaution.
</para>
</refsect1>

View File

@ -12,8 +12,22 @@ KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcac
# ignore partitions that span the entire disk
TEST=="whole_disk", GOTO="persistent_storage_end"
# for partitions import parent information
ENV{DEVTYPE}=="partition", IMPORT{parent}="ID_*"
# For partitions import parent disk ID_* information, except ID_FS_*.
#
# This is particularly important on media where a filesystem superblock and
# partition table are found on the same level, e.g. common Linux distro ISO
# installation media.
#
# In the case where a partition device points to the same filesystem that
# was detected on the parent disk, the ID_FS_* information is already
# present on the partition devices as well as the parent, so no need to
# propagate it. In the case where the partition device points to a different
# filesystem, merging the parent ID_FS_ properties would lead to
# inconsistencies, so we avoid doing so.
ENV{DEVTYPE}=="partition", \
IMPORT{parent}="ID_[!F]*", IMPORT{parent}="ID_", \
IMPORT{parent}="ID_F[!S]*", IMPORT{parent}="ID_F", \
IMPORT{parent}="ID_FS[!_]*", IMPORT{parent}="ID_FS"
# NVMe
KERNEL=="nvme*[0-9]n*[0-9]", ATTR{wwid}=="?*", SYMLINK+="disk/by-id/nvme-$attr{wwid}"

View File

@ -32,8 +32,8 @@ _networkctl() {
local i verb comps
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
local -A OPTS=(
[STANDALONE]='-a --all -h --help --version --no-pager --no-legend -s --stats'
[ARG]=''
[STANDALONE]='-a --all -h --help --version --no-pager --no-legend -s --stats -l --full'
[ARG]='-n --lines'
)
local -A VERBS=(

View File

@ -2012,6 +2012,21 @@ static int bus_unit_set_transient_property(
if (d >= 0) {
const char *other;
if (!IN_SET(d,
UNIT_REQUIRES,
UNIT_REQUISITE,
UNIT_WANTS,
UNIT_BINDS_TO,
UNIT_PART_OF,
UNIT_CONFLICTS,
UNIT_BEFORE,
UNIT_AFTER,
UNIT_ON_FAILURE,
UNIT_PROPAGATES_RELOAD_TO,
UNIT_RELOAD_PROPAGATED_FROM,
UNIT_JOINS_NAMESPACE_OF))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Dependency type %s may not be created transiently.", unit_dependency_to_string(d));
r = sd_bus_message_enter_container(message, 'a', "s");
if (r < 0)
return r;

View File

@ -14,6 +14,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-table.h"
#include "format-util.h"
#include "fs-util.h"
#include "fstab-util.h"
@ -44,6 +45,7 @@ enum {
static bool arg_no_block = false;
static PagerFlags arg_pager_flags = 0;
static bool arg_legend = true;
static bool arg_ask_password = true;
static bool arg_quiet = false;
static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
@ -89,6 +91,7 @@ static int help(void) {
" --version Show package version\n"
" --no-block Do not wait until operation finished\n"
" --no-pager Do not pipe output into a pager\n"
" --no-legend Do not show the headers\n"
" --no-ask-password Do not prompt for password\n"
" -q --quiet Suppress information messages during runtime\n"
" --user Run as user unit\n"
@ -124,6 +127,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_VERSION = 0x100,
ARG_NO_BLOCK,
ARG_NO_PAGER,
ARG_NO_LEGEND,
ARG_NO_ASK_PASSWORD,
ARG_USER,
ARG_SYSTEM,
@ -145,6 +149,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "version", no_argument, NULL, ARG_VERSION },
{ "no-block", no_argument, NULL, ARG_NO_BLOCK },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "no-legend", no_argument, NULL, ARG_NO_LEGEND },
{ "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
{ "quiet", no_argument, NULL, 'q' },
{ "user", no_argument, NULL, ARG_USER },
@ -195,6 +200,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_pager_flags |= PAGER_DISABLE;
break;
case ARG_NO_LEGEND:
arg_legend = false;
break;
case ARG_NO_ASK_PASSWORD:
arg_ask_password = false;
break;
@ -1361,44 +1370,13 @@ enum {
_COLUMN_MAX,
};
struct item {
char* columns[_COLUMN_MAX];
};
static int compare_item(const struct item *a, const struct item *b) {
if (a->columns[COLUMN_NODE] == b->columns[COLUMN_NODE])
return 0;
if (!a->columns[COLUMN_NODE])
return 1;
if (!b->columns[COLUMN_NODE])
return -1;
return path_compare(a->columns[COLUMN_NODE], b->columns[COLUMN_NODE]);
}
static int list_devices(void) {
static const char * const titles[_COLUMN_MAX] = {
[COLUMN_NODE] = "NODE",
[COLUMN_PATH] = "PATH",
[COLUMN_MODEL] = "MODEL",
[COLUMN_WWN] = "WWN",
[COLUMN_FSTYPE] = "TYPE",
[COLUMN_LABEL] = "LABEL",
[COLUMN_UUID] = "UUID"
};
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
size_t n_allocated = 0, n = 0, i;
size_t column_width[_COLUMN_MAX];
struct item *items = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
sd_device *d;
unsigned c;
int r;
for (c = 0; c < _COLUMN_MAX; c++)
column_width[c] = strlen(titles[c]);
r = sd_device_enumerator_new(&e);
if (r < 0)
return log_oom();
@ -1411,19 +1389,19 @@ static int list_devices(void) {
if (r < 0)
return log_error_errno(r, "Failed to add property match: %m");
table = table_new("NODE", "PATH", "MODEL", "WWN", "TYPE", "LABEL", "UUID");
if (!table)
return log_oom();
r = table_set_sort(table, 0, SIZE_MAX);
if (r < 0)
return log_error_errno(r, "Failed to set sort index: %m");
table_set_header(table, arg_legend);
FOREACH_DEVICE(e, d) {
struct item *j;
if (!GREEDY_REALLOC0(items, n_allocated, n+1)) {
r = log_oom();
goto finish;
}
j = items + n++;
for (c = 0; c < _COLUMN_MAX; c++) {
const char *x = NULL;
size_t k;
switch (c) {
@ -1456,59 +1434,19 @@ static int list_devices(void) {
break;
}
if (isempty(x))
continue;
j->columns[c] = strdup(x);
if (!j->columns[c]) {
r = log_oom();
goto finish;
}
k = strlen(x);
if (k > column_width[c])
column_width[c] = k;
r = table_add_cell(table, NULL, c == COLUMN_NODE ? TABLE_PATH : TABLE_STRING, strna(x));
if (r < 0)
return log_error_errno(r, "Failed to add cell: %m");
}
}
if (n == 0) {
log_info("No devices found.");
goto finish;
}
typesafe_qsort(items, n, compare_item);
(void) pager_open(arg_pager_flags);
fputs(ansi_underline(), stdout);
for (c = 0; c < _COLUMN_MAX; c++) {
if (c > 0)
fputc(' ', stdout);
r = table_print(table, NULL);
if (r < 0)
return log_error_errno(r, "Failed to print table: %m");
printf("%-*s", (int) column_width[c], titles[c]);
}
fputs(ansi_normal(), stdout);
fputc('\n', stdout);
for (i = 0; i < n; i++) {
for (c = 0; c < _COLUMN_MAX; c++) {
if (c > 0)
fputc(' ', stdout);
printf("%-*s", (int) column_width[c], strna(items[i].columns[c]));
}
fputc('\n', stdout);
}
r = 0;
finish:
for (i = 0; i < n; i++)
for (c = 0; c < _COLUMN_MAX; c++)
free(items[i].columns[c]);
free(items);
return r;
return 0;
}
static int run(int argc, char* argv[]) {

View File

@ -14,6 +14,7 @@
#include "memory-util.h"
#include "pager.h"
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
#include "sort-util.h"
#include "string-util.h"
@ -234,6 +235,7 @@ static size_t table_data_size(TableDataType type, const void *data) {
return 0;
case TABLE_STRING:
case TABLE_PATH:
return strlen(data) + 1;
case TABLE_BOOLEAN:
@ -768,6 +770,7 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
break;
case TABLE_STRING:
case TABLE_PATH:
data = va_arg(ap, const char *);
break;
@ -1038,6 +1041,9 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t
case TABLE_STRING:
return strcmp(a->string, b->string);
case TABLE_PATH:
return path_compare(a->string, b->string);
case TABLE_BOOLEAN:
if (!a->boolean && b->boolean)
return -1;
@ -1151,6 +1157,7 @@ static const char *table_data_format(Table *t, TableData *d) {
return strempty(t->empty_string);
case TABLE_STRING:
case TABLE_PATH:
if (d->uppercase) {
char *p, *q;
@ -1897,6 +1904,7 @@ static int table_data_to_json(TableData *d, JsonVariant **ret) {
return json_variant_new_null(ret);
case TABLE_STRING:
case TABLE_PATH:
return json_variant_new_string(ret, d->string);
case TABLE_BOOLEAN:

View File

@ -11,6 +11,7 @@
typedef enum TableDataType {
TABLE_EMPTY,
TABLE_STRING,
TABLE_PATH,
TABLE_BOOLEAN,
TABLE_TIMESTAMP,
TABLE_TIMESTAMP_UTC,

View File

@ -10,6 +10,7 @@
#include "bus-error.h"
#include "bus-util.h"
#include "format-table.h"
#include "in-addr-util.h"
#include "main-func.h"
#include "pager.h"
@ -45,10 +46,12 @@ typedef struct StatusInfo {
bool ntp_synced;
} StatusInfo;
static void print_status_info(const StatusInfo *i) {
static int print_status_info(const StatusInfo *i) {
_cleanup_(table_unrefp) Table *table = NULL;
const char *old_tz = NULL, *tz, *tz_colon;
bool have_time = false;
char a[LINE_MAX];
TableCell *cell;
struct tm tm;
time_t sec;
size_t n;
@ -56,6 +59,19 @@ static void print_status_info(const StatusInfo *i) {
assert(i);
table = table_new("key", "value");
if (!table)
return log_oom();
table_set_header(table, false);
assert_se(cell = table_get_cell(table, 0, 0));
(void) table_set_ellipsize_percent(table, cell, 100);
(void) table_set_align_percent(table, cell, 100);
assert_se(cell = table_get_cell(table, 0, 1));
(void) table_set_ellipsize_percent(table, cell, 100);
/* Save the old $TZ */
tz = getenv("TZ");
if (tz)
@ -77,29 +93,49 @@ static void print_status_info(const StatusInfo *i) {
} else
log_warning("Could not get time from timedated and not operating locally, ignoring.");
if (have_time) {
if (have_time)
n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
printf(" Local time: %s\n", n > 0 ? a : "n/a");
r = table_add_many(table,
TABLE_STRING, "Local time:",
TABLE_STRING, have_time && n > 0 ? a : "n/a");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
if (have_time)
n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
printf(" Universal time: %s\n", n > 0 ? a : "n/a");
} else {
printf(" Local time: %s\n", "n/a");
printf(" Universal time: %s\n", "n/a");
}
r = table_add_many(table,
TABLE_STRING, "Universal time:",
TABLE_STRING, have_time && n > 0 ? a : "n/a");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
if (i->rtc_time > 0) {
time_t rtc_sec;
rtc_sec = (time_t) (i->rtc_time / USEC_PER_SEC);
n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
printf(" RTC time: %s\n", n > 0 ? a : "n/a");
} else
printf(" RTC time: %s\n", "n/a");
}
r = table_add_many(table,
TABLE_STRING, "RTC time:",
TABLE_STRING, i->rtc_time > 0 && n > 0 ? a : "n/a");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
if (have_time)
n = strftime(a, sizeof a, "%Z, %z", localtime_r(&sec, &tm));
r = table_add_cell(table, NULL, TABLE_STRING, "Time zone:");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell_stringf(table, NULL, "%s (%s)", strna(i->timezone), have_time && n > 0 ? a : "n/a");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
/* Restore the $TZ */
if (old_tz)
r = setenv("TZ", old_tz, true);
@ -110,14 +146,19 @@ static void print_status_info(const StatusInfo *i) {
else
tzset();
printf(" Time zone: %s (%s)\n"
"System clock synchronized: %s\n"
" NTP service: %s\n"
" RTC in local TZ: %s\n",
strna(i->timezone), have_time && n > 0 ? a : "n/a",
yes_no(i->ntp_synced),
i->ntp_capable ? (i->ntp_active ? "active" : "inactive") : "n/a",
yes_no(i->rtc_local));
r = table_add_many(table,
TABLE_STRING, "System clock synchronized:",
TABLE_BOOLEAN, i->ntp_synced,
TABLE_STRING, "NTP service:",
TABLE_STRING, i->ntp_capable ? (i->ntp_active ? "active" : "inactive") : "n/a",
TABLE_STRING, "RTC in local TZ:",
TABLE_BOOLEAN, i->rtc_local);
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_print(table, NULL);
if (r < 0)
return log_error_errno(r, "Failed to show table: %m");
if (i->rtc_local)
printf("\n%s"
@ -127,6 +168,8 @@ static void print_status_info(const StatusInfo *i) {
" time is never updated, it relies on external facilities to maintain it.\n"
" If at all possible, use RTC in UTC by calling\n"
" 'timedatectl set-local-rtc 0'.%s\n", ansi_highlight(), ansi_normal());
return 0;
}
static int show_status(int argc, char **argv, void *userdata) {
@ -160,9 +203,7 @@ static int show_status(int argc, char **argv, void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to query server: %s", bus_error_message(&error, r));
print_status_info(&info);
return r;
return print_status_info(&info);
}
static int show_properties(int argc, char **argv, void *userdata) {
@ -350,13 +391,30 @@ static const char * const ntp_leap_table[4] = {
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(ntp_leap, uint32_t);
#pragma GCC diagnostic pop
static void print_ntp_status_info(NTPStatusInfo *i) {
char ts[FORMAT_TIMESPAN_MAX], tmin[FORMAT_TIMESPAN_MAX], tmax[FORMAT_TIMESPAN_MAX];
static int print_ntp_status_info(NTPStatusInfo *i) {
char ts[FORMAT_TIMESPAN_MAX], jitter[FORMAT_TIMESPAN_MAX],
tmin[FORMAT_TIMESPAN_MAX], tmax[FORMAT_TIMESPAN_MAX];
usec_t delay, t14, t23, offset, root_distance;
_cleanup_(table_unrefp) Table *table = NULL;
bool offset_sign;
TableCell *cell;
int r;
assert(i);
table = table_new("key", "value");
if (!table)
return log_oom();
table_set_header(table, false);
assert_se(cell = table_get_cell(table, 0, 0));
(void) table_set_ellipsize_percent(table, cell, 100);
(void) table_set_align_percent(table, cell, 100);
assert_se(cell = table_get_cell(table, 0, 1));
(void) table_set_ellipsize_percent(table, cell, 100);
/*
* "Timestamp Name ID When Generated
* ------------------------------------------------------------
@ -369,21 +427,46 @@ static void print_ntp_status_info(NTPStatusInfo *i) {
* d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2"
*/
printf(" Server: %s (%s)\n",
i->server_address, i->server_name);
printf("Poll interval: %s (min: %s; max %s)\n",
format_timespan(ts, sizeof(ts), i->poll_interval, 0),
format_timespan(tmin, sizeof(tmin), i->poll_min, 0),
format_timespan(tmax, sizeof(tmax), i->poll_max, 0));
r = table_add_cell(table, NULL, TABLE_STRING, "Server:");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell_stringf(table, NULL, "%s (%s)", i->server_address, i->server_name);
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell(table, NULL, TABLE_STRING, "Poll interval:");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell_stringf(table, NULL, "%s (min: %s; max %s)",
format_timespan(ts, sizeof(ts), i->poll_interval, 0),
format_timespan(tmin, sizeof(tmin), i->poll_min, 0),
format_timespan(tmax, sizeof(tmax), i->poll_max, 0));
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
if (i->packet_count == 0) {
printf(" Packet count: 0\n");
return;
r = table_add_many(table,
TABLE_STRING, "Packet count:",
TABLE_STRING, "0");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_print(table, NULL);
if (r < 0)
return log_error_errno(r, "Failed to show table: %m");
return 0;
}
if (i->dest < i->origin || i->trans < i->recv || i->dest - i->origin < i->trans - i->recv) {
log_error("Invalid NTP response");
return;
r = table_print(table, NULL);
if (r < 0)
return log_error_errno(r, "Failed to show table: %m");
return 0;
}
delay = (i->dest - i->origin) - (i->trans - i->recv);
@ -395,34 +478,79 @@ static void print_ntp_status_info(NTPStatusInfo *i) {
root_distance = i->root_delay / 2 + i->root_dispersion;
printf(" Leap: %s\n"
" Version: %" PRIu32 "\n"
" Stratum: %" PRIu32 "\n",
ntp_leap_to_string(i->leap),
i->version,
i->stratum);
if (i->stratum <= 1)
printf(" Reference: %s\n", i->reference.str);
else
printf(" Reference: %" PRIX32 "\n", be32toh(i->reference.val));
printf(" Precision: %s (%" PRIi32 ")\n",
format_timespan(ts, sizeof(ts), DIV_ROUND_UP((nsec_t) (exp2(i->precision) * NSEC_PER_SEC), NSEC_PER_USEC), 0),
i->precision);
printf("Root distance: %s (max: %s)\n",
format_timespan(ts, sizeof(ts), root_distance, 0),
format_timespan(tmax, sizeof(tmax), i->root_distance_max, 0));
printf(" Offset: %s%s\n",
offset_sign ? "+" : "-",
format_timespan(ts, sizeof(ts), offset, 0));
printf(" Delay: %s\n",
format_timespan(ts, sizeof(ts), delay, 0));
printf(" Jitter: %s\n",
format_timespan(ts, sizeof(ts), i->jitter, 0));
printf(" Packet count: %" PRIu64 "\n", i->packet_count);
r = table_add_many(table,
TABLE_STRING, "Leap:",
TABLE_STRING, ntp_leap_to_string(i->leap),
TABLE_STRING, "Version:",
TABLE_UINT32, i->version,
TABLE_STRING, "Stratum:",
TABLE_UINT32, i->stratum,
TABLE_STRING, "Reference:");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
if (!i->spike)
printf(" Frequency: %+.3fppm\n",
(double) i->freq / 0x10000);
if (i->stratum <= 1)
r = table_add_cell(table, NULL, TABLE_STRING, i->reference.str);
else
r = table_add_cell_stringf(table, NULL, "%" PRIX32, be32toh(i->reference.val));
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell(table, NULL, TABLE_STRING, "Precision:");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell_stringf(table, NULL, "%s (%" PRIi32 ")",
format_timespan(ts, sizeof(ts), DIV_ROUND_UP((nsec_t) (exp2(i->precision) * NSEC_PER_SEC), NSEC_PER_USEC), 0),
i->precision);
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell(table, NULL, TABLE_STRING, "Root distance:");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell_stringf(table, NULL, "%s (max: %s)",
format_timespan(ts, sizeof(ts), root_distance, 0),
format_timespan(tmax, sizeof(tmax), i->root_distance_max, 0));
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell(table, NULL, TABLE_STRING, "Offset:");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell_stringf(table, NULL, "%s%s",
offset_sign ? "+" : "-",
format_timespan(ts, sizeof(ts), offset, 0));
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_many(table,
TABLE_STRING, "Delay:",
TABLE_STRING, format_timespan(ts, sizeof(ts), delay, 0),
TABLE_STRING, "Jitter:",
TABLE_STRING, format_timespan(jitter, sizeof(jitter), i->jitter, 0),
TABLE_STRING, "Packet count:",
TABLE_UINT64, i->packet_count);
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
if (!i->spike) {
r = table_add_cell(table, NULL, TABLE_STRING, "Frequency:");
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
r = table_add_cell_stringf(table, NULL, "%+.3fppm", (double) i->freq / 0x10000);
if (r < 0)
return log_error_errno(r, "Failed to add cell(s): %m");
}
r = table_print(table, NULL);
if (r < 0)
log_error_errno(r, "Failed to show table: %m");
return 0;
}
static int map_server_address(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {