DO_RW_UPDATE_FILE="$FOTA_UPDATE_PREFIX/opt/.do_rw_update"
TRUE=0
FALSE=1
+SUPERFS=""
#------------------------------------------------
# critical_log msg [file]
fi
}
+map_from_super() {
+ local part_name="$1"
+ local part_table="$2"
+ echo "$part_table" | /usr/sbin/dmsetup create "$part_name" &>/dev/null
+ if [ $? = 0 ]; then
+ echo "/dev/mapper/$part_name"
+ return 0
+ else
+ echo "WARNING : SUPER FOUND BUT $part_name NOT FOUND" >&2
+ return 1
+ fi
+}
+
+check_if_super() {
+ if SUPERFS="$(/usr/bin/blkid-print "$EMMC_DEVICE" super a)"; then
+ local MAPPED_DEVICES=""
+ MAPPED_DEVICES=$(dmsetup ls)
+
+ # if dynamic partitions are used, only partitions from the current
+ # slot are mapped on boot. dmsetup will list only *_{CURRENT_AB}
+ # partitions. This check allows to tell which partitions are mapped
+ # and which have to be mapped in order to perform upgrade.
+ if [[ $MAPPED_DEVICES != *"rootfs_${NEXT_AB}"* ]]; then
+ PARSE_DYNPARTS=`/usr/sbin/parse-dynparts "$SUPERFS" --list-tables`
+
+ while read -r part_name part_table; do
+ if [ "$part_name" = "rootfs_${NEXT_AB}" ]; then
+ map_from_super "$part_name" "$part_table"
+ fi
+
+ if [ "$part_name" = "hal_${NEXT_AB}" ]; then
+ map_from_super "$part_name" "$part_table"
+ fi
+ done <<< "$PARSE_DYNPARTS"
+ fi
+ fi
+}
+
check_used_block_device() {
local MAPPER_MATCH_REGEX='.*/dev/mapper.*'
ROOTFS_DEVICE="$(findmnt / -no SOURCE)"
flog "[Error] Unable to find used block device: $EMMC_DEVICE, for /"
exit_error
fi
+
+ check_if_super
}
background_copy() {
flog "[Info] Background copying A|B partitions for update..."
start_duration=$(date +%s)
for partition_name in ${PARTITION_LIST}; do
- # echo is there to suspend abort when partition will not be found e.g. hal
- if ! CURRENT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$partition_name" "$CURRENT_AB" |\
- sed -E 's|(part_nr: [0-9]+ )\((.*)\): (.*)|\3|' || echo "__FALSE__")" || \
- [ "$CURRENT_PARTITION" == "__FALSE__" ]; then
- flog "[Error] Unable to find: $partition_name current partition on $EMMC_DEVICE device on $CURRENT_AB slot"
- check_optional_partition "$partition_name" 1
- continue
- fi
- if ! NEXT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$partition_name" "$NEXT_AB" |\
- sed -E 's|(part_nr: [0-9]+ )\((.*)\): (.*)|\3|')"; then
- flog "[Error] Unable to find: $partition_name next partition on $EMMC_DEVICE device on $CURRENT_AB slot"
- check_optional_partition "$partition_name" 1
- continue
+ if { [ "$partition_name" == "rootfs" ] || [ "$partition_name" == "hal" ]; } && [ -n "$SUPERFS" ]; then
+ CURRENT_PARTITION="/dev/mapper/${partition_name}_${CURRENT_AB}"
+ NEXT_PARTITION="/dev/mapper/${partition_name}_${NEXT_AB}"
+ else
+ if ! CURRENT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$partition_name" "$CURRENT_AB")"; then
+ flog "[Error] Unable to find: $partition_name current partition on $EMMC_DEVICE device on $CURRENT_AB slot"
+ check_optional_partition "$partition_name" 1
+ continue
+ fi
+
+ if ! NEXT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$partition_name" "$NEXT_AB")"; then
+ flog "[Error] Unable to find: $partition_name next partition on $EMMC_DEVICE device on $CURRENT_AB slot"
+ check_optional_partition "$partition_name" 1
+ continue
+ fi
fi
- if [ "$CURRENT_PARTITION" == "" ] || [ "$NEXT_PARTITION" = "" ]; then
+ if [ "$CURRENT_PARTITION" == "" ] || [ "$NEXT_PARTITION" == "" ]; then
flog "[Error] current: $CURRENT_PARTITION or next: $NEXT_PARTITION partition is empty on $EMMC_DEVICE device"
return $FALSE
fi
exit_error
fi
- local NEXT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$PART_NAME" "$NEXT_AB" |\
- /bin/sed -E 's|(part_nr: [0-9]+ )\((.*)\): (.*)|\3|')"
- local CURR_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$PART_NAME" "$CURRENT_AB" |\
- /bin/sed -E 's|(part_nr: [0-9]+ )\((.*)\): (.*)|\3|')"
+ local CURR_PARTITION=""
+ local NEXT_PARTITION=""
+
+ if { [ "$PART_NAME" == "rootfs" ] || [ "$PART_NAME" == "hal" ]; } && [ x$SUPERFS != "x" ]; then
+ NEXT_PARTITION="/dev/mapper/${PART_NAME}_${NEXT_AB}"
+ CURR_PARTITION="/dev/mapper/${PART_NAME}_${CURRENT_AB}"
+ else
+ NEXT_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$PART_NAME" "$NEXT_AB")"
+ CURR_PARTITION="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$PART_NAME" "$CURRENT_AB")"
+ fi
flog "[Info] Flashing $DELTA_NAME... to $NEXT_PARTITION"
local DST="$2"
local MOUNT_OPTIONS="$3"
local SRC
- if ! SRC="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$GPT_LABEL" "$NEXT_AB" |\
- /bin/sed -E 's|(part_nr: [0-9]+ )\((.*)\): (.*)|\3|')"; then
+ if ! SRC="$(/usr/bin/blkid-print "$EMMC_DEVICE" "$GPT_LABEL" "$NEXT_AB")"; then
flog "[Error] Unable to find $GPT_LABEL partition on $EMMC_DEVICE device for $NEXT_AB slot"
return 1
fi
void usage(const char* msg) {
if (msg) {
- printf("%s\n", msg);
+ fprintf(stderr, "%s\n", msg);
}
- printf("USAGE: blkid-print device_name partition_label suffix\n"
+ fprintf(stderr, "USAGE: blkid-print device_name partition_label suffix [verbose]\n"
"device_name: block device e.g. /dev/mmcblk0\n"
"partition_label: partiton label to search for e.g. rootfs,ramdisk etc.\n"
- "suffix: a|b partiton slot\n");
+ "suffix: a|b partiton slot\n"
+ "verbose: optional, prints part_nr: part_nr (part_label): part_path instead of part_path only\n");
}
blkid_partition partition_for(char *device_name, char *part_name, char *new_slot) {
char part_name_with_slot[MAX_PARTNAME_LEN];
int found_part_n = -1;
if (!device_name || !part_name || !new_slot){
- printf("partition_for: one or more argument is NULL\n");
+ fprintf(stderr, "partition_for: one or more argument is NULL\n");
return NULL;
}
if (snprintf(part_name_with_slot, MAX_PARTNAME_LEN, "%s_%s", part_name, new_slot) < 0) {
}
blkid_probe pr = blkid_new_probe_from_filename(device_name);
if (pr == NULL) {
- printf("ERROR: blkid error for %s\n", device_name);
+ fprintf(stderr, "ERROR: blkid error for %s\n", device_name);
usage(NULL);
return NULL;
}
blkid_partlist ls = blkid_probe_get_partitions(pr);
if (!ls) {
- printf("ERROR: unable to probe partitions.\n");
+ fprintf(stderr, "ERROR: unable to probe partitions.\n");
blkid_free_probe(pr);
return NULL;
}
int nparts = blkid_partlist_numof_partitions(ls);
if (nparts == -1) {
- printf("ERROR: unable to get partition count\n");
+ fprintf(stderr, "ERROR: unable to get partition count\n");
blkid_free_probe(pr);
return NULL;
}
int main(int argc, char *argv[]) {
char device_name_path[PATH_MAX];
- if (argc != 4) {
+ if (argc < 4 || argc > 5 || (argc == 5 && strcmp(argv[4], "verbose")) ) {
usage("Please specify correct argument number\n");
return 1;
}
+
+ int verbose = (argc == 5) ? 1 : 0;
+
char *device_name = realpath(argv[1], device_name_path);
if (!device_name) {
- printf("ERROR: Unable to determine realpath for: %s\n", argv[1]);
+ fprintf(stderr, "ERROR: Unable to determine realpath for: %s\n", argv[1]);
usage(NULL);
return 1;
}
char *suffix = argv[3];
blkid_partition part = partition_for(device_name, partition_label, suffix);
if (part == NULL) {
- printf("ERROR: Partition '%s' not found.\n", partition_label);
+ fprintf(stderr, "ERROR: Partition '%s' not found.\n", partition_label);
usage(NULL);
return 2;
}
int part_nr = blkid_partition_get_partno(part);
if (part_nr < 0) {
- printf("ERROR: Partition '%s' not found", partition_label);
+ fprintf(stderr, "ERROR: Partition '%s' not found", partition_label);
return 3;
}
const char *part_label = blkid_partition_get_name(part);
snprintf(part_path, PATH_MAX, "%s%d", device_name, part_nr);
else
snprintf(part_path, PATH_MAX, "%sp%d", device_name, part_nr);
- printf("part_nr: %d (%s): %s\n", part_nr, part_label, part_path);
- return 0;
-}
+ if (verbose)
+ printf("part_nr: %d (%s): %s\n", part_nr, part_label, part_path);
+ else
+ printf("%s\n", part_path);
+ return 0;
+}