tcp/ip 协议栈实现2-socket文件系统

2023-05-16

core_initcall(sock_init)---net/socket.c

static int __init sock_init(void)
{
	int err;

	/*
	 *      Initialize sock SLAB cache.
	 */

	sk_init();

	/*
	 *      Initialize skbuff SLAB cache
	 */
	skb_init();

	/*
	 *      Initialize the protocols module.
	 */

	init_inodecache();

	err = register_filesystem(&sock_fs_type);
	if (err)
		goto out_fs;
	sock_mnt = kern_mount(&sock_fs_type);
	if (IS_ERR(sock_mnt)) {
		err = PTR_ERR(sock_mnt);
		goto out_mount;
	}

	/* The real protocol initialization is performed in later initcalls.
	 */

#ifdef CONFIG_NETFILTER
	netfilter_init();
#endif

#ifdef CONFIG_NETWORK_PHY_TIMESTAMPING
	skb_timestamping_init();
#endif

out:
	return err;

out_mount:
	unregister_filesystem(&sock_fs_type);
out_fs:
	goto out;
}

register_filesystem(&sock_fs_type);注册套接口文件系统
kern_mount(&sock_fs_type);挂载套接口文件系统
注册的文件系统的名字是sockfs,在/proc/filesystem看到的就是这个

static struct file_system_type sock_fs_type = {
 .name =  "sockfs",
 .mount = sockfs_mount,
 .kill_sb = kill_anon_super,
};


在应用层执行系统调用socket,connect,listen,accept等时,最终会统一调用到socket文件系统的sys_socketcall函数,位于net/socket.c
sys_socketcall用SYSCALL_DEFINE2包装起来了,2表示2个参数,展开之后就是sys_socketcall
SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
{
	unsigned long a[6];
	unsigned long a0, a1;
	int err;
	unsigned int len;

	if (call < 1 || call > SYS_SENDMMSG)
		return -EINVAL;

	len = nargs[call];
	if (len > sizeof(a))
		return -EINVAL;

	/* copy_from_user should be SMP safe. */
	if (copy_from_user(a, args, len))
		return -EFAULT;

	audit_socketcall(nargs[call] / sizeof(unsigned long), a);

	a0 = a[0];
	a1 = a[1];

	switch (call) {
	case SYS_SOCKET:
		err = sys_socket(a0, a1, a[2]);
		break;
	case SYS_BIND:
		err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
		break;
	case SYS_CONNECT:
		err = sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
		break;
	case SYS_LISTEN:
		err = sys_listen(a0, a1);
		break;
	case SYS_ACCEPT:
		err = sys_accept4(a0, (struct sockaddr __user *)a1,
				  (int __user *)a[2], 0);
		break;
	case SYS_GETSOCKNAME:
		err =
		    sys_getsockname(a0, (struct sockaddr __user *)a1,
				    (int __user *)a[2]);
		break;
	case SYS_GETPEERNAME:
		err =
		    sys_getpeername(a0, (struct sockaddr __user *)a1,
				    (int __user *)a[2]);
		break;
	case SYS_SOCKETPAIR:
		err = sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
		break;
	case SYS_SEND:
		err = sys_send(a0, (void __user *)a1, a[2], a[3]);
		break;
	case SYS_SENDTO:
		err = sys_sendto(a0, (void __user *)a1, a[2], a[3],
				 (struct sockaddr __user *)a[4], a[5]);
		break;
	case SYS_RECV:
		err = sys_recv(a0, (void __user *)a1, a[2], a[3]);
		break;
	case SYS_RECVFROM:
		err = sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
				   (struct sockaddr __user *)a[4],
				   (int __user *)a[5]);
		break;
	case SYS_SHUTDOWN:
		err = sys_shutdown(a0, a1);
		break;
	case SYS_SETSOCKOPT:
		err = sys_setsockopt(a0, a1, a[2], (char __user *)a[3], a[4]);
		break;
	case SYS_GETSOCKOPT:
		err =
		    sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
				   (int __user *)a[4]);
		break;
	case SYS_SENDMSG:
		err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]);
		break;
	case SYS_SENDMMSG:
		err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);
		break;
	case SYS_RECVMSG:
		err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
		break;
	case SYS_RECVMMSG:
		err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3],
				   (struct timespec __user *)a[4]);
		break;
	case SYS_ACCEPT4:
		err = sys_accept4(a0, (struct sockaddr __user *)a1,
				  (int __user *)a[2], a[3]);
		break;
	default:
		err = -EINVAL;
		break;
	}
	return err;
}


sys_socket系统调用
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
	int retval;
	struct socket *sock;
	int flags;

	/* Check the SOCK_* constants for consistency.  */
	BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC);
	BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK);
	BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK);
	BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK);

	flags = type & ~SOCK_TYPE_MASK;
	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
		return -EINVAL;
	type &= SOCK_TYPE_MASK;

	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;

	retval = sock_create(family, type, protocol, &sock);
	if (retval < 0)
		goto out;

	retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
	if (retval < 0)
		goto out_release;

out:
	/* It may be already another descriptor 8) Not kernel problem. */
	return retval;

out_release:
	sock_release(sock);
	return retval;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

tcp/ip 协议栈实现2-socket文件系统 的相关文章

随机推荐

  • Ubuntu安装Python3.8

    在ubuntu上安装Python有两种方法 在线安装和源码编译安装 方法1 xff1a 使用apt在线安装 1 更新软件包列表并安装必备组件 xff1a span class token function sudo span span cl
  • 使用免费负载生成器swingbench对oracle数据库进行压力测试(测试Oracle的功能或评估性能)

    1 Swingbench 简介 Swingbench 是一个免费负载生成器 xff08 和基准测试 xff09 xff0c 旨在对 Oracle 数据库 进行压力测试 目前最新版本 Swingbench 2 6 SwingBench 由负载
  • 在CentOS7上升级OpenSSL3和 OpenSSH9.0p1

    1 说明 CentOS7 自带的 OpenSSH 版本 xff08 OpenSSH 7 4p1 OpenSSL 1 0 2k fips 26Jan 2017 xff09 漏扫出很多高 风险漏洞 xff0c 预采用升级处理 xff08 升至
  • 编译升级OpenSSL报错:Can‘t locate IPC/Cmd.pm

    错误信息 span class token punctuation span root 64 dowhere openssl 3 0 3 span class token punctuation span span class token
  • 安装Paddlepaddle2.4.2以后导入模块报错: ImportError: libcudart.so.10.2: cannot open shared object file: No su

    问题描述 在使用 python3 8 安装 paddle 以后 xff0c 测试导入 paddle 报错 创建环境并安装 span class token builtin class name source span activate pa
  • 人工智能导论考前整理-思考题部分

    以下均为个人观点 xff08 也参考资料得到 侵删 xff09 xff0c 仅供参考 xff0c 可考试前用 我们学校的考点是基本都在上面了 xff08 考题雷达嘿嘿 xff09 xff0c 不同学校不太一样 xff0c 以下是我之前考前边
  • 自抗扰控制器中扩张状态观测器的设计

    状态观测器是根据系统的输入输出来确定系统内部状态变量的装置 xff0c 它的示意图如下 xff1a 在自抗扰控制器的设计过程中 xff0c 我们通常把未知的干扰都用 f f f 来表示 xff0c 如果利用状态观测器可以将未知的干扰观测出来
  • 前端页面小图标不显示问题

    这个问题困扰了我好久 xff0c 主要报错是Origin 39 http localhost 39 is therefore not allowed access 等 起因是我引入bootstrap框架后后端页面的一些小图标不显示 xff0
  • Thinkphp审核功能的实现

    审核功能经过几个小时的奋战终于完成了 xff0c 现在我就与广大网友分享我的成果 我定义未审核为 1 xff0c 审核通过为1 xff0c 审核不通过为0 下面请看HTML代码 lt div class 61 34 table respon
  • Thinkphp修改密码的实现

    密码修改是开发中很基础的一个功能 密码修改的HTML代码如下 span span lt form method 61 post class 61 form horizo ntal action 61 gt span span span st
  • 二维数组的输入和输出

    二维数组我知道的有两种方法 第一种方法是平时常见的方法 xff0c 用两个循环 xff0c 例如 for i 61 0 i lt 61 n 1 i 43 43 for j 61 0 j lt 61 n 1 j 43 43 cin gt gt
  • 怎样把网站前端页面扒取

    在网上经常看到一些很好看的页面 xff0c 这些页面其实都可以把代码扒取下来的 xff0c 可以用浏览器的另存为 xff0c 也有一些相应的软件 浏览器扒取 以火狐为例 右键鼠标点击网页另存为 然后保存即可 软件扒取 这种扒取的软件有很多种
  • 算法题1

    假设有这样一个国家 xff0c 其法律规定当公民月收入为x时 xff0c 若x gt 1 则每月应当缴纳的税金为x的因数中除了x之外的最大值 同时该国法律允许公民将月收入分成若干部分 每部分均为整数 xff0c 要求每部分收入都大于1 xf
  • 3.4日期处理

    include lt iostream gt include lt cstdio gt 平年和闰年的每月的天数 int month 13 2 61 0 0 31 31 28 29 31 31 30 30 31 31 30 30 31 31
  • 关于STL和Boost的理解

    xff11 xff0e STL STL是standard Template Library即标准模板库的英文缩写 xff0c 是惠普实验室开发的一系列软件的统称 从根本上讲 STL是一些 容器 的集合 xff0c 这些容器有list vec
  • Ubuntu 各版本号和名称对照

    版本开发代号中译发布日期支持结束时间内核版本桌面版服务器版4 10Warty Warthog多疣的疣猪2004 10 202006 04 302 6 85 04Hoary Hedgehog白发的刺猬2005 04 082006 10 312
  • 【无标题】安装ROS E: 无法定位软件包 ros-melodic-desktop-full

    一 遇到问题 二 可能的原因和解决方法 1 源换一下 xff1a xff08 1 xff09 我是看这位大佬的 5条消息 记录 解决Ubuntu安装ros报错E Unable to locate package ros kinetic de
  • 无线通信原理及协议栈(ZigBee、蓝牙等)解析

    1 天线 说起无线电通信 xff0c 不可不提起天线 在无线电设备中 xff0c 用来辐射和接收无线电波的装置称为天线 在发射端 xff0c 发射机产生的已调制的高频振荡电流 xff08 能量 xff09 经馈电 xff08 指被控制装置向
  • 串口Serial连接方式

    串口Serial连接方式 1 协议终端选择Serial 2 会话选项 xff0c 选择 串行 3 进入电脑 设备管理器 xff0c 查看USB Serial Port以及端口设置 串行选项根据端口设置配置 确定并连接即可
  • tcp/ip 协议栈实现2-socket文件系统

    core initcall sock init net socket c static int init sock init void int err Initialize sock SLAB cache sk init Initializ