Passing file descriptor

来源:互联网 发布:tensorflow wordvec 编辑:程序博客网 时间:2024/05/29 15:38

在<<The Linux Programming Interface>>书中的61.13.2小节,有这样的描述:

The sendmsg() system call can do everything that is done by write(), send(), andsendto(); the recvmsg() system call can do everything that is done by read(),recv(), and recvfrom(). In addition, it also can perform scatter-gather I/O and transmit ancillary data (also known as control information).


这里说的意思是sendmsg/recvmsg除了能够进行正常的数据发送之外,还能够用来传递ancillary data数据。这里所说的ancillary data包括两类信息:file descriptor和sender credential。这里我们关注file descriptor,因为credential与之类似。


为了传递file descriptor,需要使用UNIX domain socket(可以为TDP,也可以是UDP)。使用UNIX domain socket就限定file descriptor仅仅在同一个host上有效,从机器A传递进程Pa的fd到机器B的进程Pb,显然不能使用。Why?UNIX-like机器上的文件索引结构如下:


既然fd是file descriptor table中的index,它指向当前系统上kernel中的open file description,为此从机器A传递到机器B,机器B上的open file description与A不同,为此跨机器传递fd无效。


通过查看linux-2.6.0的代码,发现其原理是:

o  Sender通过UNIX domain socket把passing file descriptor通过SCM_RIGHTS消息发送给receiver。

o  当该消息传递给kernel时,kernel会调用__send_fd_copy(cmsg,scm_cookie->fp)来把filedescriptor对应的openfile description的文件地址记录到scm_cookie->fp。

o  Receiver通过UNIX domain socket来接收消息时,会调用unix_dgram_recvmsg/unix_stream_recvmsg:

§ 它们会判断是否scm_cookie->fp为NULL。如果不为NULL,则表示正在传递file descriptor,此时会调用scm_fp_dup(scm_cookie->fp)来把存放在scm_cookie->fp中的文件地址复制到siocb->scm->fp。这里siocb是上面函数的局部变量,类型为structsock_iocb*。

§ 然后调用scm_recv(sock, msg, siocb->scm,flags) => scm_detach_fds(msg, siocb->scm)。

§ 在scm_detach_fds中,它会根据传递的file descriptor的个数,从index从0开始,分配未使用的fd,然后把该fd写入cmsg中对应该index的fd位置(这个才是在receiver中能够使用的fd)[因为要写入到userspace,所以这里使用的是put_user函数:put_user(new_fd,cmfptr)],然后把它关联到前面记录在siocb->scm->fp中的文件地址。至此,sender在cmsg中传递的filedescriptor已经被替代为receiver中有效的fd,它指向同sender中fd一样的openfile description对象。

o  上面的步骤发生在kernel,为此当receiver从调用函数recvmsg中返回时,从cmsg中得到的fd将是有效的fd,且指向与sender对应fd相同的文件(open file description)。


从上面我们可以可以理解到:当发送file descriptor时,并不会立刻执行fd的duplicate操作,仅仅增加open file description的f_count。而在sendmsg中的kernel部分,则会把sender进程中fd对应的openfile description中的file地址关联到该msg。而当接收消息时,则会在receiver进程中分配未使用的fd,然后替代cmsg中对应的fd的值,然后把cmsg中对应fd的文件指针(inopen file operation)关联到receiver中的fd。至此,sender/receiver中的fd指向相同的文件
原创粉丝点击