Skip to content

Commit 44c6660

Browse files
chroot before systemd switches root
chroot to the directory where systemd switches root from the initramfs. Otherwise the svg file cannot be saved.
1 parent 3f1dccd commit 44c6660

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

src/bootchart.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
#include <sys/uio.h>
4545
#include <time.h>
4646
#include <unistd.h>
47+
#include <sys/stat.h>
48+
#include <libgen.h>
4749

4850
#ifdef HAVE_LIBSYSTEMD
4951
#include <systemd/sd-journal.h>
@@ -310,6 +312,38 @@ static int do_journal_append(char *file) {
310312
return 0;
311313
}
312314

315+
316+
static int is_mountpoint(const char *path) {
317+
struct stat s_path, s_parent;
318+
char *path_aux, *parent_path;
319+
320+
// Root is always a mountpoint
321+
if (strcmp(path, "/") == 0) {
322+
return 1;
323+
}
324+
325+
if (stat(path, &s_path) == -1) {
326+
return -1;
327+
}
328+
329+
// Duplicate path as dirname can modify it
330+
path_aux = strdup(path);
331+
if (!path_aux) {
332+
return -1;
333+
}
334+
335+
parent_path = dirname(path_aux);
336+
if (stat(parent_path, &s_parent) == -1) {
337+
free(path_aux);
338+
return -1;
339+
}
340+
341+
free(path_aux);
342+
343+
// mount point if the directory and its parent are on different devices (filesystems)
344+
return (s_path.st_dev != s_parent.st_dev);
345+
}
346+
313347
int main(int argc, char *argv[]) {
314348
static struct list_sample_data *sampledata;
315349
_cleanup_closedir_ DIR *proc = NULL;
@@ -333,6 +367,7 @@ int main(int argc, char *argv[]) {
333367
.sa_handler = signal_handler,
334368
};
335369
bool has_procfs = false;
370+
bool sysroot_mounted = false;
336371

337372
parse_conf();
338373

@@ -433,6 +468,25 @@ int main(int argc, char *argv[]) {
433468
if (r < 0)
434469
return EXIT_FAILURE;
435470
}
471+
if (!sysroot_mounted) {
472+
// sysroot is where systemd will switch root when
473+
// switching from initramfs to the root fs. We chroot
474+
// there so we can write later the svg file.
475+
//
476+
// TODO instead of detecting this way, use signal from initramfs service.
477+
sysroot_mounted = is_mountpoint("/sysroot") == 1;
478+
if (sysroot_mounted) {
479+
// chroot does not change the cwd of the process, so we do that first
480+
if (chdir("/sysroot") != 0) {
481+
log_info_errno(errno, "cannot chdir to /sysroot: %m\n");
482+
return EXIT_FAILURE;
483+
}
484+
if (chroot(".") != 0) {
485+
log_info_errno(errno, "cannot chroot: %m\n");
486+
return EXIT_FAILURE;
487+
}
488+
}
489+
}
436490

437491
sample_stop = gettime_ns();
438492

0 commit comments

Comments
 (0)