/uevents.c (cfe47059c2c26697fd02d2f18b0afe68dc7627fd) (3970 bytes) (mode 100644) (type blob)
/*******************************************************************************
this code is protected by the GNU affero GPLv3
author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
*******************************************************************************/
#include <ulinux/compiler_types.h>
#include <ulinux/sysc.h>
#include <ulinux/types.h>
#include <ulinux/error.h>
#include <ulinux/socket/socket.h>
#include <ulinux/socket/msg.h>
#include <ulinux/socket/netlink.h>
#include <ulinux/epoll.h>
#include <ulinux/utils/mem.h>
#include "out.h"
#include "ulinux_namespace.h"
#include "globals.h"
#include "uevent.h"
static i ep_fd;
static i so;
void uevents_cleanup(void)
{
l r;
loop{
r=close(ep_fd);
if(r!=-EINTR) break;
}
if(ISERR(r)){
OUT("ERROR(%ld):unable to close epoll fd\n",r);
exit_group(-1);
}
loop{
r=close(so);
if(r!=-EINTR) break;
}
if(ISERR(r)){
OUT("ERROR(%ld):unable to close netlink socket\n",r);
exit_group(-1);
}
}
void uevents_setup(void)
{
i recv_buf_sz;
i r;
struct sockaddr_nl addr={AF_NETLINK,0,0,1};
struct epoll_event ep_evt;
OUT(PRE "setting up uevent...");
ep_fd=(i)epoll_create1(0);
if(ISERR(ep_fd)){
OUT("ERROR(%d):unable to create epoll fd\n",ep_fd);
exit_group(-1);
}
/*--------------------------------------------------------------------------*/
/* blocking socket */
so=(i)socket(PF_NETLINK,SOCK_RAW,NETLINK_KOBJECT_UEVENT);
if(ISERR(so)){
OUT("ERROR(%d):unable to create uevent netlink socket\n",so);
exit_group(-1);
}
/*--------------------------------------------------------------------------*/
recv_buf_sz=128*1024;/* 128k for kernel buffering */
r=setsockopt(so,SOL_SOCKET,SO_RCVBUFFORCE,&recv_buf_sz,sizeof(recv_buf_sz));
if(ISERR(r)){
OUT("ERROR(%ld):unable to force the size of the socket buffer\n",r);
exit_group(-1);
}
/*--------------------------------------------------------------------------*/
/* uevent groups-->only one: 1 */
r=bind(so,&addr,sizeof(addr));
if(ISERR(r)){
OUT("ERROR(%ld):unable to bind address to uevent netlink socket\n",r);
exit_group(-1);
}
/*--------------------------------------------------------------------------*/
memset(&ep_evt,0,sizeof(ep_evt));
ep_evt.events=EPOLLIN;
ep_evt.data.fd=so;
r=epoll_ctl(ep_fd,EPOLL_CTL_ADD,so,&ep_evt);
if(ISERR(r)){
OUT("ERROR(%ld):unable to register uevent netlink socket to epoll\n",r);
exit_group(-1);
}
OUT("done\n");
}
static u8 uevent_msg(void)
{
u8 buf[8192];/*presume 8kB is enough for one message*/
struct io_vec uev_io_vec;
struct msg_hdr msg;
l r;
memset(buf,0,sizeof(buf));
uev_io_vec.base=buf;
uev_io_vec.len=sizeof(buf);
memset(&msg,0,sizeof(msg));
msg.iov=&uev_io_vec;
msg.iov_len=1;
loop{
r=recvmsg(so,&msg,0);
if(r!=-EINTR) break;
}
if(ISERR(r)){
OUT("ERROR(%ld):unable to receive the uevent\n",r);
exit_group(-1);
}
if(msg.flgs&MSG_TRUNC){
OUT("ERROR:the uevent was truncated(flags=0x%x)\n",msg.flgs);
exit_group(-1);
}
return uevent_process(&buf[0],(i)r);
}
u8 uevents_process(void)
{
u8 r;
r=ROOT_NOT_FOUND;
OUT(PRE "processing uevents...\n");
loop{
l r1;
static struct epoll_event evts;/*uevent netlink event*/
loop{
memset(&evts,0,sizeof(evts));
r1=epoll_wait(ep_fd,&evts,1,UEVENTS_TIMEOUT);
if(r1!=-EINTR) break;
}
if(ISERR(r1)){
OUT(PRE "ERROR(%ld):error epolling uevent netlink socket\n",r1);
exit_group(-1);
}
if(!r1) break;/*assume no more uevents and unable to find root*/
if(evts.events&EPOLLIN){
r=uevent_msg();
if(r==ROOT_FOUND) break;
}else{
OUT(PRE "ERROR:unmanaged epolling event on uevent netlink socket(events=%u)\n",
evts.events);
exit_group(-1);
}
}
OUT(PRE "uevents processing terminated\n");
return r;
}
Mode |
Type |
Size |
Ref |
File |
100644 |
blob |
444 |
49d5064b5a60c1d457aaf871c71275eb962d83f2 |
3.16 |
100644 |
blob |
558 |
3b1926aa2a9e5e4a8fa5c8a3d178a0ed02a01346 |
DEPENDENCIES |
100644 |
blob |
35147 |
94a9ed024d3859793618152ea559a168bbcbb5e2 |
LICENSE.md |
100644 |
blob |
768 |
32cae14d717baa6c88aab11a82663e0a2aefe652 |
README |
100644 |
blob |
644 |
598bf35b742147b3cc2bc1da0fd6d41aa282e77e |
TODO |
100644 |
blob |
432 |
2516d063ca695699c1ec3d755ef782bad84f203f |
cpio.in |
100644 |
blob |
587 |
1890391057120a83a6714310987be3ca82de46cc |
globals.h |
100644 |
blob |
5197 |
6caef253d4902e1c038135a156d42a847c89dddf |
init.c |
100755 |
blob |
12172 |
9f4bb09cd1e95ca807848a2445e8580f0a8b0aa6 |
make |
100644 |
blob |
5877 |
e849ba428752ea61144fe879792c8c68a65e3160 |
modules.c |
100644 |
blob |
503 |
f478bdeefa4ae3259dedfe0b4f78036492295d27 |
modules.h |
100644 |
blob |
674 |
7f272e25a25b4da12ad81f13b6eeff1bba4187af |
out.h |
100644 |
blob |
3180 |
6d142befdbc559aa3b6089443a2988b054bc71de |
ramfs.c |
100644 |
blob |
341 |
de9218a39777b8dd8feb5ee76cdf41af215ef473 |
ramfs.h |
040000 |
tree |
- |
87b8a0b9717f8367a1f8427da787968136f8aac9 |
script |
100644 |
blob |
3592 |
e6e7af84e5bd621843bfee6c9907ad85f789dccb |
uevent.c |
100644 |
blob |
348 |
cf07be71685703316f9522de37d466034d08e635 |
uevent.h |
100644 |
blob |
3970 |
cfe47059c2c26697fd02d2f18b0afe68dc7627fd |
uevents.c |
100644 |
blob |
413 |
896725abf8b5477eb7013e55429aa89a2bf97ed3 |
uevents.h |
040000 |
tree |
- |
62d63dbff565849898f1b5138d50a03774874906 |
ulinux |
100644 |
blob |
4060 |
feb12fd4fc27f1442198ea878911269a2b2e1215 |
ulinux_namespace.h |
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"
Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/sylware/cinitramfs
Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/sylware/cinitramfs
Clone this repository using git:
git clone git://git.rocketgit.com/user/sylware/cinitramfs
You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a
merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main