diff --git a/dracut/modules.d/55kiwi-dump/kiwi-dump-image.sh b/dracut/modules.d/55kiwi-dump/kiwi-dump-image.sh index c60e43b0a18..620d3a6f091 100755 --- a/dracut/modules.d/55kiwi-dump/kiwi-dump-image.sh +++ b/dracut/modules.d/55kiwi-dump/kiwi-dump-image.sh @@ -346,8 +346,15 @@ function dump_image { dump=dump_local_image fi + # preserve pre-dump partition table + if getargbool 0 rd.kiwi.install.retain_past; then + fetch_local_partition_table "${image_target}" /tmp/parttable_pre + fi + # setup blocks and blocksize to retain last - if getargbool 0 rd.kiwi.install.retain_last; then + if getargbool 0 rd.kiwi.install.retain_last || \ + getargbool 0 rd.kiwi.install.retain_past + then if [ -n "${image_from_remote}" ];then image_size=$((blocks * blocksize)) parttable=$( @@ -409,15 +416,49 @@ function dump_image { report_and_quit "Failed to install image" fi fi + + # recreate last partition from pre-dump table + if getargbool 0 rd.kiwi.install.retain_past; then + recreate_last_partition "${image_target}" + fi } function fetch_local_partition_table { local image_source=$1 - local parttable=/tmp/parttable + local parttable=$2 + if [ -z "${parttable}" ];then + parttable=/tmp/parttable + fi sfdisk -d "${image_source}" > "${parttable}" 2>/dev/null echo "${parttable}" } +function recreate_last_partition { + # recreate last partition as it existed prior dump + local image_target=$1 + local table_type + table_type=$(get_partition_table_type "${image_target}") + if [ "${table_type}" = "gpt" ];then + relocate_gpt_at_end_of_disk "${image_target}" + fi + # parttable after image dump, the OS + sfdisk -d "${image_target}" > /tmp/parttable_1 2>/dev/null + # last partition of table as it existed prior dump + tail -n 1 /tmp/parttable_pre > /tmp/parttable_2 + # combine table snippets. Please note there can now be a gap + # between the end of the OS table and the start of the last + # partition of the table prior dump. Please also note, if the + # table prior dump had more partitions than only the last + # one to retain, this table concat will not retain those. + # and the OS dump might have overwritten them. A more + # sophisticated concat procedure would be needed to support + # this case here in this code and also in the + # compatible_to_retain() method + cat /tmp/parttable_1 /tmp/parttable_2 > /tmp/parttable + set_device_lock "${image_target}" \ + sfdisk -f "${image_target}" < /tmp/parttable +} + function fetch_remote_partition_table { local image_source=$1 local image_size=$2 @@ -452,8 +493,14 @@ function compatible_to_retain { touch /tmp/retain_not_applicable return 1 fi - if [ ! "${source_start}" = "${target_start}" ];then - report_and_quit "Cannot retain partition, start address mismatch" + if getargbool 0 rd.kiwi.install.retain_last; then + if [ ! "${source_start}" = "${target_start}" ];then + report_and_quit "Cannot retain partition, start address mismatch" + fi + elif getargbool 0 rd.kiwi.install.retain_past; then + if [ "${source_start}" -gt "${target_start}" ];then + report_and_quit "Cannot retain partition, image overlaps" + fi fi return 0 } @@ -550,7 +597,9 @@ function check_image_integrity { # no verification wanted return fi - if getargbool 0 rd.kiwi.install.retain_last; then + if getargbool 0 rd.kiwi.install.retain_last || \ + getargbool 0 rd.kiwi.install.retain_past + then if [ ! -e /tmp/retain_not_applicable ];then # no verification possible as only a portion of # the image got deployed intentionally