xref: /minix3/minix/fs/procfs/service.c (revision 31b6611abf2e94d3c0c0e282031f253dd63c282b)
1*31b6611aSDavid van Moolenbroek /* ProcFS - service.c - the service subdirectory */
2*31b6611aSDavid van Moolenbroek 
3*31b6611aSDavid van Moolenbroek #include "inc.h"
4*31b6611aSDavid van Moolenbroek 
5*31b6611aSDavid van Moolenbroek #include <minix/rs.h>
6*31b6611aSDavid van Moolenbroek #include "rs/const.h"
7*31b6611aSDavid van Moolenbroek #include "rs/type.h"
8*31b6611aSDavid van Moolenbroek 
9*31b6611aSDavid van Moolenbroek static struct rprocpub rprocpub[NR_SYS_PROCS];
10*31b6611aSDavid van Moolenbroek static struct rproc rproc[NR_SYS_PROCS];
11*31b6611aSDavid van Moolenbroek 
12*31b6611aSDavid van Moolenbroek static struct inode *service_node;
13*31b6611aSDavid van Moolenbroek 
14*31b6611aSDavid van Moolenbroek /*
15*31b6611aSDavid van Moolenbroek  * Initialize the service directory.
16*31b6611aSDavid van Moolenbroek  */
17*31b6611aSDavid van Moolenbroek void
18*31b6611aSDavid van Moolenbroek service_init(void)
19*31b6611aSDavid van Moolenbroek {
20*31b6611aSDavid van Moolenbroek 	struct inode *root, *node;
21*31b6611aSDavid van Moolenbroek 	struct inode_stat stat;
22*31b6611aSDavid van Moolenbroek 
23*31b6611aSDavid van Moolenbroek 	root = get_root_inode();
24*31b6611aSDavid van Moolenbroek 
25*31b6611aSDavid van Moolenbroek 	memset(&stat, 0, sizeof(stat));
26*31b6611aSDavid van Moolenbroek 	stat.mode = DIR_ALL_MODE;
27*31b6611aSDavid van Moolenbroek 	stat.uid = SUPER_USER;
28*31b6611aSDavid van Moolenbroek 	stat.gid = SUPER_USER;
29*31b6611aSDavid van Moolenbroek 
30*31b6611aSDavid van Moolenbroek 	service_node = add_inode(root, "service", NO_INDEX, &stat,
31*31b6611aSDavid van Moolenbroek 	    NR_SYS_PROCS, NULL);
32*31b6611aSDavid van Moolenbroek 
33*31b6611aSDavid van Moolenbroek 	if (service_node == NULL)
34*31b6611aSDavid van Moolenbroek 		panic("unable to create service node");
35*31b6611aSDavid van Moolenbroek }
36*31b6611aSDavid van Moolenbroek 
37*31b6611aSDavid van Moolenbroek /*
38*31b6611aSDavid van Moolenbroek  * Update the contents of the service directory, by first updating the RS
39*31b6611aSDavid van Moolenbroek  * tables and then updating the directory contents.
40*31b6611aSDavid van Moolenbroek  */
41*31b6611aSDavid van Moolenbroek void
42*31b6611aSDavid van Moolenbroek service_update(void)
43*31b6611aSDavid van Moolenbroek {
44*31b6611aSDavid van Moolenbroek 	struct inode *node;
45*31b6611aSDavid van Moolenbroek 	struct inode_stat stat;
46*31b6611aSDavid van Moolenbroek 	index_t slot;
47*31b6611aSDavid van Moolenbroek 
48*31b6611aSDavid van Moolenbroek 	/* There is not much we can do if either of these calls fails. */
49*31b6611aSDavid van Moolenbroek 	(void)getsysinfo(RS_PROC_NR, SI_PROCPUB_TAB, rprocpub,
50*31b6611aSDavid van Moolenbroek 	    sizeof(rprocpub));
51*31b6611aSDavid van Moolenbroek 	(void)getsysinfo(RS_PROC_NR, SI_PROC_TAB, rproc, sizeof(rproc));
52*31b6611aSDavid van Moolenbroek 
53*31b6611aSDavid van Moolenbroek 	/*
54*31b6611aSDavid van Moolenbroek 	 * As with PIDs, we make two passes.  Delete first, then add.  This
55*31b6611aSDavid van Moolenbroek 	 * prevents problems in the hypothetical case that between updates, one
56*31b6611aSDavid van Moolenbroek 	 * slot ends up with the label name of a previous, different slot.
57*31b6611aSDavid van Moolenbroek 	 */
58*31b6611aSDavid van Moolenbroek 	for (slot = 0; slot < NR_SYS_PROCS; slot++) {
59*31b6611aSDavid van Moolenbroek 		if ((node = get_inode_by_index(service_node, slot)) == NULL)
60*31b6611aSDavid van Moolenbroek 			continue;
61*31b6611aSDavid van Moolenbroek 
62*31b6611aSDavid van Moolenbroek 		/*
63*31b6611aSDavid van Moolenbroek 		 * If the slot is no longer in use, or the label name does not
64*31b6611aSDavid van Moolenbroek 		 * match, the node must be deleted.
65*31b6611aSDavid van Moolenbroek 		 */
66*31b6611aSDavid van Moolenbroek 		if (!(rproc[slot].r_flags & RS_IN_USE) ||
67*31b6611aSDavid van Moolenbroek 		    strcmp(get_inode_name(node), rprocpub[slot].label))
68*31b6611aSDavid van Moolenbroek 			delete_inode(node);
69*31b6611aSDavid van Moolenbroek 	}
70*31b6611aSDavid van Moolenbroek 
71*31b6611aSDavid van Moolenbroek 	memset(&stat, 0, sizeof(stat));
72*31b6611aSDavid van Moolenbroek 	stat.mode = REG_ALL_MODE;
73*31b6611aSDavid van Moolenbroek 	stat.uid = SUPER_USER;
74*31b6611aSDavid van Moolenbroek 	stat.gid = SUPER_USER;
75*31b6611aSDavid van Moolenbroek 
76*31b6611aSDavid van Moolenbroek 	for (slot = 0; slot < NR_SYS_PROCS; slot++) {
77*31b6611aSDavid van Moolenbroek 		if (!(rproc[slot].r_flags & RS_IN_USE) ||
78*31b6611aSDavid van Moolenbroek 		    get_inode_by_index(service_node, slot) != NULL)
79*31b6611aSDavid van Moolenbroek 			continue;
80*31b6611aSDavid van Moolenbroek 
81*31b6611aSDavid van Moolenbroek 		node = add_inode(service_node, rprocpub[slot].label, slot,
82*31b6611aSDavid van Moolenbroek 		    &stat, (index_t)0, (cbdata_t)slot);
83*31b6611aSDavid van Moolenbroek 
84*31b6611aSDavid van Moolenbroek 		if (node == NULL)
85*31b6611aSDavid van Moolenbroek 			out_of_inodes();
86*31b6611aSDavid van Moolenbroek 	}
87*31b6611aSDavid van Moolenbroek }
88*31b6611aSDavid van Moolenbroek 
89*31b6611aSDavid van Moolenbroek /*
90*31b6611aSDavid van Moolenbroek  * A lookup request is being performed.  If it is in the service directory,
91*31b6611aSDavid van Moolenbroek  * update the tables.  We do this lazily, to reduce overhead.
92*31b6611aSDavid van Moolenbroek  */
93*31b6611aSDavid van Moolenbroek void
94*31b6611aSDavid van Moolenbroek service_lookup(struct inode * parent, clock_t now)
95*31b6611aSDavid van Moolenbroek {
96*31b6611aSDavid van Moolenbroek 	static clock_t last_update = 0;
97*31b6611aSDavid van Moolenbroek 
98*31b6611aSDavid van Moolenbroek 	if (parent != service_node)
99*31b6611aSDavid van Moolenbroek 		return;
100*31b6611aSDavid van Moolenbroek 
101*31b6611aSDavid van Moolenbroek 	if (last_update != now) {
102*31b6611aSDavid van Moolenbroek 		service_update();
103*31b6611aSDavid van Moolenbroek 
104*31b6611aSDavid van Moolenbroek 		last_update = now;
105*31b6611aSDavid van Moolenbroek 	}
106*31b6611aSDavid van Moolenbroek }
107*31b6611aSDavid van Moolenbroek 
108*31b6611aSDavid van Moolenbroek /*
109*31b6611aSDavid van Moolenbroek  * A getdents request is being performed.  If it is in the service directory,
110*31b6611aSDavid van Moolenbroek  * update the tables.
111*31b6611aSDavid van Moolenbroek  */
112*31b6611aSDavid van Moolenbroek void
113*31b6611aSDavid van Moolenbroek service_getdents(struct inode * node)
114*31b6611aSDavid van Moolenbroek {
115*31b6611aSDavid van Moolenbroek 
116*31b6611aSDavid van Moolenbroek 	if (node != service_node)
117*31b6611aSDavid van Moolenbroek 		return;
118*31b6611aSDavid van Moolenbroek 
119*31b6611aSDavid van Moolenbroek 	service_update();
120*31b6611aSDavid van Moolenbroek }
121*31b6611aSDavid van Moolenbroek 
122*31b6611aSDavid van Moolenbroek /*
123*31b6611aSDavid van Moolenbroek  * A read request is being performed.  If it is on a file in the service
124*31b6611aSDavid van Moolenbroek  * directory, process the read request.  We rely on the fact that any read
125*31b6611aSDavid van Moolenbroek  * call will have been preceded by a lookup, so its table entry has been
126*31b6611aSDavid van Moolenbroek  * updated very recently.
127*31b6611aSDavid van Moolenbroek  */
128*31b6611aSDavid van Moolenbroek void
129*31b6611aSDavid van Moolenbroek service_read(struct inode * node)
130*31b6611aSDavid van Moolenbroek {
131*31b6611aSDavid van Moolenbroek 	struct inode *parent;
132*31b6611aSDavid van Moolenbroek 	index_t slot;
133*31b6611aSDavid van Moolenbroek 	struct rprocpub *rpub;
134*31b6611aSDavid van Moolenbroek 	struct rproc *rp;
135*31b6611aSDavid van Moolenbroek 
136*31b6611aSDavid van Moolenbroek 	if (get_parent_inode(node) != service_node)
137*31b6611aSDavid van Moolenbroek 		return;
138*31b6611aSDavid van Moolenbroek 
139*31b6611aSDavid van Moolenbroek 	slot = get_inode_index(node);
140*31b6611aSDavid van Moolenbroek 	rpub = &rprocpub[slot];
141*31b6611aSDavid van Moolenbroek 	rp = &rproc[slot];
142*31b6611aSDavid van Moolenbroek 
143*31b6611aSDavid van Moolenbroek 	/* TODO: add a large number of other fields! */
144*31b6611aSDavid van Moolenbroek 	buf_printf("%d %d\n", rpub->endpoint, rp->r_restarts);
145*31b6611aSDavid van Moolenbroek }
146