]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - INSTALL/tool/VentoyWorker.sh
keep up with 1.0.67 (#1464)
[Ventoy.git] / INSTALL / tool / VentoyWorker.sh
1 #!/bin/sh
2
3 . ./tool/ventoy_lib.sh
4
5 print_usage() {
6
7 echo 'Usage: Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX'
8 echo ' CMD:'
9 echo ' -i install Ventoy to sdX (fails if disk already installed with Ventoy)'
10 echo ' -I force install Ventoy to sdX (no matter installed or not)'
11 echo ' -u update Ventoy in sdX'
12 echo ' -l list Ventoy information in sdX'
13 echo ''
14 echo ' OPTION: (optional)'
15 echo ' -r SIZE_MB preserve some space at the bottom of the disk (only for install)'
16 echo ' -s/-S enable/disable secure boot support (default is disabled)'
17 echo ' -g use GPT partition style, default is MBR (only for install)'
18 echo ' -L Label of the 1st exfat partition (default is Ventoy)'
19 echo ' -n try non-destructive installation (only for install)'
20 echo ''
21 }
22
23
24 VTNEW_LABEL='Ventoy'
25 RESERVE_SIZE_MB=0
26 while [ -n "$1" ]; do
27 if [ "$1" = "-i" ]; then
28 MODE="install"
29 elif [ "$1" = "-I" ]; then
30 MODE="install"
31 FORCE="Y"
32 elif [ "$1" = "-n" ]; then
33 NONDESTRUCTIVE="Y"
34 elif [ "$1" = "-u" ]; then
35 MODE="update"
36 elif [ "$1" = "-l" ]; then
37 MODE="list"
38 elif [ "$1" = "-s" ]; then
39 SECUREBOOT="YES"
40 elif [ "$1" = "-S" ]; then
41 SECUREBOOT="NO"
42 elif [ "$1" = "-g" ]; then
43 VTGPT="YES"
44 elif [ "$1" = "-L" ]; then
45 shift
46 VTNEW_LABEL=$1
47 elif [ "$1" = "-r" ]; then
48 RESERVE_SPACE="YES"
49 shift
50 RESERVE_SIZE_MB=$1
51 elif [ "$1" = "-V" ] || [ "$1" = "--version" ]; then
52 exit 0
53 elif [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
54 print_usage
55 exit 0
56 else
57 if ! [ -b "$1" ]; then
58 vterr "$1 is NOT a valid device"
59 print_usage
60 exit 1
61 fi
62 DISK=$1
63 # Resolve symlinks now, will be needed to look up information about the device in
64 # the /sys/ filesystem, for example /sys/class/block/${DISK#/dev/}/start
65 # The main use case is supporting /dev/disk/by-id/ symlinks instead of raw devices
66 if [ -L "$DISK" ]; then
67 DISK=$(readlink -e -n "$DISK")
68 fi
69 fi
70
71 shift
72 done
73
74 if [ -z "$MODE" ]; then
75 print_usage
76 exit 1
77 fi
78
79 if ! [ -b "$DISK" ]; then
80 vterr "Disk $DISK does not exist"
81 exit 1
82 fi
83
84 if [ -e /sys/class/block/${DISK#/dev/}/start ]; then
85 vterr "$DISK is a partition, please use the whole disk."
86 echo "For example:"
87 vterr " sudo sh Ventoy2Disk.sh -i /dev/sdb1 <=== This is wrong"
88 vtinfo " sudo sh Ventoy2Disk.sh -i /dev/sdb <=== This is right"
89 echo ""
90 exit 1
91 fi
92
93 if [ -n "$RESERVE_SPACE" -a "$MODE" = "install" ]; then
94 if echo $RESERVE_SIZE_MB | grep -q '^[0-9][0-9]*$'; then
95 vtdebug "User will reserve $RESERVE_SIZE_MB MB disk space"
96 else
97 vterr "$RESERVE_SIZE_MB is invalid for reserved space"
98 exit 1
99 fi
100 fi
101
102 vtdebug "MODE=$MODE FORCE=$FORCE RESERVE_SPACE=$RESERVE_SPACE RESERVE_SIZE_MB=$RESERVE_SIZE_MB"
103
104 #check tools
105 if check_tool_work_ok; then
106 vtdebug "check tool work ok"
107 else
108 vterr "Some tools can not run on current system. Please check log.txt for details."
109 exit 1
110 fi
111
112 if [ "$MODE" = "list" ]; then
113 version=$(get_disk_ventoy_version $DISK)
114 if [ $? -eq 0 ]; then
115 echo "Ventoy Version in Disk: $version"
116
117 vtPart1Type=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"')
118 if [ "$vtPart1Type" = "EE" ]; then
119 echo "Disk Partition Style : GPT"
120 else
121 echo "Disk Partition Style : MBR"
122 fi
123
124 if check_disk_secure_boot $DISK; then
125 echo "Secure Boot Support : YES"
126 else
127 echo "Secure Boot Support : NO"
128 fi
129 else
130 echo "Ventoy Version: NA"
131 fi
132 echo ""
133 exit 0
134 fi
135
136 #check mountpoint
137 check_umount_disk "$DISK"
138
139 if grep "$DISK" /proc/mounts; then
140 vterr "$DISK is already mounted, please umount it first!"
141 exit 1
142 fi
143
144 #check swap partition
145 if swapon --help 2>&1 | grep -q '^ \-s,'; then
146 if swapon -s | grep -q "^${DISK}[0-9]"; then
147 vterr "$DISK is used as swap, please swapoff it first!"
148 exit 1
149 fi
150 fi
151
152 #check access
153 if dd if="$DISK" of=/dev/null bs=1 count=1 >/dev/null 2>&1; then
154 vtdebug "root permission check ok ..."
155 else
156 vterr "Failed to access $DISK, maybe root privilege is needed!"
157 echo ''
158 exit 1
159 fi
160
161
162 #check tmp_mnt directory
163 if [ -d ./tmp_mnt ]; then
164 vtdebug "There is a tmp_mnt directory, now delete it."
165 umount ./tmp_mnt >/dev/null 2>&1
166 rm -rf ./tmp_mnt
167 if [ -d ./tmp_mnt ]; then
168 vterr "tmp_mnt directory exits, please delete it first."
169 exit 1
170 fi
171 fi
172
173
174 if [ "$MODE" = "install" -a -z "$NONDESTRUCTIVE" ]; then
175 vtdebug "install Ventoy ..."
176
177 if [ -n "$VTGPT" ]; then
178 if parted -v > /dev/null 2>&1; then
179 PARTTOOL='parted'
180 else
181 vterr "parted is not found in the system, Ventoy can't create new partitions without it."
182 vterr "You should install \"GNU parted\" first."
183 exit 1
184 fi
185 else
186 if parted -v > /dev/null 2>&1; then
187 PARTTOOL='parted'
188 elif fdisk -v >/dev/null 2>&1; then
189 PARTTOOL='fdisk'
190 else
191 vterr "Both parted and fdisk are not found in the system, Ventoy can't create new partitions."
192 exit 1
193 fi
194 fi
195
196 version=$(get_disk_ventoy_version $DISK)
197 if [ $? -eq 0 ]; then
198 if [ -z "$FORCE" ]; then
199 vtwarn "$DISK already contains a Ventoy with version $version"
200 vtwarn "Use -u option to do a safe upgrade operation."
201 vtwarn "OR if you really want to reinstall Ventoy to $DISK, please use -I option."
202 vtwarn ""
203 exit 1
204 fi
205 fi
206
207 disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size)
208 disk_size_gb=$(expr $disk_sector_num / 2097152)
209
210 if [ $disk_sector_num -gt 4294967296 ] && [ -z "$VTGPT" ]; then
211 vterr "$DISK is over 2TB size, MBR will not work on it."
212 exit 1
213 fi
214
215 if [ -n "$RESERVE_SPACE" ]; then
216 sum_size_mb=$(expr $RESERVE_SIZE_MB + $VENTOY_PART_SIZE_MB)
217 reserve_sector_num=$(expr $sum_size_mb \* 2048)
218
219 if [ $disk_sector_num -le $reserve_sector_num ]; then
220 vterr "Can't reserve $RESERVE_SIZE_MB MB space from $DISK"
221 exit 1
222 fi
223 fi
224
225 #Print disk info
226 echo "Disk : $DISK"
227 parted -s $DISK p 2>&1 | grep Model
228 echo "Size : $disk_size_gb GB"
229 if [ -n "$VTGPT" ]; then
230 echo "Style: GPT"
231 else
232 echo "Style: MBR"
233 fi
234 echo ''
235
236 if [ -n "$RESERVE_SPACE" ]; then
237 echo "You will reserve $RESERVE_SIZE_MB MB disk space "
238 fi
239 echo ''
240
241 vtwarn "Attention:"
242 vtwarn "You will install Ventoy to $DISK."
243 vtwarn "All the data on the disk $DISK will be lost!!!"
244 echo ""
245
246 read -p 'Continue? (y/n) ' Answer
247 if [ "$Answer" != "y" ]; then
248 if [ "$Answer" != "Y" ]; then
249 exit 0
250 fi
251 fi
252
253 echo ""
254 vtwarn "All the data on the disk $DISK will be lost!!!"
255 read -p 'Double-check. Continue? (y/n) ' Answer
256 if [ "$Answer" != "y" ]; then
257 if [ "$Answer" != "Y" ]; then
258 exit 0
259 fi
260 fi
261
262 if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then
263 vterr "No enough space in disk $DISK"
264 exit 1
265 fi
266
267 # check and umount
268 check_umount_disk "$DISK"
269
270 if ! dd if=/dev/zero of=$DISK bs=64 count=512 status=none conv=fsync; then
271 vterr "Write data to $DISK failed, please check whether it's in use."
272 exit 1
273 fi
274
275 if [ -n "$VTGPT" ]; then
276 vtdebug "format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL ..."
277 format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL
278 else
279 vtdebug "format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL ..."
280 format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL
281 fi
282
283 # format part1
284
285 # DiskSize > 32GB Cluster Size use 128KB
286 # DiskSize < 32GB Cluster Size use 32KB
287 if [ $disk_size_gb -gt 32 ]; then
288 cluster_sectors=256
289 else
290 cluster_sectors=64
291 fi
292
293 PART1=$(get_disk_part_name $DISK 1)
294 PART2=$(get_disk_part_name $DISK 2)
295
296 #clean part2
297 dd status=none conv=fsync if=/dev/zero of=$DISK bs=512 count=32 seek=$part2_start_sector
298
299 #format part1
300 wait_and_create_part ${PART1} ${PART2}
301 if [ -b ${PART1} ]; then
302 vtinfo "Format partition 1 ${PART1} ..."
303 mkexfatfs -n "$VTNEW_LABEL" -s $cluster_sectors ${PART1}
304 if [ $? -ne 0 ]; then
305 echo "mkexfatfs failed, now retry..."
306 mkexfatfs -n "$VTNEW_LABEL" -s $cluster_sectors ${PART1}
307 if [ $? -ne 0 ]; then
308 echo "######### mkexfatfs failed, exit ########"
309 exit 1
310 fi
311 else
312 echo "mkexfatfs success"
313 fi
314 else
315 vterr "${PART1} NOT exist"
316 fi
317
318 vtinfo "writing data to disk ..."
319 dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=446
320
321 if [ -n "$VTGPT" ]; then
322 echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92
323 xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34
324 echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none
325 else
326 xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
327 fi
328
329 # check and umount
330 check_umount_disk "$DISK"
331
332 xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector
333
334 #test UUID
335 testUUIDStr=$(vtoy_gen_uuid | hexdump -C)
336 vtdebug "test uuid: $testUUIDStr"
337
338 #disk uuid
339 vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16
340
341 #disk signature
342 vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} skip=12 seek=440 bs=1 count=4
343
344 vtinfo "sync data ..."
345 sync
346
347 vtinfo "esp partition processing ..."
348 if [ "$SECUREBOOT" != "YES" ]; then
349 sleep 2
350 check_umount_disk "$DISK"
351 vtoycli partresize -s $DISK $part2_start_sector
352 fi
353
354 echo ""
355 vtinfo "Install Ventoy to $DISK successfully finished."
356 echo ""
357
358 elif [ "$MODE" = "install" -a -n "$NONDESTRUCTIVE" ]; then
359 vtdebug "non-destructive install Ventoy ..."
360
361 version=$(get_disk_ventoy_version $DISK)
362 if [ $? -eq 0 ]; then
363 if [ -z "$FORCE" ]; then
364 vtwarn "$DISK already contains a Ventoy with version $version."
365 vtwarn "You can not do and don not need non-destructive installation."
366 vtwarn ""
367 exit 1
368 fi
369 fi
370
371 disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size)
372 disk_size_gb=$(expr $disk_sector_num / 2097152)
373
374 if vtoycli partresize -t $DISK; then
375 OldStyle="GPT"
376 else
377 OldStyle="MBR"
378 fi
379
380 #Print disk info
381 echo "Disk : $DISK"
382 parted -s $DISK p 2>&1 | grep Model
383 echo "Size : $disk_size_gb GB"
384 echo "Style: $OldStyle"
385 echo ''
386
387 vtwarn "Attention:"
388 vtwarn "Ventoy will try non-destructive installation on $DISK if possible."
389 echo ""
390
391 read -p 'Continue? (y/n) ' Answer
392 if [ "$Answer" != "y" ]; then
393 if [ "$Answer" != "Y" ]; then
394 exit 0
395 fi
396 fi
397
398 if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then
399 vterr "No enough space in disk $DISK"
400 exit 1
401 fi
402
403 PART1=$(get_disk_part_name $DISK 1)
404 PART2=$(get_disk_part_name $DISK 2)
405
406 #Part1 size in MB aligned with 4KB
407 PART1_SECTORS=$(cat /sys/class/block/${PART1#/dev/}/size)
408 PART1_4K=$(expr $PART1_SECTORS / 8)
409 PART1_MB=$(expr $PART1_4K / 256)
410 PART1_NEW_MB=$(expr $PART1_MB - 32)
411
412 echo "$PART1 is ${PART1_MB}MB"
413
414 #check partition layout
415 echo "check partition layout ..."
416 vtoycli partresize -c $DISK
417 vtRet=$?
418 if [ $vtRet -eq 0 ]; then
419 exit 1
420 else
421 # check and umount
422 check_umount_disk "$DISK"
423 sleep 1
424 check_umount_disk "$DISK"
425
426 if [ $vtRet -eq 1 ]; then
427 echo "Free space enough, start install..."
428 part2_start_sector=$(expr $PART1_SECTORS + 2048)
429 elif [ $vtRet -eq 2 ]; then
430 echo "We need to shrink partition 1 firstly ..."
431
432 PART1_BLKID=$(blkid $PART1)
433 blkid $PART1
434
435 if echo $PART1_BLKID | egrep -q -i 'TYPE=ntfs|TYPE=.ntfs'; then
436 echo "Partition 1 contains NTFS filesystem"
437
438 which ntfsresize
439 if [ $? -ne 0 ]; then
440 echo "###[FAIL] ntfsresize not found. Please install ntfs-3g package."
441 exit 1
442 fi
443
444 echo "ntfsfix -b -d $PART1 ..."
445 ntfsfix -b -d $PART1
446
447 echo "ntfsresize --size ${PART1_NEW_MB}Mi $PART1 ..."
448 ntfsresize -f --size ${PART1_NEW_MB}Mi $PART1
449 if [ $? -ne 0 ]; then
450 echo "###[FAIL] ntfsresize failed."
451 exit 1
452 fi
453 elif echo $PART1_BLKID | egrep -q -i 'TYPE=ext[2-4]|TYPE=.ext[2-4]'; then
454 echo "Partition 1 contains EXT filesystem"
455
456 which resize2fs
457 if [ $? -ne 0 ]; then
458 echo "###[FAIL] resize2fs not found. Please install e2fsprogs package."
459 exit 1
460 fi
461
462 echo "e2fsck -f $PART1 ..."
463 e2fsck -f $PART1
464
465 echo "resize2fs $PART1 ${PART1_NEW_MB}M ..."
466 resize2fs $PART1 ${PART1_NEW_MB}M
467 if [ $? -ne 0 ]; then
468 echo "###[FAIL] resize2fs failed."
469 exit 1
470 fi
471 else
472 echo "###[FAIL] Unsupported filesystem in partition 1."
473 exit 1
474 fi
475
476 sync
477 PART1_NEW_END_MB=$(expr $PART1_NEW_MB + 1)
478 part2_start_sector=$(expr $PART1_NEW_END_MB \* 2048)
479 fi
480 fi
481
482 vtinfo "writing data to disk part2_start=$part2_start_sector ..."
483
484 dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440
485
486 if [ "$OldStyle" = "GPT" ]; then
487 echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92
488 xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34
489 echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none
490 else
491 xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
492 fi
493
494 xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector
495
496 #test UUID
497 testUUIDStr=$(vtoy_gen_uuid | hexdump -C)
498 vtdebug "test uuid: $testUUIDStr"
499
500 #disk uuid
501 vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16
502
503 vtinfo "sync data ..."
504 sync
505
506 vtinfo "esp partition processing ..."
507 if [ "$SECUREBOOT" != "YES" ]; then
508 vtoycli partresize -s $DISK $part2_start_sector
509 fi
510
511 vtinfo "update partition table $DISK $part2_start_sector ..."
512 vtoycli partresize -p $DISK $part2_start_sector
513 if [ $? -eq 0 ]; then
514 sync
515 echo ""
516 vtinfo "Ventoy non-destructive installation on $DISK successfully finished."
517 echo ""
518 else
519 echo ""
520 vterr "Ventoy non-destructive installation on $DISK failed."
521 echo ""
522 fi
523
524 else
525 vtdebug "update Ventoy ..."
526
527 oldver=$(get_disk_ventoy_version $DISK)
528 if [ $? -ne 0 ]; then
529 if is_disk_contains_ventoy $DISK; then
530 oldver="Unknown"
531 else
532 vtwarn "$DISK does not contain Ventoy or data corrupted"
533 echo ""
534 vtwarn "Please use -i option if you want to install ventoy to $DISK"
535 echo ""
536 exit 1
537 fi
538 fi
539
540 #reserve secure boot option
541 if [ -z "$SECUREBOOT" ]; then
542 if check_disk_secure_boot $DISK; then
543 SECUREBOOT="YES"
544 else
545 SECUREBOOT="NO"
546 fi
547 fi
548
549 curver=$(cat ./ventoy/version)
550
551 vtinfo "Upgrade operation is safe, all the data in the 1st partition (iso files and other) will be unchanged!"
552 echo ""
553
554 read -p "Update Ventoy $oldver ===> $curver Continue? (y/n)" Answer
555 if [ "$Answer" != "y" ]; then
556 if [ "$Answer" != "Y" ]; then
557 exit 0
558 fi
559 fi
560
561 PART2=$(get_disk_part_name $DISK 2)
562 SHORT_PART2=${PART2#/dev/}
563 part2_start=$(cat /sys/class/block/$SHORT_PART2/start)
564
565 PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"')
566
567 #reserve disk uuid
568 rm -f ./diskuuid.bin
569 dd status=none conv=fsync if=${DISK} skip=384 bs=1 count=16 of=./diskuuid.bin
570
571 dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440
572 dd status=none conv=fsync if=./diskuuid.bin of=$DISK bs=1 count=16 seek=384
573 rm -f ./diskuuid.bin
574
575 #reserve data
576 rm -f ./rsvdata.bin
577 dd status=none conv=fsync if=${DISK} skip=2040 bs=512 count=8 of=./rsvdata.bin
578
579 if [ "$PART1_TYPE" = "EE" ]; then
580 vtdebug "This is GPT partition style ..."
581 echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92
582 xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34
583 echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none
584 else
585 vtdebug "This is MBR partition style ..."
586
587 PART1_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=446 status=none | hexdump -n1 -e '1/1 "%02X"')
588 PART2_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=462 status=none | hexdump -n1 -e '1/1 "%02X"')
589
590 vtdebug "PART1_ACTIVE=$PART1_ACTIVE PART2_ACTIVE=$PART2_ACTIVE"
591 if [ "$PART1_ACTIVE" = "00" ] && [ "$PART2_ACTIVE" = "80" ]; then
592 vtdebug "change 1st partition active, 2nd partition inactive ..."
593 echo -en '\x80' | dd of=$DISK conv=fsync bs=1 count=1 seek=446 status=none
594 echo -en '\x00' | dd of=$DISK conv=fsync bs=1 count=1 seek=462 status=none
595 fi
596 xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
597 fi
598
599 dd status=none conv=fsync if=./rsvdata.bin seek=2040 bs=512 count=8 of=${DISK}
600 rm -f ./rsvdata.bin
601
602 check_umount_disk "$DISK"
603
604 xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start
605 sync
606
607 vtinfo "esp partition processing ..."
608 if [ "$SECUREBOOT" != "YES" ]; then
609 sleep 2
610 check_umount_disk "$DISK"
611 vtoycli partresize -s $DISK $part2_start
612 fi
613
614 echo ""
615 vtinfo "Update Ventoy on $DISK successfully finished."
616 echo ""
617
618 fi
619
620