Моделируйте неубиваемый процесс в состоянии D

Вот То, как можно решить эту проблему:

Кв. (усовершенствованный упаковочный инструмент) является превосходным инструментом для устанавливания/удаления программ и пакетов на Linux. Проблема состоит в том, что программы и пакеты иногда слишком стары.

Чтобы помочь решить это проблемы, можно использовать внешний репозиторий с помощью ppa (персональный архив пакета) для получения более поздних версий программного обеспечения/пакетов.

Давайте возьмем nginx, например. Версия на Кв. 1.1.19 (в то время, когда я записал это), но можно найти новейшую версию с помощью nginx/stable ppa репозиторий, который является 1.2.6.

Давайте посмотрим, как это работает:

add-apt-repository ppa:nginx/stable

add-apt-repository ppa: < user > / < package >

Обновите свои способные пакеты

apt-get update

Установка nginx

apt-get install nginx

Найдите больше репозиториев для своего дистрибутива Linux на: https://launchpad.net/

14
13.06.2014, 12:36
3 ответа

У меня была та же проблема, и я решил ее, создав модуль ядра, который застревает в состоянии D.

Поскольку у меня нет опыта работы с модулями, я взял код из этого туториала с некоторыми изменениями, найденными где-то в другом месте .

В результате устройство в / dev / memory застревает при чтении, но его можно разбудить, записав на него (требуется две записи, я не знаю почему, но мне все равно).

Чтобы использовать это просто:

# make
# make mknod
# make install
# cat /dev/memory   # this gets blocked

Чтобы разблокировать, с другого терминала:

# echo -n a > /dev/memory
# echo -n a > /dev/memory

Makefile:

obj-m += memory.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

install:
    sudo insmod memory.ko

uninstall:
    sudo rmmod memory

mknod:
    sudo mknod /dev/memory c 60 0
    sudo chmod 666 /dev/memory

Код для memory.c:

/* Necessary includes for device drivers */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <asm/uaccess.h> /* copy_from/to_user */
#include <linux/sched.h>

MODULE_LICENSE("Dual BSD/GPL");

/* Declaration of memory.c functions */
int memory_open(struct inode *inode, struct file *filp);
int memory_release(struct inode *inode, struct file *filp);
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos);
void memory_exit(void);
int memory_init(void);

/* Structure that declares the usual file */
/* access functions */
ssize_t memory_write( struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
int memory_open(struct inode *inode, struct file *filp);
int memory_release(struct inode *inode, struct file *filp);
struct file_operations memory_fops = {
    .read = memory_read,
    .write = memory_write,
    .open = memory_open,
    .release = memory_release
};

/* Declaration of the init and exit functions */
module_init(memory_init);
module_exit(memory_exit);

/* Global variables of the driver */
/* Major number */
int memory_major = 60;
/* Buffer to store data */
char *memory_buffer;

int memory_init(void) {
    int result;

    /* Registering device */
    result = register_chrdev(memory_major, "memory", &memory_fops);
    if (result < 0) {
        printk(
                "<1>memory: cannot obtain major number %d\n", memory_major);
        return result;
    }

    /* Allocating memory for the buffer */
    memory_buffer = kmalloc(1, GFP_KERNEL); 
    if (!memory_buffer) { 
        result = -ENOMEM;
        goto fail; 
    } 
    memset(memory_buffer, 0, 1);

    printk("<1>Inserting memory module\n"); 
    return 0;

fail: 
    memory_exit(); 
    return result;
}

void memory_exit(void) {
    /* Freeing the major number */
    unregister_chrdev(memory_major, "memory");

    /* Freeing buffer memory */
    if (memory_buffer) {
        kfree(memory_buffer);
    }

    printk("<1>Removing memory module\n");

}

int memory_open(struct inode *inode, struct file *filp) {

    /* Success */
    return 0;
}

int memory_release(struct inode *inode, struct file *filp) {

    /* Success */
    return 0;
}
static DECLARE_WAIT_QUEUE_HEAD(wq);
static volatile int flag = 0;

ssize_t memory_read(struct file *filp, char *buf, 
        size_t count, loff_t *f_pos) { 

    printk("<1>going to sleep\n");
    flag = 0;
    //wait_event_interruptible(wq, flag != 0);
    wait_event(wq, flag != 0);

    printk("<1>Reading from memory module\n");
    /* Transfering data to user space */ 
    copy_to_user(buf,memory_buffer,1);

    /* Changing reading position as best suits */ 
    if (*f_pos == 0) { 
        *f_pos+=1; 
        return 1; 
    } else { 
        return 0; 
    }
}

ssize_t memory_write( struct file *filp, char *buf,
        size_t count, loff_t *f_pos) {

    char *tmp;

    printk("<1>wake someone up\n");
    flag = 1;
    //wake_up_interruptible(&wq);
    wake_up(&wq);

    printk("<1>Writting to memory module\n");
    tmp=buf+count-1;
    copy_from_user(memory_buffer,tmp,1);
    return 1;
}
2
27.01.2020, 19:51

С https://blogs.oracle.com/ksplice/entry/disown_zombie_children_and_the

Процесс помещается в непрерывную спящую (STAT D), когда ему нужно подождать чего-то (обычно I/O) и он не должен обрабатывать сигналы во время ожидания. Это означает, что вы не можете kill его, потому что все, что он делает kill, это посылает ему сигналы. Это может произойти в реальном мире, если вы отключите NFS сервер, в то время как другие машины имеют к нему открытые сетевые соединения.

Мы можем создать свои собственные бесперебойные процессы ограниченной продолжительности, воспользовавшись системным вызовом vfork. vfork похожа на fork, за исключением того, что адресное пространство не копируется из родительского в дочерний процесс, в ожидании exec, который просто выбрасывает скопированные данные. Удобно для нас, когда вы vfork, родитель непрерывно ждет (посредством wait_on_completion) выхода дочернего exec или exit:

jesstess@aja:~$ cat uninterruptible.c 
int main() {
    vfork();
    sleep(60);
    return 0;
}
jesstess@aja:~$ gcc -o uninterruptible uninterruptible.c
jesstess@aja:~$ echo $$
13291
jesstess@aja:~$ ./uninterruptible
and in another shell:

jesstess@aja:~$ ps -o ppid,pid,stat,cmd $(pgrep -f uninterruptible)

13291  1972 D+   ./uninterruptible
 1972  1973 S+   ./uninterruptible

Мы видим ребенка (PID 1973, PPID 1972) в прерывистом сне и родителя (PID 1972, PPID 13291 -- оболочку) в непрерывном сне, пока он ждет 60 секунд на ребенке.

Одна аккуратная (озорная?) вещь в этом сценарии заключается в том, что процессы в непрерывном сне вносят свой вклад в среднее значение нагрузки на машину. Таким образом, вы можете запустить этот скрипт 100 раз, чтобы временно дать машине нагрузку среднее значение, увеличенное на 100, как сообщалось в uptime .

10
27.01.2020, 19:51

в основном, вы не можете. Прочитайте эту статью, под названием: Task_killable: Новое состояние процесса в Linux .

Выдержка

Ядро 2.6.25

Linux® 2,6.25 ввело новое состояние процессов для процессов спать под названием Task_killable, который предлагает альтернативу эффективным, но потенциально незамедлительным заданным task_uniNTERREBRESTIMAL и простым в пробуждении, но более безопасную задачу.

Это так q & a под названием: Что такое непрерывный процесс? также объясняет его.

Я обнаружил это в этой очень интересной книге под названием: Интерфейс программирования Linux: Linux и Unix System Programming .

2
27.01.2020, 19:51

Теги

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