Skip to content

Commit

Permalink
Merge pull request #9 from AntonioMeireles/crashcrashes
Browse files Browse the repository at this point in the history
another round attempting to add more polish and get rid of the remaining crashers
  • Loading branch information
AntonioMeireles committed Dec 2, 2015
2 parents 4e0eaa1 + 48a19bf commit 95c2fd2
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 53 deletions.
2 changes: 1 addition & 1 deletion globals.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type (
VMInfo struct {
Name, Channel, Version string
Cpus, Memory int
UUID string
UUID, MacAddress string
CloudConfig, CClocation, SSHkey, Extra string `json:",omitempty"`
Root int
Ethernet []NetworkInterface
Expand Down
6 changes: 6 additions & 0 deletions halt.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"log"
"os"
"path/filepath"
"time"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -88,11 +89,16 @@ func (vm VMInfo) halt() (err error) {
}
// wait until it's _really_ dead
defer func() {
leftover := filepath.Join(SessionContext.runDir, vm.UUID)

for range time.Tick(500 * time.Millisecond) {
if _, ee := os.FindProcess(vm.Pid); ee == nil {
break
}
}
if e := os.RemoveAll(leftover); e != nil {
log.Println(e.Error())
}
log.Printf("successfully halted '%s'\n", vm.Name)
}()

Expand Down
11 changes: 8 additions & 3 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,17 @@ func (vm *VMInfo) isActive() bool {

func (vm *VMInfo) metadataService() (endpoint string, err error) {
var (
free net.Listener
runOnce sync.Once
free net.Listener
runOnce sync.Once
freePort = func() (net.Listener, error) {
defer recover()
return net.Listen("tcp", "localhost:0")
}
)

// workaround OSX and/or golang weirdness...
for range time.Tick(500 * time.Millisecond) {
if free, err = net.Listen("tcp", "localhost:0"); err == nil {
if free, err = freePort(); err == nil {
break
}
}
Expand Down
26 changes: 17 additions & 9 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ func xhyveCommand(cmd *cobra.Command, args []string) (err error) {

func bootVM(vipre *viper.Viper) (err error) {
var (
mac, rundir string
vm, c = &VMInfo{}, &exec.Cmd{}
rundir string
vm, c = &VMInfo{}, &exec.Cmd{}
)

vm.PreferLocalImages = vipre.GetBool("local")
Expand Down Expand Up @@ -170,10 +170,6 @@ func bootVM(vipre *viper.Viper) (err error) {
return
}

if mac, err = uuid2ip.GuestMACfromUUID(vm.UUID); err != nil {
return
}

go func() {
wg.Add(1)
defer func() {
Expand All @@ -189,9 +185,10 @@ func bootVM(vipre *viper.Viper) (err error) {
break
}

for range time.Tick(100 * time.Millisecond) {
for range time.Tick(500 * time.Millisecond) {
var e error
if vm.PublicIP, e = uuid2ip.GuestIPfromMAC(mac); e == nil {
if vm.PublicIP, e =
uuid2ip.GuestIPfromMAC(vm.MacAddress); e == nil {
break
}
}
Expand Down Expand Up @@ -415,14 +412,25 @@ func (vm *VMInfo) validateNameAndUUID(name, xxid string) (err error) {
if xxid == "random" {
vm.UUID = uuid.NewV4().String()
} else {
if _, err := uuid.FromString(xxid); err != nil {
if _, err = uuid.FromString(xxid); err != nil {
log.Printf("%s not a valid UUID as it doesn't follow RFC 4122. %s\n",
xxid, " using a randomly generated one")
vm.UUID = uuid.NewV4().String()
} else {
vm.UUID = xxid
}
}
for {
if vm.MacAddress, err = uuid2ip.GuestMACfromUUID(vm.UUID); err == nil {
break
}
if xxid != "random" {
log.Printf("unable to guess the MAC Address from the provided "+
"UUID (%s). Using a randomly generated one one\n", xxid)
}
vm.UUID = uuid.NewV4().String()
}

if name == "" {
vm.Name = vm.UUID
} else {
Expand Down
40 changes: 23 additions & 17 deletions uuid2ip/uuid2ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,26 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/* originally at https://github.com/ailispaw/boot2docker-xhyve/uuid2ip and
* slightly refactored to better fit the golang bindings
* github.com/AntonioMeireles/coreos-xhyve/uuid2ip
*/

/* originally at github.com/zchee/docker-machine-xhyve/blob/embed-xhyve/vmnet/
* and slightly refactored to better fit the golang bindings
* github.com/TheNewNormal/coreos-xhyve/uuid2ip
*/
#include <stdio.h>

#include <vmnet/vmnet.h>

#include "uuid2ip.h"

static int
vmnet_get_mac_address_from_uuid(char *guest_uuid_str, char *mac, char *err) {
static char*
vmnet_get_mac_address_from_uuid(char *guest_uuid_str) {
/*
* from vmn_create() in https://github.com/mist64/xhyve/blob/master/src/pci_virtio_vmnet.c
*/
xpc_object_t interface_desc;
uuid_t uuid;
__block interface_ref iface;
__block vmnet_return_t iface_status;
__block char* mac = malloc(18);
dispatch_semaphore_t iface_created, iface_stopped;
dispatch_queue_t if_create_q, if_stop_q;
uint32_t uuid_status;
Expand All @@ -74,8 +74,8 @@ vmnet_get_mac_address_from_uuid(char *guest_uuid_str, char *mac, char *err) {

uuid_from_string(guest_uuid_str, &uuid, &uuid_status);
if (uuid_status != uuid_s_ok) {
strcpy(err, "Invalid UUID");
return -1;
fprintf(stderr, "Invalid UUID\n");
return NULL;
}

xpc_dictionary_set_uuid(interface_desc, vmnet_interface_id_key, uuid);
Expand All @@ -94,7 +94,10 @@ vmnet_get_mac_address_from_uuid(char *guest_uuid_str, char *mac, char *err) {
dispatch_semaphore_signal(iface_created);
return;
}
strcpy(mac, xpc_dictionary_get_string(interface_param, vmnet_mac_address_key));

//printf("%s\n", xpc_dictionary_get_string(interface_param, vmnet_mac_address_key));
const char *macStr = xpc_dictionary_get_string(interface_param, vmnet_mac_address_key);
strcpy(mac, macStr);

dispatch_semaphore_signal(iface_created);
});
Expand All @@ -103,9 +106,11 @@ vmnet_get_mac_address_from_uuid(char *guest_uuid_str, char *mac, char *err) {
dispatch_release(if_create_q);

if (iface == NULL || iface_status != VMNET_SUCCESS) {
strcpy(err, "virtio_net: Could not create vmnet interface, "
"permission denied or no entitlement?");
return -1;
// XXX supress noise in this cery specific case
// XXX understand some day why some random UUIDs induce this...
// fprintf(stderr, "virtio_net: Could not create vmnet interface, "
// "permission denied or no entitlement?\n");
return NULL;
}

iface_status = 0;
Expand All @@ -125,9 +130,10 @@ vmnet_get_mac_address_from_uuid(char *guest_uuid_str, char *mac, char *err) {
dispatch_release(if_stop_q);

if (iface_status != VMNET_SUCCESS) {
strcpy(err, "virtio_net: Could not stop vmnet interface, "
"permission denied or no entitlement?");
return -1;
fprintf(stderr, "virtio_net: Could not stop vmnet interface, "
"permission denied or no entitlement?\n");
return NULL;
}
return 0;

return mac;
}
31 changes: 12 additions & 19 deletions uuid2ip/uuid2ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,28 @@ import "C"
import (
"fmt"
"io/ioutil"
"net"
"os"
"regexp"
"runtime"
"strings"
"unsafe"
)

// GuestMACfromUUID returns the MAC address that will assembled from the given
// UUID by xhyve, needs to be called before xhyve actual invocation
func GuestMACfromUUID(uuid string) (mac string, err error) {
fail, uuidC := "", C.CString(uuid)
macC, failC := C.CString(mac), C.CString(fail)
var ret C.int

runtime.LockOSThread()
defer func() {
C.free(unsafe.Pointer(uuidC))
C.free(unsafe.Pointer(macC))
C.free(unsafe.Pointer(failC))
runtime.UnlockOSThread()
}()

if ret = C.vmnet_get_mac_address_from_uuid(uuidC,
(*C.char)(unsafe.Pointer(macC)),
(*C.char)(unsafe.Pointer(failC))); ret != 0 {
return mac, fmt.Errorf(C.GoString(failC))
var (
hw net.HardwareAddr
uuidC = C.CString(uuid)
)
mac = C.GoString(C.vmnet_get_mac_address_from_uuid(uuidC))
C.free(unsafe.Pointer(uuidC))
if mac == "" {
err = fmt.Errorf("Could not get a MAC address from %s", uuid)
} else if hw, err = net.ParseMAC(mac); err == nil {
mac = hw.String()
}
mac = C.GoString(macC)
return mac, nil
return
}

// GuestIPfromMAC returns the IP address that would be leased to the given MAC
Expand Down
8 changes: 4 additions & 4 deletions uuid2ip/uuid2ip.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/*-
* Copyright (c) 2002,2005 Marcel Moolenaar
* Copyright (c) 2002 Hiten Mahesh Pandya
Expand Down Expand Up @@ -26,10 +27,9 @@
*
* $FreeBSD$
*/

/* originally at https://github.com/ailispaw/boot2docker-xhyve/uuid2ip and
* slightly refactored to better fit the golang bindings
* github.com/AntonioMeireles/coreos-xhyve/uuid2ip
/* originally at github.com/zchee/docker-machine-xhyve/blob/embed-xhyve/vmnet/
* and slightly refactored to better fit the golang bindings
* github.com/TheNewNormal/coreos-xhyve/uuid2ip
*/

#pragma once
Expand Down

0 comments on commit 95c2fd2

Please sign in to comment.