summaryrefslogtreecommitdiffstats
path: root/builder/dnbd3-rootfs/hooks/prepare-root-partition.sh
blob: 3e93253f1f226222cd3bd4e952962052048eaba7 (plain) (blame)
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
#!/usr/bin/env bash
# region imports
source '/usr/lib/rebash/core.sh'
core.import '/usr/lib/openslx/tools.sh'
core.import exceptions
core.import utils
core.import logging
type emergency_shell >/dev/null 2>&1 || source /lib/dracut-lib.sh
# endregion
exceptions.try
{
source /etc/openslx
logging.set_commands_level debug
logging.set_level debug
[[ "$SLX_LOG_FILE_PATH" == "" ]] && SLX_LOG_FILE_PATH=/var/log/openslx
logging.set_log_file "$SLX_LOG_FILE_PATH"

# region find writable partition
if [[ "$SLX_WRITABLE_DEVICE_IDENTIFIER" != '' ]] &&
    ! persistent_device="$(
        tools.find_block_device "$SLX_WRITABLE_DEVICE_IDENTIFIER" '' \
        "$SLX_WRITABLE_DEVICE_IDENTIFIER_TIMEOUT_IN_SECONDS"
    )"
then
    logging.warn "Failed to find unique device with identifier" \
        "\"${SLX_WRITABLE_DEVICE_IDENTIFIER}\"; matched devices:" \
        "\"${persistent_device}\""
fi
if [ -n "$SLX_WRITABLE_DEVICE_STORAGE_FILE_PATH" ] && [ -n "$persistent_device" ]
then
    persistent_mountpoint=/mnt/slx_writable_device
    storage_file_path="${persistent_mountpoint}/$SLX_WRITABLE_DEVICE_STORAGE_FILE_PATH"
    ! mkdir --parents "$(dirname "$storage_file_path")"
    if ! mount --type auto "$persistent_device" "$persistent_mountpoint"; then
        logging.warn "Failed to mount $persistent_device, checking filesystem."
        ! $SLX_WRITABLE_DEVICE_STORAGE_FILESYSTEM_CHECK_COMMAND \
            "$persistent_device"
        if ! mount --type auto "$persistent_device" "$persistent_mountpoint"
        then
            logging.warn "Mounting $persistent_device, still failing," \
                "creating new filesystem on device"
            $SLX_WRITABLE_DEVICE_STORAGE_FILESYSTEM_CREATE_COMMAND \
                "$persistent_device"
        fi
        if ! mount --type auto "$persistent_device" "$persistent_mountpoint"
        then
            logging.warn "Mounting $persistent_device, still failing," \
                "giving up, and using ramdisk"
            persistent_device=""
        fi
    fi
    if [ -n "$persistent_device" ]; then
        if [ ! -e "$storage_file_path" ]; then
            # Create a sparse file.
            dd of="$storage_file_path" bs=1M \
                seek="$SLX_WRITABLE_DEVICE_STORAGE_MAXIMUM_FILE_SIZE_IN_MB" count=0
        fi
        persistent_device="$(losetup --find)"
        losetup "$persistent_device" "$storage_file_path"
    fi
fi

# "P" for persistent storage, "N" for not persistent (affects dmsetup call,
# see scripts/device-add-write-layer.sh)
persistent='N'
if [ -n "$persistent_device" ]; then
    writable_device="$persistent_device"
    if [ "$SLX_WRITABLE_DEVICE_PERSISTENT" = "yes" ]; then
        persistent='P'
    fi
else
    ramdisk_size_in_kb="$SLX_RAMDISK_SIZE_IN_KB"
    if [ "$ramdisk_size_in_kb" = '' ]; then
        ramdisk_size_in_kb="$(awk '/MemTotal/ {print $2}' /proc/meminfo)"
    fi
    # NOTE: If the kernel modul "brd" is compiled into current kernel we can't
    # configure ram disk size dynamically. In this case it have to be
    # configured via kernel command line: "brd.rd_size=SITE_IN_KILOBYTE"
    # statically:
    #! rmmod brd 2>/dev/null
    #modprobe brd max_part=1 rd_size="$ramdisk_size_in_kb"
    #writable_device='/dev/ram0'
    ramdisk_location="$(mktemp)"
    dd of="$ramdisk_location" seek="$ramdisk_size_in_kb" count=0 1>/dev/null
    writable_device="$(losetup --find)"
    losetup "$writable_device" "$ramdisk_location"
fi
# endregion
# region connect dnbd3
IFS_backup="$IFS"
IFS=","
return_code=1
for host in ${SLX_DNBD3_SERVERS}; do
    logging.info "Trying host \"$host\"."
    if systemd-preserve-process-marker dnbd3-client --host "$host" --image \
        "${SLX_DNBD3_IMAGE}" --device "$SLX_DNBD3_DEVICE" \
        --rid "$SLX_DNBD3_RID"
    then
        return_code=0
        break
    fi
done
IFS="$IFS_backup"

if [[ $return_code != 0 ]]; then
    logging.warn "Failed to connect \"${SLX_DNBD3_IMAGE}\" (revision" \
        "\"$SLX_DNBD3_RID\") from one of \"$SLX_DNBD3_SERVERS\" to" \
        "\"$SLX_DNBD3_DEVICE\"."
    exit 1
fi
# endregion
# region scan partitions
if [ "$SLX_LOG_FILE_PATH" != "" ]; then
    read_only_device="$(container-unpack-xmount "$SLX_DNBD3_DEVICE" \
        2>>"$SLX_LOG_FILE_PATH")"
else
    read_only_device="$(container-unpack-xmount "$SLX_DNBD3_DEVICE")"
fi


# Fail fast if no device could be determined.
[ -z "$read_only_device" ] && exit 1
# endregion
# region find read-only partition
if [ -z "$SLX_SYSTEM_PARTITION_PREPARATION_SCRIPT" ]; then
    if [ -z "$SLX_SYSTEM_PARTITION_IDENTIFIER" ]; then
        # if empty use whole device
        read_only_partition="$read_only_device"
        true
    else
        read_only_partition="$(tools.find_block_device \
            "$SLX_SYSTEM_PARTITION_IDENTIFIER" "$read_only_device")"
    fi
else
    eval "$SLX_SYSTEM_PARTITION_PREPARATION_SCRIPT"
fi
if [[ ! $? || -z "$read_only_partition" ]]; then
    logging.error "Failed to find unique device with identifier" \
        "\"${SLX_SYSTEM_PARTITION_IDENTIFIER}\"; matched devices:" \
        "\"${read_only_partition}\""
    exit 1
fi
# endregion

logging.info "Using read-only partition: $read_only_partition"
logging.info "Using writable device $writable_device, persistency: $persistent"

# combine devices with device mapper
device-add-write-layer "root" "$read_only_partition" "$writable_device" \
    "$persistent"

}
exceptions.catch
{
    logging.error "$exceptions_last_traceback"
    emergency_shell "error in ${BASH_SOURCE[0]}"
}
# region vim modline

# vim: set tabstop=4 shiftwidth=4 expandtab:
# vim: foldmethod=marker foldmarker=region,endregion:

# endregion