archiso 8.75 KB
Newer Older
1
2
3
# Initialize loopback device logic (we using on-demand mode)
# args: none
_init_loop_dev() {
4
5
6
    loop_dev_count=99
    loop_dev_range=$(cat /sys/block/loop0/range)
    loop_dev_minor=$((loop_dev_count*loop_dev_range))
7
8
9
10
11
}

# Call this function before _make_loop_dev() each time.
# args: none
_next_loop_dev() {
12
13
    loop_dev_count=$((loop_dev_count+1))
    loop_dev_minor=$((loop_dev_count*loop_dev_range))
14
15
}

16
# Setup a loopback device for image passed as argument and echo the path to loopback device used.
17
18
19
# args: /path/to/image_file
_make_loop_dev() {
    local img="${1}"
20
21
22
    mknod /dev/loop${loop_dev_count} b 7 ${loop_dev_minor} &> /dev/null
    losetup /dev/loop${loop_dev_count} "${img}" &> /dev/null
    echo /dev/loop${loop_dev_count}
23
24
}

Simo Leone's avatar
Simo Leone committed
25
# args: source, mountpoint
26
27
28
29
30
_mnt_fs() {
    local img="${1}"
    local mnt="${2}"
    local img_fullname="${img##*/}";
    local img_name="${img_fullname%%.*}"
31
    local dm_snap_name="${dm_snap_prefix}_${img_name}"
32
33
    local ro_dev ro_dev_size ro_dev_fs_type rw_dev

34
    mkdir -p "${mnt}"
35
36
37
38
39
40

    _next_loop_dev
    ro_dev=$(_make_loop_dev "${img}")
    ro_dev_size=$(blockdev --getsz ${ro_dev})
    ro_dev_fs_type=$(blkid -o value -s TYPE -p ${ro_dev} 2> /dev/null)

41
42

    if [[ "${cow_persistent}" == "P" ]]; then
43
44
        if [[ -f "/run/archiso/cowspace/${cow_directory}/${img_name}.cow" ]]; then
            msg ":: Found '/run/archiso/cowspace/${cow_directory}/${img_name}.cow', using as persistent."
45
        else
46
47
            msg ":: Creating '/run/archiso/cowspace/${cow_directory}/${img_name}.cow' as persistent."
            dd of="/run/archiso/cowspace/${cow_directory}/${img_name}.cow" count=0 seek=${ro_dev_size} &> /dev/null
48
49
        fi
    else
50
51
52
        if [[ -f "/run/archiso/cowspace/${cow_directory}/${img_name}.cow" ]]; then
            msg ":: Found '/run/archiso/cowspace/${cow_directory}/${img_name}.cow' but non-persistent requested, removing."
            rm -f "/run/archiso/cowspace/${cow_directory}/${img_name}.cow"
53
        fi
54
55
        msg ":: Creating '/run/archiso/cowspace/${cow_directory}/${img_name}.cow' as non-persistent."
        dd of="/run/archiso/cowspace/${cow_directory}/${img_name}.cow" count=0 seek=${ro_dev_size} &> /dev/null
56
57
    fi

58
    _next_loop_dev
59
    rw_dev=$(_make_loop_dev "/run/archiso/cowspace/${cow_directory}/${img_name}.cow")
60

61
    echo "0 ${ro_dev_size} snapshot ${ro_dev} ${rw_dev} ${cow_persistent} 8" | dmsetup create ${dm_snap_name}
62

63
64
65
    msg ":: Mounting '/dev/mapper/${dm_snap_name}' (${ro_dev_fs_type}) to '${mnt}'"
    if ! mount -t "${ro_dev_fs_type}" "/dev/mapper/${dm_snap_name}" "${mnt}" ; then
        echo "ERROR: while mounting '/dev/mapper/${dm_snap_name}' to '${mnt}'"
66
67
        launch_interactive_shell
    fi
Simo Leone's avatar
Simo Leone committed
68
69
}

70
# args: /path/to/image_file, mountpoint
71
72
73
74
75
76
77
78
_mnt_sfs() {
    local img="${1}"
    local mnt="${2}"
    local img_fullname="${img##*/}";

    mkdir -p "${mnt}"

    if [[ "${copytoram}" == "y" ]]; then
79
        msg -n ":: Copying squashfs image to RAM..."
80
81
        if ! cp "${img}" "/run/archiso/copytoram/${img_fullname}" ; then
            echo "ERROR: while copy '${img}' to '/run/archiso/copytoram/${img_fullname}'"
82
83
            launch_interactive_shell
        fi
84
        img="/run/archiso/copytoram/${img_fullname}"
85
        msg "done."
86
    fi
87
88
89
90
    _next_loop_dev
    msg ":: Mounting '${img}' (SquashFS) to '${mnt}'"
    if ! mount -r -t squashfs $(_make_loop_dev "${img}") "${mnt}" &> /dev/null ; then
        echo "ERROR: while mounting '${img}' to '${mnt}'"
91
92
        launch_interactive_shell
    fi
Simo Leone's avatar
Simo Leone committed
93
94
}

95
96
97
98
99
100
101
102
# args: device, mountpoint, flags
_mnt_dev() {
    local dev="${1}"
    local mnt="${2}"
    local flg="${3}"

    local fstype fserror

103
104
    mkdir -p "${mnt}"

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
    msg ":: Mounting '${dev}' to '${mnt}'"

    while ! poll_device "${dev}" 30; do
        echo "ERROR: '${dev}' device did not show up after 30 seconds..."
        echo "   Falling back to interactive prompt"
        echo "   You can try to fix the problem manually, log out when you are finished"
        launch_interactive_shell
    done

    fstype=$(blkid -o value -s TYPE -p "${dev}" 2> /dev/null)
    if [[ -n "${fstype}" ]]; then
        if mount ${flg} -t "${fstype}" "${dev}" "${mnt}"; then
            msg ":: Device '${dev}' mounted successfully."
            fserror=0
        else
            echo "ERROR; Failed to mount '${dev}' (FS is ${fstype})"
            fserror=1
        fi
    else
        echo "ERROR: '${dev}' found, but the filesystem type is unknown."
        fserror=1
    fi

    if [[ ${fserror} -eq 1 ]]; then
        echo "   Falling back to interactive prompt"
        echo "   You can try to fix the problem manually, log out when you are finished"
        launch_interactive_shell
    fi
}

135
136
_verify_checksum() {
    local _status
137
    cd "/run/archiso/bootmnt/${archisobasedir}"
138
139
140
141
142
143
    md5sum -c checksum.md5 > /checksum.log 2>&1
    _status=$?
    cd "${OLDPWD}"
    return ${_status}
}

144
run_hook() {
145
146
    modprobe loop

147
148
149
150
    [[ -z "${arch}" ]] && arch="$(uname -m)"
    [[ -z "${cowspace_size}" ]] && cowspace_size="75%"
    [[ -z "${copytoram_size}" ]] && copytoram_size="75%"
    [[ -z "${archisobasedir}" ]] && archisobasedir="arch"
151
    [[ -z "${dm_snap_prefix}" ]] && dm_snap_prefix="arch"
152
    [[ -z "${archisodevice}" ]] && archisodevice="/dev/disk/by-label/${archisolabel}"
153

154
    if [[ -z "${aitab}" ]]; then
155
        aitab="/run/archiso/bootmnt/${archisobasedir}/aitab"
156
    else
157
        aitab="/run/archiso/bootmnt/${aitab}"
158
    fi
159
160
161
162
163
164
165
166
167
168
169
170

    if [[ -n "${cow_label}" ]]; then
        cow_device="/dev/disk/by-label/${cow_label}"
        [[ -z "${cow_persistent}" ]] && cow_persistent="P"
    elif [[ -n "${cow_device}" ]]; then
        [[ -z "${cow_persistent}" ]] && cow_persistent="P"
    else
        cow_persistent="N"
    fi

    [[ -z "${cow_directory}" ]] && cow_directory="persistent_${archisolabel}/${arch}"

171
172
173
174
    # set mount handler for archiso
    mount_handler="archiso_mount_handler"
}

175
176
177
# This function is called normally from init script, but it can be called
# as chain from other mount handlers.
# args: /path/to/newroot
178
archiso_mount_handler() {
179
180
181
    local newroot="${1}"

    _init_loop_dev
182

183
    if [[ "${archisodevice}" -ef "${cow_device}" ]]; then
184
        _mnt_dev "${archisodevice}" "/run/archiso/bootmnt"
185
    else
186
        _mnt_dev "${archisodevice}" "/run/archiso/bootmnt" "-r"
187
188
    fi

189
190
    if [[ ! -f "${aitab}" ]]; then
        echo "ERROR: '${aitab}' file does not exist."
191
192
193
        echo "   Falling back to interactive prompt"
        echo "   You can try to fix the problem manually, log out when you are finished"
        launch_interactive_shell
Aaron Griffin's avatar
Aaron Griffin committed
194
195
    fi

196
    if [[ "${checksum}" == "y" ]]; then
197
        if [[ -f "/run/archiso/bootmnt/${archisobasedir}/checksum.md5" ]]; then
198
199
200
201
202
203
204
205
206
207
208
209
210
211
            msg -n ":: Self-test requested, please wait..."
            if _verify_checksum; then
                msg "done. Checksum is OK, continue booting."
            else
                echo "ERROR: one or more files are corrupted"
                echo "see /checksum.log for details"
                launch_interactive_shell
            fi
        else
            echo "ERROR: checksum=y option specified but checksum.md5 not found"
            launch_interactive_shell
        fi
    fi

212
    if [[ "${copytoram}" == "y" ]]; then
213
214
215
        msg ":: Mounting /run/archiso/copytoram (tmpfs) filesystem, size=${copytoram_size}"
        mkdir -p /run/archiso/copytoram
        mount -t tmpfs -o "size=${copytoram_size}",mode=0755 copytoram /run/archiso/copytoram
216
217
    fi

218
    if [[ -n "${cow_device}" ]]; then
219
        _mnt_dev "${cow_device}" "/run/archiso/cowspace"
220
    else
221
222
223
        msg ":: Mounting /run/archiso/cowspace (tmpfs) filesystem, size=${cowspace_size}..."
        mkdir -p /run/archiso/cowspace
        mount -t tmpfs -o "size=${cowspace_size}",mode=0755 cowspace /run/archiso/cowspace
224
    fi
225
    mkdir -p "/run/archiso/cowspace/${cow_directory}"
226

227
228
229
230
231
232
    local aitab_img aitab_mnt aitab_arch aitab_sfs_comp aitab_fs_type aitab_fs_size
    while read aitab_img aitab_mnt aitab_arch aitab_sfs_comp aitab_fs_type aitab_fs_size; do
        [[ "${aitab_img#\#}" != "${aitab_img}" ]] && continue
        [[ "${aitab_arch}" != "any" && "${aitab_arch}" != "${arch}" ]] && continue
        if [[ "${aitab_fs_type}" != "none" ]]; then
            if [[ "${aitab_sfs_comp}" != "none" ]]; then
233
234
                _mnt_sfs "/run/archiso/bootmnt/${archisobasedir}/${aitab_arch}/${aitab_img}.fs.sfs" "/run/archiso/sfs/${aitab_img}"
                _mnt_fs "/run/archiso/sfs/${aitab_img}/${aitab_img}.fs" "${newroot}${aitab_mnt}"
235
            else
236
                _mnt_fs "/run/archiso/bootmnt/${archisobasedir}/${aitab_arch}/${aitab_img}.fs" "${newroot}${aitab_mnt}"
237
238
            fi
        else
239
            _mnt_sfs "/run/archiso/bootmnt/${archisobasedir}/${aitab_arch}/${aitab_img}.sfs" "${newroot}${aitab_mnt}"
Aaron Griffin's avatar
Aaron Griffin committed
240
        fi
241
    done < "${aitab}"
242

243
    if [[ "${copytoram}" == "y" ]]; then
244
        umount /run/archiso/bootmnt
Aaron Griffin's avatar
Aaron Griffin committed
245
246
    fi
}
Dan McGee's avatar
Dan McGee committed
247
248

# vim:ft=sh:ts=4:sw=4:et: