我正在为{C ++ for Linux中的initramfs工作init
。此脚本用于解锁DM-Crypt w / LUKS加密驱动器,并将LVM驱动器设置为可用。
由于我不想重新实现cryptsetup
和gpg
的功能,我使用系统调用来调用可执行文件。如果我已经完全调出系统,使用系统调用来调用gpg工作正常(我已经有一个基于bash脚本的initramfs可以很好地启动它,我使用grub来编辑命令行来使用它来启动它旧的initramfs)。但是,在initramfs中,它甚至都不会被调用。甚至像system("echo BLAH");
这样的命令也会失败。
那么,有没有人有任何意见?
编辑:所以我弄清楚导致我的错误的原因。我不知道为什么会导致错误,但我找到了它。
为了允许热插拔,我需要将/sbin/mdev
写入/proc/sys/kernel/hotplug
...但是我最终切换了参数(在我自己写的一个函数上),所以我正在编写{ {1}}至/proc/sys/kernel/hotplug
。
我不清楚为什么会导致这个问题,但确实如此。
答案 0 :(得分:6)
我相信system()函数在shell中执行你的命令。在启动过程的早期,shell可执行文件是否已安装且可用?您可能希望研究使用fork()和execve()。
编辑:确保您的加密工具也在已安装的卷上。
答案 1 :(得分:6)
Amardeep是对的,POSIX类型系统上的system()
通过/bin/sh
运行命令。
我怀疑你真的有合法的需要通过Bourne shell调用你所说的这些程序。一个很好的理由是,如果你需要它们拥有默认的环境变量集,但由于/etc/profile
可能在启动过程的早期也不可用,我不知道这是怎么回事。< / p>
相反,请使用标准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;
}
}
如果您需要从被调用进程读取stdout或将数据发送到其stdin,您需要通过pipe()
或dup2()
进行一些标准句柄重定向。
你可以在任何优秀的Unix编程书中学到所有这些东西。我推荐W. Richard Stevens在UNIX环境中使用高级编程。由Rago合着的第二版增加了自Stevens编写第一版以来出现的平台的材料,如Linux和OS X,但这样的基础知识自原版以来没有改变。
答案 2 :(得分:1)
你在initramfs中有什么?您可以执行以下操作:
int main() {
return system("echo hello world");
}
然后将其插入这样的脚本中:
strace -o myprog.log myprog
系统启动后查看日志