summaryrefslogtreecommitdiffstats
path: root/src/blkin/blkin-lib/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/blkin/blkin-lib/tests')
-rw-r--r--src/blkin/blkin-lib/tests/CMakeLists.txt15
-rw-r--r--src/blkin/blkin-lib/tests/Makefile55
-rw-r--r--src/blkin/blkin-lib/tests/test.c200
-rw-r--r--src/blkin/blkin-lib/tests/test.cc204
-rw-r--r--src/blkin/blkin-lib/tests/test_p.cc210
5 files changed, 684 insertions, 0 deletions
diff --git a/src/blkin/blkin-lib/tests/CMakeLists.txt b/src/blkin/blkin-lib/tests/CMakeLists.txt
new file mode 100644
index 00000000..d69cec3d
--- /dev/null
+++ b/src/blkin/blkin-lib/tests/CMakeLists.txt
@@ -0,0 +1,15 @@
+#test
+add_executable(testc test.c)
+target_link_libraries(testc blkin lttng-ust)
+add_test(NAME testc COMMAND $<TARGET_FILE:testc>)
+
+#testpp
+add_executable(testpp test.cc)
+set_target_properties(testpp PROPERTIES COMPILE_FLAGS "-std=c++11")
+target_link_libraries(testpp blkin lttng-ust pthread)
+add_test(NAME testpp COMMAND $<TARGET_FILE:testpp>)
+
+#testppp
+add_executable(testppp test_p.cc)
+target_link_libraries(testppp blkin lttng-ust)
+add_test(NAME testppp COMMAND $<TARGET_FILE:testppp>)
diff --git a/src/blkin/blkin-lib/tests/Makefile b/src/blkin/blkin-lib/tests/Makefile
new file mode 100644
index 00000000..bed3fc86
--- /dev/null
+++ b/src/blkin/blkin-lib/tests/Makefile
@@ -0,0 +1,55 @@
+# Copyright 2014 Marios Kogias <marioskogias@gmail.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or
+# without modification, are permitted provided that the following
+# conditions are met:
+#
+# 1. Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the following
+# disclaimer.
+# 2. Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+.PHONY: default clean distclean run run_c run_pp
+
+LIB_DIR=$(shell pwd)/..
+DLIB=$(LIB_DIR)/libblkin
+
+test: test.c $(DLIB).so
+ gcc test.c -o test -g -I$(LIB_DIR) -L$(LIB_DIR) -lblkin
+
+testpp: test.cc $(DLIB).so
+ LD_LIBRARY_PATH=$(LIB_DIR) g++ $< -o testpp -std=c++11 -g -I$(LIB_DIR) -L$(LIB_DIR) -lblkin -lpthread
+
+testppp: test_p.cc $(DLIB).so
+ LD_LIBRARY_PATH=$(LIB_DIR) g++ $< -o testppp -g -I$(LIB_DIR) -L$(LIB_DIR) -lblkin
+
+run_c:
+ LD_LIBRARY_PATH=$(LIB_DIR) ./test
+
+run_pp:
+ LD_LIBRARY_PATH=$(LIB_DIR) ./testpp
+
+run_ppp:
+ LD_LIBRARY_PATH=$(LIB_DIR) ./testppp
+
+run: run_c run_pp
+
+clean:
+ rm -f *.o *.so test testpp testppp socket
diff --git a/src/blkin/blkin-lib/tests/test.c b/src/blkin/blkin-lib/tests/test.c
new file mode 100644
index 00000000..2cabd99b
--- /dev/null
+++ b/src/blkin/blkin-lib/tests/test.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2014 Marios Kogias <marioskogias@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * In this example we have 2 processes communicating over a unix socket.
+ * We are going to trace the communication with our library
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <zipkin_c.h>
+
+#define SOCK_PATH "/tmp/socket"
+
+struct message {
+ char actual_message[20];
+ struct blkin_trace_info trace_info;
+};
+
+void process_a()
+{
+ int i, r;
+ printf("I am process A: %d\n", getpid());
+
+ r = blkin_init();
+ if (r < 0) {
+ fprintf(stderr, "Could not initialize blkin\n");
+ exit(1);
+ }
+
+ /*initialize endpoint*/
+ struct blkin_endpoint endp;
+ blkin_init_endpoint(&endp, "10.0.0.1", 5000, "service a");
+
+ struct blkin_trace trace;
+ struct blkin_annotation ant;
+ struct message msg = {.actual_message = "message"};
+ char ack;
+
+ /*create and bind socket*/
+ int s, s2, len;
+ socklen_t t;
+ struct sockaddr_un local, remote;
+
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ perror("socket");
+ exit(1);
+ }
+
+ local.sun_family = AF_UNIX;
+ strcpy(local.sun_path, SOCK_PATH);
+ unlink(local.sun_path);
+ len = strlen(local.sun_path) + sizeof(local.sun_family);
+ if (bind(s, (struct sockaddr *)&local, len) == -1) {
+ perror("bind");
+ exit(1);
+ }
+
+ if (listen(s, 5) == -1) {
+ perror("listen");
+ exit(1);
+ }
+
+ printf("Waiting for a connection...\n");
+ t = sizeof(remote);
+ if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
+ perror("accept");
+ exit(1);
+ }
+
+ printf("Connected.\n");
+
+ for (i=0;i<10;i++) {
+
+ /*create trace*/
+ blkin_init_new_trace(&trace, "process a", &endp);
+
+ blkin_init_timestamp_annotation(&ant, "start", &endp);
+ blkin_record(&trace, &ant);
+
+ /*set trace fields to message*/
+ blkin_get_trace_info(&trace, &msg.trace_info);
+
+ /*send*/
+ send(s2, &msg, sizeof(struct message), 0);
+
+ /*wait for ack*/
+ recv(s2, &ack, 1, 0);
+
+ /*create annotation and log*/
+ blkin_init_timestamp_annotation(&ant, "end", &endp);
+ blkin_record(&trace, &ant);
+ }
+ close(s2);
+}
+
+void process_b()
+{
+ int i, r;
+ printf("I am process B: %d\n", getpid());
+
+ r = blkin_init();
+ if (r < 0) {
+ fprintf(stderr, "Could not initialize blkin\n");
+ exit(1);
+ }
+ /*initialize endpoint*/
+ struct blkin_endpoint endp;
+ blkin_init_endpoint(&endp, "10.0.0.2", 5001, "service b");
+
+ struct blkin_trace trace;
+ struct blkin_annotation ant;
+ struct message msg;
+ int s, len;
+ struct sockaddr_un remote;
+
+ /*Connect*/
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ perror("socket");
+ exit(1);
+ }
+
+ printf("Trying to connect...\n");
+
+ remote.sun_family = AF_UNIX;
+ strcpy(remote.sun_path, SOCK_PATH);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+ if (connect(s, (struct sockaddr *)&remote, len) == -1) {
+ perror("connect");
+ exit(1);
+ }
+
+ printf("Connected.\n");
+
+ for (i=0;i<10;i++) {
+ recv(s, &msg, sizeof(struct message), 0);
+
+ /*create child trace*/
+ blkin_init_child_info(&trace, &msg.trace_info, &endp, "process b");
+
+ /*create annotation and log*/
+ blkin_init_timestamp_annotation(&ant, "start", &endp);
+ blkin_record(&trace, &ant);
+
+ /*Process...*/
+ usleep(10);
+ printf("Message received %s\n", msg.actual_message);
+
+ /*create annotation and log*/
+ blkin_init_timestamp_annotation(&ant, "end", &endp);
+ blkin_record(&trace, &ant);
+
+ /*send ack*/
+ send(s, "*", 1, 0);
+ }
+}
+
+
+int main()
+{
+ if (fork()){
+ process_a();
+ exit(0);
+ }
+ else{
+ process_b();
+ exit(0);
+ }
+}
diff --git a/src/blkin/blkin-lib/tests/test.cc b/src/blkin/blkin-lib/tests/test.cc
new file mode 100644
index 00000000..f93597dd
--- /dev/null
+++ b/src/blkin/blkin-lib/tests/test.cc
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2014 Marios Kogias <marioskogias@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <thread>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <ztracer.hpp>
+#include <iostream>
+
+#define SOCK_PATH "socket"
+
+struct message {
+ int actual_message;
+ struct blkin_trace_info trace_info;
+ message(int s) : actual_message(s) {};
+ message() {}
+};
+
+class Parent {
+ private:
+ int s, s2;
+ ZTracer::Endpoint e;
+ public:
+ Parent() : e("0.0.0.0", 1, "parent")
+ {
+ connect();
+ }
+ void operator()()
+ {
+ struct sockaddr_un remote;
+ int t;
+ std::cout << "I am parent process : " << getpid() << std::endl;
+
+ /* Wait for connection */
+ t = sizeof(remote);
+ if ((s2 = accept(s, (struct sockaddr *)&remote, (socklen_t *)&t)) == -1) {
+ std::cerr << "accept" << std::endl;
+ exit(1);
+ }
+
+ std::cerr << "Connected" << std::endl;
+
+ for (int i=0;i<10;i++) {
+ /*Init trace*/
+ ZTracer::Trace tr("parent process", &e);
+
+ process(tr);
+
+ wait_response();
+
+ /*Log received*/
+ tr.event("parent end");
+ }
+ }
+
+ void process(ZTracer::Trace &tr)
+ {
+ struct message msg(rand());
+ /*Annotate*/
+ tr.event("parent start");
+ /*Set trace info to the message*/
+ msg.trace_info = *tr.get_info();
+
+ /*send*/
+ send(s2, &msg, sizeof(struct message), 0);
+ }
+
+ void wait_response()
+ {
+ char ack;
+ recv(s2, &ack, 1, 0);
+ }
+
+ void connect()
+ {
+ /*create and bind socket*/
+ int len;
+ struct sockaddr_un local;
+
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ std::cerr << "socket" << std::endl;
+ exit(1);
+ }
+
+ local.sun_family = AF_UNIX;
+ strcpy(local.sun_path, SOCK_PATH);
+ unlink(local.sun_path);
+ len = strlen(local.sun_path) + sizeof(local.sun_family);
+ if (bind(s, (struct sockaddr *)&local, len) == -1) {
+ std::cerr << "bind" << std::endl;
+ exit(1);
+ }
+
+ if (listen(s, 5) == -1) {
+ std::cerr << "listen" << std::endl;
+ exit(1);
+ }
+
+ std::cout << "Waiting for a connection..." << std::endl;
+ }
+
+};
+
+class Child {
+ private:
+ int s;
+ ZTracer::Endpoint e;
+ public:
+ Child() : e("0.0.0.1", 2, "child")
+ {
+ }
+ void operator()()
+ {
+ /*Connect to the socket*/
+ soc_connect();
+
+ for (int i=0;i<10;i++)
+ process();
+ }
+
+ void process()
+ {
+ struct message msg;
+ recv(s, &msg, sizeof(struct message), 0);
+
+ ZTracer::Trace tr("Child process", &e, &msg.trace_info, true);
+ tr.event("child start");
+
+ usleep(10);
+ std::cout << "Message received : " << msg.actual_message << ::std::endl;
+ tr.event("child end");
+
+ send(s, "*", 1, 0);
+ }
+
+
+ void soc_connect()
+ {
+ int len;
+ struct sockaddr_un remote;
+
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ std::cerr << "socket" << std::endl;
+ exit(1);
+ }
+
+ std::cout << "Trying to connect...\n" << std::endl;
+
+ remote.sun_family = AF_UNIX;
+ strcpy(remote.sun_path, SOCK_PATH);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+ if (connect(s, (struct sockaddr *)&remote, len) == -1) {
+ std::cerr << "connect" << std::endl;;
+ exit(1);
+ }
+
+ std::cout << "Connected" << std::endl;
+ }
+
+};
+int main(int argc, const char *argv[])
+{
+ int r = ZTracer::ztrace_init();
+ if (r < 0) {
+ std::cout << "Error initializing blkin" << std::endl;
+ return -1;
+ }
+ Parent p;
+ Child c;
+ std::thread workerThread1(p);
+ std::thread workerThread2(c);
+ workerThread1.join();
+ workerThread2.join();
+
+ return 0;
+}
diff --git a/src/blkin/blkin-lib/tests/test_p.cc b/src/blkin/blkin-lib/tests/test_p.cc
new file mode 100644
index 00000000..ec59da3b
--- /dev/null
+++ b/src/blkin/blkin-lib/tests/test_p.cc
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2014 Marios Kogias <marioskogias@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <ztracer.hpp>
+#include <iostream>
+#include <cstdlib>
+
+#define SOCK_PATH "socket"
+
+struct message {
+ int actual_message;
+ struct blkin_trace_info trace_info;
+ message(int s) : actual_message(s) {};
+ message() {}
+};
+
+class Parent {
+ private:
+ int s, s2;
+ ZTracer::Endpoint e;
+ public:
+ Parent() : e("0.0.0.0", 1, "parent")
+ {
+ connect();
+ }
+ void operator()()
+ {
+ struct sockaddr_un remote;
+ int t;
+ std::cout << "I am parent process : " << getpid() << std::endl;
+
+ /* Wait for connection */
+ t = sizeof(remote);
+ if ((s2 = accept(s, (struct sockaddr *)&remote, (socklen_t *)&t)) == -1) {
+ std::cerr << "accept" << std::endl;
+ exit(1);
+ }
+
+ std::cerr << "Connected" << std::endl;
+
+ for (int i=0;i<10;i++) {
+ /*Init trace*/
+ ZTracer::Trace tr("parent process", &e);
+ process(tr);
+
+ wait_response();
+
+ /*Log received*/
+ tr.event("parent end");
+ }
+ }
+
+ void process(ZTracer::Trace &tr)
+ {
+ struct message msg(rand());
+ /*Annotate*/
+ tr.event("parent start");
+ /*Set trace info to the message*/
+ msg.trace_info = *tr.get_info();
+
+ /*send*/
+ send(s2, &msg, sizeof(struct message), 0);
+ }
+
+ void wait_response()
+ {
+ char ack;
+ recv(s2, &ack, 1, 0);
+ }
+
+ void connect()
+ {
+ /*create and bind socket*/
+ int len;
+ struct sockaddr_un local;
+
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ std::cerr << "socket" << std::endl;
+ exit(1);
+ }
+
+ local.sun_family = AF_UNIX;
+ strcpy(local.sun_path, SOCK_PATH);
+ unlink(local.sun_path);
+ len = strlen(local.sun_path) + sizeof(local.sun_family);
+ if (bind(s, (struct sockaddr *)&local, len) == -1) {
+ std::cerr << "bind" << std::endl;
+ exit(1);
+ }
+
+ if (listen(s, 5) == -1) {
+ std::cerr << "listen" << std::endl;
+ exit(1);
+ }
+
+ std::cout << "Waiting for a connection..." << std::endl;
+ }
+
+};
+
+class Child {
+ private:
+ int s;
+ ZTracer::Endpoint e;
+ public:
+ Child() : e("0.0.0.1", 2, "child")
+ {
+ }
+ void operator()()
+ {
+ /*Connect to the socket*/
+ soc_connect();
+
+ for (int i=0;i<10;i++)
+ process();
+ }
+
+ void process()
+ {
+ struct message msg;
+ recv(s, &msg, sizeof(struct message), 0);
+
+ ZTracer::Trace tr("Child process", &e, &msg.trace_info, true);
+ tr.event("child start");
+
+ usleep(10);
+ std::cout << "Message received : " << msg.actual_message << ::std::endl;
+ tr.event("child end");
+
+ send(s, "*", 1, 0);
+ }
+
+
+ void soc_connect()
+ {
+ int len;
+ struct sockaddr_un remote;
+
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ std::cerr << "socket" << std::endl;
+ exit(1);
+ }
+
+ std::cout << "Trying to connect...\n" << std::endl;
+
+ remote.sun_family = AF_UNIX;
+ strcpy(remote.sun_path, SOCK_PATH);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+ if (connect(s, (struct sockaddr *)&remote, len) == -1) {
+ std::cerr << "connect" << std::endl;;
+ exit(1);
+ }
+
+ std::cout << "Connected" << std::endl;
+ }
+
+};
+int main(int argc, const char *argv[])
+{
+ if (fork()) {
+ int r = ZTracer::ztrace_init();
+ if (r < 0) {
+ std::cout << "Error initializing blkin" << std::endl;
+ exit(1);
+ }
+ Parent p;
+ p();
+ exit(0);
+ } else {
+ int r = ZTracer::ztrace_init();
+ if (r < 0) {
+ std::cout << "Error initializing blkin" << std::endl;
+ exit(1);
+ }
+ Child c;
+ c();
+ exit(0);
+ }
+ return 0;
+}