mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
Today the file descriptor for the access of the event channel driver is being closed in case of exec(2). For the support of live update of a daemon using libxenevtchn this can be problematic, so add a way to keep that file descriptor open. Add support of a flag XENEVTCHN_NO_CLOEXEC for xenevtchn_open() which will result in _not_ setting O_CLOEXEC when opening the event channel driver node. The caller can then obtain the file descriptor via xenevtchn_fd(). Add an alternative open function xenevtchn_fdopen() which takes that file descriptor as an additional parameter. This allows to allocate a xenevtchn_handle and to associate it with that file descriptor. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Wei Liu <wl@xen.org> Reviewed-by: Julien Grall <jgrall@amazon.com>
187 lines
6.0 KiB
C
187 lines
6.0 KiB
C
/*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation;
|
|
* version 2.1 of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Split off from:
|
|
* xenctrl.h
|
|
*
|
|
* A library for low-level access to the Xen control interfaces.
|
|
*
|
|
* Copyright (c) 2003-2004, K A Fraser.
|
|
*/
|
|
|
|
#ifndef XENEVTCHN_H
|
|
#define XENEVTCHN_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <xen/event_channel.h>
|
|
|
|
/* A port identifier is guaranteed to fit in 31 bits. */
|
|
typedef int xenevtchn_port_or_error_t;
|
|
|
|
typedef struct xenevtchn_handle xenevtchn_handle;
|
|
|
|
/* Callers who don't care don't need to #include <xentoollog.h> */
|
|
struct xentoollog_logger;
|
|
|
|
/*
|
|
* EVENT CHANNEL FUNCTIONS
|
|
*
|
|
* None of these do any logging.
|
|
*/
|
|
|
|
/*
|
|
* Opens the evtchn device node. Return a handle to the event channel
|
|
* driver, or NULL on failure, in which case errno will be set
|
|
* appropriately.
|
|
*
|
|
* On fork(2):
|
|
*
|
|
* After fork, a child process must not use any opened evtchn handle
|
|
* inherited from their parent. This includes operations such as
|
|
* poll() on the underlying file descriptor. Calling xenevtchn_close()
|
|
* is the only safe operation on a xenevtchn_handle which has been
|
|
* inherited.
|
|
*
|
|
* The child must open a new handle if they want to interact with
|
|
* evtchn.
|
|
*
|
|
* On exec(2):
|
|
*
|
|
* Wherever possible, the device node will be opened with O_CLOEXEC,
|
|
* so it is not inherited by the subsequent program.
|
|
*
|
|
* However the XENEVTCHN_NO_CLOEXEC flag may be used to avoid opening
|
|
* the device node with O_CLOEXEC. This is intended for use by
|
|
* daemons which support a self-reexec method of updating themselves.
|
|
*
|
|
* In this case, the updated daemon should pass the underlying file
|
|
* descriptor it inherited to xenevtchn_fdopen() to reconstruct the
|
|
* library handle.
|
|
*/
|
|
|
|
/* Don't set O_CLOEXEC when opening event channel driver node. */
|
|
#define XENEVTCHN_NO_CLOEXEC (1 << 0)
|
|
|
|
xenevtchn_handle *xenevtchn_open(struct xentoollog_logger *logger,
|
|
unsigned int flags);
|
|
|
|
/* Flag XENEVTCHN_NO_CLOEXEC is rejected by xenevtchn_fdopen(). */
|
|
xenevtchn_handle *xenevtchn_fdopen(struct xentoollog_logger *logger,
|
|
int fd, unsigned open_flags);
|
|
|
|
/*
|
|
* Close a handle previously allocated with xenevtchn_{,fd}open().
|
|
*/
|
|
int xenevtchn_close(xenevtchn_handle *xce);
|
|
|
|
/*
|
|
* Return an fd that can be select()ed on.
|
|
*
|
|
* Note that due to bugs, setting this fd to non blocking may not
|
|
* work: you would hope that it would result in xenevtchn_pending
|
|
* failing with EWOULDBLOCK if there are no events signaled, but in
|
|
* fact it may block. (Bug is present in at least Linux 3.12, and
|
|
* perhaps on other platforms or later version.)
|
|
*
|
|
* To be safe, you must use poll() or select() before each call to
|
|
* xenevtchn_pending. If you have multiple threads (or processes)
|
|
* sharing a single xce handle this will not work, and there is no
|
|
* straightforward workaround. Please design your program some other
|
|
* way.
|
|
*/
|
|
int xenevtchn_fd(xenevtchn_handle *xce);
|
|
|
|
/*
|
|
* Notify the given event channel. Returns -1 on failure, in which case
|
|
* errno will be set appropriately.
|
|
*/
|
|
int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port);
|
|
|
|
/*
|
|
* Returns a new event port awaiting interdomain connection from the given
|
|
* domain ID, or -1 on failure, in which case errno will be set appropriately.
|
|
*/
|
|
xenevtchn_port_or_error_t
|
|
xenevtchn_bind_unbound_port(xenevtchn_handle *xce, uint32_t domid);
|
|
|
|
/*
|
|
* Returns a new event port bound to the remote port for the given domain ID,
|
|
* or -1 on failure, in which case errno will be set appropriately.
|
|
*/
|
|
xenevtchn_port_or_error_t
|
|
xenevtchn_bind_interdomain(xenevtchn_handle *xce, uint32_t domid,
|
|
evtchn_port_t remote_port);
|
|
|
|
/*
|
|
* Bind an event channel to the given VIRQ. Returns the event channel bound to
|
|
* the VIRQ, or -1 on failure, in which case errno will be set appropriately.
|
|
*/
|
|
xenevtchn_port_or_error_t
|
|
xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq);
|
|
|
|
/*
|
|
* Unbind the given event channel. Returns -1 on failure, in which case errno
|
|
* will be set appropriately.
|
|
*/
|
|
int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port);
|
|
|
|
/*
|
|
* Return the next event channel to become pending, or -1 on failure, in which
|
|
* case errno will be set appropriately.
|
|
*
|
|
* At the hypervisor level the event channel will have been masked,
|
|
* and then cleared, by the underlying machinery (evtchn kernel
|
|
* driver, or equivalent). So if the event channel is signaled again
|
|
* after it is returned here, it will be queued up, and delivered
|
|
* again after you unmask it. (See the documentation in the Xen
|
|
* public header event_channel.h.)
|
|
*
|
|
* On receiving the notification from xenevtchn_pending, you should
|
|
* normally: check (by other means) what work needs doing; do the
|
|
* necessary work (if any); unmask the event channel with
|
|
* xenevtchn_unmask (if you want to receive any further
|
|
* notifications).
|
|
*/
|
|
xenevtchn_port_or_error_t
|
|
xenevtchn_pending(xenevtchn_handle *xce);
|
|
|
|
/*
|
|
* Unmask the given event channel. Returns -1 on failure, in which case errno
|
|
* will be set appropriately.
|
|
*/
|
|
int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port);
|
|
|
|
/**
|
|
* This function restricts the use of this handle to the specified
|
|
* domain.
|
|
*
|
|
* @parm xce handle to the open evtchn interface
|
|
* @parm domid the domain id
|
|
* @return 0 on success, -1 on failure with errno set appropriately.
|
|
*/
|
|
int xenevtchn_restrict(xenevtchn_handle *xce, domid_t domid);
|
|
|
|
#endif
|
|
|
|
/*
|
|
* Local variables:
|
|
* mode: C
|
|
* c-file-style: "BSD"
|
|
* c-basic-offset: 4
|
|
* tab-width: 4
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*/
|