From 15f0d1559085f00d577b901130a8bb23d072bebd Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 31 Dec 2013 12:01:52 +0200 Subject: [PATCH 01/16] Add a commentary about the creator Add a "# Generated by $PROG" commentary to every generated file in order to make it easier for people to understand where various config files come from. Signed-off-by: Artem Bityutskiy --- setup-extlinux-conf | 1 + setup-gummiboot-conf | 2 ++ setup-ivi-fstab | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/setup-extlinux-conf b/setup-extlinux-conf index 060d4fc..20e00c9 100755 --- a/setup-extlinux-conf +++ b/setup-extlinux-conf @@ -39,6 +39,7 @@ create_default_conf_file() mkdir -p $verbose "$conf_dir" >&2 cat > "$conf_file" <<-EOF + # Generated by $PROG ui vesamenu.c32 prompt 0 timeout 1 diff --git a/setup-gummiboot-conf b/setup-gummiboot-conf index dbd4dfc..7f19c6b 100755 --- a/setup-gummiboot-conf +++ b/setup-gummiboot-conf @@ -51,6 +51,7 @@ create_default_conf_file() mkdir -p $verbose "$conf_dir" >&2 cat > "$conf_file" <<-EOF + # Generated by $PROG timeout 0 default $1 EOF @@ -182,6 +183,7 @@ add_subcommand() # Create the new entry mkdir -p $verbose "$entries_dir" >&2 cat > "$entry_path" <<-EOF + # Generated by $PROG title $title version $kernel_version efi /$kernel diff --git a/setup-ivi-fstab b/setup-ivi-fstab index 01d32f7..8b67734 100755 --- a/setup-ivi-fstab +++ b/setup-ivi-fstab @@ -83,7 +83,8 @@ fi installerfw_verify_defined "INSTALLERFW_PART_COUNT" -contents="devpts /dev/pts devpts gid=5,mode=620 0 0 +contents="# Generated by $PROG +devpts /dev/pts devpts gid=5,mode=620 0 0 tmpfs /dev/shm tmpfs defaults 0 0 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0" -- 2.7.4 From bbf60157660608ad4d46f0a4e5013ca942f18b2c Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 1 Jan 2014 16:10:08 +0200 Subject: [PATCH 02/16] Source full path I do not know why, but in a Tizen IVI chroot environment sourcing does not work unless the full path is specified. Change-Id: Ia938d0d71d70b2512fd679b859f9318b203ae69d Signed-off-by: Artem Bityutskiy --- setup-extlinux-conf | 4 +--- setup-gummiboot-conf | 4 +--- setup-ivi-boot | 4 ++-- setup-ivi-bootloader-conf | 4 ++-- setup-ivi-fstab | 4 ++-- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/setup-extlinux-conf b/setup-extlinux-conf index 20e00c9..5854f7d 100755 --- a/setup-extlinux-conf +++ b/setup-extlinux-conf @@ -8,9 +8,7 @@ PROG="setup-extlinux-conf" VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" -PATH="/usr/share/setup-ivi:$srcdir:$PATH" - -. setup-ivi-sh-functions +. "$srcdir/setup-ivi-sh-functions" # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. diff --git a/setup-gummiboot-conf b/setup-gummiboot-conf index 7f19c6b..cd9c245 100755 --- a/setup-gummiboot-conf +++ b/setup-gummiboot-conf @@ -8,9 +8,7 @@ PROG="setup-gummiboot-conf" VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" -PATH="/usr/share/setup-ivi:$srcdir:$PATH" - -. setup-ivi-sh-functions +. "$srcdir/setup-ivi-sh-functions" # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. diff --git a/setup-ivi-boot b/setup-ivi-boot index 8e00208..13f2406 100755 --- a/setup-ivi-boot +++ b/setup-ivi-boot @@ -10,8 +10,8 @@ VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" PATH="/usr/share/setup-ivi:$srcdir:$PATH" -. setup-ivi-sh-functions -. installerfw-sh-functions +. "$srcdir/setup-ivi-sh-functions" +. "$srcdir/installerfw-sh-functions" # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. diff --git a/setup-ivi-bootloader-conf b/setup-ivi-bootloader-conf index ac59db2..4accba1 100755 --- a/setup-ivi-bootloader-conf +++ b/setup-ivi-bootloader-conf @@ -10,8 +10,8 @@ VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" PATH="/usr/share/setup-ivi:$srcdir:$PATH" -. setup-ivi-sh-functions -. installerfw-sh-functions +. "$srcdir/setup-ivi-sh-functions" +. "$srcdir/installerfw-sh-functions" # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. diff --git a/setup-ivi-fstab b/setup-ivi-fstab index 8b67734..100966c 100755 --- a/setup-ivi-fstab +++ b/setup-ivi-fstab @@ -10,8 +10,8 @@ VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" PATH="/usr/share/setup-ivi:$srcdir:$PATH" -. setup-ivi-sh-functions -. installerfw-sh-functions +. "$srcdir/setup-ivi-sh-functions" +. "$srcdir/installerfw-sh-functions" # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. -- 2.7.4 From 9fddf16b8c31b3e901b9558348e35939fdb472ea Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 1 Jan 2014 16:23:22 +0200 Subject: [PATCH 03/16] Fix installerfw environment save/restore Change-Id: I39edcdf6571b19f423f48adfe439ed11f2df1379 Signed-off-by: Artem Bityutskiy --- installerfw-sh-functions | 10 +++++++--- setup-ivi-boot | 4 +--- setup-ivi-fstab | 4 +++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/installerfw-sh-functions b/installerfw-sh-functions index bfa4321..f8203d3 100644 --- a/installerfw-sh-functions +++ b/installerfw-sh-functions @@ -116,7 +116,11 @@ installerfw_restore_env() # Check whether installer framework variables are defined installerfw_available() { - printenv | LC_ALL=C grep -q "^INSTALLERFW_[^[:blank:]]\+" + if printenv | LC_ALL=C grep -q "^INSTALLERFW_[^[:blank:]]\+"; then + return 0; + else + return 1; + fi } # Check if the system is an EFI boot system by checking whether the boot @@ -133,11 +137,11 @@ installerfw_is_efi_boot_system() if [ "${INSTALLERFW_PTABLE_FORMAT:-}" = "gpt" ] && \ [ "$__ptypeid" = "$__esp_ptypeid" ]; then __verbose "installerfw_is_efi_boot_system(): /boot is" \ - "the EFI system partition (type is" "\"$__ptypeid\")" + "the EFI system partition" return 0 else __verbose "installerfw_is_efi_boot_system(): no EFI" \ - "system partition found (type is" "\"$__ptypeid\")" + "system partition found" return 1 fi } diff --git a/setup-ivi-boot b/setup-ivi-boot index 13f2406..09336f0 100755 --- a/setup-ivi-boot +++ b/setup-ivi-boot @@ -143,9 +143,7 @@ done bootdir="$(installerfw_mnt_prefix "/boot")" if installerfw_available; then - if ! [ -s "$(installerfw_get_env_file_name)" ]; then - installerfw_save_env - fi + installerfw_save_env else installerfw_restore_env fi diff --git a/setup-ivi-fstab b/setup-ivi-fstab index 100966c..a0c1153 100755 --- a/setup-ivi-fstab +++ b/setup-ivi-fstab @@ -73,7 +73,9 @@ while true; do shift done -installerfw_available || installerfw_restore_env +if ! installerfw_available; then + installerfw_restore_env +fi fstab="$(installerfw_mnt_prefix "/etc/fstab")" -- 2.7.4 From c77ba17979c7813b7a29584c85963c47890bde92 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 1 Jan 2014 16:51:17 +0200 Subject: [PATCH 04/16] installerfw-sh-functions: do not define mount prefix ourselves Change-Id: If577be871295e25b211e58d7b8e70ee53c52f54a Signed-off-by: Artem Bityutskiy --- installerfw-sh-functions | 3 --- 1 file changed, 3 deletions(-) diff --git a/installerfw-sh-functions b/installerfw-sh-functions index f8203d3..4f6374e 100644 --- a/installerfw-sh-functions +++ b/installerfw-sh-functions @@ -14,9 +14,6 @@ __osrelease_file="/etc/os-release" # EFI System Partition PARTUUID __esp_ptypeid="C12A7328-F81F-11D2-BA4B-00A0C93EC93B" -# Mount prefix is assumed to be "/" if it is not defined -[ -n "${INSTALLERFW_MOUNT_PREFIX:-}" ] || export INSTALLERFW_MOUNT_PREFIX="/" - __fatal() { IFS= printf "%s\n" "$__PROG: error: $*" 1>&2 -- 2.7.4 From a24172b701d078fc03bb0eb90b472d7198254ca5 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 2 Jan 2014 07:47:52 +0200 Subject: [PATCH 05/16] Search for common files in /usr/share/setup-ivi too Change-Id: If1c3f9f21907130e6688840c59e311f9681c3134 Signed-off-by: Artem Bityutskiy --- setup-extlinux-conf | 6 +++++- setup-gummiboot-conf | 6 +++++- setup-ivi-boot | 9 +++++++-- setup-ivi-bootloader-conf | 9 +++++++-- setup-ivi-fstab | 9 +++++++-- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/setup-extlinux-conf b/setup-extlinux-conf index 5854f7d..9b67c12 100755 --- a/setup-extlinux-conf +++ b/setup-extlinux-conf @@ -8,7 +8,11 @@ PROG="setup-extlinux-conf" VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" -. "$srcdir/setup-ivi-sh-functions" +if [ -f "$srcdir/setup-ivi-sh-functions" ]; then + . "$srcdir/setup-ivi-sh-functions" +else + . /usr/share/setup-ivi/setup-ivi-sh-functions +fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. diff --git a/setup-gummiboot-conf b/setup-gummiboot-conf index cd9c245..b344029 100755 --- a/setup-gummiboot-conf +++ b/setup-gummiboot-conf @@ -8,7 +8,11 @@ PROG="setup-gummiboot-conf" VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" -. "$srcdir/setup-ivi-sh-functions" +if [ -f "$srcdir/setup-ivi-sh-functions" ]; then + . "$srcdir/setup-ivi-sh-functions" +else + . /usr/share/setup-ivi/setup-ivi-sh-functions +fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. diff --git a/setup-ivi-boot b/setup-ivi-boot index 09336f0..b020d12 100755 --- a/setup-ivi-boot +++ b/setup-ivi-boot @@ -10,8 +10,13 @@ VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" PATH="/usr/share/setup-ivi:$srcdir:$PATH" -. "$srcdir/setup-ivi-sh-functions" -. "$srcdir/installerfw-sh-functions" +if [ -f "$srcdir/setup-ivi-sh-functions" ]; then + . "$srcdir/setup-ivi-sh-functions" + . "$srcdir/installerfw-sh-functions" +else + . /usr/share/setup-ivi/setup-ivi-sh-functions + . /usr/share/setup-ivi/installerfw-sh-functions +fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. diff --git a/setup-ivi-bootloader-conf b/setup-ivi-bootloader-conf index 4accba1..85d42b0 100755 --- a/setup-ivi-bootloader-conf +++ b/setup-ivi-bootloader-conf @@ -10,8 +10,13 @@ VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" PATH="/usr/share/setup-ivi:$srcdir:$PATH" -. "$srcdir/setup-ivi-sh-functions" -. "$srcdir/installerfw-sh-functions" +if [ -f "$srcdir/setup-ivi-sh-functions" ]; then + . "$srcdir/setup-ivi-sh-functions" + . "$srcdir/installerfw-sh-functions" +else + . /usr/share/setup-ivi/setup-ivi-sh-functions + . /usr/share/setup-ivi/installerfw-sh-functions +fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. diff --git a/setup-ivi-fstab b/setup-ivi-fstab index a0c1153..705fa80 100755 --- a/setup-ivi-fstab +++ b/setup-ivi-fstab @@ -10,8 +10,13 @@ VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" PATH="/usr/share/setup-ivi:$srcdir:$PATH" -. "$srcdir/setup-ivi-sh-functions" -. "$srcdir/installerfw-sh-functions" +if [ -f "$srcdir/setup-ivi-sh-functions" ]; then + . "$srcdir/setup-ivi-sh-functions" + . "$srcdir/installerfw-sh-functions" +else + . /usr/share/setup-ivi/setup-ivi-sh-functions + . /usr/share/setup-ivi/installerfw-sh-functions +fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. -- 2.7.4 From 1a13b53c7797daecb9790135ce56945984fa5704 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 2 Jan 2014 16:19:04 +0200 Subject: [PATCH 06/16] README: a small update Signed-off-by: Artem Bityutskiy --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index b181983..6cfc7eb 100644 --- a/README +++ b/README @@ -15,5 +15,7 @@ Some coding style notes for the shell scripts 4. Be consistent with my style. If you see that something makes no sense or could be improved, change that globally. +5. All the error and verbose output should go to stderr + -- Artem Bityutskiy -- 2.7.4 From a4edabb9ed3688eb13b45d5142da8f1efada01ad Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 2 Jan 2014 17:46:33 +0200 Subject: [PATCH 07/16] installerfw-sh-functions: fix installerfw_mnt_prefix Signed-off-by: Artem Bityutskiy --- installerfw-sh-functions | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/installerfw-sh-functions b/installerfw-sh-functions index 4f6374e..d865023 100644 --- a/installerfw-sh-functions +++ b/installerfw-sh-functions @@ -42,9 +42,7 @@ installerfw_verify_defined() # tripple "/" in the resulting path. installerfw_mnt_prefix() { - installerfw_verify_defined "INSTALLERFW_MOUNT_PREFIX" - - local path="$INSTALLERFW_MOUNT_PREFIX/$1" + local path="${INSTALLERFW_MOUNT_PREFIX:-}/$1" printf "%s" "$path" | LC_ALL=C sed -e 's/\/\+/\//g' } -- 2.7.4 From 63ec75c9f69cb6a01bbde4c5bb22c354a15c40d7 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Jan 2014 14:03:11 +0200 Subject: [PATCH 08/16] *-environment: update environment variables --- efi-environment | 1 + mbr-environment | 1 + 2 files changed, 2 insertions(+) diff --git a/efi-environment b/efi-environment index 6092527..d5105ab 100644 --- a/efi-environment +++ b/efi-environment @@ -33,3 +33,4 @@ export INSTALLERFW_PART1_TYPE_ID= export INSTALLERFW_PART1_UUID=a9bf2448-17b6-4113-99d7-061435a0a8a6 export INSTALLERFW_PART_COUNT=2 export INSTALLERFW_PTABLE_FORMAT=gpt +export INSTALLERFW_INSTALLER_NAME=mic diff --git a/mbr-environment b/mbr-environment index 2e2fa58..ca1ea84 100644 --- a/mbr-environment +++ b/mbr-environment @@ -34,3 +34,4 @@ unset INSTALLERFW_PART1_TYPE_ID export INSTALLERFW_PART1_UUID=50C898EF-DC27-4CA2-A48C-326A2DE8E018 export INSTALLERFW_PART_COUNT=2 export INSTALLERFW_PTABLE_FORMAT=mbr +export INSTALLERFW_INSTALLER_NAME=mic -- 2.7.4 From d26918f124e1bd464bb0f48fe281684d05b57b6e Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Jan 2014 14:04:28 +0200 Subject: [PATCH 09/16] installerfw-sh-functions: save installer name too Signed-off-by: Artem Bityutskiy --- installerfw-sh-functions | 1 + 1 file changed, 1 insertion(+) diff --git a/installerfw-sh-functions b/installerfw-sh-functions index d865023..7d8a9b3 100644 --- a/installerfw-sh-functions +++ b/installerfw-sh-functions @@ -75,6 +75,7 @@ installerfw_save_env() -e '^INSTALLERFW_PART[[:digit:]]\+_UUID=' \ -e '^INSTALLERFW_PART_COUNT=' \ -e '^INSTALLERFW_PTABLE_FORMAT=' \ +-e '^INSTALLERFW_INSTALLER_NAME=' \ " local variables="$(printenv | eval "LC_ALL=C grep $opts")" -- 2.7.4 From dc6294231ec46157ae1e480f3e6866ab25de3ade Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Jan 2014 17:15:57 +0200 Subject: [PATCH 10/16] setup-ivi-sh-functions: introduce a newline variable ... which is handy. Signed-off-by: Artem Bityutskiy --- setup-ivi-fstab | 2 -- setup-ivi-sh-functions | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/setup-ivi-fstab b/setup-ivi-fstab index 705fa80..dca3ff8 100755 --- a/setup-ivi-fstab +++ b/setup-ivi-fstab @@ -97,8 +97,6 @@ proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0" pnum=0 -br=" -" while [ "$pnum" -lt "$INSTALLERFW_PART_COUNT" ]; do eval uuid="\${INSTALLERFW_PART${pnum}_UUID:-}" eval mountpoint="\${INSTALLERFW_PART${pnum}_MOUNTPOINT:-}" diff --git a/setup-ivi-sh-functions b/setup-ivi-sh-functions index b817e13..2a973f3 100644 --- a/setup-ivi-sh-functions +++ b/setup-ivi-sh-functions @@ -7,6 +7,10 @@ # Own name __PROG="$PROG:-setup-ivi-sh-functions" +# Just a useful variable for the newline character(s) +br=" +" + fatal() { IFS= printf "%s\n" "$PROG: error: $*" 1>&2 -- 2.7.4 From 98215dab20317c79014777e8f341d9f8eccba265 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Jan 2014 14:16:54 +0200 Subject: [PATCH 11/16] Use -- some more Change-Id: I84101a845a725a71bb626e9369b68e95663354ed Signed-off-by: Artem Bityutskiy --- README | 4 ++++ setup-extlinux-conf | 21 +++++++++++---------- setup-gummiboot-conf | 21 ++++++++++++--------- setup-ivi-boot | 8 ++++---- setup-ivi-bootloader-conf | 2 +- setup-ivi-fstab | 2 +- setup-ivi-sh-functions | 11 +++++++---- 7 files changed, 40 insertions(+), 29 deletions(-) diff --git a/README b/README index 6cfc7eb..18764d4 100644 --- a/README +++ b/README @@ -17,5 +17,9 @@ Some coding style notes for the shell scripts 5. All the error and verbose output should go to stderr +6. Use -- to separate options and arguments, this is generally a good defensive + programming practice to make sure no one tricks your commands by adding + options to what should be arguments. E.g., 'rm $file' can be made 'rm -rf /" + if one makes "$file" to be "-rf /" somehow. 'rm -- $file' would catch this. -- Artem Bityutskiy diff --git a/setup-extlinux-conf b/setup-extlinux-conf index 9b67c12..adf5969 100755 --- a/setup-extlinux-conf +++ b/setup-extlinux-conf @@ -17,7 +17,7 @@ fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. if can_switch_to_dash; then - exec dash -euf "$srcdir/$PROG" "$@" + exec dash -euf -- "$srcdir/$PROG" "$@" exit $? fi @@ -39,7 +39,7 @@ create_default_conf_file() { verbose "creating the default configuration file \"$conf_file\"" - mkdir -p $verbose "$conf_dir" >&2 + mkdir -p $verbose -- "$conf_dir" >&2 cat > "$conf_file" <<-EOF # Generated by $PROG ui vesamenu.c32 @@ -97,7 +97,7 @@ remove_label() /$anyl_regexp/!bl # a different label, stop skipping } /$l_regexp/!p # print all other lines - " "$conf_file" + " -- "$conf_file" remove_trailing_empty_lines "$conf_file" } @@ -194,7 +194,7 @@ add_subcommand() # Make sure the extlinux configuration file exists check_and_create_default_conf_file "$label" - if LC_ALL=C grep -q -e "$(label_regexp "$label")" "$conf_file" && \ + if LC_ALL=C grep -q -e "$(label_regexp "$label")" -- "$conf_file" && \ [ -z "$force" ]; then fatal "extlinux boot menu label \"$label\" already exists" \ "(use -f to force re-creating it)" @@ -289,7 +289,7 @@ remove_subcommand() local label="$1" - if ! LC_ALL=C grep -q -e "$(label_regexp "$label")" "$conf_file" && \ + if ! LC_ALL=C grep -q -e "$(label_regexp "$label")" -- "$conf_file" && \ [ -z "$force" ]; then fatal "cannot find label \"$label\" in \"$conf_file\"" \ "(use -f to ignore this error)" @@ -322,7 +322,7 @@ get_kernel_by_label() /$linux_regexp/ { s/$linux_regexp/\2/p } /$kernel_regexp/ { s/$kernel_regexp/\2/p } /$anyl_regexp/!bl # Loop till the next label - }" "$conf_file")" + }" -- "$conf_file")" printf "%s" "${result##*/}" } @@ -388,7 +388,8 @@ default_subcommand() # Find the current default label local regexp="$(get_regexp "default")" - local default_label="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$conf_file")" + local default_label="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" -- \ + "$conf_file")" if [ -z "$label" ]; then printf "%s\n" "label: $default_label" @@ -397,7 +398,7 @@ default_subcommand() fi local l_regexp="$(label_regexp "$label")" - local labels="$(LC_ALL=C grep -e "$l_regexp" "$conf_file" | wc -l)" + local labels="$(LC_ALL=C grep -e "$l_regexp" -- "$conf_file" | wc -l)" if [ "$labels" -eq "0" ] && [ -z "$force" ]; then fatal "cannot find label \"$label\" in \"$conf_file\"" \ @@ -418,14 +419,14 @@ default_subcommand() $ { s/.*/&\n$def/; q } /^[[:blank:]]*$/ { s/.*/$def\n&/; q } /$(anyl_regexp)/ { s/.*/$def\n&/; q } - " "$conf_file" + " -- "$conf_file" return 0 fi # Escape special sed characters in "$entry" and replace the old default # entry with the new one local esc_label="$(esc_sed_replacement "$label")" - LC_ALL=C sed -i -e "s/$regexp/\1$esc_label\3/" "$conf_file" + LC_ALL=C sed -i -e "s/$regexp/\1$esc_label\3/" -- "$conf_file" verbose "set the default boot kernel to \"$label"\" } diff --git a/setup-gummiboot-conf b/setup-gummiboot-conf index b344029..4fa7fbe 100755 --- a/setup-gummiboot-conf +++ b/setup-gummiboot-conf @@ -17,7 +17,7 @@ fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. if can_switch_to_dash; then - exec dash -euf "$srcdir/$PROG" "$@" + exec dash -euf -- "$srcdir/$PROG" "$@" exit $? fi @@ -51,7 +51,7 @@ create_default_conf_file() { verbose "creating the default configuration file \"$conf_file\"" - mkdir -p $verbose "$conf_dir" >&2 + mkdir -p $verbose -- "$conf_dir" >&2 cat > "$conf_file" <<-EOF # Generated by $PROG timeout 0 @@ -183,7 +183,7 @@ add_subcommand() fatal "cannot fetch kernel version from \"$kernel\"" # Create the new entry - mkdir -p $verbose "$entries_dir" >&2 + mkdir -p $verbose -- "$entries_dir" >&2 cat > "$entry_path" <<-EOF # Generated by $PROG title $title @@ -194,7 +194,7 @@ add_subcommand() if [ -n "$verbose" ]; then verbose "contents of \"$entry_path\":" - cat "$entry_path" >&2 + cat -- "$entry_path" >&2 fi } @@ -271,7 +271,7 @@ remove_subcommand() "(use -f to ignore this error)" fi - rm -rf $verbose "$entry_path" >&2 + rm -rf $verbose -- "$entry_path" >&2 verbose "removed $entry_path" } @@ -289,11 +289,13 @@ get_kernel_from_entry() if [ -f "$entry" ]; then local regexp="$(get_regexp "efi")" - local result="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$entry")" + local result="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" -- \ + "$entry")" if [ -z "$result" ]; then regexp="$(get_regexp "linux")" - result="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$entry")" + result="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" -- \ + "$entry")" [ -n "$result" ] || return 0 fi @@ -365,7 +367,8 @@ default_subcommand() # Find the current default entry local regexp="$(get_regexp "default")" - local default_entry="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$conf_file")" + local default_entry="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" -- \ + "$conf_file")" if [ -z "$entry" ]; then printf "%s\n" "entry: $default_entry" @@ -391,7 +394,7 @@ default_subcommand() # Escape special sed characters in "$entry" and replace the old default # entry with the new one local entry_esc="$(esc_sed_replacement "$entry")" - LC_ALL=C sed -i -e "s/$regexp/\1$entry_esc\3/" "$conf_file" + LC_ALL=C sed -i -e "s/$regexp/\1$entry_esc\3/" -- "$conf_file" verbose "set the default boot kernel to \"$entry"\" } diff --git a/setup-ivi-boot b/setup-ivi-boot index b020d12..ba167fc 100755 --- a/setup-ivi-boot +++ b/setup-ivi-boot @@ -21,7 +21,7 @@ fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. if can_switch_to_dash; then - exec dash -euf "$srcdir/$PROG" "$@" + exec dash -euf -- "$srcdir/$PROG" "$@" exit $? fi @@ -39,7 +39,7 @@ install_gummiboot() fi # Install gummiboot - mkdir -p $verbose "$installdir" >&2 + mkdir -p $verbose -- "$installdir" >&2 [ -f "$gummiboot_path/gummibootia32.efi" ] && \ cp $verbose "$gummiboot_path/gummibootia32.efi" \ "$installdir/bootia32.efi" >&2 @@ -73,7 +73,7 @@ install_extlinux() "variable is not defined" # Install extlinux - mkdir -p $verbose "$installdir" >&2 + mkdir -p $verbose -- "$installdir" >&2 "$extlinux" --device "$boot_devnode" -i "$installdir" || \ fatal "cannot install extlinux to \"$installdir\"" \ "(requires extlinux version 5 or greater)" @@ -163,7 +163,7 @@ else fi # Create bootloader entries for each kernel -kernels="$(ls -1 "$bootdir" | LC_ALL=C grep "^vmlinuz-" | sort -r)" +kernels="$(ls -1 "$bootdir" | LC_ALL=C grep -- "^vmlinuz-" | sort -r)" [ -n "$kernels" ] || \ fatal "no kernels (vmlinuz-*) found in \"$bootdir\"" diff --git a/setup-ivi-bootloader-conf b/setup-ivi-bootloader-conf index 85d42b0..01e689c 100755 --- a/setup-ivi-bootloader-conf +++ b/setup-ivi-bootloader-conf @@ -21,7 +21,7 @@ fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. if can_switch_to_dash; then - exec dash -euf "$srcdir/$PROG" "$@" + exec dash -euf -- "$srcdir/$PROG" "$@" exit $? fi diff --git a/setup-ivi-fstab b/setup-ivi-fstab index dca3ff8..7f1440f 100755 --- a/setup-ivi-fstab +++ b/setup-ivi-fstab @@ -21,7 +21,7 @@ fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. if can_switch_to_dash; then - exec dash -euf "$srcdir/$PROG" "$@" + exec dash -euf -- "$srcdir/$PROG" "$@" exit $? fi diff --git a/setup-ivi-sh-functions b/setup-ivi-sh-functions index 2a973f3..4831048 100644 --- a/setup-ivi-sh-functions +++ b/setup-ivi-sh-functions @@ -34,7 +34,8 @@ get_os_name() fatal "the \"$osrelease_path\" file not found" # Get the OS name - local __os_name="$(LC_ALL=C sed -n -e 's/^PRETTY_NAME="\(.*\)"$/\1/p' "$osrelease_path")" + local __os_name="$(LC_ALL=C sed -n -e 's/^PRETTY_NAME="\(.*\)"$/\1/p' \ + -- "$osrelease_path")" [ -n "$__os_name" ] || \ fatal "cannot find \"PRETTY_NAME\" variable in \"$osrelease_path\"" @@ -92,12 +93,14 @@ get_newest_kernel() local bootdir="$1"; shift # Generate the list of installed kernels - local kernels="$(ls -1 "$bootdir" | LC_ALL=C grep "^vmlinuz-" | sort -r)" + local kernels="$(ls -1 "$bootdir" | LC_ALL=C grep -- "^vmlinuz-" | \ + sort -r)" # Exclude the unwanted kernel, if any if [ -n "${1:-}" ]; then local kernel="$(esc_regexp "$1")" - kernels="$(printf "%s" "$kernels" | LC_ALL=C grep -v "^$kernel$")" + kernels="$(printf "%s" "$kernels" | LC_ALL=C grep -v -- \ + "^$kernel$")" fi printf "%s" "$kernels" | head -n1 @@ -118,5 +121,5 @@ remove_trailing_empty_lines() bl # and start over } /^[[:blank:]]*$/!p # print the pattern buffer for non-blank lines - ' "$file" + ' -- "$file" } -- 2.7.4 From b0b6a72ea990c11c0b4f445855c735a69dea7dde Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Jan 2014 19:23:26 +0200 Subject: [PATCH 12/16] setup-ivi-fstab: use correct case Apparently, mount is case-sensitive. The UUID for normal file-systems like ext4 must be lower case, just like it is in /dev/disk/by-uuid/. But the short FAT-FS ID has to be all-capitals. Take this into account in 'setup-ivi-fstab'. Also add a couple more checks to make sure the installer framework variables that we use exist. Signed-off-by: Artem Bityutskiy --- setup-ivi-fstab | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/setup-ivi-fstab b/setup-ivi-fstab index 7f1440f..a91c19c 100755 --- a/setup-ivi-fstab +++ b/setup-ivi-fstab @@ -98,11 +98,23 @@ sysfs /sys sysfs defaults 0 0" pnum=0 while [ "$pnum" -lt "$INSTALLERFW_PART_COUNT" ]; do + installerfw_verify_defined "INSTALLERFW_PART${pnum}_UUID" + installerfw_verify_defined "INSTALLERFW_PART${pnum}_MOUNTPOINT" + installerfw_verify_defined "INSTALLERFW_PART${pnum}_FSTYPE" + eval uuid="\${INSTALLERFW_PART${pnum}_UUID:-}" eval mountpoint="\${INSTALLERFW_PART${pnum}_MOUNTPOINT:-}" eval fsopts="\${INSTALLERFW_PART${pnum}_FSOPTS:-defaults}" eval fstype="\${INSTALLERFW_PART${pnum}_FSTYPE:-}" + if [ "$fstype" = "vfat" ]; then + # FAT FS's short UUID has to be uppercase + uuid="$(printf "%s" "$uuid" | tr "[:lower:]" "[:upper:]")" + else + # Normal UUID has to be lowercase + uuid="$(printf "%s" "$uuid" | tr "[:upper:]" "[:lower:]")" + fi + contents="${contents}${br}UUID=$uuid $mountpoint $fstype $fsopts 0 0" pnum="$((pnum+1))" -- 2.7.4 From 9a5e47c8e0dae1000b048759fb3417375ab3756b Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 7 Jan 2014 15:31:49 +0200 Subject: [PATCH 13/16] setup-ivi-bootloader-conf: add a menu entry for OS cloning Change-Id: I139deaae995d643e63fd997da0cee502cc3822af Signed-off-by: Artem Bityutskiy --- setup-ivi-bootloader-conf | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/setup-ivi-bootloader-conf b/setup-ivi-bootloader-conf index 01e689c..2b32595 100755 --- a/setup-ivi-bootloader-conf +++ b/setup-ivi-bootloader-conf @@ -31,6 +31,7 @@ prepare() # Get the installer framework environment installerfw_restore_env + rootdir="$(installerfw_mnt_prefix "/")" bootdir="$(installerfw_mnt_prefix "/boot")" if installerfw_is_efi_boot_system; then @@ -127,22 +128,35 @@ add_subcommand() local os_name= get_os_name "os_name" - # Add the bootloader entry + # Add the default bootloader entry setup-$boot-conf $verbose --bootdir "$bootdir" add $force \ "$kernel" "$os_name" "$kernel" "$options" - # If there is the "quiet" option, create a non-quiet configuration - local dbgopts="$(printf "%s" "$options" | LC_ALL=C \ + # Add the debug bootloader entry. If there is the "quiet" option, + # create a non-quiet configuration. + local verbose_opts="$(printf "%s" "$options" | LC_ALL=C \ sed -e "s/[[:blank:]]\+quiet[[:blank:]]\+/ / s/^quiet[[:blank:]]\+// s/[[:blank:]]\+quiet$// s/^quiet$//")" - dbgopts="$dbgopts ignore_loglevel initcall_debug log_buf_len=2M" + local debug_opts="$verbose_opts ignore_loglevel log_buf_len=2M" + local debug_opts="$debug_opts initcall_debug" + setup-$boot-conf $verbose --bootdir "$bootdir" add \ - $force "$kernel-debug" "$os_name (debug)" \ - "$kernel" "$dbgopts" + $force "$kernel-debug" "Debug $os_name" \ + "$kernel" "$verbose_opts" + + # Add the clone bootloader entry, but only if the cloning tool is + # installed + if [ -f "$rootdir/usr/sbin/setup-ivi-clone" ]; then + clone_opts="$options systemd.unit=ivi-clone.service" + clone_opts="$clone_opts ivi-clone-target=autodetect" + setup-$boot-conf $verbose --bootdir "$bootdir" add \ + $force "$kernel-clone" "Clone $os_name" \ + "$kernel" "$clone_opts" + fi } # @@ -237,9 +251,14 @@ remove_subcommand() fatal "setup-$boot-conf failed to remove" \ "entry \"$kernel\"" setup-$boot-conf $verbose --bootdir "$bootdir" \ - remove $force "$kernel-verbose" || \ + remove $force "$kernel-debug" || \ fatal "setup-$boot-conf failed to remove" \ "entry \"$kernel-verbose\"" + # The "clone" entry does not necessary exist, so use --force + setup-$boot-conf $verbose --bootdir "$bootdir" \ + remove --force "$kernel-clone" || \ + fatal "setup-$boot-conf failed to remove" \ + "entry \"$kernel-clone\"" # If this is not the default kernel, we are done [ "$kernel" = "$default_kernel" ] || return 0 -- 2.7.4 From 715a1fc310346c41135aa83af0f2587de675c5b7 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 15 Jan 2014 12:17:51 +0200 Subject: [PATCH 14/16] Add 'COPYING' file with the GPLv2 licens Change-Id: I5b8885759b1dc4f9c3a383aa1cdd74ee41d50498 Signed-off-by: Artem Bityutskiy --- COPYING | 339 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 COPYING diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. -- 2.7.4 From bdd80cef5b70e702db135df02fa26e5cb60753fd Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Jan 2014 14:04:58 +0200 Subject: [PATCH 15/16] Implement setup-ivi-clone Change-Id: I88c149fe892a25a0a3f03216d1c1c7c34d7e5478 Signed-off-by: Artem Bityutskiy --- installerfw-sh-functions | 2 +- ivi-clone.service | 9 + packaging/setup-ivi.changes | 4 +- packaging/setup-ivi.spec | 31 +++ setup-extlinux-conf | 2 +- setup-gummiboot-conf | 2 +- setup-ivi-boot | 24 +- setup-ivi-bootloader-conf | 2 +- setup-ivi-clone | 541 ++++++++++++++++++++++++++++++++++++++++++++ setup-ivi-clone-service | 180 +++++++++++++++ setup-ivi-fstab | 2 +- setup-ivi-sh-functions | 12 +- 12 files changed, 793 insertions(+), 18 deletions(-) create mode 100644 ivi-clone.service create mode 100755 setup-ivi-clone create mode 100755 setup-ivi-clone-service diff --git a/installerfw-sh-functions b/installerfw-sh-functions index 7d8a9b3..1316f8e 100644 --- a/installerfw-sh-functions +++ b/installerfw-sh-functions @@ -1,4 +1,4 @@ -# Copyright 2013 Intel Corporation +# Copyright 2013-2014 Intel Corporation # Author: Artem Bityutskiy # License: GPLv2 diff --git a/ivi-clone.service b/ivi-clone.service new file mode 100644 index 0000000..10a8d6f --- /dev/null +++ b/ivi-clone.service @@ -0,0 +1,9 @@ +[Unit] +Description=Cloning of the Tizen IVI OS to a non-removable media + +[Service] +Type=oneshot +StandardOutput=journal+console +StandardInput=tty +ExecStart=/usr/sbin/setup-ivi-clone-service +ExecStartPost=/usr/sbin/reboot diff --git a/packaging/setup-ivi.changes b/packaging/setup-ivi.changes index 94f588c..6d1cdb1 100644 --- a/packaging/setup-ivi.changes +++ b/packaging/setup-ivi.changes @@ -1,2 +1,2 @@ -* Thu Dec 19 14:29:23 UTC 2013 Artem Bityutskiy 1.0 -- Initial implementation +* Wed Jan 15 10:15:26 UTC 2014 Artem Bityutskiy 1.0 +- Initial implementation. diff --git a/packaging/setup-ivi.spec b/packaging/setup-ivi.spec index aa95539..d74a028 100644 --- a/packaging/setup-ivi.spec +++ b/packaging/setup-ivi.spec @@ -11,6 +11,7 @@ Requires: /usr/bin/grep Requires: /usr/bin/printf Requires: /usr/bin/printenv Requires: /usr/bin/sort +Requires: /usr/bin/tr Requires: virtual-setup-ivi-bootloader BuildArchitectures: noarch @@ -26,6 +27,20 @@ Provides: virtual-setup-ivi-bootloader Requires: %{name} Requires: syslinux-extlinux +%package -n setup-ivi-clone +Summary: A tool for cloning a Tizen IVI system +Requires: %{name} +Requires: /usr/bin/mount +Requires: /usr/bin/udevadm +Requires: /usr/bin/uuidgen +Requires: /usr/bin/sync +Requires: /usr/bin/tail +Requires: systemd +Requires: gptfdisk +Requires: e2fsprogs +Requires: dosfstools +Requires: rsync + %description This package provides various early system setup programs @@ -37,6 +52,10 @@ configuration files. This package provides a command-line tool for changing the extlinux bootloader configuration file. +%description -n setup-ivi-clone +This package provides a command line tool for cloning a Tizen IVI system to a +different disk. + ### ### PREP ### @@ -51,10 +70,14 @@ configuration file. %install install -d %{buildroot}/%{_sbindir} install -d %{buildroot}/%{_prefix}/share/setup-ivi +install -d %{buildroot}/%{_unitdir} install -m755 setup-ivi-boot %{buildroot}/%{_sbindir} install -m755 setup-ivi-fstab %{buildroot}/%{_sbindir} install -m755 setup-ivi-bootloader-conf %{buildroot}/%{_sbindir} +install -m755 setup-ivi-clone %{buildroot}/%{_sbindir} +install -m755 setup-ivi-clone-service %{buildroot}/%{_sbindir} +install -m644 ivi-clone.service %{buildroot}/%{_unitdir} install -m755 setup-gummiboot-conf %{buildroot}/%{_sbindir} install -m755 setup-extlinux-conf %{buildroot}/%{_sbindir} install -m644 setup-ivi-sh-functions %{buildroot}/%{_prefix}/share/setup-ivi @@ -84,3 +107,11 @@ rm -rf %{buildroot} %files -n setup-extlinux %defattr(-,root,root) %{_sbindir}/setup-extlinux-conf + +%files -n setup-ivi-clone +%defattr(-,root,root) +%{_sbindir}/setup-ivi-clone +%{_sbindir}/setup-ivi-clone-service +# Note, we do not need to run 'systemctl enable ivi-clone' for this one because +# it is activated by the 'systemd.unit=ivi-clone.service' kernel parameter. +%{_unitdir}/ivi-clone.service diff --git a/setup-extlinux-conf b/setup-extlinux-conf index adf5969..4a45152 100755 --- a/setup-extlinux-conf +++ b/setup-extlinux-conf @@ -1,6 +1,6 @@ #!/bin/sh -euf -# Copyright 2013 Intel Corporation +# Copyright 2013-2014 Intel Corporation # Author: Artem Bityutskiy # License: GPLv2 diff --git a/setup-gummiboot-conf b/setup-gummiboot-conf index 4fa7fbe..1fac081 100755 --- a/setup-gummiboot-conf +++ b/setup-gummiboot-conf @@ -1,6 +1,6 @@ #!/bin/sh -euf -# Copyright 2013 Intel Corporation +# Copyright 2013-2014 Intel Corporation # Author: Artem Bityutskiy # License: GPLv2 diff --git a/setup-ivi-boot b/setup-ivi-boot index ba167fc..428443b 100755 --- a/setup-ivi-boot +++ b/setup-ivi-boot @@ -1,6 +1,6 @@ #!/bin/sh -euf -# Copyright 2013 Intel Corporation +# Copyright 2013-2014 Intel Corporation # Author: Artem Bityutskiy # License: GPLv2 @@ -52,10 +52,9 @@ install_gummiboot() install_extlinux() { - verbose "installing extlinux to $bootdir" - local installdir="$bootdir/extlinux" local extlinux="extlinux" + local output # Check if extlinux is available if ! command -v "extlinux" >/dev/null 2>&1; then @@ -73,11 +72,13 @@ install_extlinux() "variable is not defined" # Install extlinux + verbose "installing extlinux to $bootdir, boot device node is" \ + "\"$boot_devnode\"" mkdir -p $verbose -- "$installdir" >&2 - "$extlinux" --device "$boot_devnode" -i "$installdir" || \ - fatal "cannot install extlinux to \"$installdir\"" \ - "(requires extlinux version 5 or greater)" - + output="$("$extlinux" --device "$boot_devnode" -i "$installdir" 2>&1)" \ + || fatal "cannot install extlinux to \"$installdir\" (note," \ + "extlinux version 5 or greater is required)" \ + "${br}${output}" # Get device node name for the boot disk local mbr_devnode @@ -88,9 +89,12 @@ install_extlinux() "variable is not defined" # Install the MBR part of extlinux - local mbr_bin="$(installerfw_mnt_prefix "/usr/share/syslinux/gptmbr.bin")" - dd if="$mbr_bin" of="$mbr_devnode" count=1 || \ - fatal "cannot install MBR: dd if=$mbr_bin of=$mbr_devnode" + local mbr_bin="$(installerfw_mnt_prefix \ + "/usr/share/syslinux/gptmbr.bin")" + verbose "setting up MBR, writing \"$mbr_bin\" to \"$mbr_devnode\"" + output="$(dd if="$mbr_bin" of="$mbr_devnode" count=1 2>&1)" || \ + fatal "cannot install MBR, dd if=$mbr_bin of=$mbr_devnode" \ + "failed${br}${output}" verbose "installed extlinux to $bootdir" } diff --git a/setup-ivi-bootloader-conf b/setup-ivi-bootloader-conf index 2b32595..b5b19f1 100755 --- a/setup-ivi-bootloader-conf +++ b/setup-ivi-bootloader-conf @@ -1,6 +1,6 @@ #!/bin/sh -euf -# Copyright 2013 Intel Corporation +# Copyright 2013-2014 Intel Corporation # Author: Artem Bityutskiy # License: GPLv2 diff --git a/setup-ivi-clone b/setup-ivi-clone new file mode 100755 index 0000000..e36c313 --- /dev/null +++ b/setup-ivi-clone @@ -0,0 +1,541 @@ +#!/bin/sh -euf + +# Copyright 2013-2014 Intel Corporation +# Author: Artem Bityutskiy +# License: GPLv2 + +PROG="setup-ivi-clone" +VER="1.0" + +srcdir="$(readlink -ev -- ${0%/*})" + +if [ -f "$srcdir/setup-ivi-sh-functions" ]; then + . "$srcdir/setup-ivi-sh-functions" + . "$srcdir/installerfw-sh-functions" +else + . /usr/share/setup-ivi/setup-ivi-sh-functions + . /usr/share/setup-ivi/installerfw-sh-functions +fi + +# This is a small trick which I use to make sure my scripts are portable - +# check if 'dash' is present, and if yes - use it. +if can_switch_to_dash; then + exec dash -euf -- "$srcdir/$PROG" "$@" + exit $? +fi + +# These are used in the cleanup handler, so have to be defined before the +# function +tmpdir= +unmount_list= +automount_status= + +# Unmount all partitions which we possibly mounted +unmount_partitions() +{ + printf "%s\n" "$unmount_list" | while IFS= read -r dir; do + if [ -n "$dir" ]; then + verbose "unmount \"$dir\"" + umount $verbose -- "$dir" >&2 ||: + fi + done +} + +# This function is called on exit, crashes, interrupts, etc. We clean up +# everything here before the program is terminated +cleanup_handler() +{ + local exitcode="$1" + + # Restore the default exit handler + trap - EXIT + + verbose "cleanup and exit with code $exitcode" + + unmount_partitions + rm -r $verbose -- "$tmpdir" >&2 + + if [ "$automount_status" = "active" ]; then + message "re-enabling udisks-automount-agent" + systemctl --user start udisks-automount-agent || \ + warning "cannot start udisks-automount-agent" + fi + + exit "$exitcode" +} + +# Append a line to a list, which is just text where each line is considered to +# be an element of the list. The first parameter is the line to append, the +# second parameter is the variable name to append to (the variable is defined +# outside of this function and contains the text to prepend the line to). +list_append() +{ + local __value="$1"; shift + local __list_name="$1" + eval local "__list=\$$__list_name" + + [ -z "$__list" ] && eval "$__list_name=\"\$__value\"" || \ + eval "$__list_name=\"\${__list}\${br}\${__value}\"" +} + +# Similar to 'list_append()', but prepends a list with a line. +list_prepend() +{ + local __value="$1"; shift + local __list_name="$1" + eval local "__list=\$$__list_name" + + [ -z "$__list" ] && eval "$__list_name=\"\$__value\"" || \ + eval "$__list_name=\"\${__value}\${br}\${__list}\"" +} + +# Create partitions on the destination disk. This function also updates the +# following installer framework environment variables: +# o INSTALLERFW_PARTx_PARTUUID +# o INSTALLERFW_PARTx_TYPE_ID +create_partitions() +{ + # The GPT partition type GUID for Linux partitions + local linuxfs_type_id="0fc63daf-8483-4772-8e79-3d69d8477de4" + + verbose "destroying all partitions at \"$dstdisk\"" + sgdisk -z "$dstdisk" -- > /dev/null 2>&1 ||: + sgdisk -Z "$dstdisk" -- > /dev/null 2>&1 ||: + + # Create all partitions one-by-one + local pnum=0 + local gdisk_pnum=1 + while [ "$pnum" -lt "$part_count" ]; do + installerfw_verify_defined "INSTALLERFW_PART${pnum}_SIZE" + + eval local size="\$INSTALLERFW_PART${pnum}_SIZE" + eval local bootflag="\${INSTALLERFW_PART${pnum}_BOOTFLAG:-}" + eval local type_id="\${INSTALLERFW_PART${pnum}_TYPE_ID:-$linuxfs_type_id}" + + if [ "$gdisk_pnum" -eq "$part_count" ]; then + # Make the last partition take the rest of the space + verbose "creating the last partition $pnum" + sgdisk -n "$gdisk_pnum:+0:-1s" -- "$dstdisk" > /dev/null + else + verbose "creating partition $pnum of size $size MiB" + sgdisk -n "$gdisk_pnum:+0:+${size}M" -- "$dstdisk" > /dev/null + fi + + # Re-set the UUID + local partuuid="$(uuidgen)" + verbose "setting partition $pnum PARTUUID to $partuuid" + sgdisk -u "$gdisk_pnum:$partuuid" -- "$dstdisk" > /dev/null + + # Take care of the boot flag + if [ "$bootflag" = "True" ]; then + verbose "setting the boot flag for partition $pnum" + sgdisk -A "$gdisk_pnum:set:2" -- "$dstdisk" > /dev/null + fi + + verbose "setting partition $pnum type ID to $type_id" + sgdisk -t "$gdisk_pnum:$type_id" -- "$dstdisk" > /dev/null + + # Re-define some installer framework variables + eval "export INSTALLERFW_PART${pnum}_PARTUUID=$partuuid" + eval "export INSTALLERFW_PART${pnum}_TYPE_ID=$type_id" + + pnum="$(($pnum + 1))" + gdisk_pnum="$(($gdisk_pnum + 1))" + done +} + +# Find the device node name by its major:minor numbers ($1:$2). +find_devnode_by_nums() +{ + local major="$1"; shift + local minor="$1" + + ls -1 /dev | while IFS= read -r node; do + local ma="$(printf "%d" "0x$(stat -c '%t' -- "/dev/$node")")" + local mi="$(printf "%d" "0x$(stat -c '%T' -- "/dev/$node")")" + + if [ -b "/dev/$node" ] && [ "$ma" -eq "$major" ] && \ + [ "$mi" -eq "$minor" ]; then + printf "%s" "/dev/$node" + break + fi + done +} + +# Find the device node name by a file name. In other words, for a given file, +# fine the device node of the partition this file resides on. +find_devnode_by_file() +{ + local file="$1" + local devnum="$(stat -c '%d' -- "$file")" + local major=$((($devnum / 256) % 256)) + local minor=$(($devnum % 256)) + + find_devnode_by_nums "$major" "$minor" +} + +# Find all the source and destination device nodes and declare change the +# following installer framework environment variables: +# o INSTALLERFW_PARTx_DEVNODE_NOW +# o INSTALLERFW_PARTx_DISK_DEVNODE_NOW +# And for the source partitions, the device node names are stored in +# "srcpartX_devnode" variables (X is the partition number). +find_devnodes() +{ + # Find source device nodes + + local pnum=0 + while [ "$pnum" -lt "$part_count" ]; do + installerfw_verify_defined "INSTALLERFW_PART${pnum}_MOUNTPOINT" + + eval local mountpoint="\$INSTALLERFW_PART${pnum}_MOUNTPOINT" + local devnode="$(find_devnode_by_file "$mountpoint")" + + [ -n "$devnode" ] || fatal "cannot find device node for" \ + "source partition $mountpoint" + + verbose "source partition $mountpoint device node is: $devnode" + + eval "srcpart${pnum}_devnode=$devnode" + + pnum="$(($pnum + 1))" + done + + # Find destination device nodes + + local major="$(printf "%d" "0x$(stat -c '%t' -- "$dstdisk")")" + local minor="$(printf "%d" "0x$(stat -c '%T' -- "$dstdisk")")" + + pnum=0 + while [ "$pnum" -lt "$part_count" ]; do + local part_minor="$(($minor + $pnum + 1))" + devnode="$(find_devnode_by_nums "$major" "$part_minor")" + + [ -n "$devnode" ] || fatal "cannot find device node for" \ + "destination partition $pnum" + + verbose "destination partition $pnum device node is: $devnode" + + eval "export INSTALLERFW_PART${pnum}_DEVNODE_NOW=$devnode" + eval "export INSTALLERFW_PART${pnum}_DISK_DEVNODE_NOW=$dstdisk" + + pnum="$(($pnum + 1))" + done + +} + +# Format all the destination partitions and changes the +# "INSTALLERFW_PARTx_UUID" installer framework environment variables. +format_dst_partitions() +{ + local pnum=0 + while [ "$pnum" -lt "$part_count" ]; do + installerfw_verify_defined "INSTALLERFW_PART${pnum}_FSTYPE" + eval local fstype="\$INSTALLERFW_PART${pnum}_FSTYPE" + eval local label="\${INSTALLERFW_PART${pnum}_LABEL:-}" + eval local devnode="\$INSTALLERFW_PART${pnum}_DEVNODE_NOW" + + local uuid="$(uuidgen)" + + verbose "format partition $pnum ($devnode) with mkfs.$fstype" + + if [ "$fstype" != "vfat" ]; then + verbose "partition $pnum label is \"$label\", UUID is \"$uuid\"" + + [ -z "$label" ] || label="-L $label" + + mkfs.$fstype $verbose $quiet $label -U "$uuid" -- "$devnode" >&2 + else + # FATFS Volume ID is an XXXXXXXX (32-bit) string, where + # X is are uppercase hex digits. + uuid="$(printf "%s" "$uuid" | head -c8 | \ + tr "[:lower:]" "[:upper:]")" + + verbose "partition $pnum label is \"$label\", UUID is \"$uuid\"" + + [ -z "$label" ] || label="-n $label" + + if [ -n "$verbose" ]; then + mkfs.vfat $verbose $label -i "$uuid" -- "$devnode" >&2 + else + # mkfs.vfat does not accept -q + mkfs.vfat $label -i "$uuid" -- "$devnode" > /dev/null + fi + + # However, the installer framework variable has to have + # the XXXX-XXXX format, not XXXXXXXX. Unfortunately, + # mkfs.vfat does not like the "-", while 'mount' + # requires the "-". + uuid="$(printf "%s" "$uuid" | LC_ALL=C sed -e 's/.\{4\}/&-/')" + fi + + eval "export INSTALLERFW_PART${pnum}_UUID=$uuid" + + pnum="$(($pnum+1))" + done +} + +# Mount source and destination partition +mount_partitions() +{ + local pnum=0 + while [ "$pnum" -lt "$part_count" ]; do + eval local mountpoint="\$INSTALLERFW_PART${pnum}_MOUNTPOINT" + + # Mount the source partition + eval local devnode="\$srcpart${pnum}_devnode" + local mntdir="$srcbase/$pnum" + + verbose "mounting source partition $pnum" \ + "($devnode, $mountpoint) to $mntdir" + + mkdir -p $verbose -- "$mntdir" >&2 + mount $verbose -- "$devnode" "$mntdir" >&2 + list_prepend "$mntdir" "unmount_list" + + # Mount the destination partition + eval devnode="\$INSTALLERFW_PART${pnum}_DEVNODE_NOW" + mntdir="$dstbase/$pnum" + + verbose "mounting destination partition $pnum" \ + "($devnode, $mountpoint) to $mntdir" + + mkdir -p $verbose -- "$mntdir" >&2 + mount $verbose -- "$devnode" "$mntdir" >&2 + list_prepend "$mntdir" "unmount_list" + + pnum="$(($pnum + 1))" + done +} + +# Copy data from all the source partitions to destination partitions +copy_the_data() +{ + local pnum=0 + while [ "$pnum" -lt "$part_count" ]; do + local src_mntdir="$srcbase/$pnum" + local dst_mntdir="$dstbase/$pnum" + + verbose "copy partition $pnum:" \ + "\"$src_mntdir\" -> \"$dst_mntdir\"" + + rsync -WaHXSh --exclude "${tmpdir}" "$src_mntdir/" "$dst_mntdir/" + + pnum="$(($pnum + 1))" + done +} + +# This function creates proper target hierarchy by mounting destination +# partition under the right mount points. By the time this function is called, +# all the destination partitions are mounted under "$dstbase/$pnum", so "/boot" +# is not under "/", etc. This function mounts them under "$dstbase/root" +create_dst_hierarchy() +{ + # Create a sorted list of mount points + local list= + local mountpoint= + local pnum=0 + while [ "$pnum" -lt "$part_count" ]; do + eval mountpoint="\$INSTALLERFW_PART${pnum}_MOUNTPOINT" + list_append "$mountpoint" "list" + pnum="$(($pnum+1))" + done + + list="$(printf "%s" "$list" | sort)" + + mkdir $verbose -- "$dstbase/root" >&2 + + local devnode= + local mntdir= + local IFS="$br" + for mountpoint in $list; do + installerfw_get_part_info "$mountpoint" "DEVNODE_NOW" "devnode" + mntdir="$dstbase/root$mountpoint" + + verbose "mounting \"$devnode\" under \"$mntdir\"" + mount $verbose -- "$devnode" "$mntdir" >&2 + + list_prepend "$mntdir" "unmount_list" + done +} + +# Amend the /etc/installerfw-environment file at the destination. +amend_installerfw_environment() +{ + # Most of the variables were already changed, let's take care about the + # rest. + export INSTALLERFW_INSTALLER_NAME="$PROG" + export INSTALLERFW_MOUNT_PREFIX="$dstbase/root" + + local pnum=0 + while [ "$pnum" -lt "$part_count" ]; do + eval "unset INSTALLERFW_PART${pnum}_DEVNODE" + eval "unset INSTALLERFW_PART${pnum}_DISK_DEVNODE" + pnum="$(($pnum+1))" + done + + installerfw_save_env +} + +# Check if the block device is mounted +# TODO: the much better way to do this is to use the open(2) "O_EXCL" flag +# which has special meaning for block devices. This would need to write a +# C helper program, something like setup-ivi-open-helper. +is_mounted() +{ + local devnode="$(esc_regexp "$1")" + + grep -q -e "^$devnode[p0-9]* " /proc/mounts +} + +show_usage() +{ + cat <<-EOF +Usage: $PROG [options] + +Clone a running Tizen IVI system to a different disk. The mandatory argument +"" is the device node name to clone to (e.g., /dev/sda). Be careful, +this program will destroy all the "" data! + +The program roughly works like this. + +1. Reads the "/etc/installerfw-environment" file to get information about the + partitions of the running system. +2. Partitions "" according to "/etc/installerfw-environment" (the last + partition gets re-sized to consume all the space on ""). +3. Formats all the newly created partitions on "". +4. Copies all the data from the disk Tizen IVI currently runs from to + "", partition-by-partition. +5. Configures the cloned system on "" by "setup-ivi-boot". +6. Reboots the system. + +Options: + -v, --verbose be verbose + --version show the program version and exit + -h, --help show this text and exit +EOF +} + +show_usage_fail() +{ + IFS= printf "%s\n\n" "$PROG: error: $*" >&2 + show_usage >&2 + exit 1 +} + +# Parse the options +tmp=`getopt -n $PROG -o v,h --long verbose,version,help -- "$@"` || + show_usage_fail "cannot parse command-line options" +eval set -- "$tmp" + +dstdisk= +verbose= +quiet="-q" +while true; do + case "$1" in + -v|--verbose) + verbose="-v" + quiet= + ;; + --version) + printf "%s\n" "$VER" + exit 0 + ;; + -h|--help) + show_usage + exit 0 + ;; + --) shift; break + ;; + *) show_usage_fail "unrecognized option \"$1\"" + ;; + esac + shift +done + +[ "$#" -eq 1 ] || \ + show_usage_fail "please, provide exactly one \"disk\" argument" + +dstdisk="$1" +[ -b "$dstdisk" ] || \ + fatal "\"$dstdisk\" does not exist or is not a block device node" + +is_mounted "$dstdisk" && fatal "\"$dstdisk\" is mounted" + +# Load the installer framework data +if ! installerfw_available; then + installerfw_restore_env +fi + +# Install the cleanup handler (the first parameter will be our exit code) +trap 'cleanup_handler $?' EXIT +trap 'cleanup_handler 1' HUP PIPE INT QUIT TERM + +# Create our work directory +tmpdir="$(mktemp --tmpdir="/tmp" -d -t -- "$PROG.XXXX")" +verbose "tmpdir is \"$tmpdir\"" + +srcbase="$tmpdir/src" +dstbase="$tmpdir/dst" +mkdir $verbose -- "$srcbase" >&2 +mkdir $verbose -- "$dstbase" >&2 + +# Fetch some installer framework variables +installerfw_verify_defined "INSTALLERFW_PTABLE_FORMAT" +installerfw_verify_defined "INSTALLERFW_PART_COUNT" + +ptable_format="$INSTALLERFW_PTABLE_FORMAT" +part_count="$INSTALLERFW_PART_COUNT" + +# Some general checks +if [ "$ptable_format" != "gpt" ]; then + fatal "partition table type \"$ptable_format\" is not supported" +fi + +# Disable the Tizen IVI automount agent, otherwise it may start mounting the +# $dstdisk partitions that we are going to create +automount_status="$(systemctl --user is-active udisks-automount-agent 2>/dev/null ||:)" +if [ "$automount_status" = "active" ]; then + message "disabling udisks-automount-agent" + if ! systemctl --user stop udisks-automount-agent; then + warning "cannot stop udisks-automount-agent" + automount_status="dunno" + fi +fi + +# Create partitions on the destination disk +message "partitioning $dstdisk" +create_partitions + +# Make sure the device nodes are created +udevadm settle > /dev/null 2>&1 ||: + +# Find device nodes for source and destination partitions +find_devnodes + +# Format the destination partitions +message "formatting $dstdisk" +format_dst_partitions + +# Mount the source and destination partitions +mount_partitions + +# Copy all the data +message "copying all the data to $dstdisk" +copy_the_data + +# Create proper target file-system hierarchy in order to be able to execute +# installer framework scripts for the target. +create_dst_hierarchy + +message "finished copying, configuring the cloned OS" + +# Amend the /etc/installerfw-environment file on the destination +amend_installerfw_environment + +# Configure the target system +$srcdir/setup-ivi-boot $verbose + +# Note, unmount happens in 'cleanup_handler()' +message "done, synchronizing the data" +sync diff --git a/setup-ivi-clone-service b/setup-ivi-clone-service new file mode 100755 index 0000000..775f382 --- /dev/null +++ b/setup-ivi-clone-service @@ -0,0 +1,180 @@ +#!/bin/sh -euf + +# Copyright 2013-2014 Intel Corporation +# Author: Artem Bityutskiy +# License: GPLv2 + +PROG="setup-ivi-clone-service" +VER="1.0" + +srcdir="$(readlink -ev -- ${0%/*})" +PATH="/usr/share/setup-ivi:$srcdir:$PATH" + +if [ -f "$srcdir/setup-ivi-sh-functions" ]; then + . "$srcdir/setup-ivi-sh-functions" + . "$srcdir/installerfw-sh-functions" +else + . /usr/share/setup-ivi/setup-ivi-sh-functions + . /usr/share/setup-ivi/installerfw-sh-functions +fi + +# This is a small trick which I use to make sure my scripts are portable - +# check if 'dash' is present, and if yes - use it. +if can_switch_to_dash; then + exec dash -euf -- "$srcdir/$PROG" "$@" + exit $? +fi + +# Find the first non-removable device and prints its device node name. +find_an_internal_disk() +{ + local dir + + ls -1 "/sys/block" | while IFS= read -r name; do + local removable="$(cat "/sys/block/$name/removable")" + local size="$(cat "/sys/block/$name/size")" + + if [ "$removable" -eq "0" ] && [ "$size" -ne "0" ]; then + verbose "found removable disk \"$name\"" + printf "%s" "/dev/$name" + break + fi + done +} + +# Get user-readable information about a disk. +get_disk_info() +{ + local name="${1##*/}" + local path="/sys/block/$name" + + local size="$(LC_ALL=C sed -n -e "s/[[:blank:]]*$//p" -- "$path/size")" + local info="size $(($size/2048))MiB" + + if [ -f "$path/device/vendor" ]; then + local vendor="$(LC_ALL=C sed -n -e "s/[[:blank:]]*$//p" -- \ + "$path/device/vendor")" + info="${info}, $vendor" + fi + + if [ -f "$path/device/model" ]; then + local model="$(LC_ALL=C sed -n -e "s/[[:blank:]]*$//p" -- \ + "$path/device/model")" + info="${info} $model" + fi + + printf "%s" "$info" +} + +# Get user confirmation about whether it is OK to proceed. +get_confirmation() +{ + printf "%s\n" "WARNING! All the disk data will be destroyed!" + + while true; do + printf "%s\n" "Type \"yes\" to proceed, type \"no\" to exit" + + local input + read input + + if printf "%s" "$input" | grep -q -I -e "^yes$"; then + return + elif printf "%s" "$input" | grep -q -I -e "^no$"; then + exit 0 + fi + done +} + +show_usage() +{ + cat <<-EOF +Usage: $PROG [options] + +This program is a wrapper over the 'setup-ivi-clone' program and it is intended +to be executed from a systemd service when the system boots up. + +By default, this program finds the first non-removable device in the system and +installs the OS there. However, if the 'ivi-clone-target=' kernel boot +option is present (see "/proc/cmdline"), then this program installs the OS to +the disk represented by "" (e.g., "/dev/sda"). + +The 'ivi-clone-target=autodetect' kernel option causes the default behaviour. + +Options: + -f, --force do not ask for confirmation, just proceed with cloning the OS + --version show the program version and exit + -v, --verbose be verbose + -h, --help show this text and exit +EOF +} + +show_usage_fail() +{ + IFS= printf "%s\n\n" "$PROG: error: $*" >&2 + show_usage >&2 + exit 1 +} + +# Parse the options +tmp=`getopt -n $PROG -o f,v,h --long force,verbose,version,help -- "$@"` || + show_usage_fail "cannot parse command-line options" +eval set -- "$tmp" + +verbose= +force= +while true; do + case "$1" in + -f|--force) + force="-f" + ;; + --version) + printf "%s\n" "$VER" + exit 0 + ;; + -v|--verbose) + verbose="-v" + ;; + -h|--help) + show_usage + exit 0 + ;; + --) shift; break + ;; + *) show_usage_fail "unrecognized option \"$1\"" + ;; + esac + shift +done + +[ "$#" -eq 0 ] || \ + show_usage_fail "this program does not take any arguments" + +# Sleep for a while to make sure other tasks finish and our messages appear the +# last on the console. +sleep 2 + +devnode="$(sed -n -e "s/^.*ivi-clone-target=\([^ ]\+\).*$/\1/p" /proc/cmdline)" +if [ -z "$devnode" ] || [ "$devnode" = "autodetect" ]; then + devnode="$(find_an_internal_disk)" + + [ -n "$devnode" ] || fatal "cannot find an internal disk" +fi + +# Make sure all device nodes are created +udevadm settle > /dev/null 2>&1 ||: + +[ -b "$devnode" ] || fatal "intended to clone the OS to \"$devnode\"," \ + "but it does not exist" + +disk_info="$(get_disk_info "$devnode")" +if [ -n "$disk_info" ]; then + disk_info="$devnode ($disk_info)" +else + disk_info="$devnode" +fi + +printf "%s\n" "cloning the Tizen IVI OS to \"$disk_info\"" +[ -z "$force" ] && get_confirmation +printf "%s\n" "this may take a while, be patient" + +setup-ivi-clone $verbose "$devnode" || fatal "failed to clone to $devnode" diff --git a/setup-ivi-fstab b/setup-ivi-fstab index a91c19c..c130e5f 100755 --- a/setup-ivi-fstab +++ b/setup-ivi-fstab @@ -1,6 +1,6 @@ #!/bin/sh -euf -# Copyright 2013 Intel Corporation +# Copyright 2013-2014 Intel Corporation # Author: Artem Bityutskiy # License: GPLv2 diff --git a/setup-ivi-sh-functions b/setup-ivi-sh-functions index 4831048..f1aa2c6 100644 --- a/setup-ivi-sh-functions +++ b/setup-ivi-sh-functions @@ -1,4 +1,4 @@ -# Copyright 2013 Intel Corporation +# Copyright 2013-2014 Intel Corporation # Author: Artem Bityutskiy # License: GPLv2 @@ -17,6 +17,16 @@ fatal() exit 1 } +warning() +{ + IFS= printf "%s\n" "$PROG: Warning!: $*" >&2 +} + +message() +{ + IFS= printf "%s\n" "$PROG: $*" +} + verbose() { if [ -n "$verbose" ]; then -- 2.7.4 From e4918ab0787fe9cbcde4db579d2666f3d6b7ca5e Mon Sep 17 00:00:00 2001 From: Mikko Ylinen Date: Fri, 31 Jan 2014 13:25:25 +0200 Subject: [PATCH 16/16] setup-gummiboot-conf: add splash file support The latest gummiboot supports splash image loading. Each loader entry can specify the splash image to load using 'splash' parameter. Add a new option to the script to enable callers to generate splash enabled entries. Change-Id: I5c2d997aad869455c9fec9695e5b3664525a89bd Signed-off-by: Mikko Ylinen --- setup-gummiboot-conf | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/setup-gummiboot-conf b/setup-gummiboot-conf index 1fac081..4a84039 100755 --- a/setup-gummiboot-conf +++ b/setup-gummiboot-conf @@ -101,6 +101,9 @@ Options: -f, --force if the entry already exists - re-write it, if /loader/loader.conf does not exist - create one, if / does not exist - do not fail + -s, --splash + add a splash field to the entry file. is a + mandatory parameter to specify splash image location. -h, --help show this text and exit EOF } @@ -120,16 +123,20 @@ add_subcommand() fi local tmp - tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` || + tmp=`getopt -n $PROG -o f,s:,h --long force,splash:,help -- "$@"` || show_add_usage_fail "cannot parse command-line options" eval set -- "$tmp" local force= + local splash= while true; do case "$1" in -f|--force) force="-f" ;; + -s|--splash) + splash="$2"; shift + ;; -h|--help) show_add_usage exit 0 @@ -148,6 +155,9 @@ add_subcommand() if [ "$#" -gt 4 ]; then show_add_usage_fail "too many arguments: \"$1\"" fi + if [ -n "$splash" ] && ! [ -f "$splash" ]; then + show_add_usage_fail "splash file not found: \"$splash\"" + fi prepare @@ -192,6 +202,13 @@ add_subcommand() options $options EOF + # Add an optional splash image entry if the image file exists + if [ -n "$splash" ]; then + cp $verbose -- "$splash" "$entries_dir" + printf "%s\n" "splash \\loader\\entries\\${splash##*/}" \ + >> "$entry_path" + fi + if [ -n "$verbose" ]; then verbose "contents of \"$entry_path\":" cat -- "$entry_path" >&2 -- 2.7.4