summaryrefslogblamecommitdiffstats
path: root/builder/dnbd3-rootfs/hooks/prepare-root-partition.sh
blob: d051a2509d2dcb021c6294b1146b5cb575baa1e4 (plain) (tree)
1
2
3
4
5
6
7
8
9
                   
                
                                
                                       
                      

                   
                                                        
           

              

                                
 

                   
                                
                                                  

                                      





                                                                 
                                        





                                                   

























                                                                              

                                                                            








                                                                           







                                                          
                                                                   
      







                                                                              
                                                                      

                                                  

  

           
                      
                 
       
             
                                    

                                                                            
                                                           
                              
        
                     

             

                 
 
                                
                                                                
                                                             
          
  
           
                        
                                                                 

                                             
           
                                 
                                                          
                                                      
                                   





                                                                    
    






                                                                    
  

           
                                                              
                                                                               

                                    

                                                                         
 




                                                





                                                     
#!/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 getarg >/dev/null 2>&1 || source /lib/dracut-lib.sh
# endregion
exceptions.try
{
logging.set_commands_level debug
logging.set_level debug

source /etc/openslx

# region find writable partition
if ! persistent_device=$(tools.find_block_device \
    "$SLX_WRITABLE_DEVICE_IDENTIFIER")
then
    logging.warn "Failed to find unique device with identifier" \
        "'${SLX_WRITABLE_DEVICE_IDENTIFIER}'; matched devices:" \
        "'${persistent_device}'"
fi

# TODO move somewhere else
#tmp_device="$(tools.find_block_device \
    #'$SLX_TMP_PARTITION_IDENTIFIER')"

#if [ -n $tmp_device ]; then
    #mount --type auto "$tmp_device" "$NEWROOT/tmp"
#fi

if [ -n "$SLX_WRITABLE_DEVICE_STORAGE_FILE" ] && [ -n "$persistent_device" ]
then
    persistent_mountpoint=/mnt/slx_writable_device
    storage_file=$persistent_mountpoint/$SLX_WRITABLE_DEVICE_STORAGE_FILE
    ! mkdir --parents $persistent_mountpoint
    if ! mount --type auto "$persistent_device" "$persistent_mountpoint"; then
        logging.warn "Failed to mount $persistent_device, checking filesystem"
        ! $SLX_WRITABLE_DEVICE_STORAGE_FILSYSTEM_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_FILSYSTEM_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" ]; then
            # create sparse file
            dd of="$storage_file" bs=1M \
                seek="$SLX_WRITABLE_DEVICE_STORAGE_FILE_MAX_SIZE_MB" count=0
        fi
        persistent_device="$(losetup --find)"
        losetup "$persistent_device" "$storage_file"
    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="$SLX_RAMDISK_SIZE"
    if [ "$ramdisk_size" = "" ]; then
        ramdisk_size="$(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"
    #writable_device='/dev/ram0'
    ramdisk_location="$(mktemp)"
    dd of="$ramdisk_location" seek="$ramdisk_size" 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}' from" \
        "one of '$SLX_DNBD3_SERVERS' to '$SLX_DNBD3_DEVICE'."
    exit 1
fi
# endregion
# region scan partitions
read_only_device="$(container-unpack-xmount "$SLX_DNBD3_DEVICE")"
# 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
{
    emergency_shell "error in ${BASH_SOURCE[0]}"
}
# region vim modline

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

# endregion