本系列文章闡釋AIX中對象數據庫管理器(Object Database Manager)的結構,操作 ODM 數據庫的命令,工具,以及 ODM 的一些實際應用舉例。第 2 部分向您詳細介紹 ODM 的命令以及一些關于 ODM 的實際應用中的例子,即帶您實踐在本系列文章的第 1 部分中學習到的所有關于 ODM 的知識。要了解關于ODM的詳細信息,請閱讀本系列文章的第 1 部分:ODM的基本組件,ODM負責的數據,ODM數據庫文件和ODM數據庫的對象類
ODM數據庫中存放著系統中的重要信息,在系統出現故障時,如果對ODM數據庫進行直接的維護,則有利于問題的解決,也方便查出問題出現的原因所在。在ODM數據庫可以通過手工方式進行維護,AIX提供了一些維護命令,下面介紹這些命令的作用和用法。
odmadd | 添加對象到對象類。odmadd命令使用一個ASCII碼節文件作為輸入并將在節文件中發現的ODM對象組織到ODM對象類。 |
odmchange | 改變指定的ODM對象類中指定的ODM對象。 |
odmcreate | 創建空的對象類。odmcreate命令使用描述對象類的ASCII碼文件作為輸入并產生應用訪問該對象類中的對象時使用的C語言文件(.h和.c文件)。 |
odmdelete | 從ODM對象類中刪除ODM對象。 |
odmdrop | 刪除整個ODM對象類。 |
odmget | 得到對象類的信息并將對象信息變成odmadd命令格式。 |
odmshow | 顯示ODM對象類的描述。odmshow命令使用對象名稱作為輸入并將對象信息變成odmcreate命令格式。 |
這些ODM命令顧名思義,接近關系型數據庫的DML、DDL、DCL語言,非常容易理解。
注意:ODM命令應該僅在傳統的系統維護方式如SMIT無效時才能被使用。對于一個剛入門的系統管理員,建議在使用這些命令前要多加閱讀和練習。對這些命令使用不正確可能導致系統不可用。一般ODM主要是針對有相當AIX系統管理經驗的系統管理員來使用的,主要運用于復雜的Trouble Shooting,或Problem Determination。ODM數據庫為AIX實現許多先進的功能提供了一塊重要的基石。
在使用ODM命令之前,首先檢查$ODMDIR環境變量設置是否正確(AIX默認已經設置好了此環境變量),方法如下:
# echo $ODMDIR /etc/objrepos |
如果您的系統沒有設置這個環境變量,請自行設置,方法如下:
# export ODMDIR=/etc/objrepos |
odmcreate命令以描述用戶希望在特定的應用程序中使用的對象的 ASCII 文件為輸入。產生 .c (源)和 .h(包含)文件,對于 ODM 應用程序開發和創建空的對象類是必要的。它的命令格式如下:
odmcreate [ -p ] [ -c | -h ] ClassDescriptionFile |
ClassDescriptionFile 參數指定了包含一個或多個對象類的描述的 ASCII 文件。ClassDescriptionFile 文件的缺省后綴是 .cre。 如果在 odmcreate 命令中沒有指定后綴,那么附加一個.cre 后綴。文件能夠有 C 語言注釋,如果運行時帶有 -p 標志,并能預先包含 #define 和 #include 行,這些可以被預處理的,如果在文件中使用了 -p 標志運行 C 語言預處理器。
odmcreate 命令的輸出是 .h 文件(一個包含文件),它包含了定義在 ASCII ClassDescriptionFile 文件中的對象類的 C 語言定義。結果包含文件使用在訪問存儲在 ODM 中對象的應用程序中。odmcreate 命令也產生需要編譯和綁定在應用程序中的 .c 文件。 .c 文件包含在運行時由 ODM 內部使用的結構和定義。
如果使用-c參數,只創建空的對象類;不生成 C 語言 .h 和 .c 文件。
如果使用-h參數,只生成 .c 和 .h 文件;不創建空類。
如果使用-p參數,對 ClassDescriptionFile 文件運行 C 語言預處理器。這時ClassDescriptionFile 文件中就可以包含C語言的注釋,例如可以包含#define 和 #include等關鍵字。
注意: ODM 數據庫是 32 位的數據庫。長型當在類描述文件中使用時,它是 32 位的數據項。長型 64 或整型 64 當在類描述文件中使用時,它是 64 位的數據項。生成的文件對于 32 位和 64 位應用程序具有相同功能。
odmcreate命令舉例
假定存在 ClassDescriptionFile 文件,命名為 MyObjects.cre ,下列命令創建對象類:
odmcreate MyObjects.cre
以下是 MyObjects.cre 源文件和結果 .h 文件:
/* 這是一個示例 odmcreate 輸入文件 */ * MyObjects.cre * An input file for ODM create utilities. * Creates three object classes: * Friend_Table * Enemy_Table * Fictional_Characters class Friend_Table { char Friend_of[20]; char Friend[20]; }; class Enemy_Table { char Enemy_of[20]; char Enemy[20]; }; class Fictional_Characters { char Story_Star[20]; char Birthday[20]; short Age; link Friend_Table Friend_Table Friend_of Friends_of; link Enemy_Table Enemy_Table Enemy_of Enemies_of; method Do_This; }; * End of MyObjects.cre input file for ODM create utilities. * |
按照上面文件所定義的結構創建新對象類,運行下面的命令生成頭文件 file MyObjects.h。
# odmcreate FineName.cre
* MyObjects.h * The file output from ODM processing of the MyObjects.cre input * file. Defines structures for the three object classes: * Friend_Table * Enemy_Table * Fictional_Characters #include <odmi.h> struct Friend_Table { long _id; * unique object id within object class * long _reserved; * reserved field * long _scratch; * extra field for application use * char Friend_of[20]; char Friend[20]; }; #define Friend_Table_Descs 2 extern struct Class Friend_Table_CLASS[]; #define get_Friend_Table_list(a,b,c,d,e) (struct Friend_Table * ) odm_get_list (a,b,c,d,e) struct Enemy_Table { long _id; long _reserved; long _scratch; char Enemy_of[20]; char Enemy[20]; }; #define Enemy_Table_Descs 2 extern struct Class Enemy_Table_CLASS[]; #define get_Enemy_Table_list(a,b,c,d,e) (struct Enemy_Table * ) odm_get_list (a,b,c,d,e) struct Fictional_Characters { long _id; long _reserved; long _scratch; char Story_Star[20]; char Birthday[20]; short Age; struct Friend_Table *Friends_of; * link * struct listinfo *Friends_of_info; * link * char Friends_of_Lvalue[20]; * link * struct Enemy_Table *Enemies_of; * link * struct listinfo *Enemies_of_info; * link * char Enemies_of_Lvalue[20]; * link * char Do_This[256]; * method * }; #define Fictional_Characters_Descs 6 extern struct Class Fictional_Characters_CLASS[]; #define get_Fictional_Characters_list(a,b,c,d,e) (struct Fictional_Characters * )odm_get_list (a,b,c,d,e) * End of MyObjects.h structure definition file output from ODM * processing. |
odmadd 命令以一個或多個InputFile 文件為輸入,并且添加對象到帶有節文件數據的對象類中。每個 InputFile 文件是 ASCII 文件,包含有描述要添加到對象類中的對象的數據。如果沒有指定文件,從標準輸入中獲取輸入。
下面是它的格式:
odmadd [ InputFile ... ]
要添加的類在 ASCII 輸入文件中指定。文件的常規格式如下:
class1name: descriptor1name = descriptor1value descriptor2name = descriptor2value descriptor3name = descriptor3value class2name: descriptor4name = descriptor4value .. |
輸入文件能夠包含 \ (反斜杠),它的處理和在 C 語言中一樣。輸入文件中字符串和方法的值必須用 " " (雙引號)括起來。描述符值能夠跨越多行。
odmcreate命令舉例
ASCII 輸入文件MyObjects.add由 odmadd 命令使用,如下所示:
# odmadd MyObjects.add
* MyObjects.add * An input file for ODM add utilities. * Populates three created object classes: * Friend_Table * Enemy_Table * Fictional_Characters Fictional_Characters: Story_Star = "Cinderella" #a comment for the MyObjects.add file. Birthday = "Once upon a time" Age = 19 Friends_of = "Cinderella" Enemies_of = "Cinderella" Do_This = "echo Cleans house" Fictional_Characters: Story_Star = "Snow White" Birthday = "Once upon a time" Age = 18 Friends_of = "Snow White" Enemies_of = "Snow White" Do_This = "echo Cleans house" Friend_Table: Friend_of = "Cinderella" Friend = "Fairy Godmother" Friend_Table: Friend_of = "Cinderella" Friend = "mice" Friend_Table: Friend_of = "Snow White" Friend = "Sneezy" Friend_Table: Friend_of = "Snow White" Friend = "Sleepy" Friend_Table: Friend_of = "Cinderella" Friend = "Prince" Friend_Table: Friend_of = "Snow White" Friend = "Happy" Enemy_Table: Enemy_of = "Cinderella" Enemy = "midnight" Enemy_Table: Enemy_of = "Cinderella" Enemy = "Mean Stepmother" Enemy_Table: Enemy_of = "Snow White" Enemy = "Mean Stepmother" * End of MyObjects.add input file for ODM add utilities. * |
odmget 命令以搜索規則和對象類列表為輸入,從指定的對象類中檢索選定的對象,并寫 ASCII odmadd 輸入文件到標準輸出。
下面是它的命令格式:
odmget [ -q Criteria ] ObjectClass ...
其中,-q Criteria指定用于從對象類中選擇對象的搜索標準。Criteria是一個用雙引號括起來的字符串,類似于SQL語言的查詢條件,符合條件的紀錄就會顯示出來。如果沒有指定標準(沒有 -q 標志),檢索對象類中的所有對象。
與SQL語句類似,Criteria參數指定的查詢條件可以使用關系運算符和布爾運算符,象=,!=,>,>=,<,<=,like,and等。
下面是一些使用運算符的例子:
Name like '?B?' ? 表示一個字符 Name like '*ot*' * 表示0到多個字符 Name like '[ST]*' [ST]* 表示以"S"或"T"開頭的任意多個字符串 Name like '[AD-GST]*' D-G表示范圍,可以是D、E、F、G(從D到G)中任一字符。 Name like '[!ST]*' [!ST]*表示不以"S"或"T"打頭的任意字符串 |
從PdAt對象類查找uniquetype為"tape/scsi/8mm",而且attribute為"block_size"的所有對象:
odmget命令舉例:
# odmget -q "uniquetype=tape/scsi/8mm and attribute=block_size" PdAt
bash-3.00# odmget -q "uniquetype=tape/scsi/8mm and attribute=block_size" PdAtPdAt: uniquetype = "tape/scsi/8mm" attribute = "block_size" deflt = "1024" values = "0-245760,1" width = "" type = "R" generic = "DU" rep = "nr" nls_index = 6 |
odmdelete命令給定了要從中刪除的對象類和搜索規則后,odmdelete 命令刪除所有滿足那些標準的對象。
下面是它的命令格式:
odmdelete -o ObjectClass [ -q Criteria ] |
其中,-o ObjectClass指定要從中刪除的對象類。-q標準指定用于從對象類中選擇對象的標準。 如果沒有指定標準(沒有 -q 標志),刪除所有對象。
odmdelete命令舉例:
從PdAt對象類中刪除uniquetype為"tape/scsi/8mm",而且attribute為"block_size"的所有對象:
# odmdelete -o PdAt -q "uniquetype=tape/scsi/8mm and attribute=block_size" |
如果給定了修改的對象類、搜索規則和新對象(僅對需要更改的屬性),odmchange 命令將修改所有滿足搜索規則的對象。InputFile 文件和用于 odmadd 命令的 InputFile 文件(ASCII 輸入文件)有同樣的格式。
odmchange -o ObjectClass [ -q Criteria] [ InputFile] |
其中-o ObjectClass和-q Criteria參數同上。如果不指定-q Criteria參數,則修改指定對象類中所有對象。
odmshow 命令以對象類名稱(ObjectClass)為輸入并在屏幕上顯示類描述。 類描述的格式采用 odmcreate 命令的輸入格式。
odmshow ObjectClass |
odmshow命令舉例:
例如顯示CuDv對象類的結構:
# odmshow CuDv
bash-3.00# odmshow CuDv class CuDv { char name[16]; /* offset: 0xc ( 12) */ short status; /* offset: 0x1c ( 28) */ short chgstatus; /* offset: 0x1e ( 30) */ char ddins[16]; /* offset: 0x20 ( 32) */ char location[16]; /* offset: 0x30 ( 48) */ char parent[16]; /* offset: 0x40 ( 64) */ char connwhere[16]; /* offset: 0x50 ( 80) */ link PdDv PdDv uniquetype PdDvLn[48]; /* offset: 0x60 ( 96) */ }; /* descriptors: 8 structure size: 0x98 (152) bytes data offset: 0x200030e8 population: 71 objects (71 active, 0 deleted) */ |
odmdrop 命令除去整個對象類和它所有的對象。其它對象類是否鏈接了本對象類,不用進行檢查。
它的命令格式如下:
odmdrop -o ClassName |
odmdrop命令舉例:
假定存在一個名字為 MyObjectClass 的對象類,下列命令除去對象類:odmdrop -o MyObjectClass
![]() ![]() |
![]()
|
下面描述一些不同的ODM使用的例子。
ODM維護一個您的系統安裝的所有軟件的詳細目錄。
例如,一個名為lpp的類包含當前安裝的軟件產品的信息,像軟件ID、名稱、版本和發行版本。我們可以使用命令odmget來查詢lpp ODM類關于系統安裝的所有軟件的信息并指定只輸出前30行,如下所示:
# odmget lpp|head -40
bash-3.00# odmget lpp|head -40 lpp: name = "__SWVPD_CTL__" size = 0 state = 0 cp_flag = 0 group = "" magic_letter = "" ver = 0 rel = 0 mod = 0 fix = 0 description = "" lpp_id = 230 lpp: name = "bos.rte" size = 0 state = 5 cp_flag = 262419 group = "" magic_letter = "I" ver = 5 rel = 3 mod = 0 fix = 0 description = "Base Operating System Runtime" lpp_id = 1 lpp: name = "bos.rte.Dt" size = 0 state = 5 cp_flag = 262419 group = "" magic_letter = "I" ver = 5 rel = 3 mod = 0 fix = 0 |
ODM保存所有設備配置所必須的數據。例如,名為預定義設備(PdDv)的類包括AIX 5L支持的所有設備的條目。在這個類中重要的屬性包括類型,子類,綴,基礎,可檢測性,led,steno,編目,DvDr,定義,配置,改變,未配置,未定義,啟動,停止和唯一類型。我們可以使用命令odmget來查詢在ODM PdDv類中類型以lv開頭的所有對象如下所示:
bash-3.00# odmget -q "type LIKE lv*" PdDv
bash-3.00# odmget -q "type LIKE lv*" PdDv PdDv: type = "lvtype" class = "logical_volume" subclass = "lvsubclass" prefix = "lv" devid = "" base = 1 has_vpd = 0 detectable = 0 chgstatus = 0 bus_ext = 0 fru = 0 led = 0 setno = 1 msgno = 699 catalog = "cmdlvm.cat" DvDr = "" Define = "" Configure = "" Change = "" Unconfigure = "" Undefine = "" Start = "" Stop = "" inventory_only = 0 uniquetype = "logical_volume/lvsubclass/lvtype" PdDv: type = "lvdd" class = "lvm" subclass = "lvm" prefix = "" devid = "" base = 1 has_vpd = 0 detectable = 0 chgstatus = 1 bus_ext = 0 fru = 0 led = 1425 setno = 1 msgno = 52 catalog = "devices.cat" DvDr = "hd_pin" Define = "/usr/lib/methods/deflvm" Configure = "/usr/lib/methods/cfglvdd" Change = "" Unconfigure = "" Undefine = "" Start = "" Stop = "" inventory_only = 0 uniquetype = "lvm/lvm/lvdd" PdDv: type = "lv" class = "virtual_target" subclass = "vtdev" prefix = "vtscsi" devid = "" base = 0 has_vpd = 0 detectable = 0 chgstatus = 0 bus_ext = 0 fru = 0 led = 9656 setno = 1 msgno = 1 catalog = "vtdev.cat" DvDr = "" Define = "/usr/lib/methods/define -g -d" Configure = "/usr/lib/methods/cfg_vt_lvm" Change = "" Unconfigure = "/usr/lib/methods/ucfg_vtdev" Undefine = "/usr/lib/methods/undefine" Start = "" Stop = "" inventory_only = 0 uniquetype = "virtual_target/vtdev/lv" |
ODM同樣維護一個LVM使用的所有數據的拷貝。對LVM有影響的命令被設計為硬盤上的VGDA數據總是和ODM中保存的信息同步。例如,名為CuAt的ODM類包含自定義的指定設備的屬性信息。我們可以使用命令odmget來查詢CuAt ODM類中關于hdsik0的所有屬性信息如下所示:
# odmget -q name=hdisk0 CuAt
bash-3.00# odmget -q name=hdisk0 CuAt CuAt: name = "hdisk0" attribute = "unique_id" value = "2708E6WZGWBC10IC35L073UCDY10-003IBMscsi" type = "R" generic = "" rep = "nl" nls_index = 79 CuAt: name = "hdisk0" attribute = "pvid" value = "0059041d3be9d3090000000000000000" type = "R" generic = "D" rep = "s" nls_index = 2 CuAt: name = "hdisk0" attribute = "size_in_mb" value = "73400" type = "R" generic = "D" rep = "nr" nls_index = 60 CuAt: name = "hdisk0" attribute = "led" value = "0x57D" type = "Z" generic = "" rep = "nr" nls_index = 0 CuAt: name = "hdisk0" attribute = "message_no" value = "87" type = "T" generic = "" rep = "nl" nls_index = 0 CuAt: name = "hdisk0" attribute = "diag_scsd" value = "a500000107000507000c0b" type = "R" generic = "" rep = "s" nls_index = 0 |
名為history的類包含所有軟件產品的安裝和更新的相關信息。我們可以使用命令odmget來查詢history ODM類關于系統安裝的lpp_id=100的軟件的安裝和更新信息如下所示:
# odmget history|grep -p "lpp_id = 100"
bash-3.00# odmget history|grep -p "lpp_id = 100" history: lpp_id = 100 event = 1 ver = 5 rel = 3 mod = 0 fix = 0 ptf = "" corr_svn = "" cp_mod = "" cp_fix = "" login_name = "root" state = 1 time = 1102919663 comment = "" history: lpp_id = 100 event = 1 ver = 5 rel = 3 mod = 0 fix = 30 ptf = "" corr_svn = "" cp_mod = "" cp_fix = "" login_name = "root" state = 1 time = 1129166921 comment = "" history: lpp_id = 100 event = 2 ver = 5 rel = 3 mod = 0 fix = 30 ptf = "" corr_svn = "" cp_mod = "" cp_fix = "" login_name = "root" state = 1 time = 1129167257 comment = "" |
當用戶添加一個新設備時,如果AIX系統的ODM數據庫不支持該新設備,則可以向PdDv,PdAt和PdCn對象類中添加這個新設備對象。
首先,用odmget命令從PdDv,PdAt 和PdCn對象類中復制一份已存在設備的紀,并分別保存在臨時文件中。
然后,用Vi分別編輯上一步生成的臨時文件,按照新設備說明書中所列示的屬性參數修改每個字段的值,并確保該設備在PdDv對象類中的配置是正確的。
再用odmadd命令從編輯好的臨時文件中向PdDv,PdAt 和PdCn對象類添加新設備對象。
最后,安裝新設備的驅動程序,確保系統中有合適的設備驅動程序。如果系統引導時需要該設備,則創建一個新的引導邏輯卷。
用odmchange命令修改磁帶機rmt0的屬性block_size的值
要修改某個設備的屬性值,可以使用chdev命令來完成,也可通過直接修改ODM中的內容來實現。
1.從ODM數據庫的CuAt對象類中取出SCSI接口的8mm磁帶機rmt0的block_size屬性,存入tapeattr文件中。
odmget -q "name=rmt0 and attribute=block_size" PdAt >tapeattr |
2.vi tapeattr (用vi修改tapeattr文件中的attribute屬性的值為512,并保存修改結果并退出vi)
PdAt: uniquetype = "tape/scsi/8mm" attribute = "block_size" deflt = "1024" values = "0-245760,1" width = "" type = "R" generic = "DU" rep = "nr" nls_index = 6 |
3.執行odmchange命令,用tapeattr文件的內容來修改磁帶機的屬性值。
# odmchange -o CuAt -q "name=rmt0 and attribute=block_size" tapeattr |
用odmdelete,odmadd命令把磁帶機上的block_size屬性值從1024改為512。
1.odmget -q "name=rmt0 and attribute=block_size" PdAt >tapeattr
2.vi tapeattr (用vi修改tapeattr文件并保存修改結果并退出vi)
PdAt: uniquetype = "tape/scsi/8mm" attribute = "block_size" deflt = "1024" values = "0-245760,1" width = "" type = "R" generic = "DU" rep = "nr" nls_index = 6 |
3.將rmt0設備的block_size 屬性從ODM數據庫CuAt對象類中刪除。
odmdelete -o CuAt -q "name=rmt0 and attribute=block_size" |
4.按照修改后的tapeattr文件內容創建新的對象。
odmadd tapeattr |
![]() ![]() |
![]()
|
手工刪除smit菜單的步驟如下:
1.export ODMDIR=/usr/lib/objrepos
2.rm $HOME/smit.log
3.smit -D
并執行想刪除的一些菜單命令,查看smit.log中id的值
4.odmget -q id=*** sm_menu_opt >/tmp/smit
5.odmdelete -q id=*** -o sm_menu_opt
6.vi /tmp/smit
7.odmadd /tmp/smi
![]() ![]() |
![]()
|
當您的硬盤處于無序狀態時,如為 hdisk0, hdisk2, hdisk3 而不是hdisk0, hdisk1, hdisk2,可以用以下的腳本來改正。
lsdev -Cc disk | awk '{ print $1 }' | while read HDname; do odmdelete -q "name = $HDname" -o CuAt odmdelete -q "value = $HDname" -o CuAt odmdelete -q "name = $HDname" -o CuDv odmdelete -q "value3 = $HDname" -o CuDvDr odmdelete -q "name = $HDname" -o CuVPD done rm -f /dev/hdisk* rm -f /dev/rhdisk* savebase |
執行完后,用以下命令重啟機器,之后硬盤順序將變為有序狀態:
shutdown -Fr |
![]() ![]() |
![]()
|
在/usr/lib/objrepos下,與SMIT相關的文件有:sm_cmd_hdr, sm_cmd_hdr.vc, sm_cmd_opt, sm_cmd_opt.vc, sm_menu_opt, sm_menu_opt.vc, sm_name_hdr, sm_name_hdr.vc. 如果您的SMIT由于某種原因不能用了,比如說由于在/usr/lib/objrepos下的與SMIT相關的文件不慎刪除或者損壞,這個時候smit是不能用了,即使您從別處拷來這些文件,一樣不可用,您只有重建smit class了。
恢復步驟:
1)建立smit空對象類
安裝bos.adt.samples包后,在/usr/samples/smit下可以找到smit_class.cre類描述文件。然后建立smit空對象類。
#odmcreate smit_class.cre sm_cmd_opt sm_cmd_hdr sm_menu_opt sm_name_hdr |
2)從其他主機提取smit對象
#odmget sm_cmd_hdr >sm_cmd_hdr.add #odmget sm_cmd_opt >sm_cmd_opt.add #odmget sm_menu_opt >sm_menu_opt.add #odmget sm_name_hdr >sm_name_hdr.add |
3)將第2步提取的四個文件ftp到您想要恢復的主機上
4)將提取的對象添加到第1步產生的對象類中
#odmadd sm_cmd_hdr.add #odmadd sm_cmd_opt.add #odmadd sm_menu_opt.add #odmadd sm_name_hdr.add |
![]() ![]() |
![]()
|
擁有較好 ODM 知識對于理解您的系統作用和分析問題以及故障排除都是很重要的,然而,您應該知道當使用通常的命令行命令管理系統時,改變 ODM 數據的內容是不可能的,這時您得使用 ODM 命令,這里不管是使用 SMIT 還是命令行,它們都能夠保持 ODM 和系統狀態在任何時候都同步,它是如此完美以至于您可能永遠不必使用 ODM 命令。錯誤的使用 ODM 命令會造成系統不可用,因此使用 ODM 命令時您一定要明白您在干什么。即便如此,您還是應該知道這些命令的存在并對它們有一定的了解。
文章來源于領測軟件測試網 http://www.kjueaiud.com/