Убить процесс, имеющий статус D

Тема в разделе "WASM.UNIX", создана пользователем mupsy, 2 сен 2011.

  1. mupsy

    mupsy New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2008
    Сообщения:
    55
    Всем привет, имеется следующая проблема...
    Стоит линух с ядром 2.6.32, существует раздел с XFS который мантируется через NFS,
    на XFS разделе задана квота. Когда процесс пытается писать на XFS раздел и превышает квоту то он зависает, ps x показывает что процесс имеет статус 'D' то есть убить обычным kill -9 PID его невозможно...Перезагрузка системы для меня не вариант, может быть есть какие нибудь пути решения этой проблемы,готовый модуль для убийства unkillable процессов или же просто кто нить подскажет в какую сторону копать?

    И еще один вопрос, когда процесс убивается то существует ли какая нибудь возможность скопировать логи из его директории /proc/[PID] ?

    Заранее спасибо.
     
  2. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    Сигнал TERM посылать... вроде так...


    ps позволяет посмотреть какие сигналы можно отправлять...
     
  3. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Нужно узнать на каком объёкте синхронизации он висит. Скорее всего, это inode->i_mutex. Тогда, нужно найти этот инод и разлочить mutex в ручную =)
     
  4. mupsy

    mupsy New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2008
    Сообщения:
    55
    Сигнал TERM не пройдет, так как процесс со статусом 'D' не убьешь никаким сигналом,ядро думает что процесс делает архиважную операцию и не позволяет кильнуть его...

    На сколько я знаю синхронизация должна быть на семафоре...А вот где эти i-node искать? есть какой нить мануал по этому ?
     
  5. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    1. Посмотреть lsof | grep `process name` -- это даст список файлов на чём висит процесс.
    2. Узнать инод файла, на котором он висит.
    3. Найти суперблок точки монтирования, которой принадлежит файл.
    4. Перечислить все иноды данного суперблока с целью поиска того самого ;)
    5. Разлочить мьютекс =)

    И всё это конечно из ядра =)
     
  6. mupsy

    mupsy New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2008
    Сообщения:
    55
    7mm спасибо за ансверы :)

    Это конечно ужасы что мне предстоит сделать но я буду стараться :)
     
  7. loginrl_103

    loginrl_103 New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2008
    Сообщения:
    271
    можно попробовать удалить открытые дескрипторы самого процесса, /proc/pid/fd/

    тама хранятся все открытые дескрипторы процесса, если их ...того...во-общем надо попробовать)
     
  8. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Удалить дескрипторы? Хм.. как вы себе это представляете?..
     
  9. MEPOX

    MEPOX New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    259
    sudo fuser -km =<имя приложения>
    pkill <имя приложения> //вернее часть имени, для точного совпадения лучше использовать killall, но я так никогда не делаю)

    Если у тебя нет оператора "=" подойдет `which <имя>`
     
  10. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    По поводу разлочки inode->i_mutex...

    ## module.c
    Код (Text):
    1. #include <linux/fs.h>
    2. #include <linux/module.h>
    3.  
    4. /* 0 - status, 1 - lock, 2 - unlock */
    5. unsigned int mod = 0;
    6. module_param(mod, int, 0644);
    7.  
    8. /* device's major */
    9. unsigned int maj = -1;
    10. module_param(maj, int, 0644);
    11.  
    12. /* device's minor */
    13. unsigned int min = -1;
    14. module_param(min, int, 0644);
    15.  
    16. /* inode number */
    17. unsigned long ino = -1;
    18. module_param(ino, long, 0644);
    19.  
    20. int init_module(void)
    21. {
    22.     dev_t dev = MKDEV(maj, min);
    23.     struct inode * inode;
    24.     struct super_block * sb;
    25.     struct block_device * bd;
    26.  
    27.     bd = bdget(dev);
    28.     if (!bd) {
    29.         printk("Can't get block device for %u:%u\n", maj, min);
    30.         return -ENODEV;
    31.     }
    32.  
    33.     sb = bd->bd_super;
    34.     printk("Found block device [%pK] with super block [%pK] with filesystem [%s]\n", \
    35.            bd, sb, sb->s_type ? sb->s_type->name : NULL);
    36.  
    37.     list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
    38.         if (inode->i_ino == ino) {
    39.             if (mod == 0) {
    40.                 printk(" - found requested inode [%pK] %lu (%s)\n", inode, \
    41.                        ino, mutex_is_locked(&inode->i_mutex) ? "locked" : "unlocked");
    42.             } else if (mod == 1) {
    43.                 mutex_lock(&inode->i_mutex);
    44.                 printk(" - requested inode %lu locked\n", ino);
    45.             } else if (mod == 2) {
    46.                 mutex_unlock(&inode->i_mutex);
    47.                 printk(" - requested inode %lu unlocked\n", ino);
    48.             }
    49.             break;
    50.         }
    51.     }
    52.  
    53.     bdput(bd);
    54.  
    55.     return -EAGAIN;
    56. }
    57.  
    58. void cleanup_module(void)
    59. {
    60. }
    61.  
    62. MODULE_LICENSE("GPL");
    ## Makefile
    Код (Text):
    1. SOURCE      := $(shell pwd)
    2. KERNEL      := /lib/modules/$(shell uname -r)/build
    3.  
    4. NAME        := kmutexu
    5. obj-m       := $(NAME).o
    6.  
    7. $(NAME)-y   := module.o
    8.  
    9. all :
    10.     $(MAKE) -C $(KERNEL) M=$(SOURCE) modules
    11.  
    12. clean :
    13.     $(MAKE) -C $(KERNEL) M=$(SOURCE) clean