xref: /minix/minix/servers/vfs/gcov.c (revision 045e0ed3)
1 
2 #include <string.h>
3 
4 #include "fs.h"
5 #include "file.h"
6 
7 /*===========================================================================*
8  *				do_gcov_flush				     *
9  *===========================================================================*/
10 int do_gcov_flush(void)
11 {
12 /* A userland tool has requested the gcov data from another
13  * process (possibly vfs itself). Grant the target process
14  * access to the supplied buffer, and perform the call that
15  * makes the target copy its buffer to the caller (incl vfs
16  * itself).
17  */
18   char label[LABEL_MAX];
19   vir_bytes labeladdr, buf;
20   size_t labellen, size;
21   endpoint_t endpt;
22   cp_grant_id_t grantid;
23   int r;
24   message m;
25 
26   /*
27    * Something as sensitive as system service coverage information must be
28    * call to the target service, and so it is not impossible to deadlock the
29    * system with this call.
30    */
31   if (!super_user) return(EPERM);
32 
33   labeladdr = job_m_in.m_lc_vfs_gcov.label;
34   labellen = job_m_in.m_lc_vfs_gcov.labellen;
35   buf = job_m_in.m_lc_vfs_gcov.buf;
36   size = job_m_in.m_lc_vfs_gcov.buflen;
37 
38   /* Retrieve and look up the target label. */
39   if (labellen >= sizeof(label))
40 	return EINVAL;
41   if ((r = sys_datacopy_wrapper(who_e, labeladdr, SELF, (vir_bytes)label,
42     labellen)) != OK)
43 	return r;
44   label[labellen - 1] = '\0';
45 
46   if ((r = ds_retrieve_label_endpt(label, &endpt)) != OK)
47 	return r;
48 
49   /* Hack: init is the only non-system process with a valid label. */
50   if (endpt == INIT_PROC_NR)
51 	return ENOENT;
52 
53   /* Grant target process to requestor's buffer. */
54   if ((grantid = cpf_grant_magic(endpt, who_e, buf, size, CPF_WRITE)) < 0) {
55 	printf("VFS: gcov_flush: grant failed\n");
56 	return(ENOMEM);
57   }
58 
59   if (endpt == VFS_PROC_NR) {
60 	/* Request is for VFS itself. */
61 	r = gcov_flush(VFS_PROC_NR, grantid, size);
62   } else {
63 	/* Perform generic GCOV request. */
64 	memset(&m, 0, sizeof(m));
65 	m.m_vfs_lsys_gcov.grant = grantid;
66 	m.m_vfs_lsys_gcov.size = size;
67 	r = _taskcall(endpt, COMMON_REQ_GCOV_DATA, &m);
68   }
69 
70   cpf_revoke(grantid);
71 
72   return(r);
73 }
74