in cli_tools/common/imagefile/qemu_img.go [115:162]
func (client defaultInfoClient) getFileChecksum(ctx context.Context, filename string, virtualSizeBytes int64) (checksum string, err error) {
// We calculate 4 chunks' checksum. Each of them is 100MB: 0~100MB, 0.9GB~1GB, 9.9GB~10GB, the last 100MB.
// It is align with what we did for "daisy_workflows/image_import/import_image.sh" so that we can compare them.
// Each block size is 512 Bytes. So, we need to check 20000 blocks: 200000 * 512 Bytes = 100MB
// "skips" is also the start point of each chunks.
checkBlockCount := int64(200000)
blockSize := int64(512)
totalBlockCount := virtualSizeBytes / blockSize
skips := []int64{0, int64(2000000) - checkBlockCount, int64(20000000) - checkBlockCount, totalBlockCount - checkBlockCount}
for i, skip := range skips {
tmpOutFileName := fmt.Sprintf("%v%v", client.tmpOutFilePrefix, i)
defer os.Remove(tmpOutFileName)
if skip < 0 {
skip = 0
}
// Write 100MB data to a file.
var out string
out, err = client.shellExecutor.Exec("qemu-img", "dd", fmt.Sprintf("if=%v", filename),
fmt.Sprintf("of=%v", tmpOutFileName), fmt.Sprintf("bs=%v", blockSize),
fmt.Sprintf("count=%v", skip+checkBlockCount), fmt.Sprintf("skip=%v", skip))
err = constructCmdErr(out, err, "inspection for checksum failure")
if err != nil {
return
}
// Calculate checksum for the 100MB file.
f, fileErr := os.Open(tmpOutFileName)
if fileErr != nil {
err = daisy.Errf("Failed to open file '%v' for QEMU md5 checksum calculation: %v", tmpOutFileName, fileErr)
return
}
defer f.Close()
h := md5.New()
if _, md5Err := io.Copy(h, f); md5Err != nil {
err = daisy.Errf("Failed to copy data from file '%v' for QEMU md5 checksum calculation: %v", tmpOutFileName, md5Err)
return
}
newChecksum := fmt.Sprintf("%x", h.Sum(nil))
if checksum != "" {
checksum += "-"
}
checksum += newChecksum
}
return
}