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+
313347int 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