From: Maciej Slodczyk Date: Fri, 15 Feb 2019 15:13:53 +0000 (+0100) Subject: add basic vconf listener X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=007d15eb011010fcca5a1fab582a7cabe8148954;p=platform%2Fcore%2Fsystem%2Ffaultd.git add basic vconf listener Signed-off-by: Maciej Slodczyk --- diff --git a/Makefile.am b/Makefile.am index 3e05182..d6cdadc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -49,6 +49,7 @@ AM_CFLAGS = \ -fPIE \ -rdynamic \ $(GLIB_CFLAGS) \ + $(VCONF_CFLAGS) \ -D"FAULTD_MODNAME_T=$(call name_fix,$(modname))" AM_LDFLAGS = \ @@ -57,6 +58,7 @@ AM_LDFLAGS = \ -avoid-version \ -module \ -shared \ + $(VCONF_LIBS) \ -pie SED_PROCESS = \ @@ -98,6 +100,7 @@ faultdlib_SOURCES = \ src/event_types/action_executed_event.c \ src/event_types/decision_made_event.c \ src/event_types/resource_violation_event.c \ + src/event_types/vconf_key_changed_event.c \ src/event_types/service_failed_event.c \ src/event_types/faultd_started_event.c \ src/event_types/system_booted_event.c \ @@ -122,6 +125,7 @@ EXTRA_faultd_SOURCES = \ src/listeners/audit.c \ src/listeners/systemd.c \ src/listeners/startup.c \ + src/listeners/vconf.c \ src/database/sqlite.c \ src/decision_makers/vip_fault_dm.c \ src/decision_makers/rv_dm.c \ @@ -139,6 +143,7 @@ modulesdir = $(pkglibdir)/available-modules modules_LTLIBRARIES = audit_listener.la \ systemd_listener.la \ startup_listener.la \ + vconf_listener.la \ sqlite_dbadapter.la \ vip_fault_eh.la \ resource_violation_eh.la \ @@ -153,6 +158,9 @@ audit_listener_la_SOURCES = src/listeners/audit.c audit_listener_la_LIBADD = $(AUDIT_LIBS) systemd_listener_la_SOURCES = src/listeners/systemd.c startup_listener_la_SOURCES = src/listeners/startup.c +vconf_listener_la_SOURCES = src/listeners/vconf.c +vconf_listener_config_DATA = modules.conf.d/vconf_listener.conf.d/50-default.conf +vconf_listener_configdir = $(modulesconfigdir)/vconf_listener.conf.d sqlite_dbadapter_la_SOURCES = src/database/sqlite.c sqlite_dbadapter_la_LIBADD = $(SQLITE3_LIBS) vip_fault_eh_la_SOURCES = src/decision_makers/vip_fault_dm.c @@ -230,7 +238,8 @@ if UNIT_TESTS check_PROGRAMS = test test_LDFLAGS = -ldl \ - $(GLIB_LIBS) + $(GLIB_LIBS) \ + $(VCONF_LIBS) test_LDADD = \ $(faultd_LDADD) \ @@ -242,6 +251,7 @@ test_CFLAGS = -I${top_srcdir}/src/util \ -D"FAULTD_MODNAME_T=$(call name_fix,$(modname))" \ -DTEST_BUILD \ $(GLIB_CFLAGS) \ + $(VCONF_CFLAGS) \ --coverage test_SOURCES = \ diff --git a/configure.ac b/configure.ac index 791870e..b0215c4 100644 --- a/configure.ac +++ b/configure.ac @@ -150,6 +150,13 @@ PKG_CHECK_MODULES(JSON_C, AS_IF([test "x$have_json_c" = "xno"], AC_MSG_ERROR([json-c not found])) +PKG_CHECK_MODULES(VCONF, + [vconf], + have_vconf=yes, + have_vconf=no) +AS_IF([test "x$have_vconf" = "xno"], + AC_MSG_ERROR([vconf not found])) + AC_CHECK_FUNCS([ \ printf\ ]) @@ -176,6 +183,7 @@ AC_MSG_RESULT([ libsystemd: ${have_libsystemd} glib ${have_glib} + vconf ${have_vconf} modules: ${ENABLED_MODULES/ /} ]) diff --git a/modules.conf.d/vconf_listener.conf.d/50-default.conf b/modules.conf.d/vconf_listener.conf.d/50-default.conf new file mode 100644 index 0000000..d03206b --- /dev/null +++ b/modules.conf.d/vconf_listener.conf.d/50-default.conf @@ -0,0 +1,4 @@ +{ + "keys_count" : 3, + "keys":[ "db/test/key1", "db/test/key2", "db/test/key3" ] +} diff --git a/packaging/faultd.spec b/packaging/faultd.spec index 60de114..5b0c0b5 100644 --- a/packaging/faultd.spec +++ b/packaging/faultd.spec @@ -7,7 +7,7 @@ Source1001: %{name}.manifest Summary: Fault detection daemon Group: System/Monitoring -%define with_faultd_glib_support 0 +%define with_faultd_glib_support 1 %define database_module sqlite_dbadapter BuildRequires: pkgconfig(libsystemd) @@ -17,6 +17,7 @@ BuildRequires: pkgconfig(sqlite3) %if %{with_faultd_glib_support} BuildRequires: pkgconfig(glib-2.0) %endif +BuildRequires: pkgconfig(vconf) %description faultd monitors system services, detects their abnormal execution and @@ -85,6 +86,7 @@ for mod in audit_listener \ standard_fault_eh \ standard_reboot_eh \ startup_listener \ + vconf_listener \ system_reboot_to_recovery_action do ln -s %{moduledir}/${mod}.so %{buildroot}/%{moduleconfdir}/${mod}.so; @@ -121,6 +123,7 @@ echo %{enabled_moduledir}/%{database_module}.so >> faultd-extra-files; %files extra -f faultd-extra-files %{_prefix}/lib/faultd/modules.conf.d/standard_fault_eh.conf.d/50-default.conf %{_prefix}/lib/faultd/modules.conf.d/standard_reboot_eh.conf.d/50-default.conf +%{_prefix}/lib/faultd/modules.conf.d/vconf_listener.conf.d/50-default.conf %files test-services %{_bindir}/faultd/leaker diff --git a/src/event_types/vconf_key_changed_event.c b/src/event_types/vconf_key_changed_event.c new file mode 100644 index 0000000..e363b8d --- /dev/null +++ b/src/event_types/vconf_key_changed_event.c @@ -0,0 +1,185 @@ +/* + * This file is part of faultd. + * + * Copyright © 2017 Samsung Electronics + * + * 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 +#include +#include + +#include "vconf_key_changed_event.h" + +static int allocate_vkc_event(struct faultd_event_type *type, + void *data, struct faultd_event **ev) +{ + struct vconf_key_changed_event *vkc_ev; + struct vconf_key_changed_event_data *vkc_ev_data = data; + int ret; + + vkc_ev = calloc(1, sizeof(*vkc_ev)); + if (!vkc_ev) + return -ENOMEM; + + ret = faultd_event_init_internal(type, &vkc_ev->event); + if (ret) + goto cleanup; + + vkc_ev->event_time = vkc_ev_data->event_time; + vkc_ev->key_name = vkc_ev_data->key_name; + vkc_ev->oldval = vkc_ev_data->oldval; + vkc_ev->newval = vkc_ev_data->newval; + + *ev = &vkc_ev->event; + return 0; +cleanup: + free(vkc_ev); + + return ret; +} + +static int deserialize_vkc_event(struct faultd_event_type *type, + struct faultd_object *data, struct faultd_event **ev) +{ + int ret = -EINVAL; + struct vconf_key_changed_event_data vkc_ev_data; + struct faultd_object *obj; + memset(&vkc_ev_data, 0, sizeof(vkc_ev_data)); + + list_for_each_entry(obj, &data->val.children, node) { + if ((obj->type == TYPE_STRING) && + (strcmp(VKC_EV_NAME, obj->key) == 0)) { + vkc_ev_data.key_name = obj->val.s; + } else if ((obj->type == TYPE_BOOL) && + (strcmp(VKC_EV_OLDVAL, obj->key) == 0)) { + vkc_ev_data.oldval.value.b = obj->val.b; + vkc_ev_data.oldval.type = VKC_BOOL; + } else if ((obj->type == TYPE_INT) && + (strcmp(VKC_EV_OLDVAL, obj->key) == 0)) { + vkc_ev_data.oldval.value.i = obj->val.i; + vkc_ev_data.oldval.type = VKC_INT; + } else if ((obj->type == TYPE_DOUBLE) && + (strcmp(VKC_EV_OLDVAL, obj->key) == 0)) { + vkc_ev_data.oldval.value.d = obj->val.d; + vkc_ev_data.oldval.type = VKC_DOUBLE; + } else if ((obj->type == TYPE_STRING) && + (strcmp(VKC_EV_OLDVAL, obj->key) == 0)) { + vkc_ev_data.oldval.value.s = obj->val.s; //strdup()? + vkc_ev_data.oldval.type = VKC_STRING; + } else if ((obj->type == TYPE_BOOL) && + (strcmp(VKC_EV_NEWVAL, obj->key) == 0)) { + vkc_ev_data.newval.value.b = obj->val.b; + vkc_ev_data.newval.type = VKC_BOOL; + } else if ((obj->type == TYPE_INT) && + (strcmp(VKC_EV_NEWVAL, obj->key) == 0)) { + vkc_ev_data.newval.value.i = obj->val.i; + vkc_ev_data.newval.type = VKC_INT; + } else if ((obj->type == TYPE_DOUBLE) && + (strcmp(VKC_EV_NEWVAL, obj->key) == 0)) { + vkc_ev_data.newval.value.d = obj->val.d; + vkc_ev_data.newval.type = VKC_DOUBLE; + } else if ((obj->type == TYPE_STRING) && + (strcmp(VKC_EV_NEWVAL, obj->key) == 0)) { + vkc_ev_data.newval.value.s = obj->val.s; //strdup()? + vkc_ev_data.newval.type = VKC_STRING; + } else if ((obj->type == TYPE_TIME_T) && + (strcmp(VKC_EV_TIME, obj->key) == 0)) { + vkc_ev_data.event_time = obj->val.time; + } + } + + ret = allocate_vkc_event(type, &vkc_ev_data, ev); + if (ret < 0) + goto finish; + + ret = faultd_event_deserialize_internal(data, type, *ev); + if (ret < 0) { + struct vconf_key_changed_event *vkc_ev = + to_vconf_key_changed_event(*ev); + free(vkc_ev); + goto finish; + } + ret = 0; +finish: + return ret; +} + +static void vkc_event_release(struct faultd_event *ev) +{ + struct vconf_key_changed_event *vkc_ev = + to_vconf_key_changed_event(ev); + + if (vkc_ev->key_name) + free(vkc_ev->key_name); + if (vkc_ev->oldval.type == VKC_STRING) + free(vkc_ev->oldval.value.s); + if (vkc_ev->newval.type == VKC_STRING) + free(vkc_ev->newval.value.s); + + faultd_event_cleanup_internal(&vkc_ev->event); + free(vkc_ev); +} + +static void vkc_event_serialize(struct faultd_event *ev, struct faultd_object *out) +{ + struct vconf_key_changed_event *vkc_ev = + to_vconf_key_changed_event(ev); + faultd_event_serialize_internal(ev, out); + faultd_object_append_string(out, VKC_EV_NAME, vkc_ev->key_name); + + switch (vkc_ev->oldval.type) { + case VKC_BOOL: + faultd_object_append_bool(out, VKC_EV_OLDVAL, vkc_ev->oldval.value.b); + break; + case VKC_INT: + faultd_object_append_int(out, VKC_EV_OLDVAL, vkc_ev->oldval.value.i); + break; + case VKC_DOUBLE: + faultd_object_append_double(out, VKC_EV_OLDVAL, vkc_ev->oldval.value.d); + break; + case VKC_STRING: + faultd_object_append_string(out, VKC_EV_OLDVAL, vkc_ev->oldval.value.s); + break; + } + + switch (vkc_ev->newval.type) { + case VKC_BOOL: + faultd_object_append_bool(out, VKC_EV_NEWVAL, vkc_ev->newval.value.b); + break; + case VKC_INT: + faultd_object_append_int(out, VKC_EV_NEWVAL, vkc_ev->newval.value.i); + break; + case VKC_DOUBLE: + faultd_object_append_double(out, VKC_EV_NEWVAL, vkc_ev->newval.value.d); + break; + case VKC_STRING: + faultd_object_append_string(out, VKC_EV_NEWVAL, vkc_ev->newval.value.s); + break; + } + faultd_object_append_time_t(out, VKC_EV_TIME, vkc_ev->event_time); +} + +static struct faultd_event_type vconf_key_changed_event_type = { + .name = VCONF_KEY_CHANGED_EVENT_ID, + .default_ops = { + .release = vkc_event_release, + .serialize = vkc_event_serialize, + }, + .allocate_event = allocate_vkc_event, + .deserialize_event = deserialize_vkc_event, + .node = LIST_HEAD_INIT(vconf_key_changed_event_type.node), +}; + +FAULTD_EVENT_TYPE_REGISTER(vconf_key_changed_event_type, vconf_key_changed_et) diff --git a/src/event_types/vconf_key_changed_event.h b/src/event_types/vconf_key_changed_event.h new file mode 100644 index 0000000..380d303 --- /dev/null +++ b/src/event_types/vconf_key_changed_event.h @@ -0,0 +1,67 @@ +/* + * This file is a part of faultd. + * + * Copyright © 2017 Samsung Electronics + * + * 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. + */ + +#ifndef _FAULTD_VCONF_KEY_CHANGED_EVENT_H +#define _FAULTD_VCONF_KEY_CHANGED_EVENT_H + +#include +#include "event.h" + +#define VCONF_KEY_CHANGED_EVENT_ID "vconf_key_changed" +#define VKC_EV_TIME "et" +#define VKC_EV_NAME "name" +#define VKC_EV_OLDVAL "oldval" +#define VKC_EV_NEWVAL "newval" + +enum vkc_type { + VKC_BOOL, + VKC_INT, + VKC_DOUBLE, + VKC_STRING +}; + +struct vkc_value { + enum vkc_type type; + size_t size; + union { + bool b; + int i; + double d; + char *s; + } value; +}; + +struct vconf_key_changed_event { + struct faultd_event event; + char *key_name; + struct vkc_value oldval; + struct vkc_value newval; + time_t event_time; +}; + +struct vconf_key_changed_event_data { + char *key_name; + struct vkc_value oldval; + struct vkc_value newval; + time_t event_time; +}; + +#define to_vconf_key_changed_event(EVENT) \ + container_of(EVENT, struct vconf_key_changed_event, event) + +#endif /* _FAULTD_VCONF_KEY_CHANGED_EVENT_H */ diff --git a/src/faultd.c b/src/faultd.c index 43d57fd..504ed53 100644 --- a/src/faultd.c +++ b/src/faultd.c @@ -36,6 +36,8 @@ #include "json-config.h" #include "database.h" +#define FAULTD_GLIB_MAINLOOP + static int terminate = 0; enum faultd_running_modes { diff --git a/src/listeners/vconf.c b/src/listeners/vconf.c new file mode 100644 index 0000000..2ca9431 --- /dev/null +++ b/src/listeners/vconf.c @@ -0,0 +1,330 @@ +/* + * This file is part of faultd. + * + * Copyright © 2017 Samsung Electronics + * + * 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 +#include +#include + +#include "log.h" +#include "module.h" +#include "common.h" +#include "list.h" +#include "json-config.h" +#include "event_processor.h" +#include "vconf_key_changed_event.h" + +struct vconf_kv { + char *name; + struct vkc_value val; + struct list_head node; +}; + +struct vconf_listener { + struct faultd_module module; + struct list_head keys; +}; + +#define to_vconf_listener(MOD) \ + container_of(MOD, struct vconf_listener, module) + +static struct vconf_kv *find_vconf_kv(struct vconf_listener *l, const char *name) +{ + struct vconf_kv *k = NULL; + + list_for_each_entry(k, &l->keys, node) { + if (!strcmp(k->name, name)) + return k; + } + return NULL; +} + +static void copy_vkc_value(struct vkc_value *from, struct vkc_value *to) +{ + to->type = from->type; + to->size = from->size; + switch (from->type){ + case VKC_BOOL: + to->value.i = from->value.i; + break; + case VKC_INT: + to->value.i = from->value.i; + break; + case VKC_DOUBLE: + to->value.d = from->value.d; + break; + case VKC_STRING: + to->value.s = strdup(from->value.s); + to->size = strlen (to->value.s); + break; + } + return; +} + +static int set_object_value(struct vconf_kv *k, keynode_t *node) +{ + assert (k); + assert (node); + int ret = 0; + + switch(vconf_keynode_get_type(node)) { + case VCONF_TYPE_INT:{ + int value = vconf_keynode_get_int(node); + //if (value == 0) { + // ret = -1; + // break; + //} + k->val.value.i = value; + k->val.type = VKC_INT; + k->val.size = sizeof(int); + }break; + case VCONF_TYPE_BOOL:{ + int value = vconf_keynode_get_bool(node); + if (value == -1) { + ret = -1; + break; + } + k->val.value.b = value; + k->val.type = VKC_BOOL; + k->val.size = sizeof(bool); + }break; + case VCONF_TYPE_DOUBLE:{ + double value = vconf_keynode_get_dbl(node); + //if (value == 0.0) { + // ret = -1; + // break; + //} + k->val.value.d = value; + k->val.type = VKC_DOUBLE; + k->val.size = sizeof(double); + }break; + case VCONF_TYPE_STRING:{ + char *value = vconf_keynode_get_str(node); + if (!value) { + ret = -1; + break; + } + k->val.value.s = strdup(value); + if (!k->val.value.s) + return -1; + k->val.type = VKC_STRING; + k->val.size = strlen(value); + }break; + default: + ret = -1; + break; + } + + return ret; +} + +static void on_vconf_key_changed(keynode_t *key, void *data) +{ + struct vconf_listener *l = (struct vconf_listener *)data; + char *name = NULL; + struct vconf_key_changed_event_data vkc_ev_data = {}; + struct faultd_event *ev; + struct timespec ts; + int ret = 0; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { + log_error_errno(errno, "Unable to get timestamp : %m"); + return; + } + + name = vconf_keynode_get_name(key); + if (!name) { + log_debug("vconf: key name not found (key=%s)", name); + return; + } + + struct vconf_kv *k = find_vconf_kv(l, name); + if (!k) { + log_debug("vconf: key-value pair not found (key=%s)", name); + return; + } + + vkc_ev_data.event_time = ts.tv_sec; + vkc_ev_data.key_name = strdup(name); + if (vkc_ev_data.key_name == NULL) + goto finish; + + copy_vkc_value(&k->val, &vkc_ev_data.oldval); + if (k->val.type == VKC_STRING) { + free(k->val.value.s); + k->val.value.s = NULL; + } + + if (set_object_value(k, key) < 0) + goto finish; + + copy_vkc_value(&k->val, &vkc_ev_data.newval); + + ret = faultd_event_create(VCONF_KEY_CHANGED_EVENT_ID, &vkc_ev_data, &ev); + if (ret) { + log_error_errno(ret, "Unable to allocate an event: %m."); + goto finish; + } + + ret = event_processor_report_event(ev); + faultd_event_unref(ev); + if (ret) + log_error_errno(ret, "Unable to report event: %m"); + return; +finish: + free(vkc_ev_data.key_name); + if (vkc_ev_data.oldval.type == VKC_STRING) + free(vkc_ev_data.oldval.value.s); + if (vkc_ev_data.newval.type == VKC_STRING) + free(vkc_ev_data.newval.value.s); + + return; +} + +static int add_key(struct vconf_listener *l, const char *key, keynode_t *node) +{ + int ret = 0; + struct vconf_kv *k; + + assert (l); + assert (key); + assert (node); + + k = (struct vconf_kv*)malloc(sizeof(struct vconf_kv)); + if (k == NULL) { + ret = -ENOMEM; + goto cleanup; + } + + k->name = strdup(key); + if (k->name == NULL) { + ret = -ENOMEM; + goto cleanup; + } + + if (set_object_value(k, node) < 0) { + ret = -EINVAL; + goto cleanup; + } + + list_add_tail(&k->node, &l->keys); + vconf_notify_key_changed(key, on_vconf_key_changed, l); + return 0; + +cleanup: + if (k) { + free(k->name); + free(k); + } + return ret; +} + +static void cleanup(struct vconf_listener *l) +{ + struct vconf_kv *k, *next; + + list_for_each_entry_safe(k, next, &l->keys, node) { + list_del(&k->node); + free(k->name); + if (k->val.type == VKC_STRING) + free(k->val.value.s); + free(k); + } +} + +static int vconf_listener_init(struct faultd_module *module, + struct faultd_config *config, + sd_event* event) +{ + struct vconf_listener *listener = to_vconf_listener(module); + int ret = 0; + json_object *arr, *val; + keylist_t *klist; + keynode_t *knode; + + INIT_LIST_HEAD(&listener->keys); + + if (!json_object_object_get_ex(config->root, "keys", &arr)) { + log_error("Config does not contain 'keys' parameter."); + ret = -EINVAL; + goto cleanup; + } + + if (!json_object_is_type(arr, json_type_array)) { + log_error("Config value is not an array"); + ret = -EINVAL; + goto cleanup; + } + + for (size_t i = 0; i < json_object_array_length(arr); i++) { + val = json_object_array_get_idx(arr, i); + if (val == NULL) { + log_error("vconf: no specified key (%d)\n", i); + ret = -EINVAL; + goto cleanup; + } + + klist = vconf_keylist_new(); + if (!klist) { + log_error("vconf: could not create keylist for %s\n", json_object_get_string(val)); + continue; + } + + ret = vconf_get(klist, json_object_get_string(val), VCONF_GET_ALL); + if (ret < 0) { + log_debug("vconf: keylist does not contain key %s\n", json_object_get_string(val)); + goto free_list; + } + + ret = vconf_keylist_lookup(klist, json_object_get_string(val), &knode); + if (ret < 0) { + log_debug("vconf_keylist_lookup failed for %s\n", json_object_get_string(val)); + goto free_list; + } + + ret = add_key(listener, json_object_get_string(val), knode); + if (ret < 0) + log_error("vconf: could not add key\n"); + + free_list: + vconf_keylist_free(klist); + } + return 0; + +cleanup: + cleanup(listener); + return ret; +} + +static void vconf_listener_cleanup(struct faultd_module *module) +{ + struct vconf_listener *listener = to_vconf_listener(module); + cleanup(listener); +} + +struct vconf_listener vconf_listener = { + .module = { + .name = "vconf_listener", + .type = FAULTD_MODULE_TYPE_LISTENER, + + .init = vconf_listener_init, + .cleanup = vconf_listener_cleanup, + .node = LIST_HEAD_INIT(vconf_listener.module.node), + }, +}; + +FAULTD_MODULE_REGISTER(&vconf_listener.module) diff --git a/src/util/common.c b/src/util/common.c index b9b53bc..e2e8df0 100644 --- a/src/util/common.c +++ b/src/util/common.c @@ -47,6 +47,8 @@ static const size_t data_size[] = { [TYPE_INT] = sizeof(int), [TYPE_TIMESPEC] = sizeof(struct timespec), [TYPE_TIME_T] = sizeof(time_t), + [TYPE_BOOL] = sizeof(bool), + [TYPE_DOUBLE] = sizeof(double), [TYPE_UUID] = sizeof(sd_id128_t), [TYPE_OBJECT] = sizeof(struct list_head), }; @@ -57,6 +59,8 @@ static char *faultd_object_type_names[] = { [TYPE_INT] = "TYPE_INT", [TYPE_TIMESPEC] = "TYPE_TIMESPEC", [TYPE_TIME_T] = "TYPE_TIME_T", + [TYPE_BOOL] = "TYPE_BOOL", + [TYPE_DOUBLE] = "TYPE_DOUBLE", [TYPE_UUID] = "TYPE_UUID", [TYPE_OBJECT] = "TYPE_OBJECT", }; diff --git a/src/util/common.h b/src/util/common.h index 2db6c36..0413dc6 100644 --- a/src/util/common.h +++ b/src/util/common.h @@ -76,6 +76,8 @@ enum faultd_object_type { TYPE_INT, TYPE_TIMESPEC, TYPE_TIME_T, + TYPE_BOOL, + TYPE_DOUBLE, TYPE_UUID, TYPE_OBJECT, }; @@ -103,6 +105,8 @@ union faultd_object_value { int i; struct timespec ts; time_t time; + bool b; + double d; sd_id128_t uuid; struct list_head children; }; @@ -163,6 +167,18 @@ static inline int faultd_object_append_int(struct faultd_object *obj, return faultd_object_append_new(obj, key, TYPE_INT, &val); } +static inline int faultd_object_append_bool(struct faultd_object *obj, + const char *key, bool val) +{ + return faultd_object_append_new(obj, key, TYPE_BOOL, &val); +} + +static inline int faultd_object_append_double(struct faultd_object *obj, + const char *key, double val) +{ + return faultd_object_append_new(obj, key, TYPE_DOUBLE, &val); +} + static inline int faultd_object_append_time_t(struct faultd_object *obj, const char *key, time_t val) { @@ -192,6 +208,18 @@ static inline int faultd_object_get_string(struct faultd_object *obj, return faultd_object_get_val(obj, key, TYPE_STRING, val); } +static inline int faultd_object_get_double(struct faultd_object *obj, + const char *key, double *val) +{ + return faultd_object_get_val(obj, key, TYPE_DOUBLE, val); +} + +static inline int faultd_object_get_bool(struct faultd_object *obj, + const char *key, bool *val) +{ + return faultd_object_get_val(obj, key, TYPE_BOOL, val); +} + static inline int faultd_object_get_oid(struct faultd_object *obj, const char *key, faultd_oid_t *val) {