backup.script 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. #!/bin/bash
  2. sd_multi="no"
  3. card_no="0"
  4. multiboot_label="sd"
  5. #--------------------------------------------------
  6. disp_header() {
  7. clear
  8. printf "\n\033[36m\033[1m\n"
  9. printf " =================================\n"
  10. printf " = JEEDOM Backup utility %s =\n" "${SCRIPT_VERSION}"
  11. printf " =================================\n"
  12. printf "\033[22m\033[37m\n\n"
  13. sleep 1
  14. }
  15. #--------------------------------------------------
  16. #------------------------------------------------------------------------------------------------------------
  17. # arg1: full path to image file
  18. # arg2: description
  19. # arg3: backup type, 'andro' or 'linux'
  20. # source partition is mounted on /mnt1
  21. make_image() {
  22. mkdir /imgmnt >> ${log_file} 2>&1
  23. printf " Backup: \033[32m%s\033[37m ... preparing image... " "${2}"
  24. # Get size
  25. _size_=$(du -s /mnt1 | awk '{print $1}')
  26. _size=$(( ($_size_ / 1024) + 128 ))
  27. # add 5% ext4 fs overhead
  28. _ovhd=$(( ($_size * 6) / 100 ))
  29. _size=$(( $_size + $_ovhd ))
  30. rm -f ${1} >> ${log_file} 2>&1
  31. printf " (%sM)... " "${_size}"
  32. # create sparse image file
  33. dd if=/dev/zero of=${1} bs=1 count=0 seek=${_size}M >> ${log_file} 2>&1
  34. #dd if=/dev/zero of=${1} bs=1M count=${_size} >> ${log_file} 2>&1
  35. if [ $? -ne 0 ]; then
  36. printf "ERROR\n"
  37. return 1
  38. fi
  39. sync
  40. printf "mkfs... "
  41. mkfs.ext4 ${1} >> ${log_file} 2>&1
  42. if [ $? -ne 0 ]; then
  43. printf "ERROR\n"
  44. return 1
  45. fi
  46. sync
  47. printf "mount... "
  48. mountx ${1} /imgmnt >> ${log_file} 2>&1
  49. if [ $? -ne 0 ]; then
  50. printf "ERROR\n"
  51. return 1
  52. fi
  53. # Copy partition to image
  54. printf "copy... "
  55. if [ "${3}" = "andro" ]; then
  56. rsync -r -t -p -o -g -x -l -H -D --numeric-ids -s -A -X --no-specials /mnt1/ /imgmnt/ >> ${log_file} 2>&1
  57. else
  58. rsync -r -t -p -o -g -x -l -H -D --numeric-ids -s --stats /mnt1/ /imgmnt/ >> ${log_file} 2>&1
  59. fi
  60. if [ $? -ne 0 ]; then
  61. umount /imgmnt >> ${log_file} 2>&1
  62. printf "ERROR\n"
  63. return 1
  64. fi
  65. sync
  66. umount /imgmnt >> ${log_file} 2>&1
  67. printf "OK\n"
  68. return 0
  69. }
  70. #------------------------------------------------------------------------------------------------------------
  71. #----------------------------------------------------------------------------------------------------------------
  72. backup_linux() {
  73. printf "\n Backup: \033[32m\033[1mJEEDOM%s\033[22m\033[37m\n" "${1}"
  74. # backup Linux partition, already mounted on /mnt1
  75. mkdir /mnt2/${BKP_PREFIX}_backup >> ${log_file} 2>&1
  76. mkdir /mnt2/${BKP_PREFIX}_backup/linux${1} >> ${log_file} 2>&1
  77. rm -rf /mnt2/${BKP_PREFIX}_backup/linux${1}/* >> ${log_file} 2>&1
  78. make_image "/mnt2/${BKP_PREFIX}_backup/linux${1}/jeedom.img" "Linux root" "linux"
  79. if [ $? -ne 0 ]; then
  80. umount /mnt1 >> ${log_file} 2>&1
  81. return 1
  82. fi
  83. umount /mnt1 >> ${log_file} 2>&1
  84. if [ $? -ne 0 ]; then
  85. printf "ERROR unmounting Jeedom partition\n"
  86. return 1
  87. fi
  88. # Mount boot card and copy Linux boot files
  89. printf " Backup: \033[32mCopy boot files\033[37m ... "
  90. mount -t vfat /dev/mmcblk${card_no}p1 /mnt1 >> ${log_file} 2>&1
  91. if [ $? -ne 0 ]; then
  92. printf "ERROR mounting boot partition\n"
  93. return 1
  94. fi
  95. if [ ! "${sd_multi}" = "yes" ]; then
  96. cp /mnt1/multiboot/${ODROID_IMAGE}.linux /mnt2/${BKP_PREFIX}_backup/linux${1}/${ODROID_IMAGE} >> ${log_file} 2>&1
  97. if [ $? -ne 0 ]; then
  98. printf "ERROR: Image\n"
  99. return 1
  100. fi
  101. cp /mnt1/multiboot/${ODROID_DTB}.linux /mnt2/${BKP_PREFIX}_backup/linux${1}/${ODROID_DTB} >> ${log_file} 2>&1
  102. if [ $? -ne 0 ]; then
  103. printf "ERROR: dtb\n"
  104. return 1
  105. fi
  106. cp /mnt1/multiboot/uInitrd.linux /mnt2/${BKP_PREFIX}_backup/linux${1}/uInitrd >> ${log_file} 2>&1
  107. if [ $? -ne 0 ]; then
  108. printf "ERROR: uInitrd\n"
  109. return 1
  110. fi
  111. else
  112. cp /mnt1/${ODROID_IMAGE} /mnt2/${BKP_PREFIX}_backup/linux${1} >> ${log_file} 2>&1
  113. if [ $? -ne 0 ]; then
  114. printf "ERROR: Image "
  115. fi
  116. cp /mnt1/${ODROID_DTB} /mnt2/${BKP_PREFIX}_backup/linux${1} >> ${log_file} 2>&1
  117. if [ $? -ne 0 ]; then
  118. printf "ERROR: dtb "
  119. fi
  120. cp /mnt1/uInitrd /mnt2/${BKP_PREFIX}_backup/linux${1} >> ${log_file} 2>&1
  121. if [ $? -ne 0 ]; then
  122. printf "ERROR: uInitrd "
  123. fi
  124. fi
  125. sync
  126. sleep 1
  127. umount /mnt1 >> ${log_file} 2>&1
  128. printf "OK\n"
  129. return 0
  130. }
  131. #----------------------------------------------------------------------------------------------------
  132. exit_script() {
  133. local _delay=30
  134. local B="X"
  135. echo ""
  136. while [ $_delay -gt 0 ]; do
  137. printf " \033[33mPress \033[1mE\033[22m to exit to main menu (%s) \033[37m\r" "${_delay}"
  138. if read -n 1 -t 1 -s B; then
  139. _delay=30
  140. if [ "${B}" = "E" ] || [ "${B}" = "e" ]; then
  141. break
  142. elif [ "${B}" = "s" ]; then
  143. # SCREENSHOT ===
  144. fbcat > /backup_exit.ppm
  145. fi
  146. else
  147. let _delay=_delay-1
  148. fi
  149. done
  150. printf "\r\033[2K"
  151. umount /mnt1 > /dev/null 2>&1
  152. umount /mnt2 > /dev/null 2>&1
  153. exit 0
  154. }
  155. #----------------------------------------------------------------------------------------------------
  156. #=====================================================================================
  157. mkdir /mnt1 > /dev/null 2>&1
  158. mkdir /mnt2 > /dev/null 2>&1
  159. mkdir /multiboot > /dev/null 2>&1
  160. umount /mnt1 > /dev/null 2>&1
  161. umount /mnt2 > /dev/null 2>&1
  162. disp_header
  163. # ===============
  164. # Check USB drive
  165. # ===============
  166. if [ ! -b /dev/sda ]; then
  167. printf " ERROR: USB drive not found\n"
  168. exit_script
  169. fi
  170. usb_part="0"
  171. max_usbpart=0
  172. #------------------------------------------------------------------------------------
  173. check_usbpart() {
  174. local usbpart_free=0
  175. if [ -b /dev/sda${1} ]; then
  176. let max_usbpart=max_usbpart+1
  177. printf " \033[32m\033[1m%s\033[22m partition #%s \033[37m (" "${1}" "${1}"
  178. /bin/mountx /dev/sda${1} /mnt2 > /dev/null 2>&1
  179. if [ $? -ne 0 ]; then
  180. printf "NOT MOUNTABLE)\n"
  181. else
  182. [ "${usb_part}" = "0" ] && usb_part="1"
  183. usbpart_free=$(df | grep /dev/sda${1} | awk '{print $4}')
  184. usbpart_free=$(( $usbpart_free / 1024 ))
  185. printf "%sM free)\n" "${usbpart_free}"
  186. fi
  187. umount /mnt2 > /dev/null 2>&1
  188. fi
  189. }
  190. #------------------------------------------------------------------------------------
  191. printf " \033[33mMore than one partition on USB drive detected, select which one to use for backup\033[37m\n\n"
  192. check_usbpart "1"
  193. check_usbpart "2"
  194. check_usbpart "3"
  195. check_usbpart "4"
  196. check_usbpart "5"
  197. check_usbpart "6"
  198. printf "\n"
  199. if [ $max_usbpart -eq 0 ] || [ "${usb_part}" = "0" ]; then
  200. printf " ERROR: no usable USB partition found!\n"
  201. exit_script
  202. fi
  203. _delay=30
  204. usb_part="1"
  205. while [ $_delay -gt 0 ]; do
  206. printf " \033[33mSelect the backup partition, default is \033[1m#1\033[22m %s\033[37m \r" "${_delay}"
  207. B="X"
  208. if read -n 1 -t 1 -s B; then
  209. _delay=30
  210. if [ "${B}" = "1" ] && [ $max_usbpart -ge 1 ]; then
  211. usb_part="1"
  212. break
  213. elif [ "${B}" = "2" ] && [ $max_usbpart -ge 2 ]; then
  214. usb_part="2"
  215. break
  216. elif [ "${B}" = "3" ] && [ $max_usbpart -ge 3 ]; then
  217. usb_part="3"
  218. break
  219. elif [ "${B}" = "4" ] && [ $max_usbpart -ge 4 ]; then
  220. usb_part="4"
  221. break
  222. elif [ "${B}" = "5" ] && [ $max_usbpart -ge 5 ]; then
  223. usb_part="5"
  224. break
  225. elif [ "${B}" = "6" ] && [ $max_usbpart -ge 6 ]; then
  226. usb_part="6"
  227. break
  228. fi
  229. else
  230. let _delay=_delay-1
  231. fi
  232. done
  233. disp_header
  234. # Mount backup partition
  235. /bin/mountx /dev/sda${usb_part} /mnt2 > /dev/null 2>&1
  236. if [ $? -ne 0 ]; then
  237. printf " ERROR mounting USB partition #%s\n" "${usb_part}"
  238. exit_script
  239. fi
  240. #==========================================================================================
  241. rm /mnt2/backup.log > /dev/null 2>&1
  242. log_file="/mnt2/backup.log"
  243. #log_file="ls/dev/null"
  244. # Check source drive
  245. if [ "${NUMCARDS}" = "2" ]; then
  246. printf " \033[33mTwo cards detected, select which one to use for backup\033[37m\n\n"
  247. printf " \033[32m\033[1m0\033[22m Boot card (%s)\033[37m\n" "${BOOT_CARDTYPE}"
  248. printf " \033[32m\033[1m1\033[22m Other card (%s)\033[37m\n\n" "${OTHER_CARDTYPE}"
  249. _delay=30
  250. while [ $_delay -gt 0 ]; do
  251. printf " \033[33mSelect the card, default is \033[1mEMMC\033[22m %s\033[37m \r" "${_delay}"
  252. B="X"
  253. if read -n 1 -t 1 -s B; then
  254. _delay=30
  255. if [ "${B}" = "0" ]; then
  256. card_no="${BOOT_CARDDEV}"
  257. card_type="${BOOT_CARDTYPE}"
  258. break
  259. elif [ "${B}" = "1" ]; then
  260. card_no="${OTHER_CARDDEV}"
  261. card_type="${OTHER_CARDTYPE}"
  262. break
  263. fi
  264. else
  265. let _delay=_delay-1
  266. fi
  267. done
  268. disp_header
  269. fi
  270. # === Display backup info ===
  271. printf " \033[32mBackup from "
  272. if [ "${card_type}" = "SD" ]; then
  273. multiboot_label="sd"
  274. else
  275. multiboot_label="em"
  276. fi
  277. # === Check if the backup is from multiboot card ===
  278. # shellcheck disable=SC2010
  279. tmp_crdtype=`ls -l /dev/disk/by-label | grep mmcblk${card_no}p1 | awk '{print $4}'`
  280. if [ "${tmp_crdtype}" = "${multiboot_label}userdata" ]; then
  281. sd_multi="yes"
  282. printf "\033[1mMultiBoot\033[22m %s card " "${card_type}"
  283. else
  284. printf "\033[1mOriginal Odroid\033[22m %s card " "${card_type}"
  285. fi
  286. printf " to \033[1mUSB partition #%s\033[22m\033[37m\n\n" "${usb_part}"
  287. # === Mount partition 2 (Android system or Linux) ===
  288. /bin/mountx /dev/mmcblk${card_no}p7 /mnt1 >> ${log_file} 2>&1
  289. if [ $? -ne 0 ]; then
  290. umount /mnt2 > /dev/null 2>&1
  291. printf " ERROR mounting source card, nothing to backup\n"
  292. exit_script
  293. fi
  294. # === Wait for backup confirmation ===
  295. _delay=30
  296. while [ $_delay -gt 0 ]; do
  297. printf " \033[33mReady for backup, press \033[1mY\033[22m to continue, \033[1mE\033[22m to exit (%s) \033[37m\r" "${_delay}"
  298. B="X"
  299. if read -n 1 -t 1 -s B; then
  300. _delay=30
  301. if [ "${B}" = "Y" ]; then
  302. printf "\r\033[2K"
  303. break
  304. elif [ "${B}" = "E" ] || [ "${B}" = "e" ]; then
  305. _delay=0
  306. break
  307. elif [ "${B}" = "s" ]; then
  308. # SCREENSHOT ===
  309. fbcat > /backup.ppm
  310. fi
  311. else
  312. let _delay=_delay-1
  313. fi
  314. done
  315. if [ $_delay -eq 0 ]; then
  316. printf "\r\033[2K"
  317. umount /mnt2 > /dev/null 2>&1
  318. exit_script
  319. fi
  320. if [ ! "${sd_multi}" = "yes" ]; then
  321. # backup single linux card
  322. if [ -f /mnt1/etc/fstab ]; then
  323. backup_linux ""
  324. fi
  325. fi
  326. umount /mnt1 >> ${log_file} 2>&1
  327. # === For multiboot card backup, continue to backup other operating systems ===
  328. if [ "${sd_multi}" = "yes" ]; then
  329. if [ -b /dev/disk/by-label/${multiboot_label}linux ]; then
  330. printf "\n"
  331. # === Backup multiboot Linux ===
  332. /bin/mountx /dev/disk/by-label/${multiboot_label}linux /mnt1 >> ${log_file} 2>&1
  333. if [ $? -ne 0 ]; then
  334. printf " ERROR mounting Jeedom partition\n"
  335. exit_script
  336. fi
  337. if [ -f /mnt1/etc/fstab ]; then
  338. backup_linux ""
  339. fi
  340. fi
  341. umount /mnt1 >> ${log_file} 2>&1
  342. fi
  343. if [ -d /mnt2/C2_backup/linux ]; then
  344. if [ -f /mnt2/C2_backup/linux/jeedom.img ]; then
  345. cd /mnt2
  346. tar -zcvf backupJeedom.tar.gz C2_backup
  347. cd /
  348. fi
  349. fi
  350. umount /mnt1 >> ${log_file} 2>&1
  351. umount /mnt2 > /dev/null 2>&1
  352. printf "\n FINISHED.\n"
  353. exit_script
  354. #=====================================================================================