amarao (amarao_san) wrote,
amarao
amarao_san

Отцепиться от терминала

Задачка становится всё веселее - я не могу отцепиться от терминала.

Суть проблемы:

Есть функция:
def hung():
path='/sys/devices/pci0000:80/0000:80:07.0/0000:85:00.0/host5/port-5:1/expander-5:1/port-5:1:21/end_device-5:1:21/target5:0:46/5:0:46:0/enclosure/5:0:46:0/Slot 09/fault'
file(path,'r').read()

Которая в реальной боевой испорченной системе вызывает статус TASK_ININTERRUPTBLE у процесса. После получения этого статуса процесс не реагирует ни на какие сигналы (не получает их). Ни SIGKILL, ни SIGHUP, ни SIGTSTP, ни SIGSTOP.

Сейчас сделано: декоратор, который запускает эту функцию в отдельном треде, ждёт завершения вызванного, или по таймауту рейзит эксепшен. Эксепшен может быть пойман, после этого можно делать что угодно, но завершить процесс невозможно.

Что нужно: отцепиться от терминала по этому эксепшену.

Вопрос: как? В обычном коде я могу сам себе послать TSTP и всё становится бело и пушисто. Но в случае выполнения hung() я теряю все сигналы. И, судя по всему, не только сигналы.

Вот пример самого хардкорного кода, который мне удалось написать (я пробовал _exit(), но он тоже не работает).

import signal
import thread_timeout
import os
import sys
import ctypes

@thread_timeout.thread_timeout(1)
def hung():
        path='/sys/devices/..../Slot 09/fault' # см выше
        file(path,'r').read()

try:
        hung()
except thread_timeout.FailedKillExecTimeout:
        print "failed"
        ctypes.CDLL("libc.so.6").daemon()


И вот этот вот код отлично работает, если read() заменить на sleep(100000). Процесс демонизируется, отцепляется от консоли. А при залипшем треде - не демонизируется.

Кстати, поборники "хорошотредовых языков программирования", если вы на чём-то типа go мне напишете эквивалент этого кода, то я могу попробовать проверить его в боевых условиях на сервере с залипшим IO. Мне моя интуиция говорит, что будет примерно то же самое.

В чём вопрос-то: а что именно делает функция daemon()? Всякие закрытия stdin/out мне понятны. Мне интересен момент, когда башу возвращается управление. Для этого нужно, видимо, завершить основной тред, да?

А этого-то как раз я и не могу сделать в питоне.

Ща попробую на ассемблере сисколл вызвать...
Tags: python, thread_timeout, ненависть
Subscribe

  • Rust soundness

    Каждый раз, когда я сталкиваюсь с маленькими "но" в Rust'е, это ощущение тщательной продуманности. Например, простейшие fold-функции для итераторов:…

  • still_ntp

    В ходе локального мозгового штурма у меня родилась суперидея. Надо написать ntp сервер, который может отдавать указанную дату. Т.е. сказали при…

  • arping'а не достаточно

    Я обнаружил, что arping не умеет делать целый запрос полностью (т.е. source mac, dest mac, source ip, dest ip). Dest либо IP, либо mac, и это немного…

  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 2 comments