JF Linux Kernel 2.6 Documentation: /usr/src/linux/Documentation/filesystems/sysfs.txt

filesystems/sysfs.txt

sysfs ファイルシステムの説明 [プレインテキスト版]


==================================
これは、
linux-2.6.13-rc5/Documentation/filesystems/sysfs.txt の和訳
です。
翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
更新日 : 2005/8/28
原著作者: Patrick Mochel	<mochel at osdl dot org>
翻訳者 : Hiroshi.Suzuki < setter at reset dot jp >
校正者 : Chie Nakatani さん <jeanne at mbox dot kyoto-inet dot or dot jp>
         Seiji Kaneko さん <skaneko at a2 dot mbn dot or dot jp>
==================================

sysfs - _The_ filesystem for exporting kernel objects. 

sysfs - カーネルオブジェクトをエクスポートするファイルシステム

Patrick Mochel	<mochel at osdl dot org>

10 January 2003


What it is:

どういうものか:
~~~~~~~~~~~

sysfs is a ram-based filesystem initially based on ramfs. It provides
a means to export kernel data structures, their attributes, and the 
linkages between them to userspace. 

  初めに、sysfs は ramfs を基礎とする、ram ベースのファイルシステムです。
ユーザ空間に、カーネルのデータ構造と、それらの属性、および、
それらの間の連結 (リンケージ) をエクスポートする手段を提供します。

sysfs is tied inherently to the kobject infrastructure. Please read
Documentation/kobject.txt for more information concerning the kobject
interface. 

sysfs は kobject インフラストラクチャに内部的に結びつけられています。
kobject インタフェースに関する詳細情報は、Documentation/kobject.txt を読んでください。

Using sysfs

sysfs を使う
~~~~~~~~~~~

sysfs is always compiled in. You can access it by doing:

sysfs は常に (カーネルに) 組み込まれます。次のコマンドを実行することでアクセス可能に
なります:

    mount -t sysfs sysfs /sys 


Directory Creation

ディレクトリの作成
~~~~~~~~~~~~~~~~~~

For every kobject that is registered with the system, a directory is
created for it in sysfs. That directory is created as a subdirectory
of the kobject's parent, expressing internal object hierarchies to
userspace. Top-level directories in sysfs represent the common
ancestors of object hierarchies; i.e. the subsystems the objects
belong to. 

sysfs のなかに、システムに登録されるすべての kobject のための
ディレクトリが作成されます。
そのディレクトリは、ユーザ空間に内部オブジェクトの階層を表す kobject を
親ディレクトリとするサブディレクトリとして作成されます。
sysfs のトップレベルディレクトリは、オブジェクト階層で共通の元祖
(すなわち、オブジェクトが属するサブシステム) を表します。

Sysfs internally stores the kobject that owns the directory in the
->d_fsdata pointer of the directory's dentry. This allows sysfs to do
reference counting directly on the kobject when the file is opened and
closed. 

sysfs は、ディレクトリの dentry の ->d_fsdata ポインタ 内のディレクトリを所有する、
kobject を内部的に記憶しています。
これは、ファイルがオープン/クローズしたときに、sysfs が kobject に対する
直接的な参照ができるようにします。

Attributes

属性
~~~~~~~~~~

Attributes can be exported for kobjects in the form of regular files in
the filesystem. Sysfs forwards file I/O operations to methods defined
for the attributes, providing a means to read and write kernel
attributes.

属性は、ファイルシステム内のきまったファイルの形をしている kobject のために
エクスポートできます。sysfs は、属性のため定義されたメソッドに、ファイル I/O 
処理を転送することで、カーネル属性の読み書き手段を提供します。

Attributes should be ASCII text files, preferably with only one value
per file. It is noted that it may not be efficient to contain only
value per file, so it is socially acceptable to express an array of
values of the same type. 

属性は、ひとつのファイル対してひとつの値を持っているアスキーテキストファイルで
なければいけません。ひとつのファイルにひとつの値を入れるのは非効率的かもしれませんので、
同じ種類の値の配列を示すのが、一般的であることは、良く知られています。

Mixing types, expressing multiple lines of data, and doing fancy
formatting of data is heavily frowned upon. Doing these things may get
you publically humiliated and your code rewritten without notice. 

タイプをまぜたり、データの複数行を示したり、データの変な書式は、嫌われます。
このようなことをすると、あなたが社会的な辱めを受けたり、あなたの書いたコードが
通知無しに変更されたりすることになるかもしれません。

An attribute definition is simply:

ひとつの属性の定義は単純です:

struct attribute {
        char                    * name;
        mode_t                  mode;
};


int sysfs_create_file(struct kobject * kobj, struct attribute * attr);
void sysfs_remove_file(struct kobject * kobj, struct attribute * attr);


A bare attribute contains no means to read or write the value of the
attribute. Subsystems are encouraged to define their own attribute
structure and wrapper functions for adding and removing attributes for
a specific object type. 

ひとつの属性は、素のままでは、属性の値を読み書きする手段を持っていません。
サブシステムは、特定のオブジェクトタイプの属性を追加、削除するための、それ自身の
属性構造体と、ラッパー機能を定義するための支援を行います。

For example, the driver model defines struct device_attribute like:

device_attribute 構造体を定義するドライバモデルの例:

struct device_attribute {
        struct attribute        attr;
        ssize_t (*show)(struct device * dev, char * buf);
        ssize_t (*store)(struct device * dev, const char * buf);
};

int device_create_file(struct device *, struct device_attribute *);
void device_remove_file(struct device *, struct device_attribute *);

It also defines this helper for defining device attributes: 

定義するデバイス属性のために、次のヘルパーを定義することもできます:

#define DEVICE_ATTR(_name,_mode,_show,_store)      \
struct device_attribute dev_attr_##_name = {            \
        .attr = {.name  = __stringify(_name) , .mode   = _mode },      \
        .show   = _show,                                \
        .store  = _store,                               \
};

For example, declaring

宣言の例

static DEVICE_ATTR(foo,0644,show_foo,store_foo);

is equivalent to doing:

は、次を行うのと同じです:

static struct device_attribute dev_attr_foo = {
       .attr	= {
		.name = "foo",
		.mode = 0644,
	},
	.show = show_foo,
	.store = store_foo,
};


Subsystem-Specific Callbacks

サブシステム独特のコールバック
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When a subsystem defines a new attribute type, it must implement a
set of sysfs operations for forwarding read and write calls to the
show and store methods of the attribute owners. 

サブシステムが新しい属性タイプを定義するとき、属性所有者の表示、記憶メソッドに、
読み書き呼び出しを転送するための、sysfs 処理一式を実装しなければなりません。

struct sysfs_ops {
        ssize_t (*show)(struct kobject *, struct attribute *,char *);
        ssize_t (*store)(struct kobject *,struct attribute *,const char *);
};

[ Subsystems should have already defined a struct kobj_type as a
descriptor for this type, which is where the sysfs_ops pointer is
stored. See the kobject documentation for more information. ]

[ サブシステムは、このタイプのための記述子として、
kobj_type 構造体 (sysfs_ops ポインタを格納する場所) を既に定義しているはずです ]

When a file is read or written, sysfs calls the appropriate method
for the type. The method then translates the generic struct kobject
and struct attribute pointers to the appropriate pointer types, and
calls the associated methods. 

ファイルが読み書きされるとき、sysfs は、そのタイプに適切なメソッドを呼び出します。
メソッドは、汎用 kobject 構造体および 属性ポインタ構造体を適切なポインタタイプに
変換したあとで、関連するメソッドを呼びます。

To illustrate:

コードを書いてみましょう:

#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
#define to_dev(d) container_of(d, struct device, kobj)

static ssize_t
dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
{
        struct device_attribute * dev_attr = to_dev_attr(attr);
        struct device * dev = to_dev(kobj);
        ssize_t ret = 0;

        if (dev_attr->show)
                ret = dev_attr->show(dev,buf);
        return ret;
}



Reading/Writing Attribute Data

属性データを読み書きする
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To read or write attributes, show() or store() methods must be
specified when declaring the attribute. The method types should be as
simple as those defined for device attributes:

属性を読み書きするには、属性を宣言するときに、show() または、store() メソッドが、
コードに書かれていなければなりません。

        ssize_t (*show)(struct device * dev, char * buf);
        ssize_t (*store)(struct device * dev, const char * buf);

IOW, they should take only an object and a buffer as parameters. 

言いかえれば (IOW = in other words)、それらはパラメータとしてひとつのオブジェクト
および、ひとつのバッファだけを受け取らなければならないということです。

sysfs allocates a buffer of size (PAGE_SIZE) and passes it to the
method. Sysfs will call the method exactly once for each read or
write. This forces the following behavior on the method
implementations: 

sysfs は、size (PAGE_SIZE) のバッファを割り当て、メソッドに渡します。
sysfs は、読み書きそれぞれのために、メソッドを確実に一度呼び出します。
これは、メソッドの実装に次の振舞を強制します:

- On read(2), the show() method should fill the entire buffer. 
  Recall that an attribute should only be exporting one value, or an
  array of similar values, so this shouldn't be that expensive. 

- read(2) において、show() メソッドは、バッファ全体を埋めなければなりません。
  属性はひとつの値または、類似の値の配列だけをエクスポートしなければならないことを
  思いだしてください。ですから、これは、高価 (複雑) になってはいけません。
 
  This allows userspace to do partial reads and seeks arbitrarily over
  the entire file at will. 

  これは、ユーザ空間が、望むときに、ファイル全体の任意の位置から部分的に読み出したり、
  移動することを可能にします。

- On write(2), sysfs expects the entire buffer to be passed during the
  first write. Sysfs then passes the entire buffer to the store()
  method. 

- write(2) において、sysfs は最初の書き込み中に、バッファ全体が渡されることを必要と
  します。そのあとで、sysfs は、store() メソッドにバッファ全体を渡します。
  
  When writing sysfs files, userspace processes should first read the
  entire file, modify the values it wishes to change, then write the
  entire buffer back. 

  sysfs ファイルに書き込み中、ユーザ空間の処理は、はじめにファイル全体を読み込み、
  変更したい値を編集し、そのあとで、バッファ全体を後ろに書き出さなければなりません。

  Attribute method implementations should operate on an identical
  buffer when reading and writing values. 

  属性メソッドは、値の読み書きをひとつのバッファ上で処理する実装にしなければなりません。

Other notes:

ほかの注意点:

- The buffer will always be PAGE_SIZE bytes in length. On i386, this
  is 4096. 

- バッファの長さは、常に、PAGE_SIZE バイトです。i386 では、4096 (バイト) です。

- show() methods should return the number of bytes printed into the
  buffer. This is the return value of snprintf().

- show() メソッドは、バッファに書き込んだバイト数を返さなければなりません。
  これは、snprintf() の戻り値です。

- show() should always use snprintf(). 

- show() は常に、snprintf() を使わなければなりません。

- store() should return the number of bytes used from the buffer. This
  can be done using strlen().

- store() は、バッファから使ったバイト数を返さなければなりません。
  これは、strlen() を使ってできます。

- show() or store() can always return errors. If a bad value comes
  through, be sure to return an error.

- show() や、store() は、常にエラーを返せます。不正な値がきたときには、必ずエラーを
  返すこと。

- The object passed to the methods will be pinned in memory via sysfs
  referencing counting its embedded object. However, the physical 
  entity (e.g. device) the object represents may not be present. Be 
  sure to have a way to check this, if necessary. 

- メソッドに渡されたオブジェクトは、sysfs の管理する埋め込みオブジェクトの参照カウント
  数によって、メモリ内にピン止め (固定) されます。
  しかし、オブジェクトが表す、物理的実体 (デバイスなど) は、存在しないかもしれません。
   必要なら、これを確認する方法を必ず用意してください。

A very simple (and naive) implementation of a device attribute is:

デバイス属性の、非常に簡単な (そして単純な) 実装は:

static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
        return sprintf(buf,"%s\n",dev->name);
}

static ssize_t store_name(struct device * dev, const char * buf)
{
	sscanf(buf,"%20s",dev->name);
	return strlen(buf);
}

static DEVICE_ATTR(name,S_IRUGO,show_name,store_name);


(Note that the real implementation doesn't allow userspace to set the 
name for a device.)

(現実の実装では、ユーザ空間がデバイスの名前をセットできないことに注意してください。)

Top Level Directory Layout

最上位ディレクトリレイアウト
~~~~~~~~~~~~~~~~~~~~~~~~~~

The sysfs directory arrangement exposes the relationship of kernel
data structures. 

sysfs ディレクトリの配置は、カーネルデータ構造の連携を表します。

The top level sysfs diretory looks like:

最上位の sysfs ディレクトリは、このように見えます:

block/
bus/
class/
devices/
firmware/
net/

devices/ contains a filesystem representation of the device tree. It maps
directly to the internal kernel device tree, which is a hierarchy of
struct device. 

devices/ には、デバイスツリーを、ファイルシステム表現にしたものがあります。
device 構造体の階層である、内部的なカーネルデバイスツリーに直接マップされています。

bus/ contains flat directory layout of the various bus types in the
kernel. Each bus's directory contains two subdirectories:

bus/ カーネル内におけるさまざまなバスタイプの平坦なディレクトリレイアウトを格納しています。
それぞれのバスのディレクトリは、ふたつのサブディレクトリを格納しています:

	devices/
	drivers/

devices/ contains symlinks for each device discovered in the system
that point to the device's directory under root/.

devices/ は、root/ 下にあるデバイスのディレクトリを指す、システム内で発見された
それぞれのデバイスへのシンボリックリンクを格納しています。

drivers/ contains a directory for each device driver that is loaded
for devices on that particular bus (this assumes that drivers do not
span multiple bus types).

drivers/ は、特定のバス (これは、ドライバが複数のバスタイプにまたがらないと仮定しています)
上のデバイス用にロードされた、それぞれのデバイスドライバのためのディレクトリを格納しています。

More information can driver-model specific features can be found in
Documentation/driver-model/. 

ドライバモデル特有の特徴に関する詳細は、Documentation/driver-model/ にあります。

TODO: Finish this section.

TODO: このセクションを完成する

Current Interfaces

現在のインタフェース
~~~~~~~~~~~~~~~~~~

The following interface layers currently exist in sysfs:

現在、sysfs には、次に示すインタフェースレイヤが存在します:

- devices (include/linux/device.h)
----------------------------------
Structure:

構造体:

struct device_attribute {
        struct attribute        attr;
        ssize_t (*show)(struct device * dev, char * buf);
        ssize_t (*store)(struct device * dev, const char * buf);
};

Declaring:

宣言:

DEVICE_ATTR(_name,_str,_mode,_show,_store);

Creation/Removal:

作成と削除:

int device_create_file(struct device *device, struct device_attribute * attr);
void device_remove_file(struct device * dev, struct device_attribute * attr);


- bus drivers (include/linux/device.h)

- バスドライバ (include/linux/device.h)
--------------------------------------
Structure:

構造体:

struct bus_attribute {
        struct attribute        attr;
        ssize_t (*show)(struct bus_type *, char * buf);
        ssize_t (*store)(struct bus_type *, const char * buf);
};

Declaring:

宣言:

BUS_ATTR(_name,_mode,_show,_store)

Creation/Removal:

作成と削除:

int bus_create_file(struct bus_type *, struct bus_attribute *);
void bus_remove_file(struct bus_type *, struct bus_attribute *);


- device drivers (include/linux/device.h)

- デバイスドライバ (include/linux/device.h)
-----------------------------------------

Structure:

構造体:

struct driver_attribute {
        struct attribute        attr;
        ssize_t (*show)(struct device_driver *, char * buf);
        ssize_t (*store)(struct device_driver *, const char * buf);
};

Declaring:

宣言:

DRIVER_ATTR(_name,_mode,_show,_store)

Creation/Removal:

作成と削除:

int driver_create_file(struct device_driver *, struct driver_attribute *);
void driver_remove_file(struct device_driver *, struct driver_attribute *);


Linux カーネル 2.6 付属文書一覧へ戻る