|
@@ -429,6 +429,7 @@ struct MachineState {
|
|
|
* MachineClass *mc = MACHINE_CLASS(oc); \
|
|
|
* MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \
|
|
|
* mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " Virtual Machine"; \
|
|
|
+ * MACHINE_VER_DEPRECATION(__VA_ARGS__); \
|
|
|
* if (latest) { \
|
|
|
* mc->alias = "virt"; \
|
|
|
* } \
|
|
@@ -440,6 +441,7 @@ struct MachineState {
|
|
|
* }; \
|
|
|
* static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \
|
|
|
* { \
|
|
|
+ * MACHINE_VER_DELETION(__VA_ARGS__); \
|
|
|
* type_register_static(&MACHINE_VER_SYM(info, virt, __VA_ARGS__)); \
|
|
|
* } \
|
|
|
* type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
|
|
@@ -598,6 +600,100 @@ struct MachineState {
|
|
|
_MACHINE_VER_SYM2) (sym, prefix, __VA_ARGS__)
|
|
|
|
|
|
|
|
|
+/*
|
|
|
+ * How many years/major releases for each phase
|
|
|
+ * of the life cycle. Assumes use of versioning
|
|
|
+ * scheme where major is bumped each year
|
|
|
+ */
|
|
|
+#define MACHINE_VER_DELETION_MAJOR 6
|
|
|
+#define MACHINE_VER_DEPRECATION_MAJOR 3
|
|
|
+
|
|
|
+/*
|
|
|
+ * Expands to a static string containing a deprecation
|
|
|
+ * message for a versioned machine type
|
|
|
+ */
|
|
|
+#define MACHINE_VER_DEPRECATION_MSG \
|
|
|
+ "machines more than " stringify(MACHINE_VER_DEPRECATION_MAJOR) \
|
|
|
+ " years old are subject to deletion after " \
|
|
|
+ stringify(MACHINE_VER_DELETION_MAJOR) " years"
|
|
|
+
|
|
|
+#define _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) \
|
|
|
+ (((QEMU_VERSION_MAJOR - major) > cutoff) || \
|
|
|
+ (((QEMU_VERSION_MAJOR - major) == cutoff) && \
|
|
|
+ (QEMU_VERSION_MINOR - minor) >= 0))
|
|
|
+
|
|
|
+#define _MACHINE_VER_IS_EXPIRED2(cutoff, major, minor) \
|
|
|
+ _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
|
|
|
+#define _MACHINE_VER_IS_EXPIRED3(cutoff, major, minor, micro) \
|
|
|
+ _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
|
|
|
+#define _MACHINE_VER_IS_EXPIRED4(cutoff, major, minor, _unused, tag) \
|
|
|
+ _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
|
|
|
+#define _MACHINE_VER_IS_EXPIRED5(cutoff, major, minor, micro, _unused, tag) \
|
|
|
+ _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
|
|
|
+
|
|
|
+#define _MACHINE_IS_EXPIRED(cutoff, ...) \
|
|
|
+ _MACHINE_VER_PICK(__VA_ARGS__, \
|
|
|
+ _MACHINE_VER_IS_EXPIRED5, \
|
|
|
+ _MACHINE_VER_IS_EXPIRED4, \
|
|
|
+ _MACHINE_VER_IS_EXPIRED3, \
|
|
|
+ _MACHINE_VER_IS_EXPIRED2) (cutoff, __VA_ARGS__)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Evaluates true when a machine type with (major, minor)
|
|
|
+ * or (major, minor, micro) version should be considered
|
|
|
+ * deprecated based on the current versioned machine type
|
|
|
+ * lifecycle rules
|
|
|
+ */
|
|
|
+#define MACHINE_VER_IS_DEPRECATED(...) \
|
|
|
+ _MACHINE_IS_EXPIRED(MACHINE_VER_DEPRECATION_MAJOR, __VA_ARGS__)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Evaluates true when a machine type with (major, minor)
|
|
|
+ * or (major, minor, micro) version should be considered
|
|
|
+ * for deletion based on the current versioned machine type
|
|
|
+ * lifecycle rules
|
|
|
+ */
|
|
|
+#define MACHINE_VER_SHOULD_DELETE(...) \
|
|
|
+ _MACHINE_IS_EXPIRED(MACHINE_VER_DELETION_MAJOR, __VA_ARGS__)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Sets the deprecation reason for a versioned machine based
|
|
|
+ * on its age
|
|
|
+ *
|
|
|
+ * This must be unconditionally used in the _class_init
|
|
|
+ * function for all machine types which support versioning.
|
|
|
+ *
|
|
|
+ * Initially it will effectively be a no-op, but after a
|
|
|
+ * suitable period of time has passed, it will set the
|
|
|
+ * 'deprecation_reason' field on the machine, to warn users
|
|
|
+ * about forthcoming removal.
|
|
|
+ */
|
|
|
+#define MACHINE_VER_DEPRECATION(...) \
|
|
|
+ do { \
|
|
|
+ if (MACHINE_VER_IS_DEPRECATED(__VA_ARGS__)) { \
|
|
|
+ mc->deprecation_reason = MACHINE_VER_DEPRECATION_MSG; \
|
|
|
+ } \
|
|
|
+ } while (0)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Prevents registration of a versioned machined based on
|
|
|
+ * its age
|
|
|
+ *
|
|
|
+ * This must be unconditionally used in the register
|
|
|
+ * method for all machine types which support versioning.
|
|
|
+ *
|
|
|
+ * Inijtially it will effectively be a no-op, but after a
|
|
|
+ * suitable period of time has passed, it will cause
|
|
|
+ * execution of the method to return, avoiding registration
|
|
|
+ * of the machine
|
|
|
+ */
|
|
|
+#define MACHINE_VER_DELETION(...) \
|
|
|
+ do { \
|
|
|
+ if (MACHINE_VER_SHOULD_DELETE(__VA_ARGS__)) { \
|
|
|
+ return; \
|
|
|
+ } \
|
|
|
+ } while (0)
|
|
|
+
|
|
|
#define DEFINE_MACHINE(namestr, machine_initfn) \
|
|
|
static void machine_initfn##_class_init(ObjectClass *oc, void *data) \
|
|
|
{ \
|