Merge branch 'master' of github.com:sylware/cinitramfs
[cinitramfs.git] / uevent.c
blobe6e7af84e5bd621843bfee6c9907ad85f789dccb
1 /*******************************************************************************
2 this code is protected by the GNU affero GPLv3
3 author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
4 *******************************************************************************/
5 #include <blkid.h>
7 #include <ulinux/compiler_types.h>
8 #include <ulinux/types.h>
9 #include <ulinux/error.h>
10 #include <ulinux/utils/mem.h>
11 #include <ulinux/utils/ascii/string/string.h>
12 #include <ulinux/utils/ascii/string/conv/decimal/decimal.h>
13 #include <ulinux/sysc.h>
15 #include "out.h"
16 #include "ulinux_namespace.h"
17 #include "globals.h"
19 static u8 hdr_action_is_add(u8 *hdr)
21 #define HDR_ACTION_ADD "add@"
22 if(memcmp(hdr,HDR_ACTION_ADD,sizeof(HDR_ACTION_ADD)-1)) return 0;
23 return 1;
26 static void hdr_skip(u8 **p)
28 loop if(*(*p)++==0) break;
30 #define var_skip hdr_skip
32 static u8 key_is_subsystem(u8 *p)
34 #define KEY_SUBSYSTEM "SUBSYSTEM="
35 if(memcmp(p,KEY_SUBSYSTEM,sizeof(KEY_SUBSYSTEM)-1)) return 0;
36 return 1;
39 static u8 key_is_devname(u8 *p)
41 #define KEY_DEVNAME "DEVNAME="
42 if(memcmp(p,KEY_DEVNAME,sizeof(KEY_DEVNAME)-1)) return 0;
43 return 1;
46 static void move_to_value(u8 **p)
48 loop if(*(*p)++=='=') break;
51 static u8 value_is_block(u8 *p)
53 #define VALUE_BLOCK "block"
54 if(!*p||memcmp(p,VALUE_BLOCK,sizeof(VALUE_BLOCK)-1)) return 0;
55 return 1;
58 static void value_skip(u8 **p)
60 loop if(*(*p)++==0) break;
63 static void value_str_consume(u8 **p,u8 *d)
65 loop{
66 *d++=**p;
67 if(*(*p)++==0) break;
71 #define IS_ROOT 1
72 #define IS_NOT_ROOT 0
73 /*the block device is in devtmpfs, use it to probe with libblkid*/
74 static u8 blk_dev_probe(u8 *dev_name)
76 /*the right way to do it is to query the limits on the /dev file system*/
77 u8 dev_path[ROOT_DEV_PATH_SZ]="/dev/";
78 blkid_probe pr;
79 u8 r0;
80 i r1;
81 const char *type;
82 const char *uuid;
84 r0=IS_NOT_ROOT;
86 strcat(dev_path,dev_name);
88 OUT(PRE "probing %s...\n",dev_path);
89 pr=blkid_new_probe_from_filename((const char *)dev_path);
90 if(!pr){
91 OUT(PRE "failed (unable to create a blkid probe), skipping\n");
92 return IS_NOT_ROOT;
95 r1=blkid_do_probe(pr);
96 if(r1!=0){
97 OUT(PRE "failed (unable to perform the blkid probe), skipping\n");
98 goto free_probe;
101 r1=blkid_probe_lookup_value(pr,"TYPE",&type,0);
102 if(r1!=0){
103 OUT(PRE "failed (missing blkid type tag), skipping\n");
104 goto free_probe;
106 OUT(PRE " type=%s\n",type);
108 r1=blkid_probe_lookup_value(pr,"UUID",&uuid,0);
109 if(r1!=0){
110 OUT(PRE "failed (missing blkid uuid tag), skipping\n");
111 goto free_probe;
113 OUT(PRE " uuid=%s\n",uuid);
115 if(strcmp(uuid,root_uuid)==0){
116 /*found the root filesystem*/
117 OUT(PRE "found root\n");
118 strcpy(root_dev_path,dev_path);
119 strcpy(root_fs_type,type);
120 r0=IS_ROOT;
123 OUT(PRE "done\n");
124 free_probe:
125 blkid_free_probe(pr);
126 return r0;
129 /*here we are actually looking for block devices*/
130 u8 uevent_process(u8 *p,i sz)
132 u8 *p_end;
133 u8 dev_name[256];/*usually a devtmpfs which has path components of 256 bytes*/
134 u8 r;
136 r=ROOT_NOT_FOUND;
137 if(!hdr_action_is_add(p)) return r;
138 p_end=p+sz;
139 hdr_skip(&p);
141 memset(dev_name,0,sizeof(dev_name));
143 loop{
144 if(p>=p_end) break;
146 if(key_is_subsystem(p)){
147 move_to_value(&p);
148 if(!value_is_block(p)) goto exit;
149 else value_skip(&p);
150 }else if(key_is_devname(p)){
151 move_to_value(&p);
152 value_str_consume(&p,dev_name);
153 }else var_skip(&p);
156 /*from here, we are dealing with a block device, may be our root*/
157 r=blk_dev_probe(dev_name);
159 exit:
160 return r;