Unplug v2 adds a query call to determine if a device type has had its unplug issued.
This is useful during upgrade cases when the Unplug keys have been set to 0, and can
be used to prevent XenVif from starting whilst emulated devices are present, but those
emulated devices have not been assigned a valid configuration yet (emulated devices
will receive valid configuration, but not at this point in the startup sequence during
upgrade)
Signed-off-by: Owen Smith <owen.smith@cloud.com>
Renamed UnplugWasRequested() to UnplugIsRequested() in the XENBUS_UNPLUG_INTERFACE_V2
by renaming the clashing XEN_API function from UnplugIsRequested() to UnplugGetRequest()
Signed-off-by: Paul Durrant <pdurrant@amazon.com>
DEFINE_REVISION(0x09000006, 1, 3, 8, 1, 2, 1, 2, 4, 1, 1, 1), \
DEFINE_REVISION(0x09000007, 1, 3, 8, 1, 2, 1, 2, 4, 1, 1, 2), \
DEFINE_REVISION(0x09000008, 1, 3, 9, 1, 2, 1, 2, 4, 1, 1, 2), \
- DEFINE_REVISION(0x09000009, 1, 4, 9, 1, 2, 1, 2, 4, 1, 1, 2)
+ DEFINE_REVISION(0x09000009, 1, 4, 9, 1, 2, 1, 2, 4, 1, 1, 2), \
+ DEFINE_REVISION(0x0900000A, 1, 4, 9, 1, 2, 1, 2, 4, 2, 1, 2)
#endif // _REVISION_H
IN BOOLEAN Make
);
+/*! \typedef XENBUS_UNPLUG_IS_REQUESTED
+ \brief Has a type of emulated device been unplugged
+
+ \param Interface The interface header
+ \param Type The type of device
+
+ \return TRUE The type of device has been unplugged this boot.
+*/
+typedef BOOLEAN
+(*XENBUS_UNPLUG_IS_REQUESTED)(
+ IN PINTERFACE Interface,
+ IN XENBUS_UNPLUG_DEVICE_TYPE Type
+ );
+
// {73db6517-3d06-4937-989f-199b7501e229}
DEFINE_GUID(GUID_XENBUS_UNPLUG_INTERFACE,
0x73db6517, 0x3d06, 0x4937, 0x98, 0x9f, 0x19, 0x9b, 0x75, 0x01, 0xe2, 0x29);
XENBUS_UNPLUG_REQUEST UnplugRequest;
};
-typedef struct _XENBUS_UNPLUG_INTERFACE_V1 XENBUS_UNPLUG_INTERFACE, *PXENBUS_UNPLUG_INTERFACE;
+/*! \struct _XENBUS_UNPLUG_INTERFACE_V2
+ \brief UNPLUG interface version 2
+ \ingroup interfaces
+*/
+struct _XENBUS_UNPLUG_INTERFACE_V2 {
+ INTERFACE Interface;
+ XENBUS_UNPLUG_ACQUIRE UnplugAcquire;
+ XENBUS_UNPLUG_RELEASE UnplugRelease;
+ XENBUS_UNPLUG_REQUEST UnplugRequest;
+ XENBUS_UNPLUG_IS_REQUESTED UnplugIsRequested;
+};
+
+typedef struct _XENBUS_UNPLUG_INTERFACE_V2 XENBUS_UNPLUG_INTERFACE, *PXENBUS_UNPLUG_INTERFACE;
/*! \def XENBUS_UNPLUG
\brief Macro at assist in method invocation
#endif // _WINDLL
#define XENBUS_UNPLUG_INTERFACE_VERSION_MIN 1
-#define XENBUS_UNPLUG_INTERFACE_VERSION_MAX 1
+#define XENBUS_UNPLUG_INTERFACE_VERSION_MAX 2
#endif // _XENBUS_UNPLUG_INTERFACE_H
IN UNPLUG_TYPE Type
);
+XEN_API
+BOOLEAN
+UnplugGetRequest(
+ IN UNPLUG_TYPE Type
+ );
+
// LOG
typedef enum _LOG_LEVEL {
return status;
}
+XEN_API
+BOOLEAN
+UnplugGetRequest(
+ IN UNPLUG_TYPE Type
+ )
+{
+ PUNPLUG_CONTEXT Context = &UnplugContext;
+ KIRQL Irql;
+ BOOLEAN Request;
+
+ AcquireHighLock(&Context->Lock, &Irql);
+ Request = Context->Request[Type];
+ ReleaseHighLock(&Context->Lock, Irql);
+
+ return Request;
+}
+
XEN_API
VOID
UnplugDevices(
ReleaseMutex(&Context->Mutex);
}
+__drv_requiresIRQL(PASSIVE_LEVEL)
+static BOOLEAN
+UnplugIsRequested(
+ IN PINTERFACE Interface,
+ IN XENBUS_UNPLUG_DEVICE_TYPE Type
+ )
+{
+ PXENBUS_UNPLUG_CONTEXT Context = Interface->Context;
+ BOOLEAN Requested;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ AcquireMutex(&Context->Mutex);
+
+ Requested = FALSE;
+ switch (Type) {
+ case XENBUS_UNPLUG_DEVICE_TYPE_NICS:
+ Requested = UnplugGetRequest(UNPLUG_NICS);
+ break;
+
+ case XENBUS_UNPLUG_DEVICE_TYPE_DISKS:
+ Requested = UnplugGetRequest(UNPLUG_DISKS);
+ break;
+
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+
+ ReleaseMutex(&Context->Mutex);
+
+ return Requested;
+}
+
static NTSTATUS
UnplugAcquire(
IN PINTERFACE Interface
UnplugRequest
};
+static struct _XENBUS_UNPLUG_INTERFACE_V2 UnplugInterfaceVersion2 = {
+ { sizeof (struct _XENBUS_UNPLUG_INTERFACE_V2), 2, NULL, NULL, NULL },
+ UnplugAcquire,
+ UnplugRelease,
+ UnplugRequest,
+ UnplugIsRequested
+};
+
NTSTATUS
UnplugInitialize(
IN PXENBUS_FDO Fdo,
status = STATUS_SUCCESS;
break;
}
+ case 2: {
+ struct _XENBUS_UNPLUG_INTERFACE_V2 *UnplugInterface;
+
+ UnplugInterface = (struct _XENBUS_UNPLUG_INTERFACE_V2 *)Interface;
+
+ status = STATUS_BUFFER_OVERFLOW;
+ if (Size < sizeof (struct _XENBUS_UNPLUG_INTERFACE_V2))
+ break;
+
+ *UnplugInterface = UnplugInterfaceVersion2;
+
+ ASSERT3U(Interface->Version, ==, Version);
+ Interface->Context = Context;
+
+ status = STATUS_SUCCESS;
+ break;
+ }
default:
status = STATUS_NOT_SUPPORTED;
break;