Solaris Resource Manager 系統係圍繞 kernel 而建構的一個基本附件,即一種稱為 lnode 的針對使用者的結構。lnode 實際上是,可以存處和更新各類的針對使用者的,數據大小固定的位置。在密碼對映中所定義的每個唯一 UID 都應該有一個對應的 lnode。(接續的 getpwent(3C) 呼叫回傳的每一個唯一 UID。)雖然一個 lnode 可以沒有對應的密碼映射登錄,但建議您不要這麼做。lnode 會內存於磁碟之上,並且由 kernel 自動移入或移出記憶體。從磁碟中讀取後被變更的 lnode 記憶體副本,會作為定期系統同步化操作而回寫;或在 sync 指令執行時應需求回寫;或者是在必須釋放 lnode 快取記憶體的空間以讀入後續的 lnode 時回寫。
lnode 通常是一種樹狀階層的結構,中央系統管理員為樹形的頭,其他使用者為樹中較小使用者群組的群組標頭。中央管理員為系統的超級使用者或 root 使用者。
與 lnode 有關的錯誤,例如孤立行及群組迴圈,將在第 11章, 疑難排解中加以詳述。
lnode 的主要管理責任有賴於中央管理員來肩負。當 Solaris Resource Manager 設立數種用來指派與管理的資源控制時,也可以選擇性地將特定的管理權限指派給非 root 的使用者,以分散管理使用者的負擔。
管理權限可以藉由設定使用者 uselimadm 或 admin 旗標的方式來指派給適當的使用者。子管理員是 uselimadm 旗標為 set 的一個用戶,其具有與超級使用者相同的 limadm 程式管理特權。一個 admin 旗標為 set 的群組標頭使用者稱為一位群組管理員,並且擁有(如下所述)管理其排程群組內其他使用者的權限。
中央管理員可以建立與限制以 root 為雙親的排程群組來控制整體系統資源的分割。群組管理員一般實行相同種類的資源控制,但限制在它們排成群組裡的使用者。群組管理員所做的資源 分配,只限於已經被分配給群組的資源。(例如,已分給群組標頭 lnode 的資源。)注意!群組管理員可以指定一個 admin 旗標給任何群組裡的使用者,進一步往下分配管理責任。
群組管理員能做以下事項:
修改其排程群組內任何使用者的資源限制。
注意!雖然一個群組管理員可以設定給群組大於它們能有的資源限制,被群組成員消耗的資源也視同為了群組標頭而消耗,並且當企圖超過群組標頭限制時,在單獨使用者身上限制會被加強。
修改任何在其排程群組內 lnode 的所有旗標或屬性(flag.uselimadm 和 cpu.usage 除外)。
群組管理員指派旗標的工作會進一步受到限制,因而使用者便無法取得子管理員所沒有的權限。之所以採用這種限制是為了防止群組管理員繞過 Solaris Resource Manager 的安全措施。
群組管理員的主要工具是 limadm(1MSRM) 及 limreport(1SRM) 指令。limadm 程式負責執行與一或多位現有使用者的限制、旗標以及其他 Solaris Resource Manager 屬性有關的操作。此程式再加上報告生成器, limreport,這兩個工具可以自行管理排程群組,而不干擾其他不相干的排程群組的資源配置或管理。
超級使用者可以不受所有資源限制的約束,無論其旗標的設定值為何,隨時擁有最高的管理權限,可以新增、刪除與變更使用者帳號,並且能使用 limadm 程式來變更任何 lnode 的使用量、限制或旗標值。
Solaris Resource Manager 對於 Solaris 系統有非常完善的管理效果,所以必須非常小心地安裝與維護它,以確保系統的安全性
系統管理員可以利用多種方式來維護 Solaris Resource Manager 系統的安全。最重要的是,不論在任何 Solaris 系統上,都要確保 root 密碼的私密性。所有知道 root 使用者密碼的人都會取得無限制的系統資源存取權,就好比是中央管理員一樣。
Solaris Resource Manager 內的使用者可以藉由設定其 lnode 內的特定系統旗標,以取得數種特別的管理權限。這樣有助於加強一個系統的安全性,因為可以讓授權的使用者進行必要的任務,而又不需要賦予他們超級使用者的權限。
其他某些權限則必須謹慎處理,不可隨意賦予他人,因為這樣一來會使授權的使用者取得太廣泛的權力。擁有特殊權限的使用者密碼應該小心保護,正如必須小心保護超級使用者的密碼一樣。
Solaris Resource Manager 會考慮到數項安全上的顧慮以避免授予子管理員的管理權限遭到誤用:請參閱一個典型的應用程式伺服器 和 lnode 維護程式。
在某些情況下,中央管理員如果在操控排程樹的結構時不夠小心,很可能會造成系統安全上的問題。因此中央管理員必須清楚地了解應如何正確修正排程樹,並且知道如何偵測目前結構中的潛在問題。請參閱 排程樹結構 中的詳細說明。
群組管理員可能面臨的一個問題是,他們受到和其群組成員一樣的群組限制。例如,如果群組標頭 lnode 有一個處理限制,那麼該限制也會控制整個群組所用的處理數目,包括群組標頭在內。除非進一步加以限制,否則排程群組中任何使用者都可以設法超出自己的處理限制,不讓群組管理員建立新的處理。
要防止這種情況,群組管理員就必須對每一位群組成員設定個別的限制。然而,這些限制可能要非常嚴格,才能達到預期的效果。同時迫使子管理員去管理個別的限制,也不符合 Solaris Resource Manager 階層式資源控制的目標。
另外一個解決這個問題的方法是,讓中央管理員變更其群組中的 lnode 結構。在群組管理員的 lnode 下方建立一個“控制”lnode,作為唯一的子 lnode,而不得把使用者直接放置於群組管理員自己的 lnode 下方。這樣一來,就會產生如下所示的 lnode 結構。
參看上圖,群組管理員帳號的 UID 會對應標示為"Actual"的 lnode 帳號,也就是樹形的雙親。這也就是有 admin 旗標設定的 lnode。接著會為"Control" lnode 建立一個虛擬帳號,沒有登入會在這帳號上被准許。標示為"A"、"B"和"C"的 lnode 會與群組管理員控制之下的使用者互相對應。
在此例中,"Actual" lnode 的處理限制可以為 100,而"Control" lnode的限制為 90,同時個別使用者的限制則設為 0。這個設定可以確保即使在使用者 A、B 及 C 使用一共 90 個處理(允許的全部)的情形下,子管理員仍然可以另外建立 10 個處理。
不過使用者還是可以互相阻止對方建立處理,唯一的辦法是對那些使用者設定個別的限制。唯一避免這發生的方法,是設定個別使用者的權限。但是在這個例子中,各個限制可以設定為 40,仍然可以在防止單一使用者完全佔用他人資源的同時稍留一點空間。
同時注意,在這一個例子中,中央管理員能為新使用者建立額外的 lnodes。這些 lnodes 是 'Control' lnode 的子節點,並且中央管理員不用重新平衡限制。
limits database 就是 Solaris Resource Manager 用來執行所有資源控制的使用者資訊資料庫。其中包含每個 UID 一個 lnode,藉由使用 UID 作為檔案直接索引的方式來存取。如果一個數字很大的 UID 有一個 lnode 的話,限制資料庫也會很大。然而,系統中使用者的 UID 並沒有依照順序排列,因此限制資料庫會產生很大的間隙,可能會在一種支援此資料庫的檔案系統類型上內存為一個稀疏檔。亦即檔案"空白"段落的內存實際上沒有配置到任何磁碟區段。 ufs 檔案系統支援稀疏檔,但是 tmpfs 檔案系統則不支援。請參見 儲存與回復限制資料庫 以取得有關稀疏檔和儲存與回復限制資料庫方面的資訊。
每當您建立一個新的使用者,就必須要建立一個新的 lnode。
Solaris Resource Manager 啟動檔 (/etc/init.d/init.srm) 會在第一次調用,或發現檔案遺失而開機時建立一個初始限制資料庫。
限制資料庫一般位於 /var/srm 目錄中。
限制資料庫應屬於 root,群組應屬於 root,而且由所有者讀取。因為只有附帶超級使用者證明的 kernel 內碼可以寫入檔案中,所以不需要設定寫入權限。
如果一個使用者取得寫入 Solaris Resource Manager 限制資料庫的權限,可能會造成系統安全上的顧慮。
因為限制資料庫能成為一個疏散檔案,複制時請小心。如果以一個並不支援稀疏檔的公用程式撰寫的話,此檔案多半會佔用許多磁碟空間,因為連同檔案的空白區域都會被讀作一連串的零,然後被寫回為真正的區段,不再是空白區域。這有可能發生在檔案被公用程式複製,存檔或恢復,如 tar(1), cpio(1) 或 cp(1) 等公用程式來複製、備份或回復檔案的話,就會發生這種狀況。而 ufsdump(1M) 和 ufsrestore(1M) 等程式則會保留空白。
若您想備份與回復限制資料庫,也可以使用 limreport 來生成一個 ASCII 版的檔案,並且使用 limadm 從該已存的 ASCII 版本來重新建立原始檔。例如,下列指令:
# limreport 'flag.real' - lname preserve > /var/tmp/savelnodes |
會將 /var/tmp/savelnodes 建立為密碼映射中每位使用者的 lnode 的一個 ASCII 代表。請注意這不會為那些沒有對應的密碼映射登錄儲存 lnode。因此建議只需要密碼映射中所有 UID 的 lnode 便足夠。
指令:
# limadm set -f - < /var/tmp/savelnodes |
重新建立資料被儲存的 lnode。此指令將不會刪除未儲存的 lnode,所以也可以用這些方法來儲存與回復選取的 lnode 而非整個限制資料庫。
limreport 及 limadm 指令 更加詳細地說明 limreport 和 limadm 指令的使用。因為當改變 lnode 結構的翻譯﹝限制資料庫所定義﹞成為必需,熟悉使用這些指令儲存和恢復 lnode,對管理員是一大幫助。
由於一般系統作業期間會定期變更限制資料庫的內容,建議您最好在系統處於不活動狀態,或在單一使用者模式當中執行備份操作。同樣地,一定要在沒有使用 Solaris Resource Manager 的時候才能回復整個限制資料庫,例如系統處於單一使用者模式中的時候。
每當一位新的使用者被建立之後,就會建立一個對應的 lnode,也會設定其限制及權限。使用 Solaris Resource Manager 時,管理員應該維護限制資料庫,讓它和一般 Solaris 密碼資料庫保持一致。指令:
# limreport \!flag.real - uid lname |
可以用來列印一份 UID 及沒有對應 lnode 的任何使用者登入名稱清單。
用來建立與刪除帳號的系統指令不會自動建立與刪除 lnode。要由管理員自行決定是否執行這些動作。然而,使用者登入時可以要求自動建立 lnode,請參見 PAM 子系統 中的詳細說明。
同樣地,在從密碼映射中刪除使用者帳號之前,應該使用 limadm(1MSRM) 指令,從限制資料庫中移除對應的 lnode。
刪除 lnode 時請確定將子排程樹由最底層的 lnode 開始刪除。如果您從樹的最上層開始刪除,會失去對刪除的子 lnode 的控制權,因為它們會因為雙親被移除而成為孤兒。
如果一個使用者的 UID 有所變更,應該將其 lnode 的內容複製到對應至新號碼的一個新的 lnode 上,而刪除原始的 lnode。請參見 複製與移除 lnode。
任何子 lnode 應該被附加至新建立的 lnode,或是其他適當的雙親 lnode 之上。指令:
# limreport 'sgroup==X' '%u\tsgroup=Y\n' uid | limadm set -u -f - |
可以用來尋找所有擁有 UID 為 X 的排程群組雙親的 lnode,讓它們成為有一個 UID 為 Y 的子 lnode。
下列步驟說明如何將一個 lnode 的 UID 從 X 變更為 Y。
儲存其中 UID 需要變更的 lnode 的狀態:
# limreport 'uid==X' - lname preserve > /var/tmp/savelnode.X |
將使用者密碼映射登錄的 UID 從舊的數值 (X) 變更為新的 UID (Y)。
建立一個新 UID 的 lnode,從先前儲存的狀態中回復:
# limadm set -f /var/tmp/savelnode.X |
若要變更 lnode 的所有子 lnode (UID X),將其排程群組變更為新的 lnode (UID Y):
# limreport 'sgroup==X' '%u\tsgroup=Y\n' uid | limadm set -u -f - |
確定目前沒有任何處理附加在舊的 lnode 之上。
使用 chown(2) 指令來將原始 UID 所擁有的所有檔案所有者變更為新的 UID。舉例來說:
# find / -user X -print | xargs chown Y |
刪除舊的 lnode:
# limadm delete X |
limadm 指令是管理員用來維護使用者 lnode 的主要工具。此指令會變更使用者帳號清單中的 Solaris Resource Manager 屬性值。如果任何使用者都沒有一個 lnode 存在的話,則會先建立一個預設的空白 lnode。新的 lnode 包含下列特性:
flag.real 設為 set;
cpu.shares 和 cpu.myshares 屬性設為 1;
旗標 uselimadm 和 admin 設為 clear;
所有其他旗標設為 inherit;
所有的限制及使用屬性設為 0。
如果該使用者帳號或是 root lnode 有一個 lnode 存在的話,新的 lnode 排程群組會設為 'other' 使用者 (srmother)。
limadm 調用程式需要充份的管理權限以執行指定的變更。它們必須是超級使用者,有一個為 set 的 uselimadm 旗標,或是一位群組管理員而只變更其排程群組成員的屬性。管理員應用限制到 limadm 的使用。
群組管理員無法變更自己屬性的數值。
一個使用者的 sgroup 屬性只能指派給調用程式本身或調用程式的排程群組成員的群組標頭。
群組管理員無法變更排程群組之外的使用者屬性。
無法修改任何用來儲存 usages 的屬性。如果沒有這個限制,那麼群組管理員可以減少使用其子中的一個,因而減少群組使用,以繞過其 lnodes 內的群組限制。
假如它們有一個旗標,用來評量非預設之外的數值,群組管理員只有在他們改變到相同非預設值時,才能為其他組員變更旗幟數值。
這可以確保那些權限被拒的群組管理員無法將權限賦予其影響下的任何使用者。
limadm 指令可以讓管理員移除一個 lnode 而不需要刪除密碼對映的使用者帳號。若要使用 limadm,調用程式必須是超級使用者或擁有一組 uselimadm 旗標。如果調用程式只有一個設定的 admin 旗標,那麼他們便只能刪除其作為群組標頭的使用者 lnode。
Solaris Resource Manager 的數值是以下列三種類型之一的單位來表示:
定標單位是一種預設的可讀格式,可用來顯示與輸入數值。定標單位可以減少需要輸入的數字,幫助使用者避免登錄錯誤。
原始單位是一種基本單位,以一個數值代表。舉例來說,虛擬記憶體使用量的原始單位是位元組,而虛擬記憶體累計的原始單位為每秒位元組。這些主要是用於記載使用量,這時必須知道確實的量多寡。
Solaris Resource Manager 使用內部單位來內存記憶體屬性,這些機器可讀的單位並非以位元組來表示。
Solaris Resource Manager 程式可以變換用來內存屬性值的內部單位,因此使用者得以讀取定標單位或是原始單位。亦即除了少數情況之外,使用者多半不需要懂得 Solaris Resource Manager 所使用的內部單位。
Solaris Resource Manager 使用 exa、peta、tera、giga、mega 及 kilo 這些詞來代表二次方而非十次方。例如,megabyte 代表 1,048,576 位元組,而非 1,000,000 位元組。所以它們分別為二的 60 次方 (exa)、二的 50 次方 (peta)、二的 40 次方 (tera)、二的 30 次方 (giga)、二的 20 次方 (mega) 以及二的 10 次方(kilo)。
作為使用者以及 Solaris Resource Manager 系統間主要介面的程式為 limadm、 liminfo 及 limreport。它們所執行的轉換與定標會在下列的小節中做詳細說明。
當變更屬性值的時候,limadm 容許數字後附加定標字元:[EPTGMK][B][.][wdhms]。大小寫字母可以互換。
如果屬性包含內存(記憶體屬性)或內存累計的維,那麼便採用第一個群組 (EPTGMK) 中的一個字元,再根據需要乘以 exabyte (E), petabyte (P)、terabyte (T)、gigabyte (G)、megabyte (M) 或 kilobyte (K) 的位元組數。選擇性的 B 字元可以附加其後,只是為了讓人瞭解,但沒有實際功效。
假如屬性有時間的向量(鍵入時間或日期),或屬於儲存器累加,則一個字元從第二組是許可的。然后乘以一周(w), 一天(d), 一小時(h), 一分鐘(m),或一秒鐘(s)中的秒數。
可選擇句號(。)來分隔儲存和時間單位。(例如, mh, M.h 和 MB.h 都代表 'megabyte hours')。
M 字尾的意義不明確,limadm 會試著從上下文判斷它的實際意義。如果分不清,則假設它為 mega,而不是分鐘。
輸入大數字時,這些轉換字元在輸入大的數字時很有用,可以避免登錄數量級的錯誤;不過不論登錄方法為何,其數量都是以內部單位來保存的。
您也可以單獨使用一個特殊的定標字元 u,但只能用於記憶體屬性值。它表示數字為機器的(內部)單位而非位元組。
liminfo(1SRM) 指令使用當報告為將 limadm 用於輸入時的相同字尾(請見上述內容)。一般而言,liminfo 會將數值轉換為適當的定標格式來列印,但是可以使用 -r 選項,讓 liminfo 以其原始(未定標)格式來列印數值。例如,記憶體通常被定標為一種適當的單位,例如 megabyte(如 '102 MB'),但是若指定 -r 選項,則會以位元組來列印記憶體(如 106954752 位元組)。
limreport(1SRM) 指令通常是以原始(未定標)格式來報告數值。如果需要定標數值,顯示此數值的表達式中必須明確地說明轉換。例如,要以 KB 來顯示所有使用者的虛擬記憶體使用總量,必須使數字入於最接近的 KB:
# limreport 'flag.real' '%-8.8s %d KB\n' lname '(memory.usage+1k-1)/1k' |
如此例所示,您可以在表達式中的數字上使用定標字尾,以簡化將原始單位到定標數值的轉換。
請注意,某些屬性的內部單位和其 '原始' 格式並不相同。通常使用者不需要擔心這一點,因為所有的 Solaris Resource Manager 程式都會自行轉換為定標單位或原始單位。這表示,如果 limreport 中的選取表達式指定的數字不為相關內部單位的一個整數倍數的話,那麼便永遠無法符合一個特定的位元組數。
limreport 及 limadm 指令提供管理員一個非常簡單的方法,可以為所有的使用者儲存與回復 lnode 的內容。 limreport 指令是用來選取與擷取要儲存的 lnode,而 limadm 是用來回復這些 lnode。此類指令組合最常用於複製 lnode 與修改 lnode 結構,如下節所述。
limreport 指令也提供一種靈活的方式來選取與顯示使用者屬性。它共有兩種選取層級:lnode 選取,以及屬性選取以顯示每個選定 lnode 的屬性。lnode 選取必須由一個選取表達式的規格來取得,可能是單一條件或是一組條件加上 C 語言語法的邏輯運算子。屬性選取必須列出屬性的象徵性名稱來取得。屬性顯示的方式可以由格式控制字串來指定,與 C 函數 limreport類似,並有擴充功能以處理特殊的 Solaris Resource Manager 類型。如果指定了一個格式控制字串 '-',limreport 會為每個顯示的屬性使用預設格式。請參閱 limreport(1SRM) 中更詳細的說明資訊。
limadm 指令可以變更 lnode 中的屬性內容,不過調用程式必須具有充分的權限。可以在指令行上直接指定變更指令,或者指定一個包含變更指令的檔案名稱(使用 -f 選項)。
limreport 指令可以使用 limadm 語法生成屬性值指派(請參閱 limadm 語法中的保留 識別符)其輸出可以是使用f選項的 limreport -輸入 。這可以讓管理員同時使用兩個程式,選擇性地儲存與回復限制資料庫的內容。
指令:
# limreport 'uid==X' - Y preserve | limadm set -u -f - |
會從 UID X 複製一個 lnode 到 UID Y。表達式 uid==X 提供選取來源 lnode 的方法。保留識別符會導致 limreport 將非唯讀的所有屬性值,輸出到適合傳送給 limadm 的語法。在保留標識符前放置 UID Y 會成為傳給 limadm 資料的第一個項目,因此提供目標 lnode 選取。
如果不再需要來源 lnode 的話,可以使用 limadm 來將它移除。
在 limreport 選取表達式中以 UID 作為符合條件時要特別小心。如果有多個登入名稱共用一個 UID 的話,它們全都會符合條件。這在上述的例子中無所謂,因為相同的 lnode 資料會被保留與載入很多次。在 Solaris 系統中,UID 0 同時會有 root 和 smtp 的登入名稱。