summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamian Hobson-Garcia <dhobsong@igel.co.jp>2022-04-05 12:11:38 +0900
committerDamian Hobson-Garcia <dhobsong@igel.co.jp>2022-04-20 10:58:39 +0900
commite9e5cf1f67a45e4d409dc9e1caa6ce8151579c88 (patch)
treece471b907ba5c5bc553e57aef20dda52d00c514c
parent69acc5f3928f0578438cefdd69b39bc05bb0769b (diff)
Add configuration file loading and parsing
Parse the lease configuration information from a configuration file. Each lease configuration takes a name and list of connectors to add to the lease. As long as one connector is found for a given configuration, the lease will be created. Bug-AGL: SPEC-3815 Change-Id: Iec4eaf37fba5db17a22e4945de10a06ac94063e4 Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
-rw-r--r--drm-lease-manager/lease-config.c121
-rw-r--r--drm-lease-manager/lease-config.h19
-rw-r--r--drm-lease-manager/main.c18
-rw-r--r--drm-lease-manager/meson.build5
-rw-r--r--drm-lease-manager/test/lease-config-test.c102
-rw-r--r--drm-lease-manager/test/meson.build12
-rw-r--r--meson.build1
7 files changed, 274 insertions, 4 deletions
diff --git a/drm-lease-manager/lease-config.c b/drm-lease-manager/lease-config.c
new file mode 100644
index 0000000..abb7fc1
--- /dev/null
+++ b/drm-lease-manager/lease-config.c
@@ -0,0 +1,121 @@
+/* Copyright 2022 IGEL Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lease-config.h"
+#include "log.h"
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <toml.h>
+
+#define CONFIG_ERROR(x, ...) ERROR_LOG("%s: " x, filename, ##__VA_ARGS__)
+
+static bool populate_connector_names(struct lease_config *config,
+ toml_array_t *conns)
+{
+ int cnames = toml_array_nelem(conns);
+ config->connector_names = calloc(cnames, sizeof(char *));
+ if (!config->connector_names) {
+ DEBUG_LOG("Memory allocation failed: %s\n", strerror(errno));
+ return false;
+ }
+
+ config->cnames = cnames;
+
+ for (int i = 0; i < config->cnames; i++) {
+ toml_datum_t conn = toml_string_at(conns, i);
+ if (!conn.ok) {
+ return false;
+ }
+ config->connector_names[i] = conn.u.s;
+ }
+ return true;
+}
+
+int parse_config(char *filename, struct lease_config **parsed_config)
+{
+ struct lease_config *config = NULL;
+ int nconfigs, i, ret = 0;
+ char parse_error[160];
+
+ FILE *fp = fopen(filename, "r");
+ if (!fp)
+ return 0;
+
+ toml_table_t *t_config =
+ toml_parse_file(fp, parse_error, sizeof parse_error);
+ if (!t_config) {
+ CONFIG_ERROR("configuration file parse error: %s\n",
+ parse_error);
+ fclose(fp);
+ return 0;
+ }
+
+ toml_array_t *leases = toml_array_in(t_config, "lease");
+ if (!leases) {
+ CONFIG_ERROR(
+ "Invalid config - cannot find any 'lease' configs");
+ goto err;
+ }
+ nconfigs = toml_array_nelem(leases);
+ config = calloc(nconfigs, sizeof *config);
+
+ if (!config) {
+ DEBUG_LOG("Memory allocation failed: %s\n", strerror(errno));
+ goto err;
+ }
+
+ for (i = 0; i < toml_array_nelem(leases); i++) {
+ toml_table_t *lease = toml_table_at(leases, i);
+
+ toml_datum_t name = toml_string_in(lease, "name");
+ if (!name.ok) {
+ CONFIG_ERROR("Invalid lease name in entry #%d\n", i);
+ goto err_free_config;
+ }
+
+ config[i].lease_name = name.u.s;
+
+ toml_array_t *conns = toml_array_in(lease, "connectors");
+ if (conns && !populate_connector_names(&config[i], conns)) {
+ CONFIG_ERROR("Non string connector name in lease: %s\n",
+ config[i].lease_name);
+ goto err_free_config;
+ }
+ }
+
+ *parsed_config = config;
+ ret = nconfigs;
+err:
+ toml_free(t_config);
+ fclose(fp);
+ return ret;
+err_free_config:
+ release_config(i, config);
+ goto err;
+}
+
+void release_config(int num_leases, struct lease_config *config)
+{
+ for (int i = 0; i < num_leases; i++) {
+ struct lease_config *c = &config[i];
+ free(c->lease_name);
+ for (int j = 0; j < c->cnames; j++)
+ free(c->connector_names[j]);
+ free(c->connector_names);
+ }
+ free(config);
+}
diff --git a/drm-lease-manager/lease-config.h b/drm-lease-manager/lease-config.h
new file mode 100644
index 0000000..0760a99
--- /dev/null
+++ b/drm-lease-manager/lease-config.h
@@ -0,0 +1,19 @@
+/* Copyright 2022 IGEL Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "drm-lease.h"
+
+int parse_config(char *filename, struct lease_config **parsed_config);
+void release_config(int num_leasess, struct lease_config *config);
diff --git a/drm-lease-manager/main.c b/drm-lease-manager/main.c
index 2927253..ff69e75 100644
--- a/drm-lease-manager/main.c
+++ b/drm-lease-manager/main.c
@@ -13,6 +13,7 @@
* limitations under the License.
*/
+#include "lease-config.h"
#include "lease-manager.h"
#include "lease-server.h"
#include "log.h"
@@ -27,24 +28,28 @@ static void usage(const char *progname)
printf("Usage: %s [OPTIONS] [<DRM device>]\n\n"
"Options:\n"
"-h, --help \tPrint this help\n"
+ "-c, --config \t path to configuration file (default "
+ "/etc/drm-lease-manager.toml)\n"
"-v, --verbose \tEnable verbose debug messages\n"
"-t, --lease-transfer \tAllow lease transfter to new clients\n"
"-k, --keep-on-crash \tDon't close lease on client crash\n",
progname);
}
-const char *opts = "vtkh";
+const char *opts = "vtkhc:";
const struct option options[] = {
{"help", no_argument, NULL, 'h'},
{"verbose", no_argument, NULL, 'v'},
{"lease-transfer", no_argument, NULL, 't'},
{"keep-on-crash", no_argument, NULL, 'k'},
+ {"config", required_argument, NULL, 'c'},
{NULL, 0, NULL, 0},
};
int main(int argc, char **argv)
{
char *device = "/dev/dri/card0";
+ char *config_file = "/etc/drm-lease-manager.toml";
bool debug_log = false;
bool can_transfer_leases = false;
@@ -63,6 +68,9 @@ int main(int argc, char **argv)
case 'k':
keep_on_crash = true;
break;
+ case 'c':
+ config_file = optarg;
+ break;
case 'h':
ret = EXIT_SUCCESS;
/* fall through */
@@ -77,7 +85,12 @@ int main(int argc, char **argv)
dlm_log_enable_debug(debug_log);
- struct lm *lm = lm_create(device);
+ struct lease_config *lease_configs = NULL;
+ int num_configs = parse_config(config_file, &lease_configs);
+
+ struct lm *lm =
+ lm_create_with_config(device, num_configs, lease_configs);
+
if (!lm) {
ERROR_LOG("DRM Lease initialization failed\n");
return EXIT_FAILURE;
@@ -145,5 +158,6 @@ int main(int argc, char **argv)
done:
ls_destroy(ls);
lm_destroy(lm);
+ release_config(num_configs, lease_configs);
return EXIT_FAILURE;
}
diff --git a/drm-lease-manager/meson.build b/drm-lease-manager/meson.build
index 7157f01..4732283 100644
--- a/drm-lease-manager/meson.build
+++ b/drm-lease-manager/meson.build
@@ -1,9 +1,10 @@
lease_manager_files = files('lease-manager.c')
lease_server_files = files('lease-server.c')
+lease_config_files = files('lease-config.c')
main = executable('drm-lease-manager',
- [ 'main.c', lease_manager_files, lease_server_files ],
- dependencies: [ drm_dep, dlmcommon_dep, thread_dep ],
+ [ 'main.c', lease_manager_files, lease_server_files, lease_config_files ],
+ dependencies: [ drm_dep, dlmcommon_dep, thread_dep, toml_dep ],
install: true,
)
diff --git a/drm-lease-manager/test/lease-config-test.c b/drm-lease-manager/test/lease-config-test.c
new file mode 100644
index 0000000..fa5edcd
--- /dev/null
+++ b/drm-lease-manager/test/lease-config-test.c
@@ -0,0 +1,102 @@
+/* Copyright 2022 IGEL Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lease-config.h"
+#include <check.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define CONFIG_FILE_TEMPLATE "/tmp/dlmconfig_tmpXXXXXX"
+int config_fd;
+char config_file[] = CONFIG_FILE_TEMPLATE;
+
+static void test_setup(void)
+{
+ strcpy(config_file, CONFIG_FILE_TEMPLATE);
+ config_fd = mkstemp(config_file);
+ ck_assert_int_ge(config_fd, 0);
+}
+
+static void test_shutdown(void)
+{
+ close(config_fd);
+ unlink(config_file);
+}
+
+/* parse config file test */
+/* Test details: Parse a config file
+ * Expected results: a config with the expected results
+ */
+
+START_TEST(parse_leases)
+{
+ ck_assert_ptr_ne(config_file, NULL);
+
+ char test_data[] = "[[lease]]\n"
+ "name = \"lease 1\"\n"
+ "connectors = [\"1\", \"b\",\"gamma\" ]\n"
+ "[[lease]]\n"
+ "name = \"lease 2\"\n"
+ "connectors = [\"connector 3\"]\n";
+
+ write(config_fd, test_data, sizeof(test_data));
+
+ struct lease_config *config = NULL;
+ int nconfigs = parse_config(config_file, &config);
+
+ ck_assert_int_eq(nconfigs, 2);
+ ck_assert_ptr_ne(config, NULL);
+
+ ck_assert_str_eq(config[0].lease_name, "lease 1");
+ ck_assert_int_eq(config[0].cnames, 3);
+ ck_assert_str_eq(config[0].connector_names[0], "1");
+ ck_assert_str_eq(config[0].connector_names[1], "b");
+ ck_assert_str_eq(config[0].connector_names[2], "gamma");
+
+ ck_assert_str_eq(config[1].lease_name, "lease 2");
+ ck_assert_int_eq(config[1].cnames, 1);
+ ck_assert_str_eq(config[1].connector_names[0], "connector 3");
+
+ release_config(nconfigs, config);
+}
+END_TEST
+
+static void add_parse_tests(Suite *s)
+{
+ TCase *tc = tcase_create("Config file parsing tests");
+
+ tcase_add_checked_fixture(tc, test_setup, test_shutdown);
+
+ tcase_add_test(tc, parse_leases);
+ suite_add_tcase(s, tc);
+}
+
+int main(void)
+{
+ int number_failed;
+ Suite *s;
+ SRunner *sr;
+
+ s = suite_create("DLM lease manager tests");
+
+ add_parse_tests(s);
+
+ sr = srunner_create(s);
+ srunner_run_all(sr, CK_NORMAL);
+ number_failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/drm-lease-manager/test/meson.build b/drm-lease-manager/test/meson.build
index bb97274..8d5c06f 100644
--- a/drm-lease-manager/test/meson.build
+++ b/drm-lease-manager/test/meson.build
@@ -32,5 +32,17 @@ lm_test = executable('lease-manager-test',
c_args: test_c_args,
include_directories: ls_inc)
+lc_objects = main.extract_objects(lease_config_files)
+lc_test_sources = [
+ 'lease-config-test.c'
+]
+
+lc_test = executable('lease-config-test',
+ sources: lc_test_sources,
+ objects: lc_objects,
+ dependencies: [check_dep, dlmcommon_dep, toml_dep],
+ include_directories: ls_inc)
+
test('DRM Lease manager - socket server test', ls_test, is_parallel: false)
test('DRM Lease manager - DRM interface test', lm_test)
+test('DRM Lease manager - config parse test', lc_test)
diff --git a/meson.build b/meson.build
index 7f8adf5..c2c88a6 100644
--- a/meson.build
+++ b/meson.build
@@ -35,6 +35,7 @@ configuration_inc = include_directories('.')
drm_dep = dependency('libdrm', version: '>= 2.4.89')
thread_dep = dependency('threads')
+toml_dep = dependency('libtoml')
enable_tests = get_option('enable-tests')