{ "GETREF", VM_GETREF },
{ "RS_SET_PRIV", VM_RS_SET_PRIV },
{ "QUERY_EXIT", VM_QUERY_EXIT },
+ { "WATCH_EXIT", VM_WATCH_EXIT },
{ "NOTIFY_SIG", VM_NOTIFY_SIG },
{ "INFO", VM_INFO },
{ "RS_UPDATE", VM_RS_UPDATE },
# define VM_RS_MEM_PIN 0 /* pin memory */
# define VM_RS_MEM_MAKE_VM 1 /* make VM instance */
+#define VM_WATCH_EXIT (VM_RQ_BASE+43)
+# define VM_WE_EP m1_i1
+
/* Total. */
-#define NR_VM_CALLS 43
+#define NR_VM_CALLS 44
#define VM_CALL_MASK_SIZE BITMAP_CHUNKS(NR_VM_CALLS)
/* not handled as a normal VM call, thus at the end of the reserved rage */
_PROTOTYPE( int vm_set_priv, (int procnr, void *buf));
_PROTOTYPE( int vm_update, (endpoint_t src_e, endpoint_t dst_e));
_PROTOTYPE( int vm_memctl, (endpoint_t ep, int req));
-_PROTOTYPE( int vm_query_exit, (int *endpt));
+_PROTOTYPE( int vm_query_exit, (endpoint_t *endpt));
+_PROTOTYPE( int vm_watch_exit, (endpoint_t ep));
_PROTOTYPE( int vm_forgetblock, (u64_t id));
_PROTOTYPE( void vm_forgetblocks, (void));
_PROTOTYPE( int vm_yield_block_get_block, (u64_t yieldid, u64_t getid,
uid 0;
};
-service ipc
-{
- system
- UMAP # 14
- VIRCOPY # 15
- ;
- uid 0;
- ipc
- SYSTEM USER pm rs log tty ds vm
- ;
- vm
- REMAP
- SHM_UNMAP
- GETPHYS
- GETREF
- QUERY_EXIT
- ;
-};
-
service osscore
{
system
*endpt = m.VM_QUERY_RET_PT;
return (m.VM_QUERY_IS_MORE ? 1 : 0);
}
+
+PUBLIC int vm_watch_exit(endpoint_t ep)
+{
+ message m;
+ int r;
+
+ memset(&m, 0, sizeof(m));
+ m.VM_WE_EP = ep;
+ return _syscall(VM_PROC_NR, VM_WATCH_EXIT, &m);
+}
+
MAN=
BINDIR?= /usr/sbin
+FILES=ipc.conf
+FILESNAME=ipc
+FILESDIR= /etc/system.conf.d
.include <minix.service.mk>
--- /dev/null
+service ipc
+{
+ system
+ UMAP # 14
+ VIRCOPY # 15
+ ;
+ uid 0;
+ ipc
+ SYSTEM USER pm rs log tty ds vm
+ ;
+ vm
+ REMAP
+ SHM_UNMAP
+ GETPHYS
+ GETREF
+ QUERY_EXIT
+ WATCH_EXIT
+ ;
+};
/* dispatch messages */
for (i = 0; i < SIZE(ipc_calls); i++) {
+ /* If any process does an IPC call,
+ * we have to know about it exiting.
+ * Tell VM to watch it for us.
+ */
+ if(vm_watch_exit(m.m_source) != OK) {
+ printf("IPC: watch failed on %d\n", m.m_source);
+ }
+
if (ipc_calls[i].type == call_type) {
int result;
CALLMAP(VM_GETREF, do_get_refcount);
CALLMAP(VM_INFO, do_info);
CALLMAP(VM_QUERY_EXIT, do_query_exit);
+ CALLMAP(VM_WATCH_EXIT, do_watch_exit);
CALLMAP(VM_FORGETBLOCKS, do_forgetblocks);
CALLMAP(VM_FORGETBLOCK, do_forgetblock);
CALLMAP(VM_YIELDBLOCKGETBLOCK, do_yieldblockgetblock);
/* queryexit.c */
_PROTOTYPE(int do_query_exit, (message *m));
+_PROTOTYPE(int do_watch_exit, (message *m));
_PROTOTYPE(int do_notify_sig, (message *m));
_PROTOTYPE(void init_query_exit, (void));
*===========================================================================*/
PUBLIC int do_notify_sig(message *m)
{
- int i, avails = 0;
+ int i, avails = 0, p;
endpoint_t ep = m->VM_NOTIFY_SIG_ENDPOINT;
endpoint_t ipc_ep = m->VM_NOTIFY_SIG_IPC;
int r;
+ struct vmproc *vmp;
+ int pslot;
+
+ if(vm_isokendpt(ep, &pslot) != OK) return ESRCH;
+ vmp = &vmproc[pslot];
+
+ /* Only record the event if we've been asked to report it. */
+ if(!(vmp->vm_flags & VMF_WATCHEXIT))
+ return OK;
for (i = 0; i < NR_PROCS; i++) {
/* its signal is already here */
avails++;
}
if (!avails) {
- /* no slot for signals, impossible */
+ /* no slot for signals, unlikely */
printf("VM: no slot for signals!\n");
return ENOMEM;
}
return OK;
}
+/*===========================================================================*
+ * do_watch_exit *
+ *===========================================================================*/
+PUBLIC int do_watch_exit(message *m)
+{
+ endpoint_t e = m->VM_WE_EP;
+ struct vmproc *vmp;
+ int p;
+ if(vm_isokendpt(e, &p) != OK) return ESRCH;
+ vmp = &vmproc[p];
+ vmp->vm_flags |= VMF_WATCHEXIT;
+
+ return OK;
+}
+
/*===========================================================================*
* init_query_exit *
*===========================================================================*/
#define VMF_HAS_DMA 0x010 /* Process directly or indirectly granted
* DMA buffers.
*/
+#define VMF_WATCHEXIT 0x020 /* Store in queryexit table */
#endif