libxl__domain_suspend_state *dss, int rc)
{
STATE_AO_GC(dss->ao);
+ int flrc;
+
+ flrc = libxl__fd_flags_restore(gc, dss->fd, dss->fdfl);
+ /* If suspend has failed already then report that error not this one. */
+ if (flrc && !rc) rc = flrc;
+
libxl__ao_complete(egc,ao,rc);
}
dss->live = flags & LIBXL_SUSPEND_LIVE;
dss->debug = flags & LIBXL_SUSPEND_DEBUG;
+ rc = libxl__fd_flags_modify_save(gc, dss->fd,
+ ~(O_NONBLOCK|O_NDELAY), 0,
+ &dss->fdfl);
+ if (rc < 0) goto out_err;
+
libxl__domain_save(egc, dss);
return AO_INPROGRESS;
int libxl_fd_set_nonblock(libxl_ctx *ctx, int fd, int nonblock)
{ return fd_set_flags(ctx,fd, F_GETFL,F_SETFL,"FL", O_NONBLOCK, nonblock); }
+int libxl__fd_flags_modify_save(libxl__gc *gc, int fd,
+ int mask, int val, int *r_oldflags)
+{
+ int rc, ret, fdfl;
+
+ fdfl = fcntl(fd, F_GETFL);
+ if (fdfl < 0) {
+ LOGE(ERROR, "failed to fcntl.F_GETFL for fd %d", fd);
+ rc = ERROR_FAIL;
+ goto out_err;
+ }
+
+ LOG(DEBUG, "fnctl F_GETFL flags for fd %d are %x", fd, fdfl);
+
+ if (r_oldflags)
+ *r_oldflags = fdfl;
+
+ fdfl &= mask;
+ fdfl |= val;
+
+ LOG(DEBUG, "fnctl F_SETFL of fd %d to %x", fd, fdfl);
+
+ ret = fcntl(fd, F_SETFL, fdfl);
+ if (ret < 0) {
+ LOGE(ERROR, "failed to fcntl.F_SETFL for fd %d", fd);
+ rc = ERROR_FAIL;
+ goto out_err;
+ }
+
+ rc = 0;
+
+out_err:
+ return rc;
+}
+
+int libxl__fd_flags_restore(libxl__gc *gc, int fd, int fdfl)
+{
+ int ret, rc;
+
+ LOG(DEBUG, "fnctl F_SETFL of fd %d to %x", fd, fdfl);
+
+ ret = fcntl(fd, F_SETFL, fdfl);
+ if (ret < 0) {
+ LOGE(ERROR, "failed to fcntl.F_SETFL for fd %x", fd);
+ rc = ERROR_FAIL;
+ goto out_err;
+ }
+
+ rc = 0;
+
+out_err:
+ return rc;
+
+}
void libxl_hwcap_copy(libxl_ctx *ctx,libxl_hwcap *dst, libxl_hwcap *src)
{
{
AO_CREATE(ctx, 0, ao_how);
libxl__app_domain_create_state *cdcs;
+ int rc;
GCNEW(cdcs);
cdcs->dcs.ao = ao;
libxl_domain_config_init(&cdcs->dcs.guest_config_saved);
libxl_domain_config_copy(ctx, &cdcs->dcs.guest_config_saved, d_config);
cdcs->dcs.restore_fd = cdcs->dcs.libxc_fd = restore_fd;
- if (restore_fd > -1)
+ if (restore_fd > -1) {
cdcs->dcs.restore_params = *params;
+ rc = libxl__fd_flags_modify_save(gc, cdcs->dcs.restore_fd,
+ ~(O_NONBLOCK|O_NDELAY), 0,
+ &cdcs->dcs.restore_fdfl);
+ if (rc < 0) goto out_err;
+ }
cdcs->dcs.callback = domain_create_cb;
libxl__ao_progress_gethow(&cdcs->dcs.aop_console_how, aop_console_how);
cdcs->domid_out = domid;
initiate_domain_create(egc, &cdcs->dcs);
return AO_INPROGRESS;
+
+ out_err:
+ return AO_CREATE_FAIL(rc);
+
}
static void domain_create_cb(libxl__egc *egc,
int rc, uint32_t domid)
{
libxl__app_domain_create_state *cdcs = CONTAINER_OF(dcs, *cdcs, dcs);
+ int flrc;
STATE_AO_GC(cdcs->dcs.ao);
*cdcs->domid_out = domid;
+ if (dcs->restore_fd > -1) {
+ flrc = libxl__fd_flags_restore(gc,
+ dcs->restore_fd, dcs->restore_fdfl);
+ /*
+ * If restore has failed already then report that error not
+ * this one.
+ */
+ if (flrc && !rc) rc = flrc;
+ }
+
libxl__ao_complete(egc, ao, rc);
}
* `not open'. Ignores any errors. Sets fds[] to -1. */
_hidden void libxl__pipe_close(int fds[2]);
+/* Change the flags for the file description associated with fd to
+ * (flags & mask) | val.
+ * If r_oldflags != NULL then sets *r_oldflags to the original set of
+ * flags.
+ */
+_hidden int libxl__fd_flags_modify_save(libxl__gc *gc, int fd,
+ int mask, int val, int *r_oldflags);
+/* Restores the flags for the file description associated with fd to
+ * to the previous value (returned by libxl__fd_flags_modify_save)
+ */
+_hidden int libxl__fd_flags_restore(libxl__gc *gc, int fd, int old_flags);
/* Each of these logs errors and returns a libxl error code.
* They do not mind if path is already removed.
uint32_t domid;
int fd;
+ int fdfl; /* original flags on fd */
libxl_domain_type type;
int live;
int debug;
libxl_domain_config *guest_config;
libxl_domain_config guest_config_saved; /* vanilla config */
int restore_fd, libxc_fd;
+ int restore_fdfl; /* original flags of restore_fd */
libxl_domain_restore_params restore_params;
libxl__domain_create_cb *callback;
libxl_asyncprogress_how aop_console_how;