VM: make mapping types explicit
[minix.git] / servers / pfs / main.c
blob7d8d71e0b9c7e65e80b6c853a0f67851b92a39cf
1 #include "fs.h"
2 #include <assert.h>
3 #include <signal.h>
4 #include <minix/dmap.h>
5 #include <minix/driver.h>
6 #include <minix/endpoint.h>
7 #include <minix/rs.h>
8 #include <minix/vfsif.h>
9 #include <sys/types.h>
10 #include <pwd.h>
11 #include "buf.h"
12 #include "inode.h"
13 #include "uds.h"
15 static void get_work(message *m_in);
17 /* SEF functions and variables. */
18 static void sef_local_startup(void);
19 static int sef_cb_init_fresh(int type, sef_init_info_t *info);
20 static void sef_cb_signal_handler(int signo);
22 /*===========================================================================*
23 * main *
24 *===========================================================================*/
25 int main(int argc, char *argv[])
27 /* This is the main routine of this service. The main loop consists of
28 * three major activities: getting new work, processing the work, and
29 * sending the reply. The loop never terminates, unless a panic occurs.
31 int ind, do_reply, transid;
32 message pfs_m_in;
33 message pfs_m_out;
35 /* SEF local startup. */
36 env_setargs(argc, argv);
37 sef_local_startup();
39 while(!unmountdone || !exitsignaled) {
40 endpoint_t src;
42 do_reply = 1;
43 /* Wait for request message. */
44 get_work(&pfs_m_in);
46 transid = TRNS_GET_ID(pfs_m_in.m_type);
47 pfs_m_in.m_type = TRNS_DEL_ID(pfs_m_in.m_type);
48 if (pfs_m_in.m_type == 0) {
49 assert(!IS_VFS_FS_TRANSID(transid));
50 pfs_m_in.m_type = transid;
51 transid = 0;
52 } else
53 assert(IS_VFS_FS_TRANSID(transid) || transid == 0);
55 src = pfs_m_in.m_source;
56 caller_uid = INVAL_UID; /* To trap errors */
57 caller_gid = INVAL_GID;
58 req_nr = pfs_m_in.m_type;
60 if (IS_DEV_RQ(req_nr)) {
61 ind = req_nr - DEV_RQ_BASE;
62 if (ind < 0 || ind >= DEV_CALL_VEC_SIZE) {
63 printf("pfs: bad DEV request %d\n", req_nr);
64 pfs_m_out.m_type = EINVAL;
65 } else {
66 int result;
67 result = (*dev_call_vec[ind])(&pfs_m_in, &pfs_m_out);
68 if (pfs_m_out.REP_STATUS == SUSPEND ||
69 result == SUSPEND) {
70 /* Nothing to tell, so not replying */
71 do_reply = 0;
74 } else if (IS_VFS_RQ(req_nr)) {
75 ind = req_nr - VFS_BASE;
76 if (ind < 0 || ind >= FS_CALL_VEC_SIZE) {
77 printf("pfs: bad FS request %d\n", req_nr);
78 pfs_m_out.m_type = EINVAL;
79 } else {
80 pfs_m_out.m_type =
81 (*fs_call_vec[ind])(&pfs_m_in, &pfs_m_out);
83 } else {
84 printf("pfs: bad request %d\n", req_nr);
85 pfs_m_out.m_type = EINVAL;
88 if (do_reply) {
89 if (IS_VFS_RQ(req_nr) && IS_VFS_FS_TRANSID(transid)) {
90 pfs_m_out.m_type = TRNS_ADD_ID(pfs_m_out.m_type,
91 transid);
93 reply(src, &pfs_m_out);
96 return(OK);
99 /*===========================================================================*
100 * sef_local_startup *
101 *===========================================================================*/
102 static void sef_local_startup()
104 /* Register init callbacks. */
105 sef_setcb_init_fresh(sef_cb_init_fresh);
106 sef_setcb_init_restart(sef_cb_init_fail);
108 /* No live update support for now. */
110 /* Register signal callbacks. */
111 sef_setcb_signal_handler(sef_cb_signal_handler);
113 /* Let SEF perform startup. */
114 sef_startup();
117 /*===========================================================================*
118 * sef_cb_init_fresh *
119 *===========================================================================*/
120 static int sef_cb_init_fresh(int type, sef_init_info_t *info)
122 /* Initialize the pipe file server. */
123 int i;
124 struct passwd *pw;
126 /* Initialize main loop parameters. */
127 exitsignaled = 0; /* No exit request seen yet. */
128 busy = 0; /* Server is not 'busy' (i.e., inodes in use). */
130 /* Init inode table */
131 for (i = 0; i < NR_INODES; ++i) {
132 inode[i].i_count = 0;
135 init_inode_cache();
136 uds_init();
137 buf_pool();
140 /* Drop root privileges */
141 if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) {
142 printf("PFS: unable to retrieve uid of SERVICE_LOGIN, "
143 "still running as root");
144 } else if (setuid(pw->pw_uid) != 0) {
145 panic("unable to drop privileges");
148 SELF_E = getprocnr();
150 return(OK);
153 /*===========================================================================*
154 * sef_cb_signal_handler *
155 *===========================================================================*/
156 static void sef_cb_signal_handler(int signo)
158 /* Only check for termination signal, ignore anything else. */
159 if (signo != SIGTERM) return;
162 exitsignaled = 1;
165 /*===========================================================================*
166 * get_work *
167 *===========================================================================*/
168 static void get_work(m_in)
169 message *m_in; /* pointer to message */
171 int r, srcok = 0, status;
172 endpoint_t src;
174 do {
175 /* wait for a message */
176 if ((r = sef_receive_status(ANY, m_in, &status)) != OK)
177 panic("sef_receive_status failed: %d", r);
178 src = m_in->m_source;
180 if(src == VFS_PROC_NR) {
181 srcok = 1; /* Normal FS request. */
182 } else
183 printf("PFS: unexpected source %d\n", src);
184 } while(!srcok);
188 /*===========================================================================*
189 * reply *
190 *===========================================================================*/
191 void reply(who, m_out)
192 endpoint_t who;
193 message *m_out; /* report result */
195 if (OK != send(who, m_out)) /* send the message */
196 printf("PFS(%d) was unable to send reply\n", SELF_E);