1 /* Filter driver - lowest layer - disk driver management */
6 static struct driverinfo driver
[2];
9 static asynmsg_t amsgtable
[2];
11 static int size_known
= 0;
12 static u64_t disk_size
;
14 static int problem_stats
[BD_LAST
] = { 0 };
16 /*===========================================================================*
18 *===========================================================================*/
19 static int driver_open(int which
)
21 /* Perform an open or close operation on the driver. This is
22 * unfinished code: we should never be doing a blocking sendrec() to
27 struct partition part
;
31 memset(&msg
, 0, sizeof(msg
));
32 msg
.m_type
= BDEV_OPEN
;
33 msg
.BDEV_MINOR
= driver
[which
].minor
;
34 msg
.BDEV_ACCESS
= R_BIT
| W_BIT
;
36 r
= sendrec(driver
[which
].endpt
, &msg
);
39 /* Should we restart the driver now? */
40 printf("Filter: driver_open: sendrec returned %d\n", r
);
45 if(msg
.m_type
!= BDEV_REPLY
|| msg
.BDEV_STATUS
!= OK
) {
46 printf("Filter: driver_open: sendrec returned %d, %d\n",
47 msg
.m_type
, msg
.BDEV_STATUS
);
52 /* Take the opportunity to retrieve the hard disk size. */
53 gid
= cpf_grant_direct(driver
[which
].endpt
,
54 (vir_bytes
) &part
, sizeof(part
), CPF_WRITE
);
56 panic("invalid grant: %d", gid
);
58 memset(&msg
, 0, sizeof(msg
));
59 msg
.m_type
= BDEV_IOCTL
;
60 msg
.BDEV_MINOR
= driver
[which
].minor
;
61 msg
.BDEV_REQUEST
= DIOCGETP
;
65 r
= sendrec(driver
[which
].endpt
, &msg
);
69 if (r
!= OK
|| msg
.m_type
!= BDEV_REPLY
|| msg
.BDEV_STATUS
!= OK
) {
70 /* Not sure what to do here, either. */
71 printf("Filter: ioctl(DIOCGETP) returned (%d, %d)\n",
78 disk_size
= part
.size
;
80 sectors
= div64u(disk_size
, SECTOR_SIZE
);
81 if(cmp64(mul64u(sectors
, SECTOR_SIZE
), disk_size
)) {
82 printf("Filter: partition too large\n");
87 printf("Filter: partition size: 0x%"PRIx64
" / %lu sectors\n",
91 if(cmp64(disk_size
, part
.size
)) {
92 printf("Filter: partition size mismatch "
93 "(0x%"PRIx64
" != 0x%"PRIx64
")\n",
94 part
.size
, disk_size
);
103 /*===========================================================================*
105 *===========================================================================*/
106 static int driver_close(int which
)
111 memset(&msg
, 0, sizeof(msg
));
112 msg
.m_type
= BDEV_CLOSE
;
113 msg
.BDEV_MINOR
= driver
[which
].minor
;
115 r
= sendrec(driver
[which
].endpt
, &msg
);
118 /* Should we restart the driver now? */
119 printf("Filter: driver_close: sendrec returned %d\n", r
);
124 if(msg
.m_type
!= BDEV_REPLY
|| msg
.BDEV_STATUS
!= OK
) {
125 printf("Filter: driver_close: sendrec returned %d, %d\n",
126 msg
.m_type
, msg
.BDEV_STATUS
);
134 /*===========================================================================*
136 *===========================================================================*/
137 void driver_init(void)
139 /* Initialize the driver layer. */
142 memset(driver
, 0, sizeof(driver
));
144 /* Endpoints unknown. */
145 driver
[DRIVER_MAIN
].endpt
= NONE
;
146 driver
[DRIVER_BACKUP
].endpt
= NONE
;
148 /* Get disk driver's and this proc's endpoint. */
149 driver
[DRIVER_MAIN
].label
= MAIN_LABEL
;
150 driver
[DRIVER_MAIN
].minor
= MAIN_MINOR
;
152 /* No up received yet but expected when the driver starts. */
153 driver
[DRIVER_MAIN
].up_event
= UP_EXPECTED
;
154 driver
[DRIVER_BACKUP
].up_event
= UP_EXPECTED
;
156 r
= ds_retrieve_label_endpt(driver
[DRIVER_MAIN
].label
,
157 &driver
[DRIVER_MAIN
].endpt
);
159 printf("Filter: failed to get main disk driver's endpoint: "
161 bad_driver(DRIVER_MAIN
, BD_DEAD
, EFAULT
);
162 check_driver(DRIVER_MAIN
);
164 else if (driver_open(DRIVER_MAIN
) != OK
) {
165 panic("unhandled driver_open failure");
169 driver
[DRIVER_BACKUP
].label
= BACKUP_LABEL
;
170 driver
[DRIVER_BACKUP
].minor
= BACKUP_MINOR
;
172 if(!strcmp(driver
[DRIVER_MAIN
].label
,
173 driver
[DRIVER_BACKUP
].label
)) {
174 panic("same driver: not tested");
177 r
= ds_retrieve_label_endpt(driver
[DRIVER_BACKUP
].label
,
178 &driver
[DRIVER_BACKUP
].endpt
);
180 printf("Filter: failed to get backup disk driver's "
181 "endpoint: %d\n", r
);
182 bad_driver(DRIVER_BACKUP
, BD_DEAD
, EFAULT
);
183 check_driver(DRIVER_BACKUP
);
185 else if (driver_open(DRIVER_BACKUP
) != OK
) {
186 panic("unhandled driver_open failure");
191 /*===========================================================================*
193 *===========================================================================*/
194 void driver_shutdown(void)
199 printf("Filter: %u driver deaths, %u protocol errors, "
200 "%u data errors\n", problem_stats
[BD_DEAD
],
201 problem_stats
[BD_PROTO
], problem_stats
[BD_DATA
]);
204 if(driver_close(DRIVER_MAIN
) != OK
)
205 printf("Filter: BDEV_CLOSE failed on shutdown (1)\n");
208 if(driver_close(DRIVER_BACKUP
) != OK
)
209 printf("Filter: BDEV_CLOSE failed on shutdown (2)\n");
212 /*===========================================================================*
214 *===========================================================================*/
215 u64_t
get_raw_size(void)
217 /* Return the size of the raw disks as used by the filter driver.
223 /*===========================================================================*
225 *===========================================================================*/
226 void reset_kills(void)
228 /* Reset kill and retry statistics. */
229 driver
[DRIVER_MAIN
].kills
= 0;
230 driver
[DRIVER_MAIN
].retries
= 0;
231 driver
[DRIVER_BACKUP
].kills
= 0;
232 driver
[DRIVER_BACKUP
].retries
= 0;
235 /*===========================================================================*
237 *===========================================================================*/
238 int bad_driver(int which
, int type
, int error
)
240 /* A disk driver has died or produced an error. Mark it so that we can
241 * deal with it later, and return RET_REDO to indicate that the
242 * current operation is to be retried. Also store an error code to
243 * return to the user if the situation is unrecoverable.
245 driver
[which
].problem
= type
;
246 driver
[which
].error
= error
;
251 /*===========================================================================*
253 *===========================================================================*/
254 static int new_driver_ep(int which
)
256 /* See if a new driver instance has already been started for the given
257 * driver, by retrieving its entry from DS.
262 r
= ds_retrieve_label_endpt(driver
[which
].label
, &endpt
);
265 printf("Filter: DS query for %s failed\n",
266 driver
[which
].label
);
271 if (endpt
== driver
[which
].endpt
) {
273 printf("Filter: same endpoint for %s\n", driver
[which
].label
);
279 printf("Filter: new enpdoint for %s: %d -> %d\n", driver
[which
].label
,
280 driver
[which
].endpt
, endpt
);
283 driver
[which
].endpt
= endpt
;
288 /*===========================================================================*
290 *===========================================================================*/
291 static int check_problem(int which
, int problem
, int retries
, int *tell_rs
)
293 /* A problem has occurred with a driver. Update statistics, and decide
294 * what to do. If EAGAIN is returned, the driver should be restarted;
295 * any other result will be passed up.
299 printf("Filter: check_problem processing driver %d, problem %d\n",
303 problem_stats
[problem
]++;
305 if(new_driver_ep(which
)) {
307 printf("Filter: check_problem: noticed a new driver\n");
310 if(driver_open(which
) == OK
) {
312 printf("Filter: open OK -> no recovery\n");
317 printf("Filter: open not OK -> recovery\n");
320 problem_stats
[problem
]++;
324 /* If the driver has died, we always need to restart it. If it has
325 * been giving problems, we first retry the request, up to N times,
326 * after which we kill and restart the driver. We restart the driver
327 * up to M times, after which we remove the driver from the mirror
328 * configuration. If we are not set up to do mirroring, we can only
329 * do one thing, and that is continue to limp along with the bad
335 driver
[which
].retries
++;
338 printf("Filter: disk driver %d has had "
339 "%d/%d retry attempts, %d/%d kills\n", which
,
340 driver
[which
].retries
, NR_RETRIES
,
341 driver
[which
].kills
, NR_RESTARTS
);
344 if (driver
[which
].retries
< NR_RETRIES
) {
347 printf("Filter: not restarting; retrying "
348 "(retries %d/%d, kills %d/%d)\n",
349 driver
[which
].retries
, NR_RETRIES
,
350 driver
[which
].kills
, NR_RESTARTS
);
355 printf("Filter: restarting (retries %d/%d, "
356 "kills %d/%d, internal retry %d)\n",
357 driver
[which
].retries
, NR_RETRIES
,
358 driver
[which
].kills
, NR_RESTARTS
, retries
);
363 printf("Filter: disk driver %d has reached error "
364 "threshold, restarting driver\n", which
);
367 *tell_rs
= (driver
[which
].up_event
!= UP_PENDING
);
371 /* Can't kill that which is already dead.. */
376 panic("invalid problem: %d", problem
);
379 /* At this point, the driver will be restarted. */
380 driver
[which
].retries
= 0;
381 driver
[which
].kills
++;
383 if (driver
[which
].kills
< NR_RESTARTS
)
386 /* We've reached the maximum number of restarts for this driver. */
388 printf("Filter: kill threshold reached, disabling mirroring\n");
392 if (which
== DRIVER_MAIN
) {
393 driver
[DRIVER_MAIN
] = driver
[DRIVER_BACKUP
];
395 /* This is not necessary. */
396 strlcpy(MAIN_LABEL
, BACKUP_LABEL
, sizeof(MAIN_LABEL
));
397 MAIN_MINOR
= BACKUP_MINOR
;
400 driver
[DRIVER_BACKUP
].endpt
= NONE
;
405 /* We tried, we really did. But now we give up. Tell the user.
407 printf("Filter: kill threshold reached, returning error\n");
409 if (driver
[which
].error
== EAGAIN
) return EIO
;
411 return driver
[which
].error
;
415 /*===========================================================================*
417 *===========================================================================*/
418 static void restart_driver(int which
, int tell_rs
)
420 /* Restart the given driver. Block until the new instance is up.
427 /* Tell RS to refresh or restart the driver */
428 msg
.m_type
= RS_REFRESH
;
429 msg
.RS_CMD_ADDR
= driver
[which
].label
;
430 msg
.RS_CMD_LEN
= strlen(driver
[which
].label
);
433 printf("Filter: asking RS to refresh %s..\n",
434 driver
[which
].label
);
437 r
= sendrec(RS_PROC_NR
, &msg
);
439 if (r
!= OK
|| msg
.m_type
!= OK
)
440 panic("RS request failed: %d", r
);
443 printf("Filter: RS call succeeded\n");
447 /* Wait until the new driver instance is up, and get its endpoint. */
449 printf("Filter: endpoint update driver %d; old endpoint %d\n",
450 which
, driver
[which
].endpt
);
453 if(driver
[which
].up_event
== UP_EXPECTED
) {
454 driver
[which
].up_event
= UP_NONE
;
456 while(driver
[which
].up_event
!= UP_PENDING
) {
457 r
= driver_receive(DS_PROC_NR
, &msg
, &ipc_status
);
459 panic("driver_receive returned error: %d", r
);
465 /*===========================================================================*
467 *===========================================================================*/
468 int check_driver(int which
)
470 /* See if the given driver has been troublesome, and if so, deal with
473 int problem
, tell_rs
;
476 problem
= driver
[which
].problem
;
478 if (problem
== BD_NONE
)
484 printf("Filter: check_driver: retry number %d\n",
490 driver
[which
].problem
= BD_NONE
;
492 /* Decide what to do: continue operation, restart the driver,
493 * or return an error.
495 r
= check_problem(which
, problem
, retries
, &tell_rs
);
499 /* Restarting the driver it is. First tell RS (if necessary),
500 * then wait for the new driver instance to come up.
502 restart_driver(which
, tell_rs
);
504 /* Finally, open the device on the new driver */
505 } while (driver_open(which
) != OK
);
508 printf("Filter: check_driver restarted driver %d, endpoint %d\n",
509 which
, driver
[which
].endpt
);
515 /*===========================================================================*
517 *===========================================================================*/
518 static int flt_senda(message
*mess
, int which
)
520 /* Send a message to one driver. Can only return OK at the moment. */
524 /* Fill in the last bits of the message. */
525 mess
->BDEV_MINOR
= driver
[which
].minor
;
528 /* Send the message asynchronously. */
529 amp
= &amsgtable
[which
];
530 amp
->dst
= driver
[which
].endpt
;
532 amp
->flags
= AMF_VALID
;
533 r
= senda(amsgtable
, 2);
536 panic("senda returned error: %d", r
);
541 /*===========================================================================*
543 *===========================================================================*/
544 static int check_senda(int which
)
546 /* Check whether an earlier senda resulted in an error indicating the
547 * message never got delivered. Only in that case can we reliably say
548 * that the driver died. Return BD_DEAD in this case, and BD_PROTO
553 amp
= &amsgtable
[which
];
555 if ((amp
->flags
& AMF_DONE
) && (amp
->result
== EDEADSRCDST
)) {
563 /*===========================================================================*
565 *===========================================================================*/
566 static int flt_receive(message
*mess
, int which
)
568 /* Receive a message from one or either driver, unless a timeout
569 * occurs. Can only return OK or RET_REDO.
575 r
= driver_receive(ANY
, mess
, &ipc_status
);
577 panic("driver_receive returned error: %d", r
);
579 if(mess
->m_source
== DS_PROC_NR
&& is_ipc_notify(ipc_status
)) {
584 if(mess
->m_source
== CLOCK
&& is_ipc_notify(ipc_status
)) {
585 if (mess
->NOTIFY_TIMESTAMP
< flt_alarm(-1)) {
587 printf("Filter: SKIPPING old alarm "
594 printf("Filter: timeout waiting for disk driver %d "
598 /* If we're waiting for either driver,
602 bad_driver(DRIVER_MAIN
,
603 check_senda(DRIVER_MAIN
), EFAULT
);
605 return bad_driver(DRIVER_BACKUP
,
606 check_senda(DRIVER_BACKUP
), EFAULT
);
609 /* Otherwise, just report the one not replying as dead.
611 return bad_driver(which
, check_senda(which
), EFAULT
);
614 if (mess
->m_source
!= driver
[DRIVER_MAIN
].endpt
&&
615 mess
->m_source
!= driver
[DRIVER_BACKUP
].endpt
) {
617 printf("Filter: got STRAY message %d from %d\n",
618 mess
->m_type
, mess
->m_source
);
624 /* We are waiting for a reply from one specific driver. */
626 /* If the message source is that driver, good. */
627 if (mess
->m_source
== driver
[which
].endpt
)
630 /* This should probably be treated as a real protocol
631 * error. We do not abort any receives (not even paired
632 * receives) except because of timeouts. Getting here
633 * means a driver replied at least the timeout period
634 * later than expected, which should be enough reason
635 * to kill it really. The other explanation is that it
636 * is actually violating the protocol and sending bogus
640 printf("Filter: got UNEXPECTED reply from %d\n",
647 /* We got a message from one of the drivers, and we didn't
648 * care which one we wanted to receive from. A-OK.
656 /*===========================================================================*
658 *===========================================================================*/
659 static int flt_sendrec(message
*mess
, int which
)
663 r
= flt_senda(mess
, which
);
667 if(check_senda(which
) == BD_DEAD
) {
668 return bad_driver(which
, BD_DEAD
, EFAULT
);
672 flt_alarm(DRIVER_TIMEOUT
);
674 r
= flt_receive(mess
, which
);
676 /* Clear the alarm. */
681 /*===========================================================================*
683 *===========================================================================*/
684 static int do_sendrec_both(message
*m1
, message
*m2
)
686 /* If USEE_MIRROR is set, call flt_sendrec() to both drivers.
687 * Otherwise, only call flt_sendrec() to the main driver.
688 * This function will only return either OK or RET_REDO.
693 /* If the two disks use the same driver, call flt_sendrec() twice
694 * sequentially. Such a setup is not very useful though.
696 if (!strcmp(driver
[DRIVER_MAIN
].label
, driver
[DRIVER_BACKUP
].label
)) {
697 if ((r
= flt_sendrec(m1
, DRIVER_MAIN
)) != OK
) return r
;
698 return flt_sendrec(m2
, DRIVER_BACKUP
);
701 /* If the two disks use different drivers, call flt_senda()
702 * twice, and then flt_receive(), and distinguish the return
703 * messages by means of m_source.
705 if ((r
= flt_senda(m1
, DRIVER_MAIN
)) != OK
) return r
;
706 if ((r
= flt_senda(m2
, DRIVER_BACKUP
)) != OK
) return r
;
709 flt_alarm(DRIVER_TIMEOUT
);
711 /* The message received by the 1st flt_receive() may not be
714 if ((r
= flt_receive(&ma
, -1)) != OK
) {
719 if (ma
.m_source
== driver
[DRIVER_MAIN
].endpt
) {
720 which
= DRIVER_BACKUP
;
721 } else if (ma
.m_source
== driver
[DRIVER_BACKUP
].endpt
) {
724 panic("message from unexpected source: %d",
728 r
= flt_receive(&mb
, which
);
730 /* Clear the alarm. */
736 if (ma
.m_source
== driver
[DRIVER_MAIN
].endpt
) {
747 /*===========================================================================*
749 *===========================================================================*/
750 static int do_sendrec_one(message
*m1
)
752 /* Only talk to the main driver. If something goes wrong, it will
753 * be fixed elsewhere.
754 * This function will only return either OK or RET_REDO.
757 return flt_sendrec(m1
, DRIVER_MAIN
);
760 /*===========================================================================*
762 *===========================================================================*/
763 static int paired_sendrec(message
*m1
, message
*m2
, int both
)
765 /* Sendrec with the disk driver. If the disk driver is down, and was
766 * restarted, redo the request, until the driver works fine, or can't
767 * be restarted again.
772 printf("paired_sendrec(%d) - <%d,%lx:%lx,%d> - %x,%x\n",
773 both
, m1
->m_type
, m1
->BDEV_POS_HI
, m1
->BDEV_POS_LO
,
774 m1
->BDEV_COUNT
, m1
->BDEV_GRANT
, m2
->BDEV_GRANT
);
778 r
= do_sendrec_both(m1
, m2
);
780 r
= do_sendrec_one(m1
);
784 printf("paired_sendrec about to return %d\n", r
);
790 /*===========================================================================*
792 *===========================================================================*/
793 static int single_grant(endpoint_t endpt
, vir_bytes buf
, int access
,
794 cp_grant_id_t
*gid
, iovec_s_t vector
[NR_IOREQS
], size_t size
)
796 /* 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
);
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 size
,
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], size
);
856 if(driver
[DRIVER_BACKUP
].endpt
> 0) {
857 count
= single_grant(driver
[DRIVER_BACKUP
].endpt
,
858 (vir_bytes
) buf2
, access
, &gids
[1],
865 /*===========================================================================*
867 *===========================================================================*/
868 static void single_revoke(cp_grant_id_t gid
,
869 const iovec_s_t vector
[NR_IOREQS
], int count
)
871 /* Revoke all grants associated with a request to a single driver.
872 * Modify the given size to reflect the actual I/O performed.
876 /* Revoke the grants for all the elements of the vector. */
877 for (i
= 0; i
< count
; i
++)
878 cpf_revoke(vector
[i
].iov_grant
);
880 /* Then revoke the grant for the vector itself. */
884 /*===========================================================================*
886 *===========================================================================*/
887 static void paired_revoke(const cp_grant_id_t
*gids
,
888 iovec_s_t vectors
[2][NR_IOREQS
], int count
, int both
)
890 /* Revoke grants to drivers for a single request.
893 single_revoke(gids
[0], vectors
[0], count
);
896 single_revoke(gids
[1], vectors
[1], count
);
899 /*===========================================================================*
901 *===========================================================================*/
902 int read_write(u64_t pos
, char *bufa
, char *bufb
, size_t *sizep
, int request
)
904 iovec_s_t vectors
[2][NR_IOREQS
];
906 cp_grant_id_t gids
[2];
909 gids
[0] = gids
[1] = GRANT_INVALID
;
911 /* Send two requests only if mirroring is enabled and the given request
912 * is either FLT_READ2 or FLT_WRITE.
914 both
= (USE_MIRROR
&& request
!= FLT_READ
);
916 count
= paired_grant(bufa
, bufb
, request
, gids
, vectors
, *sizep
, both
);
918 memset(&m1
, 0, sizeof(m1
));
919 m1
.m_type
= (request
== FLT_WRITE
) ? BDEV_SCATTER
: BDEV_GATHER
;
920 m1
.BDEV_COUNT
= count
;
921 m1
.BDEV_POS_LO
= ex64lo(pos
);
922 m1
.BDEV_POS_HI
= ex64hi(pos
);
926 m1
.BDEV_GRANT
= gids
[0];
927 m2
.BDEV_GRANT
= gids
[1];
929 r
= paired_sendrec(&m1
, &m2
, both
);
931 paired_revoke(gids
, vectors
, count
, both
);
936 printf("Filter: paired_sendrec returned %d\n", r
);
941 if (m1
.m_type
!= BDEV_REPLY
|| m1
.BDEV_STATUS
< 0) {
942 printf("Filter: unexpected/invalid reply from main driver: "
943 "(%x, %d)\n", m1
.m_type
, m1
.BDEV_STATUS
);
945 return bad_driver(DRIVER_MAIN
, BD_PROTO
,
946 (m1
.m_type
== BDEV_REPLY
) ? m1
.BDEV_STATUS
: EFAULT
);
949 if (m1
.BDEV_STATUS
!= (ssize_t
) *sizep
) {
950 printf("Filter: truncated reply from main driver\n");
952 /* If the driver returned a value *larger* than we requested,
953 * OR if we did NOT exceed the disk size, then we should
954 * report the driver for acting strangely!
956 if (m1
.BDEV_STATUS
> (ssize_t
) *sizep
||
957 cmp64(add64u(pos
, m1
.BDEV_STATUS
), disk_size
) < 0)
958 return bad_driver(DRIVER_MAIN
, BD_PROTO
, EFAULT
);
960 /* Return the actual size. */
961 *sizep
= m1
.BDEV_STATUS
;
965 if (m2
.m_type
!= BDEV_REPLY
|| m2
.BDEV_STATUS
< 0) {
966 printf("Filter: unexpected/invalid reply from "
967 "backup driver (%x, %d)\n",
968 m2
.m_type
, m2
.BDEV_STATUS
);
970 return bad_driver(DRIVER_BACKUP
, BD_PROTO
,
971 m2
.m_type
== BDEV_REPLY
? m2
.BDEV_STATUS
:
974 if (m2
.BDEV_STATUS
!= (ssize_t
) *sizep
) {
975 printf("Filter: truncated reply from backup driver\n");
978 if (m2
.BDEV_STATUS
> (ssize_t
) *sizep
||
979 cmp64(add64u(pos
, m2
.BDEV_STATUS
),
981 return bad_driver(DRIVER_BACKUP
, BD_PROTO
,
984 /* Return the actual size. */
985 if ((ssize_t
) *sizep
>= m2
.BDEV_STATUS
)
986 *sizep
= m2
.BDEV_STATUS
;
993 /*===========================================================================*
995 *===========================================================================*/
998 char key
[DS_MAX_KEYLEN
];
999 char *blkdriver_prefix
= "drv.blk.";
1002 endpoint_t owner_endpoint
;
1006 /* Get the event and the owner from DS. */
1007 r
= ds_check(key
, &type
, &owner_endpoint
);
1010 printf("Filter: ds_event: ds_check failed: %d\n", r
);
1013 r
= ds_retrieve_u32(key
, &value
);
1015 printf("Filter: ds_event: ds_retrieve_u32 failed\n");
1019 /* Only check for VFS driver up events. */
1020 if(strncmp(key
, blkdriver_prefix
, strlen(blkdriver_prefix
))
1021 || value
!= DS_DRIVER_UP
) {
1025 /* See if this is a driver we are responsible for. */
1026 if(driver
[DRIVER_MAIN
].endpt
== owner_endpoint
) {
1027 which
= DRIVER_MAIN
;
1029 else if(driver
[DRIVER_BACKUP
].endpt
== owner_endpoint
) {
1030 which
= DRIVER_BACKUP
;
1036 /* Mark the driver as (re)started. */
1037 driver
[which
].up_event
= driver
[which
].up_event
== UP_EXPECTED
?
1038 UP_NONE
: UP_PENDING
;