在Linux系统()调用的问题

问题描述:

我正在研究用于Linux的C++ initramfs的init。该脚本用于解锁带有加密驱动器的DM-Crypt,并将LVM驱动器设置为可用。在Linux系统()调用的问题

由于我不想重新实现cryptsetupgpg的功能,我正在使用系统调用来调用可执行文件。使用系统调用来调用gpg可以正常工作,如果我已经完全启动了系统(我已经有了一个基于initramfs的bash脚本,在启动时可以正常工作,并且我使用grub编辑命令行以使用旧的initramfs)。但是,在initramfs中它甚至不会像调用它一样。即使命令如system("echo BLAH");失败。

那么,有没有人有任何投入?


编辑:所以我想出了什么导致了我的错误。我没有线索为什么它会导致错误,但我发现它。

为了让热插拔,我需要写/sbin/mdev/proc/sys/kernel/hotplug ......不过,我结束了周围的参数开关(上的功能我写我自己不会少),所以我在写/proc/sys/kernel/hotplug/sbin/mdev

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

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合着的第二版增加了一些材料,以涵盖史蒂文斯编写第一版(如Linux和OS X)以来出现的平台,但自从原始版本以来,这样的基础知识没有改变。

+0

非常感谢您的帮助。您实际上回答了一个问题,我没有问过为什么它在manpages中说的地狱使用'exec()'系列函数而不是'system()'时,他们有非常不同的效果。如果你不介意,你有一个有用的管道输出链接? (无论哪种方式,我确实订购了你建议的书,所以我最终会得到一个很好的资源:)) – Thomas 2010-06-18 01:50:10

+1

史蒂文斯在第一版的第14.2节中介绍了它。在第二版中,它转到了第15.2节。 – 2010-06-18 05:20:48

+0

谢谢。我一定会去找的。 – Thomas 2010-06-19 02:40:32

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

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

你在initramfs中有什么?你可以做到以下几点:

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

} 

然后在这样的一个启动脚本与strace它:

strace -o myprog.log myprog 

看一次你的系统启动