ãLinuxã«ã¼ãã«2.6解èªå®¤ãï¼ä»¥éãæ§çï¼åºçå¾ãLinuxã«ã¯å¤ãã®æ©è½ã追å ãããã¨ã³ã¿ã¼ãã©ã¤ãºé åãã¯ããã¨ããæ§ã ãªå ´æã§ä½¿ãããããã«ãªãã¾ããã ããã«ä¼´ãã³ã¼ããè¥å¤§ãã¤è¤éåããå¤ãã®ã¨ã³ã¸ãã¢ã«ã¨ã£ã¦è§£èªä¸è½ãªãã©ãã¯ããã¯ã¹ã¨ãªã£ã¦ãã¾ãã ä¸çä¸ã®ãããã¨ã³ã¸ãã¢éã®åä½ã§ããLinuxã«ã¼ãã«ã«ã¡ã¹ãå ¥ãããã©ãã¯ããã¯ã¹ãããéãã¦ãæã«å¥½å¥å¿ã®èµ´ãã¾ã¾ã«ã«ã¼ãã«ã®ä¸çã解èªãããæ°Linuxã«ã¼ãã«è§£èªå®¤ãããã¸ã§ã¯ãã
æ¬ç¨¿ã§ã¯ãæ§ç第21ç« ã§è§£èª¬ããã¦ããã½ã±ããã¤ã³ã¿ã¼ãã§ã¼ã¹ã«ã¤ãã¦ãã«ã¼ãã«v6.8ã®ã³ã¼ãããã¼ã¹ã«ä¸»ã«ãã¼ã¿æ§é ãä¸å¿ã«è§£èª¬ãã¾ãã(ååã®ç¶ãã«ãªãã¾ãã)
- ã¯ããã«
- 1. socketæ§é ä½ã¨sockæ§é ä½ã®çæ
- 2. ã½ã±ããã®ãã¡ã¤ã«æ½è±¡åå¦ç
- æå¾ã«
- 次åäºå
å·çè : é ç° å²å¿ã稲è è²´æ
â» ãæ°Linuxã«ã¼ãã«è§£èªå®¤ãé£è¼è¨äºä¸è¦§ã¯ãã¡ã
ã¯ããã«
ååã®è¨äºã§ã¯ãsocketæ§é ä½ã¨sockæ§é ä½ã«ã¯ãã¼ãºã¢ãããã¦ãé¢é£ãããã¼ã¿æ§é ã¨ã¨ãã«ã½ã±ããæä½å¦çã®æµããè¦ã¦ãã¾ããã
ããããsocketæ§é ä½ãsockæ§é ä½ãã¨ãã¾ããã¼ã¿æ§é ã¯å³1ã®ããã«ãã£ã¨å¤ãåå¨ãã¾ãã
ç¹ã«socketæ§é ä½ã¨sockæ§é ä½ããã½ã±ããã®å®ä½ã§ãããã¨ãã¦è¦ã¦ãã¾ããããå®éã«ã¯ãããã®æ§é ä½ã¯ããæ§é ä½ã®ã¡ã³ãå¤æ°ã¨ãã¦åå¨ãã¦ãã¾ãã
â»å³1ã¯socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
ã«ããçæããããã¼ã¿æ§é ã®ä¾ã§ãããããã³ã«ã«ãã£ã¦ä¸é¨ãã¼ã¿æ§é ã¯å¤åãã¾ãã
ä»åã¯socket(2)
ã·ã¹ãã ã³ã¼ã«ã«ãã£ã¦ãããã®å種ãã¼ã¿æ§é ãã©ã®ããã«çæãããé¢é£ã¥ãããã¦ããã®ããè¦ã¦ããããã¨æãã¾ãã
ååã®è¨äºã§ãåæ§ã§ããããã½ã±ããçæã®ã¤ãã¦ããããã³ã«ã«ãã£ã¦å¦çãç°ãªãé¨åãå¤åã«ããã¾ãã
ååã¨åæ§ã«æ¬è¨äºã§ãsocket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
ãå®è¡ããã¨ãã®å¦çã追ã£ã¦ããããã¨æãã¾ãã
ããã§ã¯æ©éãã½ã±ããçæã®å
¨ä½ã®æµãã俯ç°ããããã«ãsocket(2)
ã·ã¹ãã ã³ã¼ã«ã®ã½ã¼ã¹ã³ã¼ã(__sys_socket()
é¢æ°)ãè¦ã¦ã¿ã¾ãããã
int __sys_socket(int family, int type, int protocol) { struct socket *sock; int flags; sock = __sys_socket_create(family, type, update_socket_protocol(family, type, protocol)); ... return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK)); }
__sys_socket()
é¢æ°ã§ã¯å¤§ãã2ã¤ã®å¦çãããã¯ã«åããã¦ãããã¨ããããã¾ãã
__sys_socket_create()
socketæ§é ä½ãsockæ§é ä½çã®ã½ã±ããã®å®ä½ã¨ãªããã¼ã¿æ§é ãæ§ç¯/çæããsock_map_fd()
fileæ§é ä½ãdentryæ§é ä½ãçæããã¡ã¤ã«æ½è±¡åå¦çãè¡ã
æ¬è¨äºã§ã2ã¤ã®å¦çãããã¯ããããã«ã¤ãã¦è§£èª¬ãã¦ããããã¨æãã¾ãã
ãªããå
ã«å
¨ä½ã®å¦çã®æµããç¥ãããæ¹ã¯ãæ¬è¨äºã®æå¾ã«é¢æ°ã®å¼ã³åºãé¢ä¿ã¨å¦çå
容ã«ã¤ãã¦å³ç¤ºãã¦ãã¾ã(å³14)ã®ã§ããã¡ããåç
§ãã ããã
1. socketæ§é ä½ã¨sockæ§é ä½ã®çæ
æ¬ç« ã§ã¯__sys_socket()
é¢æ°ã®1ã¤ç®å¦çãããã¯ã§ããã__sys_socket_create()
ã«ã¤ãã¦ã¿ã¦ããã¾ãã
__sys_socket() âââ __sys_socket_create() ... æ¬ç« ã§è§£èª¬ âââ sock_map_fd() ... æ¬¡ç« ã§è§£èª¬
ã¾ããæ¬ç« ã§ã¯ãã¼ã¿çæ/é¢é£ä»ãã¨ãã観ç¹ã«ããã¦ããããã³ã«ä¾åé¨åã¨éä¾åé¨åã«ããã¦è§£èª¬ãããã¨æãã¾ãã å³1ãç°¡ç¥åãããã®ã«è§£èª¬ç¯å²ãéããã¨å³2ã®ããã«ãªãã¾ãã
å®éã«ã½ã¼ã¹ã³ã¼ãã¬ãã«ã§ãããããã以éã§è§£èª¬ããæµãã§ãã¼ã¿çæ/é¢é£ä»ããè¡ããã¾ãã
1.1. socketæ§é ä½ã®çæ
æåã«socketæ§é ä½ã®çæå¦çã«ã¤ãã¦ã¿ã¦ã¿ã¾ãããã
socketæ§é ä½ã¯__sys_socket_create()
é¢æ°ãèµ·ç¹ã¨ããã以ä¸ã®ããã¼ã§çæããã¾ãã
__sys_socket_create() âââ __socket_create() âââ sock_alloc() ï¼ âââ ... ï¼ âââ sock_mnt->mnt_sb->s_op->alloc_inode ... sock_allocæ§é ä½(socketæ§é ä½)ã®çæ
ããã¼ã¨è¨ãã¤ã¤éä¸çµè·¯ãããªãçç¥ãã¦ãã¾ã£ã¦ãã¾ãããæçµçã«ã¯alloc_inode
ã«ç»é²ããã¦ããã³ã¼ã«ããã¯é¢æ°ã§socketæ§é ä½ã¯çæããã¾ãã
ã½ã±ããã¯sockfsã¨ããçä¼¼ãã¡ã¤ã«ã·ã¹ãã ã¨ãã¦å®è£
ããã¦ãããsock_mnt
(vfsmountæ§é ä½)ãã¾ãã«sockfsã表ç¾ãã¦ãã¾ãã
ããã¦ãç¶ãmnt_sb->s_op
ã¯sockfsã«å¯¾ãã(ã¹ã¼ãã¼ãããã¯ã®)æä½ã§ãããsocketæ§é ä½ã¯inodeã確ä¿ããæè(=alloc_inode
)ã§çæããã¦ãããã¨ããããã¾ãã
å®éã«alloc_inode
ã«ç»é²ããã¦ããsock_alloc_inode()
é¢æ°ã§ã¯ãsocketæ§é ä½ãinodeæ§é ä½ã¨ä¸ç·ã«ãsocket_allocæ§é ä½ã¨ãã¦çæ(=ã¡ã¢ãªç¢ºä¿)ãã¦ãã¾ãã
struct socket_alloc { struct socket socket; struct inode vfs_inode; };
static struct inode *sock_alloc_inode(struct super_block *sb) { struct socket_alloc *ei; ei = alloc_inode_sb(sb, sock_inode_cachep, GFP_KERNEL); // çè ã³ã¡ã³ã: socketæ§é ä½ãå«ãsocket_allocæ§é ä½ãçæ ... return &ei->vfs_inode; }
ãã®ããã«socketæ§é ä½ã¯çä¼¼ãã¡ã¤ã«ã·ã¹ãã (sockfs)ã«ãã£ã¦ãinodeã確ä¿ããæèã§çæããã¾ãã
1.2. ãããã³ã«ä¾åé¨ã®å¦ç
æ¬ç¯ã§ã¯ãããã³ã«ã«ä¾åãã以ä¸ã®ãã¼ã¿æ§é ãã©ã®ããã«çæ/é¢é£ä»ãããã¦ããããè¦ã¦ããã¾ãã
ãããã³ã«ã«ä¾åãããã¼ã¿é¨åã¯å¤§ãã次ã®2段éã§æ§ç¯ããã¾ãã
ãã¼ã¿çæé¢æ°ã®ç¹å®
å³4ã®æ°´è²ã§ç¤ºãããé åã®ãã¼ã¿æ§ç¯å¦ç(é¢æ°)ã¯ãããã³ã«ãã¡ããªã¼ãã¨ã«ç¨æããã¦ãã¾ãã
ã¾ãã¯ããã®ãã¼ã¿çæé¢æ°ãç¹å®ããå¿ è¦ãããã¾ãããããã³ã«ä¾åãã¼ã¿ã®æ§ç¯
ãããã³ã«ã«é©ããå種ãã¼ã¿æ§é (å³4ã®æ°´è²é åå ã®3ã¤ã®ãã¼ã¿æ§é )ãçæ/é¢é£ä»ãããã¾ãã
1.2.1 ãããã³ã«ä¾åé¨åã®ãã¼ã¿æ§ç¯é¢æ°ã®ç¹å®: inet_create()
åè¿°ã®ã¨ãããã¾ãã¯ãããã³ã«ãã¡ããªã¼ãã¨ã«ç¨æããã¦ãããã¼ã¿çæé¢æ°ãç¹å®ããå¿
è¦ãããã¾ãã
socket(2)
ã·ã¹ãã ã³ã¼ã«ã§ã¯ç¬¬1å¼æ°ã«ãããã³ã«ãã¡ããªã¼ãæå®ããã¦ããã®ã§ãããã使ã£ã¦çæé¢æ°ãç¹å®ãããã¨ã«ãªãã¾ãã
ãã¼ã¿çæé¢æ°ã¯ä»¥ä¸ã®net_families[family]->create
ã«ã³ã¼ã«ããã¯é¢æ°ã¨ãã¦ç»é²ããã¦ããã
net_families
é
åã®ã¨ã³ããªã¼ãç¹å®ãããã¨ã§ãé¢æ°ãç¹å®ããããã¨ã«ãªãã¾ãã
__sys_socket_create() âââ __socket_create() âââ sock_alloc() | âââ ... | âââ sock_mnt->mnt_sb->s_op->alloc_inode ... åç¯ã§è§£èª¬ âââ net_families[family]->create ... ãããã³ã«ãã¡ããªã¼ãã¨ã®ãã¼ã¿çæé¢æ°
ããã§ãnet_families
é
åã«ã¤ãã¦è¦ã¦ããã¾ãããã
net_families
ã¯ãnet_proto_familyæ§é ä½ã¸ã®ãã¤ã³ã¿ãã®é
åã«ãªã£ã¦ãã¾ãã
static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
struct net_proto_family { int family; int (*create)(struct net *net, struct socket *sock, int protocol, int kern); struct module *owner; };
å®ç¾©ããnet_proto_familyæ§é ä½ã¯ããã³ã«ãã¡ããªã¼(.family
)ã¨ãããã«å¯¾å¿ãããã¼ã¿çæé¢æ°(.create
)ã対å¿ä»ããããã®æ§é ä½ã§ãããã¨ããããã¾ãã
詳細ã¯å²æãã¾ãããåããã³ã«ãã¡ããªã¼ãåæåæã«sock_register()
ãå¼ã³åºããã¨ã§ã.family
ãã¤ã³ããã¯ã¹ã¨ãã¦èªèº«ã®net_proto_familyæ§é ä½ãnet_families
é
åã«ç»é²ããã¾ãã
ããªãã¡ãå³5ã«ç¤ºãããã«socket(2)
ã·ã¹ãã ã³ã¼ã«ã®ç¬¬1å¼æ°ã§æ¸¡ããããããã³ã«ãã¡ããªã¼ãã¤ã³ããã¯ã¹ã¨ãã¦ããã¼ã¿çæé¢æ°ãç¹å®ãããã¨ãã§ãã¾ãã
å³5ããä»åã®ä¾(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
)ã§ã¯ãnet_families[PF_INET]->create
ç»é²ããã¦ããinet_create()
ãå®è¡ããããã¨ããããã¾ãã
1.2.2 ãããã³ã«ä¾åãã¼ã¿ã®æ§ç¯
åç¯ã§ãã¼ã¿çæé¢æ°ãinet_create()
é¢æ°ã§ãããã¨ãåããã¾ããã
æ¬ç¯ã§ã¯inet_create()
é¢æ°å
ã®å¦çã«ã¤ãã¦ã¿ã¦ããã¾ãã
ä¾åãã¼ã¿ã®ãã¹ã¦: inet_protoswæ§é ä½
inet_create()
ã§ã¯ãå³4ã«ç¤ºãããããã³ã«ä¾åé¨å(æ°´è²é åå
)ã®ãã¼ã¿ãçæ/é¢é£ä»ãããã¾ãã
ããã§ããããã³ã«ä¾åé¨åã®3ã¤ã®ãã¼ã¿æ§é ã«ã¤ãã¦ãããããå¿ è¦ãªå¦çã¨æ å ±çãæ´çãã¦ã¿ã¾ãããã
æ§é ä½ | å¿ è¦ãªå¦ç | å¦çã«å¿ è¦ãªæ å ± | å®éã®æ å ± |
---|---|---|---|
sockæ§é ä½(XXX_sockæ§é ä½) | çæ(=ã¡ã¢ãªç¢ºä¿) | 確ä¿ãã¹ãã¡ã¢ãªãµã¤ãº | sizeof(struct tcp_sock) |
proto_opsæ§é ä½ | é¢é£ä»ã(â ã¡ã¢ãªç¢ºä¿) | ãããã³ã«ã«å¯¾å¿ãããã¼ã¿æ§é ã®ãã¤ã³ã¿ | &net_stream_ops |
protoæ§é ä½ | é¢é£ä»ã(â ã¡ã¢ãªç¢ºä¿) | ãããã³ã«ã«å¯¾å¿ãããã¼ã¿æ§é ã®ãã¤ã³ã¿ | &tcp_prot |
å®ã¯ãããã®ãå¦çã«å¿ è¦ãªæ å ±ããéç´ããã¦ããæ§é ä½ãããã¾ãã ããã以ä¸ã®inet_protoswæ§é ä½ã«ãªãã¾ãã
struct inet_protosw { struct list_head list; /* These two fields form the lookup key. */ unsigned short type; /* This is the 2nd argument to socket(2). */ unsigned short protocol; /* This is the L4 protocol number. */ struct proto *prot; const struct proto_ops *ops; unsigned char flags; /* See INET_PROTOSW_* below. */ };
è足ã§ãããinet_protoswæ§é ä½ã管çããinetsw
é
å(詳細ã¯å¾è¿°)ã®å®£è¨ãè¦ãã¨æ¬¡ã®ãããªã³ã¡ã³ããããã¾ãã
/* The inetsw table contains everything that inet_create needs to * build a new socket. */ static struct list_head inetsw[SOCK_MAX];
ã³ã¡ã³ãã«ãinetsw
é
å(inet_protoswæ§é ä½)ã«ã¯inet_create()
ã®å¦çã«å¿
è¦ãªãã®ããã¹ã¦è©°ã¾ã£ã¦ããã¨ããæ¨ãæ¸ããã¦ãã¾ããã
話ãæ»ãã¦inet_protoswæ§é ä½ã«ã¤ãã¦è¦ã¦ããã¾ãã
inet_protoswæ§é ä½ã«ã¯ã.type
ã¨.protocol
ã¨ããã¡ã³ãå¤æ°ãæã£ã¦ãããã¨ããããã¾ãã
ãã®.type
ã¨.protocol
ã«ã¯ã½ã±ããã¿ã¤ãã¨ãããã³ã«(çªå·)ãå
¥ããããããsocket(2)
ã®ç¬¬2,3å¼æ°ã«å¯¾å¿ããå¤ãå
¥ãã¾ãã
ããªãã¡ãinet_protoswæ§é ä½ã¯ãããã³ã«(+ã½ã±ããã¿ã¤ã)ã¨ãããã³ã«ä¾åã®ãã¼ã¿æ§é çã対å¿ä»ãã¦ããã¨è¨ãã¾ãã
å®éã«ä»åã®ä¾(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
)ã§ç¨ããããinet_protoswæ§é ä½ã®ãªãã¸ã§ã¯ããè¦ã¦ã¿ã¾ãããã
static struct inet_protosw inetsw_array[] = { { .type = SOCK_STREAM, .protocol = IPPROTO_TCP, .prot = &tcp_prot, .ops = &inet_stream_ops, .flags = INET_PROTOSW_PERMANENT | INET_PROTOSW_ICSK, }, ... };
ãããã«.type
ã¨.protocol
ã®å¤ãsocket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
ã®ç¬¬2,3å¼æ°ã¨ä¸è´ãã¦ãããã¨ããããã¾ããã
ããã¦å³7ã«ç¤ºãã¨ããã.prot
ã.ops
ã®å¤ããã®ã¾ã¾ããããã³ã«ã«å¯¾å¿ãããã¼ã¿æ§é ã«ãªã£ã¦ãããã¨ãã確ä¿ãã¹ãã¡ã¢ãªãµã¤ãºããã¼ã¿ã辿ããã¨ã§ç¹å®ã§ãããã¨ããããã¾ãã
ã¤ã¾ããé©åãªinet_protoswæ§é ä½ã®ãªãã¸ã§ã¯ããç¹å®ã§ããã°ããããã³ã«ä¾åã®ãã¼ã¿é¨åã¯çæ/é¢é£ã¥ããã§ããã¨ãããã¨ã«ãªãã¾ãã ããã§ã¯ããã®ãããã³ã«ã«å¯¾å¿ããinet_protoswæ§é ä½ã®ãªãã¸ã§ã¯ãã¯ã©ã®ããã«ç¹å®ãã¦ããã®ã§ããããã
inet_protoswæ§é ä½ã®ç¹å®
ããã§ã¯inet_protoswæ§é ä½ã®ãªãã¸ã§ã¯ããã©ã®ããã«ç®¡çããã¦ããã®ãã«ã¤ãã¦è¦ã¦ããã¾ãã
inet_protoswæ§é ä½ã®ãªãã¸ã§ã¯ãã¯inetsw
é
åã¨ãªã¹ãã«ãã£ã¦ç®¡çããã¦ãã¾ãã
/* The inetsw table contains everything that inet_create needs to * build a new socket. */ static struct list_head inetsw[SOCK_MAX];
inetsw
é
åã¯list_headæ§é ä½ã®é
åã§å³8ã®ããã«åã¨ã³ããªã¼ããªã¹ãã®å
é è¦ç´ ãæã示ãæ§é ã«ãªã£ã¦ãã¾ãã
inet_protoswæ§é ä½ã¯åä¸.type
ãã¨ã«ãªã¹ãã¨ãã¦ã¾ã¨ããããåãªã¹ãã®å
é è¦ç´ ãinetsw
é
åã®åã¨ã³ããªã¼ãæã示ãã¦ãã¾ãã
ãã®ããã«ãã¼ã¿ãæ§æãããã¨ã§ã.type
(inetswé
åã®ã¨ã³ããªã¼ã®ç¹å®)â.protocol
(ãªã¹ãã®è¦ç´ ã®ç¹å®)ã®é ã§ç®çã®inet_protoswæ§é ä½ãè¦ã¤ãåºããã¨ãã§ãã¾ãã
æå¾ã«æ¬ç¯ã®æµããå³9ã«ã¾ã¨ãã¾ããã
è£è¶³: sockæ§é ä½ã¨tcp_sockæ§é ä½ã®é¢ä¿
ããã¾ã§ã®è§£èª¬ã§ãsockæ§é ä½ãçæããå¦çã§ã¯ããsockæ§é ä½ãå«ãtcp_sockæ§é ä½ããçæãããã¨ãã表ç¾ããã¦ãã¾ããã ããã¯ããã®éãã§ã¯ããã®ã§ããå®éã«ã½ã¼ã¹ã³ã¼ãã追ã£ã¦ã¿ãã¨ãä¸è¦ãsockæ§é ä½ã®ã¿ãçæãã¦ããããã«è¦ãã¾ãã
static int inet_create(struct net *net, struct socket *sock, int protocol, int kern) { struct sock *sk; ... sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, kern); // çè ã³ã¡ã³ã: ããã§tcp_sockæ§é ä½ãçæ ... }
sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, kern);
ã§tcp_sockæ§é ä½ã®ã¡ã¢ãªã確ä¿ãã¦ãã¾ããã
é¢æ°ã®è¿ãå¤ãsockæ§é ä½ã¸ã®ãã¤ã³ã¿åã«ãªã£ã¦ãããããä¸è¦ããã¨sockæ§é ä½ã®ã¡ã¢ãªã確ä¿ãã¦ããããã«æãã¾ãã
(sk_alloc()
ã¨ããé¢æ°åãsockæ§é ä½ã®ã¡ã¢ãªé åã確ä¿ãããã«æãã¾ãã)
ããã§tcp_sockæ§é ä½ã®æ§é ãè¦ã¦ã¿ã¾ãããã
tcp_sockæ§é ä½ã§ã¯å é ã®ã¡ã³ãå¤æ°ã®æ§é ä½ãé 次ãã¹ããã¦ãããæçµçã«ã¯sockæ§é ä½ã«ãã©ãçããã¨ããããã¾ãã å³ä¸ã®ç°¡ç¥çã«ç¤ºããããæ§é ä½ã®å é ã®ã¡ã³ãå¤æ°(æ§é ä½)ãé 次ãã¹ããã¦ããå ´åããããã®ãã¤ã³ã¿å¤ã¯åä¸ã«ãªãã¾ãã ãã®ããã確ä¿ããtcp_sockæ§é ä½ã®ã¡ã¢ãªé åã®å é ã¢ãã¬ã¹ãsockæ§é ä½ã®ãã¤ã³ã¿ã¨ãã¦æ±ã£ã¦ãæ´åãããã¨ã«ãªãã¾ãã
2. ã½ã±ããã®ãã¡ã¤ã«æ½è±¡åå¦ç
åç« ã§ã¯__sys_socket_create()
é¢æ°ãèµ·ç¹ã«å¦çã辿ããã½ã±ããã®å®ä½ã¨ãªãsocketæ§é ä½ã¨sockæ§é ä½ã®ãã¼ã¿çæéç¨ãè¦ã¦ãã¾ããã
æ¬ç« ã§ã¯ã½ã±ããã®ãã¡ã¤ã«æ½è±¡åå¦çã¨ãã¦fileæ§é ä½ã®çæã«ã¤ãã¦è¦ã¦ããã¾ãã
ã¾ãã¯ä»¥ä¸ã®sock_map_fd()
é¢æ°ãè¦ã¦ã¿ã¾ãããã
__sys_socket() âââ __sys_socket_create() ... åç« ã§è§£èª¬ âââ sock_map_fd() ... æ¬ç« ã§è§£èª¬
static int sock_map_fd(struct socket *sock, int flags) { struct file *newfile; int fd = get_unused_fd_flags(flags); // çè ã³ã¡ã³ã: ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãç¢ºä¿ ... newfile = sock_alloc_file(sock, flags, NULL); // çè ã³ã¡ã³ã: fileæ§é ä½ãçæ if (!IS_ERR(newfile)) { fd_install(fd, newfile); // çè ã³ã¡ã³ã: ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¨fileæ§é ä½ãç´ã¥ã return fd; } ... }
sock_map_fd()
é¢æ°ã§ã¯ä¸»ã«ä»¥ä¸ã®æµãã§å¦çãè¡ã£ã¦ãããã¨ããããã¾ãã
1. get_unused_fd_flags()
ã§ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã確ä¿
2. sock_alloc_file()
ã§fileæ§é ä½ãçæ
3. fd_install()
ã§ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¨fileæ§é ä½ãç´ã¥ã
ããã§ã¯fileæ§é ä½ãçæãã¦ããsock_alloc_file()
é¢æ°ãè¦ã¦ã¿ã¾ãã
struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) { struct file *file; if (!dname) dname = sock->sk ? sock->sk->sk_prot_creator->name : ""; file = alloc_file_pseudo(SOCK_INODE(sock), sock_mnt, dname, O_RDWR | (flags & O_NONBLOCK), &socket_file_ops); // çè ã³ã¡ã³ã: fileæ§é ä½ã®çæ ... file->f_mode |= FMODE_NOWAIT; sock->file = file; // çè ã³ã¡ã³ã: socketæ§é ä½ã«fileæ§é ä½ã®ãã¤ã³ã¿ãç»é² file->private_data = sock; // çè ã³ã¡ã³ã: fileæ§é ä½ã«socketæ§é ä½ã®ãã¤ã³ã¿ãç»é² stream_open(SOCK_INODE(sock), file); return file; }
fileæ§é ä½ã®çæå¦çã¯alloc_file_pseudo()
é¢æ°ã§è¡ã£ã¦ãã¾ãã
alloc_file_pseudo()
é¢æ°ãå¼ã³åºãéã«fileæ§é ä½ã«é¢é£ä»ãããããã¼ã¿æ§é ãå¼æ°ã§æ¸¡ãã¦ãããã¨ããããã¾ãã
ç¹ã«ååã®è¨äºã§è§£èª¬ãããã½ã±ããããã¡ã¤ã«æä½ã®ããã®ã·ã¹ãã ã³ã¼ã«(read(2)
/write(2)
ãªã©)ã§æ±ããããã«ããããã®é¢æ°ãã¼ãã«ã§ããsocket_file_ops
ãããã§ç´ã¥ãã¦ãããã¨ããããã¾ãã
ãã®ããã«ãã¼ã¿æ§é ãçæ/é¢é£ä»ããè¡ããã¨ã§ãå種ãããã³ã«ã«å¯¾å¿ãããã¼ã¿ãæ§ç¯ããã¾ãã
æå¾ã«
æ¬è¨äºã§ã¯socket(2)
ã·ã¹ãã ã³ã¼ã«ã®ãã¼ã¿çæå¦çã¨ãã観ç¹ã§è§£èª¬ãè¡ãã¾ããã
å³è§£ãå¿ãããçµæãã½ã¼ã¹ã³ã¼ãã¯ãã¾ãæ²è¼(åç
§)ããªãã¹ã¿ã¤ã«ã®è¨äºã«ãªã£ã¦ãã¾ãã¾ããã
ããã§æå¾ã«å
¨ä½çãªé¢æ°ã®å¼ã³åºãé¢ä¿ã¨å¦çå
容ã®å¯¾å¿ãå³14ã«ç¤ºãã¾ããã(çµå±å³ç¤º...ã)
次åäºå
次åããã¯ããã¤ã¹ãã©ã¤ãã¼ãèµ·ç¹ã¨ãããã±ããã®åä¿¡å¦çã«åãè¾¼ãã§ããããã¨æãã¾ãã