xref: /spdk/test/app/stub/stub.c (revision fa2d95b3fe66e7f5c543eaef89fa00d4eaa0e6e7)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/stdinc.h"
35 
36 #include "spdk/event.h"
37 #include "spdk/nvme.h"
38 #include "spdk/string.h"
39 #include "spdk/thread.h"
40 
41 static char g_path[256];
42 static struct spdk_poller *g_poller;
43 
44 static void
45 usage(char *executable_name)
46 {
47 	printf("%s [options]\n", executable_name);
48 	printf("options:\n");
49 	printf(" -i shared memory ID [required]\n");
50 	printf(" -m mask    core mask for DPDK\n");
51 	printf(" -n channel number of memory channels used for DPDK\n");
52 	printf(" -p core    master (primary) core for DPDK\n");
53 	printf(" -s size    memory size in MB for DPDK\n");
54 	printf(" -H         show this usage\n");
55 }
56 
57 static bool
58 probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
59 	 struct spdk_nvme_ctrlr_opts *opts)
60 {
61 	/*
62 	 * Set the io_queue_size to UINT16_MAX to initialize
63 	 * the controller with the possible largest queue size.
64 	 */
65 	opts->io_queue_size = UINT16_MAX;
66 	return true;
67 }
68 
69 static void
70 attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
71 	  struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
72 {
73 }
74 
75 static int
76 stub_sleep(void *arg)
77 {
78 	usleep(1000 * 1000);
79 	return 0;
80 }
81 
82 static void
83 stub_start(void *arg1)
84 {
85 	int shm_id = (intptr_t)arg1;
86 
87 	spdk_unaffinitize_thread();
88 
89 	if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) {
90 		fprintf(stderr, "spdk_nvme_probe() failed\n");
91 		exit(1);
92 	}
93 
94 	snprintf(g_path, sizeof(g_path), "/var/run/spdk_stub%d", shm_id);
95 	if (mknod(g_path, S_IFREG, 0) != 0) {
96 		fprintf(stderr, "could not create sentinel file %s\n", g_path);
97 		exit(1);
98 	}
99 
100 	g_poller = spdk_poller_register(stub_sleep, NULL, 0);
101 }
102 
103 static void
104 stub_shutdown(void)
105 {
106 	spdk_poller_unregister(&g_poller);
107 	unlink(g_path);
108 	spdk_app_stop(0);
109 }
110 
111 int
112 main(int argc, char **argv)
113 {
114 	int ch;
115 	struct spdk_app_opts opts = {};
116 	long int val;
117 
118 	/* default value in opts structure */
119 	spdk_app_opts_init(&opts);
120 
121 	opts.name = "stub";
122 	opts.rpc_addr = NULL;
123 
124 	while ((ch = getopt(argc, argv, "i:m:n:p:s:H")) != -1) {
125 		if (ch == 'm') {
126 			opts.reactor_mask = optarg;
127 		} else if (ch == '?') {
128 			usage(argv[0]);
129 			exit(1);
130 		} else {
131 			val = spdk_strtol(optarg, 10);
132 			if (val < 0) {
133 				fprintf(stderr, "Converting a string to integer failed\n");
134 				exit(1);
135 			}
136 			switch (ch) {
137 			case 'i':
138 				opts.shm_id = val;
139 				break;
140 			case 'n':
141 				opts.mem_channel = val;
142 				break;
143 			case 'p':
144 				opts.master_core = val;
145 				break;
146 			case 's':
147 				opts.mem_size = val;
148 				break;
149 			case 'H':
150 			default:
151 				usage(argv[0]);
152 				exit(EXIT_SUCCESS);
153 			}
154 		}
155 	}
156 
157 	if (opts.shm_id < 0) {
158 		fprintf(stderr, "%s: -i shared memory ID must be specified\n", argv[0]);
159 		usage(argv[0]);
160 		exit(1);
161 	}
162 
163 	opts.shutdown_cb = stub_shutdown;
164 
165 	ch = spdk_app_start(&opts, stub_start, (void *)(intptr_t)opts.shm_id);
166 	spdk_app_fini();
167 
168 	return ch;
169 }
170