1 /*******************************************************************************
2 this code is protected by the GNU affero GPLv3
3 author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
4 *******************************************************************************/
5 #include <ulinux/compiler_types.h>
6 #include <ulinux/sysc.h>
7 #include <ulinux/types.h>
8 #include <ulinux/error.h>
9 #include <ulinux/socket/socket.h>
10 #include <ulinux/socket/msg.h>
11 #include <ulinux/socket/netlink.h>
12 #include <ulinux/epoll.h>
13 #include <ulinux/utils/mem.h>
16 #include "ulinux_namespace.h"
22 void uevents_cleanup(void)
30 OUT("ERROR(%ld):unable to close epoll fd\n",r
);
39 OUT("ERROR(%ld):unable to close netlink socket\n",r
);
44 void uevents_setup(void)
48 struct sockaddr_nl addr
={AF_NETLINK
,0,0,1};
49 struct epoll_event ep_evt
;
51 OUT(PRE
"setting up uevent...");
52 ep_fd
=(i
)epoll_create1(0);
54 OUT("ERROR(%d):unable to create epoll fd\n",ep_fd
);
58 /*--------------------------------------------------------------------------*/
61 so
=(i
)socket(PF_NETLINK
,SOCK_RAW
,NETLINK_KOBJECT_UEVENT
);
63 OUT("ERROR(%d):unable to create uevent netlink socket\n",so
);
67 /*--------------------------------------------------------------------------*/
69 recv_buf_sz
=128*1024;/* 128k for kernel buffering */
70 r
=setsockopt(so
,SOL_SOCKET
,SO_RCVBUFFORCE
,&recv_buf_sz
,sizeof(recv_buf_sz
));
72 OUT("ERROR(%ld):unable to force the size of the socket buffer\n",r
);
76 /*--------------------------------------------------------------------------*/
78 /* uevent groups-->only one: 1 */
79 r
=bind(so
,&addr
,sizeof(addr
));
81 OUT("ERROR(%ld):unable to bind address to uevent netlink socket\n",r
);
85 /*--------------------------------------------------------------------------*/
87 memset(&ep_evt
,0,sizeof(ep_evt
));
88 ep_evt
.events
=EPOLLIN
;
90 r
=epoll_ctl(ep_fd
,EPOLL_CTL_ADD
,so
,&ep_evt
);
92 OUT("ERROR(%ld):unable to register uevent netlink socket to epoll\n",r
);
98 static u8
uevent_msg(void)
100 u8 buf
[8192];/*presume 8kB is enough for one message*/
101 struct io_vec uev_io_vec
;
105 memset(buf
,0,sizeof(buf
));
108 uev_io_vec
.len
=sizeof(buf
);
110 memset(&msg
,0,sizeof(msg
));
115 r
=recvmsg(so
,&msg
,0);
119 OUT("ERROR(%ld):unable to receive the uevent\n",r
);
122 if(msg
.flgs
&MSG_TRUNC
){
123 OUT("ERROR:the uevent was truncated(flags=0x%x)\n",msg
.flgs
);
126 return uevent_process(&buf
[0],(i
)r
);
129 u8
uevents_process(void)
134 OUT(PRE
"processing uevents...\n");
137 static struct epoll_event evts
;/*uevent netlink event*/
139 memset(&evts
,0,sizeof(evts
));
140 r1
=epoll_wait(ep_fd
,&evts
,1,UEVENTS_TIMEOUT
);
142 if(r1
!=-EINTR
) break;
145 OUT(PRE
"ERROR(%ld):error epolling uevent netlink socket\n",r1
);
148 if(!r1
) break;/*assume no more uevents and unable to find root*/
149 if(evts
.events
&EPOLLIN
){
151 if(r
==ROOT_FOUND
) break;
153 OUT(PRE
"ERROR:unmanaged epolling event on uevent netlink socket(events=%u)\n",
158 OUT(PRE
"uevents processing terminated\n");