This repository has been archived by the owner on Jan 20, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 261
/
Copy pathshim_ipc.h
347 lines (278 loc) · 9.92 KB
/
shim_ipc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/* Copyright (C) 2014 Stony Brook University
* Copyright (C) 2021 Intel Corporation
* Borys Popławski <[email protected]>
*/
#ifndef SHIM_IPC_H_
#define SHIM_IPC_H_
#include "avl_tree.h"
#include "pal.h"
#include "shim_defs.h"
#include "shim_handle.h"
#include "shim_internal.h"
#include "shim_sysv.h"
#include "shim_thread.h"
#include "shim_types.h"
/* if callback func returns RESPONSE_CALLBACK, send response msg even if callback succeeded */
#define RESPONSE_CALLBACK 1
#define RANGE_SIZE 32
#define LEASE_TIME 1000
#define IPC_MSG_MINIMAL_SIZE 48
#define IPC_SEM_NOTIMEOUT ((unsigned long)-1)
#define MAX_IPC_PORT_FINI_CB 3
enum {
IPC_MSG_RESP = 0,
IPC_MSG_CONNBACK,
IPC_MSG_DUMMY,
IPC_MSG_CHILDEXIT,
IPC_MSG_LEASE,
IPC_MSG_OFFER,
IPC_MSG_SUBLEASE,
IPC_MSG_QUERY,
IPC_MSG_QUERYALL,
IPC_MSG_ANSWER,
IPC_MSG_PID_KILL,
IPC_MSG_PID_GETSTATUS,
IPC_MSG_PID_RETSTATUS,
IPC_MSG_PID_GETMETA,
IPC_MSG_PID_RETMETA,
IPC_MSG_SYSV_FINDKEY,
IPC_MSG_SYSV_TELLKEY,
IPC_MSG_SYSV_DELRES,
IPC_MSG_SYSV_MSGSND,
IPC_MSG_SYSV_MSGRCV,
IPC_MSG_SYSV_SEMOP,
IPC_MSG_SYSV_SEMCTL,
IPC_MSG_SYSV_SEMRET,
IPC_MSG_CODE_BOUND,
};
enum kill_type { KILL_THREAD, KILL_PROCESS, KILL_PGROUP, KILL_ALL };
enum pid_meta_code { PID_META_CRED, PID_META_EXEC, PID_META_CWD, PID_META_ROOT };
enum sysv_type { SYSV_NONE, SYSV_MSGQ, SYSV_SEM, SYSV_SHM };
struct shim_ipc_ids {
IDTYPE parent_id;
IDTYPE leader_id;
};
extern IDTYPE g_self_vmid;
extern struct shim_ipc_ids g_process_ipc_ids;
struct shim_ipc_msg {
unsigned char code;
size_t size;
IDTYPE src, dst;
unsigned long seq;
/* msg is used to store and read various structures, we need to ensure its proper alignment */
// TODO: this is only a temporary workaround until we rewrite the IPC subsystem.
char msg[] __attribute__((aligned(16)));
} __attribute__((packed));
struct shim_ipc_msg_with_ack {
struct avl_tree_node node;
struct shim_thread* thread;
int retval;
void* private;
struct shim_ipc_msg msg;
};
/* common functions for pid & sysv namespaces */
int add_ipc_subrange(IDTYPE idx, IDTYPE owner);
IDTYPE allocate_ipc_id(IDTYPE min, IDTYPE max);
void release_ipc_id(IDTYPE idx);
int find_owner(IDTYPE idx, IDTYPE* owner);
/* sysv namespace */
struct sysv_key {
unsigned long key;
enum sysv_type type;
};
int sysv_add_key(struct sysv_key* key, IDTYPE id);
int sysv_get_key(struct sysv_key* key, bool delete);
/* common message structs */
struct shim_ipc_resp {
int retval;
} __attribute__((packed));
struct ipc_ns_offered {
IDTYPE base;
IDTYPE size;
IDTYPE owner;
} __attribute__((packed));
/* CLD_EXIT: process exit */
struct shim_ipc_cld_exit {
IDTYPE ppid, pid;
IDTYPE uid;
unsigned int exitcode;
unsigned int term_signal;
} __attribute__((packed));
int ipc_cld_exit_send(unsigned int exitcode, unsigned int term_signal);
int ipc_cld_exit_callback(struct shim_ipc_msg* msg, IDTYPE src);
void ipc_child_disconnect_callback(IDTYPE vmid);
int ipc_lease_send(void);
int ipc_lease_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* OFFER: offer a range of IDs */
struct shim_ipc_offer {
IDTYPE base;
IDTYPE size;
} __attribute__((packed));
int ipc_offer_send(IDTYPE dest, IDTYPE base, IDTYPE size, unsigned long seq);
int ipc_offer_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* SUBLEASE: lease a range of IDs */
struct shim_ipc_sublease {
IDTYPE tenant;
IDTYPE idx;
} __attribute__((packed));
int ipc_sublease_send(IDTYPE tenant, IDTYPE idx);
int ipc_sublease_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* QUERY: query for a certain ID */
struct shim_ipc_query {
IDTYPE idx;
} __attribute__((packed));
int ipc_query_send(IDTYPE idx);
int ipc_query_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* QUERYALL: query for all IDs */
int ipc_queryall_send(void);
int ipc_queryall_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* ANSWER: reply to the query with my offered IDs */
struct shim_ipc_answer {
size_t answers_cnt;
struct ipc_ns_offered answers[];
} __attribute__((packed));
int ipc_answer_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* PID_KILL: send signal to certain pid */
struct shim_ipc_pid_kill {
IDTYPE sender;
enum kill_type type;
IDTYPE id;
int signum;
} __attribute__((packed));
int ipc_kill_process(IDTYPE sender, IDTYPE target, int sig);
int ipc_kill_thread(IDTYPE sender, IDTYPE dest_pid, IDTYPE target, int sig);
int ipc_kill_pgroup(IDTYPE sender, IDTYPE pgid, int sig);
int ipc_kill_all(IDTYPE sender, int sig);
int ipc_pid_kill_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* PID_GETSTATUS: check if certain pid(s) exists */
struct shim_ipc_pid_getstatus {
int npids;
IDTYPE pids[];
};
struct pid_status {
IDTYPE pid;
IDTYPE tgid;
IDTYPE pgid;
} __attribute__((packed));
int ipc_pid_getstatus_send(IDTYPE dest, int npids, IDTYPE* pids, struct pid_status** status);
int ipc_pid_getstatus_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* PID_RETSTATUS: return status of pid(s) */
struct shim_ipc_pid_retstatus {
int nstatus;
struct pid_status status[];
} __attribute__((packed));
int ipc_pid_retstatus_send(IDTYPE dest, int nstatus, struct pid_status* status, unsigned long seq);
int ipc_pid_retstatus_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* PID_GETMETA: get metadata of certain pid */
struct shim_ipc_pid_getmeta {
IDTYPE pid;
enum pid_meta_code code;
} __attribute__((packed));
int ipc_pid_getmeta_send(IDTYPE pid, enum pid_meta_code code, void** data);
int ipc_pid_getmeta_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* PID_RETMETA: return metadata of certain pid */
struct shim_ipc_pid_retmeta {
IDTYPE pid;
enum pid_meta_code code;
int datasize;
char data[];
} __attribute__((packed));
int ipc_pid_retmeta_send(IDTYPE dest, IDTYPE pid, enum pid_meta_code code, const void* data,
int datasize, unsigned long seq);
int ipc_pid_retmeta_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* SYSV_FINDKEY */
struct shim_ipc_sysv_findkey {
struct sysv_key key;
} __attribute__((packed));
int ipc_sysv_findkey_send(struct sysv_key* key);
int ipc_sysv_findkey_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* SYSV_TELLKEY */
struct shim_ipc_sysv_tellkey {
struct sysv_key key;
IDTYPE id;
} __attribute__((packed));
int ipc_sysv_tellkey_send(IDTYPE dest, struct sysv_key* key, IDTYPE id, unsigned long seq);
int ipc_sysv_tellkey_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* SYSV_DELRES */
struct shim_ipc_sysv_delres {
IDTYPE resid;
enum sysv_type type;
} __attribute__((packed));
int ipc_sysv_delres_send(IDTYPE dest, IDTYPE resid, enum sysv_type type);
int ipc_sysv_delres_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* SYSV_MSGSND */
struct shim_ipc_sysv_msgsnd {
IDTYPE msgid;
long msgtype;
char msg[];
} __attribute__((packed));
int ipc_sysv_msgsnd_send(IDTYPE dest, IDTYPE msgid, long msgtype, const void* buf, size_t size,
unsigned long seq);
int ipc_sysv_msgsnd_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* SYSV_MSGRCV */
struct shim_ipc_sysv_msgrcv {
IDTYPE msgid;
long msgtype;
size_t size;
int flags;
} __attribute__((packed));
int ipc_sysv_msgrcv_send(IDTYPE msgid, long msgtype, int flags, void* buf, size_t size);
int ipc_sysv_msgrcv_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* SYSV_SEMOP */
struct shim_ipc_sysv_semop {
IDTYPE semid;
unsigned long timeout;
int nsops;
struct sembuf sops[];
};
int ipc_sysv_semop_send(IDTYPE semid, struct sembuf* sops, int nsops, unsigned long timeout,
unsigned long* seq);
int ipc_sysv_semop_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* SYSV_SEMCTL */
struct shim_ipc_sysv_semctl {
IDTYPE semid;
int semnum;
int cmd;
size_t valsize;
unsigned char vals[];
} __attribute__((packed));
int ipc_sysv_semctl_send(IDTYPE semid, int semnum, int cmd, void* vals, size_t valsize);
int ipc_sysv_semctl_callback(struct shim_ipc_msg* msg, IDTYPE src);
/* SYSV_SEMRET */
struct shim_ipc_sysv_semret {
size_t valsize;
unsigned char vals[];
} __attribute__((packed));
int ipc_sysv_semret_send(IDTYPE dest, void* vals, size_t valsize, unsigned long seq);
int ipc_sysv_semret_callback(struct shim_ipc_msg* msg, IDTYPE src);
int init_ipc(void);
static inline size_t get_ipc_msg_size(size_t payload) {
size_t size = sizeof(struct shim_ipc_msg) + payload;
return (size > IPC_MSG_MINIMAL_SIZE) ? size : IPC_MSG_MINIMAL_SIZE;
}
static inline size_t get_ipc_msg_with_ack_size(size_t payload) {
static_assert(sizeof(struct shim_ipc_msg_with_ack) >= sizeof(struct shim_ipc_msg),
"Incorrect shim_ipc_msg_with_ack size");
return get_ipc_msg_size(payload) +
(sizeof(struct shim_ipc_msg_with_ack) - sizeof(struct shim_ipc_msg));
}
void init_ipc_msg(struct shim_ipc_msg* msg, int code, size_t size, IDTYPE dest);
void init_ipc_msg_with_ack(struct shim_ipc_msg_with_ack* msg, int code, size_t size, IDTYPE dest);
void ipc_msg_response_handle(IDTYPE src, unsigned long seq,
void (*callback)(struct shim_ipc_msg_with_ack*, void*), void* data);
void wake_req_msg_thread(struct shim_ipc_msg_with_ack* req_msg, void* data);
int connect_to_process(IDTYPE dest);
int request_leader_connect_back(void);
int ipc_dummy_callback(struct shim_ipc_msg* msg, IDTYPE src);
int broadcast_ipc(struct shim_ipc_msg* msg, IDTYPE exclude_id);
int send_ipc_message(struct shim_ipc_msg* msg, IDTYPE dest);
int send_ipc_message_with_ack(struct shim_ipc_msg_with_ack* msg, IDTYPE dest, unsigned long* seq);
int send_response_ipc_message(IDTYPE dest, int ret, unsigned long seq);
int init_ipc_worker(void);
void terminate_ipc_worker(void);
int init_ns_ranges(void);
int init_ns_pid(void);
int init_ns_sysv(void);
int get_all_pid_status(struct pid_status** status);
#endif /* SHIM_IPC_H_ */