1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3 * This file and its contents are supplied under the terms of the
4 * Common Development and Distribution License ("CDDL"), version 1.0.
5 * You may only use this file in accordance with the terms of version
6 * 1.0 of the CDDL.
7 *
8 * A full copy of the text of the CDDL should have accompanied this
9 * source. A copy of the CDDL is also available via the Internet at
10 * https://opensource.org/license/CDDL-1.0.
11 */
12
13 /*
14 * Copyright (c) 2020 by Delphix. All rights reserved.
15 * Copyright (c) 2020 by Datto Inc. All rights reserved.
16 */
17
18 #include <signal.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include "zstream.h"
24 #include "zstream_util.h"
25
26 void
zstream_usage(void)27 zstream_usage(void)
28 {
29 (void) fprintf(stderr,
30 "usage: zstream command args ...\n"
31 "Available commands are:\n"
32 "\n"
33 "\tzstream dump [-vCd] FILE\n"
34 "\t... | zstream dump [-vCd]\n"
35 "\n"
36 "\tzstream decompress [-v] [OBJECT,OFFSET[,TYPE]] ...\n"
37 "\n"
38 "\tzstream drop_record [-v] [OBJECT,OFFSET] ...\n"
39 "\n"
40 "\tzstream raw [-v] [-b blocks] [-g guid] IMAGE|DEVICE FILE\n"
41 "\t... | zstream raw [-v] [-b blocks] [-g guid] IMAGE|DEVICE\n"
42 "\n"
43 "\tzstream recompress [-t num_threads] [-l level] TYPE\n"
44 "\n"
45 "\tzstream token resume_token\n"
46 "\n"
47 "\tzstream redup [-v] FILE | ...\n");
48 exit(1);
49 }
50
51 /*
52 * Set the signal mask to allow THREAD_BACKTRACE_SIGNAL. WATCHDOG_SIGNAL
53 * must be blocked in all threads so that its intended recipient can listen
54 * for it with sigwait(), which detects only pending signals.
55 */
56 static void
set_signal_mask(void)57 set_signal_mask(void)
58 {
59 sigset_t mask;
60
61 safe_pthread_sigmask(SIG_SETMASK, NULL, &mask);
62 sigaddset(&mask, WATCHDOG_SIGNAL);
63 sigdelset(&mask, THREAD_BACKTRACE_SIGNAL);
64 safe_pthread_sigmask(SIG_SETMASK, &mask, NULL);
65 }
66
67 int
main(int argc,char * argv[])68 main(int argc, char *argv[])
69 {
70 set_signal_mask();
71
72 char *basename = strrchr(argv[0], '/');
73 basename = basename ? (basename + 1) : argv[0];
74 if (argc >= 1 && strcmp(basename, "zstreamdump") == 0)
75 return (zstream_do_dump(argc, argv));
76
77 if (argc < 2)
78 zstream_usage();
79
80 char *subcommand = argv[1];
81
82 if (strcmp(subcommand, "dump") == 0) {
83 return (zstream_do_dump(argc - 1, argv + 1));
84 } else if (strcmp(subcommand, "decompress") == 0) {
85 return (zstream_do_decompress(argc - 1, argv + 1));
86 } else if (strcmp(subcommand, "drop_record") == 0) {
87 return (zstream_do_drop_record(argc - 1, argv + 1));
88 } else if (strcmp(subcommand, "raw") == 0) {
89 return (zstream_do_raw(argc - 1, argv + 1));
90 } else if (strcmp(subcommand, "recompress") == 0) {
91 return (zstream_do_recompress(argc - 1, argv + 1));
92 } else if (strcmp(subcommand, "token") == 0) {
93 return (zstream_do_token(argc - 1, argv + 1));
94 } else if (strcmp(subcommand, "redup") == 0) {
95 return (zstream_do_redup(argc - 1, argv + 1));
96 } else if (strcmp(subcommand, "selftest") == 0) {
97 /* Undocumented; used by the ZFS test suite */
98 return (zstream_do_selftest(argc - 1, argv + 1));
99 } else {
100 zstream_usage();
101 }
102 }
103