4 #include <minix/dmap.h>
5 #include <minix/driver.h>
6 #include <minix/endpoint.h>
8 #include <minix/vfsif.h>
14 static void get_work(message
*m_in
, int *status
);
16 /* SEF functions and variables. */
17 static void sef_local_startup(void);
18 static int sef_cb_init_fresh(int type
, sef_init_info_t
*info
);
19 static void sef_cb_signal_handler(int signo
);
21 /*===========================================================================*
23 *===========================================================================*/
24 int main(int argc
, char *argv
[])
26 /* This is the main routine of this service. The main loop consists of
27 * three major activities: getting new work, processing the work, and
28 * sending the reply. The loop never terminates, unless a panic occurs.
30 int ind
, transid
, req_nr
, ipc_status
;
35 /* SEF local startup. */
36 env_setargs(argc
, argv
);
39 while(!unmountdone
|| !exitsignaled
) {
40 /* Wait for request message. */
41 get_work(&pfs_m_in
, &ipc_status
);
43 transid
= TRNS_GET_ID(pfs_m_in
.m_type
);
44 pfs_m_in
.m_type
= TRNS_DEL_ID(pfs_m_in
.m_type
);
45 if (pfs_m_in
.m_type
== 0) {
46 assert(!IS_VFS_FS_TRANSID(transid
));
47 pfs_m_in
.m_type
= transid
;
50 assert(IS_VFS_FS_TRANSID(transid
) || transid
== 0);
52 src
= pfs_m_in
.m_source
;
53 req_nr
= pfs_m_in
.m_type
;
55 if (IS_FS_RQ(req_nr
)) {
56 ind
= req_nr
- FS_BASE
;
57 if (ind
< 0 || ind
>= FS_CALL_VEC_SIZE
) {
58 printf("pfs: bad FS request %d\n", req_nr
);
59 pfs_m_out
.m_type
= EINVAL
;
62 (*fs_call_vec
[ind
])(&pfs_m_in
, &pfs_m_out
);
65 printf("pfs: bad request %d\n", req_nr
);
66 pfs_m_out
.m_type
= EINVAL
;
69 if (IS_FS_RQ(req_nr
) && IS_VFS_FS_TRANSID(transid
)) {
70 pfs_m_out
.m_type
= TRNS_ADD_ID(pfs_m_out
.m_type
, transid
);
72 reply(src
, &pfs_m_out
);
77 /*===========================================================================*
79 *===========================================================================*/
80 static void sef_local_startup()
82 /* Register init callbacks. */
83 sef_setcb_init_fresh(sef_cb_init_fresh
);
84 sef_setcb_init_restart(sef_cb_init_fail
);
86 /* No live update support for now. */
88 /* Register signal callbacks. */
89 sef_setcb_signal_handler(sef_cb_signal_handler
);
91 /* Let SEF perform startup. */
95 /*===========================================================================*
97 *===========================================================================*/
98 static int sef_cb_init_fresh(int type
, sef_init_info_t
*info
)
100 /* Initialize the pipe file server. */
104 /* Initialize main loop parameters. */
105 exitsignaled
= 0; /* No exit request seen yet. */
106 busy
= 0; /* Server is not 'busy' (i.e., inodes in use). */
108 /* Init inode table */
109 for (i
= 0; i
< PFS_NR_INODES
; ++i
) {
110 inode
[i
].i_count
= 0;
116 /* Drop root privileges */
117 if ((pw
= getpwnam(SERVICE_LOGIN
)) == NULL
) {
118 printf("PFS: unable to retrieve uid of SERVICE_LOGIN, "
119 "still running as root");
120 } else if (setuid(pw
->pw_uid
) != 0) {
121 panic("unable to drop privileges");
127 /*===========================================================================*
128 * sef_cb_signal_handler *
129 *===========================================================================*/
130 static void sef_cb_signal_handler(int signo
)
132 /* Only check for termination signal, ignore anything else. */
133 if (signo
!= SIGTERM
) return;
139 /*===========================================================================*
141 *===========================================================================*/
142 static void get_work(message
* m_in
, int *status
)
148 /* wait for a message */
149 if ((r
= sef_receive_status(ANY
, m_in
, status
)) != OK
)
150 panic("sef_receive_status failed: %d", r
);
151 src
= m_in
->m_source
;
153 if(src
== VFS_PROC_NR
) {
154 srcok
= 1; /* Normal FS request. */
156 printf("PFS: unexpected source %d\n", src
);
161 /*===========================================================================*
163 *===========================================================================*/
164 void reply(who
, m_out
)
166 message
*m_out
; /* report result */
170 if (OK
!= (r
= ipc_send(who
, m_out
))) /* send the message */
171 printf("PFS: unable to send reply: %d\n", r
);