コード例 #1
0
ファイル: uevents.c プロジェクト: niamtokik/cinitramfs
void uevents_setup(void)
{
  OUTC(PRE "setting up uevent...");
  ep_fd=(k_i)sysc(epoll_create1,1,0);
  if(K_ISERR(ep_fd)){
    OUT("ERROR(%d):unable to create epoll fd\n",ep_fd);
    sysc(exit_group,1,-1);
  }

  //----------------------------------------------------------------------------

  //blocking socket
  s=(k_i)sysc(socket,3,K_PF_NETLINK,K_SOCK_RAW,
                       K_NETLINK_KOBJECT_UEVENT);
  if(K_ISERR(s)){
    OUT("ERROR(%d):unable to create uevent netlink socket\n",s);
    sysc(exit_group,1,-1);
  }

  //----------------------------------------------------------------------------

  k_i recv_buf_sz=128*1024;//128k for kernel buffering
  k_l r=sysc(setsockopt,5,s,K_SOL_SOCKET,K_SO_RCVBUFFORCE,&recv_buf_sz,
                          sizeof(recv_buf_sz));
  if(K_ISERR(r)){
    OUT("ERROR(%ld):unable to force the size of the socket buffer\n",r);
    sysc(exit_group,1,-1);
  }

  //----------------------------------------------------------------------------

  //uevent groups-->only one: 1
  struct k_sockaddr_nl addr={K_AF_NETLINK,0,0,1};
  r=sysc(bind,3,s,&addr,sizeof(addr));
  if(K_ISERR(r)){
    OUT("ERROR(%ld):unable to bind address to uevent netlink socket\n",r);
    sysc(exit_group,1,-1);
  }
  
  //----------------------------------------------------------------------------

  struct k_epoll_event ep_evt;
  u_memset(&ep_evt,0,sizeof(ep_evt));
  ep_evt.events=K_EPOLLIN;
  ep_evt.data.fd=s;
  r=sysc(epoll_ctl,4,ep_fd,K_EPOLL_CTL_ADD,s,&ep_evt);
  if(K_ISERR(r)){
    OUT("ERROR(%ld):unable to register uevent netlink socket to epoll\n",r);
    sysc(exit_group,1,-1);
  }
  OUTC("done\n");
}
コード例 #2
0
ファイル: uevents.c プロジェクト: niamtokik/cinitramfs
void uevents_cleanup(void)
{
  k_l r;
  do r=sysc(close,1,ep_fd); while(r==-K_EINTR);
  if(K_ISERR(r)){
    OUT("ERROR(%ld):unable to close epoll fd\n",r);
    sysc(exit_group,1,-1);
  }

  do r=sysc(close,1,s); while(r==-K_EINTR);
  if(K_ISERR(r)){
    OUT("ERROR(%ld):unable to close netlink socket\n",r);
    sysc(exit_group,1,-1);
  }
}
コード例 #3
0
ファイル: wl_display.c プロジェクト: sylware/lwl
void wl_display_req_sync(k_u32 callback_id)
{
  k_u32 req[REQ_SYNC_DWS];
  req[0]=WL_DISPLAY_ID;
  req[1]=((REQ_SYNC_DWS*sizeof(k_u32))<<16)|WL_DISPLAY_SYNC;
  req[2]=callback_id;

  struct k_io_vec iov;
  iov.base=&req;
  iov.len=sizeof(req);

  struct k_msg_hdr msg;
  u_memset(&msg,0,sizeof(msg));
  msg.iov=&iov;
  msg.iov_len=1;

  k_l r;
  do r=sysc(sendmsg,3,srv_so,&msg,0);while(r==-K_EINTR);

  if(K_ISERR(r)){
    PERR("FATAL(%d):unable to send the sync request\n",r);
    sysc(exit_group,1,-1);
  }
  if(!r) sysc(exit_group,1,0);//server is gone
}
コード例 #4
0
ファイル: uevents.c プロジェクト: niamtokik/cinitramfs
static void uevent_msg(void)
{
  k_u8 buf[8192];//presume 8kB is enough for one message
  u_memset(buf,0,sizeof(buf));

  struct k_io_vec io_vec;
  io_vec.base=buf;
  io_vec.len=sizeof(buf);

  struct k_msg_hdr msg;
  u_memset(&msg,0,sizeof(msg));
  msg.iov=&io_vec;
  msg.iov_len=1;

  k_l r;
  do r=sysc(recvmsg,3,s,&msg,0); while(r==-K_EINTR);
  if(K_ISERR(r)){
    OUT("ERROR(%ld):unable to receive the uevent\n",r);
    sysc(exit_group,1,-1);
  }
  if(msg.flgs&K_MSG_TRUNC){
    OUT("ERROR:the uevent was truncated(flags=0x%x)\n",msg.flgs);
    sysc(exit_group,1,-1);
  }
  uevent_process(&buf[0],(k_i)r);
}
コード例 #5
0
ファイル: wl_shm.c プロジェクト: sylware/lwl
void wl_shm_req_create_pool(k_u32 shm,k_u32 shm_pool,k_i fd,k_u32 sz)
{
  k_u32 req[REQ_PAYLOAD_CREATE_POOL_DWS];
  req[0]=shm;
  req[1]=(REQ_PAYLOAD_CREATE_POOL_DWS*sizeof(k_u32))<<16|WL_SHM_CREATE_POOL;
  req[2]=shm_pool;
  req[3]=sz;

  struct k_io_vec iov;
  iov.base=&req;
  iov.len=REQ_PAYLOAD_CREATE_POOL_DWS*sizeof(k_u32);

  struct k_msg_hdr msg;
  k_u8 cmsg_buf[K_CMSG_SPACE(sizeof(fd))];
  u_memset(&msg,0,sizeof(msg));
  u_memset(cmsg_buf,0,sizeof(cmsg_buf));

  msg.ctl=cmsg_buf;
  msg.ctl_len=sizeof(cmsg_buf);

  struct k_cmsg_hdr *cmsg=K_CMSG_FIRSTHDR(&msg);
  cmsg->lvl=K_SOL_SOCKET;
  cmsg->type=K_SCM_RIGHTS;
  cmsg->len=K_CMSG_LEN(sizeof(fd));

  msg.iov=&iov;
  msg.iov_len=1;
  *((k_i*)(K_CMSG_DATA(K_CMSG_FIRSTHDR(&msg))))=fd;

  k_l r;
  do r=sysc(sendmsg,3,srv_so,&msg,0);while(r==-K_EINTR);

  if(K_ISERR(r)){
    PERR("FATAL(%ld):unable to send the shm create_pool request\n",r);
    sysc(exit_group,1,-1);
  }
  if(r!=REQ_PAYLOAD_CREATE_POOL_DWS*sizeof(k_u32)){
    PERR("FATAL:shm::create_pool request only %ld/%ld was sent\n",r,
                                     REQ_PAYLOAD_CREATE_POOL_DWS*sizeof(k_u32));
    sysc(exit_group,1,-1);
  }
  if(!r) sysc(exit_group,1,0);//server is gone
}
コード例 #6
0
ファイル: uevents.c プロジェクト: niamtokik/cinitramfs
void uevents_process(void)
{
  OUTC(PRE "processing uevents...\n");
  while(1){
    k_l r;
    static struct k_epoll_event evts;//uevent netlink event
    do{
      u_memset(&evts,0,sizeof(evts));
      r=sysc(epoll_wait,4,ep_fd,&evts,1,UEVENTS_TIMEOUT);
    }while(r==-K_EINTR);
    if(K_ISERR(r)){
      OUT(PRE "ERROR(%ld):error epolling uevent netlink socket\n",r);
      sysc(exit_group,1,-1);
    }
	if(!r) break;//assume no more uevents
    if(evts.events&K_EPOLLIN) uevent_msg();
    else{
      OUT(PRE "ERROR:unmanaged epolling event on uevent netlink socket"
          "(events=%u)\n",evts.events);
      sysc(exit_group,1,-1);
    }
  }
  OUTC(PRE "uevents processed\n");
}