mirror of
https://github.com/systemd/systemd
synced 2026-03-20 03:54:45 +01:00
Compare commits
No commits in common. "7e4dcd2d1fa32c9f2d3497f514c2dc371cda3f45" and "fac6511e4943f9a873f136c0bb3185d3cd8cbbfa" have entirely different histories.
7e4dcd2d1f
...
fac6511e49
32
NEWS
32
NEWS
@ -28,17 +28,17 @@ CHANGES WITH 249 in spe:
|
|||||||
specified root user exists already in the image. (Note that
|
specified root user exists already in the image. (Note that
|
||||||
--volatile=yes ensures it doesn't, though.)
|
--volatile=yes ensures it doesn't, though.)
|
||||||
|
|
||||||
|
* PID 1 may now show both the unit name and the unit description
|
||||||
|
strings in its status output during boot. This may be configured with
|
||||||
|
StatusUnitFormat=combined in system.conf or
|
||||||
|
systemd.status-unit-format=combined on the kernel command line.
|
||||||
|
|
||||||
* systemd-firstboot now also supports querying various system
|
* systemd-firstboot now also supports querying various system
|
||||||
parameters via the credential subsystems. Thus, as above this may be
|
parameters via the credential subsystems. Thus, as above this may be
|
||||||
used to initialize important system parameters on first boot of
|
used to initialize important system parameters on first boot of
|
||||||
previously unprovisioned images (i.e. images with a mostly empty
|
previously unprovisioned images (i.e. images with a mostly empty
|
||||||
/etc/).
|
/etc/).
|
||||||
|
|
||||||
* PID 1 may now show both the unit name and the unit description
|
|
||||||
strings in its status output during boot. This may be configured with
|
|
||||||
StatusUnitFormat=combined in system.conf or
|
|
||||||
systemd.status-unit-format=combined on the kernel command line.
|
|
||||||
|
|
||||||
* The systemd-machine-id-setup tool now supports a --image= switch for
|
* The systemd-machine-id-setup tool now supports a --image= switch for
|
||||||
provisioning a machine ID file into an OS disk image, similar to how
|
provisioning a machine ID file into an OS disk image, similar to how
|
||||||
--root= operates on an OS file tree. This matches the existing switch
|
--root= operates on an OS file tree. This matches the existing switch
|
||||||
@ -69,10 +69,9 @@ CHANGES WITH 249 in spe:
|
|||||||
and then stream their own root partition onto the target medium.
|
and then stream their own root partition onto the target medium.
|
||||||
|
|
||||||
* systemd-repart's partition configuration files gained support for a
|
* systemd-repart's partition configuration files gained support for a
|
||||||
Flags=, a ReadOnly= and a NoAuto= setting, allowing control of these
|
Flags= and a ReadOnly= setting, allowing control of the GPT partition
|
||||||
GPT partition flags for the created partitions: this is useful for
|
flags for the created partitions: this is useful for marking newly
|
||||||
marking newly created partitions as read-only, or as not being
|
created partitions as read-only from the start.
|
||||||
subject for automatic mounting from creation on.
|
|
||||||
|
|
||||||
* The /etc/os-release file has been extended with two new (optional)
|
* The /etc/os-release file has been extended with two new (optional)
|
||||||
variables IMAGE_VERSION= and IMAGE_ID=, carrying identity and version
|
variables IMAGE_VERSION= and IMAGE_ID=, carrying identity and version
|
||||||
@ -448,11 +447,6 @@ CHANGES WITH 249 in spe:
|
|||||||
(default, as before), turn echo off entirely, or echo the typed
|
(default, as before), turn echo off entirely, or echo the typed
|
||||||
characters literally.
|
characters literally.
|
||||||
|
|
||||||
* The systemd-ask-password tool also gained a new -n switch for
|
|
||||||
suppressing output of a trailing newline character when writing the
|
|
||||||
acquired password to standard output, similar to /bin/echo's -n
|
|
||||||
switch.
|
|
||||||
|
|
||||||
* New documentation has been added that describes the organization of
|
* New documentation has been added that describes the organization of
|
||||||
the systemd source code tree:
|
the systemd source code tree:
|
||||||
|
|
||||||
@ -509,14 +503,6 @@ CHANGES WITH 249 in spe:
|
|||||||
and friends), all file systems will be mounted with MS_NOSUID by
|
and friends), all file systems will be mounted with MS_NOSUID by
|
||||||
default, unless the system is running with SELinux enabled.
|
default, unless the system is running with SELinux enabled.
|
||||||
|
|
||||||
* When enumerating time zones the timedatectl tool will now consult the
|
|
||||||
'tzdata.zi' file shipped by the IANA time zone database package, in
|
|
||||||
addition to 'zone1970.tab', as before. This makes sure time zone
|
|
||||||
aliases are now correctly supported. Some distributions so far did
|
|
||||||
not install this additional file, most do however. If you
|
|
||||||
distribution does not install it yet, it might make sense to change
|
|
||||||
that.
|
|
||||||
|
|
||||||
Contributions from: Aakash Singh, adrian5, Albert Brox,
|
Contributions from: Aakash Singh, adrian5, Albert Brox,
|
||||||
Alexander Sverdlin, Alexander Tsoy, alexlzhu, Allen Webb,
|
Alexander Sverdlin, Alexander Tsoy, alexlzhu, Allen Webb,
|
||||||
Alvin Šipraga, Alyssa Ross, Anders Wenhaug, Andrea Pappacoda,
|
Alvin Šipraga, Alyssa Ross, Anders Wenhaug, Andrea Pappacoda,
|
||||||
@ -548,7 +534,7 @@ CHANGES WITH 249 in spe:
|
|||||||
William A. Kennington III, Yangyang Shen, Yegor Alexeyev, Yi Gao,
|
William A. Kennington III, Yangyang Shen, Yegor Alexeyev, Yi Gao,
|
||||||
Yu Watanabe, Zbigniew Jędrzejewski-Szmek, zsien, наб
|
Yu Watanabe, Zbigniew Jędrzejewski-Szmek, zsien, наб
|
||||||
|
|
||||||
— Berlin, 2021-07-01
|
— Warsaw, 2021-06-25
|
||||||
|
|
||||||
CHANGES WITH 248:
|
CHANGES WITH 248:
|
||||||
|
|
||||||
|
|||||||
3
TODO
3
TODO
@ -1366,9 +1366,6 @@ Features:
|
|||||||
but much rather a disconnect on success.
|
but much rather a disconnect on success.
|
||||||
- when breaking cycles drop sysv services first, then services from /run, then from /etc, then from /usr
|
- when breaking cycles drop sysv services first, then services from /run, then from /etc, then from /usr
|
||||||
- when a bus name of a service disappears from the bus make sure to queue further activation requests
|
- when a bus name of a service disappears from the bus make sure to queue further activation requests
|
||||||
- maybe introduce CoreScheduling=yes/no to optionally set a PR_SCHED_CORE cookie, so that all
|
|
||||||
processes in a service's cgroup share the same cookie and are guaranteed not to share SMT cores
|
|
||||||
with other units https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/hw-vuln/core-scheduling.rst
|
|
||||||
|
|
||||||
* unit files:
|
* unit files:
|
||||||
- allow port=0 in .socket units
|
- allow port=0 in .socket units
|
||||||
|
|||||||
@ -216,12 +216,6 @@ sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnE4D6_HI-122LP:*
|
|||||||
sensor:modalias:acpi:KIOX000A*:dmi:*:svnChuwi*:pnHi13:*
|
sensor:modalias:acpi:KIOX000A*:dmi:*:svnChuwi*:pnHi13:*
|
||||||
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
|
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
|
||||||
|
|
||||||
# Chuwi Hi13 (CWI534) with BMA250 sensor
|
|
||||||
# Note this sets the norm matrix, since the matrix which the kernel reads
|
|
||||||
# from the ACPI tables is actually wrong on these models
|
|
||||||
sensor:modalias:acpi:BOSC0200*:dmi:*:svnChuwi*:pnHi13:*
|
|
||||||
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, 1, 0; 0, 0, 1
|
|
||||||
|
|
||||||
# Chuwi HiBook
|
# Chuwi HiBook
|
||||||
# Chuwi HiBook does not have its product name filled, so we
|
# Chuwi HiBook does not have its product name filled, so we
|
||||||
# match the entire dmi-alias, assuming that the use of a BOSC0200 +
|
# match the entire dmi-alias, assuming that the use of a BOSC0200 +
|
||||||
|
|||||||
@ -81,6 +81,9 @@ KERNEL=="mmcblk[0-9]", SUBSYSTEMS=="mmc", ATTRS{name}=="?*", ENV{ID_NAME}="$attr
|
|||||||
KERNEL=="mmcblk[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}"
|
KERNEL=="mmcblk[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}"
|
||||||
KERNEL=="mmcblk[0-9]p[0-9]*", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
|
KERNEL=="mmcblk[0-9]p[0-9]*", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
|
||||||
|
|
||||||
|
# UBI-MTD
|
||||||
|
SUBSYSTEM=="ubi", KERNEL=="ubi*_*", ATTRS{mtd_num}=="*", SYMLINK+="ubi_mtd%s{mtd_num}_%s{name}"
|
||||||
|
|
||||||
# Memstick
|
# Memstick
|
||||||
KERNEL=="msblk[0-9]|mspblk[0-9]", SUBSYSTEMS=="memstick", ATTRS{name}=="?*", ATTRS{serial}=="?*", \
|
KERNEL=="msblk[0-9]|mspblk[0-9]", SUBSYSTEMS=="memstick", ATTRS{name}=="?*", ATTRS{serial}=="?*", \
|
||||||
ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}"
|
ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}"
|
||||||
|
|||||||
@ -1381,7 +1381,7 @@ int get_timezones(char ***ret) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int verify_timezone(const char *name, int log_level) {
|
bool timezone_is_valid(const char *name, int log_level) {
|
||||||
bool slash = false;
|
bool slash = false;
|
||||||
const char *p, *t;
|
const char *p, *t;
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
@ -1389,26 +1389,26 @@ int verify_timezone(const char *name, int log_level) {
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (isempty(name))
|
if (isempty(name))
|
||||||
return -EINVAL;
|
return false;
|
||||||
|
|
||||||
/* Always accept "UTC" as valid timezone, since it's the fallback, even if user has no timezones installed. */
|
/* Always accept "UTC" as valid timezone, since it's the fallback, even if user has no timezones installed. */
|
||||||
if (streq(name, "UTC"))
|
if (streq(name, "UTC"))
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
if (name[0] == '/')
|
if (name[0] == '/')
|
||||||
return -EINVAL;
|
return false;
|
||||||
|
|
||||||
for (p = name; *p; p++) {
|
for (p = name; *p; p++) {
|
||||||
if (!(*p >= '0' && *p <= '9') &&
|
if (!(*p >= '0' && *p <= '9') &&
|
||||||
!(*p >= 'a' && *p <= 'z') &&
|
!(*p >= 'a' && *p <= 'z') &&
|
||||||
!(*p >= 'A' && *p <= 'Z') &&
|
!(*p >= 'A' && *p <= 'Z') &&
|
||||||
!IN_SET(*p, '-', '_', '+', '/'))
|
!IN_SET(*p, '-', '_', '+', '/'))
|
||||||
return -EINVAL;
|
return false;
|
||||||
|
|
||||||
if (*p == '/') {
|
if (*p == '/') {
|
||||||
|
|
||||||
if (slash)
|
if (slash)
|
||||||
return -EINVAL;
|
return false;
|
||||||
|
|
||||||
slash = true;
|
slash = true;
|
||||||
} else
|
} else
|
||||||
@ -1416,31 +1416,38 @@ int verify_timezone(const char *name, int log_level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (slash)
|
if (slash)
|
||||||
return -EINVAL;
|
return false;
|
||||||
|
|
||||||
if (p - name >= PATH_MAX)
|
if (p - name >= PATH_MAX)
|
||||||
return -ENAMETOOLONG;
|
return false;
|
||||||
|
|
||||||
t = strjoina("/usr/share/zoneinfo/", name);
|
t = strjoina("/usr/share/zoneinfo/", name);
|
||||||
|
|
||||||
fd = open(t, O_RDONLY|O_CLOEXEC);
|
fd = open(t, O_RDONLY|O_CLOEXEC);
|
||||||
if (fd < 0)
|
if (fd < 0) {
|
||||||
return log_full_errno(log_level, errno, "Failed to open timezone file '%s': %m", t);
|
log_full_errno(log_level, errno, "Failed to open timezone file '%s': %m", t);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
r = fd_verify_regular(fd);
|
r = fd_verify_regular(fd);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
return log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t);
|
log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
r = loop_read_exact(fd, buf, 4, false);
|
r = loop_read_exact(fd, buf, 4, false);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
return log_full_errno(log_level, r, "Failed to read from timezone file '%s': %m", t);
|
log_full_errno(log_level, r, "Failed to read from timezone file '%s': %m", t);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Magic from tzfile(5) */
|
/* Magic from tzfile(5) */
|
||||||
if (memcmp(buf, "TZif", 4) != 0)
|
if (memcmp(buf, "TZif", 4) != 0) {
|
||||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EIO),
|
log_full(log_level, "Timezone file '%s' has wrong magic bytes", t);
|
||||||
"Timezone file '%s' has wrong magic bytes", t);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clock_boottime_supported(void) {
|
bool clock_boottime_supported(void) {
|
||||||
|
|||||||
@ -134,10 +134,7 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit);
|
|||||||
int parse_nsec(const char *t, nsec_t *nsec);
|
int parse_nsec(const char *t, nsec_t *nsec);
|
||||||
|
|
||||||
int get_timezones(char ***l);
|
int get_timezones(char ***l);
|
||||||
int verify_timezone(const char *name, int log_level);
|
bool timezone_is_valid(const char *name, int log_level);
|
||||||
static inline bool timezone_is_valid(const char *name, int log_level) {
|
|
||||||
return verify_timezone(name, log_level) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clock_boottime_supported(void);
|
bool clock_boottime_supported(void);
|
||||||
bool clock_supported(clockid_t clock);
|
bool clock_supported(clockid_t clock);
|
||||||
|
|||||||
@ -3384,6 +3384,11 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
|||||||
else
|
else
|
||||||
clean_mode = EXIT_CLEAN_DAEMON;
|
clean_mode = EXIT_CLEAN_DAEMON;
|
||||||
|
|
||||||
|
if (s->main_pid == pid)
|
||||||
|
/* Clean up the exec_fd event source. The source owns its end of the pipe, so this will close
|
||||||
|
* that too. */
|
||||||
|
s->exec_fd_event_source = sd_event_source_disable_unref(s->exec_fd_event_source);
|
||||||
|
|
||||||
if (is_clean_exit(code, status, clean_mode, &s->success_status))
|
if (is_clean_exit(code, status, clean_mode, &s->success_status))
|
||||||
f = SERVICE_SUCCESS;
|
f = SERVICE_SUCCESS;
|
||||||
else if (code == CLD_EXITED)
|
else if (code == CLD_EXITED)
|
||||||
@ -3396,11 +3401,6 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
|||||||
assert_not_reached("Unknown code");
|
assert_not_reached("Unknown code");
|
||||||
|
|
||||||
if (s->main_pid == pid) {
|
if (s->main_pid == pid) {
|
||||||
/* Clean up the exec_fd event source. We want to do this here, not later in
|
|
||||||
* service_set_state(), because service_enter_stop_post() calls service_spawn().
|
|
||||||
* The source owns its end of the pipe, so this will close that too. */
|
|
||||||
s->exec_fd_event_source = sd_event_source_disable_unref(s->exec_fd_event_source);
|
|
||||||
|
|
||||||
/* Forking services may occasionally move to a new PID.
|
/* Forking services may occasionally move to a new PID.
|
||||||
* As long as they update the PID file before exiting the old
|
* As long as they update the PID file before exiting the old
|
||||||
* PID, they're fine. */
|
* PID, they're fine. */
|
||||||
|
|||||||
@ -1340,35 +1340,27 @@ const char* unit_description(Unit *u) {
|
|||||||
return strna(u->id);
|
return strna(u->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* unit_status_string(Unit *u, char **ret_combined_buffer) {
|
const char* unit_status_string(Unit *u, char **combined) {
|
||||||
assert(u);
|
assert(u);
|
||||||
assert(u->id);
|
assert(u->id);
|
||||||
|
|
||||||
/* Return u->id, u->description, or "{u->id} - {u->description}".
|
/* Return u->id, u->description, or "{u->id} - {u->description}".
|
||||||
* Versions with u->description are only used if it is set.
|
* Versions with u->description are only used if it is set.
|
||||||
* The last option is used if configured and the caller provided the 'ret_combined_buffer'
|
* The last option is used if configured and the caller provided 'combined' pointer. */
|
||||||
* pointer.
|
|
||||||
*
|
|
||||||
* Note that *ret_combined_buffer may be set to NULL. */
|
|
||||||
|
|
||||||
if (!u->description ||
|
if (!u->description ||
|
||||||
|
streq(u->description, u->id) ||
|
||||||
u->manager->status_unit_format == STATUS_UNIT_FORMAT_NAME ||
|
u->manager->status_unit_format == STATUS_UNIT_FORMAT_NAME ||
|
||||||
(u->manager->status_unit_format == STATUS_UNIT_FORMAT_COMBINED && !ret_combined_buffer) ||
|
(u->manager->status_unit_format == STATUS_UNIT_FORMAT_COMBINED && !combined))
|
||||||
streq(u->description, u->id)) {
|
|
||||||
|
|
||||||
if (ret_combined_buffer)
|
|
||||||
*ret_combined_buffer = NULL;
|
|
||||||
return u->id;
|
return u->id;
|
||||||
}
|
|
||||||
|
|
||||||
if (ret_combined_buffer) {
|
if (u->description && u->manager->status_unit_format == STATUS_UNIT_FORMAT_COMBINED && combined) {
|
||||||
if (u->manager->status_unit_format == STATUS_UNIT_FORMAT_COMBINED) {
|
char *t = strjoin(u->id, " - ", u->description);
|
||||||
*ret_combined_buffer = strjoin(u->id, " - ", u->description);
|
if (t) {
|
||||||
if (*ret_combined_buffer)
|
*combined = t;
|
||||||
return *ret_combined_buffer;
|
return t;
|
||||||
log_oom(); /* Fall back to ->description */
|
|
||||||
} else
|
} else
|
||||||
*ret_combined_buffer = NULL;
|
log_oom();
|
||||||
}
|
}
|
||||||
|
|
||||||
return u->description;
|
return u->description;
|
||||||
|
|||||||
@ -202,13 +202,13 @@ static void test_format_timespan_one(usec_t x, usec_t accuracy) {
|
|||||||
const char *t;
|
const char *t;
|
||||||
usec_t y;
|
usec_t y;
|
||||||
|
|
||||||
log_debug(USEC_FMT" (at accuracy "USEC_FMT")", x, accuracy);
|
log_info(USEC_FMT" (at accuracy "USEC_FMT")", x, accuracy);
|
||||||
|
|
||||||
assert_se(t = format_timespan(l, sizeof l, x, accuracy));
|
assert_se(t = format_timespan(l, sizeof l, x, accuracy));
|
||||||
log_debug(" = <%s>", t);
|
log_info(" = <%s>", t);
|
||||||
|
|
||||||
assert_se(parse_sec(t, &y) >= 0);
|
assert_se(parse_sec(t, &y) >= 0);
|
||||||
log_debug(" = "USEC_FMT, y);
|
log_info(" = "USEC_FMT, y);
|
||||||
|
|
||||||
if (accuracy <= 0)
|
if (accuracy <= 0)
|
||||||
accuracy = 1;
|
accuracy = 1;
|
||||||
@ -243,17 +243,6 @@ static void test_format_timespan(usec_t accuracy) {
|
|||||||
test_format_timespan_one(USEC_INFINITY, accuracy);
|
test_format_timespan_one(USEC_INFINITY, accuracy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_verify_timezone(void) {
|
|
||||||
log_info("/* %s */", __func__);
|
|
||||||
|
|
||||||
assert_se(verify_timezone("Europe/Berlin", LOG_DEBUG) == 0);
|
|
||||||
assert_se(verify_timezone("Australia/Sydney", LOG_DEBUG) == 0);
|
|
||||||
assert_se(verify_timezone("Europe/Do not exist", LOG_DEBUG) == -EINVAL);
|
|
||||||
assert_se(verify_timezone("Europe/DoNotExist", LOG_DEBUG) == -ENOENT);
|
|
||||||
assert_se(verify_timezone("/DoNotExist", LOG_DEBUG) == -EINVAL);
|
|
||||||
assert_se(verify_timezone("DoNotExist/", LOG_DEBUG) == -EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_timezone_is_valid(void) {
|
static void test_timezone_is_valid(void) {
|
||||||
log_info("/* %s */", __func__);
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
@ -273,9 +262,8 @@ static void test_get_timezones(void) {
|
|||||||
assert_se(r == 0);
|
assert_se(r == 0);
|
||||||
|
|
||||||
STRV_FOREACH(zone, zones) {
|
STRV_FOREACH(zone, zones) {
|
||||||
r = verify_timezone(*zone, LOG_ERR);
|
log_info("zone: %s", *zone);
|
||||||
log_debug_errno(r, "verify_timezone(\"%s\"): %m", *zone);
|
assert_se(timezone_is_valid(*zone, LOG_ERR));
|
||||||
assert_se(r >= 0 || r == -ENOENT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,9 +317,11 @@ static void test_usec_sub_signed(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_format_timestamp(void) {
|
static void test_format_timestamp(void) {
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
log_info("/* %s */", __func__);
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
for (unsigned i = 0; i < 100; i++) {
|
for (i = 0; i < 100; i++) {
|
||||||
char buf[MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESPAN_MAX)];
|
char buf[MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESPAN_MAX)];
|
||||||
usec_t x, y;
|
usec_t x, y;
|
||||||
|
|
||||||
@ -339,27 +329,27 @@ static void test_format_timestamp(void) {
|
|||||||
x = x % (2147483600 * USEC_PER_SEC) + 1;
|
x = x % (2147483600 * USEC_PER_SEC) + 1;
|
||||||
|
|
||||||
assert_se(format_timestamp(buf, sizeof(buf), x));
|
assert_se(format_timestamp(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(parse_timestamp(buf, &y) >= 0);
|
assert_se(parse_timestamp(buf, &y) >= 0);
|
||||||
assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
|
assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
|
||||||
|
|
||||||
assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_UTC));
|
assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_UTC));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(parse_timestamp(buf, &y) >= 0);
|
assert_se(parse_timestamp(buf, &y) >= 0);
|
||||||
assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
|
assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
|
||||||
|
|
||||||
assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_US));
|
assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_US));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(parse_timestamp(buf, &y) >= 0);
|
assert_se(parse_timestamp(buf, &y) >= 0);
|
||||||
assert_se(x == y);
|
assert_se(x == y);
|
||||||
|
|
||||||
assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_US_UTC));
|
assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_US_UTC));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(parse_timestamp(buf, &y) >= 0);
|
assert_se(parse_timestamp(buf, &y) >= 0);
|
||||||
assert_se(x == y);
|
assert_se(x == y);
|
||||||
|
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(parse_timestamp(buf, &y) >= 0);
|
assert_se(parse_timestamp(buf, &y) >= 0);
|
||||||
|
|
||||||
/* The two calls above will run with a slightly different local time. Make sure we are in the same
|
/* The two calls above will run with a slightly different local time. Make sure we are in the same
|
||||||
@ -383,64 +373,64 @@ static void test_format_timestamp_relative(void) {
|
|||||||
/* Years and months */
|
/* Years and months */
|
||||||
x = now(CLOCK_REALTIME) - (1*USEC_PER_YEAR + 1*USEC_PER_MONTH);
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_YEAR + 1*USEC_PER_MONTH);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "1 year 1 month ago"));
|
assert_se(streq(buf, "1 year 1 month ago"));
|
||||||
|
|
||||||
x = now(CLOCK_REALTIME) - (1*USEC_PER_YEAR + 2*USEC_PER_MONTH);
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_YEAR + 2*USEC_PER_MONTH);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "1 year 2 months ago"));
|
assert_se(streq(buf, "1 year 2 months ago"));
|
||||||
|
|
||||||
x = now(CLOCK_REALTIME) - (2*USEC_PER_YEAR + 1*USEC_PER_MONTH);
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_YEAR + 1*USEC_PER_MONTH);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "2 years 1 month ago"));
|
assert_se(streq(buf, "2 years 1 month ago"));
|
||||||
|
|
||||||
x = now(CLOCK_REALTIME) - (2*USEC_PER_YEAR + 2*USEC_PER_MONTH);
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_YEAR + 2*USEC_PER_MONTH);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "2 years 2 months ago"));
|
assert_se(streq(buf, "2 years 2 months ago"));
|
||||||
|
|
||||||
/* Months and days */
|
/* Months and days */
|
||||||
x = now(CLOCK_REALTIME) - (1*USEC_PER_MONTH + 1*USEC_PER_DAY);
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_MONTH + 1*USEC_PER_DAY);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "1 month 1 day ago"));
|
assert_se(streq(buf, "1 month 1 day ago"));
|
||||||
|
|
||||||
x = now(CLOCK_REALTIME) - (1*USEC_PER_MONTH + 2*USEC_PER_DAY);
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_MONTH + 2*USEC_PER_DAY);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "1 month 2 days ago"));
|
assert_se(streq(buf, "1 month 2 days ago"));
|
||||||
|
|
||||||
x = now(CLOCK_REALTIME) - (2*USEC_PER_MONTH + 1*USEC_PER_DAY);
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_MONTH + 1*USEC_PER_DAY);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "2 months 1 day ago"));
|
assert_se(streq(buf, "2 months 1 day ago"));
|
||||||
|
|
||||||
x = now(CLOCK_REALTIME) - (2*USEC_PER_MONTH + 2*USEC_PER_DAY);
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_MONTH + 2*USEC_PER_DAY);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "2 months 2 days ago"));
|
assert_se(streq(buf, "2 months 2 days ago"));
|
||||||
|
|
||||||
/* Weeks and days */
|
/* Weeks and days */
|
||||||
x = now(CLOCK_REALTIME) - (1*USEC_PER_WEEK + 1*USEC_PER_DAY);
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_WEEK + 1*USEC_PER_DAY);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "1 week 1 day ago"));
|
assert_se(streq(buf, "1 week 1 day ago"));
|
||||||
|
|
||||||
x = now(CLOCK_REALTIME) - (1*USEC_PER_WEEK + 2*USEC_PER_DAY);
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_WEEK + 2*USEC_PER_DAY);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "1 week 2 days ago"));
|
assert_se(streq(buf, "1 week 2 days ago"));
|
||||||
|
|
||||||
x = now(CLOCK_REALTIME) - (2*USEC_PER_WEEK + 1*USEC_PER_DAY);
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_WEEK + 1*USEC_PER_DAY);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "2 weeks 1 day ago"));
|
assert_se(streq(buf, "2 weeks 1 day ago"));
|
||||||
|
|
||||||
x = now(CLOCK_REALTIME) - (2*USEC_PER_WEEK + 2*USEC_PER_DAY);
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_WEEK + 2*USEC_PER_DAY);
|
||||||
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
log_debug("%s", buf);
|
log_info("%s", buf);
|
||||||
assert_se(streq(buf, "2 weeks 2 days ago"));
|
assert_se(streq(buf, "2 weeks 2 days ago"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,7 +607,6 @@ int main(int argc, char *argv[]) {
|
|||||||
test_format_timespan(1);
|
test_format_timespan(1);
|
||||||
test_format_timespan(USEC_PER_MSEC);
|
test_format_timespan(USEC_PER_MSEC);
|
||||||
test_format_timespan(USEC_PER_SEC);
|
test_format_timespan(USEC_PER_SEC);
|
||||||
test_verify_timezone();
|
|
||||||
test_timezone_is_valid();
|
test_timezone_is_valid();
|
||||||
test_get_timezones();
|
test_get_timezones();
|
||||||
test_usec_add();
|
test_usec_add();
|
||||||
|
|||||||
@ -66,6 +66,9 @@ KERNEL=="mmcblk[0-9]", SUBSYSTEMS=="mmc", ATTRS{name}=="?*", ATTRS{serial}=="?*"
|
|||||||
ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}"
|
ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}"
|
||||||
KERNEL=="mmcblk[0-9]p[0-9]*", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
|
KERNEL=="mmcblk[0-9]p[0-9]*", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
|
||||||
|
|
||||||
|
# UBI-MTD
|
||||||
|
SUBSYSTEM=="ubi", KERNEL=="ubi*_*", ATTRS{mtd_num}=="*", SYMLINK+="ubi_mtd%s{mtd_num}_%s{name}"
|
||||||
|
|
||||||
# Memstick
|
# Memstick
|
||||||
KERNEL=="msblk[0-9]|mspblk[0-9]", SUBSYSTEMS=="memstick", ATTRS{name}=="?*", ATTRS{serial}=="?*", \
|
KERNEL=="msblk[0-9]|mspblk[0-9]", SUBSYSTEMS=="memstick", ATTRS{name}=="?*", ATTRS{serial}=="?*", \
|
||||||
ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}"
|
ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user