def cleanup_stale_sentinel_fifos(): for path in glob.glob(sentinel_path_prefix + '*.fifo'): if path in sentinel_fifos_inuse: continue try: os.unlink(path) except OSError, e: log.warning('could not delete stale fifo %s: %s', path, utils.exception_string(e))
def _sentinel_watch(self): log.info("waiting for sentinel_fifo") try: self.sentinel_fifo.read(1) except OSError, e: pass self.sentinel_lock.acquire() if self.pid: try: (p,st) = os.waitpid(self.pid, os.WNOHANG) if p == self.pid: message = oshelp.waitstatus_description(st) else: # obviously it is malfunctioning, kill it now try: os.kill(self.pid, signal.SIGKILL) message = "malfunctioning (closed sentinel), killed" except: message = "malfunctioning or died ?" message = "pid %d: %s" % (self.pid, message) except Exception, e: message = "waitpid failed: %s" % utils.exception_string(e) message = "device model failure: %s" % message try: message += "; see %s " % self.logfile except: pass self._dmfailed(message) self.pid = None
def createXenPaging(self): if not self.vm.info.is_hvm(): return if self.actmem == "0": return if self.xenpaging_pid: return xenpaging_bin = auxbin.pathTo("xenpaging") args = [xenpaging_bin] args = args + ([ "-f", "/var/lib/xen/xenpaging/%s.%d.paging" % (str(self.vm.info['name_label']), self.vm.getDomid())]) if self.xenpaging_extra: args = args + (self.xenpaging_extra) args = args + ([ "-d", "%d" % self.vm.getDomid()]) self.xenpaging_logfile = "/var/log/xen/xenpaging-%s.log" % str(self.vm.info['name_label']) logfile_mode = os.O_WRONLY|os.O_CREAT|os.O_APPEND|os.O_TRUNC null = os.open("/dev/null", os.O_RDONLY) try: os.unlink(self.xenpaging_logfile) except: pass logfd = os.open(self.xenpaging_logfile, logfile_mode, 0644) sys.stderr.flush() contract = osdep.prefork("%s:%d" % (self.vm.getName(), self.vm.getDomid())) xenpaging_pid = os.fork() if xenpaging_pid == 0: #child try: osdep.postfork(contract) os.dup2(null, 0) os.dup2(logfd, 1) os.dup2(logfd, 2) try: env = dict(os.environ) log.info("starting %s" % args) os.execve(xenpaging_bin, args, env) except Exception, e: log.warn('failed to execute xenpaging: %s' % utils.exception_string(e)) os._exit(126) except: log.warn("starting xenpaging failed") os._exit(127) else: osdep.postfork(contract, abandon=True) self.xenpaging_pid = xenpaging_pid os.close(null) os.close(logfd) self.vm.storeDom("xenpaging/xenpaging-pid", self.xenpaging_pid) self.vm.storeDom("memory/target-tot_pages", int(self.actmem) * 1024)
def _sentinel_watch(self): log.info("waiting for sentinel_fifo") try: self.sentinel_fifo.read(1) except OSError, e: pass self.sentinel_lock.acquire() try: if self.pid: (p,st) = os.waitpid(self.pid, os.WNOHANG) if p == self.pid: message = oshelp.waitstatus_description(st) else: # obviously it is malfunctioning, kill it now try: os.kill(self.pid, signal.SIGKILL) message = "malfunctioning (closed sentinel), killed" except: message = "malfunctioning or died ?" message = "pid %d: %s" % (self.pid, message) else: message = "no longer running" except Exception, e: message = "waitpid failed: %s" % utils.exception_string(e)
def createDeviceModel(self, restore = False): if self.device_model is None: return if self.pid: return # Execute device model. #todo: Error handling args = self.getDeviceModelArgs(restore) env = dict(os.environ) if self.display: env['DISPLAY'] = self.display if self.xauthority: env['XAUTHORITY'] = self.xauthority unique_id = "%i-%i" % (self.vm.getDomid(), time.time()) sentinel_path = sentinel_path_prefix + unique_id sentinel_path_fifo = sentinel_path + '.fifo' os.mkfifo(sentinel_path_fifo, 0600) sentinel_write = file(sentinel_path_fifo, 'r+') self._openSentinel(sentinel_path_fifo) self.vm.storeDom("image/device-model-fifo", sentinel_path_fifo) xstransact.Mkdir("/local/domain/0/device-model/%i" % self.vm.getDomid()) xstransact.SetPermissions("/local/domain/0/device-model/%i" % self.vm.getDomid(), { 'dom': self.vm.getDomid(), 'read': True, 'write': True }) log.info("spawning device models: %s %s", self.device_model, args) # keep track of pid and spawned options to kill it later self.logfile = "/var/log/xen/qemu-dm-%s.log" % str(self.vm.info['name_label']) # rotate log logfile_mode = os.O_WRONLY|os.O_CREAT|os.O_APPEND logrotate_count = XendOptions.instance().get_qemu_dm_logrotate_count() if logrotate_count > 0: logfile_mode |= os.O_TRUNC if os.path.exists("%s.%d" % (self.logfile, logrotate_count)): os.unlink("%s.%d" % (self.logfile, logrotate_count)) for n in range(logrotate_count - 1, 0, -1): if os.path.exists("%s.%d" % (self.logfile, n)): os.rename("%s.%d" % (self.logfile, n), "%s.%d" % (self.logfile, (n + 1))) if os.path.exists(self.logfile): os.rename(self.logfile, self.logfile + ".1") null = os.open("/dev/null", os.O_RDONLY) logfd = os.open(self.logfile, logfile_mode, 0666) sys.stderr.flush() contract = osdep.prefork("%s:%d" % (self.vm.getName(), self.vm.getDomid())) pid = os.fork() if pid == 0: #child try: osdep.postfork(contract) os.dup2(null, 0) os.dup2(logfd, 1) os.dup2(logfd, 2) oshelp.close_fds((sentinel_write.fileno(),)) try: os.execve(self.device_model, args, env) except Exception, e: print >>sys.stderr, ( 'failed to set up fds or execute dm %s: %s' % (self.device_model, utils.exception_string(e))) os._exit(126) except: os._exit(127) else: osdep.postfork(contract, abandon=True) self.pid = pid os.close(null) os.close(logfd) sentinel_write.close() self.vm.storeDom("image/device-model-pid", self.pid) log.info("device model pid: %d", self.pid) # we would very much prefer not to have a thread here and instead # have a callback but sadly we don't have Twisted in xend self.sentinel_thread = thread.start_new_thread(self._sentinel_watch,()) if self.device_model.find('stubdom-dm') > -1 : from xen.xend import XendDomain domains = XendDomain.instance() domains.domains_lock.release() count = 0 while True: orig_state = xstransact.Read("/local/domain/0/device-model/%i/state" % self.vm.getDomid()) # This can occur right after start-up if orig_state != None: break log.debug('createDeviceModel %i: orig_state is None, retrying' % self.vm.getDomid()) time.sleep(0.1) count += 1 if count > 100: break domains.domains_lock.acquire()
self.sentinel_lock.acquire() if self.pid: try: (p, st) = os.waitpid(self.pid, os.WNOHANG) if p == self.pid: message = oshelp.waitstatus_description(st) else: # obviously it is malfunctioning, kill it now try: os.kill(self.pid, signal.SIGKILL) message = "malfunctioning (closed sentinel), killed" except: message = "malfunctioning or died ?" message = "pid %d: %s" % (self.pid, message) except Exception, e: message = "waitpid failed: %s" % utils.exception_string(e) message = "device model failure: %s" % message try: message += "; see %s " % self.logfile except: pass self._dmfailed(message) self.pid = None else: log.info("%s device model terminated", self.vm.getName()) self.sentinel_lock.release() def destroyDeviceModel(self): if self.device_model is None: return self.sentinel_lock.acquire()
def createDeviceModel(self, restore=False): if self.device_model is None: return if self.pid: return # Execute device model. #todo: Error handling args = self.getDeviceModelArgs(restore) env = dict(os.environ) if self.display: env['DISPLAY'] = self.display if self.xauthority: env['XAUTHORITY'] = self.xauthority unique_id = "%i-%i" % (self.vm.getDomid(), time.time()) sentinel_path = sentinel_path_prefix + unique_id sentinel_path_fifo = sentinel_path + '.fifo' os.mkfifo(sentinel_path_fifo, 0600) sentinel_write = file(sentinel_path_fifo, 'r+') self._openSentinel(sentinel_path_fifo) self.vm.storeDom("image/device-model-fifo", sentinel_path_fifo) xstransact.Mkdir("/local/domain/0/device-model/%i" % self.vm.getDomid()) xstransact.SetPermissions( "/local/domain/0/device-model/%i" % self.vm.getDomid(), { 'dom': self.vm.getDomid(), 'read': True, 'write': True }) log.info("spawning device models: %s %s", self.device_model, args) # keep track of pid and spawned options to kill it later self.logfile = "/var/log/xen/qemu-dm-%s.log" % str( self.vm.info['name_label']) # rotate log logfile_mode = os.O_WRONLY | os.O_CREAT | os.O_APPEND logrotate_count = XendOptions.instance().get_qemu_dm_logrotate_count() if logrotate_count > 0: logfile_mode |= os.O_TRUNC if os.path.exists("%s.%d" % (self.logfile, logrotate_count)): os.unlink("%s.%d" % (self.logfile, logrotate_count)) for n in range(logrotate_count - 1, 0, -1): if os.path.exists("%s.%d" % (self.logfile, n)): os.rename("%s.%d" % (self.logfile, n), "%s.%d" % (self.logfile, (n + 1))) if os.path.exists(self.logfile): os.rename(self.logfile, self.logfile + ".1") null = os.open("/dev/null", os.O_RDONLY) logfd = os.open(self.logfile, logfile_mode, 0666) sys.stderr.flush() contract = osdep.prefork("%s:%d" % (self.vm.getName(), self.vm.getDomid())) pid = os.fork() if pid == 0: #child try: osdep.postfork(contract) os.dup2(null, 0) os.dup2(logfd, 1) os.dup2(logfd, 2) oshelp.close_fds((sentinel_write.fileno(), )) try: os.execve(self.device_model, args, env) except Exception, e: print >> sys.stderr, ( 'failed to set up fds or execute dm %s: %s' % (self.device_model, utils.exception_string(e))) os._exit(126) except: os._exit(127) else: osdep.postfork(contract, abandon=True) self.pid = pid os.close(null) os.close(logfd) sentinel_write.close() self.vm.storeDom("image/device-model-pid", self.pid) log.info("device model pid: %d", self.pid) # we would very much prefer not to have a thread here and instead # have a callback but sadly we don't have Twisted in xend self.sentinel_thread = thread.start_new_thread(self._sentinel_watch, ()) if self.device_model.find('stubdom-dm') > -1: from xen.xend import XendDomain domains = XendDomain.instance() domains.domains_lock.release() count = 0 while True: orig_state = xstransact.Read( "/local/domain/0/device-model/%i/state" % self.vm.getDomid()) # This can occur right after start-up if orig_state != None: break log.debug( 'createDeviceModel %i: orig_state is None, retrying' % self.vm.getDomid()) time.sleep(0.1) count += 1 if count > 100: break domains.domains_lock.acquire()
def createDeviceModel(self, restore = False): if self.device_model is None: return if self.pid: return # Execute device model. #todo: Error handling args = self.getDeviceModelArgs(restore) env = dict(os.environ) if self.display: env['DISPLAY'] = self.display if self.xauthority: env['XAUTHORITY'] = self.xauthority if self.vncconsole: args = args + ([ "-vncviewer" ]) unique_id = "%i-%i" % (self.vm.getDomid(), time.time()) sentinel_path = sentinel_path_prefix + unique_id sentinel_path_fifo = sentinel_path + '.fifo' os.mkfifo(sentinel_path_fifo, 0600) sentinel_write = file(sentinel_path_fifo, 'r+') self._openSentinel(sentinel_path_fifo) self.vm.storeDom("image/device-model-fifo", sentinel_path_fifo) xstransact.Mkdir("/local/domain/0/device-model/%i" % self.vm.getDomid()) xstransact.SetPermissions("/local/domain/0/device-model/%i" % self.vm.getDomid(), { 'dom': self.vm.getDomid(), 'read': True, 'write': True }) log.info("spawning device models: %s %s", self.device_model, args) # keep track of pid and spawned options to kill it later self.logfile = "/var/log/xen/qemu-dm-%s.log" % str(self.vm.info['name_label']) # rotate log logfile_mode = os.O_WRONLY|os.O_CREAT|os.O_APPEND logrotate_count = XendOptions.instance().get_qemu_dm_logrotate_count() if logrotate_count > 0: logfile_mode |= os.O_TRUNC if os.path.exists("%s.%d" % (self.logfile, logrotate_count)): os.unlink("%s.%d" % (self.logfile, logrotate_count)) for n in range(logrotate_count - 1, 0, -1): if os.path.exists("%s.%d" % (self.logfile, n)): os.rename("%s.%d" % (self.logfile, n), "%s.%d" % (self.logfile, (n + 1))) if os.path.exists(self.logfile): os.rename(self.logfile, self.logfile + ".1") null = os.open("/dev/null", os.O_RDONLY) logfd = os.open(self.logfile, logfile_mode) sys.stderr.flush() pid = os.fork() if pid == 0: #child try: os.dup2(null, 0) os.dup2(logfd, 1) os.dup2(logfd, 2) os.close(null) os.close(logfd) self.sentinel_fifo.close() try: os.execve(self.device_model, args, env) except Exception, e: print >>sys.stderr, ( 'failed to set up fds or execute dm %s: %s' % (self.device_model, utils.exception_string(e))) os._exit(126) except: os._exit(127) else: self.pid = pid os.close(null) os.close(logfd) sentinel_write.close() self.vm.storeDom("image/device-model-pid", self.pid) log.info("device model pid: %d", self.pid) # we would very much prefer not to have a thread here and instead # have a callback but sadly we don't have Twisted in xend self.sentinel_thread = thread.start_new_thread(self._sentinel_watch,())