1
0
mirror of https://github.com/systemd/systemd synced 2025-11-18 08:14:46 +01:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Lennart Poettering
90305bd17a pull: add pretty progress bar to systemd-pull too
This already exists in systemd-import, but let's add it for systemd-pull
too.
2025-10-29 13:09:57 +01:00
Lennart Poettering
6fa83be763 main: switch explicitly to tty1 on soft-reboot
Fixes: #39462
2025-10-29 13:09:20 +01:00
Daan De Meyer
2988bba60f mount-util: Iterate mountinfo backwards when unmounting
Submounts will always be located further in the mountinfo file, so
when we're unmounting, iterating backwards is likely to be more
efficient than iterating forwards. It'll also reduce the amount of
EBUSY debug logging we'll get since we'll stop trying to unmount
parent mounts with submounts which will always fail with EBUSY.
2025-10-29 12:01:32 +01:00
Daan De Meyer
35e03f6302 core: Don't setup mount propagation tunnel if not required
If we know we have mount_setattr(), then we don't need the mount
propagation tunnel, so don't set it up.
2025-10-29 12:01:02 +01:00
8 changed files with 75 additions and 14 deletions

View File

@ -166,6 +166,8 @@ static inline bool osc_char_is_valid(char c) {
return (unsigned char) c >= 32 && (unsigned char) c < 127; return (unsigned char) c >= 32 && (unsigned char) c < 127;
} }
#define VTNR_MAX 63
static inline bool vtnr_is_valid(unsigned n) { static inline bool vtnr_is_valid(unsigned n) {
return n >= 1 && n <= 63; return n >= 1 && n <= VTNR_MAX;
} }

View File

@ -53,6 +53,7 @@
#include "memfd-util.h" #include "memfd-util.h"
#include "mkdir-label.h" #include "mkdir-label.h"
#include "mount-util.h" #include "mount-util.h"
#include "mountpoint-util.h"
#include "namespace-util.h" #include "namespace-util.h"
#include "nsflags.h" #include "nsflags.h"
#include "open-file.h" #include "open-file.h"
@ -3806,13 +3807,15 @@ static int apply_mount_namespace(
return r; return r;
if (params->runtime_scope == RUNTIME_SCOPE_SYSTEM) { if (params->runtime_scope == RUNTIME_SCOPE_SYSTEM) {
propagate_dir = path_join("/run/systemd/propagate/", params->unit_id); if (!mount_new_api_supported()) {
if (!propagate_dir) propagate_dir = path_join("/run/systemd/propagate/", params->unit_id);
return -ENOMEM; if (!propagate_dir)
return -ENOMEM;
incoming_dir = strdup("/run/systemd/incoming"); incoming_dir = strdup("/run/systemd/incoming");
if (!incoming_dir) if (!incoming_dir)
return -ENOMEM; return -ENOMEM;
}
private_namespace_dir = strdup("/run/systemd"); private_namespace_dir = strdup("/run/systemd");
if (!private_namespace_dir) if (!private_namespace_dir)

View File

@ -3,6 +3,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <getopt.h> #include <getopt.h>
#include <linux/oom.h> #include <linux/oom.h>
#include <linux/vt.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/prctl.h> #include <sys/prctl.h>
@ -1931,6 +1932,32 @@ static void finish_remaining_processes(ManagerObjective objective) {
broadcast_signal(SIGKILL, /* wait_for_exit= */ false, /* send_sighup= */ false, arg_defaults.timeout_stop_usec); broadcast_signal(SIGKILL, /* wait_for_exit= */ false, /* send_sighup= */ false, arg_defaults.timeout_stop_usec);
} }
static void reduce_vt(ManagerObjective objective) {
int r;
if (objective != MANAGER_SOFT_REBOOT)
return;
/* Switches back to VT 1, and releases all other VTs, in an attempt to return to a situation similar
* to how it was during the original kernel initialization. This is important because if some random
* TTY is in foreground, /dev/console will end up pointing to it, where the future init system will
* then write its status output to, but where it probably shouldn't be writing to. */
r = chvt(1);
if (r < 0)
log_debug_errno(r, "Failed to switch to VT TTY 1, ignoring: %m");
_cleanup_close_ int tty0_fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
if (tty0_fd < 0)
return (void) log_debug_errno(tty0_fd, "Failed to open '/dev/tty0', ignoring: %m");
for (int ttynr = 2; ttynr <= VTNR_MAX; ttynr++)
if (ioctl(tty0_fd, VT_DISALLOCATE, ttynr) < 0)
log_debug_errno(errno, "Failed to disallocate VT TTY %i, ignoring: %m", ttynr);
else
log_debug("Successfully disallocated VT TTY %i.", ttynr);
}
static int do_reexecute( static int do_reexecute(
ManagerObjective objective, ManagerObjective objective,
int argc, int argc,
@ -1998,6 +2025,7 @@ static int do_reexecute(
(void) setrlimit(RLIMIT_MEMLOCK, saved_rlimit_memlock); (void) setrlimit(RLIMIT_MEMLOCK, saved_rlimit_memlock);
finish_remaining_processes(objective); finish_remaining_processes(objective);
reduce_vt(objective);
if (switch_root_dir) { if (switch_root_dir) {
r = switch_root(/* new_root= */ switch_root_dir, r = switch_root(/* new_root= */ switch_root_dir,

View File

@ -1039,7 +1039,7 @@ static int parse_fstab(bool prefix_sysroot) {
log_debug("Parsing %s...", fstab); log_debug("Parsing %s...", fstab);
r = libmount_parse_full(fstab, /* source = */ NULL, &table, &iter); r = libmount_parse_full(fstab, /* source = */ NULL, MNT_ITER_FORWARD, &table, &iter);
if (r == -ENOENT) if (r == -ENOENT)
return 0; return 0;
if (r < 0) if (r < 0)
@ -1442,7 +1442,7 @@ static int add_mounts_from_creds(bool prefix_sysroot) {
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
r = libmount_parse_full(cred, f, &table, &iter); r = libmount_parse_full(cred, f, MNT_ITER_FORWARD, &table, &iter);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse credential '%s' (as fstab): %m", cred); return log_error_errno(r, "Failed to parse credential '%s' (as fstab): %m", cred);

View File

@ -18,12 +18,16 @@
#include "mkdir-label.h" #include "mkdir-label.h"
#include "path-util.h" #include "path-util.h"
#include "pidref.h" #include "pidref.h"
#include "pretty-print.h"
#include "process-util.h" #include "process-util.h"
#include "pull-common.h" #include "pull-common.h"
#include "pull-job.h" #include "pull-job.h"
#include "pull-tar.h" #include "pull-tar.h"
#include "ratelimit.h"
#include "rm-rf.h" #include "rm-rf.h"
#include "string-util.h" #include "string-util.h"
#include "terminal-util.h"
#include "time-util.h"
#include "tmpfile-util.h" #include "tmpfile-util.h"
#include "uid-classification.h" #include "uid-classification.h"
#include "web-util.h" #include "web-util.h"
@ -65,6 +69,9 @@ typedef struct TarPull {
int tree_fd; int tree_fd;
int userns_fd; int userns_fd;
unsigned last_percent;
RateLimit progress_ratelimit;
} TarPull; } TarPull;
TarPull* tar_pull_unref(TarPull *i) { TarPull* tar_pull_unref(TarPull *i) {
@ -144,6 +151,8 @@ int tar_pull_new(
.tar_pid = PIDREF_NULL, .tar_pid = PIDREF_NULL,
.tree_fd = -EBADF, .tree_fd = -EBADF,
.userns_fd = -EBADF, .userns_fd = -EBADF,
.last_percent = UINT_MAX,
.progress_ratelimit = { 100 * USEC_PER_MSEC, 1 },
}; };
i->glue->on_finished = pull_job_curl_on_finished; i->glue->on_finished = pull_job_curl_on_finished;
@ -202,8 +211,20 @@ static void tar_pull_report_progress(TarPull *i, TarProgress p) {
assert_not_reached(); assert_not_reached();
} }
if (percent == i->last_percent)
return;
if (!ratelimit_below(&i->progress_ratelimit))
return;
sd_notifyf(false, "X_IMPORT_PROGRESS=%u%%", percent); sd_notifyf(false, "X_IMPORT_PROGRESS=%u%%", percent);
if (isatty_safe(STDERR_FILENO))
(void) draw_progress_bar("Total:", percent);
log_debug("Combined progress %u%%", percent); log_debug("Combined progress %u%%", percent);
i->last_percent = percent;
} }
static int tar_pull_determine_path( static int tar_pull_determine_path(
@ -323,6 +344,7 @@ static int tar_pull_make_local_copy(TarPull *i) {
t = mfree(t); t = mfree(t);
clear_progress_bar(/* prefix= */ NULL);
log_info("Created new local image '%s'.", i->local); log_info("Created new local image '%s'.", i->local);
if (FLAGS_SET(i->flags, IMPORT_PULL_SETTINGS)) { if (FLAGS_SET(i->flags, IMPORT_PULL_SETTINGS)) {
@ -389,6 +411,8 @@ static void tar_pull_job_on_finished(PullJob *j) {
i = j->userdata; i = j->userdata;
if (j->error != 0) { if (j->error != 0) {
clear_progress_bar(/* prefix= */ NULL);
if (j == i->tar_job) { if (j == i->tar_job) {
if (j->error == ENOMEDIUM) /* HTTP 404 */ if (j->error == ENOMEDIUM) /* HTTP 404 */
r = log_error_errno(j->error, "Failed to retrieve image file. (Wrong URL?)"); r = log_error_errno(j->error, "Failed to retrieve image file. (Wrong URL?)");
@ -452,6 +476,7 @@ static void tar_pull_job_on_finished(PullJob *j) {
tar_pull_report_progress(i, TAR_VERIFYING); tar_pull_report_progress(i, TAR_VERIFYING);
clear_progress_bar(/* prefix= */ NULL);
r = pull_verify(i->verify, r = pull_verify(i->verify,
i->checksum, i->checksum,
i->tar_job, i->tar_job,

View File

@ -86,6 +86,7 @@ int dlopen_libmount(void) {
int libmount_parse_full( int libmount_parse_full(
const char *path, const char *path,
FILE *source, FILE *source,
int direction,
struct libmnt_table **ret_table, struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter) { struct libmnt_iter **ret_iter) {
@ -95,13 +96,14 @@ int libmount_parse_full(
/* Older libmount seems to require this. */ /* Older libmount seems to require this. */
assert(!source || path); assert(!source || path);
assert(IN_SET(direction, MNT_ITER_FORWARD, MNT_ITER_BACKWARD));
r = dlopen_libmount(); r = dlopen_libmount();
if (r < 0) if (r < 0)
return r; return r;
table = sym_mnt_new_table(); table = sym_mnt_new_table();
iter = sym_mnt_new_iter(MNT_ITER_FORWARD); iter = sym_mnt_new_iter(direction);
if (!table || !iter) if (!table || !iter)
return -ENOMEM; return -ENOMEM;
@ -126,7 +128,7 @@ int libmount_parse_fstab(
struct libmnt_table **ret_table, struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter) { struct libmnt_iter **ret_iter) {
return libmount_parse_full(fstab_path(), NULL, ret_table, ret_iter); return libmount_parse_full(fstab_path(), NULL, MNT_ITER_FORWARD, ret_table, ret_iter);
} }
int libmount_is_leaf( int libmount_is_leaf(

View File

@ -47,6 +47,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_iter*, sym_mnt_free_iter,
int libmount_parse_full( int libmount_parse_full(
const char *path, const char *path,
FILE *source, FILE *source,
int direction,
struct libmnt_table **ret_table, struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter); struct libmnt_iter **ret_iter);
@ -55,14 +56,14 @@ static inline int libmount_parse_mountinfo(
struct libmnt_table **ret_table, struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter) { struct libmnt_iter **ret_iter) {
return libmount_parse_full("/proc/self/mountinfo", source, ret_table, ret_iter); return libmount_parse_full("/proc/self/mountinfo", source, MNT_ITER_FORWARD, ret_table, ret_iter);
} }
static inline int libmount_parse_with_utab( static inline int libmount_parse_with_utab(
struct libmnt_table **ret_table, struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter) { struct libmnt_iter **ret_iter) {
return libmount_parse_full(NULL, NULL, ret_table, ret_iter); return libmount_parse_full(NULL, NULL, MNT_ITER_FORWARD, ret_table, ret_iter);
} }
int libmount_parse_fstab(struct libmnt_table **ret_table, struct libmnt_iter **ret_iter); int libmount_parse_fstab(struct libmnt_table **ret_table, struct libmnt_iter **ret_iter);

View File

@ -52,7 +52,7 @@ int umount_recursive_full(const char *prefix, int flags, char **keep) {
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
bool again = false; bool again = false;
r = libmount_parse_mountinfo(f, &table, &iter); r = libmount_parse_full("/proc/self/mountinfo", f, MNT_ITER_BACKWARD, &table, &iter);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m"); return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");