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