【linux kernel】start_kernel函数详解系列之proc_root_init

一、开篇

​ 本文所有代码出自linux内核版本:4.1.15

​ 在start_kernel函数中将调用proc_root_init()初始化proc文件系统的目录。该函数定义如下(/fs/proc/root.c):

void __init proc_root_init(void)
{
	int err;

	proc_init_inodecache();
	err = register_filesystem(&proc_fs_type);
	if (err)
		return;

	proc_self_init();
	proc_thread_self_init();
	proc_symlink("mounts", NULL, "self/mounts");

	proc_net_init();

#ifdef CONFIG_SYSVIPC
	proc_mkdir("sysvipc", NULL);
#endif
	proc_mkdir("fs", NULL);
	proc_mkdir("driver", NULL);
	proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */
#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
	/* just give it a mountpoint */
	proc_create_mount_point("openprom");
#endif
	proc_tty_init();
	proc_mkdir("bus", NULL);
	proc_sys_init();
}

proc_root_init()函数开始处,调用proc_init_inodecache()函数分配proc的inode缓存(proc_inode_cachep),如下代码片段(/fs/proc/inode.c):

void __init proc_init_inodecache(void)
{
	proc_inode_cachep = kmem_cache_create("proc_inode_cache",
					     sizeof(struct proc_inode),
					     0, (SLAB_RECLAIM_ACCOUNT|
						SLAB_MEM_SPREAD|SLAB_PANIC),
					     init_once);
}

上述代码中,proc_inode_cachep是一个指向struct kmem_cache结构的指针。当对proc文件系统分配inode时,将在proc_inode_cachep指向的slab缓存区域中分配内存,这个操作由proc_alloc_inode()函数完成,如下代码:

static struct inode *proc_alloc_inode(struct super_block *sb)
{
	/* 省略了部分代码 */
    
	ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, GFP_KERNEL);
    
	/* 省略了部分代码 */
	return inode;
}

当释放proc文件系统分配的inode时,将调用proc_i_callback()函数释放proc_inode_cachep指向的slab缓存区(proc_i_callback()函数被proc_destroy_inode()调用),如下代码所示:

static void proc_i_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	kmem_cache_free(proc_inode_cachep, PROC_I(inode));
}

对于proc文件系统来说,对proc_inode_cachep指向的slab缓存区域的分配和释放两个操作函数都被注册到了proc文件系统超级块的操作集合(proc_sops)中,如下代码所示(/fs/proc/inode.c):

static const struct super_operations proc_sops = {
    /* 分配inode */
	.alloc_inode	= proc_alloc_inode,
    /* 释放inode */
	.destroy_inode	= proc_destroy_inode,
    
	/* ......*/
    
};

回到proc_root_init()函数中,会继续调用register_filesystem()向linux内核注册proc文件系统,其文件系统的类型描述定义如下:

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,
};

在向内核中注册了proc文件系统后,会调用proc_self_init()函数(fs/proc/self.c)为self分配索引节点号(/proc/self目录指:访问/proc文件系统的进程)。

接着,将调用proc_setup_thread_self()函数,该函数将设置/proc/thread-self目录,其中包含有关当前线程的信息。如下代码片段:

	proc_self_init();
	proc_thread_self_init();

紧接着,会创建/proc/self/mounts,它将包含调用的挂载点:

proc_symlink("mounts", NULL, "self/mounts");

接着会创建/proc/fs、/proc/driver、/proc/mounts、/proc/net、/proc/sys、/proc/tty相关proc文件系统的信息条目,如下代码:

   proc_net_init();

#ifdef CONFIG_SYSVIPC
	proc_mkdir("sysvipc", NULL);
#endif
	proc_mkdir("fs", NULL);
	proc_mkdir("driver", NULL);
	proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */
#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
	/* just give it a mountpoint */
	proc_create_mount_point("openprom");
#endif
	proc_tty_init();
	proc_mkdir("bus", NULL);

proc_root_init()函数的最后,会调用proc_sys_init()函数创建/proc/sys目录并初始化sysctl。


二、结尾

至此,proc_root_init()函数就分析完毕啦。总结一下,该函数主要用于为proc文件系统创建目录

我们可以使用proc_mkdir()函数创建自己的proc文件系统目录,例如小生这里创建了一个目录如下:

proc_mkdir("iriczhao", NULL);

编译linux内核后运行,在bash shell中输入ls /proc/,命令将显示我们自己定义的目录,如下图所示:
在这里插入图片描述
(当然,以上操作似乎无任何意义,这么做,无非加深对linux内核的理解啦。毕竟动手实践,永远是把控linux内核的最佳方式!)

linux内核如何向proc文件系统递交内核本身的信息,这又是另外的话题了…

搜索/关注【嵌入式小生】wx公众号,获取更多精彩内容>>>>
请添加图片描述

`nfs3_proc_create` 函数Linux 内核中用于处理 NFSv3 协议的 `CREATE` 操作的函数。它负责在 NFS 服务器上创建一个新文件。 以下是 `nfs3_proc_create` 函数的大致流程: 1. 首先,函数会检查所传递的参数的有效性,例如文件名、父目录的文件句柄等。 2. 接下来,函数会创建一个新的 RPC 请求,并设置相关的请求参数,包括操作类型(CREATE)、文件名、父目录的文件句柄等。 3. 然后,函数会调用 `nfs3_rpc_ops` 结构中的 `create` 函数指针,将 RPC 请求发送到 NFS 服务器。 4. 在 `create` 函数中,会构建一个 RPC 消息(NFSv3 CREATE 请求),并将请求的参数填充到消息中。 5. 函数会调用 `nfs3_proc_xdr_encode` 函数来将请求消息进行编码,并将编码后的数据发送给 NFS 服务器。 6. 当服务器接收到请求后,会执行相应的操作来创建新文件,并将操作结果返回给客户端。 7. 客户端接收到服务器的响应后,会调用 `nfs3_proc_xdr_decode` 函数来解码响应消息。 8. 解码后的响应数据会被提取出来,并根据操作结果进行处理。如果创建操作成功,则会返回新文件的属性信息;否则,会返回相应的错误码。 9. 最后,函数会清理请求相关的数据结构,并返回操作结果给调用者。 需要注意的是,上述流程仅为大致过程,具体的实现细节可能因内核版本和配置而有所不同。详细的函数流程可以查看相应内核版本的源代码文件(例如 `fs/nfs/nfs3proc.c`)来进行分析和了解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

iriczhao

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

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

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

打赏作者

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

抵扣说明:

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

余额充值