xref: /minix3/minix/fs/procfs/service.c (revision e4d99eb9b04c9e4b5eae1e3658fb71795f36d65a)
131b6611aSDavid van Moolenbroek /* ProcFS - service.c - the service subdirectory */
231b6611aSDavid van Moolenbroek 
331b6611aSDavid van Moolenbroek #include "inc.h"
431b6611aSDavid van Moolenbroek 
531b6611aSDavid van Moolenbroek #include <minix/rs.h>
631b6611aSDavid van Moolenbroek #include "rs/const.h"
731b6611aSDavid van Moolenbroek #include "rs/type.h"
831b6611aSDavid van Moolenbroek 
941ba8c04SLionel Sambuc enum policy {
1041ba8c04SLionel Sambuc 	POL_NONE	= 0x00,	/*     user	| endpoint	*/
1141ba8c04SLionel Sambuc 	POL_RESET	= 0x01,	/* visible	|  change	*/
1241ba8c04SLionel Sambuc 	POL_RESTART	= 0x02,	/* transparent	| preserved	*/
1341ba8c04SLionel Sambuc 	POL_LIVE_UPDATE	= 0x04	/* transparent	| preserved	*/
1441ba8c04SLionel Sambuc };
1541ba8c04SLionel Sambuc 
1641ba8c04SLionel Sambuc struct policies {
1741ba8c04SLionel Sambuc 	#define MAX_POL_FORMAT_SZ 20
1841ba8c04SLionel Sambuc 	char formatted[MAX_POL_FORMAT_SZ];
1941ba8c04SLionel Sambuc 	enum policy supported;
2041ba8c04SLionel Sambuc };
2141ba8c04SLionel Sambuc 
22129adfebSDavid van Moolenbroek typedef struct {
230eabb93cSDavid van Moolenbroek 	struct rproc proc[NR_SYS_PROCS];
240eabb93cSDavid van Moolenbroek 	struct rprocpub pub[NR_SYS_PROCS];
25129adfebSDavid van Moolenbroek } ixfer_rproc_t;
26129adfebSDavid van Moolenbroek static ixfer_rproc_t rproc;
270eabb93cSDavid van Moolenbroek 
2841ba8c04SLionel Sambuc static struct policies policies[NR_SYS_PROCS];
2931b6611aSDavid van Moolenbroek 
3031b6611aSDavid van Moolenbroek static struct inode *service_node;
3131b6611aSDavid van Moolenbroek 
3241ba8c04SLionel Sambuc /* Updates the policies state from RS. Always returns an ASCIIZ string.  */
3341ba8c04SLionel Sambuc static const char *
3441ba8c04SLionel Sambuc service_get_policies(struct policies * pol, index_t slot)
3531b6611aSDavid van Moolenbroek {
3641ba8c04SLionel Sambuc #if 1 /* The following should be retrieved from RS and formated instead. */
3741ba8c04SLionel Sambuc 	int pos;
3841ba8c04SLionel Sambuc 	char *ref_label;
3941ba8c04SLionel Sambuc 	static const struct {
4041ba8c04SLionel Sambuc 		const char *label;
4141ba8c04SLionel Sambuc 		const char *policy_str;
4241ba8c04SLionel Sambuc 	} def_pol[] = {
4341ba8c04SLionel Sambuc 		/* audio */
4441ba8c04SLionel Sambuc 		{ .label = "es1370", .policy_str = "reset" },
4541ba8c04SLionel Sambuc 		{ .label = "es1371", .policy_str = "reset" },
4641ba8c04SLionel Sambuc 		{ .label = "sb16", .policy_str = "reset" },
4741ba8c04SLionel Sambuc 		/* bus */
4841ba8c04SLionel Sambuc 		{ .label = "i2c", .policy_str = "restart" },
4941ba8c04SLionel Sambuc 		{ .label = "pci", .policy_str = "restart" },
5041ba8c04SLionel Sambuc 		{ .label = "ti1225", .policy_str = "restart" },
5141ba8c04SLionel Sambuc 		/* clock */
5241ba8c04SLionel Sambuc 		{ .label = "readclock.drv", .policy_str = "restart" },
5341ba8c04SLionel Sambuc 		/* eeprom */
5441ba8c04SLionel Sambuc 		{ .label = "cat24c256", .policy_str = "restart" },
5541ba8c04SLionel Sambuc 		/* examples */
5641ba8c04SLionel Sambuc 		{ .label = "hello", .policy_str = "restart" },
5741ba8c04SLionel Sambuc 		/* hid */
5841ba8c04SLionel Sambuc 		{ .label = "pckbd", .policy_str = "reset" },
5941ba8c04SLionel Sambuc 		/* iommu */
6041ba8c04SLionel Sambuc 		{ .label = "amddev", .policy_str = "" },
6141ba8c04SLionel Sambuc 		/* net */
620c474453SCristiano Giuffrida 		{ .label = "3c90x", .policy_str = "reset" },
630c474453SCristiano Giuffrida 		{ .label = "atl2", .policy_str = "reset" },
640c474453SCristiano Giuffrida 		{ .label = "dec21140A", .policy_str = "reset" },
650c474453SCristiano Giuffrida 		{ .label = "dp8390", .policy_str = "reset" },
660c474453SCristiano Giuffrida 		{ .label = "dpeth", .policy_str = "reset" },
670c474453SCristiano Giuffrida 		{ .label = "e1000", .policy_str = "reset" },
680c474453SCristiano Giuffrida 		{ .label = "fxp", .policy_str = "reset" },
690c474453SCristiano Giuffrida 		{ .label = "lance", .policy_str = "reset" },
700c474453SCristiano Giuffrida 		{ .label = "lan8710a", .policy_str = "reset" },
710c474453SCristiano Giuffrida 		{ .label = "orinoco", .policy_str = "reset" },
720c474453SCristiano Giuffrida 		{ .label = "rtl8139", .policy_str = "reset" },
730c474453SCristiano Giuffrida 		{ .label = "rtl8169", .policy_str = "reset" },
7441ba8c04SLionel Sambuc 		{ .label = "uds", .policy_str = "reset" },
750c474453SCristiano Giuffrida 		{ .label = "virtio_net", .policy_str = "reset" },
7641ba8c04SLionel Sambuc 		/* power */
7741ba8c04SLionel Sambuc 		{ .label = "acpi", .policy_str = "" },
7841ba8c04SLionel Sambuc 		{ .label = "tps65217", .policy_str = "" },
7941ba8c04SLionel Sambuc 		{ .label = "tps65590", .policy_str = "" },
8041ba8c04SLionel Sambuc 		/* printer */
8141ba8c04SLionel Sambuc 		{ .label = "printer", .policy_str = "restart" },
8241ba8c04SLionel Sambuc 		/* sensors */
8341ba8c04SLionel Sambuc 		{ .label = "bmp085", .policy_str = "" },
8441ba8c04SLionel Sambuc 		{ .label = "sht21", .policy_str = "restart" },
8541ba8c04SLionel Sambuc 		{ .label = "tsl2550", .policy_str = "restart" },
8641ba8c04SLionel Sambuc 		/* storage */
8741ba8c04SLionel Sambuc 		{ .label = "ahci", .policy_str = "reset" },
8841ba8c04SLionel Sambuc 		{ .label = "at_wini", .policy_str = "reset" },
8941ba8c04SLionel Sambuc 		{ .label = "fbd", .policy_str = "reset" },
9041ba8c04SLionel Sambuc 		{ .label = "filter", .policy_str = "reset" },
9141ba8c04SLionel Sambuc 		{ .label = "floppy", .policy_str = "reset" },
9241ba8c04SLionel Sambuc 		{ .label = "memory", .policy_str = "restart" },
9341ba8c04SLionel Sambuc 		{ .label = "mmc", .policy_str = "reset" },
9441ba8c04SLionel Sambuc 		{ .label = "virtio_blk", .policy_str = "reset" },
9541ba8c04SLionel Sambuc 		{ .label = "vnd", .policy_str = "reset" },
9641ba8c04SLionel Sambuc 		/* system */
9741ba8c04SLionel Sambuc 		{ .label = "gpio", .policy_str = "restart" },
9867b47183SLionel Sambuc 		{ .label = "log", .policy_str = "reset" },
9941ba8c04SLionel Sambuc 		{ .label = "random", .policy_str = "restart" },
10041ba8c04SLionel Sambuc 		/* tty */
10141ba8c04SLionel Sambuc 		{ .label = "pty", .policy_str = "restart" },
1020c474453SCristiano Giuffrida 		{ .label = "tty", .policy_str = "restart" },
10341ba8c04SLionel Sambuc 		/* usb */
10441ba8c04SLionel Sambuc 		{ .label = "usbd", .policy_str = "" },
10541ba8c04SLionel Sambuc 		{ .label = "usb_hub", .policy_str = "" },
10641ba8c04SLionel Sambuc 		{ .label = "usb_storage", .policy_str = "" },
10741ba8c04SLionel Sambuc 		/* video */
10841ba8c04SLionel Sambuc 		{ .label = "fb", .policy_str = "" },
10941ba8c04SLionel Sambuc 		{ .label = "tda19988", .policy_str = "" },
11041ba8c04SLionel Sambuc 		/* vmm_guest */
11141ba8c04SLionel Sambuc 		{ .label = "vbox", .policy_str = "" },
11241ba8c04SLionel Sambuc 		/* fs */
11341ba8c04SLionel Sambuc 		{ .label = "ext2", .policy_str = "" },
11441ba8c04SLionel Sambuc 		{ .label = "hgfs", .policy_str = "" },
11541ba8c04SLionel Sambuc 		{ .label = "isofs", .policy_str = "" },
1160c474453SCristiano Giuffrida 		{ .label = "mfs", .policy_str = "restart" },
1170c474453SCristiano Giuffrida 		{ .label = "pfs", .policy_str = "restart" },
1180c474453SCristiano Giuffrida 		{ .label = "procfs", .policy_str = "restart" },
119da21d850SDavid van Moolenbroek 		{ .label = "ptyfs", .policy_str = "" },
12041ba8c04SLionel Sambuc 		{ .label = "vbfs", .policy_str = "" },
12141ba8c04SLionel Sambuc 		/* net */
12241ba8c04SLionel Sambuc 		{ .label = "inet", .policy_str = "reset" },
12341ba8c04SLionel Sambuc 		{ .label = "lwip", .policy_str = "" },
12441ba8c04SLionel Sambuc 		/* servers */
1250c474453SCristiano Giuffrida 		{ .label = "devman", .policy_str = "restart" },
1260c474453SCristiano Giuffrida 		{ .label = "ds", .policy_str = "restart" },
12741ba8c04SLionel Sambuc 		{ .label = "input", .policy_str = "reset" },
12841ba8c04SLionel Sambuc 		{ .label = "ipc", .policy_str = "restart" },
12941ba8c04SLionel Sambuc 		{ .label = "is", .policy_str = "restart" },
1300c474453SCristiano Giuffrida 		{ .label = "pm", .policy_str = "restart" },
1310c474453SCristiano Giuffrida 		{ .label = "rs", .policy_str = "restart" },
1320c474453SCristiano Giuffrida 		{ .label = "sched", .policy_str = "restart" },
1330c474453SCristiano Giuffrida 		{ .label = "vfs", .policy_str = "restart" },
1348b0f8559SLionel Sambuc 		{ .label = "vm", .policy_str = "restart" },
13541ba8c04SLionel Sambuc 		//{ .label = "", .policy_str = "" },
13641ba8c04SLionel Sambuc 	};
13731b6611aSDavid van Moolenbroek 
13841ba8c04SLionel Sambuc 	/* Find the related policy, based on the file name of the service. */
1390eabb93cSDavid van Moolenbroek 	ref_label = strrchr(rproc.pub[slot].proc_name, '/');
14041ba8c04SLionel Sambuc 	if (NULL == ref_label)
1410eabb93cSDavid van Moolenbroek 		ref_label = rproc.pub[slot].proc_name;
14231b6611aSDavid van Moolenbroek 
14341ba8c04SLionel Sambuc 	memset(pol[slot].formatted, 0, MAX_POL_FORMAT_SZ);
14441ba8c04SLionel Sambuc 	for(pos = 0; pos < (sizeof(def_pol) / sizeof(def_pol[0])); pos++) {
14541ba8c04SLionel Sambuc 		if (0 == strcmp(ref_label, def_pol[pos].label)) {
146f5321d8dSDavid van Moolenbroek 			(void)strncpy(pol[slot].formatted,
147f5321d8dSDavid van Moolenbroek 			    def_pol[pos].policy_str, MAX_POL_FORMAT_SZ);
14841ba8c04SLionel Sambuc 			pol[slot].formatted[MAX_POL_FORMAT_SZ-1] = '\0';
14941ba8c04SLionel Sambuc 			break;
15041ba8c04SLionel Sambuc 		}
15141ba8c04SLionel Sambuc 	}
15241ba8c04SLionel Sambuc #else
15341ba8c04SLionel Sambuc 	/* Should do something sensible, based on flags from RS/SEF. */
15441ba8c04SLionel Sambuc #endif
15531b6611aSDavid van Moolenbroek 
15641ba8c04SLionel Sambuc 	return pol[slot].formatted;
15731b6611aSDavid van Moolenbroek }
15831b6611aSDavid van Moolenbroek 
1590c474453SCristiano Giuffrida /* Returns a ASCIIZ string encoding RS flags.  */
1600c474453SCristiano Giuffrida static const char *
1610c474453SCristiano Giuffrida service_get_flags(index_t slot)
1620c474453SCristiano Giuffrida {
1630c474453SCristiano Giuffrida 	static char str[10];
1640c474453SCristiano Giuffrida 	int flags, sys_flags;
1650c474453SCristiano Giuffrida 
1660c474453SCristiano Giuffrida 	flags = rproc.proc[slot].r_flags;
1670c474453SCristiano Giuffrida 	sys_flags = rproc.pub[slot].sys_flags;
1680c474453SCristiano Giuffrida 
1690c474453SCristiano Giuffrida 	str[0] = (flags & RS_ACTIVE)        ? 'A' : '-';
1700c474453SCristiano Giuffrida 	str[1] = (flags & RS_UPDATING)      ? 'U' : '-';
1710c474453SCristiano Giuffrida 	str[2] = (flags & RS_EXITING)       ? 'E' : '-';
1720c474453SCristiano Giuffrida 	str[3] = (flags & RS_NOPINGREPLY)   ? 'N' : '-';
1730c474453SCristiano Giuffrida 	str[4] = (sys_flags & SF_USE_COPY)  ? 'C' : '-';
1740c474453SCristiano Giuffrida 	str[5] = (sys_flags & SF_USE_REPL)  ? 'R' : '-';
1750c474453SCristiano Giuffrida 	str[6] = (sys_flags & SF_NEED_COPY) ? 'c' : '-';
1760c474453SCristiano Giuffrida 	str[7] = (sys_flags & SF_NEED_REPL) ? 'r' : '-';
1770c474453SCristiano Giuffrida 	str[8] = (sys_flags & SF_CORE_SRV)  ? 's' : '-';
1780c474453SCristiano Giuffrida 	str[9] = '\0';
1790c474453SCristiano Giuffrida 
1800c474453SCristiano Giuffrida 	return str;
1810c474453SCristiano Giuffrida }
1820c474453SCristiano Giuffrida 
18331b6611aSDavid van Moolenbroek /*
184f5321d8dSDavid van Moolenbroek  * Return whether a slot is in use and active.  The purpose of this check is
185f5321d8dSDavid van Moolenbroek  * to ensure that after eliminating all slots that do not pass this check, we
186f5321d8dSDavid van Moolenbroek  * are left with a set of live services each with a unique label.
187f5321d8dSDavid van Moolenbroek  */
188f5321d8dSDavid van Moolenbroek static int
189f5321d8dSDavid van Moolenbroek service_active(index_t slot)
190f5321d8dSDavid van Moolenbroek {
191f5321d8dSDavid van Moolenbroek 
192fefec20eSDavid van Moolenbroek 	/*
193fefec20eSDavid van Moolenbroek 	 * Init is in RS's process tables as the representation of user
194fefec20eSDavid van Moolenbroek 	 * processes.  It is not a system service.
195fefec20eSDavid van Moolenbroek 	 */
196f5321d8dSDavid van Moolenbroek 	return ((rproc.proc[slot].r_flags & (RS_IN_USE | RS_ACTIVE)) ==
197fefec20eSDavid van Moolenbroek 	    (RS_IN_USE | RS_ACTIVE) &&
198fefec20eSDavid van Moolenbroek 	   rproc.pub[slot].endpoint != INIT_PROC_NR);
199f5321d8dSDavid van Moolenbroek }
200f5321d8dSDavid van Moolenbroek 
201f5321d8dSDavid van Moolenbroek /*
20231b6611aSDavid van Moolenbroek  * Update the contents of the service directory, by first updating the RS
20331b6611aSDavid van Moolenbroek  * tables and then updating the directory contents.
20431b6611aSDavid van Moolenbroek  */
20541ba8c04SLionel Sambuc static void
20631b6611aSDavid van Moolenbroek service_update(void)
20731b6611aSDavid van Moolenbroek {
20831b6611aSDavid van Moolenbroek 	struct inode *node;
20931b6611aSDavid van Moolenbroek 	struct inode_stat stat;
21031b6611aSDavid van Moolenbroek 	index_t slot;
2110eabb93cSDavid van Moolenbroek 	static int warned = FALSE;
2120eabb93cSDavid van Moolenbroek 	int r;
21331b6611aSDavid van Moolenbroek 
2140eabb93cSDavid van Moolenbroek 	/* There is not much we can do if this call fails. */
2150eabb93cSDavid van Moolenbroek 	r = getsysinfo(RS_PROC_NR, SI_PROCALL_TAB, &rproc, sizeof(rproc));
2160eabb93cSDavid van Moolenbroek 	if (r != OK && !warned) {
2170eabb93cSDavid van Moolenbroek 		printf("PROCFS: unable to obtain RS tables (%d)\n", r);
2180eabb93cSDavid van Moolenbroek 		warned = TRUE;
2190eabb93cSDavid van Moolenbroek 	}
22031b6611aSDavid van Moolenbroek 
22131b6611aSDavid van Moolenbroek 	/*
22231b6611aSDavid van Moolenbroek 	 * As with PIDs, we make two passes.  Delete first, then add.  This
22331b6611aSDavid van Moolenbroek 	 * prevents problems in the hypothetical case that between updates, one
22431b6611aSDavid van Moolenbroek 	 * slot ends up with the label name of a previous, different slot.
22531b6611aSDavid van Moolenbroek 	 */
22631b6611aSDavid van Moolenbroek 	for (slot = 0; slot < NR_SYS_PROCS; slot++) {
22731b6611aSDavid van Moolenbroek 		if ((node = get_inode_by_index(service_node, slot)) == NULL)
22831b6611aSDavid van Moolenbroek 			continue;
22931b6611aSDavid van Moolenbroek 
23031b6611aSDavid van Moolenbroek 		/*
23131b6611aSDavid van Moolenbroek 		 * If the slot is no longer in use, or the label name does not
23231b6611aSDavid van Moolenbroek 		 * match, the node must be deleted.
23331b6611aSDavid van Moolenbroek 		 */
234f5321d8dSDavid van Moolenbroek 		if (!service_active(slot) ||
2350eabb93cSDavid van Moolenbroek 		    strcmp(get_inode_name(node), rproc.pub[slot].label))
23631b6611aSDavid van Moolenbroek 			delete_inode(node);
23731b6611aSDavid van Moolenbroek 	}
23831b6611aSDavid van Moolenbroek 
23931b6611aSDavid van Moolenbroek 	memset(&stat, 0, sizeof(stat));
24031b6611aSDavid van Moolenbroek 	stat.mode = REG_ALL_MODE;
24131b6611aSDavid van Moolenbroek 	stat.uid = SUPER_USER;
24231b6611aSDavid van Moolenbroek 	stat.gid = SUPER_USER;
24331b6611aSDavid van Moolenbroek 
24431b6611aSDavid van Moolenbroek 	for (slot = 0; slot < NR_SYS_PROCS; slot++) {
245f5321d8dSDavid van Moolenbroek 		if (!service_active(slot) ||
24631b6611aSDavid van Moolenbroek 		    get_inode_by_index(service_node, slot) != NULL)
24731b6611aSDavid van Moolenbroek 			continue;
24831b6611aSDavid van Moolenbroek 
2490eabb93cSDavid van Moolenbroek 		node = add_inode(service_node, rproc.pub[slot].label, slot,
25031b6611aSDavid van Moolenbroek 		    &stat, (index_t)0, (cbdata_t)slot);
25131b6611aSDavid van Moolenbroek 
25231b6611aSDavid van Moolenbroek 		if (node == NULL)
25331b6611aSDavid van Moolenbroek 			out_of_inodes();
25431b6611aSDavid van Moolenbroek 	}
25531b6611aSDavid van Moolenbroek }
25631b6611aSDavid van Moolenbroek 
25731b6611aSDavid van Moolenbroek /*
25841ba8c04SLionel Sambuc  * Initialize the service directory.
25941ba8c04SLionel Sambuc  */
26041ba8c04SLionel Sambuc void
26141ba8c04SLionel Sambuc service_init(void)
26241ba8c04SLionel Sambuc {
26341ba8c04SLionel Sambuc 	struct inode *root, *node;
26441ba8c04SLionel Sambuc 	struct inode_stat stat;
26541ba8c04SLionel Sambuc 
26641ba8c04SLionel Sambuc 	root = get_root_inode();
26741ba8c04SLionel Sambuc 
26841ba8c04SLionel Sambuc 	memset(&stat, 0, sizeof(stat));
26941ba8c04SLionel Sambuc 	stat.mode = DIR_ALL_MODE;
27041ba8c04SLionel Sambuc 	stat.uid = SUPER_USER;
27141ba8c04SLionel Sambuc 	stat.gid = SUPER_USER;
27241ba8c04SLionel Sambuc 
27341ba8c04SLionel Sambuc 	service_node = add_inode(root, "service", NO_INDEX, &stat,
27441ba8c04SLionel Sambuc 	    NR_SYS_PROCS, NULL);
27541ba8c04SLionel Sambuc 
27641ba8c04SLionel Sambuc 	if (service_node == NULL)
27741ba8c04SLionel Sambuc 		panic("unable to create service node");
27841ba8c04SLionel Sambuc }
27941ba8c04SLionel Sambuc 
28041ba8c04SLionel Sambuc /*
28131b6611aSDavid van Moolenbroek  * A lookup request is being performed.  If it is in the service directory,
28231b6611aSDavid van Moolenbroek  * update the tables.  We do this lazily, to reduce overhead.
28331b6611aSDavid van Moolenbroek  */
28431b6611aSDavid van Moolenbroek void
28531b6611aSDavid van Moolenbroek service_lookup(struct inode * parent, clock_t now)
28631b6611aSDavid van Moolenbroek {
28731b6611aSDavid van Moolenbroek 	static clock_t last_update = 0;
28831b6611aSDavid van Moolenbroek 
28931b6611aSDavid van Moolenbroek 	if (parent != service_node)
29031b6611aSDavid van Moolenbroek 		return;
29131b6611aSDavid van Moolenbroek 
29231b6611aSDavid van Moolenbroek 	if (last_update != now) {
29331b6611aSDavid van Moolenbroek 		service_update();
29431b6611aSDavid van Moolenbroek 
29531b6611aSDavid van Moolenbroek 		last_update = now;
29631b6611aSDavid van Moolenbroek 	}
29731b6611aSDavid van Moolenbroek }
29831b6611aSDavid van Moolenbroek 
29931b6611aSDavid van Moolenbroek /*
30031b6611aSDavid van Moolenbroek  * A getdents request is being performed.  If it is in the service directory,
30131b6611aSDavid van Moolenbroek  * update the tables.
30231b6611aSDavid van Moolenbroek  */
30331b6611aSDavid van Moolenbroek void
30431b6611aSDavid van Moolenbroek service_getdents(struct inode * node)
30531b6611aSDavid van Moolenbroek {
30631b6611aSDavid van Moolenbroek 
30731b6611aSDavid van Moolenbroek 	if (node != service_node)
30831b6611aSDavid van Moolenbroek 		return;
30931b6611aSDavid van Moolenbroek 
31031b6611aSDavid van Moolenbroek 	service_update();
31131b6611aSDavid van Moolenbroek }
31231b6611aSDavid van Moolenbroek 
31331b6611aSDavid van Moolenbroek /*
31431b6611aSDavid van Moolenbroek  * A read request is being performed.  If it is on a file in the service
31531b6611aSDavid van Moolenbroek  * directory, process the read request.  We rely on the fact that any read
31631b6611aSDavid van Moolenbroek  * call will have been preceded by a lookup, so its table entry has been
31731b6611aSDavid van Moolenbroek  * updated very recently.
31831b6611aSDavid van Moolenbroek  */
31931b6611aSDavid van Moolenbroek void
32031b6611aSDavid van Moolenbroek service_read(struct inode * node)
32131b6611aSDavid van Moolenbroek {
32231b6611aSDavid van Moolenbroek 	struct inode *parent;
32331b6611aSDavid van Moolenbroek 	index_t slot;
32431b6611aSDavid van Moolenbroek 	struct rprocpub *rpub;
32531b6611aSDavid van Moolenbroek 	struct rproc *rp;
32631b6611aSDavid van Moolenbroek 
32731b6611aSDavid van Moolenbroek 	if (get_parent_inode(node) != service_node)
32831b6611aSDavid van Moolenbroek 		return;
32931b6611aSDavid van Moolenbroek 
33031b6611aSDavid van Moolenbroek 	slot = get_inode_index(node);
3310eabb93cSDavid van Moolenbroek 	rpub = &rproc.pub[slot];
3320eabb93cSDavid van Moolenbroek 	rp = &rproc.proc[slot];
33331b6611aSDavid van Moolenbroek 
33431b6611aSDavid van Moolenbroek 	/* TODO: add a large number of other fields! */
33541ba8c04SLionel Sambuc 	buf_printf("filename: %s\n", rpub->proc_name);
33641ba8c04SLionel Sambuc 	buf_printf("endpoint: %d\n", rpub->endpoint);
337a8f606deSCristiano Giuffrida 	buf_printf("pid:      %d\n", rp->r_pid);
33841ba8c04SLionel Sambuc 	buf_printf("restarts: %d\n", rp->r_restarts);
3390c474453SCristiano Giuffrida 	buf_printf("flags:    %s\n", service_get_flags(slot));
34041ba8c04SLionel Sambuc 	buf_printf("policies: %s\n", service_get_policies(policies, slot));
341*e4d99eb9SDavid van Moolenbroek 	buf_printf("ASRcount: %u\n", rp->r_asr_count);
34231b6611aSDavid van Moolenbroek }
343