⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 configfs.txt

📁 linux 内核源代码
💻 TXT
📖 第 1 页 / 共 2 页
字号:
		struct config_group *(*make_group)(struct config_group *group,						   const char *name);		int (*commit_item)(struct config_item *item);		void (*disconnect_notify)(struct config_group *group,					  struct config_item *item);		void (*drop_item)(struct config_group *group,				  struct config_item *item);	};A group creates child items by providing thect_group_ops->make_item() method.  If provided, this method is called from mkdir(2) in the group's directory.  The subsystem allocates a newconfig_item (or more likely, its container structure), initializes it,and returns it to configfs.  Configfs will then populate the filesystemtree to reflect the new item.If the subsystem wants the child to be a group itself, the subsystemprovides ct_group_ops->make_group().  Everything else behaves the same,using the group _init() functions on the group.Finally, when userspace calls rmdir(2) on the item or group,ct_group_ops->drop_item() is called.  As a config_group is also aconfig_item, it is not necessary for a separate drop_group() method.The subsystem must config_item_put() the reference that was initializedupon item allocation.  If a subsystem has no work to do, it may omitthe ct_group_ops->drop_item() method, and configfs will callconfig_item_put() on the item on behalf of the subsystem.IMPORTANT: drop_item() is void, and as such cannot fail.  When rmdir(2)is called, configfs WILL remove the item from the filesystem tree(assuming that it has no children to keep it busy).  The subsystem isresponsible for responding to this.  If the subsystem has references tothe item in other threads, the memory is safe.  It may take some timefor the item to actually disappear from the subsystem's usage.  But itis gone from configfs.When drop_item() is called, the item's linkage has already been torndown.  It no longer has a reference on its parent and has no place inthe item hierarchy.  If a client needs to do some cleanup before thisteardown happens, the subsystem can implement thect_group_ops->disconnect_notify() method.  The method is called afterconfigfs has removed the item from the filesystem view but before theitem is removed from its parent group.  Like drop_item(),disconnect_notify() is void and cannot fail.  Client subsystems shouldnot drop any references here, as they still must do it in drop_item().A config_group cannot be removed while it still has child items.  Thisis implemented in the configfs rmdir(2) code.  ->drop_item() will not becalled, as the item has not been dropped.  rmdir(2) will fail, as thedirectory is not empty.[struct configfs_subsystem]A subsystem must register itself, usually at module_init time.  Thistells configfs to make the subsystem appear in the file tree.	struct configfs_subsystem {		struct config_group	su_group;		struct mutex		su_mutex;	};	int configfs_register_subsystem(struct configfs_subsystem *subsys);	void configfs_unregister_subsystem(struct configfs_subsystem *subsys);	A subsystem consists of a toplevel config_group and a mutex.The group is where child config_items are created.  For a subsystem,this group is usually defined statically.  Before callingconfigfs_register_subsystem(), the subsystem must have initialized thegroup via the usual group _init() functions, and it must also haveinitialized the mutex.	When the register call returns, the subsystem is live, and itwill be visible via configfs.  At that point, mkdir(2) can be called andthe subsystem must be ready for it.[An Example]The best example of these basic concepts is the simple_childrensubsystem/group and the simple_child item in configfs_example.c  Itshows a trivial object displaying and storing an attribute, and a simplegroup creating and destroying these children.[Hierarchy Navigation and the Subsystem Mutex]There is an extra bonus that configfs provides.  The config_groups andconfig_items are arranged in a hierarchy due to the fact that theyappear in a filesystem.  A subsystem is NEVER to touch the filesystemparts, but the subsystem might be interested in this hierarchy.  Forthis reason, the hierarchy is mirrored via the config_group->cg_childrenand config_item->ci_parent structure members.A subsystem can navigate the cg_children list and the ci_parent pointerto see the tree created by the subsystem.  This can race with configfs'management of the hierarchy, so configfs uses the subsystem mutex toprotect modifications.  Whenever a subsystem wants to navigate thehierarchy, it must do so under the protection of the subsystemmutex.A subsystem will be prevented from acquiring the mutex while a newlyallocated item has not been linked into this hierarchy.   Similarly, itwill not be able to acquire the mutex while a dropping item has notyet been unlinked.  This means that an item's ci_parent pointer willnever be NULL while the item is in configfs, and that an item will onlybe in its parent's cg_children list for the same duration.  This allowsa subsystem to trust ci_parent and cg_children while they hold themutex.[Item Aggregation Via symlink(2)]configfs provides a simple group via the group->item parent/childrelationship.  Often, however, a larger environment requires aggregationoutside of the parent/child connection.  This is implemented viasymlink(2).A config_item may provide the ct_item_ops->allow_link() andct_item_ops->drop_link() methods.  If the ->allow_link() method exists,symlink(2) may be called with the config_item as the source of the link.These links are only allowed between configfs config_items.  Anysymlink(2) attempt outside the configfs filesystem will be denied.When symlink(2) is called, the source config_item's ->allow_link()method is called with itself and a target item.  If the source itemallows linking to target item, it returns 0.  A source item may wish toreject a link if it only wants links to a certain type of object (say,in its own subsystem).When unlink(2) is called on the symbolic link, the source item isnotified via the ->drop_link() method.  Like the ->drop_item() method,this is a void function and cannot return failure.  The subsystem isresponsible for responding to the change.A config_item cannot be removed while it links to any other item, norcan it be removed while an item links to it.  Dangling symlinks are notallowed in configfs.[Automatically Created Subgroups]A new config_group may want to have two types of child config_items.While this could be codified by magic names in ->make_item(), it is muchmore explicit to have a method whereby userspace sees this divergence.Rather than have a group where some items behave differently thanothers, configfs provides a method whereby one or many subgroups areautomatically created inside the parent at its creation.  Thus,mkdir("parent) results in "parent", "parent/subgroup1", up through"parent/subgroupN".  Items of type 1 can now be created in"parent/subgroup1", and items of type N can be created in"parent/subgroupN".These automatic subgroups, or default groups, do not preclude otherchildren of the parent group.  If ct_group_ops->make_group() exists,other child groups can be created on the parent group directly.A configfs subsystem specifies default groups by filling in theNULL-terminated array default_groups on the config_group structure.Each group in that array is populated in the configfs tree at the sametime as the parent group.  Similarly, they are removed at the same timeas the parent.  No extra notification is provided.  When a ->drop_item()method call notifies the subsystem the parent group is going away, italso means every default group child associated with that parent group.As a consequence of this, default_groups cannot be removed directly viarmdir(2).  They also are not considered when rmdir(2) on the parentgroup is checking for children.[Dependant Subsystems]Sometimes other drivers depend on particular configfs items.  Forexample, ocfs2 mounts depend on a heartbeat region item.  If thatregion item is removed with rmdir(2), the ocfs2 mount must BUG or goreadonly.  Not happy.configfs provides two additional API calls: configfs_depend_item() andconfigfs_undepend_item().  A client driver can callconfigfs_depend_item() on an existing item to tell configfs that it isdepended on.  configfs will then return -EBUSY from rmdir(2) for thatitem.  When the item is no longer depended on, the client driver callsconfigfs_undepend_item() on it.These API cannot be called underneath any configfs callbacks, asthey will conflict.  They can block and allocate.  A client driverprobably shouldn't calling them of its own gumption.  Rather it shouldbe providing an API that external subsystems call.How does this work?  Imagine the ocfs2 mount process.  When it mounts,it asks for a heartbeat region item.  This is done via a call into theheartbeat code.  Inside the heartbeat code, the region item is lookedup.  Here, the heartbeat code calls configfs_depend_item().  If itsucceeds, then heartbeat knows the region is safe to give to ocfs2.If it fails, it was being torn down anyway, and heartbeat can gracefullypass up an error.[Committable Items]NOTE: Committable items are currently unimplemented.Some config_items cannot have a valid initial state.  That is, nodefault values can be specified for the item's attributes such that theitem can do its work.  Userspace must configure one or more attributes,after which the subsystem can start whatever entity this itemrepresents.Consider the FakeNBD device from above.  Without a target address *and*a target device, the subsystem has no idea what block device to import.The simple example assumes that the subsystem merely waits until all theappropriate attributes are configured, and then connects.  This will,indeed, work, but now every attribute store must check if the attributesare initialized.  Every attribute store must fire off the connection ifthat condition is met.Far better would be an explicit action notifying the subsystem that theconfig_item is ready to go.  More importantly, an explicit action allowsthe subsystem to provide feedback as to whether the attributes areinitialized in a way that makes sense.  configfs provides this ascommittable items.configfs still uses only normal filesystem operations.  An item iscommitted via rename(2).  The item is moved from a directory where itcan be modified to a directory where it cannot.Any group that provides the ct_group_ops->commit_item() method hascommittable items.  When this group appears in configfs, mkdir(2) willnot work directly in the group.  Instead, the group will have twosubdirectories: "live" and "pending".  The "live" directory does notsupport mkdir(2) or rmdir(2) either.  It only allows rename(2).  The"pending" directory does allow mkdir(2) and rmdir(2).  An item iscreated in the "pending" directory.  Its attributes can be modified atwill.  Userspace commits the item by renaming it into the "live"directory.  At this point, the subsystem receives the ->commit_item()callback.  If all required attributes are filled to satisfaction, themethod returns zero and the item is moved to the "live" directory.As rmdir(2) does not work in the "live" directory, an item must beshutdown, or "uncommitted".  Again, this is done via rename(2), thistime from the "live" directory back to the "pending" one.  The subsystemis notified by the ct_group_ops->uncommit_object() method.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -