1 /* Filter driver - lowest layer - disk driver management */
6 static struct driverinfo driver
[2];
9 static endpoint_t self_ep
;
10 static asynmsg_t amsgtable
[2];
12 static int size_known
= 0;
13 static u64_t disk_size
;
15 static int problem_stats
[BD_LAST
] = { 0 };
17 /*===========================================================================*
19 *===========================================================================*/
20 static int driver_open(int which
)
22 /* Perform an open or close operation on the driver. This is
23 * unfinished code: we should never be doing a blocking sendrec() to
28 struct partition part
;
32 msg
.m_type
= DEV_OPEN
;
33 msg
.DEVICE
= driver
[which
].minor
;
34 msg
.IO_ENDPT
= self_ep
;
35 r
= sendrec(driver
[which
].endpt
, &msg
);
38 /* Should we restart the driver now? */
39 printf("Filter: driver_open: sendrec returned %d\n", r
);
44 if(msg
.m_type
!= TASK_REPLY
|| msg
.REP_STATUS
!= OK
) {
45 printf("Filter: driver_open: sendrec returned %d, %d\n",
46 msg
.m_type
, msg
.REP_STATUS
);
51 /* Take the opportunity to retrieve the hard disk size. */
52 gid
= cpf_grant_direct(driver
[which
].endpt
,
53 (vir_bytes
) &part
, sizeof(part
), CPF_WRITE
);
55 panic("invalid grant: %d", gid
);
57 msg
.m_type
= DEV_IOCTL_S
;
58 msg
.REQUEST
= DIOCGETP
;
59 msg
.DEVICE
= driver
[which
].minor
;
60 msg
.IO_ENDPT
= self_ep
;
61 msg
.IO_GRANT
= (char *) gid
;
63 r
= sendrec(driver
[which
].endpt
, &msg
);
67 if (r
!= OK
|| msg
.m_type
!= TASK_REPLY
|| msg
.REP_STATUS
!= OK
) {
68 /* Not sure what to do here, either. */
69 printf("Filter: ioctl(DIOCGETP) returned (%d, %d)\n",
76 disk_size
= part
.size
;
78 sectors
= div64u(disk_size
, SECTOR_SIZE
);
79 if(cmp64(mul64u(sectors
, SECTOR_SIZE
), disk_size
)) {
80 printf("Filter: partition too large\n");
85 printf("Filter: partition size: 0x%s / %lu sectors\n",
86 print64(disk_size
), sectors
);
89 if(cmp64(disk_size
, part
.size
)) {
90 printf("Filter: partition size mismatch (%s != %s)\n",
91 print64(part
.size
), print64(disk_size
));
100 /*===========================================================================*
102 *===========================================================================*/
103 static int driver_close(int which
)
108 msg
.m_type
= DEV_CLOSE
;
109 msg
.DEVICE
= driver
[which
].minor
;
110 msg
.IO_ENDPT
= self_ep
;
111 r
= sendrec(driver
[which
].endpt
, &msg
);
114 /* Should we restart the driver now? */
115 printf("Filter: driver_close: sendrec returned %d\n", r
);
120 if(msg
.m_type
!= TASK_REPLY
|| msg
.REP_STATUS
!= OK
) {
121 printf("Filter: driver_close: sendrec returned %d, %d\n",
122 msg
.m_type
, msg
.REP_STATUS
);
130 /*===========================================================================*
132 *===========================================================================*/
133 void driver_init(void)
135 /* Initialize the driver layer. */
138 self_ep
= getprocnr();
140 memset(driver
, 0, sizeof(driver
));
142 /* Endpoints unknown. */
143 driver
[DRIVER_MAIN
].endpt
= NONE
;
144 driver
[DRIVER_BACKUP
].endpt
= NONE
;
146 /* Get disk driver's and this proc's endpoint. */
147 driver
[DRIVER_MAIN
].label
= MAIN_LABEL
;
148 driver
[DRIVER_MAIN
].minor
= MAIN_MINOR
;
150 /* No up received yet but expected when the driver starts. */
151 driver
[DRIVER_MAIN
].up_event
= UP_EXPECTED
;
152 driver
[DRIVER_BACKUP
].up_event
= UP_EXPECTED
;
154 r
= ds_retrieve_label_endpt(driver
[DRIVER_MAIN
].label
,
155 &driver
[DRIVER_MAIN
].endpt
);
157 printf("Filter: failed to get main disk driver's endpoint: "
159 bad_driver(DRIVER_MAIN
, BD_DEAD
, EFAULT
);
160 check_driver(DRIVER_MAIN
);
162 else if (driver_open(DRIVER_MAIN
) != OK
) {
163 panic("unhandled driver_open failure");
167 driver
[DRIVER_BACKUP
].label
= BACKUP_LABEL
;
168 driver
[DRIVER_BACKUP
].minor
= BACKUP_MINOR
;
170 if(!strcmp(driver
[DRIVER_MAIN
].label
,
171 driver
[DRIVER_BACKUP
].label
)) {
172 panic("same driver: not tested");
175 r
= ds_retrieve_label_endpt(driver
[DRIVER_BACKUP
].label
,
176 &driver
[DRIVER_BACKUP
].endpt
);
178 printf("Filter: failed to get backup disk driver's "
179 "endpoint: %d\n", r
);
180 bad_driver(DRIVER_BACKUP
, BD_DEAD
, EFAULT
);
181 check_driver(DRIVER_BACKUP
);
183 else if (driver_open(DRIVER_BACKUP
) != OK
) {
184 panic("unhandled driver_open failure");
189 /*===========================================================================*
191 *===========================================================================*/
192 void driver_shutdown(void)
197 printf("Filter: %u driver deaths, %u protocol errors, "
198 "%u data errors\n", problem_stats
[BD_DEAD
],
199 problem_stats
[BD_PROTO
], problem_stats
[BD_DATA
]);
202 if(driver_close(DRIVER_MAIN
) != OK
)
203 printf("Filter: DEV_CLOSE failed on shutdown (1)\n");
206 if(driver_close(DRIVER_BACKUP
) != OK
)
207 printf("Filter: DEV_CLOSE failed on shutdown (2)\n");
210 /*===========================================================================*
212 *===========================================================================*/
213 u64_t
get_raw_size(void)
215 /* Return the size of the raw disks as used by the filter driver.
221 /*===========================================================================*
223 *===========================================================================*/
224 void reset_kills(void)
226 /* Reset kill and retry statistics. */
227 driver
[DRIVER_MAIN
].kills
= 0;
228 driver
[DRIVER_MAIN
].retries
= 0;
229 driver
[DRIVER_BACKUP
].kills
= 0;
230 driver
[DRIVER_BACKUP
].retries
= 0;
233 /*===========================================================================*
235 *===========================================================================*/
236 int bad_driver(int which
, int type
, int error
)
238 /* A disk driver has died or produced an error. Mark it so that we can
239 * deal with it later, and return RET_REDO to indicate that the
240 * current operation is to be retried. Also store an error code to
241 * return to the user if the situation is unrecoverable.
243 driver
[which
].problem
= type
;
244 driver
[which
].error
= error
;
249 /*===========================================================================*
251 *===========================================================================*/
252 static int new_driver_ep(int which
)
254 /* See if a new driver instance has already been started for the given
255 * driver, by retrieving its entry from DS.
260 r
= ds_retrieve_label_endpt(driver
[which
].label
, &endpt
);
263 printf("Filter: DS query for %s failed\n",
264 driver
[which
].label
);
269 if (endpt
== driver
[which
].endpt
) {
271 printf("Filter: same endpoint for %s\n", driver
[which
].label
);
277 printf("Filter: new enpdoint for %s: %d -> %d\n", driver
[which
].label
,
278 driver
[which
].endpt
, endpt
);
281 driver
[which
].endpt
= endpt
;
286 /*===========================================================================*
288 *===========================================================================*/
289 static int check_problem(int which
, int problem
, int retries
, int *tell_rs
)
291 /* A problem has occurred with a driver. Update statistics, and decide
292 * what to do. If EAGAIN is returned, the driver should be restarted;
293 * any other result will be passed up.
297 printf("Filter: check_problem processing driver %d, problem %d\n",
301 problem_stats
[problem
]++;
303 if(new_driver_ep(which
)) {
305 printf("Filter: check_problem: noticed a new driver\n");
308 if(driver_open(which
) == OK
) {
310 printf("Filter: open OK -> no recovery\n");
315 printf("Filter: open not OK -> recovery\n");
318 problem_stats
[problem
]++;
322 /* If the driver has died, we always need to restart it. If it has
323 * been giving problems, we first retry the request, up to N times,
324 * after which we kill and restart the driver. We restart the driver
325 * up to M times, after which we remove the driver from the mirror
326 * configuration. If we are not set up to do mirroring, we can only
327 * do one thing, and that is continue to limp along with the bad
333 driver
[which
].retries
++;
336 printf("Filter: disk driver %d has had "
337 "%d/%d retry attempts, %d/%d kills\n", which
,
338 driver
[which
].retries
, NR_RETRIES
,
339 driver
[which
].kills
, NR_RESTARTS
);
342 if (driver
[which
].retries
< NR_RETRIES
) {
345 printf("Filter: not restarting; retrying "
346 "(retries %d/%d, kills %d/%d)\n",
347 driver
[which
].retries
, NR_RETRIES
,
348 driver
[which
].kills
, NR_RESTARTS
);
353 printf("Filter: restarting (retries %d/%d, "
354 "kills %d/%d, internal retry %d)\n",
355 driver
[which
].retries
, NR_RETRIES
,
356 driver
[which
].kills
, NR_RESTARTS
, retries
);
361 printf("Filter: disk driver %d has reached error "
362 "threshold, restarting driver\n", which
);
365 *tell_rs
= (driver
[which
].up_event
!= UP_PENDING
);
369 /* Can't kill that which is already dead.. */
374 panic("invalid problem: %d", problem
);
377 /* At this point, the driver will be restarted. */
378 driver
[which
].retries
= 0;
379 driver
[which
].kills
++;
381 if (driver
[which
].kills
< NR_RESTARTS
)
384 /* We've reached the maximum number of restarts for this driver. */
386 printf("Filter: kill threshold reached, disabling mirroring\n");
390 if (which
== DRIVER_MAIN
) {
391 driver
[DRIVER_MAIN
] = driver
[DRIVER_BACKUP
];
393 /* This is not necessary. */
394 strcpy(MAIN_LABEL
, BACKUP_LABEL
);
395 MAIN_MINOR
= BACKUP_MINOR
;
398 driver
[DRIVER_BACKUP
].endpt
= NONE
;
403 /* We tried, we really did. But now we give up. Tell the user.
405 printf("Filter: kill threshold reached, returning error\n");
407 if (driver
[which
].error
== EAGAIN
) return EIO
;
409 return driver
[which
].error
;
413 /*===========================================================================*
415 *===========================================================================*/
416 static void restart_driver(int which
, int tell_rs
)
418 /* Restart the given driver. Block until the new instance is up.
425 /* Tell RS to refresh or restart the driver */
426 msg
.m_type
= RS_REFRESH
;
427 msg
.RS_CMD_ADDR
= driver
[which
].label
;
428 msg
.RS_CMD_LEN
= strlen(driver
[which
].label
);
431 printf("Filter: asking RS to refresh %s..\n",
432 driver
[which
].label
);
435 r
= sendrec(RS_PROC_NR
, &msg
);
437 if (r
!= OK
|| msg
.m_type
!= OK
)
438 panic("RS request failed: %d", r
);
441 printf("Filter: RS call succeeded\n");
445 /* Wait until the new driver instance is up, and get its endpoint. */
447 printf("Filter: endpoint update driver %d; old endpoint %d\n",
448 which
, driver
[which
].endpt
);
451 if(driver
[which
].up_event
== UP_EXPECTED
) {
452 driver
[which
].up_event
= UP_NONE
;
454 while(driver
[which
].up_event
!= UP_PENDING
) {
455 r
= driver_receive(DS_PROC_NR
, &msg
, &ipc_status
);
457 panic("driver_receive returned error: %d", r
);
463 /*===========================================================================*
465 *===========================================================================*/
466 int check_driver(int which
)
468 /* See if the given driver has been troublesome, and if so, deal with
471 int problem
, tell_rs
;
474 problem
= driver
[which
].problem
;
476 if (problem
== BD_NONE
)
482 printf("Filter: check_driver: retry number %d\n",
488 driver
[which
].problem
= BD_NONE
;
490 /* Decide what to do: continue operation, restart the driver,
491 * or return an error.
493 r
= check_problem(which
, problem
, retries
, &tell_rs
);
497 /* Restarting the driver it is. First tell RS (if necessary),
498 * then wait for the new driver instance to come up.
500 restart_driver(which
, tell_rs
);
502 /* Finally, open the device on the new driver */
503 } while (driver_open(which
) != OK
);
506 printf("Filter: check_driver restarted driver %d, endpoint %d\n",
507 which
, driver
[which
].endpt
);
513 /*===========================================================================*
515 *===========================================================================*/
516 static int flt_senda(message
*mess
, int which
)
518 /* Send a message to one driver. Can only return OK at the moment. */
522 /* Fill in the last bits of the message. */
523 mess
->DEVICE
= driver
[which
].minor
;
524 mess
->IO_ENDPT
= self_ep
;
526 /* Send the message asynchronously. */
527 amp
= &amsgtable
[which
];
528 amp
->dst
= driver
[which
].endpt
;
530 amp
->flags
= AMF_VALID
;
531 r
= senda(amsgtable
, 2);
534 panic("senda returned error: %d", r
);
539 /*===========================================================================*
541 *===========================================================================*/
542 static int check_senda(int which
)
544 /* Check whether an earlier senda resulted in an error indicating the
545 * message never got delivered. Only in that case can we reliably say
546 * that the driver died. Return BD_DEAD in this case, and BD_PROTO
551 amp
= &amsgtable
[which
];
553 if ((amp
->flags
& AMF_DONE
) && (amp
->result
== EDEADSRCDST
)) {
561 /*===========================================================================*
563 *===========================================================================*/
564 static int flt_receive(message
*mess
, int which
)
566 /* Receive a message from one or either driver, unless a timeout
567 * occurs. Can only return OK or RET_REDO.
573 r
= driver_receive(ANY
, mess
, &ipc_status
);
575 panic("driver_receive returned error: %d", r
);
577 if(mess
->m_source
== DS_PROC_NR
&& is_ipc_notify(ipc_status
)) {
582 if(mess
->m_source
== CLOCK
&& is_ipc_notify(ipc_status
)) {
583 if (mess
->NOTIFY_TIMESTAMP
< flt_alarm(-1)) {
585 printf("Filter: SKIPPING old alarm "
592 printf("Filter: timeout waiting for disk driver %d "
596 /* If we're waiting for either driver,
600 bad_driver(DRIVER_MAIN
,
601 check_senda(DRIVER_MAIN
), EFAULT
);
603 return bad_driver(DRIVER_BACKUP
,
604 check_senda(DRIVER_BACKUP
), EFAULT
);
607 /* Otherwise, just report the one not replying as dead.
609 return bad_driver(which
, check_senda(which
), EFAULT
);
612 if (mess
->m_source
!= driver
[DRIVER_MAIN
].endpt
&&
613 mess
->m_source
!= driver
[DRIVER_BACKUP
].endpt
) {
615 printf("Filter: got STRAY message %d from %d\n",
616 mess
->m_type
, mess
->m_source
);
622 /* We are waiting for a reply from one specific driver. */
624 /* If the message source is that driver, good. */
625 if (mess
->m_source
== driver
[which
].endpt
)
628 /* This should probably be treated as a real protocol
629 * error. We do not abort any receives (not even paired
630 * receives) except because of timeouts. Getting here
631 * means a driver replied at least the timeout period
632 * later than expected, which should be enough reason
633 * to kill it really. The other explanation is that it
634 * is actually violating the protocol and sending bogus
638 printf("Filter: got UNEXPECTED reply from %d\n",
645 /* We got a message from one of the drivers, and we didn't
646 * care which one we wanted to receive from. A-OK.
654 /*===========================================================================*
656 *===========================================================================*/
657 static int flt_sendrec(message
*mess
, int which
)
661 r
= flt_senda(mess
, which
);
665 if(check_senda(which
) == BD_DEAD
) {
666 return bad_driver(which
, BD_DEAD
, EFAULT
);
670 flt_alarm(DRIVER_TIMEOUT
);
672 r
= flt_receive(mess
, which
);
674 /* Clear the alarm. */
679 /*===========================================================================*
681 *===========================================================================*/
682 static int do_sendrec_both(message
*m1
, message
*m2
)
684 /* If USEE_MIRROR is set, call flt_sendrec() to both drivers.
685 * Otherwise, only call flt_sendrec() to the main driver.
686 * This function will only return either OK or RET_REDO.
691 /* If the two disks use the same driver, call flt_sendrec() twice
692 * sequentially. Such a setup is not very useful though.
694 if (!strcmp(driver
[DRIVER_MAIN
].label
, driver
[DRIVER_BACKUP
].label
)) {
695 if ((r
= flt_sendrec(m1
, DRIVER_MAIN
)) != OK
) return r
;
696 return flt_sendrec(m2
, DRIVER_BACKUP
);
699 /* If the two disks use different drivers, call flt_senda()
700 * twice, and then flt_receive(), and distinguish the return
701 * messages by means of m_source.
703 if ((r
= flt_senda(m1
, DRIVER_MAIN
)) != OK
) return r
;
704 if ((r
= flt_senda(m2
, DRIVER_BACKUP
)) != OK
) return r
;
707 flt_alarm(DRIVER_TIMEOUT
);
709 /* The message received by the 1st flt_receive() may not be
712 if ((r
= flt_receive(&ma
, -1)) != OK
) {
717 if (ma
.m_source
== driver
[DRIVER_MAIN
].endpt
) {
718 which
= DRIVER_BACKUP
;
719 } else if (ma
.m_source
== driver
[DRIVER_BACKUP
].endpt
) {
722 panic("message from unexpected source: %d",
726 r
= flt_receive(&mb
, which
);
728 /* Clear the alarm. */
734 if (ma
.m_source
== driver
[DRIVER_MAIN
].endpt
) {
745 /*===========================================================================*
747 *===========================================================================*/
748 static int do_sendrec_one(message
*m1
, const message
*m2
)
750 /* Only talk to the main driver. If something goes wrong, it will
751 * be fixed elsewhere.
752 * This function will only return either OK or RET_REDO.
755 return flt_sendrec(m1
, DRIVER_MAIN
);
758 /*===========================================================================*
760 *===========================================================================*/
761 static int paired_sendrec(message
*m1
, message
*m2
, int both
)
763 /* Sendrec with the disk driver. If the disk driver is down, and was
764 * restarted, redo the request, until the driver works fine, or can't
765 * be restarted again.
770 printf("paired_sendrec(%d) - <%d,%x:%x,%d> - %x,%x\n",
771 both
, m1
->m_type
, m1
->HIGHPOS
, m1
->POSITION
, m1
->COUNT
,
772 m1
->IO_GRANT
, m2
->IO_GRANT
);
776 r
= do_sendrec_both(m1
, m2
);
778 r
= do_sendrec_one(m1
, m2
);
782 printf("paired_sendrec about to return %d\n", r
);
788 /*===========================================================================*
790 *===========================================================================*/
791 static int single_grant(endpoint_t endpt
, vir_bytes buf
, int access
,
792 cp_grant_id_t
*gid
, iovec_s_t vector
[NR_IOREQS
], const size_t *sizep
)
794 /* Create grants for a vectored request to a single driver.
802 /* Split up the request into chunks, if requested. This makes no
803 * difference at all, except that this works around a weird performance
804 * bug with large DMA PRDs on some machines.
806 if (CHUNK_SIZE
> 0) chunk
= CHUNK_SIZE
;
809 /* Fill in the vector, creating a grant for each item. */
810 for (count
= 0; size
> 0 && count
< NR_IOREQS
; count
++) {
811 /* The last chunk will contain all the remaining data. */
812 if (chunk
> size
|| count
== NR_IOREQS
- 1)
815 grant
= cpf_grant_direct(endpt
, buf
, chunk
, access
);
816 if (!GRANT_VALID(grant
))
817 panic("invalid grant: %d", grant
);
819 vector
[count
].iov_grant
= grant
;
820 vector
[count
].iov_size
= chunk
;
826 /* Then create a grant for the vector itself. */
827 *gid
= cpf_grant_direct(endpt
, (vir_bytes
) vector
,
828 sizeof(vector
[0]) * count
, CPF_READ
| CPF_WRITE
);
830 if (!GRANT_VALID(*gid
))
831 panic("invalid grant: %d", *gid
);
836 /*===========================================================================*
838 *===========================================================================*/
839 static int paired_grant(char *buf1
, char *buf2
, int request
,
840 cp_grant_id_t
*gids
, iovec_s_t vectors
[2][NR_IOREQS
], size_t *sizes
,
843 /* Create memory grants, either to one or to both drivers.
848 access
= (request
== FLT_WRITE
) ? CPF_READ
: CPF_WRITE
;
850 if(driver
[DRIVER_MAIN
].endpt
> 0) {
851 count
= single_grant(driver
[DRIVER_MAIN
].endpt
,
852 (vir_bytes
) buf1
, access
, &gids
[0], vectors
[0],
857 if(driver
[DRIVER_BACKUP
].endpt
> 0) {
858 count
= single_grant(driver
[DRIVER_BACKUP
].endpt
,
859 (vir_bytes
) buf2
, access
, &gids
[1],
860 vectors
[1], &sizes
[1]);
866 /*===========================================================================*
868 *===========================================================================*/
869 PRIVATE
void single_revoke(cp_grant_id_t gid
, const iovec_s_t vector
[NR_IOREQS
],
870 size_t *sizep
, int count
)
872 /* Revoke all grants associated with a request to a single driver.
873 * Modify the given size to reflect the actual I/O performed.
877 /* Revoke the grants for all the elements of the vector. */
878 for (i
= 0; i
< count
; i
++) {
879 cpf_revoke(vector
[i
].iov_grant
);
880 *sizep
-= vector
[i
].iov_size
;
883 /* Then revoke the grant for the vector itself. */
887 /*===========================================================================*
889 *===========================================================================*/
890 static void paired_revoke(const cp_grant_id_t
*gids
,
891 iovec_s_t vectors
[2][NR_IOREQS
],
892 size_t *sizes
, int count
, int both
)
894 /* Revoke grants to drivers for a single request.
897 single_revoke(gids
[0], vectors
[0], &sizes
[0], count
);
900 single_revoke(gids
[1], vectors
[1], &sizes
[1], count
);
903 /*===========================================================================*
905 *===========================================================================*/
906 int read_write(u64_t pos
, char *bufa
, char *bufb
, size_t *sizep
, int request
)
908 iovec_s_t vectors
[2][NR_IOREQS
];
910 cp_grant_id_t gids
[2];
914 gids
[0] = gids
[1] = GRANT_INVALID
;
915 sizes
[0] = sizes
[1] = *sizep
;
917 /* Send two requests only if mirroring is enabled and the given request
918 * is either FLT_READ2 or FLT_WRITE.
920 both
= (USE_MIRROR
&& request
!= FLT_READ
);
922 count
= paired_grant(bufa
, bufb
, request
, gids
, vectors
, sizes
, both
);
924 m1
.m_type
= (request
== FLT_WRITE
) ? DEV_SCATTER_S
: DEV_GATHER_S
;
926 m1
.POSITION
= ex64lo(pos
);
927 m1
.HIGHPOS
= ex64hi(pos
);
931 m1
.IO_GRANT
= (char *) gids
[0];
932 m2
.IO_GRANT
= (char *) gids
[1];
934 r
= paired_sendrec(&m1
, &m2
, both
);
936 paired_revoke(gids
, vectors
, sizes
, count
, both
);
941 printf("Filter: paired_sendrec returned %d\n", r
);
946 if (m1
.m_type
!= TASK_REPLY
|| m1
.REP_STATUS
!= OK
) {
947 printf("Filter: unexpected/invalid reply from main driver: "
948 "(%x, %d)\n", m1
.m_type
, m1
.REP_STATUS
);
950 return bad_driver(DRIVER_MAIN
, BD_PROTO
,
951 (m1
.m_type
== TASK_REPLY
) ? m1
.REP_STATUS
: EFAULT
);
954 if (sizes
[0] != *sizep
) {
955 printf("Filter: truncated reply from main driver\n");
957 /* If the driver returned a value *larger* than we requested,
958 * OR if we did NOT exceed the disk size, then we should
959 * report the driver for acting strangely!
961 if (sizes
[0] < 0 || sizes
[0] > *sizep
||
962 cmp64(add64u(pos
, sizes
[0]), disk_size
) < 0)
963 return bad_driver(DRIVER_MAIN
, BD_PROTO
, EFAULT
);
965 /* Return the actual size. */
970 if (m2
.m_type
!= TASK_REPLY
|| m2
.REP_STATUS
!= OK
) {
971 printf("Filter: unexpected/invalid reply from "
972 "backup driver (%x, %d)\n",
973 m2
.m_type
, m2
.REP_STATUS
);
975 return bad_driver(DRIVER_BACKUP
, BD_PROTO
,
976 m2
.m_type
== TASK_REPLY
? m2
.REP_STATUS
:
979 if (sizes
[1] != *sizep
) {
980 printf("Filter: truncated reply from backup driver\n");
983 if (sizes
[1] < 0 || sizes
[1] > *sizep
||
984 cmp64(add64u(pos
, sizes
[1]), disk_size
) < 0)
985 return bad_driver(DRIVER_BACKUP
, BD_PROTO
,
988 /* Return the actual size. */
989 if (*sizep
>= sizes
[1])
997 /*===========================================================================*
999 *===========================================================================*/
1002 char key
[DS_MAX_KEYLEN
];
1003 char *driver_prefix
= "drv.vfs.";
1006 endpoint_t owner_endpoint
;
1010 /* Get the event and the owner from DS. */
1011 r
= ds_check(key
, &type
, &owner_endpoint
);
1014 printf("Filter: ds_event: ds_check failed: %d\n", r
);
1017 r
= ds_retrieve_u32(key
, &value
);
1019 printf("Filter: ds_event: ds_retrieve_u32 failed\n");
1023 /* Only check for VFS driver up events. */
1024 if(strncmp(key
, driver_prefix
, sizeof(driver_prefix
))
1025 || value
!= DS_DRIVER_UP
) {
1029 /* See if this is a driver we are responsible for. */
1030 if(driver
[DRIVER_MAIN
].endpt
== owner_endpoint
) {
1031 which
= DRIVER_MAIN
;
1033 else if(driver
[DRIVER_BACKUP
].endpt
== owner_endpoint
) {
1034 which
= DRIVER_BACKUP
;
1040 /* Mark the driver as (re)started. */
1041 driver
[which
].up_event
= driver
[which
].up_event
== UP_EXPECTED
?
1042 UP_NONE
: UP_PENDING
;