Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lima-vm
GitHub Repository: lima-vm/lima
Path: blob/master/pkg/store/disk.go
2606 views
1
// SPDX-FileCopyrightText: Copyright The Lima Authors
2
// SPDX-License-Identifier: Apache-2.0
3
4
package store
5
6
import (
7
"errors"
8
"fmt"
9
"io/fs"
10
"os"
11
"path/filepath"
12
13
"github.com/lima-vm/go-qcow2reader"
14
15
"github.com/lima-vm/lima/v2/pkg/limatype/filenames"
16
)
17
18
type Disk struct {
19
Name string `json:"name"`
20
Size int64 `json:"size"`
21
Format string `json:"format"`
22
Dir string `json:"dir"`
23
Instance string `json:"instance"`
24
InstanceDir string `json:"instanceDir"`
25
MountPoint string `json:"mountPoint"`
26
27
// if the Disk is in use and the FSType is specified
28
FSType *string `json:"fsType,omitempty"`
29
}
30
31
func InspectDisk(diskName string, fsType *string) (*Disk, error) {
32
disk := &Disk{
33
Name: diskName,
34
FSType: fsType,
35
}
36
37
diskDir, err := DiskDir(diskName)
38
if err != nil {
39
return nil, err
40
}
41
42
disk.Dir = diskDir
43
dataDisk := filepath.Join(diskDir, filenames.DataDisk)
44
if _, err := os.Stat(dataDisk); err != nil {
45
return nil, err
46
}
47
48
disk.Size, disk.Format, err = inspectDisk(dataDisk)
49
if err != nil {
50
return nil, err
51
}
52
53
instDir, err := os.Readlink(filepath.Join(diskDir, filenames.InUseBy))
54
if err != nil {
55
if !errors.Is(err, fs.ErrNotExist) {
56
return nil, err
57
}
58
} else {
59
disk.Instance = filepath.Base(instDir)
60
disk.InstanceDir = instDir
61
}
62
63
if disk.FSType != nil && *disk.FSType == "swap" {
64
disk.MountPoint = "[SWAP]" // only used for log message
65
} else {
66
disk.MountPoint = fmt.Sprintf("/mnt/lima-%s", diskName)
67
}
68
69
return disk, nil
70
}
71
72
// inspectDisk attempts to inspect the disk size and format with qcow2reader.
73
func inspectDisk(fName string) (size int64, format string, _ error) {
74
f, err := os.Open(fName)
75
if err != nil {
76
return -1, "", err
77
}
78
defer f.Close()
79
img, err := qcow2reader.Open(f)
80
if err != nil {
81
return -1, "", err
82
}
83
sz := img.Size()
84
if sz < 0 {
85
return -1, "", fmt.Errorf("cannot determine size of %q", fName)
86
}
87
88
return sz, string(img.Type()), nil
89
}
90
91
func (d *Disk) Lock(instanceDir string) error {
92
inUseBy := filepath.Join(d.Dir, filenames.InUseBy)
93
return os.Symlink(instanceDir, inUseBy)
94
}
95
96
func (d *Disk) Unlock() error {
97
inUseBy := filepath.Join(d.Dir, filenames.InUseBy)
98
return os.Remove(inUseBy)
99
}
100
101