Контейнер Docker зависает в статусе Created

Использование реализации grep, которая знает флаг -oиtr:

#!/bin/sh

printf '%s\n' "$@" | grep -oiE '[0-9]+[^0-9]*booklets' | tr -dc '0-9\n'

Это shскрипт (, а не bash, хотя он будет работать и с bash). Он предполагает, что ни одна строка, переданная ему в командной строке, не содержит встроенного в нее символа новой строки.

Расширенное регулярное выражение [0-9]+[^0-9]*bookletsбудет соответствовать любой строке, похожей на <integer><zero or more non-digit characters><"booklets">, а с -oэто именно то, что будет возвращено из grep. trпросто удаляет из вывода grepвсе, что не является цифрой или новой строкой.

trможно заменить на sed 's/[^0-9].*//', что удалит все, начиная с первого нецифрового символа -в строке.

Проверка:

$ sh script.sh 101s18-exam02--100-booklets.pdf
100
$ sh script.sh "MATH232 Exam 01 99 booklets.pdf"
99
$ sh script.sh 35BOOKLETS.pdf
35

$ sh script.sh 101s18-exam02--100-booklets.pdf "MATH232 Exam 01 99 booklets.pdf" 35BOOKLETS.pdf
100
99
35

Обратите внимание, что строки с пробелами необходимо заключать в кавычки.

2
27.03.2020, 23:46
1 ответ

Анализ журналов, созданных sudo strace -ff -p $(pidof containerd) -o strace_log, показывает, что он останавливается, когда execve()вызывается пользователем. процесс с именем runc init. Это привело меня к этому отчету об ошибке в runc GH. страница , что объясняет, что это ошибка ядра, которая может воспроизводиться с каждым программа, которая использует pthreads и execve()и представляет собой краткий Go программа, с помощью которой можно воспроизвести проблему:

package main

import (
    "os"
    "syscall"
)

func main() {
    syscall.Exec("/bin/echo", []string{"/bin/echo", "Hello"}, os.Environ())
}

Зная, что это ошибка ядра, я использовал Raspberry Pi для тестирования. мог бы быстро собрать и заменить ядро ​​​​Linux, не рискуя основная машина не загружается или играет с виртуальными машинами, а также Go не установлен по умолчанию в Raspbian. Я использовал следующий C программа для тестирования:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdint.h>

void *foo(void *p)
{
  (void) p;
  while(1)
    {
      puts("in thread");
      sleep(2);
    }
}

int main(void)
{
  printf("pid: %jd\n", (intmax_t) getpid());
  pthread_t tid;
  pthread_create(&tid, NULL, foo, NULL);

  char *envp[] = {"var"};
  char *ls_args[] = { "/bin/ls", "-l", NULL};
  if (execve(ls_args[0], ls_args, envp) < 0) {    
    perror("execve error");
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

Постройте с помощью gcc strace-test.c -o strace-test -pthreadи убедитесь, что strace -f./strace-testтакже застревает.

Патч, который должен был исправить strace, отправлен в ядро ​​Linux. список рассылки в 2016 но он не был принят, вы можете прочитать всю дискуссию до понять, почему. Тем не менее, я применил этот патч к своему локальному Дерево ядра Linux для Raspberry Pi против rpi -5.6.y ветвь и после пересборки и замены ядра на Raspberry Pi strace -f./strace-testбольше не зависает. Исходный код Linux имеет немного изменилось с 2016 года, и патч не применяется чисто. ПСВ, полный патч, который я применил,:

diff --git a/kernel/fork.c b/kernel/fork.c
index 60a1295..c26aaa1 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1224,7 +1224,7 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
        struct mm_struct *mm;
        int err;

-       err =  mutex_lock_killable(&task->signal->cred_guard_mutex);
+       err =  mutex_lock_interruptible(&task->signal->cred_guard_mutex);
        if (err)
                return ERR_PTR(err);

diff --git a/kernel/signal.c b/kernel/signal.c
index 9ad8dea..ea7c7b5 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -108,6 +108,10 @@ static bool sig_ignored(struct task_struct *t, int sig, bool force)
        if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))
                return false;

+       /* Do not ignore signals sent from child to the parent */
+       if (current->ptrace && current->parent == t)
+               return 0;
+
        /*
         * Tracers may want to know about even ignored signal unless it
         * is SIGKILL which can't be reported anyway but can be ignored
2
19.03.2021, 02:32

Теги

Похожие вопросы