Add 'system booted' event 11/130511/7
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Mon, 22 May 2017 11:24:14 +0000 (13:24 +0200)
committerPaweł Szewczyk <p.szewczyk@samsung.com>
Wed, 21 Jun 2017 09:50:54 +0000 (11:50 +0200)
Event is generated based on boot id stored in database. This commit is
based on stub implementation of last boot id retrieval from db.

Change-Id: I59c22fbae6eeebda9de83e7905aed478711cc655
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
Makefile.am
src/event_types/system_booted_event.c [new file with mode: 0644]
src/event_types/system_booted_event.h [new file with mode: 0644]
src/listeners/startup.c

index 340aa823068fbfbcf626f517809c3f0c6272130d..e552a8b0b68326ee6f8bb01dff214337eb133b81 100644 (file)
@@ -61,6 +61,7 @@ faultd_SOURCES = \
     src/event_types/resource_violation_event.c \
     src/event_types/service_failed_event.c \
     src/event_types/faultd_started_event.c \
+    src/event_types/system_booted_event.c \
     src/faultd.c \
     src/listeners/audit.c \
     src/listeners/systemd.c \
diff --git a/src/event_types/system_booted_event.c b/src/event_types/system_booted_event.c
new file mode 100644 (file)
index 0000000..637c2be
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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 <ejdb/bson.h>
+#include <stdio.h>
+#include <errno.h>
+#include <malloc.h>
+
+#include "system_booted_event.h"
+
+static int allocate_sb_event(struct faultd_event_type *type,
+                             void *data, struct faultd_event **ev)
+{
+       struct system_booted_event *sb_ev;
+       struct sb_event_data *sb_ev_data = data;
+       int ret;
+
+       sb_ev = malloc(sizeof(*sb_ev));
+       if (!sb_ev)
+               return -ENOMEM;
+       memset(sb_ev, 0, sizeof(*sb_ev));
+
+       ret = faultd_event_init_internal(type, &sb_ev->event);
+       if (ret)
+               goto free_sb_ev;
+
+       sb_ev->prev_boot_id = sb_ev_data->prev_boot_id;
+       *ev = &sb_ev->event;
+
+       return 0;
+free_sb_ev:
+       free(sb_ev);
+       return ret;
+}
+
+static void sb_event_release(struct faultd_event *ev)
+{
+       struct system_booted_event *sb_ev=
+               to_system_booted_event(ev);
+
+       faultd_event_cleanup_internal(&sb_ev->event);
+       free(sb_ev);
+}
+
+static char *sb_event_to_string(struct faultd_event *ev)
+{
+       struct system_booted_event *sb_ev =
+               to_system_booted_event(ev);
+       char *str;
+       int ret;
+
+       ret = asprintf(&str, "System booted event:"
+                                  " Time: %lld.%.9ld"
+                                  " Previous boot ID: %s"
+                                  " Current boot ID: %s",
+                                  (long long)ev->timestamp.tv_sec,
+                                  ev->timestamp.tv_nsec,
+                                  SD_ID128_CONST_STR(sb_ev->prev_boot_id),
+                                  SD_ID128_CONST_STR(ev->boot_id)
+                                  );
+
+       return ret > 0 ? str : NULL;
+}
+
+static void sb_event_serialize(struct faultd_event *ev, bson *out)
+{
+       struct system_booted_event *sb_ev=
+               to_system_booted_event(ev);
+
+       faultd_event_serialize_internal(ev, out);
+       bson_append_binary(out, "prev_boot_id", BSON_BIN_UUID,
+                       (char *)&sb_ev->prev_boot_id, sizeof(sb_ev->prev_boot_id));
+}
+
+static struct faultd_event_type system_booted_event_type = {
+       .name = SYSTEM_BOOTED_EVENT_ID,
+       .default_ops = {
+               .release = sb_event_release,
+               .serialize = sb_event_serialize,
+               .to_string = sb_event_to_string,
+       },
+       .allocate_event = allocate_sb_event,
+       .node = LIST_HEAD_INIT(system_booted_event_type.node),
+};
+
+FAULTD_EVENT_TYPE_REGISTER(system_booted_event_type, system_booted_et)
diff --git a/src/event_types/system_booted_event.h b/src/event_types/system_booted_event.h
new file mode 100644 (file)
index 0000000..c6676c6
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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_SYSTEM_BOOTED_EVENT_H
+#define FAULTD_SYSTEM_BOOTED_EVENT_H
+
+#include <time.h>
+
+#include "event.h"
+#include "common.h"
+#include "service.h"
+
+#define SYSTEM_BOOTED_EVENT_ID "system_booted"
+
+struct system_booted_event {
+       struct faultd_event event;
+       sd_id128_t prev_boot_id;
+};
+
+struct sb_event_data {
+       sd_id128_t prev_boot_id;
+};
+
+#define to_system_booted_event(EVENT)                                          \
+       container_of(EVENT, struct system_booted_event, event)
+
+#endif /* FAULTD_SYSTEM_BOOTED_EVENT_H */
index e5b998f0961f8898c1952fba20d8e4f2dfedc64f..0811db566bbfaff43506979255fddba44a56b7b3 100644 (file)
 #include "event.h"
 #include "event_processor.h"
 #include "faultd_started_event.h"
+#include "system_booted_event.h"
+#include "database.h"
+
+#define LAST_BOOT_ID_OID "32a4ca4f96ddfcd8aa1f5026"
 
 struct startup_listener {
        struct faultd_module module;
 };
 
+static int retrieve_last_boot_id(sd_id128_t *boot_id)
+{
+       /* stub */
+       *boot_id = SD_ID128_NULL;
+       return 0;
+}
+
+static void store_boot_id(sd_id128_t *boot_id)
+{
+       bson b;
+       bson_oid_t oid;
+
+       bson_oid_from_string(&oid, LAST_BOOT_ID_OID);
+
+       bson_init(&b);
+       bson_append_oid(&b, JDBIDKEYNAME, &oid);
+       bson_append_binary(&b, "boot_id", BSON_BIN_UUID, (char *)boot_id, sizeof(*boot_id));
+       bson_finish(&b);
+
+       database_store(&b, &oid);
+       bson_destroy(&b);
+}
+
 static int startup_listener_init(struct faultd_module *module,
                struct faultd_config *cfg, sd_event *event)
 {
        int rc;
-       struct faultd_event *ev;
+       struct faultd_event *started_ev, *booted_ev;
+       struct sb_event_data sb_ev_data;
+       sd_id128_t boot_id;
+
+       rc = faultd_event_create(FAULTD_STARTED_EVENT_ID, NULL, &started_ev);
+       if (rc) {
+               log_error_errno(rc, "Unable to allocate an event");
+               return rc;
+       }
+
+       rc = event_processor_report_event(started_ev);
+       if (rc) {
+               log_error_errno(rc, "Unable to report event");
+               faultd_event_unref(started_ev);
+               return rc;
+       }
+
+       rc = retrieve_last_boot_id(&boot_id);
+       if (rc < 0) {
+               log_error_errno(rc, "Could not retrieve boot id");
+               return rc;
+       }
+
+       if (sd_id128_equal(started_ev->boot_id, boot_id))
+               return 0;
+
+       store_boot_id(&started_ev->boot_id);
+       sb_ev_data.prev_boot_id = boot_id;
 
-       rc = faultd_event_create(FAULTD_STARTED_EVENT_ID, NULL, &ev);
+       rc = faultd_event_create(SYSTEM_BOOTED_EVENT_ID, &sb_ev_data, &booted_ev);
        if (rc) {
                log_error_errno(rc, "Unable to allocate an event");
                return rc;
        }
 
-       rc = event_processor_report_event(ev);
+       rc = event_processor_report_event(booted_ev);
        if (rc) {
                log_error_errno(rc, "Unable to report event");
-               faultd_event_unref(ev);
+               faultd_event_unref(booted_ev);
                return rc;
        }