Skip to content

Commit 35e5ad7

Browse files
tylerfanellislp
authored andcommitted
examples/nitro: Connect to enclave console via vsock
Signed-off-by: Tyler Fanelli <[email protected]>
1 parent b3d8703 commit 35e5ad7

File tree

1 file changed

+50
-56
lines changed

1 file changed

+50
-56
lines changed

examples/nitro.c

Lines changed: 50 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
#include <stdlib.h>
1212
#include <string.h>
1313
#include <sys/socket.h>
14+
#include <sys/time.h>
1415
#include <sys/un.h>
16+
#include <linux/vm_sockets.h>
1517
#include <libkrun.h>
1618
#include <getopt.h>
1719
#include <stdbool.h>
@@ -23,7 +25,10 @@
2325
#define MAX_PATH 4096
2426
#endif
2527

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
2732

2833
static void print_help(char *const name)
2934
{
@@ -84,31 +89,56 @@ bool parse_cmdline(int argc, char *const argv[], struct cmdline *cmdline)
8489

8590
void *listen_enclave_output(void *opaque)
8691
{
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+
}
90119

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);
93123
return (void *) -1;
124+
}
94125

126+
bzero(buf, BUFSIZE);
95127
for (;;) {
96-
ret = read(sock, &buf, 512);
128+
ret = read(sock_fd, &buf, BUFSIZE);
97129
if (ret <= 0)
98130
break;
99-
else if (ret < 512) {
100-
buf[ret] = '\0';
101-
}
131+
132+
buf[ret] = '\0';
102133

103134
printf("%s", buf);
104135
}
105136
}
106137

107138
int main(int argc, char *const argv[])
108139
{
109-
int ret, ctx_id, err, i, sock_fd, enable = 1;
140+
int ret, cid, ctx_id, err;
110141
struct cmdline cmdline;
111-
struct sockaddr_un addr;
112142
pthread_t thread;
113143

114144
if (!parse_cmdline(argc, argv, &cmdline)) {
@@ -161,62 +191,26 @@ int main(int argc, char *const argv[])
161191
return -1;
162192
}
163193

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) {
194200
errno = -err;
195-
perror("Error configuring enclave vsock");
201+
perror("Error creating the microVM");
196202
return -1;
197203
}
198204

199-
ret = pthread_create(&thread, NULL, listen_enclave_output,
200-
(void *) sock_fd);
205+
ret = pthread_create(&thread, NULL, listen_enclave_output, (void *) cid);
201206
if (ret < 0) {
202207
perror("unable to create new listener thread");
203-
close(sock_fd);
204208
exit(1);
205209
}
206210

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-
216211
ret = pthread_join(thread, NULL);
217212
if (ret < 0) {
218213
perror("unable to join listener thread");
219-
close(sock_fd);
220214
exit(1);
221215
}
222216

0 commit comments

Comments
 (0)