Beispiel #1
0
def _helperMainLoop(pipe, lifeLine, parentLifelineFD, logQueue):
    os.close(parentLifelineFD)

    # Restoring signal handlers that might deadlock on prepareForShutdown
    # in the children.
    # This must be improved using pthread_sigmask before forking so that
    # we don't risk to have a race condition.
    for signum in (signal.SIGTERM, signal.SIGUSR1):
        signal.signal(signum, signal.SIG_DFL)

    # Close all file-descriptors we don't need
    # Logging won't work past this point
    FDSWHITELIST = (0, 1, 2, lifeLine, parentLifelineFD, pipe.fileno(),
                     logQueue._reader.fileno(), logQueue._writer.fileno())

    for fd in misc.getfds():
        if fd not in FDSWHITELIST:
            try:
                os.close(fd)
            except OSError:
                pass    # Nothing we can do

    _setUpLogging(logQueue)

    poller = select.poll()
    poller.register(lifeLine, 0) # Only SIGERR\SIGHUP
    poller.register(pipe.fileno(), select.EPOLLIN | select.EPOLLPRI)

    try:
        while True:

            for (fd, event) in poller.poll():
                # If something happened in lifeLine, it means that papa is gone
                # and we should go as well
                if fd == lifeLine or event in (select.EPOLLHUP, select.EPOLLERR):
                    return

            func, args, kwargs = pipe.recv()
            threading.current_thread().setName(kwargs[LOGGING_THREAD_NAME])
            kwargs.pop(LOGGING_THREAD_NAME)
            res = err = None
            try:
                res = func(*args, **kwargs)
            except KeyboardInterrupt as ex:
                err = ex
            except Exception as ex:
                err = ex

            pipe.send((res, err))
    except:
        # If for some reason communication with the host failed crash silently
        # There is no logging in oop and VDSM will handle it.
        pass
Beispiel #2
0
def closeFDs(whitelist):
    for fd in misc.getfds():
        if fd in whitelist:
            continue

        while True:
            try:
                os.close(fd)
                break
            except (OSError, IOError) as e:
                if e.errno in (errno.EINTR, errno.EAGAIN):
                    continue

                if e.errno == errno.EBADF:
                    break

                raise
Beispiel #3
0
def closeFDs(whitelist):
    for fd in misc.getfds():
        if fd in whitelist:
            continue

        while True:
            try:
                os.close(fd)
                break
            except (OSError, IOError) as e:
                if e.errno in (errno.EINTR, errno.EAGAIN):
                    continue

                if e.errno == errno.EBADF:
                    break

                raise
Beispiel #4
0
def _helperMainLoop(pipe, lifeLine, parentLifelineFD, logQueue):
    os.close(parentLifelineFD)

    # Restoring signal handlers that might deadlock on prepareForShutdown
    # in the children.
    # This must be improved using pthread_sigmask before forking so that
    # we don't risk to have a race condition.
    for signum in (signal.SIGTERM, signal.SIGUSR1):
        signal.signal(signum, signal.SIG_DFL)

    # Removing all the handlers from the loggers. This avoid a deadlock on
    # the logging locks. Multi-process and multi-threading don't mix well.
    #   - BZ#732652: https://bugzilla.redhat.com/show_bug.cgi?id=732652
    #   - I6721: http://bugs.python.org/issue6721
    for log in logging.Logger.manager.loggerDict.values():
        if hasattr(log, 'handlers'): del log.handlers[:]

    # Close all file-descriptors we don't need
    # Logging won't work past this point
    FDSWHITELIST = (0, 1, 2, lifeLine, parentLifelineFD, pipe.fileno(),
                    logQueue._reader.fileno(), logQueue._writer.fileno())
    for fd in misc.getfds():
        if fd not in FDSWHITELIST:
            try:
                os.close(fd)
            except OSError:
                pass  # Nothing we can do

    # Add logger handler (via Queue)
    hdlr = QueueHandler(logQueue)
    hdlr.setLevel(_log.getEffectiveLevel())
    logging.root.handlers = [hdlr]
    for log in logging.Logger.manager.loggerDict.values():
        if hasattr(log, 'handlers'): log.handlers.append(hdlr)

    poller = select.poll()
    poller.register(lifeLine, 0)  # Only SIGERR\SIGHUP
    poller.register(pipe.fileno(), select.EPOLLIN | select.EPOLLPRI)

    try:
        while True:

            for (fd, event) in poller.poll():
                # If something happened in lifeLine, it means that papa is gone
                # and we should go as well
                if fd == lifeLine or event in (select.EPOLLHUP,
                                               select.EPOLLERR):
                    return

            func, args, kwargs = pipe.recv()
            threading.current_thread().setName(kwargs[LOGGING_THREAD_NAME])
            kwargs.pop(LOGGING_THREAD_NAME)
            res = err = None
            try:
                res = func(*args, **kwargs)
            except KeyboardInterrupt as ex:
                err = ex
            except Exception as ex:
                err = ex

            pipe.send((res, err))
    except:
        # If for some reason communication with the host failed crash silently
        # There is no logging in oop and VDSM will handle it.
        pass
Beispiel #5
0
def _helperMainLoop(pipe, lifeLine, parentLifelineFD, logQueue):
    os.close(parentLifelineFD)

    # Restoring signal handlers that might deadlock on prepareForShutdown
    # in the children.
    # This must be improved using pthread_sigmask before forking so that
    # we don't risk to have a race condition.
    for signum in (signal.SIGTERM, signal.SIGUSR1):
        signal.signal(signum, signal.SIG_DFL)

    # Removing all the handlers from the loggers. This avoid a deadlock on
    # the logging locks. Multi-process and multi-threading don't mix well.
    #   - BZ#732652: https://bugzilla.redhat.com/show_bug.cgi?id=732652
    #   - I6721: http://bugs.python.org/issue6721
    for log in logging.Logger.manager.loggerDict.values():
        if hasattr(log, 'handlers'): del log.handlers[:]

    # Close all file-descriptors we don't need
    # Logging won't work past this point
    FDSWHITELIST = (0, 1, 2, lifeLine, parentLifelineFD, pipe.fileno(),
                     logQueue._reader.fileno(), logQueue._writer.fileno())
    for fd in misc.getfds():
        if fd not in FDSWHITELIST:
            try:
                os.close(fd)
            except OSError:
                pass    # Nothing we can do

    # Add logger handler (via Queue)
    hdlr = QueueHandler(logQueue)
    hdlr.setLevel(_log.getEffectiveLevel())
    logging.root.handlers = [hdlr]
    for log in logging.Logger.manager.loggerDict.values():
        if hasattr(log, 'handlers'): log.handlers.append(hdlr)

    poller = select.poll()
    poller.register(lifeLine, 0) # Only SIGERR\SIGHUP
    poller.register(pipe.fileno(), select.EPOLLIN | select.EPOLLPRI)

    try:
        while True:

            for (fd, event) in poller.poll():
                # If something happened in lifeLine, it means that papa is gone
                # and we should go as well
                if fd == lifeLine or event in (select.EPOLLHUP, select.EPOLLERR):
                    return

            func, args, kwargs = pipe.recv()
            threading.current_thread().setName(kwargs[LOGGING_THREAD_NAME])
            kwargs.pop(LOGGING_THREAD_NAME)
            res = err = None
            try:
                res = func(*args, **kwargs)
            except KeyboardInterrupt as ex:
                err = ex
            except Exception as ex:
                err = ex

            pipe.send((res, err))
    except:
        # If for some reason communication with the host failed crash silently
        # There is no logging in oop and VDSM will handle it.
        pass