2017-05-19 5 views
1

Je travaille sur les sockets netlink, le code écrit pour l'application et le module noyau. Le module du noyau enverra des notifications régulièrement à l'application de l'espace utilisateur. Si l'application est tuée, le module noyau n'arrête pas d'envoyer une notification. Comment le noyau saura quand l'application est tuée? Pouvons-nous lier et délier l'utilisateur dans netlink_kernel_cfg à cette fin? J'ai beaucoup cherché mais je n'ai trouvé aucune information à ce sujet.Comment le noyau sait-il la présence de netlink dans l'espace utilisateur?

Répondre

1

Lorsqu'une application est supprimée sous Linux, tous les descripteurs de fichiers (y compris les descripteurs de socket) sont fermés. Afin d'avoir votre module de noyau prévenu lorsque l'application se ferme la prise NetLink vous devez implémenter l'option .unbind op dans struct netlink_kernel_cfg.

include/linux/netlink.h

/* optional Netlink kernel configuration parameters */ 
struct netlink_kernel_cfg { 
     unsigned int groups; 
     unsigned int flags; 
     void   (*input)(struct sk_buff *skb); 
     struct mutex *cb_mutex; 
     int    (*bind)(struct net *net, int group); 
     void   (*unbind)(struct net *net, int group); 
     bool   (*compare)(struct net *net, struct sock *sk); 
}; 

Définissez les paramètres de configuration dans votre module:

struct netlink_kernel_cfg cfg = { 
     .unbind = my_unbind, 
}; 

netlink = netlink_kernel_create(&my_netlink, ... , &cfg); 

Pour comprendre comment il est utilisé, notez le fragment suivant du protocole NetLink famille proto_ops définition:

static const struct proto_ops netlink_ops = { 
     .family =  PF_NETLINK, 
     .owner =  THIS_MODULE, 
     .release =  netlink_release, 

.release est appelée à la fermeture du socket (dans votre cas, en raison de l'application en cours de suppression).

Dans le cadre de son processus de nettoyage, netlink_release() a la mise en œuvre suivante:

net/NetLink/af_netlink.c

 if (nlk->netlink_unbind) { 
       int i; 

       for (i = 0; i < nlk->ngroups; i++) 
         if (test_bit(i, nlk->groups)) 
           nlk->netlink_unbind(sock_net(sk), i + 1); 

Ici vous pouvez voir que si l'option netlink_unbind a été fournie, puis elle sera exécutée, vous fournissant un rappel lorsque votre ap La plication a fermé le socket (soit gracieusement, soit à la suite d'une mise à mort).