2011-12-03 6 views
2

일부 기본 커널 모듈 - netlink 소켓 (사용자 측 libnl)을 사용하는 사용자 공간 프로그램 통신을 코딩하려고합니다. 사용자 공간 프로그램은 커널에 메시지를 보내고 응답을 기대합니다. 불행히도, 리턴 값 -16 (EBUSY)으로 수신 응답이 실패합니다.Netlink 소켓 및 libnl - nl_recvmsgs_default 반환 -16 (EBUSY)

흥미롭게도, net32 소켓에서 직접 데이터를 받으면 recvnl_socket_get_fd(sock)에 표준 시스템 호출을 사용하면 모든 것이 잘 동작합니다!

왜 이런 일이 일어나는 지 아는 사람이 있습니까? 여기

struct nl_sock *sock; 
struct nl_msg *msg; 
int family, res; 

// Allocate a new netlink socket 
sock = nl_socket_alloc(); 

// Connect to generic netlink socket on kernel side 
genl_connect(sock); 

// Ask kernel to resolve family name to family id 
family = genl_ctrl_resolve(sock, PSVFS_FAMILY_NAME); 

// Construct a generic netlink by allocating a new message, fill in 
// the header and append a simple integer attribute. 
msg = nlmsg_alloc(); 
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_ECHO, 
     PSVFS_C_INIT, PSVFS_VERSION); 
nla_put_string(msg, PSVFS_A_MSG, "stuff"); 

// Send message over netlink socket 
nl_send_auto_complete(sock, msg); 

// Free message 
nlmsg_free(msg); 

nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, parse_cb, NULL); 

res = nl_recvmsgs_default(sock); 
printf("After receive %i.\n", res); 

(이 하나가 제대로 호출됩니다) 사용자 공간 프로그램에 의해 전송 님에게 메일에 대한 커널 측 콜백입니다 : 여기

은 (parse_cb가 호출되지 않는 콜백입니다) 사용자 공간 코드입니다 :

int psvfs_vfs_init(struct sk_buff *skb2, struct genl_info *info) { 
    send_to_daemon("VFS initialized.", PSVFS_C_INIT, info->snd_seq+1, info->snd_pid); 

    return 0; 
} 

그리고 여기가 'send_to_daemon'기능이다

int send_to_daemon(char* msg, int command, int seq, u32 pid) { 
    int res = 0; 
    struct sk_buff* skb; 
    void* msg_head; 

    skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 
    if (skb == NULL) { 
     res = -ENOMEM; 
     goto out; 
    } 

    msg_head = genlmsg_put(skb, 0, seq, &psvfs_gnl_family, 0, command); 
    if (msg_head == NULL) { 
     res = -ENOMEM; 
     goto out; 
    } 

    res = nla_put_string(skb, PSVFS_A_MSG, msg); 
    if (res != 0) 
     goto out; 

    genlmsg_end(skb, msg_head); 

    res = genlmsg_unicast(&init_net, skb, pid); 
    if (res != 0) 
     goto out; 

    out: 
    return res; 
} 

답변

1

OK, 나는 어 발견 여기서 잘못했다.

libnl 함수는 표준 POSIX 리턴 코드와 다른 자체 오류 코드가 있으며, -16은 NLE_SEQ_MISMATCH을 나타냅니다.

문제는 내가 메시지에 할당 한 잘못된 일련 번호로 인해 발생했습니다.

+0

이것은 다소 늦었지만 같은 문제가 있습니다. 인터넷에 아무도 libnl 설명서를 업데이트하지 않았습니다 .... 어떻게 해결 했습니까? 내 콜백 함수가 전혀 호출되지 않고 -16 오류가 발생합니다. 내가 순차적으로 메시지를 보내는 것에 신경 쓰지 않기 때문에 나는 그들 모두에게 시퀀스 번호 "0"을 할당하고있다. "nl_socket_disable_seq_check"을 호출하면 콜백 함수가 여전히 호출되지 않지만 "nl_recvmsgs_default"는 0 만 반환합니다. – Chris

+0

정책의 정확성을 검사합니다. 정책에 메모리를 할당하면 일부 가비지가 저장 될 수 있으며 넷 링크 구조의 일부 필드가 잘못된 값으로 초기화 될 수 있습니다. 또한 콜백 핸들러를 모든 메시지에 설정했는지 확인하십시오. 핸들러를 잘못된 유형으로 설정할 수 있습니다. – t0k3n1z3r