return rc;
}
-int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid)
+void libxl__destroy_device_model(libxl__egc *egc,
+ libxl__destroy_devicemodel_state *ddms)
{
+ STATE_AO_GC(ddms->ao);
int rc;
+ int domid = ddms->domid;
char *path = DEVICE_MODEL_XS_PATH(gc, LIBXL_TOOLSTACK_DOMID, domid, "");
+
if (!xs_rm(CTX->xsh, XBT_NULL, path))
LOGD(ERROR, domid, "xs_rm failed for %s", path);
+
/* We should try to destroy the device model anyway. */
rc = kill_device_model(gc,
GCSPRINTF("/local/domain/%d/image/device-model-pid", domid));
-
+
libxl__qmp_cleanup(gc, domid);
- return rc;
+ ddms->callback(egc, ddms, rc);
}
/* Return 0 if no dm needed, 1 if needed and <0 if error. */
}
/* Callbacks for libxl__destroy_domid */
+static void dm_destroy_cb(libxl__egc *egc,
+ libxl__destroy_devicemodel_state *ddms,
+ int rc);
+
static void devices_destroy_cb(libxl__egc *egc,
libxl__devices_remove_state *drs,
int rc);
if (rc < 0) {
LOGEVD(ERROR, rc, domid, "xc_domain_pause failed");
}
+
if (dm_present) {
- if (libxl__destroy_device_model(gc, domid) < 0)
- LOGD(ERROR, domid, "libxl__destroy_device_model failed");
+ dis->ddms.ao = ao;
+ dis->ddms.domid = domid;
+ dis->ddms.callback = dm_destroy_cb;
+
+ libxl__destroy_device_model(egc, &dis->ddms);
+ return;
+ } else {
+ dm_destroy_cb(egc, &dis->ddms, 0);
+ return;
}
- dis->drs.ao = ao;
- dis->drs.domid = domid;
- dis->drs.callback = devices_destroy_cb;
- dis->drs.force = 1;
- libxl__devices_destroy(egc, &dis->drs);
- return;
out:
assert(rc);
return;
}
+static void dm_destroy_cb(libxl__egc *egc,
+ libxl__destroy_devicemodel_state *ddms,
+ int rc)
+{
+ libxl__destroy_domid_state *dis = CONTAINER_OF(ddms, *dis, ddms);
+ STATE_AO_GC(dis->ao);
+ uint32_t domid = dis->domid;
+
+ if (rc < 0)
+ LOGD(ERROR, domid, "libxl__destroy_device_model failed");
+
+ dis->drs.ao = ao;
+ dis->drs.domid = domid;
+ dis->drs.callback = devices_destroy_cb;
+ dis->drs.force = 1;
+ libxl__devices_destroy(egc, &dis->drs);
+}
+
static void devices_destroy_cb(libxl__egc *egc,
libxl__devices_remove_state *drs,
int rc)
void *userdata),
void *check_callback_userdata);
-_hidden int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid);
-
_hidden const libxl_vnc_info *libxl__dm_vnc(const libxl_domain_config *g_cfg);
_hidden char *libxl__abs_path(libxl__gc *gc, const char *s, const char *path);
typedef struct libxl__domain_destroy_state libxl__domain_destroy_state;
typedef struct libxl__destroy_domid_state libxl__destroy_domid_state;
+typedef struct libxl__destroy_devicemodel_state libxl__destroy_devicemodel_state;
typedef struct libxl__devices_remove_state libxl__devices_remove_state;
typedef void libxl__domain_destroy_cb(libxl__egc *egc,
libxl__destroy_domid_state *dis,
int rc);
+typedef void libxl__devicemodel_destroy_cb(libxl__egc *egc,
+ libxl__destroy_devicemodel_state *ddms,
+ int rc);
+
typedef void libxl__devices_remove_callback(libxl__egc *egc,
libxl__devices_remove_state *drs,
int rc);
int num_devices;
};
+struct libxl__destroy_devicemodel_state {
+ /* filled in by user */
+ libxl__ao *ao;
+ uint32_t domid;
+ libxl__devicemodel_destroy_cb *callback; /* May be called re-entrantly */
+ /* private to implementation */
+};
+
struct libxl__destroy_domid_state {
/* filled in by user */
libxl__ao *ao;
libxl__domid_destroy_cb *callback;
/* private to implementation */
libxl__devices_remove_state drs;
+ libxl__destroy_devicemodel_state ddms;
libxl__ev_child destroyer;
bool soft_reset;
};
_hidden void libxl__destroy_domid(libxl__egc *egc,
libxl__destroy_domid_state *dis);
+/* Used to detroy the device model */
+_hidden void libxl__destroy_device_model(libxl__egc *egc,
+ libxl__destroy_devicemodel_state *ddms);
+
/* Entry point for devices destruction */
_hidden void libxl__devices_destroy(libxl__egc *egc,
libxl__devices_remove_state *drs);