2012-01-14 62 views
2

我試圖從內核模塊設置背景,但我無法使它工作。從內核模塊更改gnome背景

我已經得到的是:

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

+5

你爲什麼使用內核模塊來做到這一點? – Dave 2012-01-14 04:57:40

+3

不要這樣做。因爲內核可以運行而不需要任何桌面運行。如果絕對必要,請更改桌面啓動腳本以查詢有關您的模塊的內核,然後更改背景。 – 2012-01-14 08:10:05

+0

@Dave這是一個同事的惡作劇。讓我們說這是一個詳細的。 – Juan 2012-01-15 08:31:47

回答

4

具有一般應避免內核調用用戶空間程序:

  • 即擠佔內核代碼的決策,如各種二進制文件的位置以及它們所採用的選項。

  • 它違反了系統的分層結構。通常,內核應該從用戶空間提供呼叫,而不是相反。

  • 如果用戶空間處於不可預見的狀態,它會以意想不到的方式破壞。

儘管 - 一般通過user-mode helper API,內核確實支持調用用戶空間程序。這通常用於需要用戶空間協作(如電源管理)的相對較低級別的操作,或者由於其內在限制而無法在內核空間中合理執行的操作。也就是說,它很少使用,只有在所有其他替代方法都用完之後才能使用。

你或許應該首先考慮這些替代品:

  • 有一個守護進程通過Netlink套接字連接到您的模塊。由於其對用戶空間程序員的熟悉,該方法被廣泛使用(例如,udev)。有用戶空間庫(例如libnl)可以顯着促進創建使用此方法的程序。

  • 讓守護進程輪詢一個由您的模塊創建和更新的sysfs文件。

  • 讓守護進程通過新的設備節點與您的模塊進行通信。

  • 讓模塊通過點燃CPU來發送煙霧信號 - 只需不要直接調用用戶空間程序,除非您沒有其他選擇。

有一個how-to描述了內核/用戶空間通信的最常用方法。

既然你假定一個工作桌面,有一個守護進程監視你的內核模塊應該是可行的。作爲一項附加功能,您將能夠將一些代碼移動到用戶空間,其中調試工具更加廣泛,開發風險更低且更耗時。

編輯:

順便說一句,call_usermodehelper()應該從進程上下文調用。從定時器調用它並不能滿足這個要求 - 你的代碼基本上運行在中斷環境中。

+0

+1,不能解決我的問題,但幫助我理解許多事情 – 2012-01-15 21:47:29