Use chunked ISO search instead of reading entire 1.2GB file into memory
os.ReadFile on the ISO was OOM-killing the container. Switch to 8MB chunked reads with overlap to handle matches spanning chunk boundaries. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+44
-12
@@ -170,13 +170,16 @@ func rewriteGrubConfig(original, answerURL string) string {
|
||||
return strings.Join(collapsed, "\n")
|
||||
}
|
||||
|
||||
// findAllOccurrences searches the entire ISO file for all locations where
|
||||
// the grub.cfg content appears — this catches both the ISO9660 filesystem
|
||||
// copy and any copy inside an embedded EFI boot partition image.
|
||||
func findAllOccurrences(isoPath string, content []byte) ([]int64, error) {
|
||||
data, err := os.ReadFile(isoPath)
|
||||
f, err := os.Open(isoPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read ISO: %w", err)
|
||||
return nil, fmt.Errorf("open ISO: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
stat, err := f.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
needle := content
|
||||
@@ -184,20 +187,49 @@ func findAllOccurrences(isoPath string, content []byte) ([]int64, error) {
|
||||
needle = needle[:256]
|
||||
}
|
||||
|
||||
const chunkSize = 8 * 1024 * 1024
|
||||
overlap := len(needle) - 1
|
||||
buf := make([]byte, chunkSize+overlap)
|
||||
|
||||
var offsets []int64
|
||||
start := 0
|
||||
for {
|
||||
idx := bytes.Index(data[start:], needle)
|
||||
if idx == -1 {
|
||||
filePos := int64(0)
|
||||
|
||||
for filePos < stat.Size() {
|
||||
readStart := filePos
|
||||
if filePos > 0 {
|
||||
readStart -= int64(overlap)
|
||||
}
|
||||
|
||||
n, err := f.ReadAt(buf, readStart)
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
searchFrom := 0
|
||||
if filePos > 0 {
|
||||
searchFrom = overlap
|
||||
}
|
||||
|
||||
chunk := buf[:n]
|
||||
pos := searchFrom
|
||||
for {
|
||||
idx := bytes.Index(chunk[pos:], needle)
|
||||
if idx == -1 {
|
||||
break
|
||||
}
|
||||
offsets = append(offsets, readStart+int64(pos)+int64(idx))
|
||||
pos += idx + 1
|
||||
}
|
||||
|
||||
filePos += chunkSize
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
offsets = append(offsets, int64(start+idx))
|
||||
start += idx + 1
|
||||
}
|
||||
|
||||
if len(offsets) == 0 {
|
||||
return nil, fmt.Errorf("grub.cfg content not found in ISO raw data (searched %d bytes with %d-byte needle)",
|
||||
len(data), len(needle))
|
||||
stat.Size(), len(needle))
|
||||
}
|
||||
|
||||
return offsets, nil
|
||||
|
||||
Reference in New Issue
Block a user