def discard_until(fd, s, deadline):
    """Read chunks from `fd` until one is encountered that ends with `s`. This
    is used to skip output produced by ``/etc/profile``, ``/etc/motd`` and
    mandatory SSH banners while waiting for :attr:`Stream.EC0_MARKER` to
    appear, indicating the first stage is ready to receive the compressed
    :mod:`mitogen.core` source.

    :param int fd:
        File descriptor to read from.
    :param bytes s:
        Marker string to discard until encountered.
    :param float deadline:
        Absolute UNIX timestamp after which timeout should occur.

    :raises mitogen.core.TimeoutError:
        Attempt to read beyond deadline.
    :raises mitogen.parent.EofError:
        All streams indicated EOF, suggesting the child process has exitted.
    :raises mitogen.core.StreamError:
        Attempt to read past end of file.
    """
    it = iter_read([fd], deadline)
    try:
        for buf in it:
            if IOLOG.level == logging.DEBUG:
                for line in buf.splitlines():
                    IOLOG.debug('discard_until: discarding %r', line)
            if buf.endswith(s):
                return
    finally:
        it.close()