内核连接器

来源:互联网 发布:连云港大数据产业园 编辑:程序博客网 时间:2024/04/30 02:30
Chinese translated version of Documentation\connector\connector.txt




If you have any comment or update to the content, please contact the
original document maintainer directly.  However, if you have a problem
communicating in English you can also ask the Chinese maintainer for
help.  Contact the Chinese maintainer if this translation is outdated
or if there is a problem with the translation.




Chinese maintainer:huneng <huneng1991@163.com>
---------------------------------------------------------------------
Documentation\connector\connector.txt的中文翻译




如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
译存在问题,请联系中文版维护者。




中文版维护者: 胡能  <huneng1991@163.com>
中文版翻译者: 胡能  <huneng1991@163.com>
中文版校译者: 胡能  <huneng1991@163.com>




以下为正文
---------------------------------------------------------------------


/*****************************************/
Kernel Connector.
内核连接器
/*****************************************/


Kernel connector - new netlink based userspace <-> kernel space easy
to use communication module.
内核连接器-新的网络连接器,基于用户空间<->内核空间,容易使用通信模块。


The Connector driver makes it easy to connect various agents using a
netlink based network.  One must register a callback and an identifier.
When the driver receives a special netlink message with the appropriate
identifier, the appropriate callback will be called.
连接器驱动程序使连接不通的代理变得简单,使用一个网络连接器。
连接器需要注册一个函数调用和标识符。
当驱动程序接收到一个特殊的网络连接器的附有相应的标识符的消息时,相应的回调会被调用。


From the userspace point of view it's quite straightforward:
从用户空间点看是十分直接的
socket();
bind();
send();
recv();


But if kernelspace wants to use the full power of such connections, the
driver writer must create special sockets, must know about struct sk_buff
handling, etc...  The Connector driver allows any kernelspace agents to use
netlink based networking for inter-process communication in a significantly
easier way:
但是如果内核空间想要去使用这种连接器所有的能量,驱动程序写操作器必须生成特别的套接字,
必须知道有关结构sk_buff,handling,等等。
连接器的驱动程序允许所有的内核空间代理使用网络连接器,通过一种十分简单的方式为内部进程交流,


int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
void cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask);


struct cb_id
{
__u32 idx;
__u32 val;
};


idx and val are unique identifiers which must be registered in the
connector.h header for in-kernel usage.  void (*callback) (void *) is a
callback function which will be called when a message with above idx.val
is received by the connector core.  The argument for that function must
be dereferenced to struct cn_msg *.
idx和val是唯一的标识符,必须被注册在connector.h头文件中,方便内核使用。
void(*callback)(void*)是一个回调函数,将在一个在idx.val上的消息被连接器核心接收到时调用。
函数的参数必须与结构cn_msg*无关。


struct cn_msg
{
struct cb_id id;


__u32 seq;
__u32 ack;


__u32 len;/* Length of the following data */
__u8 data[0];
};


/*****************************************/
Connector interfaces.
/*****************************************/


int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));


 Registers new callback with connector core.
 在连接器控制系统中注册新的回调。
 
 struct cb_id *id - unique connector's user identifier.
 唯一的连接器用户标识符。
 It must be registered in connector.h for legal in-kernel users.
 必须在connector.h中注册,为合法的内核用户。
 char *name - connector's callback symbolic name.
 连接器回调符号名。
 void (*callback) (struct cn..) - connector's callback.
 连接器回调。
 cn_msg and the sender's credentials
 cn_msg和发送者证书。


void cn_del_callback(struct cb_id *id);


 Unregisters new callback with connector core.
 注销新的回调函数在连接器内核。
 struct cb_id *id - unique connector's user identifier.
 唯一的连接器用户标识符。


int cn_netlink_send(struct cn_msg *msg, u32 __groups, int gfp_mask);


 Sends message to the specified groups.  It can be safely called from
 softirq context, but may silently fail under strong memory pressure.
 If there are no listeners for given group -ESRCH can be returned.
 发送消息到特别的组。它可以安全的从软中断上下文中调用,但是可能会毫无察觉的失败,
 在强大的内存压力下。
 如果没有对指定的组的监听者 会返回-ESRCH
 
 struct cn_msg * - message header(with attached data).
     消息头(含有附加数据)。
 u32 __group - destination group.
 目标组。
 If __group is zero, then appropriate group will
 be searched through all registered connector users,
 and message will be delivered to the group which was
 created for user with the same ID as in msg.
 If __group is not zero, then message will be delivered
 to the specified group.
 如果__group为0,合适的组会被搜索到,通过所有注册的连接器的用户,
 消息会被传递到组,在消息中为同一组的用户生成同样的ID。
 如果__group不为0,消息会被传送到特殊的组。
 int gfp_mask - GFP mask.


 Note: When registering new callback user, connector core assigns
 netlink group to the user which is equal to its id.idx.
 解释:当注册新的回调用户,连接器核心会分配网络连接器组给与id.idx相等的用户。


/*****************************************/
Protocol description.
协议描述
/*****************************************/


The current framework offers a transport layer with fixed headers.  The
recommended protocol which uses such a header is as following:
目前的框架提供一个拥有固定头的转换层。
所以建议的协议是使用如下所示的头:


msg->seq and msg->ack are used to determine message genealogy.  When
someone sends a message, they use a locally unique sequence and random
acknowledge number.  The sequence number may be copied into
nlmsghdr->nlmsg_seq too.
msg->seq和msg->ack是用来决定消息类型的。
当某个部分发送一个消息,他们会使用逻辑上唯一的序列和随机确认的数。
序列数可能会被复制到nlmsghdr->nlmsg_seq。


The sequence number is incremented with each message sent.
序列数是同每个发送来的消息一同增长的。


If you expect a reply to the message, then the sequence number in the
received message MUST be the same as in the original message, and the
acknowledge number MUST be the same + 1.
如果你想要一个消息回应,在接收到的消息的序列数中必须同原始的消息一致,
而且确认数必须等于序列数+1。


If we receive a message and its sequence number is not equal to one we
are expecting, then it is a new message.  If we receive a message and
its sequence number is the same as one we are expecting, but its
acknowledge is not equal to the acknowledge number in the original
message + 1, then it is a new message.
如果我们收到一个消息而且它的序列数是不等于我们所期望的,那么他是一个新的消息。
如果我们收到一个消息而且它的序列数和我们所期望的一样,但是他的确认号不等于原始消息的确认号+1,
那么他是一个新消息。


Obviously, the protocol header contains the above id.
显然的,协议头包含上述的id。


The connector allows event notification in the following form: kernel
driver or userspace process can ask connector to notify it when
selected ids will be turned on or off (registered or unregistered its
callback).  It is done by sending a special command to the connector
driver (it also registers itself with id={-1, -1}).
连接器允许事件通知按如下形式:内核驱动程序或者用户空间进程可以请求连接器通知它,
当选择的ids将被打开或关闭(注册了或者没注册回调)。
这个过程的完成是通过发送一个特别的命令到连接器驱动程序(这当然也要使用id={-1, -1}来注册它。


As example of this usage can be found in the cn_test.c module which
uses the connector to request notification and to send messages.
作为这种使用方式的例子可以在cn_test.c模块中找到,在那里面,
使用连接器来回答通知并且发送消息。


/*****************************************/
Reliability.
可信任度。
/*****************************************/


Netlink itself is not a reliable protocol.  That means that messages can
be lost due to memory pressure or process' receiving queue overflowed,
so caller is warned that it must be prepared.  That is why the struct
cn_msg [main connector's message header] contains u32 seq and u32 ack
fields.
网络连接器自身是一个可信赖的协议。
这就意味着消息可能因为内存压力或者进程接收队列过载而丢失,
所以调用者警告他必须准备好。
这就是为什么结构cn_msg[主要的连接器消息头]包含32位序列号和32位确认号域。


/*****************************************/
Userspace usage.
用户空间使用。
/*****************************************/


2.6.14 has a new netlink socket implementation, which by default does not
allow people to send data to netlink groups other than 1.
So, if you wish to use a netlink socket (for example using connector)
with a different group number, the userspace application must subscribe to
that group first.  It can be achieved by the following pseudocode:
2.6.14有一个新的连接器套接字实现,默认情况下不允许发送数据到多于一个组的网络连接器。
所以,如果你希望使用一个网络连接器套接字(例如使用连接器),附有不同的组数,
用户空间应用程序必须首先描述那个组。
可以通过下面的步骤来实现:


s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);


l_local.nl_family = AF_NETLINK;
l_local.nl_groups = 12345;
l_local.nl_pid = 0;


if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
perror("bind");
close(s);
return -1;
}


{
int on = l_local.nl_groups;
setsockopt(s, 270, 1, &on, sizeof(on));
}


Where 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket
option.  To drop a multicast subscription, one should call the above socket
option with the NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.
SOL_NETLINK大于270,并且1是一个NETLINK_ADD_MEMBERSHIP套接字选项。
丢掉一个多投射的订阅,必须调用上述以NETLINK_DROP_MEMBERSHIP为参数的套接字选项,
这个参数被定义为0。


2.6.14 netlink code only allows to select a group which is less or equal to
the maximum group number, which is used at netlink_kernel_create() time.
In case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use
group number 12345, you must increment CN_NETLINK_USERS to that number.
Additional 0xf numbers are allocated to be used by non-in-kernel users.
2.6.14版本的网络连接器代码只允许选择一个不大于最大组数的组,在调用
netlink_kernel_create()时会调用。


Due to this limitation, group 0xffffffff does not work now, so one can
not use add/remove connector's group notifications, but as far as I know, 
only cn_test.c test module used it.
因为这个限制,组0xffffffff并不工作,所以不能使用add/remove连接器组通知,
就我所知,只有cn_test.c测试模型可以使用它。


Some work in netlink area is still being done, so things can be changed in
2.6.15 timeframe, if it will happen, documentation will be updated for that
kernel.
在网络连接器领域的工作任然在被使用中,所以一些事物的改变表现在2.6.15时间框架中,
如果发生了,文件将会为那个版本的时间框架改变。