(&mut self, context: crate::device::ActivationContext)
| 1087 | } |
| 1088 | |
| 1089 | fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult { |
| 1090 | let crate::device::ActivationContext { |
| 1091 | mem, |
| 1092 | interrupt_cb, |
| 1093 | mut queues, |
| 1094 | device_status, |
| 1095 | } = context; |
| 1096 | self.device_status = device_status; |
| 1097 | // See if the guest didn't ack the device being read-only. |
| 1098 | // If so, warn and pretend it did. |
| 1099 | let original_acked_features = self.common.acked_features; |
| 1100 | self.common.acked_features |= self.common.avail_features & (1u64 << VIRTIO_BLK_F_RO); |
| 1101 | if original_acked_features != self.common.acked_features { |
| 1102 | warn!("Guest did not acknowledge that device is read-only, acting as if it did!"); |
| 1103 | } |
| 1104 | self.common.activate(&queues, interrupt_cb.clone())?; |
| 1105 | |
| 1106 | // Recompute the barrier size from the queues that are actually activated. |
| 1107 | self.common.paused_sync = Some(Arc::new(Barrier::new(queues.len() + 1))); |
| 1108 | |
| 1109 | let writeback = self.is_writeback_enabled(self.config.writeback == 1); |
| 1110 | self.set_writeback_mode(writeback); |
| 1111 | |
| 1112 | let mut epoll_threads = Vec::new(); |
| 1113 | let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into()); |
| 1114 | |
| 1115 | for i in 0..queues.len() { |
| 1116 | let (_, mut queue, queue_evt) = queues.remove(0); |
| 1117 | queue.set_event_idx(event_idx); |
| 1118 | |
| 1119 | let queue_size = queue.size(); |
| 1120 | let (kill_evt, pause_evt) = self.common.dup_eventfds(); |
| 1121 | let queue_idx = i as u16; |
| 1122 | |
| 1123 | let mut handler = BlockEpollHandler { |
| 1124 | queue_index: queue_idx, |
| 1125 | queue, |
| 1126 | mem: mem.clone(), |
| 1127 | disk_image: self |
| 1128 | .disk_image |
| 1129 | .create_async_io(queue_size as u32) |
| 1130 | .map_err(|e| { |
| 1131 | error!("failed to create new AsyncIo: {e}"); |
| 1132 | ActivateError::BadActivate |
| 1133 | })?, |
| 1134 | disk_nsectors: self.disk_nsectors.clone(), |
| 1135 | interrupt_cb: interrupt_cb.clone(), |
| 1136 | serial: self.serial.clone(), |
| 1137 | kill_evt, |
| 1138 | pause_evt, |
| 1139 | writeback: self.writeback.clone(), |
| 1140 | counters: self.counters.clone(), |
| 1141 | queue_evt, |
| 1142 | // Analysis during boot shows around ~40 maximum requests |
| 1143 | // This gives head room for systems with slower I/O without |
| 1144 | // compromising the cost of the reallocation or memory overhead |
| 1145 | inflight_requests: VecDeque::with_capacity(64), |
| 1146 | rate_limiter: self |
nothing calls this directly
no test coverage detected