|
15 | 15 | package fsutils |
16 | 16 |
|
17 | 17 | import ( |
| 18 | + "bufio" |
| 19 | + "bytes" |
18 | 20 | "fmt" |
| 21 | + "os" |
19 | 22 | "regexp" |
20 | 23 | "strconv" |
21 | 24 | "strings" |
@@ -547,6 +550,63 @@ func DetectIsUEFISupport(rootfs fsdriver.IRootFsDriver, partitions []fsdriver.ID |
547 | 550 | return false |
548 | 551 | } |
549 | 552 |
|
| 553 | +func DetectIsBIOSSupport(partDev string, rootfs fsdriver.IRootFsDriver) bool { |
| 554 | + fi, err := os.OpenFile(partDev, os.O_RDONLY, 0444) |
| 555 | + if err != nil { |
| 556 | + log.Errorf("failed open partdev %s: %s", partDev, err) |
| 557 | + return false |
| 558 | + } |
| 559 | + defer fi.Close() |
| 560 | + |
| 561 | + // read first sector |
| 562 | + sector := make([]byte, 512) |
| 563 | + n, err := fi.Read(sector) |
| 564 | + if err != nil || n != 512 { |
| 565 | + log.Errorf("failed read first sector %d %s: %s", n, partDev, err) |
| 566 | + return false |
| 567 | + } |
| 568 | + |
| 569 | + bootSignature := sector[510:512] |
| 570 | + expectedSignature := []byte{0x55, 0xAA} |
| 571 | + log.Infof("Detect is bios support bootSignature: %x", bootSignature) |
| 572 | + if bootSignature[0] != expectedSignature[0] || bootSignature[1] != expectedSignature[1] { |
| 573 | + return false |
| 574 | + } |
| 575 | + partitionType := rootfs.GetPartition().GetPhysicalPartitionType() |
| 576 | + if partitionType == "mbr" { |
| 577 | + return true |
| 578 | + } else if partitionType == "gpt" { |
| 579 | + /* |
| 580 | + Number Start (sector) End (sector) Size Code Name |
| 581 | + 1 227328 83886046 39.9 GiB 8300 |
| 582 | + 14 2048 10239 4.0 MiB EF02 |
| 583 | + 15 10240 227327 106.0 MiB EF00 |
| 584 | +
|
| 585 | + # EF02 is BIOS Boot partition |
| 586 | + */ |
| 587 | + out, err := procutils.NewCommand("sgdisk", "-p", partDev).Output() |
| 588 | + if err != nil { |
| 589 | + log.Errorf("sgdisk -p %s failed: %s, %s", partDev, err, out) |
| 590 | + return false |
| 591 | + } |
| 592 | + re := regexp.MustCompile(`^\s*(\d+)\s+(\d+)\s+(\d+)\s+([\d\.]+\s+\w+)\s+(\w+)\s*(.*)$`) |
| 593 | + scanner := bufio.NewScanner(bytes.NewReader(out)) |
| 594 | + for scanner.Scan() { |
| 595 | + line := scanner.Text() |
| 596 | + m := re.FindStringSubmatch(line) |
| 597 | + if m == nil { |
| 598 | + continue |
| 599 | + } |
| 600 | + code := m[5] |
| 601 | + if code == "EF02" { |
| 602 | + return true |
| 603 | + } |
| 604 | + } |
| 605 | + } |
| 606 | + |
| 607 | + return false |
| 608 | +} |
| 609 | + |
550 | 610 | func MountRootfs(readonly bool, partitions []fsdriver.IDiskPartition) (fsdriver.IRootFsDriver, error) { |
551 | 611 | errs := []error{} |
552 | 612 | for i := 0; i < len(partitions); i++ { |
@@ -706,6 +766,7 @@ func ProbeImageInfo(d deploy_iface.IDeployer) (*apis.ImageInfo, error) { |
706 | 766 | // multi partition concurrent, so we need umount rootfs first |
707 | 767 | imageInfo.IsUefiSupport = d.DetectIsUEFISupport(rootfs) |
708 | 768 | imageInfo.PhysicalPartitionType = partition.GetPhysicalPartitionType() |
| 769 | + imageInfo.IsBiosSupport = d.DetectIsBIOSSupport(rootfs) |
709 | 770 | log.Infof("ProbeImageInfo response %s", imageInfo) |
710 | 771 | return imageInfo, nil |
711 | 772 | } |
0 commit comments