================================== これは、 linux-2.6.13-rc5/Documentation/filesystems/sysfs.txt の和訳 です。 翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ > 更新日 : 2005/8/28 原著作者: Patrick Mochel 翻訳者 : Hiroshi.Suzuki < setter at reset dot jp > 校正者 : Chie Nakatani さん Seiji Kaneko さん ================================== sysfs - _The_ filesystem for exporting kernel objects. sysfs - カーネルオブジェクトをエクスポートするファイルシステム Patrick Mochel 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 *);