xref: /minix/minix/fs/mfs/main.c (revision 7f5f010b)
1 #include "fs.h"
2 #include <assert.h>
3 #include <minix/callnr.h>
4 #include <signal.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <minix/dmap.h>
8 #include <minix/endpoint.h>
9 #include <minix/vfsif.h>
10 #include "buf.h"
11 #include "inode.h"
12 
13 
14 /* Declare some local functions. */
15 static void get_work(message *m_in);
16 static void reply(endpoint_t who, message *m_out);
17 
18 /* SEF functions and variables. */
19 static void sef_local_startup(void);
20 static int sef_cb_init_fresh(int type, sef_init_info_t *info);
21 static void sef_cb_signal_handler(int signo);
22 
23 /*===========================================================================*
24  *				main                                         *
25  *===========================================================================*/
26 int main(int argc, char *argv[])
27 {
28 /* This is the main routine of this service. The main loop consists of
29  * three major activities: getting new work, processing the work, and
30  * sending the reply. The loop never terminates, unless a panic occurs.
31  */
32   int error = OK, ind, transid;
33 
34   /* SEF local startup. */
35   env_setargs(argc, argv);
36   sef_local_startup();
37 
38   while(!unmountdone || !exitsignaled) {
39 	endpoint_t src;
40 
41 	/* Wait for request message. */
42 	get_work(&fs_m_in);
43 
44 	transid = TRNS_GET_ID(fs_m_in.m_type);
45 	fs_m_in.m_type = TRNS_DEL_ID(fs_m_in.m_type);
46 	if (fs_m_in.m_type == 0) {
47 		assert(!IS_VFS_FS_TRANSID(transid));
48 		fs_m_in.m_type = transid;	/* Backwards compat. */
49 		transid = 0;
50 	} else
51 		assert(IS_VFS_FS_TRANSID(transid));
52 
53 	src = fs_m_in.m_source;
54 	caller_uid = INVAL_UID;	/* To trap errors */
55 	caller_gid = INVAL_GID;
56 	req_nr = fs_m_in.m_type;
57 
58 	if (req_nr < FS_BASE) {
59 		fs_m_in.m_type += FS_BASE;
60 		req_nr = fs_m_in.m_type;
61 	}
62 	ind = req_nr - FS_BASE;
63 
64 	if (ind < 0 || ind >= NREQS) {
65 		printf("MFS: bad request %d from %d\n", req_nr, src);
66 		printf("ind = %d\n", ind);
67 		error = EINVAL;
68 	} else {
69 		error = (*fs_call_vec[ind])();
70 		/*cch_check();*/
71 	}
72 
73 	fs_m_out.m_type = error;
74 	if (IS_VFS_FS_TRANSID(transid)) {
75 		/* If a transaction ID was set, reset it */
76 		fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, transid);
77 	}
78 	reply(src, &fs_m_out);
79   }
80 
81   return(OK);
82 }
83 
84 /*===========================================================================*
85  *			       sef_local_startup			     *
86  *===========================================================================*/
87 static void sef_local_startup()
88 {
89   /* Register init callbacks. */
90   sef_setcb_init_fresh(sef_cb_init_fresh);
91   sef_setcb_init_restart(sef_cb_init_fail);
92 
93   /* No live update support for now. */
94 
95   /* Register signal callbacks. */
96   sef_setcb_signal_handler(sef_cb_signal_handler);
97 
98   /* Let SEF perform startup. */
99   sef_startup();
100 }
101 
102 /*===========================================================================*
103  *		            sef_cb_init_fresh                                *
104  *===========================================================================*/
105 static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
106 {
107 /* Initialize the Minix file server. */
108   int i;
109 
110   lmfs_may_use_vmcache(1);
111 
112   /* Init inode table */
113   for (i = 0; i < NR_INODES; ++i) {
114 	inode[i].i_count = 0;
115 	cch[i] = 0;
116   }
117 
118   init_inode_cache();
119 
120   lmfs_buf_pool(DEFAULT_NR_BUFS);
121 
122   return(OK);
123 }
124 
125 /*===========================================================================*
126  *		           sef_cb_signal_handler                             *
127  *===========================================================================*/
128 static void sef_cb_signal_handler(int signo)
129 {
130   /* Only check for termination signal, ignore anything else. */
131   if (signo != SIGTERM) return;
132 
133   exitsignaled = 1;
134   (void) fs_sync();
135 
136   /* If unmounting has already been performed, exit immediately.
137    * We might not get another message.
138    */
139   if (unmountdone) exit(0);
140 }
141 
142 /*===========================================================================*
143  *				get_work				     *
144  *===========================================================================*/
145 static void get_work(m_in)
146 message *m_in;				/* pointer to message */
147 {
148   int r, srcok = 0;
149   endpoint_t src;
150 
151   do {
152 	if ((r = sef_receive(ANY, m_in)) != OK) 	/* wait for message */
153 		panic("sef_receive failed: %d", r);
154 	src = m_in->m_source;
155 
156 	if(src == VFS_PROC_NR) {
157 		if(unmountdone)
158 			printf("MFS: unmounted: unexpected message from FS\n");
159 		else
160 			srcok = 1;		/* Normal FS request. */
161 
162 	} else
163 		printf("MFS: unexpected source %d\n", src);
164   } while(!srcok);
165 
166    assert((src == VFS_PROC_NR && !unmountdone));
167 }
168 
169 
170 /*===========================================================================*
171  *				reply					     *
172  *===========================================================================*/
173 static void reply(
174   endpoint_t who,
175   message *m_out                       	/* report result */
176 )
177 {
178   if (OK != ipc_send(who, m_out))    /* send the message */
179 	printf("MFS(%d) was unable to send reply\n", sef_self());
180 }
181 
182 
183 #if 0
184 /*===========================================================================*
185  *				cch_check				     *
186  *===========================================================================*/
187 static void cch_check(void)
188 {
189   int i;
190 
191   for (i = 0; i < NR_INODES; ++i) {
192 	if (inode[i].i_count != cch[i] && req_nr != REQ_GETNODE &&
193 	    req_nr != REQ_PUTNODE && req_nr != REQ_READSUPER &&
194 	    req_nr != REQ_MOUNTPOINT && req_nr != REQ_UNMOUNT &&
195 	    req_nr != REQ_SYNC && req_nr != REQ_LOOKUP) {
196 		printf("MFS(%d) inode(%lu) cc: %d req_nr: %d\n", sef_self(),
197 			inode[i].i_num, inode[i].i_count - cch[i], req_nr);
198 	}
199 
200 	cch[i] = inode[i].i_count;
201   }
202 }
203 #endif
204 
205