halapi: Separate g_compatibility_info into manifest and backend 39/309639/14
authorYoungjae Cho <y0.cho@samsung.com>
Fri, 12 Apr 2024 11:09:02 +0000 (20:09 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Mon, 15 Apr 2024 12:29:13 +0000 (21:29 +0900)
To load those data separately, manifest and backend, separate their
data structure. It holds major/minor version instead of compatibility.
The compatibility could easily be knonw if major/minor versions of
manifest and backend have been held on memory.

In addition, storing format has been changed. Each segment is separated
by ':'.
 {index}:{module_name}:{manifest_major}.{manifest_minor}:
  {backend_major}.{backend_minor}:{manifest_desciption}:
  {backend_description}:{compatibility}

Change-Id: Ifd59eebc60e092e0c465e92b36ffde81e1185f15
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
include/hal-common.h
src/hal-api-common.c
src/hal-api-compatibility-checker.c
src/hal-api-compatibility-checker.h
tools/hal-compatibility-checker/main.c

index d0ab34e86c78e265b1ea4009bad5cc3e49544778..5590b750bdcfd069a8d559143b25af743948ad37 100644 (file)
@@ -217,18 +217,6 @@ int hal_common_get_backend_library_names(enum hal_module module,
                                        int library_count,
                                        int library_name_size);
 
-
-/**
- * @brief Check version compatibility of modules specified in manifests and stores its result
- * @param[out] backend_compatibilities Pointer for storing array of compatibilities about all \n
- *             modules. The data is owned by caller, so it is responsible for caller to free it \n
- *             using free()
- * @param[out] length Pointer for retrieving length of array
- * @return @c 0 on success, otherwise a negative error value
- */
-int hal_common_check_backend_compatibility_all(
-       enum hal_common_backend_compatibility **backend_compatibilities, int *length);
-
 /**
  * @brief Check compatibility of the given module
  * @param[in] module HAL module for checking compatibility
index 30e1219add11161ef07180bd7d32c819a2f72136..9dc597fee58d994cca5346e76073f55d718fd892 100644 (file)
@@ -763,13 +763,6 @@ int hal_common_get_backend_library_names(enum hal_module module,
        return (ret < 0) ? ret : 0;
 }
 
-EXPORT
-int hal_common_check_backend_compatibility_all(
-       enum hal_common_backend_compatibility **backend_compatibilities, int *length)
-{
-       return hal_api_cc_check_backend_compatibility_all(backend_compatibilities, length);
-}
-
 EXPORT
 int hal_common_check_backend_compatibility(enum hal_module module,
        enum hal_common_backend_compatibility *backend_compatibility)
index bec7f5c65ac122920ccd8da6b4e374f030d434db..b544db27e26a4bd2aefda7e8e57483635fd35b8c 100644 (file)
 #include "hal-api-compatibility-checker-parser.h"
 #include "hal-api-compatibility-checker-util.h"
 
-#define HAL_COMMON_DEFAULT_HAL_INFO_INI                        "/hal/etc/hal-info.ini"
-#define HAL_COMMON_DEFAULT_BACKEND_COMPATIBILITY_PATH          "/opt/etc/hal/.hal-backend-compatibility"
+#define HAL_CC_DEFAULT_HAL_INFO_INI_PATH               "/hal/etc/hal-info.ini"
+#define HAL_CC_DEFAULT_COMPATIBILITY_RESULT_PATH       "/opt/etc/hal/.hal-backend-compatibility"
 
-#define COMPAT_INFO_MODULE_NAME_MAX            64
-#define COMPAT_INFO_COMPAT_DESC_MAX            64
-#define COMPAT_INFO_FILE_ALIGN_BYTE            ((COMPAT_INFO_MODULE_NAME_MAX + COMPAT_INFO_COMPAT_DESC_MAX) + 32)
+#define COMPAT_INFO_MODULE_NAME_MAX                    64
+#define COMPAT_INFO_COMPAT_DESC_MAX                    64
+#define COMPAT_INFO_FILE_ALIGN_BYTE                    ((COMPAT_INFO_MODULE_NAME_MAX + COMPAT_INFO_COMPAT_DESC_MAX) + 32)
+
+#define HAL_CC_VERSION_UNINITIALIZED                   (-1)
+
+#define LOAD_FLAG_NO_RELOAD                            (1 << 0)
+#define STORE_FLAG_NO_OVERWRITE                                (1 << 0)
 
 struct compatibility_info {
        enum hal_module module;
        char module_name[COMPAT_INFO_MODULE_NAME_MAX];
-       enum hal_common_backend_compatibility compat;
-       char compat_desc[COMPAT_INFO_COMPAT_DESC_MAX];
-};
-
-struct compatibility_data {
-       enum hal_module module;
-       int major;
-       int minor;
+       int major_version;
+       int minor_version;
+       const char *error_desc;
 };
 
-static struct compatibility_info g_compatibility_info[HAL_MODULE_END];
-static bool g_compatibility_info_loaded = false;
+static struct compatibility_info g_compatibility_manifest_info[HAL_MODULE_END];
+static bool g_compatibility_manifest_info_loaded = false;
 
-static void set_compatibility_info_compat(enum hal_module module,
-       enum hal_common_backend_compatibility compat, const char *desc)
-{
-       if (module < HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END)
-               return;
+static struct compatibility_info g_compatibility_backend_info[HAL_MODULE_END];
+static bool g_compatibility_backend_info_loaded = false;
 
-       g_compatibility_info[module].compat = compat;
+static enum hal_common_backend_compatibility g_compatibility_result[HAL_MODULE_END];
+static bool g_compatibility_result_synced = false;
 
-       if (!desc)
-               return;
+static enum hal_common_backend_compatibility
+is_manifest_backend_version_compatible(int manifest_major, int manifest_minor,
+       int backend_major, int backend_minor)
+{
+       if (manifest_major == HAL_CC_VERSION_UNINITIALIZED
+               || manifest_minor == HAL_CC_VERSION_UNINITIALIZED
+               || backend_major == HAL_CC_VERSION_UNINITIALIZED
+               || backend_minor == HAL_CC_VERSION_UNINITIALIZED)
+               return HAL_COMMON_BACKEND_COMPATIBILITY_UNKNOWN;
 
-       snprintf(g_compatibility_info[module].compat_desc,
-               COMPAT_INFO_COMPAT_DESC_MAX, "%s", desc);
-}
+       if (manifest_major != backend_major)
+               return HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE;
 
-static void init_compatibility_info(enum hal_module module)
-{
-       if (module < HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END)
-               return;
+       if (manifest_minor < backend_minor)
+               return HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE;
 
-       g_compatibility_info[module].module = module;
-       snprintf(g_compatibility_info[module].module_name, COMPAT_INFO_MODULE_NAME_MAX,
-               "%s", g_hal_module_info[module].module_name ? : "Not defined");
-       set_compatibility_info_compat(module, HAL_COMMON_BACKEND_COMPATIBILITY_UNKNOWN,
-               "Manifest hasn't specified the module");
+       return HAL_COMMON_BACKEND_COMPATIBILITY_COMPATIBLE;
 }
 
-static int write_compatibility_info(int fd, enum hal_module module)
+static void init_compatibility_info(struct compatibility_info *info)
 {
-       char buffer[COMPAT_INFO_FILE_ALIGN_BYTE] = { 0 , };
-       struct compatibility_info *ci = NULL;
-       ssize_t ret;
-       int len = 0;
-
-       if (fd == -1)
-               return -EINVAL;
-
-       if (module < HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END)
-               return -EINVAL;
-
-       ci = &g_compatibility_info[module];
-
-       len = snprintf(buffer, sizeof(buffer), "%d:%s:%d:%s\n",
-               ci->module, ci->module_name, ci->compat, ci->compat_desc);
-
-       ret = write(fd, buffer, len);
-       if (ret == -1)
-               return -errno;
-
-       return 0;
+       assert(info);
+
+       for (enum hal_module module = 0; module < HAL_MODULE_END; ++module) {
+               info[module].module = module;
+               snprintf(info[module].module_name, COMPAT_INFO_MODULE_NAME_MAX,
+                       "%s", g_hal_module_info[module].module_name ? : "Not defined");
+               info[module].major_version = HAL_CC_VERSION_UNINITIALIZED;
+               info[module].minor_version = HAL_CC_VERSION_UNINITIALIZED;
+               info[module].error_desc = "Uninitialized module";
+       }
 }
 
-static int parse_directory(const char *manifest_dir, halcc_manifest *manifest)
+static int parse_manifest_directory(const char *manifest_dir, halcc_manifest *manifest)
 {
        DIR *dir;
        int dfd;
@@ -156,78 +143,22 @@ static int parse_directory(const char *manifest_dir, halcc_manifest *manifest)
        return 0;
 }
 
-static enum hal_common_backend_compatibility is_compatible(int manifest_major, int manifest_minor,
-       int backend_major, int backend_minor)
-{
-       if (manifest_major != backend_major)
-               return HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE;
-
-       if (manifest_minor < backend_minor)
-               return HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE;
-
-       return HAL_COMMON_BACKEND_COMPATIBILITY_COMPATIBLE;
-}
-
-static void make_compatibility_info_specific(struct halcc_hal *hal, void *user_data)
-{
-       struct compatibility_data *data = user_data;
-       struct __hal_module_info *info = NULL;
-       const char *hal_name = NULL;
-       const char *module_name = NULL;
-       enum hal_module module;
-       int manifest_major;
-       int manifest_minor;
-       int backend_major;
-       int backend_minor;
-       int ret;
-
-       assert(hal);
-       assert(data);
-
-       module = data->module;
-       info = _hal_api_conf_get_module_info(module, NULL);
-       if (info == NULL)
-               return;
-
-       module_name = info->module_name;
-
-       if (halcc_hal_get_name(hal, &hal_name) < 0 || hal_name == NULL)
-               return;
-
-       ret = strncmp(hal_name, module_name, strlen(hal_name) + 1);
-       if (ret != 0)
-               return;
-
-       ret = halcc_hal_get_version(hal, &manifest_major, &manifest_minor, NULL);
-       if (ret < 0)
-               return;
-
-       backend_major = data->major;
-       backend_minor = data->minor;
-
-       g_compatibility_info[module].compat = is_compatible(manifest_major,
-               manifest_minor, backend_major, backend_minor);
-}
-
-static void make_compatibility_info(void *data, void *user_data)
+static void make_compatibility_manifest_info(void *data, void *user_data)
 {
        enum hal_module module;
        halcc_hal *hal;
        const char *hal_name = NULL;
        int manifest_major, manifest_minor;
-       int backend_major, backend_minor;
        halcc_dependency_state_e state;
        int ret;
-       enum hal_common_backend_compatibility compat = HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE;
+       const char *error_desc = NULL;
+       struct compatibility_info *manifest_info = NULL;
 
        hal = (halcc_hal *) data;
+       manifest_info = (struct compatibility_info *) user_data;
 
        assert(hal);
-
-       if (user_data) { // search for specific objective
-               make_compatibility_info_specific(hal, user_data);
-               return;
-       }
+       assert(manifest_info);
 
        if (halcc_hal_get_name(hal, &hal_name) < 0 || hal_name == NULL)
                return;
@@ -249,37 +180,22 @@ static void make_compatibility_info(void *data, void *user_data)
                return;
        }
 
+
        if (halcc_hal_get_dependency_state(hal, &state) != 0) {
-               set_compatibility_info_compat(module,
-                       HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE,
-                       "Manifest failed to resolve dependency");
-               return;
+               error_desc = "Failed to resolve dependency";
+               goto out;
        }
 
        if (halcc_hal_get_version(hal, &manifest_major, &manifest_minor, NULL) < 0) {
-               set_compatibility_info_compat(module,
-                       HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE,
-                       "Manifest has invalid version");
-               return;
+               error_desc = "Invalid manifest version";
+               goto out;
        }
 
-       ret = hal_common_get_backend_version(module, &backend_major, &backend_minor);
-       if (ret < 0) {
-               set_compatibility_info_compat(module,
-                       HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE,
-                       "Backend has invalid version");
-               return;
-       }
+       manifest_info[module].major_version = manifest_major;
+       manifest_info[module].minor_version = manifest_minor;
 
-       compat = is_compatible(manifest_major, manifest_minor, backend_major, backend_minor);
-       if (compat == HAL_COMMON_BACKEND_COMPATIBILITY_COMPATIBLE)
-               set_compatibility_info_compat(module,
-                       HAL_COMMON_BACKEND_COMPATIBILITY_COMPATIBLE,
-                       "Compatible");
-       else
-               set_compatibility_info_compat(module,
-                       HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE,
-                       "Backend has incompatible version");
+out:
+       manifest_info[module].error_desc = error_desc;
 }
 
 static int get_tizen_hal_version(int *major, int *minor)
@@ -292,9 +208,9 @@ static int get_tizen_hal_version(int *major, int *minor)
        assert(major);
        assert(minor);
 
-       fp = fopen(HAL_COMMON_DEFAULT_HAL_INFO_INI, "r");
+       fp = fopen(HAL_CC_DEFAULT_HAL_INFO_INI_PATH, "r");
        if (!fp) {
-               _E("Failed to open %s, %m\n", HAL_COMMON_DEFAULT_HAL_INFO_INI);
+               _E("Failed to open %s, %m\n", HAL_CC_DEFAULT_HAL_INFO_INI_PATH);
                return -errno;
        }
 
@@ -364,18 +280,22 @@ static int set_owner(int fd)
        return fchown(fd, uid_system_fw, gid_system_fw);
 }
 
-static int store_backend_compatibility_to_storage(bool overwrite)
+static int store_hal_backend_compatibility(struct compatibility_info *manifest_info,
+       struct compatibility_info *backend_info,
+       enum hal_common_backend_compatibility *backend_compatibilities,
+       int store_flag)
 {
        int fd = -1;
        int flag = O_WRONLY | O_CREAT | O_TRUNC;
        int ret;
 
-       assert(g_compatibility_info_loaded);
+       assert(g_compatibility_manifest_info_loaded);
+       assert(g_compatibility_backend_info_loaded);
 
-       if (!overwrite)
+       if (store_flag & STORE_FLAG_NO_OVERWRITE)
                flag |= O_EXCL;
 
-       fd = open(HAL_COMMON_DEFAULT_BACKEND_COMPATIBILITY_PATH, flag, 0644);
+       fd = open(HAL_CC_DEFAULT_COMPATIBILITY_RESULT_PATH, flag, 0644);
        if (fd == -1)
                return (errno == EEXIST) ? 0 : -errno;
 
@@ -385,20 +305,53 @@ static int store_backend_compatibility_to_storage(bool overwrite)
                return ret;
        }
 
-       for (enum hal_module module = 0; module < HAL_MODULE_END; ++module)
-               write_compatibility_info(fd, module);
+       for (enum hal_module module = 0; module < HAL_MODULE_END; ++module) {
+               char buffer[COMPAT_INFO_FILE_ALIGN_BYTE] = { 0 , };
+               ssize_t ret2;
+               int length = 0;
+               enum hal_common_backend_compatibility compatibility;
+               const char *compatibility_desc = NULL;
+
+               compatibility = backend_compatibilities[module];
+               compatibility_desc = (compatibility == HAL_COMMON_BACKEND_COMPATIBILITY_COMPATIBLE) ?
+                       "Compatible" : "Incompatible";
+
+               length = snprintf(buffer, sizeof(buffer), "%d:%s:%d.%d:%d.%d:%s:%s:%s\n",
+                       module,
+                       manifest_info[module].module_name,
+                       manifest_info[module].major_version, manifest_info[module].minor_version,
+                       backend_info[module].major_version, backend_info[module].minor_version,
+                       manifest_info[module].error_desc ?: "-",
+                       backend_info[module].error_desc ?: "-",
+                       compatibility_desc);
+
+               ret2 = write(fd, buffer, length);
+               if (ret2 < 0)
+                       _W("Failed to write compatibility result(%d)", -errno);
+       }
 
        close(fd);
 
        return 0;
 }
 
-static int load_backend_compatibility_from_manifest(void *data)
+static int load_hal_manifest(struct compatibility_info *manifest_info, int load_flag)
 {
        char manifest_dir[64] = { 0, };
        halcc_manifest *manifest = NULL;
        int ret = 0;
 
+       if (!manifest_info)
+               return -EINVAL;
+
+       if ((load_flag & LOAD_FLAG_NO_RELOAD) && g_compatibility_manifest_info_loaded)
+               return 0;
+
+       init_compatibility_info(manifest_info);
+       g_compatibility_manifest_info_loaded = false;
+
+       g_compatibility_result_synced = false;
+
        ret = build_compatibility_manifest_dir(manifest_dir, sizeof(manifest_dir));
        if (ret < 0)
                return ret;
@@ -407,24 +360,15 @@ static int load_backend_compatibility_from_manifest(void *data)
        if (ret < 0)
                return ret;
 
-       ret = parse_directory(manifest_dir, manifest);
+       ret = parse_manifest_directory(manifest_dir, manifest);
        if (ret < 0)
                goto out;
 
        halcc_manifest_validate_hal_dependency(manifest);
 
-       if (data) { // search for specific objective
-               halcc_manifest_foreach_hal(manifest, make_compatibility_info, data);
-               return 0;
-       }
+       halcc_manifest_foreach_hal(manifest, make_compatibility_manifest_info, manifest_info);
 
-       g_compatibility_info_loaded = false;
-
-       for (enum hal_module module = 0; module < HAL_MODULE_END; ++module)
-               init_compatibility_info(module);
-       halcc_manifest_foreach_hal(manifest, make_compatibility_info, NULL);
-
-       g_compatibility_info_loaded = true;
+       g_compatibility_manifest_info_loaded = true;
 
 out:
        if (manifest)
@@ -433,36 +377,147 @@ out:
        return ret;
 }
 
-static int load_backend_compatibility_from_storage(void)
+
+static int load_hal_backend_version(struct compatibility_info *backend_info, int load_flag)
+{
+       enum hal_module module;
+       int major_version;
+       int minor_version;
+       int ret;
+
+       if (!backend_info)
+               return -EINVAL;
+
+       if ((load_flag & LOAD_FLAG_NO_RELOAD) && g_compatibility_backend_info_loaded)
+               return 0;
+
+       init_compatibility_info(backend_info);
+       g_compatibility_backend_info_loaded = false;
+
+       g_compatibility_result_synced = false;
+
+       for (module = 0; module < HAL_MODULE_END; ++module) {
+               ret = hal_common_get_backend_version(module, &major_version, &minor_version);
+               if (ret < 0) {
+                       _W("Failed to get backend(%s) version(%d)", backend_info[module].module_name, ret);
+                       backend_info[module].error_desc = "Invalid backend version";
+                       continue;
+               }
+
+               backend_info[module].major_version = major_version;
+               backend_info[module].minor_version = minor_version;
+               backend_info[module].error_desc = NULL;
+       }
+
+       g_compatibility_backend_info_loaded = true;
+
+       return 0;
+}
+
+static int load_hal_manifest_and_hal_backend_version_fallback(struct compatibility_info *manifest_info,
+       struct compatibility_info *backend_info, int load_flag)
+{
+       int ret;
+
+       if (!manifest_info || !backend_info)
+               return -EINVAL;
+
+       ret = load_hal_manifest(manifest_info, load_flag);
+       if (ret < 0)
+               return ret;
+
+       ret = load_hal_backend_version(backend_info, load_flag);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int scanf_hal_backend_compatibility(const char *str,
+       enum hal_module *module,
+       int *manifest_major, int *manifest_minor,
+       int *backend_major, int *backend_minor)
+{
+       enum hal_module tmp_module;
+       int tmp_manifest_major;
+       int tmp_manifest_minor;
+       int tmp_backend_major;
+       int tmp_backend_minor;
+       int ret;
+
+       if (!str)
+               return -EINVAL;
+
+       if (!module
+               || !manifest_major || !manifest_minor
+               || !backend_major || !backend_minor)
+               return -EINVAL;
+
+       ret = sscanf(str, "%d:%*[^:]:%d.%d:%d.%d",
+               (int *) &tmp_module,
+               &tmp_manifest_major, &tmp_manifest_minor,
+               &tmp_backend_major, &tmp_backend_minor);
+       if (ret != 5)
+               return -EINVAL;
+
+       if (tmp_module < 0 || tmp_module >= HAL_MODULE_END)
+               return -EINVAL;
+
+       *module = tmp_module;
+       *manifest_major = tmp_manifest_major;
+       *manifest_minor = tmp_manifest_minor;
+       *backend_major = tmp_backend_major;
+       *backend_minor = tmp_backend_minor;
+
+       return 0;
+}
+
+static int load_hal_backend_compatibility_file(struct compatibility_info *manifest_info,
+       struct compatibility_info *backend_info)
 {
        FILE *fp = NULL;
        char *line = NULL;
        size_t len = 0;
-       enum hal_module module;
        int ret;
 
-       if (g_compatibility_info_loaded)
-               return 0;
+       if (!manifest_info || !backend_info)
+               return -EINVAL;
 
-       fp = fopen(HAL_COMMON_DEFAULT_BACKEND_COMPATIBILITY_PATH, "r");
+       fp = fopen(HAL_CC_DEFAULT_COMPATIBILITY_RESULT_PATH, "r");
        if (!fp)
                return -errno;
 
-       for (module = 0; module < HAL_MODULE_END; ++module)
-               init_compatibility_info(module);
+       init_compatibility_info(manifest_info);
+       g_compatibility_manifest_info_loaded = false;
+
+       init_compatibility_info(backend_info);
+       g_compatibility_backend_info_loaded = false;
+
+       g_compatibility_result_synced = false;
 
-       module = 0;
        while (getline(&line, &len, fp) != EOF) {
-               struct compatibility_info *ci = NULL;
+               enum hal_module module;
+               int manifest_major_version = HAL_CC_VERSION_UNINITIALIZED;
+               int manifest_minor_version = HAL_CC_VERSION_UNINITIALIZED;
+               int backend_major_version = HAL_CC_VERSION_UNINITIALIZED;
+               int backend_minor_version = HAL_CC_VERSION_UNINITIALIZED;
+
+               ret = scanf_hal_backend_compatibility(line,
+                       &module,
+                       &manifest_major_version, &manifest_minor_version,
+                       &backend_major_version, &backend_minor_version);
+               if (ret < 0)
+                       continue;
 
-               if (module >= HAL_MODULE_END)
-                       break;
+               if (manifest_info) {
+                       manifest_info[module].major_version = manifest_major_version;
+                       manifest_info[module].minor_version = manifest_minor_version;
+               }
 
-               ci = &g_compatibility_info[module++];
-               ret = sscanf(line, "%d:%63[^:]:%d:%63s",
-                       (int *) &ci->module, ci->module_name, (int *) &ci->compat, ci->compat_desc);
-               if (ret != 4)
-                       _E("Failed to load %d module", module);
+               if (backend_info) {
+                       backend_info[module].major_version = backend_major_version;
+                       backend_info[module].minor_version = backend_minor_version;
+               }
        }
 
        free(line);
@@ -470,57 +525,78 @@ static int load_backend_compatibility_from_storage(void)
        fclose(fp);
        fp = NULL;
 
-       g_compatibility_info_loaded = true;
+       g_compatibility_manifest_info_loaded = true;
+       g_compatibility_backend_info_loaded = true;
 
        return 0;
 }
 
-static int load_backend_compatibility(void *data)
+static int load_hal_manifest_and_hal_backend_version(struct compatibility_info *manifest_info,
+       struct compatibility_info *backend_info, int load_flag)
 {
-       if (g_compatibility_info_loaded)
-               return 0;
+       int ret;
 
-       load_backend_compatibility_from_storage();
-       if (g_compatibility_info_loaded)
-               return 0;
+       if (!manifest_info || !backend_info)
+               return -EINVAL;
 
-       load_backend_compatibility_from_manifest(data);
-       if (g_compatibility_info_loaded)
+       if ((load_flag & LOAD_FLAG_NO_RELOAD)
+               && g_compatibility_manifest_info_loaded
+               && g_compatibility_backend_info_loaded)
                return 0;
 
-       return -ENODATA;
+       ret = load_hal_backend_compatibility_file(manifest_info, backend_info);
+       if (ret < 0)
+               return load_hal_manifest_and_hal_backend_version_fallback(manifest_info,
+                       backend_info, load_flag);
+
+       return 0;
+}
+
+static int check_hal_backend_compatibility(const struct compatibility_info *manifest_info,
+       const struct compatibility_info *backend_info,
+       enum hal_common_backend_compatibility *backend_compatibilities)
+{
+       assert(manifest_info);
+       assert(backend_info);
+       assert(backend_compatibilities);
+
+       if (g_compatibility_result_synced)
+           return 0;
+
+       for (enum hal_module module = 0; module < HAL_MODULE_END; ++module)
+               backend_compatibilities[module] = is_manifest_backend_version_compatible(
+                       manifest_info[module].major_version, manifest_info[module].minor_version,
+                       backend_info[module].major_version, backend_info[module].minor_version);
+
+       g_compatibility_result_synced = true;
+
+       return 0;
 }
 
-int hal_api_cc_check_backend_compatibility_all(
-       enum hal_common_backend_compatibility **backend_compatibilities, int *length)
+static int check_backend_compatibility_all(
+       const enum hal_common_backend_compatibility **backend_compatibilities)
 {
        int ret;
-       enum hal_common_backend_compatibility *arr = NULL;
 
-       ret = load_backend_compatibility(NULL);
+       if (!backend_compatibilities)
+               return -EINVAL;
+
+       ret = load_hal_manifest_and_hal_backend_version(g_compatibility_manifest_info,
+               g_compatibility_backend_info, LOAD_FLAG_NO_RELOAD);
        if (ret < 0)
                return ret;
 
-       ret = store_backend_compatibility_to_storage(false);
+       ret = check_hal_backend_compatibility(g_compatibility_manifest_info,
+               g_compatibility_backend_info, g_compatibility_result);
        if (ret < 0)
                return ret;
 
-       if (!backend_compatibilities)
-               return 0;
-
-       if (!length)
-               return -EINVAL;
-
-       arr = calloc(HAL_MODULE_END, sizeof(enum hal_common_backend_compatibility));
-       if (!arr)
-               return -ENOMEM;
-
-       for (int i = 0; i < HAL_MODULE_END; ++i)
-               arr[i] = g_compatibility_info[i].compat;
+       ret = store_hal_backend_compatibility(g_compatibility_manifest_info,
+               g_compatibility_backend_info, g_compatibility_result, STORE_FLAG_NO_OVERWRITE);
+       if (ret < 0)
+               return ret;
 
-       *length = HAL_MODULE_END;
-       *backend_compatibilities = arr;
-       arr = NULL;
+       *backend_compatibilities = g_compatibility_result;
 
        return 0;
 }
@@ -529,6 +605,7 @@ int hal_api_cc_check_backend_compatibility(enum hal_module module,
        enum hal_common_backend_compatibility *backend_compatibility)
 {
        int ret;
+       const enum hal_common_backend_compatibility *backend_compatibilities = NULL;
 
        if (module < HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END)
                return -EINVAL;
@@ -536,15 +613,13 @@ int hal_api_cc_check_backend_compatibility(enum hal_module module,
        if (!backend_compatibility)
                return -EINVAL;
 
-       ret = load_backend_compatibility(NULL);
+       ret = check_backend_compatibility_all(&backend_compatibilities);
        if (ret < 0)
                return ret;
 
-       ret = store_backend_compatibility_to_storage(false);
-       if (ret < 0)
-               return ret;
+       assert(backend_compatibilities);
 
-       *backend_compatibility = g_compatibility_info[module].compat;
+       *backend_compatibility = backend_compatibilities[module];
 
        return 0;
 }
@@ -555,17 +630,21 @@ int hal_api_cc_check_backend_compatibility_by_version(enum hal_module module,
 {
        int ret;
 
-       struct compatibility_data data = {
-               .module = module,
-               .major = backend_major,
-               .minor = backend_minor,
-       };
+       if (module < HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END)
+               return -EINVAL;
+
+       if (!backend_compatibility)
+               return -EINVAL;
 
-       ret = load_backend_compatibility(&data);
+       ret = load_hal_manifest(g_compatibility_manifest_info, LOAD_FLAG_NO_RELOAD);
        if (ret < 0)
                return ret;
 
-       *backend_compatibility = g_compatibility_info[module].compat;
+       *backend_compatibility = is_manifest_backend_version_compatible(
+               g_compatibility_manifest_info[module].major_version,
+               g_compatibility_manifest_info[module].minor_version,
+               backend_major,
+               backend_minor);
 
        return 0;
 }
index 8e0153bb2f2eda6a8045de78b679a2b6831b8614..a3b5097a3ab21cc95d0ce697322d1bf813e6d5d6 100644 (file)
@@ -19,9 +19,6 @@
 
 #include <hal-common.h>
 
-int hal_api_cc_check_backend_compatibility_all(
-       enum hal_common_backend_compatibility **backend_compatibilities, int *length);
-
 int hal_api_cc_check_backend_compatibility(enum hal_module module,
        enum hal_common_backend_compatibility *backend_compatibility);
 
index 8ec6790c5b3fbca60f9fbcad27cc9a318d28dd6f..e5879e2ea10eb838ce5308fe3141b9421a85fd62 100644 (file)
@@ -220,8 +220,10 @@ int main(int argc, char *argv[])
                return 0;
        }
 
-       // Not for getting result, but for storing result to backing storage
-       hal_common_check_backend_compatibility_all(NULL, NULL);
+       for (enum hal_module module = 0; module < HAL_MODULE_END; ++module) {
+               enum hal_common_backend_compatibility compatibility;
+               hal_common_check_backend_compatibility(module, &compatibility);
+       }
 
        return 0;
 }