2

我正在init为 Linux 的 C++ 中的 initramfs 工作。此脚本用于解锁带有 LUKS 加密驱动器的 DM-Crypt,并将 LVM 驱动器设置为可用。

因为我不想重新实现它的功能,cryptsetup所以gpg我正在使用系统调用来调用可执行文件。如果我已经完全启动了系统,则使用系统调用来调用 gpg 可以正常工作(我已经有一个基于 bash 脚本的 initramfs 可以正常启动它,并且我使用 grub 编辑命令行以使用旧的initramfs)。然而,在 initramfs 中,它甚至从来没有像被调用过一样。甚至像system("echo BLAH"); 失败这样的命令。

那么,有人有意见吗?


编辑:所以我弄清楚是什么导致了我的错误。我不知道为什么会导致错误,但我找到了。

为了允许热插拔,我需要写信/sbin/mdev/proc/sys/kernel/hotplug...但是我最终切换了参数(在我自己写的函数上)所以我写信/proc/sys/kernel/hotplug/sbin/mdev.

我不知道为什么会导致问题,但是确实如此。

4

3 回答 3

7

我相信 system() 函数会在 shell 中执行您的命令。shell 可执行文件是否在启动过程的早期就已安装并可用?您可能想研究使用 fork() 和 execve()。

编辑:确保您的加密工具也在安装的卷上。

于 2010-06-16T18:05:47.580 回答
7

Amardeep 是对的,system()在 POSIX 类型系统上通过/bin/sh.

我怀疑您是否真的需要通过 Bourne shell 调用您所说的这些程序。一个很好的理由是,如果您需要它们具有默认的环境变量集,但由于/etc/profile在引导过程的早期可能也不可用,所以我看不出这里是怎么回事。

相反,使用标准fork()/exec()模式:

int system_alternative(const char* pgm, char *const argv[])
{
    pid_t pid = fork();
    if (pid > 0) {
        // We're the parent, so wait for child to finish
        int status;
        waitpid(pid, &status, 0);
        return status;
    }
    else if (pid == 0) {
        // We're the child, so run the specified program.  Our exit status will
        // be that of the child program unless the execv() syscall fails.
        return execv(pgm, argv);
    }
    else {
        // Something horrible happened, like system out of memory
        return -1;
    }
}

如果您需要从被调用的进程中读取标准输出或将数据发送到其标准输入,则需要通过pipe()dup2()在其中进行一些标准句柄重定向。

您可以在任何一本好的 Unix 编程书籍中了解有关此类事情的所有信息。我推荐W. Richard Stevens的《UNIX 环境中的高级编程》 。由 Rago 合着的第二版增加了涵盖自 Stevens 编写第一版以来出现的平台的材料,如 Linux 和 OS X,但此类基础知识自原版以来并未改变。

于 2010-06-16T20:48:03.587 回答
1

你在 initramfs 有什么?您可以执行以下操作:

int main() {
   return system("echo hello world");

}

然后在这样的 initscript 中对其进行 strace :

strace -o myprog.log myprog

系统启动后查看日志

于 2010-06-16T18:51:39.457 回答