Всем привет, имеется следующая проблема... Стоит линух с ядром 2.6.32, существует раздел с XFS который мантируется через NFS, на XFS разделе задана квота. Когда процесс пытается писать на XFS раздел и превышает квоту то он зависает, ps x показывает что процесс имеет статус 'D' то есть убить обычным kill -9 PID его невозможно...Перезагрузка системы для меня не вариант, может быть есть какие нибудь пути решения этой проблемы,готовый модуль для убийства unkillable процессов или же просто кто нить подскажет в какую сторону копать? И еще один вопрос, когда процесс убивается то существует ли какая нибудь возможность скопировать логи из его директории /proc/[PID] ? Заранее спасибо.
Нужно узнать на каком объёкте синхронизации он висит. Скорее всего, это inode->i_mutex. Тогда, нужно найти этот инод и разлочить mutex в ручную =)
Сигнал TERM не пройдет, так как процесс со статусом 'D' не убьешь никаким сигналом,ядро думает что процесс делает архиважную операцию и не позволяет кильнуть его... На сколько я знаю синхронизация должна быть на семафоре...А вот где эти i-node искать? есть какой нить мануал по этому ?
1. Посмотреть lsof | grep `process name` -- это даст список файлов на чём висит процесс. 2. Узнать инод файла, на котором он висит. 3. Найти суперблок точки монтирования, которой принадлежит файл. 4. Перечислить все иноды данного суперблока с целью поиска того самого 5. Разлочить мьютекс =) И всё это конечно из ядра =)
можно попробовать удалить открытые дескрипторы самого процесса, /proc/pid/fd/ тама хранятся все открытые дескрипторы процесса, если их ...того...во-общем надо попробовать)
sudo fuser -km =<имя приложения> pkill <имя приложения> //вернее часть имени, для точного совпадения лучше использовать killall, но я так никогда не делаю) Если у тебя нет оператора "=" подойдет `which <имя>`
По поводу разлочки inode->i_mutex... ## module.c Код (Text): #include <linux/fs.h> #include <linux/module.h> /* 0 - status, 1 - lock, 2 - unlock */ unsigned int mod = 0; module_param(mod, int, 0644); /* device's major */ unsigned int maj = -1; module_param(maj, int, 0644); /* device's minor */ unsigned int min = -1; module_param(min, int, 0644); /* inode number */ unsigned long ino = -1; module_param(ino, long, 0644); int init_module(void) { dev_t dev = MKDEV(maj, min); struct inode * inode; struct super_block * sb; struct block_device * bd; bd = bdget(dev); if (!bd) { printk("Can't get block device for %u:%u\n", maj, min); return -ENODEV; } sb = bd->bd_super; printk("Found block device [%pK] with super block [%pK] with filesystem [%s]\n", \ bd, sb, sb->s_type ? sb->s_type->name : NULL); list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { if (inode->i_ino == ino) { if (mod == 0) { printk(" - found requested inode [%pK] %lu (%s)\n", inode, \ ino, mutex_is_locked(&inode->i_mutex) ? "locked" : "unlocked"); } else if (mod == 1) { mutex_lock(&inode->i_mutex); printk(" - requested inode %lu locked\n", ino); } else if (mod == 2) { mutex_unlock(&inode->i_mutex); printk(" - requested inode %lu unlocked\n", ino); } break; } } bdput(bd); return -EAGAIN; } void cleanup_module(void) { } MODULE_LICENSE("GPL"); ## Makefile Код (Text): SOURCE := $(shell pwd) KERNEL := /lib/modules/$(shell uname -r)/build NAME := kmutexu obj-m := $(NAME).o $(NAME)-y := module.o all : $(MAKE) -C $(KERNEL) M=$(SOURCE) modules clean : $(MAKE) -C $(KERNEL) M=$(SOURCE) clean