fn activate(
        &mut self,
        _mem_space: Arc<AddressSpace>,
        interrupt_cb: Arc<VirtioInterrupt>,
        queues: &[Arc<Mutex<Queue>>],
        queue_evts: Vec<EventFd>,
    ) -> Result<()> {
        let mut host_notifies = Vec::new();
        let backend = match &self.backend {
            None => return Err("Failed to get backend for vhost net".into()),
            Some(backend_) => backend_,
        };

        backend
            .set_features(self.vhost_features)
            .chain_err(|| "Failed to set features for vhost net")?;
        backend
            .set_mem_table()
            .chain_err(|| "Failed to set mem table for vhost net")?;

        for (queue_index, queue_mutex) in queues.iter().enumerate() {
            let queue = queue_mutex.lock().unwrap();
            let actual_size = queue.vring.actual_size();
            let queue_config = queue.vring.get_queue_config();

            backend
                .set_vring_num(queue_index, actual_size)
                .chain_err(|| {
                    format!(
                        "Failed to set vring num for vhost net, index: {} size: {}",
                        queue_index, actual_size,
                    )
                })?;
            backend
                .set_vring_addr(&queue_config, queue_index, 0)
                .chain_err(|| {
                    format!(
                        "Failed to set vring addr for vhost net, index: {}",
                        queue_index,
                    )
                })?;
            backend.set_vring_base(queue_index, 0).chain_err(|| {
                format!(
                    "Failed to set vring base for vhost net, index: {}",
                    queue_index,
                )
            })?;
            backend
                .set_vring_kick(queue_index, &queue_evts[queue_index])
                .chain_err(|| {
                    format!(
                        "Failed to set vring kick for vhost net, index: {}",
                        queue_index,
                    )
                })?;

            drop(queue);

            let host_notify = VhostNotify {
                notify_evt: EventFd::new(libc::EFD_NONBLOCK)
                    .chain_err(|| ErrorKind::EventFdCreate)?,
                queue: queue_mutex.clone(),
            };
            backend
                .set_vring_call(queue_index, &host_notify.notify_evt)
                .chain_err(|| {
                    format!(
                        "Failed to set vring call for vhost net, index: {}",
                        queue_index,
                    )
                })?;
            host_notifies.push(host_notify);

            let tap = match &self.tap {
                None => bail!("Failed to get tap for vhost net"),
                Some(tap_) => tap_,
            };
            backend.set_backend(queue_index, &tap.file).chain_err(|| {
                format!(
                    "Failed to set tap device for vhost net, index: {}",
                    queue_index,
                )
            })?;
        }

        let handler = VhostIoHandler {
            interrupt_cb,
            host_notifies,
            reset_evt: self.reset_evt.as_raw_fd(),
        };

        EventLoop::update_event(
            EventNotifierHelper::internal_notifiers(Arc::new(Mutex::new(handler))),
            None,
        )?;

        Ok(())
    }
/// Activate the virtio device, this function is called by vcpu thread when frontend
/// virtio driver is ready and write `DRIVER_OK` to backend.
Activate the virtio device, this function is called by vcpu thread when frontend
virtio driver is ready and write `DRIVER_OK` to backend.
Activate the virtio device this function is called by vcpu thread when frontend virtio driver is ready and write ` DRIVER_OK ` to backend .
fn activate(
        &mut self,
        _mem_space: Arc<AddressSpace>,
        interrupt_cb: Arc<VirtioInterrupt>,
        queues: &[Arc<Mutex<Queue>>],
        queue_evts: Vec<EventFd>,
    ) -> Result<()> {
        let mut host_notifies = Vec::new();
        let backend = match &self.backend {
            None => return Err("Failed to get backend for vhost net".into()),
            Some(backend_) => backend_,
        };
        backend
            .set_features(self.vhost_features)
            .chain_err(|| "Failed to set features for vhost net")?;
        backend
            .set_mem_table()
            .chain_err(|| "Failed to set mem table for vhost net")?;
        for (queue_index, queue_mutex) in queues.iter().enumerate() {
            let queue = queue_mutex.lock().unwrap();
            let actual_size = queue.vring.actual_size();
            let queue_config = queue.vring.get_queue_config();
            backend
                .set_vring_num(queue_index, actual_size)
                .chain_err(|| {
                    format!(
                        "Failed to set vring num for vhost net, index: {} size: {}",
                        queue_index, actual_size,
                    )
                })?;
            backend
                .set_vring_addr(&queue_config, queue_index, 0)
                .chain_err(|| {
                    format!(
                        "Failed to set vring addr for vhost net, index: {}",
                        queue_index,
                    )
                })?;
            backend.set_vring_base(queue_index, 0).chain_err(|| {
                format!(
                    "Failed to set vring base for vhost net, index: {}",
                    queue_index,
                )
            })?;
            backend
                .set_vring_kick(queue_index, &queue_evts[queue_index])
                .chain_err(|| {
                    format!(
                        "Failed to set vring kick for vhost net, index: {}",
                        queue_index,
                    )
                })?;
            drop(queue);
            let host_notify = VhostNotify {
                notify_evt: EventFd::new(libc::EFD_NONBLOCK)
                    .chain_err(|| ErrorKind::EventFdCreate)?,
                queue: queue_mutex.clone(),
            };
            backend
                .set_vring_call(queue_index, &host_notify.notify_evt)
                .chain_err(|| {
                    format!(
                        "Failed to set vring call for vhost net, index: {}",
                        queue_index,
                    )
                })?;
            host_notifies.push(host_notify);
            let tap = match &self.tap {
                None => bail!("Failed to get tap for vhost net"),
                Some(tap_) => tap_,
            };
            backend.set_backend(queue_index, &tap.file).chain_err(|| {
                format!(
                    "Failed to set tap device for vhost net, index: {}",
                    queue_index,
                )
            })?;
        }
        let handler = VhostIoHandler {
            interrupt_cb,
            host_notifies,
            reset_evt: self.reset_evt.as_raw_fd(),
        };
        EventLoop::update_event(
            EventNotifierHelper::internal_notifiers(Arc::new(Mutex::new(handler))),
            None,
        )?;
        Ok(())
    }
fn activate ( & mut self , _mem_space : Arc < AddressSpace > , interrupt_cb : Arc < VirtioInterrupt > , queues : & [ Arc < Mutex < Queue > > ] , queue_evts : Vec < EventFd > , ) -> Result < ( ) > { let mut host_notifies = Vec :: new ( ) ; let backend = match & self . backend { None => return Err ( " " . into ( ) ) , Some ( backend_ ) => backend_ , } ; backend . set_features ( self . vhost_features ) . chain_err ( | | " " ) ? ; backend . set_mem_table ( ) . chain_err ( | | " " ) ? ; for ( queue_index , queue_mutex ) in queues . iter ( ) . enumerate ( ) { let queue = queue_mutex . lock ( ) . unwrap ( ) ; let actual_size = queue . vring . actual_size ( ) ; let queue_config = queue . vring . get_queue_config ( ) ; backend . set_vring_num ( queue_index , actual_size ) . chain_err ( | | { format ! ( " " queue_index actual_size ) } ) ? ; backend . set_vring_addr ( & queue_config , queue_index , 0 ) . chain_err ( | | { format ! ( " " queue_index ) } ) ? ; backend . set_vring_base ( queue_index , 0 ) . chain_err ( | | { format ! ( " " queue_index ) } ) ? ; backend . set_vring_kick ( queue_index , & queue_evts [ queue_index ] ) . chain_err ( | | { format ! ( " " queue_index ) } ) ? ; drop ( queue ) ; let host_notify = VhostNotify { notify_evt : EventFd :: new ( libc :: EFD_NONBLOCK ) . chain_err ( | | ErrorKind :: EventFdCreate ) ? , queue : queue_mutex . clone ( ) , } ; backend . set_vring_call ( queue_index , & host_notify . notify_evt ) . chain_err ( | | { format ! ( " " queue_index ) } ) ? ; host_notifies . push ( host_notify ) ; let tap = match & self . tap { None => bail ! ( " " ) , Some ( tap_ ) => tap_ , } ; backend . set_backend ( queue_index , & tap . file ) . chain_err ( | | { format ! ( " " queue_index ) } ) ? ; } let handler = VhostIoHandler { interrupt_cb , host_notifies , reset_evt : self . reset_evt . as_raw_fd ( ) , } ; EventLoop :: update_event ( EventNotifierHelper :: internal_notifiers ( Arc :: new ( Mutex :: new ( handler ) ) ) , None , ) ? ; Ok ( ( ) ) }
Activate the virtio device, this function is called by vcpu thread when frontend
virtio driver is ready and write `DRIVER_OK` to backend.
Activate the virtio device this function is called by vcpu thread when frontend virtio driver is ready and write ` DRIVER_OK ` to backend .
&mut self
_mem_space
Arc<AddressSpace>
interrupt_cb
Arc<VirtioInterrupt>
queues
&[Arc<Mutex<Queue>>]
queue_evts
Vec<EventFd>
&mut self
_mem_space
Arc<AddressSpace>
interrupt_cb
Arc<VirtioInterrupt>
queues
&[Arc<Mutex<Queue>>]
queue_evts
Vec<EventFd>