【问题标题】:Inside a chroot execvp() returns "Argument list too long"在 chroot execvp() 中返回“参数列表太长”
【发布时间】:2016-06-21 18:50:54
【问题描述】:

我在 chroot 中运行大量命令时遇到问题。命令本身是由 Makefile 触发的,因此错误是经典的:

make: execvp: /bin/sh: Argument list too long

我确实进行了调查,并且了解了查看 make 的源代码,它通过 libc 提供的 execvp() 创建了一个作业(我已经看到该命令作为“/bin/sh”“-c”“传递。 ..我的论点”)。 所以我查看了 libc 源代码,基本上它看起来有一个由 ARG_MAX 定义的限制,但是最近它没有像代码所说的那样使用:

/* Legacy value of ARG_MAX.  The macro is now not defined since the
   actual value varies based on the stack size.  */
#define legacy_ARG_MAX 131072

所以它认为我需要通过以下方式更改堆栈大小:

ulimit -s VALUE

所以我比较了 chroot 之外的值,我确实在 chroot 内部设置了一个更大的值。然而同样的结果... 有人有想法吗?我不知道我的调查方向是否错误。 非常感谢您的帮助!

【问题讨论】:

  • 我不知道是不是这样,因为这可能与它在 chroot 内部失败的事实有关,并且感觉它可能与它有关,因为肯定有限制它,但我不知道是什么......

标签: linux makefile libc chroot execvp


【解决方案1】:

我在 chroot 中运行大量命令时遇到问题。

有人有想法吗?

命令行通常与环境变量和堆栈共享空间,无论您多么努力地拉伸它们,仍然存在限制。

长期的解决方案是避免挑战极限。例如,不是 sh -c "humongous command",而是从 make 文件将 "humongous command" 写入临时文件,然后运行 ​​sh /tmp/filename

【讨论】:

  • 问题在于,无论您想通过命令与 shell 交互的任何方式,Makefile 都必须扩展保存长命令的变量,因此它总是会失败。通过字符串连接构造这个长变量的选项不是一个可行的选项,因为它意味着重写所有的 Makefile,而且它没有意义,因为它在 chroot 之外构建得很好。
  • @Stan,在这种情况下,我没有解决方案。您可能在 ServerFault 上运气更好:这本身不是软件开发主题,而是管理。管理员更了解如何处理系统限制。
【解决方案2】:

我确实解决了使用指向这些对象文件的基本路径的符号链接,将 Makefile 中非常长的对象文件的相对路径替换为较短版本的问题。

@ln -s $(OBJ_BASE_PATH) ./a
NEW_OBJ_FILE_LIST=$(OLD_OBJ_FILE_LIST:$(OBJ_BASE_PATH)%=./a%)

之后,Makefile 可以扩展 $(NEW_OBJ_FILE_LIST),因为它足够短并且可以工作。

我仍然对它在 chroot 之外工作的原因感到困惑。我想唯一的原因是在某种程度上......在某种程度上......在chroot内部,系统正在将路径与chroot的基本路径“连接”起来,就像我的情况一样“/var/chroots/my_long_path_to_the_chroot/”这样就超出了限制。我没有付出任何额外的努力来调查,所以我不确认,我只是假设。

【讨论】:

    猜你喜欢
    • 2020-02-13
    • 2010-09-20
    • 2019-06-03
    • 2017-11-30
    • 2020-05-09
    • 2014-05-21
    • 2015-04-04
    • 2021-10-26
    • 2014-04-18
    相关资源
    最近更新 更多