proc文件系统

proc文件系统是一种虚拟文件系统,其信息不能从块设备读取。只有在读取文件内容时才动态生成响应的信息。使用proc文件系统,可以获得有关内核各子系统的信息(如内存利用率、附接的外设等),也可以在不重新编译内核源代码的情况下修改内核的行为,或重启系统。
proc文件系统提供一种接口,可用于该机制导出所有选项,直接地修改参数无需开发专门程序,只需要一个shell和标准的cat、echo即可。
/proc信息
信息可以分为一下几类:
内存管理,系统进程的特征数据,文件系统,设备驱动程序,系统总线,电源管理,终端,系统控制参数。
proc常见文件
buddyinfo:用于诊断内存碎片问题;
在这里插入图片描述
cmdline:在启动时传递值内核的相关参数信息,这些信息通常由lilo或grub等启动管理工具进行传递。
在这里插入图片描述
cpuinfo:处理器的相关信息文件。
在这里插入图片描述
crypto:系统上已安装的内核使用的密码算法及每个算法的详细信息列表。
在这里插入图片描述
devices:系统已经加载的所有块设备和字符设备的信息;
在这里插入图片描述
diskstats:每块磁盘设备的磁盘I/O统计信息列表。
在这里插入图片描述
fb:帧缓冲设备列表文件,包含帧缓冲设备的设备号和相关驱动信息。
在这里插入图片描述
filesystems:当前被内核支持的文件系统类型列表文件,被标示为nodev的文件系统表示不需要块设备的支持。
在这里插入图片描述
interrupts:X86或X86_64体系架构系统上每个IRQ相关的中断号列表;
在这里插入图片描述
iomem:每个物理设备上的记忆体(RAM或者ROM)在系统内存中的映射信息。
在这里插入图片描述
ioports:当前正在使用且已经注册过的与物理设备进行通讯的输入-输出端口范围信息列表。
在这里插入图片描述
kallsyms:模块管理工具用来动态链接或绑定模块的符号定义,由内核输出;
在这里插入图片描述
在这里插入图片描述
locks:保存当前由内核锁定的文件的相关信息,包含内核内部的调试数据;每个锁占一行,且具有一个唯一编号。
在这里插入图片描述
meminfo:系统中关于当前内存的利用状况等的信息,常由free命令使用。
在这里插入图片描述
mounts:文件系统挂载情况
在这里插入图片描述
modules:当前装入内核的所有模块名称列表,可以由lsmod命令使用,也可以直接查看。
在这里插入图片描述
在这里插入图片描述
partitions:块设备每个分区的主设备号(major)和次设备号(minor)等信息。
在这里插入图片描述
stat:实时追踪自系统上次启动以来的多种统计信息。
在这里插入图片描述
swaps:当前系统上的交换分区及其空间利用信息。
在这里插入图片描述
uptime:系统上次启动以来的运行时间
在这里插入图片描述
version:当前系统运行的内核版本。
在这里插入图片描述
vmstat:当前系统虚拟内存的多种统计数据。
在这里插入图片描述
zoneinfo:内存区域(zone)的详细信息列表。
在这里插入图片描述
proc的数据结构
实现proc文件系统的代码紧围绕这些数据结构而建立的,proc大量使用VFS的数据结构,因为作为一种文件系统,他必须集成到内核的VFS抽象层中。
还有一些特定于proc的数据结构,用于组织内核提供的数据信息。还必须提供一个到内核各个子系统的接口,使得内核能从其数据结构中提取信息,然后借助/proc提供给用户空间。proc文件系统中的每个数据项都由proc_dir_entry的一个实例描述。

/*
 * This is not completely implemented yet. The idea is to
 * create an in-memory tree (like the actual /proc filesystem
 * tree) of these proc_dir_entries, so that we can dynamically
 * add new files to /proc.
 *
 * parent/subdir are used for the directory structure (every /proc file has a
 * parent, but "subdir" is empty for all non-directory entries).
 * subdir_node is used to build the rb tree "subdir" of the parent.
 */
struct proc_dir_entry {
	unsigned int low_ino;//inode编号
	umode_t mode;//反应对应数据项的类型(文件,目录等),以及访问权限分配
	nlink_t nlink;//子目录和软连接项目
	kuid_t uid;//用户ID
	kgid_t gid;//组ID
	loff_t size;//表示按字节计算的文件长度
	const struct inode_operations *proc_iops;//节点操作
	const struct file_operations *proc_fops;//文件操作
	struct proc_dir_entry *parent;//父目录指针
	struct rb_root subdir;//指向一个目录的第一个子数据项
	struct rb_node subdir_node;//子目录节点
	void *data;
	atomic_t count;		/* use count */
	atomic_t in_use;	/* number of callers into module in progress; */
			/* negative -> it's going away RSN */
	struct completion *pde_unload_completion;
	struct list_head pde_openers;	/* who did ->open, but not ->release */
	spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
	u8 namelen;
	char name[];
};

proc文件系统中的每个数据项的数据结构,都是由proc_dir_entry一个实例进行描述的。
装载proc文件系统
内核内部用于描述proc文件系统结构和内容的数据已经初始化之后,下一步是将该文件系统装载到目录树中,在内核添加新的文件系统时,会扫描一个链表,查找与该文件系统相关的file_system_type实例。

static struct file_system_type proc_fs_type = {
	.name		= "proc",
	.mount		= proc_mount,
	.kill_sb	= proc_kill_sb,
	.fs_flags	= FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
};
struct file_system_type {
	const char *name;
	int fs_flags;
#define FS_REQUIRES_DEV		1 
#define FS_BINARY_MOUNTDATA	2
#define FS_HAS_SUBTYPE		4
#define FS_USERNS_MOUNT		8	/* Can be mounted by userns root */
#define FS_USERNS_DEV_MOUNT	16 /* A userns mount does not imply MNT_NODEV */
#define FS_USERNS_VISIBLE	32	/* FS must already be visible */
#define FS_RENAME_DOES_D_MOVE	32768	/* FS will handle d_move() during rename() internally. */
	struct dentry *(*mount) (struct file_system_type *, int,
		       const char *, void *);
	struct dentry *(*mount2) (struct vfsmount *, struct file_system_type *, int,
			       const char *, void *);
	void *(*alloc_mnt_data) (void);
	void (*kill_sb) (struct super_block *);
	struct module *owner;
	struct file_system_type * next;
	struct hlist_head fs_supers;

	struct lock_class_key s_lock_key;
	struct lock_class_key s_umount_key;
	struct lock_class_key s_vfs_rename_key;
	struct lock_class_key s_writers_key[SB_FREEZE_LEVELS];

	struct lock_class_key i_lock_key;
	struct lock_class_key i_mutex_key;
	struct lock_class_key i_mutex_dir_key;
};

proc文件系统超级块由proc_get_sb提供,此函数基于另一个内核辅助例程(get_sb_single),借助proc_fill_supper(主要负责用一些定义后从不改变的值来填充super_block的每个成员)来填充一个super_block的新实例。
在这里插入图片描述
proc_sops中对超级块的各个操作,其中收集内核管理proc文件系统所需的各个函数。
在这里插入图片描述
静态的proc_dir_entry实例:

/*
 * This is the root "inode" in the /proc tree..
 */
struct proc_dir_entry proc_root = {
	.low_ino	= PROC_ROOT_INO, 
	.namelen	= 5, 
	.mode		= S_IFDIR | S_IRUGO | S_IXUGO, 
	.nlink		= 2, 
	.count		= ATOMIC_INIT(1),
	.proc_iops	= &proc_root_inode_operations, 
	.proc_fops	= &proc_root_operations,
	.parent		= &proc_root,
	.subdir		= RB_ROOT,
	.name		= "/proc",
};

管理/proc数据项
1.数据项的创建和注册
新数据项分为两个步骤添加到proc文件系统,首先,创建proc_dir_entry的一个新实例,填充描述该数据项的所有需要的信息。
使用fs/proc/generic.c中的proc_register将其注册到proc文件系统中:

static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
	int ret;

	ret = proc_alloc_inum(&dp->low_ino);
	if (ret)
		return ret;

	write_lock(&proc_subdir_lock);
	dp->parent = dir;
	if (pde_subdir_insert(dir, dp) == false) {
		WARN(1, "proc_dir_entry '%s/%s' already registered\n",
		     dir->name, dp->name);
		write_unlock(&proc_subdir_lock);
		proc_free_inum(dp->low_ino);
		return -EEXIST;
	}
	write_unlock(&proc_subdir_lock);

	return 0;
}

创建数据项之后,注册到/proc文件系统步骤:
a.生成一个唯一一个proc内部编号,向数据项赋予身份,get_inode_number返回一个未使用的编号,用于为动态生成的数据项;
b.必须适当的设置proc_dir_entry实例的next和parent成员,将新数据项集成到proc文件系统的层次结构中;
c.如果此proc_dir_entry成员的proc_iopsproc_fops为NULL指针,那么需要根据文件类型,适当的设置指向file_operationsinode_operations结构实例的指针。
用于管理proc的数据项:
a.proc_mkdir创建一个新目录
b.proc_mkdir_mode:创建一个新目录,目录的访问权限可以显示指定。
c.proc_symlink:生成一个符号链接
d.remove_proc_entry:从目录中删除一个动态生成的数据项。
内核源码相关示例文件,在Documentation/DocBook/procfs_example.c.负责proc文件系统的读写例程和内核子系统之间的交互。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

<( ̄︶ ̄)Okay.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值