import string def parse_meminfo(meminfo): dict = {} l1 = string.split(meminfo,"\n") for i in l1: l2 = string.split(i) if len(l2) >= 2: dict[string.rstrip(l2[0], ":")] = l2[1] try: for i in ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree'): val = int(dict[i])*1024 if (val < 0): return None dict[i] = val except: return None if dict['SwapTotal'] < dict['SwapFree']: return None return dict def is_suspicious(dom): ret = False if dom.meminfo['SwapTotal'] < dom.meminfo['SwapFree']: ret = True if dom.meminfo['MemTotal'] < dom.meminfo['MemFree'] + dom.meminfo['Cached'] + dom.meminfo['Buffers']: ret = True if ret: print 'suspicious meminfo for domain', dom.id, 'mem actual', dom.memory_actual, dom.meminfo return ret def refresh_meminfo_for_domain(dom, xenstore_key): meminfo = parse_meminfo(xenstore_key) dom.meminfo = meminfo if meminfo is None: return if is_suspicious(dom): dom.meminfo = None dom.mem_used = None else: dom.mem_used = dom.meminfo['MemTotal'] - dom.meminfo['MemFree'] - dom.meminfo['Cached'] - dom.meminfo['Buffers'] + dom.meminfo['SwapTotal'] - dom.meminfo['SwapFree'] def prefmem(dom): CACHE_FACTOR = 1.3 #dom0 is special, as it must have large cache, for vbds. Thus, give it a special boost if dom.id == '0': return dom.mem_used*CACHE_FACTOR + 350*1024*1024 return dom.mem_used*CACHE_FACTOR def memneeded(dom): #do not change #in balance(), "distribute totalsum proportionally to mempref" relies on this exact formula ret = prefmem(dom) - dom.memory_actual return ret def balloon(memsize, domdict): REQ_SAFETY_NET_FACTOR = 1.05 donors = list() request = list() available = 0 for i in domdict.keys(): if domdict[i].meminfo is None: continue if domdict[i].no_progress: continue need = memneeded(domdict[i]) if need < 0: print 'balloon: dom' , i, 'has actual memory', domdict[i].memory_actual donors.append((i,-need)) available-=need print 'req=', memsize, 'avail=', available, 'donors', donors if available