Skip to content

Commit 8657586

Browse files
committed
fix nil pointer deref issue and make vz work
Signed-off-by: Ansuman Sahoo <[email protected]>
1 parent 4e814fb commit 8657586

File tree

4 files changed

+87
-59
lines changed

4 files changed

+87
-59
lines changed

pkg/driver/qemu/qemu_driver.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/lima-vm/lima/v2/pkg/osutil"
3636
"github.com/lima-vm/lima/v2/pkg/ptr"
3737
"github.com/lima-vm/lima/v2/pkg/store/filenames"
38+
"github.com/lima-vm/lima/v2/pkg/version/versionutil"
3839
)
3940

4041
type LimaQemuDriver struct {
@@ -73,6 +74,39 @@ func (l *LimaQemuDriver) Configure(inst *limatype.Instance, sshLocalPort int) *d
7374
l.Instance.Config.Video.VNC.Display = ptr.Of("127.0.0.1:0,to=9")
7475
}
7576

77+
mountTypesUnsupported := make(map[string]struct{})
78+
for _, f := range l.Instance.Config.MountTypesUnsupported {
79+
mountTypesUnsupported[f] = struct{}{}
80+
}
81+
82+
if runtime.GOOS == "windows" {
83+
// QEMU for Windows does not support 9p
84+
mountTypesUnsupported[limatype.NINEP] = struct{}{}
85+
}
86+
87+
if l.Instance.Config.MountType == nil || *l.Instance.Config.MountType == "" || *l.Instance.Config.MountType == "default" {
88+
l.Instance.Config.MountType = ptr.Of(limatype.NINEP)
89+
if _, ok := mountTypesUnsupported[limatype.NINEP]; ok {
90+
// Use REVSSHFS if the instance does not support 9p
91+
l.Instance.Config.MountType = ptr.Of(limatype.REVSSHFS)
92+
} else if limayaml.IsExistingInstanceDir(l.Instance.Dir) && !versionutil.GreaterEqual(limayaml.ExistingLimaVersion(l.Instance.Dir), "1.0.0") {
93+
// Use REVSSHFS if the instance was created with Lima prior to v1.0
94+
l.Instance.Config.MountType = ptr.Of(limatype.REVSSHFS)
95+
}
96+
}
97+
98+
if _, ok := mountTypesUnsupported[*l.Instance.Config.MountType]; ok {
99+
// We cannot return an error here, but Validate() will return it.
100+
logrus.Warnf("Unsupported mount type: %q", *l.Instance.Config.MountType)
101+
}
102+
103+
for i := range l.Instance.Config.Mounts {
104+
mount := &l.Instance.Config.Mounts[i]
105+
if mount.Virtiofs.QueueSize == nil && *l.Instance.Config.MountType == limatype.VIRTIOFS {
106+
l.Instance.Config.Mounts[i].Virtiofs.QueueSize = ptr.Of(limayaml.DefaultVirtiofsQueueSize)
107+
}
108+
}
109+
76110
return &driver.ConfiguredDriver{
77111
Driver: l,
78112
}

pkg/driver/vz/vz_driver_darwin.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/lima-vm/lima/v2/pkg/limatype"
2424
"github.com/lima-vm/lima/v2/pkg/limayaml"
2525
"github.com/lima-vm/lima/v2/pkg/osutil"
26+
"github.com/lima-vm/lima/v2/pkg/ptr"
2627
"github.com/lima-vm/lima/v2/pkg/reflectutil"
2728
"github.com/lima-vm/lima/v2/pkg/store/filenames"
2829
)
@@ -66,6 +67,7 @@ var knownYamlProperties = []string{
6667
"User",
6768
"Video",
6869
"VMType",
70+
"VMOpts",
6971
}
7072

7173
const Enabled = true
@@ -93,12 +95,28 @@ func (l *LimaVzDriver) Configure(inst *limatype.Instance, sshLocalPort int) *dri
9395
l.Instance = inst
9496
l.SSHLocalPort = sshLocalPort
9597

98+
if l.Instance.Config.MountType != nil {
99+
mountTypesUnsupported := make(map[string]struct{})
100+
for _, f := range l.Instance.Config.MountTypesUnsupported {
101+
mountTypesUnsupported[f] = struct{}{}
102+
}
103+
104+
if _, ok := mountTypesUnsupported[*l.Instance.Config.MountType]; ok {
105+
// We cannot return an error here, but Validate() will return it.
106+
logrus.Warnf("Unsupported mount type: %q", *l.Instance.Config.MountType)
107+
}
108+
}
109+
96110
return &driver.ConfiguredDriver{
97111
Driver: l,
98112
}
99113
}
100114

101115
func (l *LimaVzDriver) AcceptConfig(cfg *limatype.LimaYAML, filePath string) error {
116+
if cfg.MountType == nil {
117+
cfg.MountType = ptr.Of(limatype.VIRTIOFS)
118+
}
119+
102120
if dir, basename := filepath.Split(filePath); dir != "" && basename == filenames.LimaYAML && limayaml.IsExistingInstanceDir(dir) {
103121
vzIdentifier := filepath.Join(dir, filenames.VzIdentifier) // since Lima v0.14
104122
if _, err := os.Lstat(vzIdentifier); !errors.Is(err, os.ErrNotExist) {
@@ -111,9 +129,6 @@ func (l *LimaVzDriver) AcceptConfig(cfg *limatype.LimaYAML, filePath string) err
111129
l.Instance = &limatype.Instance{}
112130
}
113131
l.Instance.Config = cfg
114-
defer func() {
115-
l.Instance.Config = nil
116-
}()
117132

118133
if err := l.Validate(); err != nil {
119134
return fmt.Errorf("config not supported by the VZ driver: %w", err)
@@ -135,7 +150,7 @@ func (l *LimaVzDriver) Validate() error {
135150
"Update macOS, or change vmType to \"qemu\" if the VM does not start up. (https://github.com/lima-vm/lima/issues/3334)",
136151
*l.Instance.Config.VMType)
137152
}
138-
if *l.Instance.Config.MountType == limatype.NINEP {
153+
if l.Instance.Config.MountType != nil && *l.Instance.Config.MountType == limatype.NINEP {
139154
return fmt.Errorf("field `mountType` must be %q or %q for VZ driver , got %q", limatype.REVSSHFS, limatype.VIRTIOFS, *l.Instance.Config.MountType)
140155
}
141156
if *l.Instance.Config.Firmware.LegacyBIOS {
@@ -149,7 +164,7 @@ func (l *LimaVzDriver) Validate() error {
149164
}
150165
}
151166
}
152-
if unknown := reflectutil.UnknownNonEmptyFields(l.Instance.Config, knownYamlProperties...); len(unknown) > 0 {
167+
if unknown := reflectutil.UnknownNonEmptyFields(l.Instance.Config, knownYamlProperties...); l.Instance.Config.VMType != nil && len(unknown) > 0 {
153168
logrus.Warnf("vmType %s: ignoring %+v", *l.Instance.Config.VMType, unknown)
154169
}
155170

pkg/limayaml/defaults.go

Lines changed: 16 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import (
3737
"github.com/lima-vm/lima/v2/pkg/store/dirnames"
3838
"github.com/lima-vm/lima/v2/pkg/store/filenames"
3939
"github.com/lima-vm/lima/v2/pkg/version"
40-
"github.com/lima-vm/lima/v2/pkg/version/versionutil"
4140
)
4241

4342
const (
@@ -139,18 +138,7 @@ func defaultGuestInstallPrefix() string {
139138
func FillDefault(y, d, o *limatype.LimaYAML, filePath string, warn bool) {
140139
instDir := filepath.Dir(filePath)
141140

142-
// existingLimaVersion can be empty if the instance was created with Lima prior to v0.20,
143-
var existingLimaVersion string
144-
if !IsExistingInstanceDir(instDir) {
145-
existingLimaVersion = version.Version
146-
} else {
147-
limaVersionFile := filepath.Join(instDir, filenames.LimaVersion)
148-
if b, err := os.ReadFile(limaVersionFile); err == nil {
149-
existingLimaVersion = strings.TrimSpace(string(b))
150-
} else if !errors.Is(err, os.ErrNotExist) {
151-
logrus.WithError(err).Warnf("Failed to read %q", limaVersionFile)
152-
}
153-
}
141+
existingLimaVersion := ExistingLimaVersion(instDir)
154142

155143
if y.User.Name == nil {
156144
y.User.Name = d.User.Name
@@ -627,15 +615,6 @@ func FillDefault(y, d, o *limatype.LimaYAML, filePath string, warn bool) {
627615
}
628616

629617
y.MountTypesUnsupported = slices.Concat(o.MountTypesUnsupported, y.MountTypesUnsupported, d.MountTypesUnsupported)
630-
mountTypesUnsupported := make(map[string]struct{})
631-
for _, f := range y.MountTypesUnsupported {
632-
mountTypesUnsupported[f] = struct{}{}
633-
}
634-
635-
if runtime.GOOS == "windows" {
636-
// QEMU for Windows does not support 9p
637-
mountTypesUnsupported[limatype.NINEP] = struct{}{}
638-
}
639618

640619
// MountType has to be resolved before resolving Mounts
641620
if y.MountType == nil {
@@ -644,28 +623,6 @@ func FillDefault(y, d, o *limatype.LimaYAML, filePath string, warn bool) {
644623
if o.MountType != nil {
645624
y.MountType = o.MountType
646625
}
647-
if y.MountType == nil || *y.MountType == "" || *y.MountType == "default" {
648-
switch *y.VMType {
649-
case limatype.VZ:
650-
y.MountType = ptr.Of(limatype.VIRTIOFS)
651-
case limatype.QEMU:
652-
y.MountType = ptr.Of(limatype.NINEP)
653-
if _, ok := mountTypesUnsupported[limatype.NINEP]; ok {
654-
// Use REVSSHFS if the instance does not support 9p
655-
y.MountType = ptr.Of(limatype.REVSSHFS)
656-
} else if IsExistingInstanceDir(instDir) && !versionutil.GreaterEqual(existingLimaVersion, "1.0.0") {
657-
// Use REVSSHFS if the instance was created with Lima prior to v1.0
658-
y.MountType = ptr.Of(limatype.REVSSHFS)
659-
}
660-
default:
661-
y.MountType = ptr.Of(limatype.REVSSHFS)
662-
}
663-
}
664-
665-
if _, ok := mountTypesUnsupported[*y.MountType]; ok {
666-
// We cannot return an error here, but Validate() will return it.
667-
logrus.Warnf("Unsupported mount type: %q", *y.MountType)
668-
}
669626

670627
if y.MountInotify == nil {
671628
y.MountInotify = d.MountInotify
@@ -752,9 +709,6 @@ func FillDefault(y, d, o *limatype.LimaYAML, filePath string, warn bool) {
752709
if mount.NineP.Msize == nil {
753710
mounts[i].NineP.Msize = ptr.Of(Default9pMsize)
754711
}
755-
if mount.Virtiofs.QueueSize == nil && *y.VMType == limatype.QEMU && *y.MountType == limatype.VIRTIOFS {
756-
mounts[i].Virtiofs.QueueSize = ptr.Of(DefaultVirtiofsQueueSize)
757-
}
758712
if mount.Writable == nil {
759713
mount.Writable = ptr.Of(false)
760714
}
@@ -863,6 +817,21 @@ func FillDefault(y, d, o *limatype.LimaYAML, filePath string, warn bool) {
863817
fixUpForPlainMode(y)
864818
}
865819

820+
// ExistingLimaVersion returns empty if the instance was created with Lima prior to v0.20,
821+
func ExistingLimaVersion(instDir string) string {
822+
if !IsExistingInstanceDir(instDir) {
823+
return version.Version
824+
} else {
825+
limaVersionFile := filepath.Join(instDir, filenames.LimaVersion)
826+
if b, err := os.ReadFile(limaVersionFile); err == nil {
827+
return strings.TrimSpace(string(b))
828+
} else if !errors.Is(err, os.ErrNotExist) {
829+
logrus.WithError(err).Warnf("Failed to read %q", limaVersionFile)
830+
}
831+
}
832+
return version.Version
833+
}
834+
866835
func fixUpForPlainMode(y *limatype.LimaYAML) {
867836
if !*y.Plain {
868837
return

pkg/limayaml/load.go

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,22 @@ func load(b []byte, filePath string, warn bool) (*limatype.LimaYAML, error) {
7171
}
7272

7373
FillDefault(&y, &d, &o, filePath, warn)
74-
vmType, err := ResolveVMType(&y, filePath)
74+
vmType, err := CheckExplicitVM(&y, filePath)
7575
if err != nil {
7676
logrus.WithError(err).Warnf("Failed to resolve VMType for %q", filePath)
7777
}
7878
y.VMType = ptr.Of(vmType)
7979

80+
if err := AcceptConfig(&y, filePath); err != nil {
81+
logrus.WithError(err).Warnf("Failed to accept config for %q", filePath)
82+
return nil, fmt.Errorf("failed to accept config for %q: %w", filePath, err)
83+
}
84+
8085
return &y, nil
8186
}
8287

83-
func ResolveVMType(y *limatype.LimaYAML, filePath string) (limatype.VMType, error) {
84-
// Check if the VMType is explicitly specified
88+
// Check if the VMType is explicitly specified
89+
func CheckExplicitVM(y *limatype.LimaYAML, filePath string) (limatype.VMType, error) {
8590
if y.VMType != nil && *y.VMType != "" && *y.VMType != "default" {
8691
logrus.Debugf("ResolveVMType: VMType %q is explicitly specified in %q", *y.VMType, filePath)
8792
_, _, exists := registry.Get(*y.VMType)
@@ -92,19 +97,24 @@ func ResolveVMType(y *limatype.LimaYAML, filePath string) (limatype.VMType, erro
9297
return limatype.NewVMType(*y.VMType), nil
9398
}
9499

100+
return "", nil
101+
}
102+
103+
func AcceptConfig(y *limatype.LimaYAML, filePath string) error {
95104
candidates := registry.List()
96105
for vmType, location := range candidates {
97-
if location != registry.External {
106+
if location != registry.External && vmType == limatype.VZ {
98107
// For now we only support internal drivers.
99108
_, intDriver, _ := registry.Get(vmType)
100109
if err := intDriver.AcceptConfig(y, filePath); err == nil {
101110
logrus.Debugf("ResolveVMType: resolved VMType %q (from %q)", vmType, location)
102-
return limatype.NewVMType(vmType), nil
111+
y.VMType = ptr.Of(vmType)
112+
return nil
103113
} else {
104114
logrus.Debugf("ResolveVMType: VMType %q is not accepted by the driver: %v", vmType, err)
115+
return fmt.Errorf("VMType %q is not accepted by the driver: %w", vmType, err)
105116
}
106117
}
107118
}
108-
109-
return "", errors.New("no driver can handle this config")
119+
return fmt.Errorf("no VMType found for %q", filePath)
110120
}

0 commit comments

Comments
 (0)