Example #1
0
File: disk.go Project: hyperhq/runv
func (dc *DiskContext) remove(result chan<- api.Result) {
	if result == nil {
		result = make(chan api.Result, 4)
	}

	if dc.IsDir() {
		result <- api.NewResultBase(dc.Name, true, "no need to unplug")
		return
	}

	go func() {
		r := make(chan VmEvent, 4)
		dc.sandbox.DCtx.RemoveDisk(dc.sandbox, dc.DiskDescriptor, &VolumeUnmounted{Name: dc.Name, Success: true}, r)

		ev, ok := <-r
		if !ok {
			dc.failed()
			result <- api.NewResultBase(dc.Name, false, "disk remove session broken")
			return
		}

		_, ok = ev.(*VolumeUnmounted)
		if !ok {
			dc.failed()
			result <- api.NewResultBase(dc.Name, false, "disk remove failed")
			return
		}

		result <- api.NewResultBase(dc.Name, true, "")
	}()
}
Example #2
0
func (nc *NetworkContext) removeInterface(id string, result chan api.Result) {
	if inf, ok := nc.idMap[id]; !ok {
		nc.sandbox.Log(WARNING, "trying remove a non-exist interface %s", id)
		result <- api.NewResultBase(id, true, "not exist")
		return
	} else if inf.HostDevice == "" { // a virtual interface
		delete(nc.idMap, id)
		delete(nc.lo, inf.IpAddr)
		result <- api.NewResultBase(id, true, "")
		return
	} else {
		nc.slotLock.Lock()
		defer nc.slotLock.Unlock()

		if _, ok := nc.eth[inf.Index]; !ok {
			delete(nc.idMap, id)
			nc.sandbox.Log(INFO, "non-configured network device %d remove failed", inf.Index)
			result <- api.NewResultBase(id, true, "not configured eth")
			return
		}

		var devChan chan VmEvent = make(chan VmEvent, 1)

		nc.sandbox.Log(DEBUG, "remove network card %d: %s", inf.Index, inf.IpAddr)
		nc.sandbox.DCtx.RemoveNic(nc.sandbox, inf, &NetDevRemovedEvent{Index: inf.Index}, devChan)

		go func() {
			ev, ok := <-devChan
			if !ok {
				return
			}

			success := true
			message := ""

			if fe, ok := ev.(*DeviceFailed); ok {
				success = false
				message = "unplug failed"
				if inf, ok := fe.Session.(*NetDevRemovedEvent); ok {
					nc.sandbox.Log(ERROR, "interface remove failed: %#v", inf)
				}
			}

			nc.slotLock.Lock()
			defer nc.slotLock.Unlock()
			nc.freeSlot(inf.Index)
			nc.cleanupInf(inf)

			result <- api.NewResultBase(id, success, message)
		}()
	}
}
Example #3
0
func (cc *ContainerContext) add(wgDisk *sync.WaitGroup, result chan api.Result) {
	wgDisk.Wait()
	for vn, vcs := range cc.Volumes {
		vol, ok := cc.sandbox.volumes[vn]
		if !ok || !vol.isReady() {
			cc.Log(ERROR, "vol %s is failed to insert", vn)
			result <- api.NewResultBase(cc.Id, false, "volume failed")
			return
		}

		for _, mp := range vcs.MountPoints {
			if vol.IsDir() {
				cc.Log(DEBUG, "volume (fs mapping) %s is ready", vn)
				cc.fsmap = append(cc.fsmap, &hyperstartapi.FsmapDescriptor{
					Source:       vol.Filename,
					Path:         mp.Path,
					ReadOnly:     mp.ReadOnly,
					DockerVolume: vol.DockerVolume,
				})
			} else {
				cc.Log(DEBUG, "volume (disk) %s is ready", vn)
				cc.vmVolumes = append(cc.vmVolumes, &hyperstartapi.VolumeDescriptor{
					Device:       vol.DeviceName,
					Addr:         vol.ScsiAddr,
					Mount:        mp.Path,
					Fstype:       vol.Fstype,
					ReadOnly:     mp.ReadOnly,
					DockerVolume: vol.DockerVolume,
				})
			}
		}
	}

	if !cc.root.isReady() {
		result <- api.NewResultBase(cc.Id, false, "root volume insert failed")
		return
	}

	if cc.sandbox.LogLevel(TRACE) {
		vmspec := cc.VmSpec()
		cc.Log(TRACE, "resource ready for container: %#v", vmspec)
	}

	cc.Log(INFO, "all images and volume resources have been added to sandbox")
	result <- api.NewResultBase(cc.Id, true, "")
}
Example #4
0
func (ctx *VmContext) RemoveVolume(name string, result chan<- api.Result) {
	ctx.lock.Lock()
	defer ctx.lock.Unlock()

	disk, ok := ctx.volumes[name]
	if !ok {
		ctx.Log(WARNING, "volume %s not exist", name)
		result <- api.NewResultBase(name, true, "not exist")
		return
	}

	if disk.containers() > 0 {
		ctx.Log(ERROR, "cannot remove a in use volume %s", name)
		result <- api.NewResultBase(name, false, "in use")
		return
	}

	ctx.Log(INFO, "remove disk %s", name)
	delete(ctx.volumes, name)
	disk.remove(result)
}
Example #5
0
File: disk.go Project: hyperhq/runv
func (dc *DiskContext) insert(result chan api.Result) {
	if result == nil {
		result = make(chan api.Result, 4)
	}
	if dc.isReady() {
		result <- api.NewResultBase(dc.Name, true, "already inserted")
		return
	}

	dc.ScsiId = dc.sandbox.nextScsiId()
	usage := "volume"
	if dc.isRootVol {
		usage = "image"
	}

	go func() {
		r := make(chan VmEvent, 4)
		dc.sandbox.DCtx.AddDisk(dc.sandbox, usage, dc.DiskDescriptor, r)

		ev, ok := <-r
		if !ok {
			dc.failed()
			result <- api.NewResultBase(dc.Name, false, "disk insert session broken")
			return
		}

		de, ok := ev.(*BlockdevInsertedEvent)
		if !ok {
			dc.failed()
			result <- api.NewResultBase(dc.Name, false, "disk insert failed")
			return
		}

		dc.DeviceName = de.DeviceName
		dc.ScsiAddr = de.ScsiAddr

		result <- api.NewResultBase(dc.Name, true, "")
		dc.inserted()
	}()
}
Example #6
0
File: vm.go Project: gnawux/runv
func (vm *Vm) Shutdown() api.Result {
	if vm.ctx.current != StateRunning {
		return api.NewResultBase(vm.Id, false, "not in running state")
	}
	Status, err := vm.GetResponseChan()
	if err != nil {
		return api.NewResultBase(vm.Id, false, "fail to get response chan")
	}
	defer vm.ReleaseResponseChan(Status)

	vm.Hub <- &ShutdownCommand{}
	for {
		Response, ok := <-Status
		if !ok {
			return api.NewResultBase(vm.Id, false, "status channel broken")
		}
		glog.V(1).Infof("Got response: %d: %s", Response.Code, Response.Cause)
		if Response.Code == types.E_VM_SHUTDOWN {
			return api.NewResultBase(vm.Id, true, "set sandbox config successfully")
		}
	}
}
Example #7
0
func (ctx *VmContext) AddVolume(vol *api.VolumeDescription, result chan api.Result) {
	ctx.lock.Lock()
	defer ctx.lock.Unlock()

	if _, ok := ctx.volumes[vol.Name]; ok {
		estr := fmt.Sprintf("duplicate volume %s", vol.Name)
		ctx.Log(WARNING, estr)
		result <- api.NewResultBase(vol.Name, true, estr)
		return
	}

	dc := NewDiskContext(ctx, vol)

	if vol.IsDir() {
		ctx.Log(INFO, "return volume add success for dir %s", vol.Name)
		result <- api.NewResultBase(vol.Name, true, "")
	} else {
		ctx.Log(DEBUG, "insert disk for volume %s", vol.Name)
		dc.insert(result)
	}

	ctx.volumes[vol.Name] = dc
}
Example #8
0
File: vm.go Project: gnawux/runv
func (vm *Vm) WaitInit() api.Result {
	Status, err := vm.GetResponseChan()
	if err != nil {
		vm.ctx.Log(ERROR, "failed to get status chan to monitor startpod: %v", err)
		return api.NewResultBase(vm.Id, false, err.Error())
	}
	defer vm.ReleaseResponseChan(Status)

	for {
		s, ok := <-Status
		if !ok {
			return api.NewResultBase(vm.Id, false, "status channel broken")
		}

		switch s.Code {
		case types.E_OK:
			return api.NewResultBase(vm.Id, true, "set sandbox config successfully")
		case types.E_FAILED, types.E_VM_SHUTDOWN:
			return api.NewResultBase(vm.Id, false, "set sandbox config failed")
		default:
			vm.ctx.Log(DEBUG, "got message %#v while waiting start pod command finish")
		}
	}
}
Example #9
0
func (ctx *VmContext) RemoveContainer(id string, result chan<- api.Result) {
	ctx.lock.Lock()
	defer ctx.lock.Unlock()

	cc, ok := ctx.containers[id]
	if !ok {
		ctx.Log(WARNING, "container %s not exist", id)
		result <- api.NewResultBase(id, true, "not exist")
		return
	}

	for v := range cc.Volumes {
		if vol, ok := ctx.volumes[v]; ok {
			vol.unwait(id)
		}
	}

	cc.root.unwait(id)

	ctx.Log(INFO, "remove container %s", id)
	delete(ctx.containers, id)
	cc.root.remove(result)
}