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 ipc_sendrec()
27 struct part_geom part
;
31 memset(&msg
, 0, sizeof(msg
));
32 msg
.m_type
= BDEV_OPEN
;
33 msg
.BDEV_MINOR
= driver
[which
].minor
;
34 msg
.BDEV_ACCESS
= BDEV_R_BIT
| BDEV_W_BIT
;
36 r
= ipc_sendrec(driver
[which
].endpt
, &msg
);
39 /* Should we restart the driver now? */
40 printf("Filter: driver_open: ipc_sendrec returned %d\n", r
);
45 if(msg
.m_type
!= BDEV_REPLY
|| msg
.BDEV_STATUS
!= OK
) {
46 printf("Filter: driver_open: ipc_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
;
66 r
= ipc_sendrec(driver
[which
].endpt
, &msg
);
70 if (r
!= OK
|| msg
.m_type
!= BDEV_REPLY
|| msg
.BDEV_STATUS
!= OK
) {
71 /* Not sure what to do here, either. */
72 printf("Filter: ioctl(DIOCGETP) returned (%d, %d)\n",
79 disk_size
= part
.size
;
81 sectors
= (unsigned long)(disk_size
/ SECTOR_SIZE
);
82 if ((u64_t
)sectors
* SECTOR_SIZE
!= disk_size
) {
83 printf("Filter: partition too large\n");
88 printf("Filter: partition size: 0x%"PRIx64
" / %lu sectors\n",
92 if (disk_size
!= part
.size
) {
93 printf("Filter: partition size mismatch "
94 "(0x%"PRIx64
" != 0x%"PRIx64
")\n",
95 part
.size
, disk_size
);
104 /*===========================================================================*
106 *===========================================================================*/
107 static int driver_close(int which
)
112 memset(&msg
, 0, sizeof(msg
));
113 msg
.m_type
= BDEV_CLOSE
;
114 msg
.BDEV_MINOR
= driver
[which
].minor
;
116 r
= ipc_sendrec(driver
[which
].endpt
, &msg
);
119 /* Should we restart the driver now? */
120 printf("Filter: driver_close: ipc_sendrec returned %d\n", r
);
125 if(msg
.m_type
!= BDEV_REPLY
|| msg
.BDEV_STATUS
!= OK
) {
126 printf("Filter: driver_close: ipc_sendrec returned %d, %d\n",
127 msg
.m_type
, msg
.BDEV_STATUS
);
135 /*===========================================================================*
137 *===========================================================================*/
138 void driver_init(void)
140 /* Initialize the driver layer. */
143 memset(driver
, 0, sizeof(driver
));
145 /* Endpoints unknown. */
146 driver
[DRIVER_MAIN
].endpt
= NONE
;
147 driver
[DRIVER_BACKUP
].endpt
= NONE
;
149 /* Get disk driver's and this proc's endpoint. */
150 driver
[DRIVER_MAIN
].label
= MAIN_LABEL
;
151 driver
[DRIVER_MAIN
].minor
= MAIN_MINOR
;
153 /* No up received yet but expected when the driver starts. */
154 driver
[DRIVER_MAIN
].up_event
= UP_EXPECTED
;
155 driver
[DRIVER_BACKUP
].up_event
= UP_EXPECTED
;
157 r
= ds_retrieve_label_endpt(driver
[DRIVER_MAIN
].label
,
158 &driver
[DRIVER_MAIN
].endpt
);
160 printf("Filter: failed to get main disk driver's endpoint: "
162 bad_driver(DRIVER_MAIN
, BD_DEAD
, EFAULT
);
163 check_driver(DRIVER_MAIN
);
165 else if (driver_open(DRIVER_MAIN
) != OK
) {
166 panic("unhandled driver_open failure");
170 driver
[DRIVER_BACKUP
].label
= BACKUP_LABEL
;
171 driver
[DRIVER_BACKUP
].minor
= BACKUP_MINOR
;
173 if(!strcmp(driver
[DRIVER_MAIN
].label
,
174 driver
[DRIVER_BACKUP
].label
)) {
175 panic("same driver: not tested");
178 r
= ds_retrieve_label_endpt(driver
[DRIVER_BACKUP
].label
,
179 &driver
[DRIVER_BACKUP
].endpt
);
181 printf("Filter: failed to get backup disk driver's "
182 "endpoint: %d\n", r
);
183 bad_driver(DRIVER_BACKUP
, BD_DEAD
, EFAULT
);
184 check_driver(DRIVER_BACKUP
);
186 else if (driver_open(DRIVER_BACKUP
) != OK
) {
187 panic("unhandled driver_open failure");
192 /*===========================================================================*
194 *===========================================================================*/
195 void driver_shutdown(void)
200 printf("Filter: %u driver deaths, %u protocol errors, "
201 "%u data errors\n", problem_stats
[BD_DEAD
],
202 problem_stats
[BD_PROTO
], problem_stats
[BD_DATA
]);
205 if(driver_close(DRIVER_MAIN
) != OK
)
206 printf("Filter: BDEV_CLOSE failed on shutdown (1)\n");
209 if(driver_close(DRIVER_BACKUP
) != OK
)
210 printf("Filter: BDEV_CLOSE failed on shutdown (2)\n");
213 /*===========================================================================*
215 *===========================================================================*/
216 u64_t
get_raw_size(void)
218 /* Return the size of the raw disks as used by the filter driver.
224 /*===========================================================================*
226 *===========================================================================*/
227 void reset_kills(void)
229 /* Reset kill and retry statistics. */
230 driver
[DRIVER_MAIN
].kills
= 0;
231 driver
[DRIVER_MAIN
].retries
= 0;
232 driver
[DRIVER_BACKUP
].kills
= 0;
233 driver
[DRIVER_BACKUP
].retries
= 0;
236 /*===========================================================================*
238 *===========================================================================*/
239 int bad_driver(int which
, int type
, int error
)
241 /* A disk driver has died or produced an error. Mark it so that we can
242 * deal with it later, and return RET_REDO to indicate that the
243 * current operation is to be retried. Also store an error code to
244 * return to the user if the situation is unrecoverable.
246 driver
[which
].problem
= type
;
247 driver
[which
].error
= error
;
252 /*===========================================================================*
254 *===========================================================================*/
255 static int new_driver_ep(int which
)
257 /* See if a new driver instance has already been started for the given
258 * driver, by retrieving its entry from DS.
263 r
= ds_retrieve_label_endpt(driver
[which
].label
, &endpt
);
266 printf("Filter: DS query for %s failed\n",
267 driver
[which
].label
);
272 if (endpt
== driver
[which
].endpt
) {
274 printf("Filter: same endpoint for %s\n", driver
[which
].label
);
280 printf("Filter: new enpdoint for %s: %d -> %d\n", driver
[which
].label
,
281 driver
[which
].endpt
, endpt
);
284 driver
[which
].endpt
= endpt
;
289 /*===========================================================================*
291 *===========================================================================*/
292 static int check_problem(int which
, int problem
, int retries
, int *tell_rs
)
294 /* A problem has occurred with a driver. Update statistics, and decide
295 * what to do. If EAGAIN is returned, the driver should be restarted;
296 * any other result will be passed up.
300 printf("Filter: check_problem processing driver %d, problem %d\n",
304 problem_stats
[problem
]++;
306 if(new_driver_ep(which
)) {
308 printf("Filter: check_problem: noticed a new driver\n");
311 if(driver_open(which
) == OK
) {
313 printf("Filter: open OK -> no recovery\n");
318 printf("Filter: open not OK -> recovery\n");
321 problem_stats
[problem
]++;
325 /* If the driver has died, we always need to restart it. If it has
326 * been giving problems, we first retry the request, up to N times,
327 * after which we kill and restart the driver. We restart the driver
328 * up to M times, after which we remove the driver from the mirror
329 * configuration. If we are not set up to do mirroring, we can only
330 * do one thing, and that is continue to limp along with the bad
336 driver
[which
].retries
++;
339 printf("Filter: disk driver %d has had "
340 "%d/%d retry attempts, %d/%d kills\n", which
,
341 driver
[which
].retries
, NR_RETRIES
,
342 driver
[which
].kills
, NR_RESTARTS
);
345 if (driver
[which
].retries
< NR_RETRIES
) {
348 printf("Filter: not restarting; retrying "
349 "(retries %d/%d, kills %d/%d)\n",
350 driver
[which
].retries
, NR_RETRIES
,
351 driver
[which
].kills
, NR_RESTARTS
);
356 printf("Filter: restarting (retries %d/%d, "
357 "kills %d/%d, internal retry %d)\n",
358 driver
[which
].retries
, NR_RETRIES
,
359 driver
[which
].kills
, NR_RESTARTS
, retries
);
364 printf("Filter: disk driver %d has reached error "
365 "threshold, restarting driver\n", which
);
368 *tell_rs
= (driver
[which
].up_event
!= UP_PENDING
);
372 /* Can't kill that which is already dead.. */
377 panic("invalid problem: %d", problem
);
380 /* At this point, the driver will be restarted. */
381 driver
[which
].retries
= 0;
382 driver
[which
].kills
++;
384 if (driver
[which
].kills
< NR_RESTARTS
)
387 /* We've reached the maximum number of restarts for this driver. */
389 printf("Filter: kill threshold reached, disabling mirroring\n");
393 if (which
== DRIVER_MAIN
) {
394 driver
[DRIVER_MAIN
] = driver
[DRIVER_BACKUP
];
396 /* This is not necessary. */
397 strlcpy(MAIN_LABEL
, BACKUP_LABEL
, sizeof(MAIN_LABEL
));
398 MAIN_MINOR
= BACKUP_MINOR
;
401 driver
[DRIVER_BACKUP
].endpt
= NONE
;
406 /* We tried, we really did. But now we give up. Tell the user.
408 printf("Filter: kill threshold reached, returning error\n");
410 if (driver
[which
].error
== EAGAIN
) return EIO
;
412 return driver
[which
].error
;
416 /*===========================================================================*
418 *===========================================================================*/
419 static void restart_driver(int which
, int tell_rs
)
421 /* Restart the given driver. Block until the new instance is up.
428 /* Tell RS to refresh or restart the driver */
429 msg
.m_type
= RS_REFRESH
;
430 msg
.RS_CMD_ADDR
= driver
[which
].label
;
431 msg
.RS_CMD_LEN
= strlen(driver
[which
].label
);
434 printf("Filter: asking RS to refresh %s..\n",
435 driver
[which
].label
);
438 r
= ipc_sendrec(RS_PROC_NR
, &msg
);
440 if (r
!= OK
|| msg
.m_type
!= OK
)
441 panic("RS request failed: %d", r
);
444 printf("Filter: RS call succeeded\n");
448 /* Wait until the new driver instance is up, and get its endpoint. */
450 printf("Filter: endpoint update driver %d; old endpoint %d\n",
451 which
, driver
[which
].endpt
);
454 if(driver
[which
].up_event
== UP_EXPECTED
) {
455 driver
[which
].up_event
= UP_NONE
;
457 while(driver
[which
].up_event
!= UP_PENDING
) {
458 r
= driver_receive(DS_PROC_NR
, &msg
, &ipc_status
);
460 panic("driver_receive returned error: %d", r
);
466 /*===========================================================================*
468 *===========================================================================*/
469 int check_driver(int which
)
471 /* See if the given driver has been troublesome, and if so, deal with
474 int problem
, tell_rs
;
477 problem
= driver
[which
].problem
;
479 if (problem
== BD_NONE
)
485 printf("Filter: check_driver: retry number %d\n",
491 driver
[which
].problem
= BD_NONE
;
493 /* Decide what to do: continue operation, restart the driver,
494 * or return an error.
496 r
= check_problem(which
, problem
, retries
, &tell_rs
);
500 /* Restarting the driver it is. First tell RS (if necessary),
501 * then wait for the new driver instance to come up.
503 restart_driver(which
, tell_rs
);
505 /* Finally, open the device on the new driver */
506 } while (driver_open(which
) != OK
);
509 printf("Filter: check_driver restarted driver %d, endpoint %d\n",
510 which
, driver
[which
].endpt
);
516 /*===========================================================================*
518 *===========================================================================*/
519 static int flt_senda(message
*mess
, int which
)
521 /* Send a message to one driver. Can only return OK at the moment. */
525 /* Fill in the last bits of the message. */
526 mess
->BDEV_MINOR
= driver
[which
].minor
;
529 /* Send the message asynchronously. */
530 amp
= &amsgtable
[which
];
531 amp
->dst
= driver
[which
].endpt
;
533 amp
->flags
= AMF_VALID
;
534 r
= ipc_senda(amsgtable
, 2);
537 panic("ipc_senda returned error: %d", r
);
542 /*===========================================================================*
544 *===========================================================================*/
545 static int check_senda(int which
)
547 /* Check whether an earlier senda resulted in an error indicating the
548 * message never got delivered. Only in that case can we reliably say
549 * that the driver died. Return BD_DEAD in this case, and BD_PROTO
554 amp
= &amsgtable
[which
];
556 if ((amp
->flags
& AMF_DONE
) && (amp
->result
== EDEADSRCDST
)) {
564 /*===========================================================================*
566 *===========================================================================*/
567 static int flt_receive(message
*mess
, int which
)
569 /* Receive a message from one or either driver, unless a timeout
570 * occurs. Can only return OK or RET_REDO.
576 r
= driver_receive(ANY
, mess
, &ipc_status
);
578 panic("driver_receive returned error: %d", r
);
580 if(mess
->m_source
== DS_PROC_NR
&& is_ipc_notify(ipc_status
)) {
585 if(mess
->m_source
== CLOCK
&& is_ipc_notify(ipc_status
)) {
586 if (mess
->m_notify
.timestamp
< flt_alarm((clock_t) -1)) {
588 printf("Filter: SKIPPING old alarm "
595 printf("Filter: timeout waiting for disk driver %d "
599 /* If we're waiting for either driver,
603 bad_driver(DRIVER_MAIN
,
604 check_senda(DRIVER_MAIN
), EFAULT
);
606 return bad_driver(DRIVER_BACKUP
,
607 check_senda(DRIVER_BACKUP
), EFAULT
);
610 /* Otherwise, just report the one not replying as dead.
612 return bad_driver(which
, check_senda(which
), EFAULT
);
615 if (mess
->m_source
!= driver
[DRIVER_MAIN
].endpt
&&
616 mess
->m_source
!= driver
[DRIVER_BACKUP
].endpt
) {
618 printf("Filter: got STRAY message %d from %d\n",
619 mess
->m_type
, mess
->m_source
);
625 /* We are waiting for a reply from one specific driver. */
627 /* If the message source is that driver, good. */
628 if (mess
->m_source
== driver
[which
].endpt
)
631 /* This should probably be treated as a real protocol
632 * error. We do not abort any receives (not even paired
633 * receives) except because of timeouts. Getting here
634 * means a driver replied at least the timeout period
635 * later than expected, which should be enough reason
636 * to kill it really. The other explanation is that it
637 * is actually violating the protocol and sending bogus
641 printf("Filter: got UNEXPECTED reply from %d\n",
648 /* We got a message from one of the drivers, and we didn't
649 * care which one we wanted to receive from. A-OK.
657 /*===========================================================================*
659 *===========================================================================*/
660 static int flt_sendrec(message
*mess
, int which
)
664 r
= flt_senda(mess
, which
);
668 if(check_senda(which
) == BD_DEAD
) {
669 return bad_driver(which
, BD_DEAD
, EFAULT
);
673 flt_alarm(DRIVER_TIMEOUT
);
675 r
= flt_receive(mess
, which
);
677 /* Clear the alarm. */
682 /*===========================================================================*
684 *===========================================================================*/
685 static int do_sendrec_both(message
*m1
, message
*m2
)
687 /* If USEE_MIRROR is set, call flt_sendrec() to both drivers.
688 * Otherwise, only call flt_sendrec() to the main driver.
689 * This function will only return either OK or RET_REDO.
694 /* If the two disks use the same driver, call flt_sendrec() twice
695 * sequentially. Such a setup is not very useful though.
697 if (!strcmp(driver
[DRIVER_MAIN
].label
, driver
[DRIVER_BACKUP
].label
)) {
698 if ((r
= flt_sendrec(m1
, DRIVER_MAIN
)) != OK
) return r
;
699 return flt_sendrec(m2
, DRIVER_BACKUP
);
702 /* If the two disks use different drivers, call flt_senda()
703 * twice, and then flt_receive(), and distinguish the return
704 * messages by means of m_source.
706 if ((r
= flt_senda(m1
, DRIVER_MAIN
)) != OK
) return r
;
707 if ((r
= flt_senda(m2
, DRIVER_BACKUP
)) != OK
) return r
;
710 flt_alarm(DRIVER_TIMEOUT
);
712 /* The message received by the 1st flt_receive() may not be
715 if ((r
= flt_receive(&ma
, -1)) != OK
) {
720 if (ma
.m_source
== driver
[DRIVER_MAIN
].endpt
) {
721 which
= DRIVER_BACKUP
;
722 } else if (ma
.m_source
== driver
[DRIVER_BACKUP
].endpt
) {
725 panic("message from unexpected source: %d",
729 r
= flt_receive(&mb
, which
);
731 /* Clear the alarm. */
737 if (ma
.m_source
== driver
[DRIVER_MAIN
].endpt
) {
748 /*===========================================================================*
750 *===========================================================================*/
751 static int do_sendrec_one(message
*m1
)
753 /* Only talk to the main driver. If something goes wrong, it will
754 * be fixed elsewhere.
755 * This function will only return either OK or RET_REDO.
758 return flt_sendrec(m1
, DRIVER_MAIN
);
761 /*===========================================================================*
763 *===========================================================================*/
764 static int paired_sendrec(message
*m1
, message
*m2
, int both
)
766 /* Sendrec with the disk driver. If the disk driver is down, and was
767 * restarted, redo the request, until the driver works fine, or can't
768 * be restarted again.
773 printf("paired_sendrec(%d) - <%d,%llx,%d> - %x,%x\n",
774 both
, m1
->m_type
, m1
->BDEV_POS
,
775 m1
->BDEV_COUNT
, m1
->BDEV_GRANT
, m2
->BDEV_GRANT
);
779 r
= do_sendrec_both(m1
, m2
);
781 r
= do_sendrec_one(m1
);
785 printf("paired_sendrec about to return %d\n", r
);
791 /*===========================================================================*
793 *===========================================================================*/
794 static int single_grant(endpoint_t endpt
, vir_bytes buf
, int access
,
795 cp_grant_id_t
*gid
, iovec_s_t vector
[NR_IOREQS
], size_t size
)
797 /* Create grants for a vectored request to a single driver.
803 /* Split up the request into chunks, if requested. This makes no
804 * difference at all, except that this works around a weird performance
805 * bug with large DMA PRDs on some machines.
807 if (CHUNK_SIZE
> 0) chunk
= CHUNK_SIZE
;
810 /* Fill in the vector, creating a grant for each item. */
811 for (count
= 0; size
> 0 && count
< NR_IOREQS
; count
++) {
812 /* The last chunk will contain all the remaining data. */
813 if (chunk
> size
|| count
== NR_IOREQS
- 1)
816 grant
= cpf_grant_direct(endpt
, buf
, chunk
, access
);
817 if (!GRANT_VALID(grant
))
818 panic("invalid grant: %d", grant
);
820 vector
[count
].iov_grant
= grant
;
821 vector
[count
].iov_size
= chunk
;
827 /* Then create a grant for the vector itself. */
828 *gid
= cpf_grant_direct(endpt
, (vir_bytes
) vector
,
829 sizeof(vector
[0]) * count
, CPF_READ
);
831 if (!GRANT_VALID(*gid
))
832 panic("invalid grant: %d", *gid
);
837 /*===========================================================================*
839 *===========================================================================*/
840 static int paired_grant(char *buf1
, char *buf2
, int request
,
841 cp_grant_id_t
*gids
, iovec_s_t vectors
[2][NR_IOREQS
], size_t size
,
844 /* Create memory grants, either to one or to both drivers.
849 access
= (request
== FLT_WRITE
) ? CPF_READ
: CPF_WRITE
;
851 if(driver
[DRIVER_MAIN
].endpt
> 0) {
852 count
= single_grant(driver
[DRIVER_MAIN
].endpt
,
853 (vir_bytes
) buf1
, access
, &gids
[0], vectors
[0], size
);
857 if(driver
[DRIVER_BACKUP
].endpt
> 0) {
858 count
= single_grant(driver
[DRIVER_BACKUP
].endpt
,
859 (vir_bytes
) buf2
, access
, &gids
[1],
866 /*===========================================================================*
868 *===========================================================================*/
869 static void single_revoke(cp_grant_id_t gid
,
870 const iovec_s_t vector
[NR_IOREQS
], 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
);
881 /* Then revoke the grant for the vector itself. */
885 /*===========================================================================*
887 *===========================================================================*/
888 static void paired_revoke(const cp_grant_id_t
*gids
,
889 iovec_s_t vectors
[2][NR_IOREQS
], int count
, int both
)
891 /* Revoke grants to drivers for a single request.
894 single_revoke(gids
[0], vectors
[0], count
);
897 single_revoke(gids
[1], vectors
[1], count
);
900 /*===========================================================================*
902 *===========================================================================*/
903 int read_write(u64_t pos
, char *bufa
, char *bufb
, size_t *sizep
, int request
)
905 iovec_s_t vectors
[2][NR_IOREQS
];
907 cp_grant_id_t gids
[2];
910 gids
[0] = gids
[1] = GRANT_INVALID
;
912 /* Send two requests only if mirroring is enabled and the given request
913 * is either FLT_READ2 or FLT_WRITE.
915 both
= (USE_MIRROR
&& request
!= FLT_READ
);
917 count
= paired_grant(bufa
, bufb
, request
, gids
, vectors
, *sizep
, both
);
919 memset(&m1
, 0, sizeof(m1
));
920 m1
.m_type
= (request
== FLT_WRITE
) ? BDEV_SCATTER
: BDEV_GATHER
;
921 m1
.BDEV_COUNT
= count
;
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 (pos
+ (unsigned int) m1
.BDEV_STATUS
< disk_size
))
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 (pos
+ (unsigned int) 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
;