適用於 Solaris 2.6 的 Solaris Resource Manager 1.0 系統管理指南(SPARC 平台版)

第 5章 管理 lnode

Solaris Resource Manager 系統係圍繞 kernel 而建構的一個基本附件,即一種稱為 lnode 的每位-使用者結構。在密碼映射中所定義的每個唯一 UID 都應該有一個對應的 lnode。(接續的 getpwent(3C) 呼叫回傳的每一個唯一 UID。)雖然一個 lnode 可以沒有對應的密碼映射登錄,但建議您不要這麼做。Lnode 會內存於磁碟之上,並且由 kernel 自動移入或移出記憶體。從磁碟中讀取後被變更的 lnode 記憶體副本,會作為定期系統同步化操作而回寫;或在 sync(1M) 指令執行時應需求回寫;或者是在必須釋放 lnode 快取記憶體的空間以讀入後續的 lnode 時回寫。lnode 實際上是一個大小固定的位置,可以內存與更新各類的每位-使用者資料。

Lnode 通常是一種樹狀階層的結構,中央管理員為樹形的頭,其他使用者為樹中較小使用者群組的群組 header。中央管理員為系統的超級使用者或 root 使用者。

與 lnode 有關的錯誤,例如孤立行及群組迴圈,將在第 9章, 解決難題中加以詳述。

授權管理

Lnode 的主要管理責任有賴於中央管理員來肩負。當 Solaris Resource Manager 設立數種用來指派與管理的資源控制時,也可以選擇性地將特定的管理權限指派給非 root 的使用者,以分散管理使用者的負擔。管理權限可以藉由設定使用者 uselimadmadmin 旗標的方式來指派給適當的使用者。uselimadm 旗標為 set 的使用者在 limadm(1MSRM) 程式中和超級使用者享有相同的管理權限。一個 admin 旗標為 set 的群組 header 使用者稱為一位子管理員,並且擁有(如下所述)管理其排程群組內其他使用者的權限。

中央管理員可以建立與限制以 root 為雙親的排程群組來控制整體系統資源的分割。子管理員一般會執行同類的資源控制,但是僅限於其排程群組之內的使用者。子管理員所能分割的資源僅限於已經配置給群組(例如配置給群組 header lnode)的資源。請注意,子管理員可以將 admin 旗標指派給其排程群組中的任何使用者,更進一步地分派其自身的管理責任。

子管理員可以進行下列工作﹕

  1. 為其排程群組內的使用者建立與刪除 lnode。

  2. 修改其排程群組內任何使用者的資源限制。

    請注意,雖然子管理員可以將一個資源的限制設定得比群組的限制還要大,群組成員所佔用的資源也會被認為是群組 header 所佔用的資源,因此當使用者超出群組 header 的限制時,就會強制實施對個別使用者的限制。

  3. 修改其排程群組內的任何 lnode 旗標,但是旗標不能有 noadmin 條件。子管理員指派旗標的工作會進一步受到限制,因而使用者便無法取得子管理員所沒有的權限。之所以採用這種限制是為了防止子管理員繞過 Solaris Resource Manager 的安全措施。

  4. 調整他們自己的任何具有 selfadmin 條件的屬性。

子管理員的主要工具是 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 內的特定系統旗標,以取得數種特別的管理權限。這樣有助於加強一個系統的安全性,因為可以讓授權的使用者進行必要的任務,而又不需要賦予他們超級使用者的權限。

其他某些權限則必須謹慎處理,不可隨意賦予他人,因為這樣一來會使授權的使用者取得太廣泛的權力。擁有特殊權限的使用者密碼應該小心保護,正如必須小心保護 root 使用者的密碼一樣。

在某些情況下,中央管理員如果在操控排程樹的結構時不夠小心,很可能會造成系統安全上的問題。因此中央管理員必須清楚地了解應如何正確修正排程樹,並且知道如何偵測目前結構中的潛在問題。

uselimadmadmin 旗標

中央管理員可以透過一位使用者 lnode 中的 uselimadmadmin 旗標,指派 Solaris Resource Manager 內的管理權限。 指向 limadm(1MSRM) 指令的 uselimadm 旗標可以讓使用者取得與中央管理員相同的管理權限。設定給一個群組 header 的 admin 旗標,賦予群組 header 管理其所帶領的群組成員的權限,但無法修改任何群組之外的 lnode 內容。

admin 旗標為 set 的群組 header 稱為子管理員。 Solaris Resource Manager 有數種安全措施可以防止子管理員濫用管理權限﹕請參閱"一個典型的應用程式伺服器"以及"Lnode 維護程式"中的詳細說明。

一位子管理員在刪除 lnode 時,應該確定從最底層的 lnode 開始刪除子樹。如果您是從正在刪除的子樹頂層開始的話,便會失去控制被刪除的 lnode 子的權限,因為它們在其雙親被移除之後成為孤立。一旦被孤立後,子管理員便無法修改 lnode,因為它們已經不屬於排程群組之內。

建議的子管理員 lnode 結構

子管理員可能面臨的一個問題是,他們受到和其群組成員一樣的群組限制。例如,如果群組 header lnode 有一個處理限制,那麼該限制也會控制整個群組所用的處理數目,包括群組 header 在內。除非進一步加以限制,否則排程群組中任何使用者都可以設法超出自己的處理限制,不讓子管理員建立新的處理。要防止這種情況,群組管理員就必須對每一位群組成員設定個別的限制。然而,這些限制可能要非常嚴格,才能達到預期的效果。同時迫使子管理員去管理個別的限制,也不符合 Solaris Resource Manager 階層式資源控制的目標。另外一個解決這個問題的方法是,讓管理員變更其群組中的 lnode 結構。不直接將使用者放在自己的 lnode 之下,相反地,他們應該在自己底下建立一個"Control"lnode 來作為他們唯一的子 lnode,然後再讓所有使用者成為此控制 lnode 的子。這樣一來,就會產生如下所示的 lnode 結構。

圖 5-1 子管理員 lnode 結構

Graphic

參看上圖,子管理員帳號的 UID 會對應標示為"Actual"的 lnode 帳號,也就是樹形的雙親。這也就是 admin 旗標為 set 的 lnode。接著會為"Control"lnode 建立一個虛擬帳號,此帳號不會允許任何登入。標示為"A"、"B"和"C"的 lnode 會與子管理員控制之下的使用者互相對應。

在此例中,"Actual"lnode 的處理限制可以為 100,而"Control"lnode 的限制為 90,同時個別使用者的限制則設為 0。這個設定可以確保即使在使用者 A、B 及 C 使用一共 90 個處理(允許的全部)的情形下,子管理員仍然可以另外建立 10 個處理。不過使用者還是可以互相阻止對方建立處理,唯一的辦法是對那些使用者設定個別的限制。但是在這個例子中,各個限制可以設定為 40,仍然可以在防止單一使用者完全佔用他人資源的同時稍留一點空間。也請注意,這個例子中的子管理員可以為新使用者建立額外的 lnode 來作為"Control"lnode 的子,而不需要擔心如何重新平衡各項限制。

限制資料庫

限制資料庫就是 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(1SRM) 來生成一個 ASCII 版的檔案,並且使用 limadm(1MSRM) 從該已存的 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 而非整個限制資料庫。

"limreportlimadm 指令" 更加詳細地說明 limreport(1SRM)limadm(1MSRM) 指令的使用。如果管理員可以熟悉如何使用這些儲存與回復 lnode 的指令的話,幫助極大。因為當 lnode 結構的解譯(如設置檔定義)被變更時,可能有必要使用這些指令。

請注意,由於一般系統作業期間會定期變更限制資料庫的內容,建議您最好在系統處於不活動狀態,或在單一使用者模式當中執行備份操作。同樣地,一定要在沒有使用 Solaris Resource Manager 的時候才能回復整個限制資料庫,例如系統處於單一使用者模式中的時候。

建立與刪除 lnode

每當一位新的使用者被建立之後,就會建立一個對應的 lnode,也會設定其限制及權限。使用者必須等到 lnode 建立之後才能登入系統。使用 Solaris Resource Manager 時,管理員應該維護限制資料庫,讓它和一般 Solaris 密碼資料庫保持一致。指令﹕

# limreport \ !flag.real - uid lname 

可以用來列印一份 UID 及沒有對應 lnode 的任何使用者登入名稱清單。

在此版本中,用來建立與刪除帳號的系統指令不會自動建立與刪除 lnode。要由管理員自行決定是否執行這些動作。然而,使用者登入時可以要求自動建立 lnode,請參閱"PAM 子系統"中的細節說明。

同樣地,在從密碼映射中刪除使用者帳號之前,應該使用 limadm(1MSRM) 指令,從限制資料庫中移除對應的 lnode。

如果一個使用者的 UID 有所變更,應該將其 lnode 的內容複製到對應至新號碼的一個新的 lnode 上,而刪除原始的 lnode。請參閱"複製與移除 lnode"

任何子 lnode 應該被附加至新建立的 lnode,或是其他適當的雙親 lnode 之上。指令﹕

# limreport 'sgroup==X' '%u\tsgroup=Y\n' uid | limadm set -u -f - 

可以用來尋找所有擁有 UID 為 X 的排程群組雙親的 lnode,讓它們成為有一個 Y UID 的子 lnode。

下列步驟說明如何從 X 將一個 lnode 的 UID 變更為 Y。

  1. 儲存其中 UID 需要變更的 lnode 的狀態﹕

    # limreport 'uid==X' - lname preserve > /var/tmp/savelnode.X

  2. 將使用者密碼映射登錄的 UID 從舊的數值 (X) 變更為新的 UID (Y)。

  3. 建立一個新 UID 的 lnode,從先前儲存的狀態中回復﹕

    # limadm set -f /var/tmp/savelnode.X

  4. 若要變更 lnode 的所有子 lnode (UID X),將其排程群組變更為新的 lnode (UID Y)﹕

    # limreport 'sgroup==X' '%u\tsgroup=Y\n' uid | limadm set -u -f -  

  5. 確定目前沒有任何處理附加在舊的 lnode 之上。請參閱"建立與刪除 lnode"

  6. 使用 chown(2) 指令來將原始 UID 所擁有的所有檔案所有者變更為新的 UID。舉例來說﹕

    # find / -user X -print | xargs chown Y

  7. 刪除舊的 lnode﹕

    # limadm delete X

Lnode 維護程式

limadm 指令是管理員用來維護使用者 lnode 的主要工具。此指令會變更使用者帳號清單中的 Solaris Resource Manager 屬性值。如果任何使用者都沒有一個 lnode 存在的話,則會先建立一個內定的空白 lnode。新的 lnode 包含下列特性﹕

如果該使用者為子管理員,新 lnode 的排程群組設為limadm 調用程式的值;否則如果該使用者帳號有一個 lnode 的話(如果調用程式是 rootuselimadm 旗標為 set),便設為使用者 other,否則便設為 root lnode。

limadm 調用程式需要充份的管理權限以執行指定的變更。它們必須是超級使用者,有一個為 set 的uselimadm 旗標,或是一位子管理員而只變更其排程群組成員的屬性。子管理員使用 limadm 的限制如下﹕

limadm 指令可以讓管理員移除一個 lnode 而不需要刪除密碼映射中對應的使用者帳號。要使用 limadm,調用程式必須為超級使用者,有一個 set 的uselimadm 旗標,或是有 set 的admin 旗標。如果調用程式只有一個 set 的admin 旗標,那麼他們便只能刪除其作為群組 header 的使用者 lnode。

單位

Solaris Resource Manager 的數值是以下列三種類型之一的單位來表示﹕

定標

定標單位是一種內定的可讀格式,可用來顯示與輸入數值。定標單位可以減少需要輸入的數字,幫助使用者避免登錄錯誤。

原始(或未定標)

原始單位是一種基本單位,以一個數值代表。舉例來說,虛擬記憶體使用量的原始單位是位元組,而虛擬記憶體累計的原始單位為每秒位元組。這些主要是用於記載使用量,這時必須知道確實的量多寡。

Internal

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(1MSRM)liminfo(1SRM) 以及 limreport(1SRM)。它們所執行的轉換與定標會在下列的小節中做詳細說明。

limadm 指令

當變更屬性值的時候,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' 小時)。M 字尾的意義不明確, limadm 會試著從上下文判斷它的實際意義。如果分不清,則假設它為 mega,而不是分鐘。

這些轉換字元在輸入大的數字時很有用,可以避免登錄數量級的錯誤;不過不論登錄方法為何,其數量都是以內部單位來內存的。

您也可以單獨使用一個特殊的定標字元 u,但只能用於記憶體屬性值。它表示數字為機器的(內部)單位而非位元組。

liminfo 指令

liminfo(1SRM) 指令使用的報告字尾和 limadm(1MSRM) 使用的輸入字尾相同(請見上述內容)。一般而言,liminfo 會將數值轉換為適當的定標格式來列印,但是可以使用 -r 選項,讓 liminfo 以其原始(未定標)格式來列印數值。例如,記憶體通常被定標為一種適當的單位,例如megabyte(如 '102 MB'),但是若指定 -r 選項,則會以位元組來列印記憶體(如 106954752 位元組)。

limreport 指令

limreport(1SRM) 指令通常是以原始(未定標)格式來報告數值。如果需要定標數值,顯示此數值的表達式中必須明確地說明轉換。例如,要以 kilobyte 來顯示所有使用者的虛擬記憶體使用總量,必須使數字入於最接近的 kilobyte﹕

# limreport 'flag.real' '%-8.8s %d KB\n' lname '(memory.usage+1k-1)/1k' 

如此例所示,表達式中的數字上可以使用定標字尾,以簡化將原始單位到定標數值的轉換。

請注意,某些屬性的內部單位和其 '原始' 格式並不相同。通常使用者不需要擔心這一點,因為所有的 Solaris Resource Manager 程式都會自行轉換為定標單位或原始單位。這表示,如果 limreport 中的選取表達式指定的數字不為相關內部單位的一個整數倍數的話,那麼便永遠無法符合一個特定的位元組數。

操控 lnode

limreportlimadm 指令

limreport(1SRM)limadm(1MSRM) 指令提供管理員一個非常簡單的方法,可以為所有的使用者儲存與回復 lnode 的內容。limreport 指令是用來選取與擷取要儲存的 lnode,而 limadm 是用來回復這些 lnode。此類指令組合最常用於複製 lnode 與修改 lnode 結構。

limreport 指令提供一種靈活的方式來選取與顯示使用者屬性。它共有兩種選取層級﹕lnode 選取,以及屬性選取以顯示每個選定 lnode 的屬性。lnode 選取必須由一個選取表達式的規格來取得,可能是單一條件或是一組條件加上 C 語言語法的邏輯運算子。屬性選取必須列出屬性的象徵性名稱來取得。屬性顯示的方式可以由格式控制字串來指定,與 C 函數 limreport 類似,並有擴充功能以處理特殊的 Solaris Resource Manager 類型。如果指定了一個格式控制字串 '-',limreport 會為每個顯示的屬性使用內定格式。請參閱 limreport(1SRM) 中更詳細的說明資訊。

limadm 指令可以變更 lnode 中的屬性內容,不過調用程式必須具有充分的權限。可以在指令行上直接指定變更指令,或者指定一個包含變更指令的檔案名稱(使用 -f 選項)。

limreport 可以使用 lim 語法來生成屬性數值的賦值(意指 lim 語法中的保留標識符),其輸出可以利用 f 選項來輸入 -limreport。這可以讓管理員同時使用兩個程式,選擇性地儲存與回復限制資料庫的內容。

複製與移除 lnode

指令﹕

# limreport 'uid==X' - Y preserve | limadm set -u -f -

會從 UID X 複製一個 lnode 到 UID Y。表達式 'uid==X' 提供選取來源 lnode 的方法。保留標識符會導致 limreport 輸出所有屬性數值,其為適合傳給 limadm 的非唯讀語法。在保留標識符前放置 UID Y 會成為傳給 lim 資料的第一個項目,因此提供目標 lnode 選取。

如果不再需要來源 lnode 的話,可以使用 limadm 來將它移除。


註解 -

limreport 選取表達式中以 UID 作為符合條件時要特別小心。如果有多個登入名稱共用一個 UID 的話,它們全都會符合條件。這在上述的例子中無所謂,因為相同的 lnode 資料會被保留與載入很多次。在 Solaris 系統中,UID 0 同時會有 rootsmtp 的登入名稱。