-
Notifications
You must be signed in to change notification settings - Fork 1
/
geninit.api
208 lines (157 loc) · 4.87 KB
/
geninit.api
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#!/bin/bash
#
# geninit public API
#
# To authors of builders:
# these functions should be used over other functions in geninit such as
# __add_file, which generally have no awareness of things such as $basedir or
# $kernver.
#
shopt -s extglob
add_dirpath() { # {{{
# add all elements of a path (equivalent of mkdir -p)
# $1: an absolute path
[[ $1 == /?* ]] || return 1 # must be an absolute path, but not root itself
local path=
local -a pieces
IFS='/' read -ra pathparts <<< "$1"
for part in "${pathparts[@]}"; do
[[ $part ]] || continue
path+=/$part
add_dir "$path"
done
} # }}}
add_dir() { # {{{
# add a directory (equivalent of mkdir *without* -p)
# $1: absolute path on initcpio
# $2: mode (optional, defaults to 755)
(( ! $# )) && return 1 # NOOP
local path=$1 mode=${2:-755}
__add_dir "$path" "$mode"
} # }}}
add_file() { # {{{
# add a regular file. no parsing done.
# $1: source on disk
# $2: destination on initcpio (optional: assumes same as source)
(( ! $# )) && return 1 # NOOP
# determine source and destination
local src=$basedir$1 dest=${2:-$1} mode=
if [[ ! -f $src ]]; then
err "$src: No such file"
return 1
fi
mode=$(stat -c %a "$src")
if [[ -z $mode ]]; then
err "failed to stat file: \`$src'"
return 1
fi
add_path_to_file "$dest"
__add_file "$dest" "$src" "$mode"
} # }}}
add_symlink() { # {{{
# add a symlink
# $1: name on initcpio
# $2: target of $1
(( $# != 2 )) || return 1
__add_slink "$@"
} # }}}
add_path_to_file() { # {{{
# add the path leading up to a file
# $1: filename with full path
[[ $1 ]] && add_dirpath "${1%/*}"
} # }}}
add_module() { # {{{
# add a kernel module. deps are resolved recursively and added
# $1: kernel module by name (no path, with or without extension)
local -a firmware moddeps
local modpath= module= dep=
module=${1%.ko?(.gz)}
if [[ -z $basedir ]]; then # fast path =)
read -rd '' modpath < <(kmodinfo -n "$module" 2>/dev/null)
else # slow path =(
read -rd '' modpath < <(find "$basedir$moduledir" -name "$mod.ko" -o -name "$mod.ko.gz" -print0)
fi
[[ -z $modpath ]] && return 1
add_path_to_file "$modpath"
add_file "$modpath" || return 1
# grab firmware
IFS=',' read -rd '' -a firmware < <(kmodinfo -F firmware "$modpath")
for fw in "${firmware[@]}"; do
__add_file "$basedir/lib/firmware/$fw" "/lib/firmware/$fw"
done
# resolve deps
IFS=',' read -rd '' -a moddeps < <(kmodinfo -F depends "$modpath")
for dep in "${moddeps[@]}"; do
add_module "$dep"
done
# add in any quirks
if [[ ${modquirks[$module]} ]]; then
add_module "${modquirks[$module]}"
fi
return 0
} # }}}
add_binary() { # {{{
# comment goes here
# this needs reworking to use $basedir
[[ -f $basedir$1 ]] || { err "$1 not found"; return 1; }
local -a sodeps
local sodep=
IFS=$'\n' read -rd '' -a sodeps < <(ldd "$basedir$1" |\
sed -n '2,$s#.\+=>[[:blank:]]\+\([^ ]\+\) (.\+#\1#p')
for sodep in "${sodeps[@]}"; do
[[ -e $sodep ]] || continue
add_dirpath "${sodep%/*}"
if [[ -f $sodep ]]; then # but wait! a symlink is a regular file! FFFUUUUU
if [[ ! -L $sodep ]]; then
add_file "$sodep"
else
__add_slink "$sodep" "$(readlink -e "$sodep")"
add_file "$(readlink -e "$sodep")"
fi
fi
done
# the binary itself
add_file "$basedir$1" "${2:-$1}"
# we always need the big bad linker
__add_slink "$ld_so" $(readlink -e "$ld_so")
add_file "$(readlink -e "$ld_so")"
} # }}}
add_device() { # {{{
# add a device node to cpio_filelist
# $1: pathname on initcpio
# $2: device type (b=block or c=character)
# $3: device major
# $4: device minor
# $5: mode (optional, defaults to 644)
# nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>
(( $# == 4 )) || (( $# == 5 )) || return 1
[[ $2 = [bc] ]] || return 1
qgrep "^nod $1 " "$cpio_filelist" && return 1
printf 'nod %s %s 0 0 %s %s %s\n' "$1" "${5:-644}" "${@:2:3}" >> "$cpio_filelist"
} # }}}
use_hookscript() { # {{{
# specifies that a builder should install a hookscript
[[ $builder ]] || return 1
add_file "$basedir$_sharedir/hooks/$builder" "/hooks/$builder"
} # }}}
add_driver_classes() { # {{{
local -a mods
local -i ret=0
local mod=
# find modules by class (e.g. drivers/ata)
pushd "$moduledir/kernel" &>/dev/null
while read -rd '' mod; do
mod=${mod##*/}
mods+=("${mod%.ko?(.gz)}")
done < <(find "$@" \( -name '*.ko' -o -name '*.ko.gz' \) -print0 2>/dev/null | sort -z)
popd &>/dev/null
# only add what autodetect found if we have a module cache
if [[ -s $autodetect_cache ]]; then
IFS=$'\n' read -rd '' -a mods < <(grep -Ff <(printf '%s\n' "${mods[@]}") "$autodetect_cache")
fi
for mod in "${mods[@]}"; do
add_module "$mod" && (( ++ret ))
done
# return 0 on modules added, else 1
return $(( ! ret ))
} # }}}