Skip to content

Commit 83db9de

Browse files
committed
vde: defer vnl validation until starting qemu
Fix #146 Signed-off-by: Akihiro Suda <[email protected]>
1 parent 089165d commit 83db9de

File tree

2 files changed

+29
-24
lines changed

2 files changed

+29
-24
lines changed

pkg/limayaml/validate.go

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -179,31 +179,31 @@ func validateNetwork(yNetwork Network) error {
179179
// optionally with vde:// prefix.
180180
if !strings.Contains(vde.VNL, "://") || strings.HasPrefix(vde.VNL, "vde://") {
181181
vdeSwitch := strings.TrimPrefix(vde.VNL, "vde://")
182-
fi, err := os.Stat(vdeSwitch)
183-
if err != nil {
184-
return fmt.Errorf("field `%s.vnl` %q failed stat: %w", field, vdeSwitch, err)
185-
}
186-
if fi.IsDir() {
187-
/* Switch mode (vdeSwitch is dir, port != 65535) */
188-
ctlSocket := filepath.Join(vdeSwitch, "ctl")
189-
fi, err = os.Stat(ctlSocket)
190-
if err != nil {
191-
return fmt.Errorf("field `%s.vnl` control socket %q failed stat: %w", field, ctlSocket, err)
192-
}
193-
if fi.Mode()&os.ModeSocket == 0 {
194-
return fmt.Errorf("field `%s.vnl` file %q is not a UNIX socket", field, ctlSocket)
195-
}
196-
if vde.SwitchPort == 65535 {
197-
return fmt.Errorf("field `%s.vnl` points to a non-PTP switch, so the port number must not be 65535", field)
198-
}
182+
if fi, err := os.Stat(vdeSwitch); err != nil {
183+
// negligible when the instance is stopped
184+
logrus.WithError(err).Debugf("field `%s.vnl` %q failed stat", field, vdeSwitch)
199185
} else {
200-
/* PTP mode (vdeSwitch is socket, port == 65535) */
201-
if fi.Mode()&os.ModeSocket == 0 {
202-
return fmt.Errorf("field `%s.vnl` %q is not a directory nor a UNIX socket", field, vdeSwitch)
203-
}
204-
if vde.SwitchPort != 65535 {
205-
return fmt.Errorf("field `%s.vnl` points to a PTP (switchless) socket %q, so the port number has to be 65535 (got %d)",
206-
field, vdeSwitch, vde.SwitchPort)
186+
if fi.IsDir() {
187+
/* Switch mode (vdeSwitch is dir, port != 65535) */
188+
ctlSocket := filepath.Join(vdeSwitch, "ctl")
189+
// ErrNotExist during os.Stat(ctlSocket) can be ignored. ctlSocket does not need to exist until actually starting the VM
190+
if fi, err = os.Stat(ctlSocket); err == nil {
191+
if fi.Mode()&os.ModeSocket == 0 {
192+
return fmt.Errorf("field `%s.vnl` file %q is not a UNIX socket", field, ctlSocket)
193+
}
194+
}
195+
if vde.SwitchPort == 65535 {
196+
return fmt.Errorf("field `%s.vnl` points to a non-PTP switch, so the port number must not be 65535", field)
197+
}
198+
} else {
199+
/* PTP mode (vdeSwitch is socket, port == 65535) */
200+
if fi.Mode()&os.ModeSocket == 0 {
201+
return fmt.Errorf("field `%s.vnl` %q is not a directory nor a UNIX socket", field, vdeSwitch)
202+
}
203+
if vde.SwitchPort != 65535 {
204+
return fmt.Errorf("field `%s.vnl` points to a PTP (switchless) socket %q, so the port number has to be 65535 (got %d)",
205+
field, vdeSwitch, vde.SwitchPort)
206+
}
207207
}
208208
}
209209
} else if runtime.GOOS != "linux" {

pkg/qemu/qemu.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,11 @@ func Cmdline(cfg Config) (string, []string, error) {
207207
// VDE2 only accepts the latter form.
208208
// VDE2 supports macOS but VDE4 does not yet, so we trim vde:// prefix here for VDE2 compatibility.
209209
vdeSock := strings.TrimPrefix(vde.VNL, "vde://")
210+
if !strings.Contains(vdeSock, "://") {
211+
if _, err := os.Stat(vdeSock); err != nil {
212+
return "", nil, fmt.Errorf("cannot use VNL %q: %w", vde.VNL, err)
213+
}
214+
}
210215
args = append(args, "-netdev", fmt.Sprintf("vde,id=net%d,sock=%s", i+1, vdeSock))
211216
args = append(args, "-device", fmt.Sprintf("virtio-net-pci,netdev=net%d,mac=%s", i+1, vde.MACAddress))
212217
}

0 commit comments

Comments
 (0)