diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2022-04-17 14:15:24 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2022-04-17 14:15:24 +0000 |
commit | f26bb872bf4f043a1b817c808a6947fcb03ecda4 (patch) | |
tree | 132ab4d71c41c26fe05e12a57fc9e684ffbd08ec /testing | |
parent | 5e7262973c7b0bf753e5e560956c176d9d12424d (diff) | |
download | sg3_utils-f26bb872bf4f043a1b817c808a6947fcb03ecda4.tar.gz |
sg_lib: add hex2fp(); sg_rtpg: https://github.com/hreinecke/sg3_utils/pull/79 applies; json_builder work
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@944 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'testing')
-rw-r--r-- | testing/Makefile | 10 | ||||
-rw-r--r-- | testing/sg_mrq_dd.cpp | 28 | ||||
-rw-r--r-- | testing/sg_tst_json_builder.c | 157 |
3 files changed, 182 insertions, 13 deletions
diff --git a/testing/Makefile b/testing/Makefile index 46d00a2e..5d05ad5a 100644 --- a/testing/Makefile +++ b/testing/Makefile @@ -7,7 +7,7 @@ MANDIR=$(DESTDIR)/$(PREFIX)/man EXECS = sg_sense_test sg_queue_tst bsg_queue_tst sg_chk_asc sg_tst_nvme \ sg_tst_ioctl sg_tst_bidi tst_sg_lib sgs_dd sg_tst_excl \ sg_tst_excl2 sg_tst_excl3 sg_tst_context sg_tst_async sgh_dd \ - sg_mrq_dd sg_iovec_tst sg_take_snap + sg_mrq_dd sg_iovec_tst sg_take_snap sg_tst_json_builder EXTRAS = @@ -49,7 +49,8 @@ LIBFILESOLD = ../lib/sg_lib.o ../lib/sg_lib_data.o ../lib/sg_io_linux.o LIBFILESNEW = ../lib/sg_pt_linux_nvme.o ../lib/sg_lib.o ../lib/sg_lib_data.o \ ../lib/sg_pt_linux.o ../lib/sg_io_linux.o \ ../lib/sg_pt_common.o ../lib/sg_cmds_basic.o \ - ../lib/sg_cmds_basic2.o ../lib/sg_lib_names.o + ../lib/sg_cmds_basic2.o ../lib/sg_lib_names.o \ + ../lib/sg_json_builder.o all: $(EXECS) @@ -63,7 +64,7 @@ depend dep: done > .depend clean: - /bin/rm -f *.o $(EXECS) $(EXTRAS) $(BSG_EXTRAS) core .depend + /bin/rm -f *.o $(EXECS) $(EXTRAS) $(BSG_EXTRAS) json_writer core .depend sg_sense_test: sg_sense_test.o $(LIBFILESOLD) $(LD) -o $@ $(LDFLAGS) $^ @@ -120,6 +121,9 @@ sg_iovec_tst: sg_iovec_tst.o sg_scat_gath.o $(LIBFILESNEW) sg_take_snap: sg_take_snap.o $(LIBFILESNEW) $(LD) -o $@ $(LDFLAGS) $^ +sg_tst_json_builder: sg_tst_json_builder.o $(LIBFILESNEW) + $(LD) -o $@ $(LDFLAGS) $^ + install: $(EXECS) install -d $(INSTDIR) diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp index 7b81a63a..9f17146c 100644 --- a/testing/sg_mrq_dd.cpp +++ b/testing/sg_mrq_dd.cpp @@ -30,7 +30,7 @@ * */ -static const char * version_str = "1.40 20220118"; +static const char * version_str = "1.41 20220413"; #define _XOPEN_SOURCE 600 #ifndef _GNU_SOURCE @@ -390,6 +390,7 @@ static atomic<int> num_ebusy(0); static atomic<int> num_start_eagain(0); static atomic<int> num_fin_eagain(0); static atomic<int> num_miscompare(0); +static atomic<int> num_fallthru_sigusr2(0); static atomic<bool> vb_first_time(true); static sigset_t signal_set; @@ -1072,17 +1073,16 @@ siginfo_handler(int sig) print_stats(" "); } -#if 0 +/* Usually this signal (SIGUSR2) will be caught by the timed wait in the + * sig_listen_thread thread but some might slip through while the timed + * wait is being re-armed or after that thread is finished. This handler + * acts as a backstop. */ static void siginfo2_handler(int sig) { if (sig) { ; } /* unused, dummy to suppress warning */ - pr2serr("Progress report, continuing ...\n"); - if (do_time > 0) - calc_duration_throughput(1); - print_stats(" "); + ++num_fallthru_sigusr2; } -#endif static void install_handler(int sig_num, void (*sig_handler) (int sig)) @@ -4247,7 +4247,7 @@ main(int argc, char * argv[]) install_handler(SIGQUIT, interrupt_handler); install_handler(SIGPIPE, interrupt_handler); install_handler(SIGUSR1, siginfo_handler); - // install_handler(SIGUSR2, siginfo2_handler); + install_handler(SIGUSR2, siginfo2_handler); num_ifiles = clp->inf_v.size(); num_ofiles = clp->outf_v.size(); @@ -4590,9 +4590,11 @@ jump: } std::this_thread::yield(); // not enough it seems { /* allow time for SIGUSR2 signal to get through */ - struct timespec tspec = {0, 400000}; /* 400 usecs */ + struct timespec tspec = {0, 1000000}; /* 1 msec */ + struct timespec rem; - nanosleep(&tspec, NULL); + while ((nanosleep(&tspec, &rem) < 0) && (EINTR == errno)) + tspec = rem; } } @@ -4645,5 +4647,11 @@ fini: if (0 == res) res = clp->reason_res.load(); sigprocmask(SIG_SETMASK, &orig_signal_set, NULL); + if (clp->verbose) { + int num_sigusr2 = num_fallthru_sigusr2.load(); + if (num_sigusr2 > 0) + pr2serr("Number of fall-through SIGUSR2 signals caught: %d\n", + num_sigusr2); + } return (res >= 0) ? res : SG_LIB_CAT_OTHER; } diff --git a/testing/sg_tst_json_builder.c b/testing/sg_tst_json_builder.c new file mode 100644 index 00000000..f91e600a --- /dev/null +++ b/testing/sg_tst_json_builder.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Simple streaming JSON writer + * + * This takes care of the annoying bits of JSON syntax like the commas + * after elements + * + * Authors: Stephen Hemminger <stephen@networkplumber.org> + * + * Borrowed from Linux kernel [5.17.0]: tools/bpf/bpftool/json_writer.[hc] + */ + +#include <stdio.h> +#include <stdbool.h> +#include <stdarg.h> +#include <assert.h> +#include <malloc.h> +#include <inttypes.h> +#include <stdint.h> + +#include "../lib/sg_json_builder.h" + + + +static json_serialize_opts out_settings = { + json_serialize_mode_multiline, + 0, + 4 +}; + +int +main(int arnum, char * argv[]) +{ + size_t len; + json_value * jv1p; + json_value * jv2p; + json_value * jv3p = json_object_new(0); + json_value * jvp = json_object_new(0); + json_value * jv4p; + json_value * jv5p; + json_value * ja1p = json_array_new(0); + json_value * ja2p; + json_value * ja3p; + json_value * jsp = json_string_new("hello world 1"); + json_value * js2p = json_string_new("hello world 2"); + json_value * js3p = json_string_new("hello world 3"); + json_value * js10 = json_string_new("good-bye world"); + json_value * js11 = json_string_new("good-bye world 2"); + json_value * js12 = json_string_new("duplicate name 1"); + char b[8192]; + + jv1p = json_object_push(jvp, "contents", jsp); + + if (jvp == jv1p) + printf("jvp == jv1p\n"); + else + printf("jvp != jv1p\n"); + +#if 1 + json_array_push(ja1p, js2p); + jv2p = json_object_push(jvp, "extra", js3p); + if (jv2p) + printf("jv2p->type=%d\n", jv2p->type); + else + printf("jv2p is NULL\n"); + ja2p = json_array_push(ja1p, json_string_new("hello world 99")); + if (ja2p) + printf("ja2p->type=%d\n", ja2p->type); + else + printf("ja2p is NULL\n"); + // json_object_push(ja2p, "boo", json_string_new("hello world 88")); + json_object_push(jvp, "a_array", ja1p); + jv4p = json_object_push(jvp, "a_object", jv3p); + if (jv4p) + printf("jv4p->type=%d\n", jv4p->type); + else + printf("jv4p is NULL\n"); + json_object_push(jv4p, "test", js10); + json_object_push(jv4p, "test2", js11); + json_object_push(jv4p, "test", js12); + // ja3p = json_array_push(ja2p, json_string_new("good-bye")); + // jv4p = json_object_push(jvp, "a_array", ja2p); + // jv5p = json_object_merge(jvp, ja1p); +#endif + jv5p = jvp; + + jv1p = json_string_new("boo"); + + len = json_measure_ex(jv5p, out_settings); + printf("jvp length: %zu bytes\n", len); + if (len < sizeof(b)) { + json_serialize_ex(b, jv5p, out_settings); + printf("json serialized:\n"); + printf("%s\n", b); + } else + printf("since json output length [%zu] > 8192, skip outputting\n", + len); + + json_builder_free(jvp); + return 0; +} + + +#if 0 +int main(int argc, char **argv) +{ + json_writer_t *wr = jsonw_new(stdout); + + jsonw_start_object(wr); + jsonw_pretty(wr, true); + jsonw_name(wr, "Vyatta"); + jsonw_start_object(wr); + jsonw_string_field(wr, "url", "http://vyatta.com"); + jsonw_uint_field(wr, "downloads", 2000000ul); + jsonw_float_field(wr, "stock", 8.16); + + jsonw_name(wr, "ARGV"); + jsonw_start_array(wr); + while (--argc) + jsonw_string(wr, *++argv); + jsonw_end_array(wr); + + jsonw_name(wr, "empty"); + jsonw_start_array(wr); + jsonw_end_array(wr); + + jsonw_name(wr, "NIL"); + jsonw_start_object(wr); + jsonw_end_object(wr); + + jsonw_null_field(wr, "my_null"); + + jsonw_name(wr, "special chars"); + jsonw_start_array(wr); + jsonw_string_field(wr, "slash", "/"); + jsonw_string_field(wr, "newline", "\n"); + jsonw_string_field(wr, "tab", "\t"); + jsonw_string_field(wr, "ff", "\f"); + jsonw_string_field(wr, "quote", "\""); + jsonw_string_field(wr, "tick", "\'"); + jsonw_string_field(wr, "backslash", "\\"); + jsonw_end_array(wr); + +jsonw_name(wr, "ARGV"); +jsonw_start_array(wr); +jsonw_string(wr, "boo: appended or new entry?"); +jsonw_end_array(wr); + + jsonw_end_object(wr); + + jsonw_end_object(wr); + jsonw_destroy(&wr); + return 0; +} + +#endif + |