Изменение фона гнома из модуля ядра - PullRequest
2 голосов
/ 14 января 2012

Я пытаюсь установить фон из модуля ядра, но не могу заставить его работать.

То, что я уже получил, это:

static void change_desktop(unsigned long unused);

static struct timer_list timer = TIMER_INITIALIZER(change_desktop, 0, 0);

static int umh_test( void ) {
    char *argv[] = { "/usr/bin/sudo", "-u", "mmarquez", "/bin/bash", "/home/mmarquez/script.sh", NULL };
    static char *envp[] = {
        "HOME=/home/mmarquez",
        "TERM=linux",
        "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
        NULL
    };
    call_usermodehelper( argv[0], argv, envp, UMH_WAIT_PROC);
    return call_usermodehelper( argv[0], argv, envp, UMH_WAIT_PROC);
}

static void change_desktop(unsigned long unused) {
    umh_test()

    timer.expires = jiffies + 10 * HZ;
    add_timer(&timer);
}

int __init init_module(void) {
    change_desktop(0);
    return 0;
}

void __exit exit_module(void) {
}

ИСценарий:

#!/bin/bash
nautilus_pid=$(pgrep -u $LOGNAME -n nautilus)
eval $(tr '\0' '\n' < /proc/$nautilus_pid/environ | grep '^DBUS_SESSION_BUS_ADDRESS=')
export DBUS_SESSION_BUS_ADDRESS
cp /home/mmarquez/Pictures/logo.png /home/mmarquez/Pictures/bg.png
gconftool-2 --set /desktop/gnome/background/picture_filename --type string /home/mmarquez/Pictures/bg.png

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

Если вместо запуска скрипта я печатаю сообщение с помощью printk (), оно работает хорошо.Если я не планирую сценарий с таймером, а вместо этого запускаю его несколько раз в блоке, он работает отлично.Но он также зависает, если я запускаю / bin / true вместо / usr / bin / sudo.Замена статической структуры на нестатическую оставляет ту же проблему.

Я использую GNOME 2 и ядро ​​2.6.32.37

1 Ответ

4 голосов
/ 14 января 2012

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

  • Он связывает код ядра с политическими решениями, такими как расположение различных двоичных файлов и параметры, которые они принимают.

  • Нарушает многоуровневую структуру системы.В целом, ядро ​​должно обслуживать вызовы из пользовательского пространства, а не наоборот.

  • Это может привести к неожиданным сбоям, если пользовательское пространство находится в непредвиденном состоянии.

Ядро поддерживает вызов программ пользовательского пространства, хотя, как правило, через вспомогательный API пользовательского режима .Это обычно используется для относительно низкоуровневых операций, которые требуют взаимодействия в пространстве пользователя, таких как управление питанием, или для операций, которые не могут быть разумно выполнены в пространстве ядра из-за его внутренних ограничений.Тем не менее, он используется очень редко и только после того, как все другие альтернативы были исчерпаны.

Возможно, вам следует сначала рассмотреть эти другие альтернативы:

  • Подключить демона кВаш модуль через Netlink сокет.Этот метод широко используется (например, udev ) из-за его привычного отношения к программистам пользовательского пространства.Существуют библиотеки пользовательского пространства (например, libnl ), которые значительно облегчают создание программ, использующих этот подход.

  • Проведите опрос демонов a sysfs *Файл 1036 *, созданный и обновленный вашим модулем.

  • Демон имеет связь с вашим модулем через новый узел устройства.

  • Ваш модульотправляйте дымовые сигналы, зажигая ваш процессор - просто пожалуйста не вызывайте программы пользовательского пространства напрямую, если у вас нет другого выбора.

Существует инструкции , описывающие наиболее распространенные методы взаимодействия между ядром и пользовательским пространством.

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

РЕДАКТИРОВАТЬ:

Кстати, call_usermodehelper() предполагается вызывать из контекста процесса.Вызов его из таймера не отвечает этому требованию - ваш код в основном выполняется в контексте прерывания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...