Skip to content

Commit b012b46

Browse files
committed
Add pidfile, check for pid before getting state
Save the pid in a file when starting up the qemu process, to make it much quicker to query the non-running machines. When the process terminates, remove the old pidfile again. This allows to quickly determine it has not been started.
1 parent a8ac469 commit b012b46

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

qemu.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"path/filepath"
1313
"strconv"
1414
"strings"
15+
"syscall"
1516
"time"
1617

1718
"github.com/docker/machine/libmachine/drivers"
@@ -202,6 +203,9 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
202203

203204
func (d *Driver) GetURL() (string, error) {
204205
log.Debugf("GetURL called")
206+
if _, err := os.Stat(d.pidfilePath()); err != nil {
207+
return "", nil
208+
}
205209
ip, err := d.GetIP()
206210
if err != nil {
207211
log.Warnf("Failed to get IP: %s", err)
@@ -240,8 +244,32 @@ func (d *Driver) GetPort() (int, error) {
240244
return d.EnginePort, nil
241245
}
242246

247+
func checkPid(pid int) error {
248+
process, err := os.FindProcess(pid)
249+
if err != nil {
250+
return err
251+
}
252+
return process.Signal(syscall.Signal(0))
253+
}
254+
243255
func (d *Driver) GetState() (state.State, error) {
244256

257+
if _, err := os.Stat(d.pidfilePath()); err != nil {
258+
return state.Stopped, nil
259+
}
260+
p, err := ioutil.ReadFile(d.pidfilePath())
261+
if err != nil {
262+
return state.Error, err
263+
}
264+
pid, err := strconv.Atoi(strings.TrimSpace(string(p)))
265+
if err != nil {
266+
return state.Error, err
267+
}
268+
if err := checkPid(pid); err != nil {
269+
// No pid, remove pidfile
270+
os.Remove(d.pidfilePath())
271+
return state.Stopped, nil
272+
}
245273
ret, err := d.RunQMPCommand("query-status")
246274
if err != nil {
247275
return state.Error, err
@@ -338,6 +366,7 @@ func (d *Driver) Start() error {
338366
"-boot", "d",
339367
"-cdrom", filepath.Join(machineDir, "boot2docker.iso"),
340368
"-qmp", fmt.Sprintf("unix:%s,server,nowait", d.monitorPath()),
369+
"-pidfile", d.pidfilePath(),
341370
}
342371

343372
if d.Network == "user" {
@@ -509,6 +538,11 @@ func (d *Driver) monitorPath() string {
509538
return filepath.Join(machineDir, "monitor")
510539
}
511540

541+
func (d *Driver) pidfilePath() string {
542+
machineDir := filepath.Join(d.StorePath, "machines", d.GetMachineName())
543+
return filepath.Join(machineDir, "qemu.pid")
544+
}
545+
512546
// Make a boot2docker VM disk image.
513547
func (d *Driver) generateDiskImage(size int) error {
514548
log.Debugf("Creating %d MB hard disk image...", size)

0 commit comments

Comments
 (0)