|
11 | 11 | #include <stdlib.h>
|
12 | 12 | #include <string.h>
|
13 | 13 | #include <sys/socket.h>
|
| 14 | +#include <sys/time.h> |
14 | 15 | #include <sys/un.h>
|
| 16 | +#include <linux/vm_sockets.h> |
15 | 17 | #include <libkrun.h>
|
16 | 18 | #include <getopt.h>
|
17 | 19 | #include <stdbool.h>
|
|
23 | 25 | #define MAX_PATH 4096
|
24 | 26 | #endif
|
25 | 27 |
|
26 |
| -#define IPC_SOCK_PATH "/tmp/krun_nitro_example_ipc.sock" |
| 28 | +#define VMADDR_CID_HYPERVISOR 0 |
| 29 | +#define CID_TO_CONSOLE_PORT_OFFSET 10000 |
| 30 | + |
| 31 | +#define BUFSIZE 512 |
27 | 32 |
|
28 | 33 | static void print_help(char *const name)
|
29 | 34 | {
|
@@ -84,31 +89,56 @@ bool parse_cmdline(int argc, char *const argv[], struct cmdline *cmdline)
|
84 | 89 |
|
85 | 90 | void *listen_enclave_output(void *opaque)
|
86 | 91 | {
|
87 |
| - int ret, fd = (int) opaque, sock, len; |
88 |
| - char buf[512]; |
89 |
| - struct sockaddr_un client_sockaddr; |
| 92 | + socklen_t addr_sz = sizeof(struct sockaddr_vm); |
| 93 | + struct sockaddr_vm addr; |
| 94 | + int ret, sock_fd, cid; |
| 95 | + struct timeval timeval; |
| 96 | + char buf[BUFSIZE]; |
| 97 | + |
| 98 | + cid = (int) opaque; |
| 99 | + |
| 100 | + sock_fd = socket(AF_VSOCK, SOCK_STREAM, 0); |
| 101 | + if (sock_fd < 0) |
| 102 | + return (void *) -1; |
| 103 | + |
| 104 | + bzero((char *) &addr, sizeof(struct sockaddr_vm)); |
| 105 | + addr.svm_family = AF_VSOCK; |
| 106 | + addr.svm_cid = VMADDR_CID_HYPERVISOR; |
| 107 | + addr.svm_port = cid + CID_TO_CONSOLE_PORT_OFFSET; |
| 108 | + |
| 109 | + // Set vsock timeout limit to 5 seconds. |
| 110 | + memset(&timeval, 0, sizeof(struct timeval)); |
| 111 | + timeval.tv_sec = 5; |
| 112 | + |
| 113 | + ret = setsockopt(sock_fd, AF_VSOCK, SO_VM_SOCKETS_CONNECT_TIMEOUT, |
| 114 | + (void *) &timeval, sizeof(struct timeval)); |
| 115 | + if (ret < 0) { |
| 116 | + close(sock_fd); |
| 117 | + return (void *) -1; |
| 118 | + } |
90 | 119 |
|
91 |
| - sock = accept(fd, (struct sockaddr *) &client_sockaddr, &len); |
92 |
| - if (sock < 1) |
| 120 | + ret = connect(sock_fd, (struct sockaddr *) &addr, addr_sz); |
| 121 | + if (ret < 0) { |
| 122 | + close(sock_fd); |
93 | 123 | return (void *) -1;
|
| 124 | + } |
94 | 125 |
|
| 126 | + bzero(buf, BUFSIZE); |
95 | 127 | for (;;) {
|
96 |
| - ret = read(sock, &buf, 512); |
| 128 | + ret = read(sock_fd, &buf, BUFSIZE); |
97 | 129 | if (ret <= 0)
|
98 | 130 | break;
|
99 |
| - else if (ret < 512) { |
100 |
| - buf[ret] = '\0'; |
101 |
| - } |
| 131 | + |
| 132 | + buf[ret] = '\0'; |
102 | 133 |
|
103 | 134 | printf("%s", buf);
|
104 | 135 | }
|
105 | 136 | }
|
106 | 137 |
|
107 | 138 | int main(int argc, char *const argv[])
|
108 | 139 | {
|
109 |
| - int ret, ctx_id, err, i, sock_fd, enable = 1; |
| 140 | + int ret, cid, ctx_id, err; |
110 | 141 | struct cmdline cmdline;
|
111 |
| - struct sockaddr_un addr; |
112 | 142 | pthread_t thread;
|
113 | 143 |
|
114 | 144 | if (!parse_cmdline(argc, argv, &cmdline)) {
|
@@ -161,62 +191,26 @@ int main(int argc, char *const argv[])
|
161 | 191 | return -1;
|
162 | 192 | }
|
163 | 193 |
|
164 |
| - // Create and initialize UNIX IPC socket for reading enclave output. |
165 |
| - sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); |
166 |
| - if (sock_fd < 0) { |
167 |
| - perror("Error creating UNIX IPC socket for enclave communication"); |
168 |
| - return -1; |
169 |
| - } |
170 |
| - memset(&addr, 0, sizeof(struct sockaddr_un)); |
171 |
| - addr.sun_family = AF_UNIX; |
172 |
| - strcpy(addr.sun_path, IPC_SOCK_PATH); |
173 |
| - |
174 |
| - // Listen on the socket for enclave output. |
175 |
| - unlink(IPC_SOCK_PATH); |
176 |
| - ret = bind(sock_fd, (struct sockaddr *) &addr, sizeof(addr)); |
177 |
| - if (ret < 0) { |
178 |
| - perror("Error binding socket"); |
179 |
| - close(sock_fd); |
180 |
| - exit(1); |
181 |
| - } |
182 |
| - |
183 |
| - ret = listen(sock_fd, 1); |
184 |
| - if (ret < 0) { |
185 |
| - perror("Error listening on socket"); |
186 |
| - close(sock_fd); |
187 |
| - exit(1); |
188 |
| - } |
189 |
| - |
190 |
| - // Configure the IPC socket to read output from the enclave. The "port" |
191 |
| - // argument is ignored. |
192 |
| - if (err = krun_add_vsock_port(ctx_id, 0, IPC_SOCK_PATH)) { |
193 |
| - close(sock_fd); |
| 194 | + /* |
| 195 | + * Start and enter the microVM. In the libkrun-nitro flavor, a positive |
| 196 | + * value returned by krun_start_enter() is the enclave's CID. |
| 197 | + */ |
| 198 | + cid = krun_start_enter(ctx_id); |
| 199 | + if (cid < 0) { |
194 | 200 | errno = -err;
|
195 |
| - perror("Error configuring enclave vsock"); |
| 201 | + perror("Error creating the microVM"); |
196 | 202 | return -1;
|
197 | 203 | }
|
198 | 204 |
|
199 |
| - ret = pthread_create(&thread, NULL, listen_enclave_output, |
200 |
| - (void *) sock_fd); |
| 205 | + ret = pthread_create(&thread, NULL, listen_enclave_output, (void *) cid); |
201 | 206 | if (ret < 0) {
|
202 | 207 | perror("unable to create new listener thread");
|
203 |
| - close(sock_fd); |
204 | 208 | exit(1);
|
205 | 209 | }
|
206 | 210 |
|
207 |
| - // Start and enter the microVM. Unless there is some error while creating the microVM |
208 |
| - // this function never returns. |
209 |
| - if (err = krun_start_enter(ctx_id)) { |
210 |
| - close(sock_fd); |
211 |
| - errno = -err; |
212 |
| - perror("Error creating the microVM"); |
213 |
| - return -1; |
214 |
| - } |
215 |
| - |
216 | 211 | ret = pthread_join(thread, NULL);
|
217 | 212 | if (ret < 0) {
|
218 | 213 | perror("unable to join listener thread");
|
219 |
| - close(sock_fd); |
220 | 214 | exit(1);
|
221 | 215 | }
|
222 | 216 |
|
|
0 commit comments