Product SiteDocumentation Site

Fedora 16

リソース管理ガイド

Fedora 16 のシステムリソース管理

エディッション 1

Prpič Martin [FAMILY Given]

Red Hat エンジニアリングコンテンツサービス

Landmann Rüdiger [FAMILY Given]

Red Hat エンジニアリングコンテンツサービス

Silas Douglas [FAMILY Given]

Red Hat エンジニアリングコンテンツサービス

法律上の通知

Copyright © 2011 Red Hat, Inc and others.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. The original authors of this document, and Red Hat, designate the Fedora Project as the "Attribution Party" for purposes of CC-BY-SA. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, MetaMatrix, Fedora, the Infinity Logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
For guidelines on the permitted uses of the Fedora trademarks, refer to https://fedoraproject.org/wiki/Legal:Trademark_guidelines.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
All other trademarks are the property of their respective owners.
概要
Fedora 16 のシステムリソース管理

序文
1. 表記方法
1.1. 印刷における表記方法
1.2. 引用における表記方法
1.3. 注記および警告
2. フィードバック
1. Control Group について (cgroup)
1.1. Control Group の構成
1.2. サブシステム、階層、Control Group、タスクの関係
1.3. リソース管理の影響
2. Control Group の使用法
2.1. cgconfig サービス
2.1.1. cgconfig.conf ファイル
2.2. 階層の作成とサブシステムの接続
2.3. 既存の階層へのサブシステムの接続と接続解除
2.4. 階層の接続解除
2.5. Control Group の作成
2.6. Control Group の削除
2.7. パラメータのセッティング
2.8. Control Group へのプロセス移動
2.8.1. cgred デーモン
2.9. Control Group 内のプロセスの開始
2.9.1. Control Group 内のサービスの開始
2.9.2. Root Control Group 内のプロセスの振る舞い
2.10. /etc/cgconfig.conf ファイルの生成
2.10.1. パラメータのブラックリスト化
2.10.2. パラメータのホワイトリスト化
2.11. Control Group に関する情報の取得
2.11.1. プロセスの確認
2.11.2. サブシステムの確認
2.11.3. 階層の確認
2.11.4. Control Group の確認
2.11.5. Control Group のパラメータの表示
2.12. Control Group のアンロード
2.13. その他のリソース
3. サブシステムと調整可能なパラメータ
3.1. blkio
3.1.1. 比例ウェイト分割の設定オプション
3.1.2. I/O スロットリングの設定オプション
3.1.3. 共通の設定オプション
3.1.4. 使用例
3.2. cpu
3.3. cpuacct
3.4. cpuset
3.5. devices
3.6. freezer
3.7. memory
3.8. net_cls
3.9. ns
3.10. その他のリソース
A. 改訂履歴

序文

1. 表記方法

本ガイドは特定の単語や語句を強調したり、 記載内容の特定部分に注意を引かせる目的で次のような表記方法を使用しています。
PDF版 および印刷版では、 Liberation Fonts セットから採用した書体を使用しています。 ご使用のシステムに Liberation Fonts セットがインストールされている場合、 HTML 版でもこのセットが使用されます。 インストールされていない場合は代替として同等の書体が表示されます。 注記: Red Hat Enterprise Linux 5 およびそれ以降のバージョンにはデフォルトで Liberation Fonts セットが収納されます。

1.1. 印刷における表記方法

特定の単語や語句に注意を引く目的で 4 種類の表記方法を使用しています。 その表記方法および適用される状況は以下の通りです。
等幅の太字
シェルコマンド、ファイル名、パスなどシステムへの入力を強調するために使用しています。またキー配列やキーの組み合わせを強調するのにも使用しています。 例えば、
現在作業中のディレクトリ内のファイル my_next_bestselling_novel の内容を表示させるには、 シェルプロンプトで cat my_next_bestselling_novel コマンドを入力してから Enter を押してそのコマンドを実行します。
上記にはファイル名、シェルコマンド、キーが含まれています。 すべて等幅の太字で表されているため文中内で見分けやすくなっています。
キーが 1 つの場合と複数のキーの組み合わせになる場合を区別するため、 その組み合わせを構成するキー同士をハイフンでつないでいます。 例えば、
Enter を押してコマンドを実行します。
1 番目の仮想ターミナルに切り替えるは、 Ctrl+Alt+F2 を押します。 X-Windows セッションに戻るには、 Ctrl+Alt+F1 を押します。
最初の段落では押すべき 1 つのキーを特定して強調しています。 次の段落では同時に押すべき 3 つのキーの組み合わせが 2 種類ありそれぞれ強調されています。
ソースコードの説明では 1 段落内で提示されるクラス名、 メソッド、 関数、 変数名、 戻り値を上記のように 等幅の太字 で表示します。 例えば、
ファイル関連のクラス群はファイルシステムに対しては filesystem、 ファイルには file、 ディレクトリには dir をそれぞれ含みます。 各クラスは個別に関連する権限セットを持っています。
プロポーショナルの太字
アプリケーション名、 ダイアログボックスのテキスト、ラベル付きボタン、 チェックボックスとラジオボタンのラベル、 メニュータイトルとサブメニュータイトルなどシステム上で見られる単語や語句を表します。 例えば、
メインメニューバーから システム > 個人設定 > マウス の順で選択し マウスの個人設定 を起動します。 ボタン タブ内で 左ききのマウス チェックボックスをクリックしてから 閉じる をクリックしマウスの主要ボタンを左から右に切り替えます (マウスを左ききの人が使用するのに適した設定にする)。
gedit ファイルに特殊な文字を挿入する場合は、 メインメニューバーから アプリケーション > アクセサリ > 文字マップ の順で選択します。 次に 文字マップ メニューバーから 検索 > 検索… と選択して 検索 フィールド内にその文字名を入力し をクリックします。 探している文字が 文字表 内で強調表示されます。 この強調表示された文字をダブルクリックすると コピーするテキスト フィールド内に置かれるので次に コピー ボタンをクリックします。 ここでドキュメントに戻り gedit メニューバーから 編集 > 貼り付け を選択します。
上記には、 アプリケーション名、 システム全体のメニュー名と項目、 アプリケーション固有のメニュー名、 GUI インタフェースで見られるボタンやテキストがあります。 すべてプロポーショナルの太字で表示されているため文中内で見分けやすくなっています。
等幅の太字で且つ斜体 または プロポーショナルの太字で且つ斜体
等幅の太字やプロポーショナルの太字はいずれであっても斜体の場合は置換可能なテキストか変化するテキストを示します。 斜体は記載されている通りには入力しないテキスト、あるいは状況に応じて変化する出力テキストを表します。 例えば、
ssh を使用してリモートマシンに接続するには、 シェルプロンプトで ssh username@domain.name と入力します。 リモートマシンが example.com であり、 そのマシンで使用しているユーザー名が john なら ssh john@example.com と入力します。
mount -o remount file-system コマンドは指定したファイルシステムを再マウントします。 例えば、 /home ファイルシステムを再マウントするコマンドは mount -o remount /home になります。
現在インストールされているパッケージのバージョンを表示するには、 rpm -q package コマンドを使用します。 結果として次を返してきます、 package-version-release
上記の太字斜体の単語 — username、 domain.name、 file-system、 package、 version、 release に注目してください。 いずれもコマンドを発行するときに入力するテキスト用のプレースホルダーかシステムにより出力されるテキスト用のプレースホルダーになっています。
タイトル表示のような標準的な使用の他、 斜体は新しい重要な用語が初めて出現する場合にも使用されます。 例えば、
Publican は DocBook の発行システムです。

1.2. 引用における表記方法

端末の出力とソースコード一覧は、視覚的に周囲の文から区別されています。
端末に送信される出力は mono-spaced roman (等幅の Roman) にセットされるので以下のように表示されます。
books        Desktop   documentation  drafts  mss    photos   stuff  svn
books_tests  Desktop1  downloads      images  notes  scripts  svgs
ソースコードの一覧も mono-spaced roman (等幅の Roman) でセットされますが、以下のように強調表示されます。
package org.jboss.book.jca.ex1;

import javax.naming.InitialContext;

public class ExClient
{
   public static void main(String args[]) 
       throws Exception
   {
      InitialContext iniCtx = new InitialContext();
      Object         ref    = iniCtx.lookup("EchoBean");
      EchoHome       home   = (EchoHome) ref;
      Echo           echo   = home.create();

      System.out.println("Created Echo");

      System.out.println("Echo.echo('Hello') = " + echo.echo("Hello"));
   }
}

1.3. 注記および警告

情報が見過ごされないよう 3 種類の視覚的なスタイルを使用して注意を引いています。

注記

注記は説明している部分に対するヒントや近道あるいは代替となる手段などになります。注記を無視しても悪影響はありませんが知っておくと便利なコツを見逃すことになるかもしれません。

重要

重要ボックスは見逃しやすい事項を詳細に説明しています。現在のセッションにのみ適用される設定上の変更点、 更新を適用する前に再起動が必要なサービスなどがあります。重要ボックスを無視してもデータを喪失するような結果にはなりませんがイライラ感やフラストレーションが生じる可能性があります。

警告

警告は無視しないでください。警告を無視するとデータを喪失する可能性が非常に高くなります。

2. フィードバック

本ガイドに誤植を見つけられた場合や本ガイドの改善案をお持ちの場合はぜひお知らせください。 Bugzilla http://bugzilla.redhat.com/bugzilla/ にて、 Product には Fedora Documentation. を選びレポートの提出をお願いいたします。
バグレポートを提出される場合は、 そのガイドの識別子となる resource-management-guide を必ず明記して頂くようお願いします。
ドキュメントに関する改善のご意見についてはできるだけ具体的にお願いいたします。 エラーを発見された場合は、 セクション番号および該当部分の前後の文章も含めてご報告頂くと照合が容易になります。

第1章 Control Group について (cgroup)

Fedora 16 では、control group と呼ばれる新たなカーネル機能を搭載しています。本ガイドでは、この機能を cgroup という略称で記載しています。cgroup により、ユーザーは、CPU 時間、システムメモリー、ネットワーク帯域幅などのリソースやそれらのリソースの組み合わせを、システム上で実行中のユーザー定義タスクグループ (プロセス) の間で割り当てることができるようになります。また、設定した cgroup のモニタリングを行ったり、特定のリソースに対する cgroup のアクセスを拒否することができるのに加えて、稼働中のシステムで cgroup を動的に再設定することもできます。cgconfig (control group config ) サービスがブート時に起動し、事前に定義された cgroup を再構築するように設定して、再起動後もリソース割り当てが永続されるようすることが可能です。
cgroup を使用することにより、システム管理者は、システムリソースの割り当て、優先順位付け、拒否、管理、モニタリングに対する粒度の細かいコントロールが可能となります。ハードウェアリソースは、タスクおよびユーザー間で素早く分配され、全体的な効率が向上します。

1.1. Control Group の構成

プロセスと同様に、cgroup は階層的に構成されており、子 cgroup は、親 cgroup の属性の一部を継承するようになっています。ただし、これら 2 つのモデルの間には相異点があります。

Linux プロセスモデル

Linux システム上のプロセスはすべて、init プロセスという、共通の親プロセスの子プロセスです。init プロセスは、ブート時にカーネルによって実行され、その他のプロセスを開始します (その結果、その他のプロセスがそれら独自の子プロセスを開始する場合もあります)。プロセスはすべて、単一の親プロセスの下位プロセスであるため、Linux プロセスモデルは、単一の階層またはツリーとなっています。
また、init を除いた Linux プロセスはすべて、環境 (例: PATH 変数)[1] および親プロセスのその他特定の属性 (例: オープンファイル記述子) を継承します。

cgroup モデル

cgroup は、以下のような点でプロセスと類似しています:
  • 階層型である
  • 子 cgroup は、親 cgroup から特定の属性を継承する
根本的な相違点は、cgroup の場合には、多数の異なる階層がシステム上に同時に存在可能であることです。Linux プロセスモデルが単一のプロセスツリーとすれば、cgroup モデルは、単一もしくは複数の異なる、連結されていないタスクツリー (すなわちプロセス)ということになります。
cgroups の複数の分離した階層が必要なのは、各階層が 単一または複数の サブシステム に接続されていることが理由です。サブシステム[2] とは、CPU 時間やメモリーなどの単一のリソースを指します。Fedora 16 は、9 つの cgroup サブシステムを提供しています。それらの名前と機能は、以下のとおりです。
Fedora で利用可能なサブシステム
  • blkio — このサブシステムは、物理ドライブ (例: ディスク、ソリッドステート、USB) などのブロックデバイスへの入力およびブロックデバイスからの出力のアクセスの制限を設定します。
  • cpu — このサブシステムは、スケジューラを使用して cgroup タスクに CPU へのアクセスを提供します。
  • cpuacct — このサブシステムは、cgroup 内のタスクで使用される CPU リソースについての自動レポートを生成します。
  • cpuset — このサブシステムは、個別の CPU (マルチコアシステム上) およびメモリーノードを cgroup 内のタスクに割り当てます。
  • devices — このサブシステムは、cgroup 内のタスクによるデバイスへのアクセスを許可または拒否します。
  • freezer — このサブシステムは、cgroup 内のタスクを一時停止または再開します。
  • memory — このサブシステムは、cgroup 内のタスクによって使用されるメモリーに対する制限を設定し、それらのタスクによって使用されるメモリーリソースについての自動レポートを生成します。
  • net_cls — このサブシステムは、Linux トラフィックコントローラ (tc) が特定の cgroup から発信されるパケットを識別できるようにするクラス識別子 (classid) を使用して、ネットワークパケットにタグを付けます。
  • nsnamespace サブシステム。

サブシステムは、リソースコントローラという別名でも知られています

man ページやカーネルのドキュメントなど、cgroup に関連した資料で リソースコントローラ または単に コントローラ という用語が使用されている場合があります。これらの 2 つの用語は、subsystemと同じ意味です。これは、サブシステムが通常リソースのスケジュールを行ったり、サブシステムが接続されている階層内の cgroups に対する制限を適用したりすることが理由で、このように呼ばれています。
サブシステム (リソースコントローラ) の定義は、極めて大まかで、タスクグループ (すなわちプロセス) に基づいて動作するものとされています。

1.2. サブシステム、階層、Control Group、タスクの関係

cgroup の用語においては、システムプロセスはタスクと呼ばれることを念頭に置いてください。
ではここで、サブシステム、cgroup の階層、およびタスクの間における関係を管理するにあたってのいくつかの簡単なルールとそれらのルールがもたらす影響について説明しましょう。

ルール 1

単一階層には、単一または複数のサブシステムを接続することができます。
このため、cpu および memory のサブシステム (もしくは任意数のサブシステム) を単一階層に接続できます。ただし、それぞれが他の階層に接続されていないことが条件となります(ルール2を参照)。
ルール 1
単一階層には、単一または複数のサブシステムを接続することができます。
図1.1 ルール 1

ルール 2

単一サブシステム (例: cpu) はいずれも、一つの階層にしか接続できません。
このため、cpu および memory のサブシステム (もしくは任意数のサブシステム) を単一階層に接続できます。ただし、それぞれが他の階層に接続されていないことが条件となります。
ルール 2—丸付き数字はサブシステムが接続される時系列を表します。
単一サブシステムを複数の階層に接続する。
図1.2 ルール 2—丸付き数字はサブシステムが接続される時系列を表します。

ルール 3

システムに新たな階層が作成されると、システム上の全タスクは最初に、その階層のデフォルトの cgroup のメンバーとなります。これは、root cgroup としても知られています。作成した単一階層ではいずれも、システム上の各タスクは、その階層内で 正確に一つの cgroup のメンバーにすることができます。cgroup がそれぞれ異なる階層にあるならば、単一のタスクを複数の cgroups のメンバーとすることが可能となります。タスクが同じ階層内の第 2 の cgroup のメンバーとなると、タスクはその階層内の第 1 の cgroup から即時に削除されます。タスクが同じ階層内の異なる 2 つの cgroup のメンバーとなることはありません。
このため、cpumemory のサブシステムが cpu_and_mem という名前の階層に接続されて、net_cls サブシステムが net という名前の階層に接続された場合、稼働中の httpd プロセスは、cpu_and_mem 内の任意の単一 cgroup、および、net 内の 任意の単一 cgroup のメンバーとすることができます。
httpd プロセスがメンバーとなっている cpu_and_mem 内の cgroup によって、CPU 時間が、他のプロセスに割り当てられた時間の半分に制限され、メモリー使用量が最大で 1024 MB に限定される可能性があります。また、メンバーとなっている net 内の cgroup によって、転送速度が 30 メガバイト毎秒に制限される場合があります。
第 1 の階層が作成されると、そのシステム上の全タスクは、最低でも 1 つの cgroup (root cgroup) のメンバーとなります。このため、cgroup を使用すると、常にシステムタスクは、最低でも一つの cgroup のメンバーとなります。
ルール 3
タスクは同じ階層にある2つの異なる cgroup のメンバーになることができません。
図1.3 ルール 3

ルール 4

システム上のいずれかのプロセス (タスク) が自分自身をフォークすると、子プロセス (タスク) が作成されます。子タスクは、自動的に、親がメンバーとなっているすべての cgroup のメンバーとなります。この後で、子タスクは、必要に応じて、異なる cgroup に移動することができますが、最初は必ず親タスクの cgroup (プロセス用語では「環境」という) を継承します。
この結果として、cpu_and_mem 階層内の half_cpu_1gb_max という名前の cgroup と、net 階層内の trans_rate_30 という cgroup のメンバーである httpd タスクについて検討してみましょう。 この httpd プロセスが自己をフォークすると、その子プロセスは自動的に half_cpu_1gb_max cgroup と trans_rate_30 cgroup のメンバーとなり、親タスクが属するのとまったく同じ cgroup を継承します。
それ以降には、親タスクと子タスクは完全に相互に独立した状態となり、一方のタスクが属する cgroup を変更しても他方のタスクには影響を及ぼしません。また、親タスクの cgroup を変更しても、孫タスクへも一切影響はありません。つまり、子タスクはいずれも、最初は親タスクとまったく同じ cgroup へのメンバーシップを継承しますが、これらのメンバーシップは後で変更もしくは削除することができるということになります。
ルール 4—丸付き数字はサブシステムが接続される時系列を表します。
fork したタスクはその親の cgroup プロパティを継承します。
図1.4 ルール 4—丸付き数字はサブシステムが接続される時系列を表します。

1.3. リソース管理の影響

  • タスクは、単一の階層内では一つの cgroup のみにしか属すことができないため、任意の単一サブシステムによってタスクが制限されたり、影響を受ける状況は一つのみということになります。これは、制限ではなく特長であり、論理にかなっています。
  • 単一階層内の全タスクに影響を及ぼすように、複数のサブシステムをまとめてグループ化することができます。その階層内の cgroup には異なるパラメータが設定されているため、これらのタスクが受ける影響が異なってきます。
  • 場合によっては、階層の リファクタリング が必要となることがあります。例えば、複数のサブシステムが接続された階層からサブシステムを削除したり、新たな別の階層に接続する場合などです。
  • 逆に言えば、別個の階層間でサブシステムを分割する必要性が低減すると、階層を削除して、そのサブシステムを既存の階層に接続することができるということになります。
  • この設計により、cpuメモリー のサブシステムが接続されているような、単一階層内の特定のタスクに対していくつかのパラメータを設定するなど、簡易 cgroup の使用が可能となります。
  • この設計により、高度に特化した構成も可能となり、システム上の各タスク (プロセス) は、単一のサブシステムが接続された各階層のメンバーとすることができます。このような構成では、システム管理者があらゆるタスクの全パラメータを全面的に管理することができます。


[1] 親プロセスは、子プロセスに受け渡す前に環境を変更することが可能。
[2] libcgroup の man ページおよびその他のドキュメントでは、サブシステムが リソースコントローラ もしくは単に コントローラ とも呼ばれることを認識しておく必要があります。

第2章 Control Group の使用法

The easiest way to work with cgroups is to install the libcgroup-tools package, which contains a number of cgroup-related command line utilities and their associated man pages. It is possible to mount hierarchies and set cgroup parameters (non-persistently) using shell commands and utilities available on any system. However, using the libcgroup-tools-provided utilities simplifies the process and extends your capabilities. Therefore, this guide focuses on libcgroup-tools commands throughout. In most cases, we have included the equivalent shell commands to help describe the underlying mechanism. However, we recommend that you use the libcgroup-tools commands wherever practical.

Installing the libcgroup-tools package

In order to use cgroups, first ensure the libcgroup-tools package is installed on your system by running, as root:
~]# yum install libcgroup-tools

2.1. cgconfig サービス

The cgconfig service installed with the libcgroup-tools package provides a convenient way to create hierarchies, attach subsystems to hierarchies, and manage cgroups within those hierarchies. We recommend that you use cgconfig to manage hierarchies and cgroups on your system.
The cgconfig service is not started by default on Fedora 16. When you start the service with chkconfig, it reads the cgroup configuration file — /etc/cgconfig.conf. Cgroups are therefore recreated from session to session and become persistent. Depending on the contents of the configuration file, cgconfig can create hierarchies, mount necessary file systems, create cgroups, and set subsystem parameters for each group.
The default /etc/cgconfig.conf file installed with the libcgroup-tools package creates and mounts an individual hierarchy for each subsystem, and attaches the subsystems to these hierarchies.
cgconfig サービスを停止 (service cgconfig stop コマンドを使用) すると、マウントされていたすべての階層がアンマウントされます。

2.1.1. cgconfig.conf ファイル

/etc/cgconfig.conf ファイルには、mountgroup の2つの主要タイプエントリが含まれます。mount エントリは、仮想ファイルシステムとして階層を作成してマウントし、サブシステムをそれらの階層に接続します。mount エントリは、以下のような構文を用いて定義します。
mount {
    <controller> = <path>;
    …
}
使用例については、例2.1「mount エントリの作成」 を参照してください。
例2.1 mount エントリの作成
以下の例では、cpuset サブシステム用の階層を作成します。
mount {
    cpuset = /cgroup/red;
}
これに相当するシェルコマンドは以下の通りです。
~]# mkdir /cgroup/red
~]# mount -t cgroup -o cpuset red /cgroup/red

group エントリは cgroup を作成して、サブシステムパラメータをセットします。group エントリは、以下のような構文を使用して定義します。
group <name> {
    [<permissions>]
    <controller> {
        <param name> = <param value>;
        …
    }
    …
}
permissions セクションはオプションである点に注意してください。グループエントリのパーミッションを定義するには、以下のような構文を使用します。
perm {
    task {
        uid = <task user>;
        gid = <task group>;
    }
    admin {
       uid = <admin name>;
       gid = <admin group>;
    }
}
使用例については、例2.2「group エントリの作成」 を参照してください。
例2.2 group エントリの作成
以下の例では、sql デーモン用の cgroup を作成し、sqladmin グループのユーザーがタスクを cgroup に追加することができ、また root ユーザーがサブシステムのパラメータを変更できるパーミッションを設定します。
group daemons/sql {
    perm {
        task {
            uid = root;
            gid = sqladmin;
        } admin {
            uid = root;
            gid = root;
        }
    } cpu {
        cpu.shares = 100;
    }
}
例2.1「mount エントリの作成」 の mount エントリの例と組み合わせた場合に、相当するシェルコマンドは以下の通りです。
~]# mkdir -p /cgroup/cpu/daemons/sql
~]# chown root:root /cgroup/cpu/daemons/sql/*
~]# chown root:sqladmin /cgroup/cpu/daemons/sql/tasks
~]# echo 100 > /cgroup/cpu/daemons/sql/cpu.shares

変更内容を有効化するために cgconfig サービスを再起動する

/etc/cgconfig.conf への変更内容を有効化するには、cgconfig サービスを再起動する必要があります。
~]# systemctl restart cgconfig.service 
When you install the libcgroup-tools package, a sample configuration file is written to /etc/cgconfig.conf. The hash symbols ('#') at the start of each line comment that line out and make it invisible to the cgconfig service.

2.2. 階層の作成とサブシステムの接続

稼働中のシステムに及ぼす影響

以下に示した新規階層作成とサブシステム接続の手順は、ご使用のシステム上で cgroup がまだ設定されていないことを前提としています。その場合、これらの手順は、システム上の操作には影響を及ぼしません。しかし、タスクを持つ cgroup 内の調整可能なパラメータを変更すると、それらのタスクに直ちに影響を及ぼす可能性があります。本ガイドでは、単一もしくは複数のタスクに影響を及ぼす可能性がある調整可能な cgroup のパラメータの変更を初回に例示する際に警告します。
cgroup が設定済み (手動もしくは cgconfig サービスを使用して) のシステム上では、最初に既存の階層をアンマウントしておかないと、これらのコマンドは失敗し、システムの操作に影響を及ぼします。実稼働システム上ではこれらの手順を試さないようにしてください。
階層を作成して、サブシステムを接続するには、root として、/etc/cgconfig.conf ファイルの mount セクションを編集します。mount セクションのエントリは、以下のような形式になります。
subsystem = /cgroup/hierarchy;
cgconfig は次回の起動時に、階層を作成し、サブシステムを接続します。
以下の例は、cpu_and_mem という名前の階層を作成し、cpucpusetcpuacct、および memory のサブシステムを接続します。
mount {
    cpuset  = /cgroup/cpu_and_mem;
    cpu     = /cgroup/cpu_and_mem;
    cpuacct = /cgroup/cpu_and_mem;
    memory  = /cgroup/cpu_and_mem;
}

その他の方法

シェルコマンドとユーティリティを使用して、階層の作成とサブシステムの接続を行うこともできます。
root として、その階層用の マウントポイント を作成します。マウントポイントには、cgroupの名前を入れます。
~]# mkdir /cgroup/name
例:
~]# mkdir /cgroup/cpu_and_mem
次に、mount コマンドを使用して、階層をマウントし、同時に一つまたは複数のサブシステムを接続します。例えば:
~]# mount -t cgroup -o subsystems name /cgroup/name
ここで、subsystems は、コンマ区切りのサブシステム一覧で、また name は階層名です。利用可能な全サブシステムの簡単な説明はFedora で利用可能なサブシステム に記載しています。また 3章サブシステムと調整可能なパラメータ には詳しい参考情報を記載しています。
例2.3 mount コマンドを使用して、サブシステムを接続します。
この例では、/cgroup/cpu_and_mem という名前のディレクトリが既に存在しており、作成する階層のマウントポイントとして機能します。cpucpuset、および memory のサブシステムを cpu_and_mem と名付けた階層に接続した後、cpu_and_mem 階層を /cgroup/cpu_and_memmount します。
~]# mount -t cgroup -o cpu,cpuset,memory cpu_and_mem /cgroup/cpu_and_mem
You can list all available subsystems along with their current mount points (i.e. where the hierarchy they are attached to is mounted) with the lssubsys [3] command:
~]# lssubsys -am
cpu,cpuset,memory /cgroup/cpu_and_mem
net_cls
ns
cpuacct
devices
freezer
blkio
この出力は、以下のような内容を示しています。
  • cpucpuset、および memory のサブシステムは、/cgroup/cpu_and_mem にマウントされた階層に接続されています。
  • net_clsnscpuacctdevicesfreezer、および blkio のサブシステムは、対応するマウントポイントがないことから、まだ、どの階層にも接続されていないことを示しています。

2.3. 既存の階層へのサブシステムの接続と接続解除

サブシステムを既存の階層に追加するには、既存の階層から接続を解除するか、異なる階層に移動した上で、root として/etc/cgconfig.conf ファイルの mount セクションを 「階層の作成とサブシステムの接続」 に記載されているのと同じ構文を用いて編集します。cgconfig は、次回の起動時に、指定した階層にしたがってサブシステムを再編成します。

その他の方法

接続されていないサブシステムを既存の階層に追加するには、その階層を再マウントします。mount コマンドで、追加するサブシステムと remount オプションを指定します。
例2.4 階層を再マウントしてサブシステムを追加
lssubsys コマンドは、cpu_and_mem 階層に接続されている cpucpuset、および memory のサブシステムを表示します。
~]# lssubsys -am
cpu,cpuset,memory /cgroup/cpu_and_mem
net_cls
ns
cpuacct
devices
freezer
blkio
remount オプションを指定し、サブシステムの一覧に cpuacct を追加した上で、cpu_and_mem 階層を再マウントします。
~]# mount -t cgroup -o remount,cpu,cpuset,cpuacct,memory cpu_and_mem /cgroup/cpu_and_mem
lssubsys コマンドを実行すると、cpuacctcpu_and_mem 階層に接続されていると表示されるようになりました。
~]# lssubsys -am
cpu,cpuacct,cpuset,memory /cgroup/cpu_and_mem
net_cls
ns
devices
freezer
blkio

また同様に、階層を再マウントしてサブシステム名を -o オプションから削除することで、既存の階層からサブシステムの接続を解除することができます。例えば、cpuacct サブシステムの接続を解除するには、単に再マウントして名前を削除します。
~]# mount -t cgroup -o remount,cpu,cpuset,memory cpu_and_mem /cgroup/cpu_and_mem

2.4. 階層の接続解除

cgroup の階層を アンマウント するには、umount コマンドを使用します。
~]# umount /cgroup/name
例:
~]# umount /cgroup/cpu_and_mem
階層が現在空である場合 (つまり、root cgroup のみを格納している場合) には、階層はアンマウント時に非アクティブ化されます。階層に他の cgroup が含まれる場合には、階層はマウントされていなくても、カーネル内でアクティブな状態を維持します。
階層を削除するには、その階層をアンマウントする前に、すべての子 cgroup が削除されていることを確認してください。もしくは、cgclear コマンドを使用すると、空でない階層も非アクティブ化することができます — 「Control Group のアンロード」 を参照してください。

2.5. Control Group の作成

cgroups を作成するには cgcreate コマンドを使用します。cgcreate の構文は次のとおりです:
cgcreate -t uid:gid -a uid:gid -g subsystems:path
ここで:
  • -t (オプション) — ユーザー (ユーザー ID、uid) とグループ (グループ ID、gid) を指定して、この cgroup の tasks 疑似ファイルを所有するようにします。このユーザーは cgroup にタスクを追加することができます。

    タスクの削除

    cgroup からタスクを削除するには、異なる cgroup に移動するのが唯一の手段である点に注意してください。タスクを移動するには、ユーザーは 移動先の cgroup への書き込みアクセスが必要となります。元の cgroup への書き込みアクセスは重要ではありません。
  • -a (オプション) — ユーザー (ユーザー ID、uid) とグループ (グループ ID、gid) を指定して、このcgroup の tasks 以外の全疑似ファイルを所有するようにします。このユーザーは cgroup 内のタスクが持つシステムリソースへのアクセスを変更できます。
  • -g — cgroup が作成されるべき階層を、それらの階層に関連付けされる、コンマ区切りの subsystems 一覧として指定します。この一覧内のサブシステムが異なる階層にある場合には、それらの各階層内でグループが作成されます。階層の一覧の後には、コロンならびに階層に対して相対的な子グループへの path が続きます。このパスには、階層のマウントポイントを入れないでください。
    例えば、/cgroup/cpu_and_mem/lab1/ディレクトリ内に配置されている cgroup が単に lab1 という名前である場合でも、1 つのサブシステムに対して階層は 1 つしかないため、そのパスは既に一意に特定されていることになります。また、グループは、cgroup が作成された階層内に存在する全サブシステムによって制御される点にも注意してください。cgcreate コマンドでこれらのサブシステムが指定されていない場合でも変わりません。例2.5「cgcreate の使用方法」 を参照してください。
同じ階層内の cgroup はすべて同じコントローラを持つため、子グループは親グループと同じコントローラを持つことになります。
例2.5 cgcreate の使用方法
cpu および memory サブシステムが cpu_and_mem 階層に一緒にマウントされており、かつ net_cls コントローラが net という名前の別の階層にマウントされているシステムを想定して、以下のコマンドを実行します。
~]# cgcreate -g cpu,net_cls:/test-subgroup
cgcreate コマンドにより、test-subgroup という名前の 2 つのグループを作成します。一方は、cpu_and_mem 階層に、もう一方は net 階層に入ります。 cgcreate コマンドで指定してなくても、cpu_and_mem 階層内の test-subgroup グループは、 memory サブシステムによって制御されます。

その他の方法

cgroup の子を作成するには、mkdir コマンドを使用します:
~]# mkdir /cgroup/hierarchy/name/child_name
例:
~]# mkdir /cgroup/cpuset/lab1/group1

2.6. Control Group の削除

cgdelete で cgroup を削除します。この構文は、cgcreate の構文と似ています。以下のコマンドを実行します:
cgdelete subsystems:path
ここで:
  • subsystems は、コンマ区切りのサブシステム一覧です。
  • path は、階層の root に対して相対的な cgroup へのパスです。
例:
~]# cgdelete cpu,net_cls:/test-subgroup
cgdelete-r のオプションを使用すると、すべてのサブグループを再帰的に削除することもできます。
cgroup を削除すると、その cgroup のタスクは、親グループに移動します。

2.7. パラメータのセッティング

該当する cgroup を修正できるパーミッションを持つユーザーアカウントから、cgset コマンドで、サブシステムのパラメータをセットします。例えば、/cgroup/cpuset/group1 が存在する場合には、以下のようなコマンドで、このグループがアクセスできる CPU を指定します。
cpuset]# cgset -r cpuset.cpus=0-1 group1
cgset の構文は次のとおりです:
cgset -r parameter=value path_to_cgroup
ここで:
  • parameter はセットするパラメータで、特定の cgroup のディレクトリ内のファイルに対応しています。
  • value はパラメータ用の値です
  • path_to_cgroup階層の root に相対的な cgroup へのパスです。例えば、root グループのパラメータを設定するには、(/cgroup/cpuacct/ が存在する場合)、以下のコマンドを実行します。
    cpuacct]# cgset -r cpuacct.usage=0 /
    また、. は root グループ (つまり、root グループ自体) に対して相対的であるため、以下のコマンドを実行することもできます。
    cpuacct]# cgset -r cpuacct.usage=0 .
    ただし、/ は推奨の構文である点に注意してください。

    root グループにパラメータの

    root グループに設定できるパラメータはごくわずかです (例: 上記の例に示した、cpuacct.usage パラメータ)。これは、root グループが既存のリソースをすべて所有しており、特定のパラメータ (例: cpuset.cpu パラメータ) を定義することによって既存のプロセスを制限することは意味がないためです。
    root グループのサブグループである group1 のパラメータを設定するには、以下のコマンドを実行します。
    cpuacct]# cgset -r cpuacct.usage=0 group1
    グループ名の末尾のスラッシュ (例: cpuacct.usage=0 group1/) はオプションです。
cgset で設定できる値は、特定の階層のより高位で設定されている値によって左右される可能性があります。例えば、group1 がシステム上の CPU 0 のみを使用するように制限されている場合、group1/subgroup1 が CPU 0 および 1 を使用するように、もしくは CPU 1 のみを使用するようには設定できません。
また、cgset を使用して、異なる cgroup からパラメータをコピーすることもできます。例えば:
~]# cgset --copy-from group1/ group2/
cgset を用いてパラメーターをコピーするための構文は次のとおりです:
cgset --copy-from path_to_source_cgroup path_to_target_cgroup
ここで:
  • path_to_source_cgroup は、コピーするパラメータを持つ、その階層の root グループに対して相対的な cgroup へのパスです。
  • path_to_target_cgroup は、その階層の root グループに対して相対的な、コピー先 cgroup へのパスです。
一つのグループから別のグループにパラメータをコピーする前には、様々なサブシステムの必須パラメータが設定済みであることを確認してください。必須パラメータが設定されていない場合にはコマンドが失敗してしまいます。必須パラメータに関する詳しい情報は、 必須のパラメータ を参照してください。

その他の方法

cgroup ディレクトリ内のパラメータをセットするには、echo コマンドを使用して その値を該当するサブシステムの疑似ファイルに書き込みます。例えば、以下のコマンドは、値 0-1 を cgroup group1cpuset.cpus 疑似ファイルに 書き込みます。
~]# echo 0-1 > /cgroup/cpuset/group1/cpuset.cpus
この値を入れると、この cgroup のタスクはシステム上の CPU 0 と 1 に限定されます。

2.8. Control Group へのプロセス移動

cgclassify コマンドを実行して、プロセスを cgroup に移動します。
~]# cgclassify -g cpu,memory:group1 1701
cgclassify の構文は次のとおりです:
cgclassify -g subsystems:path_to_cgroup pidlist
ここで:
  • subsystems は、コンマ区切りのサブシステム一覧、または、利用可能なすべてのサブシステムに関連付けされた階層内のプロセスを起動するための * とします。同じ名前の cgroup が複数の階層に存在する場合には、-g オプションを指定すると、それらの各グループ内にプロセスが移動される点に注意してください。ここで指定するサブシステムの各階層内に cgroup が存在していることを確認してください。
  • path_to_cgroup は、その階層内の cgroup へのパスです
  • pidlist は、プロセス識別子 (PID) のスペースで区切られた一覧です。
また、pid の前に -- sticky オプションを付けて、同じ cgroup の子プロセスを保持することもできます。このオプションをセットしないで cgred デーモンが 稼働していると、子プロセスは /etc/cgrules.conf にあるセッティングに基づいて cgroup に割り当てられますが、プロセス自体はそれを開始した cgroup 内に残ります。
cgclassify を使用すると、いくつかのプロセスを同時に移動することができます。例えば、以下のコマンドは 17011138 の PID を持つプロセスを cgroup group1/ に移動します:
~]# cgclassify -g cpu,memory:group1 1701 1138
移動する PID は、スペースで区切り、また指定したグループは異なる階層内にある必要がある点に注意してください。

その他の方法

プロセスを cgroup のディレクトリに移動するには、その PID を cgroup の tasks ファイルに 書き込みます。例えば、PID 1701 の付いたプロセスを /cgroup/lab1/group1/ にある cgroup に 移動する場合は、以下のコマンドを実行します。
~]# echo 1701 > /cgroup/lab1/group1/tasks

2.8.1. cgred デーモン

cgred は、/etc/cgrules.conf ファイル内にセットされたパラメータセットにしたがってタスクを cgroup に移動するデーモンです。/etc/cgrules.conf ファイル内のエントリは、次の2つの形式のいずれかとなります。
  • user hierarchies control_group
  • user:command hierarchies control_group
例:
maria			devices		/usergroup/staff
このエントリは、maria というユーザーに属するプロセスはいずれも、/usergroup/staff cgroup 内に指定されたパラメータにしたがってデバイスサブシステムにアクセスすることを指定します。特定のコマンドを特定の cgroup に関連付けるには、以下のようにして command パラメータを追加します。
maria:ftp		devices		/usergroup/staff/ftp
このエントリにより、maria という名前のユーザーが ftp コマンドを使用する時には、devices サブシステムが入っている階層の /usergroup/staff/ftp cgroup へプロセスが自動的に移動するように指定されるようになります。 ただし、このデーモンは、該当する条件が満たされている場合にのみ、プロセスを cgroup に移動する点に注意してください。このため、ftp プロセスが、誤ったグループで短時間実行される可能性があります。また、そのプロセスが誤ったグループ内にある間に子プロセスが急速に発生した場合には、それらは移動されない可能性があります。
/etc/cgrules.conf ファイル内のエントリには、以下のような表記を追加することが可能です。
  • @user にプレフィックスを付けた場合には、個別のユーザーではなくグループを示します。 例えば、@adminsadmins グループ内のすべてのユーザーです。
  • * — 「すべて」を示します。例えば、subsystem フィールド内の * は全サブシステムを示します。
  • % — その上の行の項目と同じ項目を示します。例えば:
    @adminstaff		devices		/admingroup
    @labstaff		%		%
    

2.9. Control Group 内のプロセスの開始

必須のパラメータ

サブシステムによっては、それらのサブシステムのいずれかを使用する cgroup にタスクを移動できる前に設定しておく必要のある必須パラメータがあります。例えば、cpuset サブシステムを使用する cgroup にタスクを移動する前には、その cgroup に対して、cpuset.cpuscpuset.mems のパラメータを定義する必要があります。
このセクション内の例は、コマンド用の正しい構文を示していますが、これは例の中で使用されているコントローラ用に関連した 必須パラメータをセットしているシステム上でのみ機能します。関連したコントローラをまだ設定していない場合は、このセクションから サンプルコマンドを直接コピーしても自分のシステム上で機能させることは期待できません。
特定のサブシステムでそのパラメータが必須であるかについては、3章サブシステムと調整可能なパラメータ を参照してください。
cgexec コマンドを実行して、cgroup 内のプロセスを開始することもできます。例えば、 以下のコマンドは、そのグループに課せられた制限にしたがって、group1 cgroup 内で lynx Web ブラウザを起動します。
~]# cgexec -g cpu:group1 lynx http://www.redhat.com
cgexec の構文は次のとおりです:
cgexec -g subsystems:path_to_cgroup command arguments
ここで:
  • subsystems は、コンマ区切りのサブシステム一覧、または、利用可能なすべてのサブシステムに関連付けされた階層内のプロセスを起動するための * とします。「パラメータのセッティング」 でも説明しているように、同じ名前の cgroup が複数の階層に存在する場合には、-g オプションを指定すると、それらの各グループ内にプロセスが作成される点に注意してください。ここで指定するサブシステムの各階層内に cgroup が存在していることを確認してください。
  • path_to_cgroup は、階層に対して相対的な cgroup へのパスです。
  • command は実行するコマンドです。
  • arguments はコマンドのすべての引数です。
command の前に -- sticky オプションを追加すると、同じ cgroup の子プロセスを維持することもできます。このオプションをセットしないで cgred が稼働すると、子プロセスは /etc/cgrules.conf にあるセッティングに基づいて cgroup に割り当てられます。しかし、 プロセス自体はそれを開始した cgroup 内に残ります。

その他の方法

新たなプロセスを開始すると、そのプロセスは、親プロセスのグループを継承します。このため、特定の cgroup でプロセスを開始するもう一つの方法として、シェルプロセスをそのグループに移動し (「Control Group へのプロセス移動」 を参照)、そのシェルからプロセスを起動することができます。例えば:
~]# echo $$ > /cgroup/lab1/group1/tasks
lynx
lynx を終了したあとには、既存のシェルは依然として group1 cgroup にあることに注意してください。したがって、より適切な方法は以下のようになります。
~]# sh -c "echo \$$ > /cgroup/lab1/group1/tasks && lynx"

2.9.1. Control Group 内のサービスの開始

cgroup 内の特定のサービスを起動することができます。cgroup 内で起動できるサービスは、以下の条件を満たしている必要があります。
  • /etc/sysconfig/servicename ファイルを使用する
  • サービスを起動するのに /etc/init.d/functionsdaemon() 関数を使用する
cgroup 内で条件に適合したサービスを開始するには、/etc/sysconfig 内でそのサービスのファイルを編集して、 CGROUP_DAEMON="subsystem:control_group" の 形式でエントリを追加します。ここで、subsystem は特定の階層に関連付けされたサブシステムであり、 control_group はその階層内の cgroup です。例えば:
CGROUP_DAEMON="cpuset:daemons/sql"

2.9.2. Root Control Group 内のプロセスの振る舞い

blkio および cpu の特定の設定オプションは、ルート cgroup において実行しているプロセス(タスク)に、サブグループにおけるものと異なる方法で影響します。以下の例を検討します:
  1. あるルートグループの下に二つのサブグループを作成します: /rootgroup/red/ および /rootgroup/blue/
  2. 各サブグループおよびルートグループにおいて、cpu.shares 設定オプションを定義し、1 に設定します。
上で設定されたシナリオにおいて、各グループにおかれた一つのプロセス(つまり、/rootgroup/tasks, /rootgroup/red/tasks および /rootgroup/blue/tasks におかれた一つのタスク)は CPU を 33.33% 消費することになります:
/rootgroup/ process:      33.33%
/rootgroup/blue/ process: 33.33%
/rootgroup/red/ process:  33.33%
サブグループ blue および red に置かれた他のプロセスはすべて、そのサブグループにおいて複数のプロセスの間で分けるために特定のサブグループに割り当てられている、CPU の 33.33% という結果になります。
しかし、ルートグループに置かれた複数のプロセスは、グループごとではなく、プロセスごとに CPU リソースを分け合うことになります。たとえば、/rootgroup/ に3つのプロセス、/rootgroup/red/ に1つのプロセス、/rootgroup/blue/ に1つのプロセスがあり、すべてのグループにおいて cpu.shares オプションが 1 に設定されていると、CPU リソースは以下のように分けられます:
/rootgroup/ processes:    20% + 20% + 20%
/rootgroup/blue/ process: 20%
/rootgroup/red/ process:  20%
そのため、利用可能な資源を重みや配分に基づいて分割する blkio および cpu 設定オプション(たとえば、cpu.shares または blkio.weight)を使用するとき、すべてのプロセスをルートグループから特定のサブグループに移動することを推奨します。すべてのプロセスをルートグループから特定のサブグループに移動するには、以下のコマンドを使用できます:
rootgroup]# for i in `cat tasks`; do echo $i > red/tasks; done

2.10. /etc/cgconfig.conf ファイルの生成

/etc/cgconfig.conf ファイルの設定は cgsnapshot ユーティリティを使用して、現在の cgroup 設定から生成することができます。このユーティリティは、すべてのサブシステムの現在の状態およびそれらの cgroups のスナップショットをとり、それらの設定を /etc/cgconfig.conf ファイルに表現されるように返します。例2.6「cgsnapshot ユーティリティの使用法」cgsnapshot ユーティリティの使用例を示します。
例2.6 cgsnapshot ユーティリティの使用法
以下のコマンドを使用してシステムにおいて cgroups を設定したと仮定します:
~]# mkdir /cgroup/cpu
~]# mount -t cgroup -o cpu cpu /cgroup/cpu
~]# mkdir /cgroup/cpu/lab1
~]# mkdir /cgroup/cpu/lab2
~]# echo 2 > /cgroup/cpu/lab1/cpu.shares
~]# echo 3 > /cgroup/cpu/lab2/cpu.shares
~]# echo 5000000 > /cgroup/cpu/lab1/cpu.rt_period_us
~]# echo 4000000 > /cgroup/cpu/lab1/cpu.rt_runtime_us
~]# mkdir /cgroup/cpuacct
~]# mount -t cgroup -o cpuacct cpuacct /cgroup/cpuacct
上のコマンドにより cpu サブシステムに対して、いくつかのパラメーターに対する特定の値を持つ、2つのサブシステムをマウントして2つの cgroups を作成しました。そして、cgsnapshot コマンドを(with the -s オプションおよび空の /etc/cgsnapshot_blacklist.conf ファイル[4]とともに)実行することにより以下の出力が生成されます:
~]$ cgsnapshot -s
# Configuration file generated by cgsnapshot
mount {
        cpu = /cgroup/cpu;
        cpuacct = /cgroup/cpuacct;
}

group lab2 {
        cpu {
                cpu.rt_period_us="1000000";
                cpu.rt_runtime_us="0";
                cpu.shares="3";
        }
}

group lab1 {
        cpu {
                cpu.rt_period_us="5000000";
                cpu.rt_runtime_us="4000000";
                cpu.shares="2";
        }
}
上の例において使用されている -s オプションは、cgsnapshot ユーティリティのブラックリストまたはホワイトリストに定義されていないパラメーターにより引き起こされる、出力ファイルにおけるすべての警告を無視するよう cgsnapshot に指示しています。ブラックリストに関する詳細は「パラメータのブラックリスト化」を参照してください。ホワイトリストに関する詳細は「パラメータのホワイトリスト化」を参照してください。

何もオプションを指定していないとき、cgsnapshot により生成された出力は標準出力に返されます。出力をリダイレクトするためのファイルを指定するには -f を使用します:
~]$ cgsnapshot -f ~/test/cgconfig_test.conf

-f オプションは指定されたファイルを上書きします

-f オプションを使用するとき、指定したファイルにある内容をすべて上書きすることに注意してください。そのため、/etc/cgconfig.conf ファイルに直接そのまま出力することは控えるようお勧めします。
cgsnapshot ユーティリティはサブシステムごとに設定ファイルを作成することもできます。サブシステムの名前を指定することにより、出力はサブシステムに対応する設定から構成されます:
~]$ cgsnapshot cpuacct
# Configuration file generated by cgsnapshot
mount {
        cpuacct = /cgroup/cpuacct;
}

2.10.1. パラメータのブラックリスト化

cgsnapshot ユーティリティはパラメーターのブラックリスト化を許可します。パラメーターがブラックリスト化されていると、cgsnapshot により生成される出力に表示されません。デフォルトで、/etc/cgsnapshot_blacklist.conf ファイルがブラックリストのパラメーターのためにチェックされます。パラメーターがブラックリストになければ、ホワイトリストがチェックされます。他のブラックリストを指定するには、-b オプションを使用します。たとえば:
~]$ cgsnapshot -b ~/test/my_blacklist.conf

2.10.2. パラメータのホワイトリスト化

cgsnapshot ユーティリティはパラメーターのホワイトリスト化も許可します。パラメーターがホワイトリスト化されていると、cgsnapshot により生成される出力に表示されます。パラメーターがブラックリストにもホワイトリストにもなければ、このことを知らせる警告が表示されます:
~]$ cgsnapshot -f ~/test/cgconfig_test.conf
WARNING: variable cpu.rt_period_us is neither blacklisted nor whitelisted
WARNING: variable cpu.rt_runtime_us is neither blacklisted nor whitelisted
デフォルトで、ホワイトリストの設定ファイルはありません。ホワイトリストとして使用するためのファイルを指定するには、-w オプションを使用します。たとえば:
~]$ cgsnapshot -w ~/test/my_whitelist.conf
-t オプションを指定することにより、ホワイトリストからのパラメーターのみを持つ設定を生成するよう cgsnapshot に指示します。

2.11. Control Group に関する情報の取得

2.11.1. プロセスの確認

プロセスが属する cgroup を確認するには以下のコマンドを実行します:
~]$ ps -O cgroup
また、プロセスの PID がわかっている場合は、以下のコマンドを実行します:
~]$ cat /proc/PID/cgroup

2.11.2. サブシステムの確認

カーネルで使用可能なサブシステムおよびそれらがどのようにして階層にまとめてマウントされているかを確認するには、以下のコマンドを実行します。
~]$ cat /proc/cgroups
また、特定のサブシステムのマウントポイントを確認するには、以下のコマンドを実行します。
~]$ lssubsys -m subsystems
subsystems は、対象となるサブシステムの一覧です。lssubsys -m コマンドでは、各階層ごとの最上位のマウントポイントのみが返される点に注意してください。

2.11.3. 階層の確認

/cgroup 下に階層をマウントすることを推奨します。ご使用のシステムがそのような状態であることを前提として、そのディレクトリの内容を一覧表示もしくはブラウズします。tree がシステムにインストールされている場合には、このコマンドを実行して、階層およびそれらの中にある cgroup の概要を取得します。
~]$ tree /cgroup/

2.11.4. Control Group の確認

システム上の cgroup を一覧表示するには、以下のコマンドを実行します。
~]$ lscgroup
controller:path の形式でコントローラとパスを指定すると、特定の階層への出力を限定することができます。例えば:
~]$ lscgroup cpuset:adminusers
cpuset サブシステムが接続されている階層内の adminusers cgroup のサブグループのみを一覧表示します。

2.11.5. Control Group のパラメータの表示

特定の cgroup のパラメータを表示するには、以下のコマンドを実行します。
~]$ cgget -r parameter list_of_cgroups
ここで parameter は、サブシステムの値を含んだ擬似ファイルで、list_of_cgroups は cgroup のスペース区切りの一覧です。例えば:
~]$ cgget -r cpuset.cpus -r memory.limit_in_bytes lab1 lab2
cgroup lab1 および lab2cpuset.cpus 値と memory.limit_in_bytes 値を表示します。
パラメータ自体の名前がわからない場合には、以下のようなコマンドを使用してください。
~]$ cgget -g cpuset /

2.12. Control Group のアンロード

このコマンドは、すべての Control Group を破棄してしまいます

cgclear コマンドにより、全階層内のすべての cgroup が破棄されます。これらの階層が設定ファイル内に記載されていない場合は、簡単には再構築できません。
cgroup ファイルシステム全体を消去するには、cgclear コマンドを使用します。
cgroup 内のタスクはすべて、階層内の root ノードに再割り当てされ、全 cgroup が削除され、ファイルシステム自体が システムからアンマウントされます。したがって、以前にマウントされていた階層をすべて破棄することになります。最後に、cgroup ファイルシステムがマウントされていたディレクトリが実際に削除されます。

マウントされたすべての cgroups の正確な一覧化

mount コマンドを使用して cgroup を作成すると (cgconfig サービスを使用して作成した場合とは対照的に) /etc/mtab ファイル (マウントされているファイルシステムのテーブル) にエントリが追加されます。 この変更は、/proc/mounts ファイルにも反映されます。しかし、 cgclear コマンドやその他の cgconfig コマンドを使用して cgroup をアップロードする場合には、直接のカーネルインターフェースが使用され、/etc/mtab ファイルには変更が反映されず、/proc/mounts ファイル内に新たな情報が書き込まれるだけとなります。 このため、cgclear コマンドで cgroup をアップロードした後でも、アンマウント済みのグループが /etc/mtab ファイル内に依然として表示されている可能性があり、その結果、mount コマンドの実行時に表示される可能性があります。マウントされているすべての cgroup の正確な一覧を確認するには、 /proc/mounts ファイルを参照することをお勧めします。

2.13. その他のリソース

The definitive documentation for cgroup commands are the manual pages provided with the libcgroup-tools package. The section numbers are specified in the list of man pages below.
The libcgroup-tools Man Pages
  • man 1 cgclassifycgclassify コマンドは、実行中のタスクを単一もしくは複数の cgroup に移動するのに使用します。
    man 1 cgclearcgclear コマンドは、一つの階層内のすべての cgroup を削除するのに使用します。
    man 5 cgconfig.conf — cgroup は cgconfig.conf ファイル内で定義されます。
    man 8 cgconfigparsercgconfigparser コマンドは、cgconfig.conf ファイルを解析して、階層をマウントします。
    man 1 cgcreatecgcreate コマンドは階層内に新たな cgroup を作成します。
    man 1 cgdeletecgdelete コマンドは、特定の cgroup を削除します。
    man 1 cgexeccgexec コマンドは特定の cgroup 内のタスクを実行します。
    man 1 cggetcgget コマンドは、cgroup のパラメータを表示します。
    man 1 cgsnapshotcgsnapshot コマンドは、既存のサブシステムから設定ファイルを生成します。
    man 5 cgred.confcgred.conf は、cgred サービスの設定ファイルです。
    man 5 cgrules.confcgrules.conf には、特定の cgroup にタスクが属する場合に判断するためのルールが含まれます。
    man 8 cgrulesengdcgrulesengd サービスは、タスクを cgroup に配分します。
    man 1 cgsetcgset コマンドは、cgroup のパラメータを設定します。
    man 1 lscgrouplscgroup コマンドは、階層内の cgroup を一覧表示します。
    man 1 lssubsyslssubsys コマンドは、特定のサブシステムを含む階層を一覧表示します。


[3] The lssubsys command is one of the utilities provided by the libcgroup-tools package. You must install libcgroup-tools to use it: refer to 2章Control Group の使用法 if you are unable to run lssubsys.
[4] cpu.shares パラメーターはデフォルトで /etc/cgsnapshot_blacklist.conf ファイルに指定されます、これは例2.6「cgsnapshot ユーティリティの使用法」で生成された出力において省略されています。このように、例の目的のために、空の /etc/cgsnapshot_blacklist.conf ファイルが使用されます。

第3章 サブシステムと調整可能なパラメータ

Subsystems とは、cgroup を認識するカーネルモジュールで、通常は、異なるレベルのシステムリソースを異なる cgroup に割り当てるリソースコントローラです。ただし、サブシステムは、プロセスグループによって異なった扱いをする必要がある場合に、カーネルとのその他のインタラクション用にプログラムすることも可能です。新規サブシステムを開発するための アプリケーションプログラミングインターフェース (API) については、ご使用のシステムの /usr/share/doc/kernel-doc-kernel-version/Documentation/cgroups/ にインストールされているカーネルの文書 cgroups.txt (kernel-doc パッケージにより提供) に記載されています。cgroup に関するドキュメントの最新バージョンは、オンラインでもご覧いただけます: http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt。ただし、最新版のドキュメントに記載されている機能は、ご使用のシステムにインストールされているカーネルで利用可能な機能と一致しない場合がある点に注意してください。
cgroup 用のサブシステムパラメータを含んでいる 状態オブジェクト (State object) は cgroup の仮想ファイルシステム内で 疑似ファイル (pseudofiles)として表示されます。これらの疑似ファイルは、シェルコマンドまたはそれに相当するシステムコールで操作することができます。例えば、cpuset.cpus は、cgroup によるアクセスが許可されている CPU を指定する疑似ファイルです。システム上で稼働する Web サーバー用の cgroup が /cgroup/cpuset/webserver である場合には、以下のコマンドを実行してください。
~]# echo 0,2 > /cgroup/cpuset/webserver/cpuset.cpus
上記のコマンドは、0,2 の値を cpuset.cpus 疑似ファイルに書き込むことにより、/cgroup/cpuset/webserver/tasks に記載されている PID のタスクがシステム上の CPU 0 と CPU 2 のみを使用するように限定します。

3.1. blkio

ブロック I/O (blkio) サブシステムは、cgroup 内のタスクによる、ブロックデバイス上の I/O へのアクセスを制御・監視します。これらの疑似ファイルに値を書き込むと、アクセスまたは帯域幅が限定され、またこれらの疑似ファイルから値を読み取ると、I/O 操作についての情報が提供されます。
blkio サブシステムは I/O へのアクセスを制御するために2つのポリシーを提供します:
  1. 比例ウェイト分割 — Completely Fair Queuing I/O スケジューラーにおいて実装されました、このポリシーによりウェイトを特定の cgroups に設定できます。各 cgroup はすべての予約された I/O 操作のセットパーセンテージ(cgroup のウェイトに依存します)を持つことを意味します。詳細は「比例ウェイト分割の設定オプション」を参照してください。
  2. I/O スロットリング (上限) — 特定のデバイスにより実行される I/O 操作数に対する上限を設定するために使用されます。デバイスは読み込みまたは書き込み操作の制限された割合を持てることを意味します。詳細は「I/O スロットリングの設定オプション」を参照してください。

バッファーされた書き込み操作

現在、ブロック I/O サブシステムはバッファーされた書き込み操作に対して機能しません。これは主に直接 I/O に照準を合わせていますが、バッファーされた読み込み操作に対して機能します。

3.1.1. 比例ウェイト分割の設定オプション

blkio.weight
デフォルトで cgroup に提供される ブロック I/O アクセスの相対的比率 (ウェイト) を 100 から 1000 の範囲内で指定します。この値は、特定のデバイスに対して、blkio.weight_device パラメータによってオーバーライドされます。例えば、ブロックデバイスにアクセスするためのデフォルトのウェイト 500 を cgroup に割り当てるには、以下のコマンドを実行します。
echo 500 > blkio.weight
blkio.weight_device
特定のデバイス上で cgroup に提供される IO アクセスの相対的比率 (ウェイト) を 100 から 1000 の範囲内で指定します。このパラメータの値は、指定したデバイスの blkio.weight パラメータの値をオーバーライドします。これらの値は、major:minor weight という形式と取り、majorminor は、http://www.kernel.org/doc/Documentation/devices.txt から入手可能な Linux Allocated Devices (別名 Linux Devices List) で指定されているデバイスタイプとノード番号となります。例えば、cgroup による /dev/sda へのアクセスに 500 のウェイトを割り当てるには、以下のコマンドを実行します。
echo 8:0 500 > blkio.weight_device
Linux Allocated Devices の表記では、8:0/dev/sda を示します。
blkio.time
cgroup が特定のデバイスに I/O アクセスを行った時間をレポートします。エントリは、majorminor、および time の 3 つのフィールドで構成されます。majorminorLinux Allocated Devices で指定されているデバイスタイプとノード番号、また time はミリ秒 (ms) 単位の時間です。
blkio.sectors
cgroup により、特定のデバイスとの間で転送されたセクターの数をレポートします。エントリは、majorminor、および sectors の 3 つのフィールドで構成されます。majorminorLinux Allocated Devices で指定されているデバイスタイプとノード番号、また sectors はセクター数です。
blkio.io_serviced
特定のデバイス上で cgroup によって実行された I/O 操作の回数をレポートします。エントリはmajorminoroperation、および bytes の 4 つのフィールドで構成されます。majorminorLinux Allocated Devices で指定されているデバイスタイプとノード数で、operation は操作のタイプ (readwritesync、または async)、number は操作回数を示します。
blkio.io_service_bytes
CFQスケジューラーにより見えるように、cgroup により特定のデバイス上で転送されたバイト数をレポートします。エントリは、majorminoroperation、および bytes の 4 つのフィールドで構成されます。majorminor は、Linux Allocated Devices で指定されているデバイスタイプとノード番号です。operation は操作のタイプ (readwritesync、または async) です。bytes は転送されたバイト数です。
blkio.io_service_time
cgroup により特定のデバイス上で行われる I/O 操作の要求がディスパッチされてから完了するまでの合計時間をレポートします。エントリは、majorminoroperation、および bytes の 4 つのフィールドで構成されます。majorminor は、Linux Allocated Devices で指定されているデバイスタイプとノード番号です。operation は操作のタイプ (readwritesync、または async)、time は時間をナノ秒 (ns) 単位で示します。時間は、大きな単位ではなく、ナノ秒単位でレポートされるため、ソリッドステートのデバイスでもレポートが有意となります。
blkio.io_wait_time
スケジューラキュー内のサービスを待つのに費した、cgroup による 特定のデバイス上の I/O 操作の合計時間をレポートします。このレポートを解析する際には、以下の点に注意してください。
  • レポートされる時間は、cgroup 自体が I/O 操作を待つのに費した時間ではなく、cgroup の全 I/O 操作の累計であるため、経過時間の合計よりも長い場合があります。グループ全体として費した待ち時間を確認するには、blkio.group_wait_time を使用します。
  • デバイスに queue_depth > 1 がある場合は、レポートされる時間には、デバイスが要求を並べ替える間に費した待ち時間ではなく、要求がデバイスにディスパッチされるまでの時間のみが含まれます。
エントリは、majorminoroperation、および time の 4 つのフィールドで構成されます。majorminor は、Linux Allocated Devices で指定されているデバイスタイプとノード番号です。operation は、操作のタイプ (readwritesync、または async)、time はナノ秒 (ns) 単位の時間を示します。時間は、大きな単位ではなく、ナノ秒単位でレポートされるため、ソリッドステートのデバイスでもレポートが有意となります。
blkio.io_merged
cgroup により、I/O 操作要求にマージされた、BIOS 要求数をレポートします。エントリは numberoperation の 2 つのフィールドで構成されます。number は、要求数、operation は操作のタイプ (readwritesync、または async) を示します。
blkio.io_queued
cgroupt により、I/O 操作のキューに入れられた要求の数をレポートします。エントリは、numberoperation の 2 つのフィールドで構成されます。number は、要求数、operation は操作のタイプ (readwritesync、または async) を示します。
blkio.avg_queue_size
グループ存在の全時間にわたる、cgroup による I/O 操作の平均キューサイズをレポートします。キューサイズは、この cgroup がタイムスライスを取得する度にサンプリングされます。このレポートは、システム上で CONFIG_DEBUG_BLK_CGROUP=y が設定されている場合のみ利用可能である点に注意してください。
blkio.group_wait_time
cgroup が一つのキューで費した待ち時間の合計を (ナノ秒単位 — ns で) レポートします。レポートは、この cgroup がタイムスライスを取得する度に更新されるので、cgroup がタイムスライスを待っている間にこの疑似ファイルを読んだ場合には、現在キューに入っている操作を待つのに費した時間は含まれません。このレポートは、システム上でCONFIG_DEBUG_BLK_CGROUP=y が設定されている場合のみ利用可能である点に注意してください。
blkio.empty_time
cgroup が保留中の要求なしに費した時間の合計を (ナノ秒単位 — ns で) レポートします。レポートは、保留中の要求がこの cgroup のキューに入る度に更新されるので、cgroup に保留中の要求がない時に疑似ファイルを読んだ場合には、現在の空の状態で費した時間はレポートには含まれません。このレポートは、システム上で CONFIG_DEBUG_BLK_CGROUP=y が設定されている場合のみ利用可能である点に注意してください。
blkio.idle_time
すでにキューに入っている別の要求や別のグループからの要求よりも高い要求に備えて、cgroup に対してスケジューラがアイドリング状態で費した時間の合計を (ナノ秒単位 — ns で) レポートします。レポートは、グループがアイドリング状態でなくなった時点で毎回更新されるため、cgroup がアイドリング状態の間にこの疑似ファイルを読んだ場合には、現在のアイドリング状態で費した時間はレポートには含まれません。このレポートは、システム上で CONFIG_DEBUG_BLK_CGROUP=y が設定されている場合のみ利用可能である点に注意してください。
blkio.dequeue
cgroup が I/O 操作を要求した回数をレポートします。エントリは、majorminor、および number の 3 つのフィールドで構成されます。majorminor は、Linux Allocated Devices で指定されているデバイスタイプとノード番号です。number は、グループがキューから削除された要求の回数です。このレポートは、システム上で CONFIG_DEBUG_BLK_CGROUP=y が設定されている場合のみ利用可能である点に注意してください。

3.1.2. I/O スロットリングの設定オプション

blkio.throttle.read_bps_device
デバイスが実行できる読み込み操作数の上限を指定します。読み込み操作の割合は秒あたりのバイト数で指定します。エントリは3つの項目を持ちます: majorminor、および bytes_per_secondmajorminor は、Linux Allocated Devices で指定されているデバイスタイプとノード番号となります。また bytes_per_second読み込み操作が実行できる上限の割合です。例えば、/dev/sda デバイスが最大 10 MBps で読み込み操作を実行できるようにするには、以下のコマンドを実行します:
~]# echo "8:0 10485760" > /cgroups/blkio/test/blkio.throttle.read_bps_device
blkio.throttle.read_iops_device
デバイスが実行できる読み込み操作数の上限を指定します。読み込み操作の割合は秒あたりの操作回数で指定します。エントリは3つの項目を持ちます: majorminor、およびoperations_per_secondmajorminorLinux Allocated Devices で指定されているデバイスタイプとノード番号となります。また operations_per_second読み込み操作が実行できる上限の割合です。例えば、/dev/sda デバイスが秒あたり最大 10 回の読み込み操作を実行できるようにするには、以下のコマンドを実行します:
~]# echo "8:0 10" > /cgroups/blkio/test/blkio.throttle.read_iops_device
blkio.throttle.write_bps_device
デバイスが実行できる書き込み操作数の上限を指定します。書き込み操作の割合は秒あたりのバイト数で指定します。エントリは3つの項目を持ちます: majorminor、および bytes_per_secondmajorminor は、Linux Allocated Devices で指定されているデバイスタイプとノード番号となります。また bytes_per_second書き込み操作が実行できる上限の割合です。例えば、/dev/sda デバイスが最大 10 MBps で書き込み操作を実行できるようにするには、以下のコマンドを実行します:
~]# echo "8:0 10485760" > /cgroups/blkio/test/blkio.throttle.write_bps_device
blkio.throttle.write_iops_device
デバイスが実行できる書き込み操作数の上限を指定します。書き込み操作の割合は秒あたりの操作回数で指定します。エントリは3つの項目を持ちます: majorminor、およびoperations_per_secondmajorminorLinux Allocated Devices で指定されているデバイスタイプとノード番号となります。また operations_per_second書き込み操作が実行できる上限の割合です。例えば、/dev/sda デバイスが秒あたり最大 10 回の書き込み操作を実行できるようにするには、以下のコマンドを実行します:
~]# echo "8:0 10" > /cgroups/blkio/test/blkio.throttle.write_iops_device
blkio.throttle.io_serviced
特定のデバイス上で cgroup によって実行された I/O 操作の回数をスロットリングのポリシーにより見られるようにレポートします。エントリはmajorminoroperation、および number の 4 つのフィールドで構成されます。majorminorLinux Allocated Devices で指定されているデバイスタイプとノード数で、operation は操作のタイプ (readwritesync、または async)、number は操作回数を示します。
blkio.throttle.io_service_bytes
cgroup により特定のデバイス上で転送されたバイト数をレポートします。blkio.io_service_bytesblkio.throttle.io_service_bytes\n の唯一の違いは、CFQ スケジューラーが要求キューにおいて実行しているときに前者は更新されないことです。エントリは、majorminoroperation、および bytes の 4 つのフィールドで構成されます。majorminor は、Linux Allocated Devices で指定されているデバイスタイプとノード番号です。operation は操作のタイプ (readwritesync、または async) です。bytes は転送されたバイト数です。

3.1.3. 共通の設定オプション

以下の設定オプションは「blkio」に一覧化されているポリシーのいずれかのために使用されます。
blkio.reset_stats
その他の疑似ファイルに記録されている統計をリセットします。この cgroup の統計をリセットするには、このファイルに整数を書き込みます。

3.1.4. 使用例

さまざまな blkio.weight 値を持つ2つの異なる cgroups において2つの dd スレッドを実行するという簡単なテストは例3.1「blkio 比例ウェイト分割」を参照してください。
例3.1 blkio 比例ウェイト分割
  1. blkio サブシステムをマウントします:
    ~]# mount -t cgroup -o blkio blkio /cgroup/blkio/
    
  2. blkio サブシステムに対するう2つの cgroups を作成します:
    ~]# mkdir /cgroup/blkio/test1/
    ~]# mkdir /cgroup/blkio/test2/
    
  3. 前に作成した cgroups にさまざまな blkio ウェイトを設定します:
    ~]# echo 1000 > /cgroup/blkio/test1/blkio.weight
    ~]# echo 500 > /cgroup/blkio/test2/blkio.weight
    
  4. 2つの大きなファイルを作成します:
    ~]# dd if=/dev/zero of=file_1 bs=1M count=4000
    ~]# dd if=/dev/zero of=file_2 bs=1M count=4000
    
    上のコマンドは容量 4 GB の2つのファイル (file_1file_2) を作成します。
  5. 各テスト cgroups に対して、ある大きなファイルにおいて(ファイルの内容を読み込んでヌルデバイスに出力する) dd コマンドを実行します:
    ~]# cgexec -g blkio:test1 time dd if=file_1 of=/dev/null
    ~]# cgexec -g blkio:test2 time dd if=file_2 of=/dev/null
    
    どちらのコマンドも、完了すると、かかった時間を表示します。
  6. 同時に2つの dd スレッドを実行すると、iotop ユーティリティによりリアルタイムにパフォーマンスをモニターできます。iotop ユーティリティをインストールするには、root として yum install iotop コマンドを実行します。以下は先ほど開始した dd スレッドを実行中に \niotop ユーティリティで見られるような出力例です:
    Total DISK READ: 83.16 M/s | Total DISK WRITE: 0.00 B/s
        TIME  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN      IO    COMMAND
    15:18:04 15071 be/4 root       27.64 M/s    0.00 B/s  0.00 % 92.30 % dd if=file_2 of=/dev/null
    15:18:04 15069 be/4 root       55.52 M/s    0.00 B/s  0.00 % 88.48 % dd if=file_1 of=/dev/null
    

例3.1「blkio 比例ウェイト分割」において最も正確な結果を得るためには、dd コマンドを実行する前に、以下のコマンドを使用してすべてのファイルシステムバッファーと空きページキャッシュ、dentry および inode をフラッシュします:
~]# sync
~]# echo 3 > /proc/sys/vm/drop_caches
加えて、スループットの消費においてグループ間でより強力な分離を提供する、グループ分離 (group isolation) を有効にできます。グループ分離が無効化されるとき、公平性は連続的な作業負荷に対してのみ期待できます。デフォルトで、グループ分離は有効化されていて、公平性はランダム I/O に対しても同様に期待できます。グループ分離を有効化するには、以下のコマンドを使用します:
~]# echo 1 > /sys/block/<disk_device>/queue/iosched/group_isolation
ここで <disk_device> 希望するデバイスの名前を意味します。例えば sda です。

3.2. cpu

cpu サブシステムは、cgroup への CPU アクセスをスケジュールします。CPU リソースへのアクセスは、以下のパラメータにしたがって、それぞれを cgroup の仮想ファイルシステム内の個別の 疑似ファイル 内でスケジュールすることができます。
cpu.shares
cgroup 内のタスクで使用できる CPU 時間の相対的配分を指定する整数値を含みます。例えば、cpu.shares1 にセットされた 2 つの cgroup のタスクには同等の CPU 時間が提供されますが、cpu.shares2 にセットされた cgroup のタスクには、cpu.shares1 にセットされた cgroup のタスクの 2 倍の CPU 時間が提供されます。
cpu.rt_runtime_us
cgroup 内のタスクによる CPU リソースへのアクセスの最長連続時間をマイクロ秒(µs、ただしここでは "us" と表示)で指定します。この上限を設定することにより、cgroup 内のタスクが CPU 時間を独占できないようにします。cgroup 内のタスクが 毎 5 秒中 4 秒間 CPU リソースにアクセスできるようにする必要がある場合は、cpu.rt_runtime_us4000000cpu.rt_period_us5000000 にセットします。
cpu.rt_period_us
リアルタイムのスケジューリングタスクのみに適用でき、このパラメーターは cgroup による CPU リソースへのアクセスの一定間隔をマイクロ秒(µs、ただしここでは "us" と表示)で指定します。cgroup 内のタスクが毎 5 秒中 4 秒間 CPU リソースにアクセスできるようにする必要がある場合は、cpu.rt_runtime_us4000000cpu.rt_period_us5000000 にセットします。

3.3. cpuacct

CPU Accounting (cpuacct) サブシステムは、cgroup 内のタスクで使用される CPU リソースに関する自動レポートを生成します。3 つのレポートが利用できます:
cpuacct.usage
この cgroup 内の全タスク (下位階層のタスクを含む) により消費される総 CPU 時間 (ナノ秒単位) をレポートします。

Resetting cpuacct.usage

cpuacct.usage にある値をリセットするには、以下のコマンドを実行します:
~]# echo 0 > /cgroups/cpuacct/cpuacct.usage
上のコマンドは cpuacct.usage_percpu にある値をリセットします。
cpuacct.stat
この cgroup における(より低階層にあるタスクを含め)すべてのタスクにより消費されたユーザーおよびシステム CPU 時間を以下の形式で表示します:
  • system — ユーザーモードのタスクにより消費された CPU 時間。
  • system — システム (カーネル) モードのタスクにより消費された CPU 時間。
CPU 時間は USER_HZ 変数により定義された単位で報告されます。
cpuacct.usage_percpu
この cgroup 内の全タスク (下位階層のタスクを含む) により、各 CPU 上で消費される CPU 時間 (ナノ秒単位) をレポートします

3.4. cpuset

cpuset サブシステムは、個別の CPU とメモリーノードを cgroup に割り当てます。各 cpuset は、以下のパラメータにしたがって、それぞれを cgroup 仮想ファイルシステム内の別々の 疑似ファイル 内で指定することができます。

必須のパラメータ

一部のサブシステムには、それらのいずれかを使用する cgroup にタスクを移動する前にセットしておく必要がある必須パラメータがあります。例えば、cpuset を使用する cgroup にタスクを cgroup に移動する前に、その cgroup に対して cpuset.cpuscpuset.mems のパラメータを定義しておく必要があります。
cpuset.cpus (必須)
cgroup 内のタスクがアクセスを許可される CPU を指定します。これは ASCII 形式のコンマ区切りの一覧で、ダッシュ ("-") はその範囲を示します。例えば、
0-2,16
これは、CPU 0、1、2、および 16 を示します。
cpuset.mems (必須)
この cgroup 内のタスクがアクセスを許可されるメモリーを指定します。これは ASCII 形式のコンマ区切りの一覧で、ダッシュ ("-") は範囲を示します。例えば、
0-2,16
これは、メモリーノード 0、1、2、および 16 を示します。
cpuset.memory_migrate
cpuset.mems 内の値が変更された場合に、メモリー内のページが新規ノードに移行すべきかどうかを指定するフラグ (0 または 1) が含まれます。デフォルトでは、メモリー移行は無効 (0) になっており、元のノードが cpuset.mems に指定されているノードの1つでなくなっても、ページは最初に割り当てられたノードに残ります。有効 (1) にすると場合、システムは cpuset.mems により指定された新規のパラメータ内のメモリーノードにページを移行します。また、可能な場合には、それらの相対的配置を維持します。例えば、最初に cpuset.mems で指定されていた一覧の第 2 のノードにあるページは、この場所が使用可能な場合には、cpuset.mems で今回指定された一覧の第 2 のノードに割り当てられます。
cpuset.cpu_exclusive
他の cpuset がこの cpuset 用に指定された CPU を共有できるかどうかを指定するフラグ (0 または 1) が含まれます。デフォルト (0) では、CPU は 1つの cpuset 専用には割り当てられません。
cpuset.mem_exclusive
他の cpuset がこの cpuset 用に指定されたメモリーノードを共有できるかどうかを指定するフラグ (0 または 1) が含まれます。デフォルト (0) では、メモリーノードは 1つの cpuset 専用には割り当てられません。メモリーノードを cpuset (1) の排他利用のために予約することは、cpuset.mem_hardwall パラメーターを用いてメモリーハードウォールを有効にするのと機能的に同じです。
cpuset.mem_hardwall
メモリーページとバッファーデータのカーネル割り当てがこの cpuset 用に指定されたメモリーノードに制限されるかどうかを指定するフラグ (0 または 1) が含まれます。デフォルト (0) では、ページとバッファーデータが複数のユーザーに所属しているプロセスを超えて共有できます。ハードウォールを有効にすると (1) 、各タスクのユーザー割り当ては分離されたままにできます。
cpuset.memory_pressure
この cpuset 内のプロセスによって発生した memory pressure の移動平均を含んでいる 読み取り専用のファイルです。この疑似ファイル内の値は、cpuset.memory_pressure_enabled が 有効になった時に自動的に更新されます。それ以外は疑似ファイルは値 0 を取ります。
cpuset.memory_pressure_enabled
この cgroup 内のプロセスによって発生した memory pressure をシステムが計算すべきかどうかを指定するフラグ (0 または 1) が含まれます。計算された値は cpuset.memory_pressure に出力されて、プロセスが使用中のメモリーの解放を試みるレートを示します。これは、1 秒あたりのメモリー再生試行回数に1000を乗じた整数値としてレポートされます。
cpuset.memory_spread_page
この cpuset に割り当てられたメモリーノード全体にわたってファイルシステムバッファを均等に分散すべきかどうかを指定するフラグ (0 または 1) が含まれます。デフォルト (0) では、これらの バッファ用にメモリーページを均等に分散しようとする試みはなく、バッファはそれを作成したプロセスを実行しているのと同じノードに配置されます。
cpuset.memory_spread_slab
ファイルの入力/出力演算用のカーネルスラブキャッシュが cpuset 全体に均等に分散されるべきかどうかを指定するフラグ (0 または 1) が含まれます。デフォルト (0) では、カーネルスラブキャッシュを均等に分散しようとする試みはなく、スラブキャッシュはそれを作成したプロセスを実行しているのと同じノード上に配置されます。
cpuset.sched_load_balance
カーネルがこの cpuset 内の CPU 全体にわたって負荷を分散するかどうかを指定するフラグ (0 または 1) が含まれます。デフォルト (1) では、カーネルは過負荷状態の CPU から、使用頻度のより低い CPU へ プロセスを移動して負荷を分散します。
ただし、いずれかの親 cgroup でロードバランシングが有効化されている場合には、ロードバランシングがより高いレベルで既に実行されていることになるため、cgroup 内におけるこのフラグの設定は、無効となる点に注意してください。したがって、cgroup 内でロードバランシングを無効にするには、その階層内の各親 cgroup でもロードバランシングを無効にしてください。この場合には、対象となる cgroup の兄弟のロードバランシングも無効にすべきかどうかも検討すべきです。
cpuset.sched_relax_domain_level
-1 から小さい正の値までの間の整数が含まれます。これはカーネルが負荷を分散するために試行すべき CPU の範囲の幅を示します。cpuset.sched_load_balance が無効になっている場合には、この値は意味がありません。
この値の正確な効果はシステムアーキテクチャに応じて変化しますが、以下の値が標準的です:
cpuset.sched_relax_domain_level の値
効果
-1ロードバランシングにシステムデフォルト値を使用
0ロードバランシングを即実行せず、定期的に負荷を分散
1同じコア上のスレッド全体にわたって、ロードバランシングを即実行
2同じパッケージ内のコア全体にわたって、ロードバランシングを即実行
3同じノードまたはブレード上の CPU 全体にわたって、ロードバランシングを即実行
4NUMA (非均等メモリーアクセス) を使用するアーキテクチャ上のいくつかの CPU にわたって、ロードバランシングを即実行
5NUMA を使用するアーキテクチャ上の全 CPU にわたって、ロードバランシングを即実行

3.5. devices

devices サブシステムは、cgroup 内のタスクによるデバイスへのアクセスを許可または拒否します。
devices.allow
cgroup 内のタスクがアクセスをするデバイスを指定します。エントリは typemajorminor、および access の 4 つのフィールドで構成されます。typemajor、および minor のフィールドに使用される値は、http://www.kernel.org/doc/Documentation/devices.txt に掲載の Linux Allocated Devices (別名 Linux Devices List) で指定されているデバイスタイプ、ノード番号に対応します。
type
type は以下の3つの値の内の1つを取ります:
  • a文字デバイスブロックデバイス の両方を併せた、すべてのデバイスに該当します
  • b — ブロックデバイスを指定します
  • c — 文字デバイスを指定します
major, minor
majorminor は、Linux Allocated Devices で指定されているデバイスノード番号です。メジャー(major) とマイナー(minor)番号はコロンで区切られます。例えば、8 は、SCSI ディスクドライブを指定するメジャー番号であり、マイナー番号 1 は第 1 の SCSI ディスクドライブ上の第 1 のパーティションを指定します。したがって、8:1 は、このパーティションを完全に指定し、/dev/sda1 の ファイルシステムの場所に相当します。
* は、すべてのメジャーまたはマイナーデバイスノードを表します。例えば、9:* (全 RAID デバイス) または *:* (全デバイス) というように表示します。
access
access は、以下の文字 (単一または複数) からなるシーケンスです。
  • r — タスクによる指定デバイスの読み取りを許可します
  • w — タスクによる指定デバイスへの書き込みを許可します
  • m — タスクによる、まだ存在していないデバイスファイルの作成を許可します
例えば、accessr と指定されている時は、タスクは指定デバイスから読み取るだけですが、 accessrw と指定されていると、タスクはデバイスからの読み取りとデバイスへの書き込みができます。
devices.deny
cgroup 内のタスクがアクセスできないデバイスを指定します。エントリの構文は devices.allow と全く同じです。
devices.list
この cgroup 内のタスクによるアクセス制御が設定されている対象デバイスをレポートします。

3.6. freezer

freezer サブシステムは cgroup 内のタスクを一時停止あるいは再開します。
freezer.state
freezer.state の取り得る値には、以下の3つがあります:
  • FROZEN — cgroup 内のタスクは一時停止しています。
  • FREEZING — システムが cgroup 内のタスクを一時停止している最中です。
  • THAWED — cgroup 内のタスクが再開しています。
特定のプロセスを一時停止するには、
  1. freezer サブシステムが接続された階層内の cgroup にそのプロセスを移動します。
  2. 特定の cgroup をフリーズさせて、その中に含まれるプロセスを一時停止します。
一時停止 (フリーズ) した cgroup にプロセスを移動することはできません。
FROZENTHAWED の値は freezer.state に書き込むことができますが、FREEZING の書き込みは出来ず、読み取りのみが可能である点に注意してください。

3.7. memory

memory サブシステムは、cgroup 内のタスクによって使用されるメモリーリソースの自動レポートを生成し、他のタスクによるメモリー使用の上限を設定します。
memory.stat
以下の表に記載した、広範囲なメモリーの統計をレポートします。
表3.1 memory.stat によりレポートされる値
統計 説明
cache tmpfs (shmem) を含むページキャッシュ (バイト単位)
rss tmpfs (shmem) を含まない匿名のスワップキャッシュ (バイト単位)
mapped_file tmpfs (shmem) を含むメモリーマップドファイルのサイズ (バイト単位)
pgpgin メモリー内へページされたページ数
pgpgout メモリーからページアウトされたページ数
swap スワップの使用量 (バイト単位)
active_anon tmpfs (shmem) を含む、アクティブな最長時間未使用 (LRU) 一覧上の匿名のスワップキャッシュ (バイト単位)
inactive_anon tmpfs (shmem) を含む、非アクティブ LRU 一覧上の匿名のスワップキャッシュ (バイト単位)
active_file アクティブ LRU 一覧にある、ファイルと関連づけされたメモリー (バイト単位)
inactive_file 非アクティブ LRU 一覧にある、ファイルに関連付けされたメモリー (バイト)
unevictable 再生不可のメモリー (バイト単位)
hierarchical_memory_limit memory cgroup が含まれる階層のメモリー制限 (バイト単位)
hierarchical_memsw_limit memory cgroup が含まれる階層のメモリーとスワップの制限 (バイト単位)

また、これらのファイルの中で、hierarchical_memory_limit および hierarchical_memsw_limit 以外のファイルには、それぞれ、total_ というプレフィックスの付いた対応ファイルがあり、cgroup についてだけでなく、その子グループについてもレポートします。例えば、swap は cgroup によるスワップの使用量をレポートし、total_swap は cgroup とその子グループによるスワップの使用量をレポートします。
memory.stat によってレポートされた値を解析する際には、さまざま統計が相互に関連している点に注意してください。
  • active_anon + inactive_anon = 匿名メモリー + tmpfs のファイルキャッシュ + スワップキャッシュ
    したがって、active_anon + inactive_anonrss となります。これは、rsstmpfs が含まれないのが理由です。
  • active_file + inactive_file = cache - size of tmpfs
memory.usage_in_bytes
cgroup 内のプロセスによる現在のメモリー総使用量をレポートします (バイト単位)。
memory.memsw.usage_in_bytes
cgroup 内のプロセスによる現在のメモリー使用量と使用済みスワップ領域の和をレポートします (バイト単位)。
memory.max_usage_in_bytes
cgroup 内のプロセスによるメモリー最大使用量をレポートします (バイト単位)。
memory.memsw.max_usage_in_bytes
cgroup 内のプロセスによるスワップメモリー最大使用量と使用済みスワップ領域をレポートします (バイト単位)。
memory.limit_in_bytes
ユーザーメモリーの最大値を (ファイルキャッシュを含む) をセットします。単位が指定されていない場合、その値はバイト単位と解釈されます。ただし、より大きな単位を示すサフィックスを使用することが可能です — キロバイトには k または K、メガバイトには m または M、ギガバイトには g または G
root cgroup を制限するのには、memory.limit_in_bytes は使用できません。値を適用できるのは、下位階層のグループに対してのみです。
memory.limit_in_bytes-1 と書き込み、現行の制限値を削除します。
memory.memsw.limit_in_bytes
メモリーとスワップ使用量の合計の最大値をセットします。単位が指定されていない場合、その値はバイト単位と解釈されます。ただし、より大きな単位を示すサフィックスを使用することが可能です — キロバイトには k または K、メガバイトには m または M、ギガバイトには g または G
root cgroup を制限するのに、memory.memsw.limit_in_bytes は使用できません。値を適用できるのは、下位階層のグループに対してのみです。
memory.memsw.limit_in_bytes-1 と書き込み、現行の制限値を削除します。

memory.memsw.limit_in_bytes と memory.limit_in_bytes パラメーターの設定法

memory.memsw.limit_in_bytes パラメーターを設定する前に memory.limit_in_bytes パラメーターを設定することが重要です。逆の順番で実行しようとすると、エラーになります。なぜなら、memory.memsw.limit_in_bytes は、すべてのメモリー制限(前に memory.limit_in_bytes で設定された)が消費された後でのみ利用可能になるからです。
以下の例を検討します: 特定の cgroup に対して memory.limit_in_bytes = 2G および memory.memsw.limit_in_bytes = 4G を設定することにより、その cgroup にあるプロセスが 2 GB のメモリーおよび、それらを消費すると他にスワップ専用の 2 GB を割り当てることができます。memory.memsw.limit_in_bytes パラメーターはメモリーとスワップの合計を表します。memory.memsw.limit_in_bytes パラメーターを持っていない cgroup にあるプロセスは、(設定したメモリー制限を消費した後)潜在的に利用可能なスワップをすべて使い切る可能性があり、利用可能なスワップの不足により引き起こされる Out Of Memory の状況の引き金になる可能性があります。
memory.limit_in_bytesmemory.memsw.limit_in_bytes パラメーターが /etc/cgconfig.conf ファイルにおいて設定される順番は同様に重要です。以下はそのような設定の正しい例です:
memory {
    memory.limit_in_bytes = 1G;
    memory.memsw.limit_in_bytes = 1G;
}
memory.failcnt
memory.limit_in_bytes にセットされているメモリーの上限値に達した回数をレポートします。
memory.memsw.failcnt
memory.memsw.limit_in_bytes にセットされているメモリーとスワップ領域の合計が上限に達した回数をレポートします。
memory.force_empty
0 にセットされている場合には、cgroup 内のタスクによって使用される全ページのメモリーを空にします。このインターフェイスは、cgroup がタスクを持たない時にのみ使用できます。メモリーを解放できない場合は、可能ならば 親 cgroup に移動されます。cgroup を削除する前には、memory.force_empty を使用して、未使用のページキャッシュが親 cgroup に移動されないようにしてください。
memory.swappiness
ページキャッシュからページを再生する代わりに、カーネルがこの cgroup 内のタスクで使用されるプロセスメモリーを スワップアウトする傾向をセットします。これはシステム全体用に /proc/sys/vm/swappiness 内にセットされているのと同じ傾向で、同じ方法で算出されます。デフォルト値は 60 です。これより低い値を設定すると、カーネルがプロセスメモリーをスワップアウトする傾向が低減します。また100 以上に設定すると、カーネルはこの cgroup 内のプロセスのアドレス領域となる部分のページをスワップアウトできるようになります。
0 の値に設定しても、プロセスメモリーがスワップアウトされるのを防ぐことはできない点に注意してください。グローバル仮想メモリ管理ロジックは、cgroup の値を読み取らないため、システムメモリが不足した場合に、依然としてスワップアウトが発生する可能性があります。ページを完全にロックするには、cgroup の代わりに mlock() を使用してください。
以下にあげるグループの swappiness は変更できません。
  • /proc/sys/vm/swappiness にセットされた swappiness を使用している root cgroup
  • 配下に子グループがある cgroup
memory.use_hierarchy
cgroup の階層全体にわたって、メモリー使用量を算出すべきかどうかを指定するフラグ (0 または 1) が含まれます。有効 (1) となっている場合、メモリーサブシステムはメモリーの上限を超過しているプロセスとその子プロセスからメモリーを再生します。デフォルト (0) では、サブシステムはタスクの子からメモリーを再生しません。

3.8. net_cls

net_cls サブシステムは、Linux トラフィックコントローラ (tc) が 特定の cgroup から発信されるパケットを識別できるようにするクラス識別子 (classid) を使用して、ネットワークパケットをタグ付けします。トラフィックコントローラは、異なる cgroup からのパケットに異なる優先順位を割り当てるように設定できます。
net_cls.classid
net_cls.classid はトラフィック制御ハンドル (handle) を意味する単一値を含みます。net_cls.classid から読み込まれる classid の値は10進形式で表現されますが、ファイルに書き込まれる値は16進形式を予期されます。例えば、0x100001 は従来どおり iproute2 により使用される形式で 10:1 として書かれたものを意味します。net_cls.classid ファイルにおいて、数値 1048577 により表されます。
これらのハンドルの形式は次のとおりです: 0xAAAABBBB、ここで AAAA は16進数のメジャー番号です、BBBB は16進数のマイナー番号です。先頭の0をいくつでも省略できます、つまり 0x100010x00010001 と同じで、1:1 を表します。以下は net_cls.classid ファイルにおいて 10:1 のハンドルを設定する例です:
~]# echo 0x100001 > /cgroup/net_cls/red/net_cls.classid
~]# cat /cgroup/net_cls/red/net_cls.classid
1048577
net_cls がネットワークパケットに追加する処理を使用するためのトラフィックコントローラの設定法を確認するには tc の man ページを参照してください。

3.9. ns

ns サブシステムは、プロセスを異なる 名前空間 にグループ化する手段を提供します。特定の名前空間内では、プロセス間における相互のインタラクションが可能ですが、他の名前空間で実行されているプロセスからは分離しています。このように分離した名前空間は、オペレーティングシステムレベルの仮想化に使用される場合には、コンテナ とも呼ばれています。

3.10. その他のリソース

サブシステム固有のカーネルのドキュメント
以下のファイルはすべて /usr/share/doc/kernel-doc-<kernel_version>/Documentation/cgroups/ ディレクトリ下に配置されています (kernel-doc パッケージにより提供されます)。
  • blkio サブシステム — blkio-controller.txt
  • cpuacct サブシステム — cpuacct.txt
  • cpuset サブシステム — cpusets.txt
  • devices サブシステム — devices.txt
  • freezer サブシステム — freezer-subsystem.txt
  • memory サブシステム — memory.txt

改訂履歴

改訂履歴
改訂 1.0-7Fri Dec 23 2011Hradílek Jaromír [FAMILY Given]
Fedora 16 release of the Resource Management Guide.
改訂 1.0-6Tue Dec 6 2011Prpič Martin [FAMILY Given]
Red Hat Enterprise Linux 6.2 GA release of the Resource Management Guide.
改訂 1.0-5Thu May 19 2011Prpič Martin [FAMILY Given]
Red Hat Enterprise Linux 6.1 GA release of the Resource Management Guide.
改訂 1.0-4Tue Mar 1 2011Prpič Martin [FAMILY Given]
複数の例を修正 — BZ#667623BZ#667676BZ#667699
cgclear コマンドについて明確化 — BZ#577101
lssubsystem コマンドについて明確化 — BZ#678517
プロセスのフリーズ — BZ#677548
改訂 1.0-3Wed Nov 17 2010Landmann Rüdiger [FAMILY Given]
再マウントの例を修正 — BZ#612805
改訂 1.0-2Thu Nov 11 2010Landmann Rüdiger [FAMILY Given]
プレリリースのフィードバック手順を削除
改訂 1.0-1Wed Nov 10 2010Landmann Rüdiger [FAMILY Given]
QE からの修正 — BZ#581702 and BZ#612805
改訂 1.0-0Tue Nov 9 2010Landmann Rüdiger [FAMILY Given]
GA 用の機能実装完了バージョン