summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryce Harrington <bryce@osg.samsung.com>2016-03-09 16:49:31 -0800
committerBryce Harrington <bryce@osg.samsung.com>2016-03-25 17:45:07 -0700
commit4c769b25fce3c8ece1f39edc6aea016444d9c224 (patch)
tree6cc2bb0d165b6b0048a82d23aad1ba78ea59cc5b
parent3b5b6b7befa31fb9470c2cab9e5362f8586c0e33 (diff)
compositor: Version the backend configuration structures
With this struct versioning, it is possible to add new options without breaking the ABI, as long as all additions are made to the end of a struct and nothing existing is modified or removed. When things are added, the structure's size will increase, and we'll use this size as our minor version number. If existing things need to be changed, then the major version, struct_version, is incremented to indicate the ABI break. >From our call site in main we record these major and minor version as struct_version and struct_size. The backend then verifies these against its own assumptions. So long as the backend's struct is equal or larger than what was passed in and the major versions are equal, we're good; but if it is larger, then this is a fatal error. Signed-off-by: Bryce Harrington <bryce@osg.samsung.com> Reviewed-by: Benoit Gschwind <gschwind@gnu-log.net> v5: Update to current trunk
-rw-r--r--src/compositor-drm.c10
-rw-r--r--src/compositor.h16
-rw-r--r--src/main.c2
3 files changed, 26 insertions, 2 deletions
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 78a9ef8f..f039c008 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -3229,8 +3229,14 @@ backend_init(struct weston_compositor *compositor, int *argc, char *argv[],
struct weston_backend_config *config_base)
{
struct drm_backend *b;
- struct weston_drm_backend_config *config =
- (struct weston_drm_backend_config *)config_base;
+ struct weston_drm_backend_config *config;
+
+ if (config_base == NULL ||
+ config_base->struct_version != 1 ||
+ config_base->struct_size > sizeof(struct weston_drm_backend_config))
+ return -1;
+
+ config = (struct weston_drm_backend_config *)config_base;
b = drm_backend_create(compositor, config);
if (b == NULL)
diff --git a/src/compositor.h b/src/compositor.h
index edc26cb0..f93d76a0 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -684,6 +684,22 @@ struct weston_backend_output_config {
* data.
*/
struct weston_backend_config {
+ /** Major version for the backend-specific config struct
+ *
+ * This version must match exactly what the backend expects, otherwise
+ * the struct is incompatible.
+ */
+ uint32_t struct_version;
+
+ /** Minor version of the backend-specific config struct
+ *
+ * This must be set to sizeof(struct backend-specific config).
+ * If the value here is smaller than what the backend expects, the
+ * extra config members will assume their default values.
+ *
+ * A value greater than what the backend expects is incompatible.
+ */
+ size_t struct_size;
};
struct weston_backend {
diff --git a/src/main.c b/src/main.c
index 4021bb0c..807bd4d8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -748,6 +748,8 @@ load_drm_backend(struct weston_compositor *c, const char *backend,
"gbm-format", &config->base.gbm_format,
NULL);
+ config->base.base.struct_version = 1;
+ config->base.base.struct_size = sizeof(struct weston_drm_backend_config);
config->base.configure_output = drm_configure_output;
if (load_backend_new(c, backend, &config->base.base) < 0) {