搜尋
首頁系統教程LinuxLinux設備模型(3)_Uevent

Linux設備模型(3)_Uevent

Feb 11, 2024 pm 01:06 PM
linuxlinux教程linux系統linux指令shell腳本overflow嵌入式linuxlinux入門linux學習

1. Uevent的功能

Uevent是Kobject的一部分,用於在Kobject狀態改變時(例如增加、移除等),通知使用者空間程式。使用者空間程式在接收這樣的事件後,會做出相對應的處理。

通常情況下,此機制用於支援熱插拔設備。例如,插入U碟後,與USB相關的驅動程式會動態地建立用於表示該U碟的device結構(其中包括對應的kobject),並告知使用者空間程式。這將使得設備節點能夠動態地被建立在/dev/目錄下。更進一步地,該機制還可以通知其它的應用程序,將該U盤設備掛載到系統中,從而實現對該設備的動態支援。

2. Uevent在kernel中的位置

#下面圖片描述了Uevent模組在核心中的位置:

Linux設備模型(3)_Uevent

由此可知,Uevent的機制是比較簡單的,設備模型中任何設備有事件需要回報時,會觸發Uevent提供的介面。 Uevent模組準備好上報事件的格式後,可以透過兩個途徑把事件上報到用戶空間:一種是透過kmod模組,直接呼叫用戶空間的可執行檔;另一種是透過netlink通訊機制,將事件從核心空間傳遞給使用者空間。

註1:有關kmod和netlink,會在其它文章中描述,因此本文就不再詳細說明了。

3. Uevent的內部邏輯解析

3.1 Source Code位置

Uevent的程式碼比較簡單,主要涉及kobject.h和kobject_uevent.c兩個文件,如下:

  • include/linux/kobject.h
  • lib/kobject_uevent.c
3.2 資料結構描述

#kobject.h定義了uevent相關的常數和資料結構,如下:

  • kobject_action
 1: /* include/linux/kobject.h, line 50 */
 2: enum kobject_action {   
 3:     KOBJ_ADD,
 4:     KOBJ_REMOVE,    
 5:     KOBJ_CHANGE, 
 6:     KOBJ_MOVE,
 7:     KOBJ_ONLINE, 
 8:     KOBJ_OFFLINE,
 9:     KOBJ_MAX 
 10: };

kobject_action定義了event的類型,包括:

#ADD/REMOVE,Kobject(或上層資料結構)的新增/移除事件。

ONLINE/OFFLINE,Kobject(或上層資料結構)的上線/下線事件,其實是是否啟用。

CHANGE,Kobject(或上層資料結構)的狀態或內容改變。

MOVE,Kobject(或上層資料結構)更改名稱或更改Parent(意味著在sysfs中更改了目錄結構)。

CHANGE,如果裝置驅動需要回報的事件不再上面事件的範圍內,或者是自訂的事件,可以使用該event,並攜帶對應的參數。

  • # kobj_uevent_env
#
 1: /* include/linux/kobject.h, line 31 */
 2: #define UEVENT_NUM_ENVP         32 /* number of env pointers */
 3: #define UEVENT_BUFFER_SIZE      2048 /* buffer for the variables */
 4:  
 5: /* include/linux/kobject.h, line 116 */
 6: struct kobj_uevent_env {
 7:     char *envp[UEVENT_NUM_ENVP];
 8:     int envp_idx;
 9:     char buf[UEVENT_BUFFER_SIZE];
 10:    int buflen;
 11: };

前面有提到過,在利用Kmod向用戶空間回報event事件時,會直接執行用戶空間的執行檔。而在Linux系統,可執行檔的執行,依賴環境變量,因此kobj_uevent_env用於組織此事件上報時的環境變數。

#

envp,指针数组,用于保存每个环境变量的地址,最多可支持的环境变量数量为UEVENT_NUM_ENVP。

envp_idx,用于访问环境变量指针数组的index。

buf,保存环境变量的buffer,最大为UEVENT_BUFFER_SIZE。

buflen,访问buf的变量。

  • kset_uevent_ops
 1: /* include/linux/kobject.h, line 123 */
 2: struct kset_uevent_ops {
 3:     int (* const filter)(struct kset *kset, struct kobject *kobj);
 4:     const char *(* const name)(struct kset *kset, struct kobject *kobj);
 5:     int (* const uevent)(struct kset *kset, struct kobject *kobj,
 6:                         struct kobj_uevent_env *env);
 7: };

kset_uevent_ops是为kset量身订做的一个数据结构,里面包含filter和uevent两个回调函数,用处如下:

filter,当任何Kobject需要上报uevent时,它所属的kset可以通过该接口过滤,阻止不希望上报的event,从而达到从整体上管理的目的。

name,该接口可以返回kset的名称。如果一个kset没有合法的名称,则其下的所有Kobject将不允许上报uvent

uevent,当任何Kobject需要上报uevent时,它所属的kset可以通过该接口统一为这些event添加环境变量。因为很多时候上报uevent时的环境变量都是相同的,因此可以由kset统一处理,就不需要让每个Kobject独自添加了。

3.3 内部动作

通过kobject.h,uevent模块提供了如下的API(这些API的实现是在”lib/kobject_uevent.c”文件中):

 1: /* include/linux/kobject.h, line 206 */
 2: int kobject_uevent(struct kobject *kobj, enum kobject_action action);
 3: int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
 4:                         char *envp[]);
 5:  
 6: __printf(2, 3)
 7: int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
 8:  
 9: int kobject_action_type(const char *buf, size_t count,
 10:                         enum kobject_action *type);

kobject_uevent_env,以envp为环境变量,上报一个指定action的uevent。环境变量的作用是为执行用户空间程序指定运行环境。具体动作如下:

  • 找出kobj本身或其parent是否從屬於某個kset,如果不是,則報錯返回(註2:由此可以說明,如果一個kobject沒有加入kset,是不允許上報uevent的)
  • # 查看kobj->uevent_suppress是否設置,如果設置,則忽略所有的uevent上報並返回(註3:由此可知,可以透過Kobject的uevent_suppress標誌,管控Kobject的uevent的回報)
  • # 如果所屬的kset有uevent_ops->filter函數,則呼叫該函數,過濾此次上報(註4:這佐證了3.2小節有關filter接口的說明,kset可以透過filter接口過濾不希望上報的event,從而達到整體的管理效果)
  • 判斷所屬的kset是否有合法的名稱(稱為subsystem,和前期的核心版本有區別),否則不允許上報uevent
  • 分配一個用於此回報的、儲存環境變數的buffer(結果保存在env指標中),並取得該Kobject在sysfs中路徑資訊(用戶空間軟體需要依據該路徑資訊在sysfs中存取它)
  • 呼叫add_uevent_var介面(下面會介紹),將Action、路徑資訊、subsystem等信息,加入env指標中
  • 如果傳入的envp不空,則解析傳入的環境變數中,同樣呼叫add_uevent_var接口,加入env指標中
  • # 如果所屬的kset存在uevent_ops->uevent接口,呼叫該接口,新增kset統一的環境變數到env指標
  • 根據ACTION的類型,設定kobj->state_add_uevent_sent和kobj->state_remove_uevent_sent變量,以記錄正確的狀態
  • 呼叫add_uevent_var接口,新增格式為”SEQNUM=%llu”的序號
  • # 如果定義了”CONFIG_NET”,則使用netlink傳送該uevent
  • # 以uevent_helper、subsystem以及新增了標準環境變數(HOME=/,PATH=/sbin:/bin:/usr/sbin:/usr/bin)的env指標為參數,呼叫kmod模組提供的call_usermodehelper函數,上報uevent。
    其中uevent_helper的內容是由核心配置項目CONFIG_UEVENT_HELPER_PATH(位於./drivers/base/Kconfig)決定的(可參考lib/kobject_uevent.c, line 32),該配置項目指定了一個使用者空間程式(或腳本),用於解析上報的uevent,例如”/sbin/hotplug”。
    call_usermodehelper的作用,就是fork一個行程,以uevent為參數,執行uevent_helper。

kobject_uevent,和kobject_uevent_env功能一樣,只是沒有指定任何的環境變數。

add_uevent_var,以格式化字元的形式(類似printf、printk等),將環境變數copy到env指標中。

kobject_action_type,將enum kobject_action類型的Action,轉換為字串。

#說明:怎麼指定處理uevent的使用者空間程式(簡稱uevent helper)?

上面介紹kobject_uevent_env的內部動作時,有提到,Uevent模組透過Kmod上報Uevent時,會透過call_usermodehelper函數,呼叫使用者空間的可執行檔(或腳本,簡稱\**uevent helper\* * )處理該event。而該uevent helper的路徑則保存在\**uevent_helper陣列中。

可以在編譯核心時,透過CONFIG_UEVENT_HELPER_PATH配置項,靜態指定uevent helper。但這種方式會為每個event fork一個進程,隨著核心支援的裝置數量的增多,這種方式在系統啟動時將會是致命的(可以導致記憶體溢出等)。因此只有在早期的核心版本中會使用這種方式,現在核心不再建議使用該方式。因此核心編譯時,需要把該配置項留空。

在系統啟動後,大部分的裝置已經ready,可以依需要,重新指定一個uevent helper,以便偵測系統運作過程中的熱拔插事件。這可以透過把helper的路徑寫入到"/sys/kernel/uevent_helper」檔案中實現。實際上,核心透過sysfs檔案系統的形式,將uevent_helper數組開放到用戶空間,供用戶空間程式修改訪問,具體可參考"\*\*\*\*./kernel/ksysfs.c」中對應的程式碼,這裡不再詳細描述。

以上是Linux設備模型(3)_Uevent的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:良许Linux教程网。如有侵權,請聯絡admin@php.cn刪除
Linux與Windows的典型用例是什麼?Linux與Windows的典型用例是什麼?May 03, 2025 am 12:01 AM

LinuxIsideAlforCustomization,開發和ServerManagement,WhileWindowSexcelSineAsofuse,SoftWareCompatibility andgaming.linuxoffershighighighighignfigurabilityfordefordeerserersandserserservervevendingservervevelicersandervervevelopservervevelopservervevelopsetups,whereaswindowspprovidesaprovidesauser-frovideslyinlyintellyintlyintellyinterfrignlyInterFaroffacorDofroardOaforportort

Linux和Windows之間的用戶帳戶管理有什麼區別?Linux和Windows之間的用戶帳戶管理有什麼區別?May 02, 2025 am 12:02 AM

Linux和Windows在用戶賬戶管理上的主要區別在於權限模型和管理工具。 Linux使用基於Unix的權限模型和命令行工具(如useradd、usermod、userdel),而Windows採用自己的安全模型和圖形用戶界面(GUI)管理工具。

Linux的命令行環境如何使其比Windows更安全?Linux的命令行環境如何使其比Windows更安全?May 01, 2025 am 12:03 AM

Linux'scommandlinecanbemoresecurethanWindowsifmanagedcorrectly,butrequiresmoreuserknowledge.1)Linux'sopen-sourcenatureallowsforquicksecurityupdates.2)Misconfigurationcanleadtovulnerabilities.Windows'commandlineismorecontrolledbutlesscustomizable,with

如何在Linux中自動製作USB驅動器安裝如何在Linux中自動製作USB驅動器安裝Apr 30, 2025 am 10:04 AM

本指南說明瞭如何在Linux的啟動下自動安裝USB驅動器,從而節省了時間和精力。 步驟1:確定您的USB驅動器 使用LSBLK命令列出所有塊設備。 您的USB驅動器可能會標記為 /dev /sdb1, /dev /sdc1等

2025年,最佳Linux,Windows和Mac的最佳跨平台應用程序2025年,最佳Linux,Windows和Mac的最佳跨平台應用程序Apr 30, 2025 am 09:57 AM

跨平台應用程序已徹底改變了軟件開發,從而在Linux,Windows和MacOS等操作系統上實現了無縫功能。 這消除了根據您的設備切換應用程序的需求,提供一致的體驗

2025年AI和機器學習的最佳Linux工具2025年AI和機器學習的最佳Linux工具Apr 30, 2025 am 09:44 AM

人工智能(AI)正在迅速改變許多部門,從醫療保健和金融到藝術和音樂等創意領域。 Linux具有開源性,適應性和性能功能,已成為首要的Platfo

5最佳輕巧的Linux發行版,不帶GUI5最佳輕巧的Linux發行版,不帶GUIApr 30, 2025 am 09:38 AM

尋找沒有圖形用戶界面(GUI)的快速,最小和高效的Linux分佈? 輕巧,無GUI-Linux發行版非常適合較舊的硬件或服務器和嵌入式系統(例如服務器和嵌入式系統)。他們消耗較少的res

如何在Redhat發行中安裝葡萄酒10.0如何在Redhat發行中安裝葡萄酒10.0Apr 30, 2025 am 09:32 AM

Wine 10.0穩定版發布:在Linux上運行Windows應用更上一層樓 Wine,這款開源免費的應用程序,讓Linux用戶能夠在Unix/Linux類操作系統上運行Windows軟件和遊戲,迎來了10.0穩定版的發布!此版本已提供源代碼和二進制包下載,支持Linux、Windows和Mac等多種發行版。 這一版本凝聚了一年的辛勤工作和超過8600項改進,帶來了諸多令人興奮的提升。主要亮點包括: 增強對藍牙設備的支持。 提升對HID輸入設備的支持。 優化了32位和64位應用程序的運行性能。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具