Add check for dm-bow error during upgrade
[platform/core/system/upgrade.git] / scripts / rw-upgrade / rw-update-macro.inc
1 #!/bin/sh
2
3 STAT="/usr/bin/stat"
4 OLD_VER=
5 NEW_VER=
6 OLD_VER_INFO="/opt/etc/version"
7 COLOR_ERROR='\033[01;31m'
8 COLOR_DEBUG='\033[01;34m'
9 COLOR_NOTIFY='\033[01;33m'
10 COLOR_RESET='\033[00;00m'
11
12 DEBUG()
13 {
14         LOG_TEXT=$1
15         echo -e "${COLOR_DEBUG}${LOG_TEXT}${COLOR_RESET}"
16 }
17
18 ERROR()
19 {
20         LOG_TEXT=$1
21         echo -e "${COLOR_ERROR}${LOG_TEXT}${COLOR_RESET}"
22 }
23
24 NOTIFY()
25 {
26         LOG_TEXT=$1
27         echo -e "${COLOR_NOTIFY}${LOG_TEXT}${COLOR_RESET}"
28 }
29
30 CRITICAL_LOG()
31 {
32         LOG="[$SCRIPT_NAME]$1"
33         dlogsend -k "$LOG"
34         if [ "$2" != "" ]; then
35                 echo "$LOG" >> "$2"
36         fi
37         echo "$LOG"
38 }
39
40 # Convert version to 4 digits
41 convert_version() {
42         i=0
43         VER=(0 0 0 0)
44         for ENT in $(echo "$1" | tr "." "\n"); do
45                 VER[$i]=$ENT
46                 ((i++))
47         done
48         CVT_VER=${VER[0]}.${VER[1]}.${VER[2]}.${VER[3]}
49 }
50
51 get_version_info() {
52         if [ -f $OLD_VER_INFO ]; then
53                 source $OLD_VER_INFO
54         fi
55         NEW_VER=$(cat /etc/config/model-config.xml | grep platform.version\" \
56                         | sed -e 's/.*>\(.*\)<.*/\1/' | head -1)
57         convert_version $NEW_VER
58         NEW_VER=$CVT_VER
59 }
60
61 write_version_info() {
62         get_version_info
63         echo "OLD_VER=$NEW_VER" > $OLD_VER_INFO
64         /bin/chmod 775 $OLD_VER_INFO
65         /bin/chown .system_fw $OLD_VER_INFO
66 }
67
68 BACKUP_ZIP="/usr/system/RestoreDir/opt.zip"
69
70 restore_from_zip() {
71
72         TARGET_FILE=$1
73         TARGET_DIR=$(dirname /$TARGET_FILE)
74
75         echo "restore_from_zip: $TARGET_FILE"
76         if [ ! -d $TARGET_DIR ]; then
77                 mkdir -p $TARGET_DIR
78         fi
79
80         # The attributes of directory can not be overwritten by unzip.
81         # Unzip the directory into temp path and copy it to original path.
82         if [ "z${TARGET_FILE: -1}" = "z/" ]; then
83                 RESTORE_DIR_PATH="/tmp/restored_dir"
84                 mkdir -p $RESTORE_DIR_PATH
85                 unzip -oX $BACKUP_ZIP $TARGET_FILE -d $RESTORE_DIR_PATH > /dev/null
86                 cp -af $RESTORE_DIR_PATH/$TARGET_FILE $TARGET_DIR
87                 rm -rf $RESTORE_DIR_PATH
88         else
89                 unzip -oX $BACKUP_ZIP $TARGET_FILE -d / > /dev/null
90         fi
91
92         # Restore smack label
93         TMP=$(mktemp /tmp/smackinfo.XXXXXX)
94         PATH_FOR_SMACK=$(echo $TARGET_FILE | sed -e "s/\/$//")
95         SMACK_VAL=$(grep "$PATH_FOR_SMACK " /usr/system/RestoreDir/smack_label.txt | \
96                         { read FILE SMACK; echo $SMACK; })
97         if [ "z$SMACK_VAL" = "z" ]; then
98                 echo "No smack label for $PATH_FOR_SMACK"
99         else
100                 echo "/$PATH_FOR_SMACK $SMACK_VAL" > $TMP
101                 rstsmack $TMP
102         fi
103         rm $TMP
104 }
105
106 restore_backup_file() {
107
108         OVERWRITE=
109         RESTORE_PATH=
110
111         while [ "z$1" != "z" ]; do
112                 case $1 in
113                 -f )
114                         OVERWRITE=$1
115                         ;;
116                 -r )
117                         ;;
118                 * )
119                         RESTORE_PATH=$1
120                         ;;
121                 esac
122                 shift
123         done
124
125         if [ "z$RESTORE_PATH" = "z" ]; then
126                 echo "There is no file to restore"
127                 return
128         fi
129
130         if [ ! "z${RESTORE_PATH:0:1}" = "z/" ]; then
131                 echo "Full path of file is required"
132                 return
133         fi
134
135         if [ -e "$RESTORE_PATH" ]; then
136                 if [ ! "z$OVERWRITE" = "z" ]; then
137                         echo "Warning: $RESTORE_PATH already exists. It will be overwritten"
138                 else
139                         echo "Error: $RESTORE_PATH already exists"
140                         return
141                 fi
142         fi
143
144         # Check if the target file is backed up
145         PATH_FOR_ZIP=$(echo $RESTORE_PATH | sed -e "s/^\///")
146         FOUND_FILES=$(unzip -l $BACKUP_ZIP | awk '{print $4}' | \
147                         grep "^$PATH_FOR_ZIP")
148         FOUND_FILE=$(echo "$FOUND_FILES" | \
149                         grep -E "$PATH_FOR_ZIP$|$PATH_FOR_ZIP/$")
150         if [ "z$FOUND_FILE" = "z" ]; then
151                 echo "Error: $RESTORE_PATH was not backed up"
152                 return
153         fi
154
155         echo "restore_backup_file: $RESTORE_PATH"
156         if [ ! "z${FOUND_FILE: -1}" = "z/" ]; then
157                 restore_from_zip $FOUND_FILE
158         else
159                 for FILE in $FOUND_FILES; do
160                         restore_from_zip $FILE
161                 done
162         fi
163 }
164
165 IS_MOUNT_RO()
166 {
167         PART_PATH="$1"
168         if ! grep "$PART_PATH" /proc/mounts | \
169                 awk '{print $4}' | \
170                 awk -F',' '{for(i=1; i<=NF; i++) {if ($i == "ro") {found=1; exit}}} END {exit found}'; then
171
172                 ERROR "Partition $PART_PATH is mounted as RO, probably due to an error"
173                 return 1
174         fi
175         return 0
176 }
177
178 COMMIT_BOW_PARTITION()
179 {
180         LABEL=${1}
181
182         BOWDEV_PATH=/dev/mapper/bowdev_${LABEL}
183
184         if ! IS_MOUNT_RO "$BOWDEV_PATH"; then
185                 # If the partition is in read-only mode, it is most likely that
186                 # an dm-bow error occurred as a result of insufficient free
187                 # space. Therefore, the upgrade must be considered unsuccessful.
188                 return 1
189         fi
190
191         DM_NUMBER=$(($("${STAT}" -c "0x%T" $(readlink -f ${BOWDEV_PATH}))))
192         echo 2 > /sys/block/dm-${DM_NUMBER}/bow/state
193         NOTIFY "Changes on partition ${LABEL} commited (dm-bow)"
194         return 0
195 }
196
197 COMMIT_F2FS_PARTITION()
198 {
199         LABEL=${1}
200         PART_DEVICE=${2}
201
202         if mount -o remount,checkpoint=enable "${PART_DEVICE}"; then
203                 NOTIFY "Changes on partition ${LABEL} commited (f2fs)"
204                 return 0
205         else
206                 ERROR "Error when commit changes on partition ${LABEL} (f2fs)"
207                 return 1
208         fi
209 }
210
211 DELETE_BTRFS_PARTITION() {
212         PART="$1"
213         MNT_POINT="$("$FINDMNT" "$PART" -o TARGET)"
214         if [ "$MNT_POINT" = "" ]; then
215                 ERROR "Unable to find btrfs mountpoint for: $PART"
216                 return 1
217         fi
218         NOTIFY "Deleting btrfs snapshot"
219         umount "${MNT_POINT}"
220         mount -o subvolid=5,rw "${PART}" "${MNT_POINT}"
221         btrfs subvolume delete "$MNT_POINT"/fota/RO_update
222         rm -rf "$MNT_POINT/fota/RO_update"
223         umount "${MOUNT_POINT}"
224         mount -o rw "${PART}" "${MNT_POINT}"
225         return 0
226 }
227
228
229 COMMIT_BTRFS_PARTITION()
230 {
231         LABEL=${1}
232         PART_SYSTEM_DATA=$(blkid --match-token PARTLABEL="${LABEL}" -o device -l || blkid --match-token LABEL="${LABEL}" -o device -l)
233         if DELETE_BTRFS_PARTITION "${PART_SYSTEM_DATA}"; then
234                 NOTIFY "Changes on partition ${LABEL} commited (btrfs)"
235                 return 0
236         fi
237
238         return 1
239 }
240
241 COMMIT_PARTITION()
242 {
243         LABEL=${1}
244
245         PART_DEVICE=$(blkid --match-token PARTLABEL="${LABEL}" -o device -l || blkid --match-token LABEL="${LABEL}" -o device -l)
246         if [ -z "${PART_DEVICE}" ]; then
247                 NOTIFY "WARNING: Partition ${LABEL} not found"
248                 return 0
249         fi
250
251         TYPE=$(blkid ${PART_DEVICE} -o value -s TYPE | tail -n 1)
252         if [ "${TYPE}" = "ext4" ]; then
253                 COMMIT_BOW_PARTITION "${LABEL}"
254         elif [ "${TYPE}" = "f2fs" ]; then
255                 COMMIT_F2FS_PARTITION "${LABEL}" ${PART_DEVICE}
256         elif [ "${TYPE}" = "btrfs" ]; then
257                 COMMIT_BTRFS_PARTITION "${LABEL}"
258         else
259                 ERROR "ERROR: Cannot commit ${LABEL}: Unsupported filesystem ${TYPE}"
260         fi
261         return $?
262 }
263
264 COMMIT_CHANGES()
265 {
266         if ! COMMIT_PARTITION system-data; then
267                 return 1
268         fi
269         if ! COMMIT_PARTITION user; then
270                 return 1
271         fi
272
273         return 0
274 }