Skip to content

Commit

Permalink
xen-bus: only set the xen device frontend state if it is missing
Browse files Browse the repository at this point in the history
Some toolstack implementations will set the frontend xenstore
keys to Initialising which will then trigger the in guest PV
drivers to begin initialising and some implementations will
then set their state to Closing. If this has occurred then
device realize must not overwrite the frontend keys as then
the handshake will stall.

Signed-off-by: Mark Syms <mark.syms@citrix.com>

Also avoid creating the frontend area if it already exists.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
Message-Id: <20190918115745.39006-1-paul.durrant@citrix.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
  • Loading branch information
MarkSymsCtx authored and anthonyper-ctx committed Sep 24, 2019
1 parent ef916ab commit 6bd6b95
Showing 1 changed file with 31 additions and 16 deletions.
47 changes: 31 additions & 16 deletions hw/xen/xen-bus.c
Expand Up @@ -857,6 +857,13 @@ static void xen_device_frontend_changed(void *opaque)
}
}

static bool xen_device_frontend_exists(XenDevice *xendev)
{
enum xenbus_state state;

return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1);
}

static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
{
XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
Expand All @@ -865,19 +872,25 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp)

xendev->frontend_path = xen_device_get_frontend_path(xendev);

perms[0].id = xendev->frontend_id;
perms[0].perms = XS_PERM_NONE;
perms[1].id = xenbus->backend_id;
perms[1].perms = XS_PERM_READ | XS_PERM_WRITE;
/*
* The frontend area may have already been created by a legacy
* toolstack.
*/
if (!xen_device_frontend_exists(xendev)) {
perms[0].id = xendev->frontend_id;
perms[0].perms = XS_PERM_NONE;
perms[1].id = xenbus->backend_id;
perms[1].perms = XS_PERM_READ | XS_PERM_WRITE;

g_assert(xenbus->xsh);
g_assert(xenbus->xsh);

xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, perms,
ARRAY_SIZE(perms), &local_err);
if (local_err) {
error_propagate_prepend(errp, local_err,
"failed to create frontend: ");
return;
xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, perms,
ARRAY_SIZE(perms), &local_err);
if (local_err) {
error_propagate_prepend(errp, local_err,
"failed to create frontend: ");
return;
}
}

xendev->frontend_state_watch =
Expand Down Expand Up @@ -1290,12 +1303,14 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
xen_device_backend_set_online(xendev, true);
xen_device_backend_set_state(xendev, XenbusStateInitWait);

xen_device_frontend_printf(xendev, "backend", "%s",
xendev->backend_path);
xen_device_frontend_printf(xendev, "backend-id", "%u",
xenbus->backend_id);
if (!xen_device_frontend_exists(xendev)) {
xen_device_frontend_printf(xendev, "backend", "%s",
xendev->backend_path);
xen_device_frontend_printf(xendev, "backend-id", "%u",
xenbus->backend_id);

xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
}

xendev->exit.notify = xen_device_exit;
qemu_add_exit_notifier(&xendev->exit);
Expand Down

0 comments on commit 6bd6b95

Please sign in to comment.