diff --git a/bin/initoverlayfs-install b/bin/initoverlayfs-install index 5f2616f..53bf88d 100755 --- a/bin/initoverlayfs-install +++ b/bin/initoverlayfs-install @@ -119,6 +119,7 @@ extract_initrd_into_initoverlayfs() { # main() args="$*" +initoverlayfs_init="false" while [[ $# -gt 0 ]]; do echo "$1" case $1 in @@ -126,6 +127,11 @@ while [[ $# -gt 0 ]]; do kver="$2" shift 2 ;; + --initoverlayfs-init) + initoverlayfs_init="true" + args=$(echo "$args" | sed "s/--initoverlayfs-init//g") + shift 1 + ;; *) shift 1 ;; @@ -149,11 +155,16 @@ detect_path_initramfs if ! [ -e "$INITOVERLAYFS_CONF" ] || ! grep -q '[^[:space:]]' "$INITOVERLAYFS_CONF"; then boot_partition=$(< /etc/fstab grep "${INITRAMFS_DIR}.*ext4" | awk '{print $1}') - printf "%s\n%s\n%s\n%s\n" \ + printf "%s\n%s\n%s\n%s" \ "bootfs $boot_partition" \ "bootfstype ext4" \ - "initoverlayfs_builder dracut -M -o \"initoverlayfs fcoe\"" \ - "initrd_builder dracut -M -m \"kernel-modules udev-rules initoverlayfs systemd base\" -o \"bash systemd-initrd i18n kernel-modules-extra rootfs-block dracut-systemd usrmount fs-lib microcode_ctl-fw_dir_override shutdown nss-softokn\"" > $INITOVERLAYFS_CONF + "initoverlayfs_builder dracut -M -o \"initoverlayfs fcoe\"" > $INITOVERLAYFS_CONF + + if $initoverlayfs_init; then + printf "%s\n" "initrd_builder dracut -M -m \"initoverlayfs\" -o \"kernel-modules udev-rules systemd base bash systemd-initrd i18n kernel-modules-extra rootfs-block dracut-systemd usrmount fs-lib microcode_ctl-fw_dir_override shutdown nss-softokn\"" >> $INITOVERLAYFS_CONF + else + printf "%s\n" "initrd_builder dracut -M -m \"kernel-modules udev-rules initoverlayfs systemd base\" -o \"bash systemd-initrd i18n kernel-modules-extra rootfs-block dracut-systemd usrmount fs-lib microcode_ctl-fw_dir_override shutdown nss-softokn\"" >> $INITOVERLAYFS_CONF + fi erofs_compression_supported="true" # shellcheck disable=SC2034 @@ -167,6 +178,10 @@ if ! [ -e "$INITOVERLAYFS_CONF" ] || ! grep -q '[^[:space:]]' "$INITOVERLAYFS_CO fi done + if $initoverlayfs_init; then + printf "%s\n" "initoverlayfs_init true" >> $INITOVERLAYFS_CONF + fi + if $erofs_compression_supported; then printf "%s\n" "erofs_compression -zlz4hc,11" >> $INITOVERLAYFS_CONF fi diff --git a/build-scripts/version.sh b/build-scripts/version.sh index 7e23ef7..9c383ac 100755 --- a/build-scripts/version.sh +++ b/build-scripts/version.sh @@ -2,7 +2,7 @@ # SPDX-License-Identifier: LGPL-2.1-or-later # Current version of initoverlayfs -VERSION=0.992 +VERSION=0.993 # Specify if build is a official release or a snapshot build IS_RELEASE=false # Used for official releases. Increment if necessary diff --git a/initoverlayfs.c b/initoverlayfs.c index 38b64ec..2f7ef41 100644 --- a/initoverlayfs.c +++ b/initoverlayfs.c @@ -4,6 +4,7 @@ #include "initoverlayfs.h" #include +#include #include #include #include @@ -102,7 +103,7 @@ exit(errno); \ } while (0) -static inline long loop_ctl_get_free(void) { +static long loop_ctl_get_free(void) { autoclose const int loopctlfd = open("/dev/loop-control", O_RDWR | O_CLOEXEC); if (loopctlfd < 0) { print("open(\"/dev/loop-control\", O_RDWR | O_CLOEXEC) = %d %d (%s)\n", @@ -120,10 +121,10 @@ static inline long loop_ctl_get_free(void) { return devnr; } -static inline int loop_configure(const long devnr, - const int filefd, - char** loopdev, - const char* file) { +static int loop_configure(const long devnr, + const int filefd, + char** loopdev, + const char* file) { const struct loop_config loopconfig = { .fd = (unsigned int)filefd, .block_size = 0, @@ -161,7 +162,7 @@ static inline int loop_configure(const long devnr, return 0; } -static inline int losetup(char** loopdev, const char* file) { +static int losetup(char** loopdev, const char* file) { autoclose const int filefd = open(file, O_RDONLY | O_CLOEXEC); if (filefd < 0) { print("open(\"%s\", O_RDONLY| O_CLOEXEC) = %d %d (%s)\n", file, filefd, @@ -176,7 +177,7 @@ static inline int losetup(char** loopdev, const char* file) { return 0; } -static inline bool convert_bootfs(conf* c) { +static bool convert_bootfs(conf* c, const bool systemd) { if (!c->bootfs.val->c_str) { print("c->bootfs.val.c_str pointer is null\n"); return false; @@ -187,26 +188,48 @@ static inline bool convert_bootfs(conf* c) { return false; } - const char* token = strtok(c->bootfs.val->c_str, "="); autofree char* bootfs_tmp = 0; - if (!strcmp(token, "PARTLABEL")) { - token = strtok(NULL, "="); - if (asprintf(&bootfs_tmp, "/dev/disk/by-partlabel/%s", token) < 0) + if (systemd) { + const char* token = strtok(c->bootfs.val->c_str, "="); + if (!strcmp(token, "PARTLABEL")) { + token = strtok(NULL, "="); + if (asprintf(&bootfs_tmp, "/dev/disk/by-partlabel/%s", token) < 0) + return false; + } else if (!strcmp(token, "LABEL")) { + token = strtok(NULL, "="); + if (asprintf(&bootfs_tmp, "/dev/disk/by-label/%s", token) < 0) + return false; + } else if (!strcmp(token, "UUID")) { + token = strtok(NULL, "="); + if (asprintf(&bootfs_tmp, "/dev/disk/by-uuid/%s", token) < 0) + return false; + } else if (!strcmp(token, "PARTUUID")) { + token = strtok(NULL, "="); + if (asprintf(&bootfs_tmp, "/dev/disk/by-partuuid/%s", token) < 0) + return false; + } else return false; - } else if (!strcmp(token, "LABEL")) { - token = strtok(NULL, "="); - if (asprintf(&bootfs_tmp, "/dev/disk/by-label/%s", token) < 0) - return false; - } else if (!strcmp(token, "UUID")) { - token = strtok(NULL, "="); - if (asprintf(&bootfs_tmp, "/dev/disk/by-uuid/%s", token) < 0) - return false; - } else if (!strcmp(token, "PARTUUID")) { - token = strtok(NULL, "="); - if (asprintf(&bootfs_tmp, "/dev/disk/by-partuuid/%s", token) < 0) + } else { + blkid_cache cache; + + const char* read = NULL; + + // Open the cache + if (blkid_get_cache(&cache, read)) + print("blkid_get_cache(%p, \"%s\")\n", &cache, read ? read : NULL); + + if (blkid_probe_all(cache)) + print("blkid_probe_all(%p)\n", &cache); + + const char* type = strtok(c->bootfs.val->c_str, "="); + const char* value = strtok(NULL, "="); + + const blkid_dev b_dev = blkid_find_dev_with_tag(cache, type, value); + if (asprintf(&bootfs_tmp, "%s", blkid_dev_devname(b_dev)) < 0) return false; - } else - return false; + + blkid_put_cache(cache); + } swap(c->bootfs.scoped->c_str, bootfs_tmp); c->bootfs.val->c_str = c->bootfs.scoped->c_str; @@ -214,7 +237,7 @@ static inline bool convert_bootfs(conf* c) { return true; } -static inline int convert_fs(conf* c) { +static int convert_fs(conf* c) { if (!c->fstype.scoped->c_str) { c->fstype.scoped->c_str = strdup("erofs"); c->fstype.val->c_str = c->fstype.scoped->c_str; @@ -257,7 +280,7 @@ static inline int convert_fs(conf* c) { #define SYSROOT "/initoverlayfs" -static inline void mounts(const conf* c) { +static void mounts(const conf* c) { autofree char* dev_loop = 0; if (c->fs.val->c_str && losetup(&dev_loop, c->fs.val->c_str)) print("losetup(\"%s\", \"%s\") %d (%s)\n", dev_loop, c->fs.val->c_str, @@ -269,25 +292,22 @@ static inline void mounts(const conf* c) { "%d (%s)\n", dev_loop, c->fstype.val->c_str, errno, strerror(errno)); - if (mount("overlay", SYSROOT, "overlay", 0, - "volatile," OVERLAY_STR) && - errno == EINVAL && - mount("overlay", SYSROOT, "overlay", 0, OVERLAY_STR)) - print( - "mount(\"overlay\", \"" SYSROOT "\", \"overlay\", 0, \"" OVERLAY_STR - "\") %d (%s)\n", - errno, strerror(errno)); + if (mount("overlay", SYSROOT, "overlay", 0, "volatile," OVERLAY_STR) && + errno == EINVAL && mount("overlay", SYSROOT, "overlay", 0, OVERLAY_STR)) + print("mount(\"overlay\", \"" SYSROOT "\", \"overlay\", 0, \"" OVERLAY_STR + "\") %d (%s)\n", + errno, strerror(errno)); - if (mount("/boot", SYSROOT "/boot", c->bootfstype.val->c_str, MS_MOVE, - NULL)) - print( - "mount(\"/boot\", \"" SYSROOT "/boot\", \"%s\", MS_MOVE, NULL) " - "%d (%s)\n", - c->bootfstype.val->c_str, errno, strerror(errno)); + if (mount("/boot", SYSROOT "/boot", c->bootfstype.val->c_str, MS_MOVE, NULL)) + print("mount(\"/boot\", \"" SYSROOT + "/boot\", \"%s\", MS_MOVE, NULL) " + "%d (%s)\n", + c->bootfstype.val->c_str, errno, strerror(errno)); } -static void wait_mount_bootfs(const conf* c) { - fork_execlp("udevadm", "wait", c->bootfs.val->c_str); +static void wait_mount_bootfs(const conf* c, const bool systemd) { + if (systemd) + fork_execlp("udevadm", "wait", c->bootfs.val->c_str); errno = 0; if (mount(c->bootfs.val->c_str, "/boot", c->bootfstype.val->c_str, 0, NULL)) @@ -297,25 +317,296 @@ static void wait_mount_bootfs(const conf* c) { c->bootfs.val->c_str, c->bootfstype.val->c_str, errno, strerror(errno)); } -int main(void) { - pid_t loop_pid; - fork_execl_no_wait(loop_pid, "/usr/sbin/modprobe", "loop"); - autofree_conf conf conf = {.bootfs = {0, 0}, - .bootfstype = {0, 0}, - .fs = {0, 0}, - .fstype = {0, 0}}; +static int recursive_rm(const int fd); + +static int if_directory(const int dfd, + const struct dirent* d, + const struct stat* rb, + int* isdir) { + struct stat sb; + if (fstatat(dfd, d->d_name, &sb, AT_SYMLINK_NOFOLLOW)) { + print("stat of %s failed\n", d->d_name); + return 1; + } + + /* skip if device is not the same */ + if (sb.st_dev != rb->st_dev) + return 1; + + /* remove subdirectories */ + if (S_ISDIR(sb.st_mode)) { + autoclose const int cfd = openat(dfd, d->d_name, O_RDONLY); + if (cfd >= 0) + recursive_rm(cfd); /* it closes cfd too */ + + *isdir = 1; + } + + return 0; +} + +static int for_each_directory(DIR* dir, const int dfd, const struct stat* rb) { + errno = 0; + struct dirent* d = readdir(dir); + if (!d) { + if (errno) { + print("failed to read directory\n"); + return -1; + } + + return 0; /* end of directory */ + } + + if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..") || + !strcmp(d->d_name, "initoverlayfs")) + return 1; + + int isdir = 0; + if (d->d_type == DT_DIR || d->d_type == DT_UNKNOWN) + if (if_directory(dfd, d, rb, &isdir)) + return 1; + + if (unlinkat(dfd, d->d_name, isdir ? AT_REMOVEDIR : 0)) + print("failed to unlink %s\n", d->d_name); + + return 1; +} + +/* remove all files/directories below dirName -- don't cross mountpoints */ +static int recursive_rm(const int fd) { + autoclosedir DIR* dir = fdopendir(fd); + if (!dir) { + print("failed to open directory\n"); + return -1; + } + + struct stat rb; + const int dfd = dirfd(dir); + if (fstat(dfd, &rb)) { + print("stat failed\n"); + return -1; + } + + while (1) { + const int ret = for_each_directory(dir, dfd, &rb); + if (ret <= 0) + return ret; + } + + return 0; +} + +static int move_chroot_chdir(const char* newroot) { + printd("move_chroot_chdir(\"%s\")\n", newroot); + if (mount(newroot, "/", NULL, MS_MOVE, NULL) < 0) { + print("failed to mount moving %s to /\n", newroot); + return -1; + } + + if (chroot(".")) { + print("failed to change root\n"); + return -1; + } + + if (chdir("/")) { + print("cannot change directory to %s\n", "/"); + return -1; + } + + return 0; +} + +static int switchroot_move(const char* newroot) { + if (chdir(newroot)) { + print("failed to change directory to %s", newroot); + return -1; + } + + autoclose const int cfd = open("/", O_RDONLY | O_CLOEXEC); + if (cfd < 0) { + print("cannot open %s", "/"); + return -1; + } + + if (move_chroot_chdir(newroot)) + return -1; + + switch (fork()) { + case 0: /* child */ + { + struct statfs stfs; + if (fstatfs(cfd, &stfs) == 0 && + (stfs.f_type == RAMFS_MAGIC || stfs.f_type == TMPFS_MAGIC)) { + recursive_rm(cfd); + } else + print("old root filesystem is not an initramfs"); + + exit(EXIT_SUCCESS); + } + case -1: /* error */ + break; + + default: /* parent */ + return 0; + } + + return -1; +} + +static int stat_oldroot_newroot(const char* newroot, + struct stat* newroot_stat, + struct stat* oldroot_stat) { + if (stat("/", oldroot_stat) != 0) { + print("stat of %s failed\n", "/"); + return -1; + } + + if (stat(newroot, newroot_stat) != 0) { + print("stat of %s failed\n", newroot); + return -1; + } + + return 0; +} + +static int switchroot(const char* newroot) { + /* Don't try to unmount the old "/", there's no way to do it. */ + // const char* umounts[] = {"/dev", "/proc", "/sys", "/run", NULL}; + const char* umounts[] = {"/dev", "/sys", "/run", NULL}; + // const char* umounts[] = {"/dev", NULL}; + struct stat newroot_stat, oldroot_stat, sb; + if (stat_oldroot_newroot(newroot, &newroot_stat, &oldroot_stat)) + return -1; + + for (int i = 0; umounts[i] != NULL; ++i) { + autofree char* newmount; + if (asprintf(&newmount, "%s%s", newroot, umounts[i]) < 0) { + print( + "asprintf(%p, \"%%s%%s\", \"%s\", \"%s\") MS_NODEV, NULL) %d (%s)\n", + (void*)newmount, newroot, umounts[i], errno, strerror(errno)); + return -1; + } + + if ((stat(umounts[i], &sb) == 0) && sb.st_dev == oldroot_stat.st_dev) { + /* mount point to move seems to be a normal directory or stat failed */ + continue; + } + + printd("(stat(\"%s\", %p) == 0) && %lx != %lx)\n", newmount, (void*)&sb, + sb.st_dev, newroot_stat.st_dev); + if ((stat(newmount, &sb) != 0) || (sb.st_dev != newroot_stat.st_dev)) { + /* mount point seems to be mounted already or stat failed */ + umount2(umounts[i], MNT_DETACH); + continue; + } + + printd("mount(\"%s\", \"%s\", NULL, MS_MOVE, NULL)\n", umounts[i], + newmount); + if (mount(umounts[i], newmount, NULL, MS_MOVE, NULL) < 0) { + print("failed to mount moving %s to %s, forcing unmount\n", umounts[i], + newmount); + umount2(umounts[i], MNT_FORCE); + } + } + + return switchroot_move(newroot); +} + +static int mount_proc_sys_dev(void) { + if (false) { + if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV, + NULL)) { + print( + "mount(\"proc\", \"/proc\", \"proc\", MS_NOSUID | MS_NOEXEC | " + "MS_NODEV, NULL) %d (%s)\n", + errno, strerror(errno)); + return errno; + } + } + + if (mount("sysfs", "/sys", "sysfs", MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL)) { + print( + "mount(\"sysfs\", \"/sys\", \"sysfs\", MS_NOSUID | MS_NOEXEC | " + "MS_NODEV, NULL) %d (%s)\n", + errno, strerror(errno)); + return errno; + } + + if (mount("devtmpfs", "/dev", "devtmpfs", MS_NOSUID | MS_STRICTATIME, + "mode=0755,size=4m")) { + print( + "mount(\"devtmpfs\", \"/dev\", \"devtmpfs\", MS_NOSUID | " + "MS_STRICTATIME, \"mode=0755,size=4m\") %d (%s)\n", + errno, strerror(errno)); + return errno; + } + + return 0; +} + +static FILE* log_open_kmsg(void) { + kmsg_f = fopen("/dev/kmsg", "w"); + if (!kmsg_f) { + print("open(\"/dev/kmsg\", \"w\"), %d = errno\n", errno); + return kmsg_f; + } + + setvbuf(kmsg_f, 0, _IOLBF, 0); + return kmsg_f; +} + +static void execl_single_arg(const char* exe) { + printd("execl_single_arg(\"%s\")\n", exe); + execl(exe, exe, (char*)NULL); +} + +static void exec_init(void) { + execl_single_arg("/sbin/init"); + execl_single_arg("/etc/init"); + execl_single_arg("/bin/init"); + execl_single_arg("/bin/sh"); +} + +int main(int argc, char* argv[]) { + (void)argv; + bool systemd = false; + if (argc > 1) + systemd = true; + + autofclose FILE* kmsg_f_scoped = NULL; + if (!systemd) { + mount_proc_sys_dev(); + log_open_kmsg(); + kmsg_f = kmsg_f_scoped; + } + + pid_t loop_pid = 0; + if (systemd) { + fork_execl_no_wait(loop_pid, "/usr/sbin/modprobe", "loop"); + } + + autofree_conf conf conf = { + .bootfs = {0, 0}, .bootfstype = {0, 0}, .fs = {0, 0}, .fstype = {0, 0}}; if (conf_construct(&conf)) return 0; conf_read(&conf, "/etc/initoverlayfs.conf"); - const bool do_bootfs = convert_bootfs(&conf); + const bool do_bootfs = convert_bootfs(&conf, systemd); convert_fs(&conf); - waitpid(loop_pid, 0, 0); + if (systemd) + waitpid(loop_pid, 0, 0); + if (do_bootfs) - wait_mount_bootfs(&conf); + wait_mount_bootfs(&conf, systemd); errno = 0; mounts(&conf); + if (switchroot("/initoverlayfs")) { + print("switchroot(\"/initoverlayfs\") %d (%s)\n", errno, strerror(errno)); + return 0; + } + + exec_init(); return 0; } diff --git a/initoverlayfs.h b/initoverlayfs.h index e5d4f61..5656d2e 100644 --- a/initoverlayfs.h +++ b/initoverlayfs.h @@ -28,6 +28,11 @@ #define print(...) \ do { \ + if (kmsg_f) { \ + fprintf(kmsg_f, "storage-init: " __VA_ARGS__); \ + break; \ + } \ + \ printf(__VA_ARGS__); \ } while (0) @@ -41,6 +46,8 @@ #define printd(...) #endif +static FILE* kmsg_f = 0; + typedef struct str { char* c_str; int len; diff --git a/initoverlayfs.spec.in b/initoverlayfs.spec.in index 05c686f..95939bc 100644 --- a/initoverlayfs.spec.in +++ b/initoverlayfs.spec.in @@ -7,6 +7,7 @@ URL: https://github.com/containers/initoverlayfs Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz BuildRequires: gcc +BuildRequires: libblkid-devel Recommends: lz4 Recommends: gzip Requires: erofs-utils @@ -22,7 +23,7 @@ Requires: dracut %build RPM_OPT_FLAGS="${RPM_OPT_FLAGS/-flto=auto /}" -gcc ${RPM_OPT_FLAGS} initoverlayfs.c -o initoverlayfs +gcc ${RPM_OPT_FLAGS} -lblkid initoverlayfs.c -o initoverlayfs %install install -D -m755 bin/initoverlayfs-install ${RPM_BUILD_ROOT}/%{_bindir}/initoverlayfs-install @@ -44,6 +45,12 @@ install -D -m644 lib/systemd/system/pre-initoverlayfs-switch-root.service ${RPM_ %{_prefix}/lib/systemd/system/pre-initoverlayfs-switch-root.service %changelog +* Mon Mar 11 2024 Eric Curtin - 0.993-1 +- Add option to use initoverlayfs as an init system and mount + storage immediately. +- Used in Automotive, requires storage drivers to be built + directly in the kernel. + * Mon Feb 12 2024 Eric Curtin - 0.992-1 - Update to 0.992 release. - Automatically rebuild kernel on upgrade (ecurtin) diff --git a/lib/dracut/modules.d/81initoverlayfs/module-setup.sh b/lib/dracut/modules.d/81initoverlayfs/module-setup.sh index ee467d9..63fcc68 100644 --- a/lib/dracut/modules.d/81initoverlayfs/module-setup.sh +++ b/lib/dracut/modules.d/81initoverlayfs/module-setup.sh @@ -4,26 +4,34 @@ installkernel() { hostonly="" instmods erofs overlay loop } -# called by dracut -depends() { - echo "systemd" -} - install() { - inst_multiple -o /etc/initoverlayfs.conf /usr/sbin/initoverlayfs \ - "/etc/initoverlayfs-hash-$kernel.img" \ - "$systemdsystemunitdir/pre-initoverlayfs.target" \ + INITOVERLAYFS_CONF="/etc/initoverlayfs.conf" + INITOVERLAYFS_INIT=$(sed -ne "s/^initoverlayfs_init\s//pg" "$INITOVERLAYFS_CONF") + USE_SYSTEMD="true" + if [ "$INITOVERLAYFS_INIT" = "true" ]; then + USE_SYSTEMD="false" + fi + + inst_multiple -o $INITOVERLAYFS_CONF /usr/sbin/initoverlayfs \ + /usr/sbin/blkid /usr/bin/bash "/etc/initoverlayfs-hash-$kernel.img" + + if $USE_SYSTEMD; then + inst_multiple -o "$systemdsystemunitdir/pre-initoverlayfs.target" \ "$systemdsystemunitdir/pre-initoverlayfs.service" \ "$systemdsystemunitdir/pre-initoverlayfs-switch-root.service" + fi + inst_dir /boot /initrofs /overlay /overlay/upper /overlay/work /initoverlayfs - inst_dir /boot /initrofs /overlay /overlay/upper /overlay/work \ - /initoverlayfs - + if $USE_SYSTEMD; then $SYSTEMCTL -q --root "$initdir" set-default pre-initoverlayfs.target $SYSTEMCTL -q --root "$initdir" add-wants sysinit.target pre-initoverlayfs.service $SYSTEMCTL -q --root "$initdir" add-wants sysinit.target pre-initoverlayfs-switch-root.service + else + ln_r "/usr/sbin/initoverlayfs" "/usr/sbin/init" + ln_r "/usr/sbin/initoverlayfs" "/init" + fi - > "${initdir}/usr/bin/bash" + > "${initdir}/usr/bin/bash" } diff --git a/scripts/build-bin-only.sh b/scripts/build-bin-only.sh index af6d985..578f7d8 100755 --- a/scripts/build-bin-only.sh +++ b/scripts/build-bin-only.sh @@ -2,18 +2,20 @@ set -ex -clang++ -o a -O3 -pedantic -fno-exceptions -fno-rtti -Wall -Wextra -Werror -Wno-write-strings -Wno-language-extension-token -Wno-deprecated -std=c++20 initoverlayfs.c & -g++ -o b -O0 -ggdb -pedantic -fno-exceptions -fno-rtti -Wall -Wextra -Werror -Wno-write-strings -Wno-language-extension-token -std=c++20 initoverlayfs.c & -clang -o c -O3 -pedantic -fno-exceptions -Wall -Wextra -Werror -Wno-language-extension-token initoverlayfs.c & +FLAGS="-lblkid" + +clang++ -o a -O3 $FLAGS -pedantic -fno-exceptions -fno-rtti -Wall -Wextra -Werror -Wno-write-strings -Wno-language-extension-token -Wno-deprecated -std=c++20 initoverlayfs.c & +g++ -o b -O0 $FLAGS -ggdb -pedantic -fno-exceptions -fno-rtti -Wall -Wextra -Werror -Wno-write-strings -Wno-language-extension-token -std=c++20 initoverlayfs.c & +clang -o c -O3 $FLAGS -pedantic -fno-exceptions -Wall -Wextra -Werror -Wno-language-extension-token initoverlayfs.c & if [ -e /usr/lib/rpm/redhat/redhat-hardened-cc1 ]; then - gcc -O2 -fanalyzer -fno-exceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection initoverlayfs.c -o d & + gcc -O2 $FLAGS -fanalyzer -fno-exceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection initoverlayfs.c -o d & else - gcc -O2 -fanalyzer -fno-exceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection initoverlayfs.c -o d & + gcc -O2 $FLAGS -fanalyzer -fno-exceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection initoverlayfs.c -o d & fi wait -gcc -O0 -fno-exceptions -ggdb -pedantic -Wall -Wextra -Werror -fanalyzer initoverlayfs.c -sudo valgrind ./a.out +gcc -O0 $FLAGS -fno-exceptions -ggdb -pedantic -Wall -Wextra -Werror -fanalyzer initoverlayfs.c +#sudo valgrind ./a.out diff --git a/scripts/install.sh b/scripts/install.sh index 15ece7f..be6af2b 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -12,5 +12,5 @@ if rpm -Uvh "$rpm_to_install"; then echo "$rpmbuild_output" fi -initoverlayfs-install +initoverlayfs-install -f "$1" diff --git a/scripts/install_perf.sh b/scripts/install_perf.sh new file mode 100755 index 0000000..6774a8c --- /dev/null +++ b/scripts/install_perf.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +set -ex + +REL="$(git tag | tail -1)" +mkdir -p "$HOME/rpmbuild/SOURCES/" +git archive -o "$HOME/rpmbuild/SOURCES/initoverlayfs-$REL.tar.gz" --prefix "initoverlayfs-$REL/" HEAD +./build-scripts/create-spec.sh +rpmbuild_output=$(rpmbuild -bb initoverlayfs.spec 2>&1) +rpm_to_install=$(echo "$rpmbuild_output" | grep "Wrote:" | awk '{print $2}') +if rpm -Uvh "$rpm_to_install"; then + echo "$rpmbuild_output" +fi + +if [ "$1" = "rootfs" ]; then + head -c "$2" /dev/urandom > /usr/bin/binary + cp binary-reader.service /usr/lib/systemd/system/ + gcc -O3 read.c -o /usr/bin/binary-reader + ln -fs ../binary-reader.service /usr/lib/systemd/system/sysinit.target.wants/ + dracut -f -o initoverlayfs +elif [ "$1" = "initrd" ]; then + rm -f /usr/lib/systemd/system/sysinit.target.wants/binary-reader.service + mkdir -p /usr/lib/dracut/modules.d/81early-service/ + cp lib/dracut/modules.d/81early-service/module-setup.sh /usr/lib/dracut/modules.d/81early-service/ + dracut -f -o initoverlayfs +elif [ "$1" = "initoverlayfs" ]; then + rm -rf /boot/initr* + initoverlayfs-install -f --initoverlayfs-init +fi +