редактировать:
я, наконец, смог пройти < = 256Кб как единый аргумент командной строки (см редактирования (4) в нижней части). Однако, пожалуйста, внимательно прочитайте, как я это сделал, и решите сами, если это так, как вы хотите. По крайней мере, вы должны понимать, почему вы «застреваете» иначе, чем я узнал.
С сцеплением ARG_MAX
к ulim -s
/4 пришел введение MAX_ARG_STRLEN
как макс. длина аргумента:
/*
* linux/fs/exec.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
...
#ifdef CONFIG_MMU
/*
* The nascent bprm->mm is not visible until exec_mmap() but it can
* use a lot of memory, account these pages in current->mm temporary
* for oom_badness()->get_mm_rss(). Once exec succeeds or fails, we
* change the counter back via acct_arg_size(0).
*/
...
static bool valid_arg_len(struct linux_binprm *bprm, long len)
{
return len <= MAX_ARG_STRLEN;
}
...
#else
...
static bool valid_arg_len(struct linux_binprm *bprm, long len)
{
return len <= bprm->p;
}
#endif /* CONFIG_MMU */
...
static int copy_strings(int argc, struct user_arg_ptr argv,
struct linux_binprm *bprm)
{
...
str = get_user_arg_ptr(argv, argc);
...
len = strnlen_user(str, MAX_ARG_STRLEN);
if (!len)
goto out;
ret = -E2BIG;
if (!valid_arg_len(bprm, len))
goto out;
...
}
...
MAX_ARG_STRLEN
определяется как 32 раз размер страницы в linux/include/uapi/linux/binfmts.h
:
...
/*
* These are the maximum length and maximum number of strings passed to the
* execve() system call. MAX_ARG_STRLEN is essentially random but serves to
* prevent the kernel from being unduly impacted by misaddressed pointers.
* MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer.
*/
#define MAX_ARG_STRLEN (PAGE_SIZE * 32)
#define MAX_ARG_STRINGS 0x7FFFFFFF
...
размер страницы по умолчанию 4KB, так что вы не можете передать аргументы больше, чем 128KB.
Я не могу попробовать это сейчас, но, возможно, переключение на огромный режим страницы (размер страницы 4 МБ), если это возможно, на вашей системе решает эту проблему.
Для получения более подробной информации и ссылок см. this answer - a similar question on Unix & Linux SE.
редактирует:
(1) По this answer можно изменить размер страницы x86_64
Linux до 1 МБ, позволяя CONFIG_TRANSPARENT_HUGEPAGE
и установка CONFIG_TRANSPARENT_HUGEPAGE_MADVISE
в n
в ядре конфигурации.
(2) Перекомпилировав мое ядро с выше изменениями конфигурации getconf PAGESIZE
еще возвращает 4096. По this answerCONFIG_HUGETLB_PAGE
также необходимы, который я мог бы тянуть через CONFIG_HUGETLBFS
. Я перекомпиляю сейчас и снова проверю.
(3) Я пересобрал ядро с поддержкой CONFIG_HUGETLBFS
и теперь /proc/meminfo
содержит соответствующие HugePages_*
записей, указанных в the corresponding section of the kernel documentation. Однако размер страницы в соответствии с getconf PAGESIZE
по-прежнему не изменился. Поэтому, хотя я могу теперь запросить огромные страницы с помощью вызовов mmap
, размер страницы по умолчанию для ядра MAX_ARG_STRLEN
по-прежнему фиксирован на уровне 4 КБ.
(4) Я изменил linux/include/uapi/linux/binfmts.h
к #define MAX_ARG_STRLEN (PAGE_SIZE * 64)
, пересобрал ядро и теперь ваш код производит:
...
117037
123196
123196
129680
129680
136505
143689
151251
159211
...
227982
227982
239981
239981
252611
252611
265906
./testCL: line 11: ./foo: Argument list too long
279901
./testCL: line 11: ./foo: Argument list too long
294632
./testCL: line 11: ./foo: Argument list too long
Так что теперь предел переместился с 128 КБ до 256 КБ, как и ожидалось. Хотя я не знаю о потенциальных побочных эффектах. Насколько я могу судить, моя система работает нормально.
Спасибо, это именно то, о чем я просил. В моем случае это означает, что это невозможно (т. Е. Не может запускать пользовательские ядра). Но очень полезно знать, что я застрял и знаю ** почему **. Кстати, сообщение об ошибке «Список аргументов слишком велико» вводит в заблуждение, особенно потому, что эта часть фактически исправлена. Это вопрос индивидуального аргумента. – swdev