歡迎您光臨本站 註冊首頁

Linux的kobject和Windows的GUID

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

一.數據結構設計
0.需要被管理的實體實際上很雜,包括設備,驅動,匯流排,類型,塊設備,電源等等...迫切需要統一管理.
1.kobject代表每一個被管理實體,很顯然的,這些實體可以帶有一個或者多個屬性.
2.這些屬性由attribute表示,由於被管理的實體不同,可能還會互相嵌套,因此很難給出一個明確的attribute的定義,因此使用了list_head的設計方式,將它僅僅作為一個錨點,真實的數據存在於它附近的內存區域,通過container_of宏來得到.(之可以這麼做,得益於馮諾依曼機器的連續存儲)
3.另外,由於kobject也是一個錨點,並不攜帶真實數據,因此kobject和attribute之間也不便直接建立關係,而是通過kobj_type結構體解除耦合的.
4.為了將被管理實體歸類,設計了kset數據結構,管理一類kobject
5.kset同時也是一個kobject,這就實現了一個組合模式.kobject的精化最終在這裡體現.
二.用什麼方式表現
1.由於kobject將所有被管理實體組織成一個樹型結構,因此任意可以表示樹型結構的方式都可以採用.
2.linux並不像windows導出很多操作介面(比如註冊表,文件等),它基本只導出文件介面,也就是一個vfs介面,同時linux的文件系統組織是樹型的,且實現了mount擴展機制,將不同類型的文件系統子樹嫁接在根的任意子節點(需要是目錄)上.
3.很方便為kobject實現一個文件系統,然後mount到某一處.
4.這個文件系統類型就是sysfs,一般處於/目錄下的/sysfs目錄中.
三.實現


1.kobject的定義:
struct kobject {
const char *name; //名稱
struct list_head entry; //
struct kobject *parent; //kobject組成鏈表,便於查找
struct kset *kset; //此kobj所屬的kset
struct kobj_type *ktype; //kobj_type解耦了kobj和attr
struct sysfs_dirent *sd; //sysfs中的組織結構
struct kref kref; //引用計數
...
};
2.kobj_type的定義:
struct kobj_type {
void (*release)(struct kobject *kobj);
struct sysfs_ops *sysfs_ops; //該kobj_type所屬的kobject的所有attribute的總的store和show方法
struct attribute **default_attrs; //此type的屬性們
};
3.kset的定義:
struct kset {
struct list_head list; //屬於此kset的kobj們
...
struct kobject kobj; //kset本身也是一個kobject,實現一個類別
struct kset_uevent_ops *uevent_ops; //實現向用戶態的通知機制
};
4.真實attribute的定義:
struct edac_pci_dev_attribute {
struct attribute attr; //所屬的attribute結構錨點
void *value; //真實的,單獨的attribute的值
ssize_t(*show) (void *, char *); //真實的,單獨的attribute的show
ssize_t(*store) (void *, const char *, size_t);//真實的,單獨的attribute的store
};
5.每一個kobject在sysfs中都實現為一個目錄,kobject是樹型的,該樹和sysfs中的目錄樹真切地對應.
6.一個kobject的每一個attribute在sysfs中都實現為該kobject對應目錄下的一個文件,所有的attribute統一由該kobject的kobj_type管理.
7.sysfs文件系統中每一個文件代表它所屬目錄的kobject的一個屬性,擁有讀/寫方法,即show/store.


8.所有處於同一目錄下的attribute的show/store統一由該目錄所屬kobject的kobj_type的show/store來分發,比如對於/sys/devices目錄:
8.1.在註冊一個頂層設備(比如匯流排等)時,均會將該device結構體的kobj的ktype初始化為device_ktype:
static struct kobj_type device_ktype = {
.release = device_release,
.sysfs_ops = &dev_sysfs_ops,
};
8.2.所有的8.1中註冊的device的屬性讀寫操作(show/store)全部通過以下的dev_sysfs_ops代理:
static struct sysfs_ops dev_sysfs_ops = {
.show = dev_attr_show,
.store = dev_attr_store,
};
static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct device_attribute *dev_attr = to_dev_attr(attr);
struct device *dev = to_dev(kobj);
ret = dev_attr->show(dev, dev_attr, buf);
}
8.3.對於每一個單獨的屬性,要單獨定義,比如對於devt屬性:
static struct device_attribute devt_attr =
__ATTR(dev, S_IRUGO, show_dev, NULL);
定義完之後,通過device_create_file加入sysfs文件系統:
device_create_file(dev, &devt_attr);
8.4.當dev_attr_show中調用dev_attr->show時,執行流被路由到show_dev函數:
static ssize_t show_dev(struct device *dev, struct device_attribute *attr, char *buf)
{
return print_dev_t(buf, dev->devt);
}
9.每一個kobject代表一個目錄,其sd欄位將kobject樹轉換成了sysfs文件系統的文件目錄樹.注意,sysfs使用dentry中的d_fsdata欄位和kobject解除了耦合,所有的操作只有在介面層面上操作dentry和inode,進入后就會通過dentry的d_fsdata欄位和inode的i_private欄位轉換為kobject機制的結構,比如sysfs_dirent結構.
四.和Windows管理方式的對比


1.windows使用GUID來管理設備,驅動,匯流排,類型,塊設備,電源等等...它本身就很統一.
2.windows使用註冊表來管理這些,例如HKEY_LOCAL_MACHINESYSTEMControlSet001ControlClass鍵下面保存有各種類型的被管理實體,對應於linux的sysfs的根目錄.
3.GUID是個無結構的大數,通過複雜的演算法生成,只求唯一性,GUID之間沒有關聯性,耦合性更低.kobject恰恰相反,它在本機範圍內構建了一個樹型的被管理實體結構.
4.sysfs便於查找,而GUID某種意義上只能遍歷,消耗很大,這就是註冊表隨著時間增加會拖慢系統速度的原因之一.
5.GUID方式的管理也支持屬性,並且節點也可以包含到其它節點的鏈接,這點和sysfs很相似.
6.微軟希望使用GUID來管理所有它能管理的實體,甚至包括office文檔,然而這被證明不是一個好主意,雖然一個大數耦合性很低,內聚性很強,然而內聚性過強也會導致不能和外界通信.
7.總之,GUID的方式沒有做到恰到好處.
五.總結
1.Linux使用kobject-一個組合模式的數據結構.
2.Windows使用GUID-一個無耦合全內聚的數字.
3.處處都存在設計模式.
3.1.面向對象的思想(OO)在kobject的設計中表現的很淋漓,具體就在kobj_type,雖然使用了type這個詞,但實際上就是class,一個kobject的具體attitude就是一個kobj_type這個class的一個實例,由於kobject是表徵凌亂不堪的實體的,因此kobject肯定區分了不同的類型,每一種類型的“操作attitude的方式(方法)”肯定相同,因此出現了kobj_type這個數據結構來解除分類的kobject與無類別的attitude之間的耦合.
3.2.錨點的設計方式其實在我們日常生活中也很普遍,比如身份證就代表某個人,人與人不同,然而身份證的格式是一樣的,個人就是雜亂不堪的被管理實體,身份證就是kobject


[火星人 ] Linux的kobject和Windows的GUID已經有545次圍觀

http://coctec.com/docs/linux/show-post-48772.html