def service_loop(self): """start a RePCe server serving self's server stop servicing if a timeout is configured and got no keep-alime in that inteval """ if boolify(gconf.use_rsync_xattrs) and not privileged(): raise GsyncdError( "using rsync for extended attributes is not supported") repce = RepceServer(self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs)) t = syncdutils.Thread( target=lambda: (repce.service_loop(), syncdutils.finalize())) t.start() logging.info("slave listening") if gconf.timeout and int(gconf.timeout) > 0: while True: lp = self.server.last_keep_alive time.sleep(int(gconf.timeout)) if lp == self.server.last_keep_alive: logging.info( "connection inactive for %d seconds, stopping" % int(gconf.timeout)) break else: select((), (), ())
def __init__(self, obj, fd_tup): (inf, ouf, rw, ww) = fd_tup.split(',') repce = RepceServer(obj, int(inf), int(ouf), 1) t = syncdutils.Thread( target=lambda: (repce.service_loop(), syncdutils.finalize())) t.start() logging.info('Agent listining...') select((), (), ())
def service_loop(self): repce = RepceServer(self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs)) t = syncdutils.Thread(target=repce.service_loop) t.start() logging.info("slave listening") if gconf.timeout and int(gconf.timeout) > 0: while True: lp = self.server.last_keep_alive time.sleep(int(gconf.timeout)) if lp == self.server.last_keep_alive: logging.info( "connection inactive for %d seconds, stopping" % int(gconf.timeout)) break else: select.select((), (), ())
class Popen(subprocess.Popen): """customized subclass of subprocess.Popen with a ring buffer for children error output""" @classmethod def init_errhandler(cls): """start the thread which handles children's error output""" cls.errstore = {} def tailer(): while True: errstore = cls.errstore.copy() try: poe, _, _ = select([po.stderr for po in errstore], [], [], 1) except ValueError, selecterror: continue for po in errstore: if po.stderr not in poe: continue po.lock.acquire() try: if po.on_death_row: continue la = errstore[po] try: fd = po.stderr.fileno() except ValueError: # file is already closed continue l = os.read(fd, 1024) if not l: continue tots = len(l) for lx in la: tots += len(lx) while tots > 1 << 20 and la: tots -= len(la.pop(0)) la.append(l) finally: po.lock.release() t = syncdutils.Thread(target=tailer) t.start() cls.errhandler = t
def service_loop(self): """start a RePCe server serving self's server stop servicing if a timeout is configured and got no keep-alime in that inteval """ repce = RepceServer(self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs)) t = syncdutils.Thread( target=lambda: (repce.service_loop(), syncdutils.finalize())) t.start() logging.info("slave listening") if gconf.timeout and int(gconf.timeout) > 0: while True: lp = self.server.last_keep_alive time.sleep(int(gconf.timeout)) if lp == self.server.last_keep_alive: logging.info( "connection inactive for %d seconds, stopping" % int(gconf.timeout)) break else: select((), (), ())
def init_errhandler(cls): """start the thread which handles children's error output""" cls.errstore = {} def tailer(): while True: for po in select([po.stderr for po in cls.errstore], [], []): po.lock.acquire() try: la = cls.errstore.get(po) if la == None: continue l = os.read(po.stderr.fileno(), 1024) tots = len(l) for lx in la: tots += len(lx) while tots > 1 << 20 and la: tots -= len(la.pop(0)) finally: po.lock.release() t = syncdutils.Thread(target=tailer) t.start() cls.errhandler = t
def inhibit(self, *a): """inhibit a gluster filesystem Mount glusterfs over a temporary mountpoint, change into the mount, and lazy unmount the filesystem. """ mpi, mpo = os.pipe() mh = Popen.fork() if mh: os.close(mpi) fcntl.fcntl(mpo, fcntl.F_SETFD, fcntl.FD_CLOEXEC) d = None margv = self.make_mount_argv(*a) if self.mntpt: # mntpt is determined pre-mount d = self.mntpt os.write(mpo, d + '\0') po = Popen(margv, **self.mountkw) self.handle_mounter(po) po.terminate_geterr() logging.debug('auxiliary glusterfs mount in place') if not d: # mntpt is determined during mount d = self.mntpt os.write(mpo, d + '\0') os.write(mpo, 'M') t = syncdutils.Thread(target=lambda: os.chdir(d)) t.start() tlim = gconf.starttime + int(gconf.connection_timeout) while True: if not t.isAlive(): break if time.time() >= tlim: syncdutils.finalize(exval=1) time.sleep(1) os.close(mpo) _, rv = syncdutils.waitpid(mh, 0) if rv: rv = (os.WIFEXITED(rv) and os.WEXITSTATUS(rv) or 0) - \ (os.WIFSIGNALED(rv) and os.WTERMSIG(rv) or 0) logging.warn('stale mount possibly left behind on ' + d) raise GsyncdError("cleaning up temp mountpoint %s failed with status %d" % \ (d, rv)) else: rv = 0 try: os.setsid() os.close(mpo) mntdata = '' while True: c = os.read(mpi, 1) if not c: break mntdata += c if mntdata: mounted = False if mntdata[-1] == 'M': mntdata = mntdata[:-1] assert (mntdata) mounted = True assert (mntdata[-1] == '\0') mntpt = mntdata[:-1] assert (mntpt) if mounted: po = self.umount_l(mntpt) po.terminate_geterr(fail_on_err=False) if po.returncode != 0: po.errlog() rv = po.returncode self.cleanup_mntpt(mntpt) except: logging.exception('mount cleanup failure:') rv = 200 os._exit(rv) logging.debug('auxiliary glusterfs mount prepared')