diff --git a/deployment/extensions/gc-emulator-service/Service.go b/deployment/extensions/gc-emulator-service/Service.go index a8d28b9..7998157 100644 --- a/deployment/extensions/gc-emulator-service/Service.go +++ b/deployment/extensions/gc-emulator-service/Service.go @@ -27,6 +27,7 @@ func main() { router := gin.Default() router.POST("/gc/begin", manager.Begin) router.GET("/gc/is-asleep", manager.IsAsleep) + router.GET("/gc/core-usage", manager.GetCoreUsage) router.POST("/gc/dev/switch", manager.Switch) err = router.Run("100.64.42.11:4000") diff --git a/deployment/extensions/gc-emulator-service/internal/apis.go b/deployment/extensions/gc-emulator-service/internal/apis.go index 7ba1eaa..a35f179 100644 --- a/deployment/extensions/gc-emulator-service/internal/apis.go +++ b/deployment/extensions/gc-emulator-service/internal/apis.go @@ -61,3 +61,13 @@ func (o *GreenCoreMgt) Switch(c *gin.Context) { IsAwake: o.IsGreenCoreAwake, }) } + +func (o *GreenCoreMgt) GetCoreUsage(c *gin.Context) { + + usages, err := o.obtainCoreUsage() + if err != nil { + c.JSON(http.StatusInternalServerError, "Something went wrong. Check admin logs.") + return + } + c.IndentedJSON(http.StatusOK, usages) +} diff --git a/deployment/extensions/gc-emulator-service/internal/config-parser.go b/deployment/extensions/gc-emulator-service/internal/config-parser.go index 4b24d65..ea65789 100644 --- a/deployment/extensions/gc-emulator-service/internal/config-parser.go +++ b/deployment/extensions/gc-emulator-service/internal/config-parser.go @@ -10,6 +10,7 @@ type ComputeHost struct { Ip string `yaml:"ip"` User string `yaml:"user"` DynamicCoreIds []int `yaml:"dynamic-core-ids"` + StableCoreIds []int `yaml:"stable-core-ids"` } type ConfYaml struct { diff --git a/deployment/extensions/gc-emulator-service/internal/inspect.go b/deployment/extensions/gc-emulator-service/internal/inspect.go new file mode 100644 index 0000000..4cf82b9 --- /dev/null +++ b/deployment/extensions/gc-emulator-service/internal/inspect.go @@ -0,0 +1,56 @@ +package internal + +import ( + "fmt" + "slices" + "strconv" + "strings" +) + +func (o *GreenCoreMgt) obtainCoreUsage() ([]HostCoreUsage, error) { + + var hostCoreUsages []HostCoreUsage + for _, host := range o.conf.ComputeHosts { + var hostCoreUsage HostCoreUsage + hostCoreUsage.Ip = host.Ip + + var usedDynamicCores []int + var usedStableCores []int + + var domains []domainsVirshModel + err := RunThirdPartyClient[domainsVirshModel](&domains, "virsh-list-domains.sh", host.User, host.Ip) + if err != nil { + return nil, err + } + for _, domain := range domains { + var cpuAffinities []emulatorPinVirshModel + err := RunThirdPartyClient[emulatorPinVirshModel](&cpuAffinities, "virsh-domain-get-pinned-cpu-core.sh", host.User, host.Ip, domain.Name) + if err != nil { + return nil, err + } + for _, cpuAffinity := range cpuAffinities { + pinnedCore, _ := strconv.Atoi(strings.Split(cpuAffinity.EmulatorCPUAffinity, "*: ")[1]) + if slices.Contains(host.DynamicCoreIds, pinnedCore) { + usedDynamicCores = append(usedDynamicCores, pinnedCore) + } + if slices.Contains(host.StableCoreIds, pinnedCore) { + usedStableCores = append(usedStableCores, pinnedCore) + } + } + } + + hostCoreUsage.RegCoresAvl = len(host.StableCoreIds) + hostCoreUsage.RegCoresUsg = len(usedStableCores) + if o.IsGreenCoreAwake { + hostCoreUsage.GreenCoresAvl = len(host.DynamicCoreIds) + hostCoreUsage.GreenCoresUsg = len(usedDynamicCores) + } else { + hostCoreUsage.GreenCoresAvl = 0 + hostCoreUsage.GreenCoresUsg = 0 + } + hostCoreUsages = append(hostCoreUsages, hostCoreUsage) + + fmt.Printf("core usage for %s is %+v\\n\n", host.Ip, hostCoreUsage) + } + return hostCoreUsages, nil +} diff --git a/deployment/extensions/gc-emulator-service/internal/models.go b/deployment/extensions/gc-emulator-service/internal/models.go index 1bfe005..3578222 100644 --- a/deployment/extensions/gc-emulator-service/internal/models.go +++ b/deployment/extensions/gc-emulator-service/internal/models.go @@ -15,3 +15,11 @@ type emulatorPinVirshModel struct { type GcStatus struct { IsAwake bool `json:"is-awake"` } + +type HostCoreUsage struct { + Ip string `json:"host-ip"` + RegCoresAvl int `json:"reg-cores-avl"` + RegCoresUsg int `json:"reg-cores-usg"` + GreenCoresAvl int `json:"green-cores-avl"` + GreenCoresUsg int `json:"green-cores-usg"` +} diff --git a/experiment/trace-generation/openstack_client.py b/experiment/trace-generation/openstack_client.py index 185482a..dccdbcb 100644 --- a/experiment/trace-generation/openstack_client.py +++ b/experiment/trace-generation/openstack_client.py @@ -33,7 +33,7 @@ def create_vm(vm): print('attempting to create vm: ', vm['name']) try: cmd = "openstack server create --nic net-id=\"public\" --image \"cirros-0.6.2-x86_64-disk\" --flavor \"pinned.vcpu-" + str( - round(vm['vcpu'])) + "\" \"" + vm['name'] + "\" --wait " + round(vm['vcpu'])) + "\" \"" + vm['name'] + "\" --wait --hint type="+vm['type']+" " returned_output = subprocess.check_output(cmd, shell=True) print('vm creation for vm:', vm, returned_output.decode("utf-8")) return True