@@ -173,7 +173,7 @@ impl std::fmt::Debug for Error {
173173}
174174
175175/// Types of errors associated with vmm actions.
176- #[ derive( Debug ) ]
176+ #[ derive( Clone , Debug ) ]
177177pub enum ErrorKind {
178178 /// User Errors describe bad configuration (user input).
179179 User ,
@@ -182,6 +182,16 @@ pub enum ErrorKind {
182182 Internal ,
183183}
184184
185+ impl PartialEq for ErrorKind {
186+ fn eq ( & self , other : & ErrorKind ) -> bool {
187+ match ( self , other) {
188+ ( & ErrorKind :: User , & ErrorKind :: User ) => true ,
189+ ( & ErrorKind :: Internal , & ErrorKind :: Internal ) => true ,
190+ _ => false ,
191+ }
192+ }
193+ }
194+
185195/// Wrapper for all errors associated with VMM actions.
186196#[ derive( Debug ) ]
187197pub enum VmmActionError {
@@ -316,7 +326,7 @@ impl std::convert::From<StartMicrovmError> for VmmActionError {
316326
317327impl VmmActionError {
318328 /// Returns the error type.
319- pub fn get_kind ( & self ) -> & ErrorKind {
329+ pub fn kind ( & self ) -> & ErrorKind {
320330 use self :: VmmActionError :: * ;
321331
322332 match * self {
@@ -3203,6 +3213,259 @@ mod tests {
32033213 stdin_handle. lock ( ) . set_canon_mode ( ) . unwrap ( ) ;
32043214 }
32053215
3216+ // Helper function to get ErrorKind of error.
3217+ fn error_kind < T : std:: convert:: Into < VmmActionError > > ( err : T ) -> ErrorKind {
3218+ let err: VmmActionError = err. into ( ) ;
3219+ err. kind ( ) . clone ( )
3220+ }
3221+
3222+ #[ test]
3223+ fn test_error_conversion ( ) {
3224+ // Test `DriveError` conversion
3225+ assert_eq ! (
3226+ error_kind( DriveError :: CannotOpenBlockDevice ) ,
3227+ ErrorKind :: User
3228+ ) ;
3229+ assert_eq ! (
3230+ error_kind( DriveError :: InvalidBlockDevicePath ) ,
3231+ ErrorKind :: User
3232+ ) ;
3233+ assert_eq ! (
3234+ error_kind( DriveError :: BlockDevicePathAlreadyExists ) ,
3235+ ErrorKind :: User
3236+ ) ;
3237+ assert_eq ! (
3238+ error_kind( DriveError :: BlockDeviceUpdateFailed ) ,
3239+ ErrorKind :: User
3240+ ) ;
3241+ assert_eq ! (
3242+ error_kind( DriveError :: OperationNotAllowedPreBoot ) ,
3243+ ErrorKind :: User
3244+ ) ;
3245+ assert_eq ! (
3246+ error_kind( DriveError :: UpdateNotAllowedPostBoot ) ,
3247+ ErrorKind :: User
3248+ ) ;
3249+ assert_eq ! (
3250+ error_kind( DriveError :: RootBlockDeviceAlreadyAdded ) ,
3251+ ErrorKind :: User
3252+ ) ;
3253+
3254+ // Test `VmConfigError` conversion
3255+ assert_eq ! ( error_kind( VmConfigError :: InvalidVcpuCount ) , ErrorKind :: User ) ;
3256+ assert_eq ! (
3257+ error_kind( VmConfigError :: InvalidMemorySize ) ,
3258+ ErrorKind :: User
3259+ ) ;
3260+ assert_eq ! (
3261+ error_kind( VmConfigError :: UpdateNotAllowedPostBoot ) ,
3262+ ErrorKind :: User
3263+ ) ;
3264+
3265+ // Test `NetworkInterfaceError` conversion
3266+ assert_eq ! (
3267+ error_kind( NetworkInterfaceError :: GuestMacAddressInUse ( String :: new( ) ) ) ,
3268+ ErrorKind :: User
3269+ ) ;
3270+ assert_eq ! (
3271+ error_kind( NetworkInterfaceError :: EpollHandlerNotFound (
3272+ Error :: DeviceEventHandlerNotFound
3273+ ) ) ,
3274+ ErrorKind :: Internal
3275+ ) ;
3276+ assert_eq ! (
3277+ error_kind( NetworkInterfaceError :: HostDeviceNameInUse ( String :: new( ) ) ) ,
3278+ ErrorKind :: User
3279+ ) ;
3280+ assert_eq ! (
3281+ error_kind( NetworkInterfaceError :: DeviceIdNotFound ) ,
3282+ ErrorKind :: User
3283+ ) ;
3284+ // NetworkInterfaceError::OpenTap can be of multiple kinds.
3285+ {
3286+ assert_eq ! (
3287+ error_kind( NetworkInterfaceError :: OpenTap ( TapError :: OpenTun (
3288+ io:: Error :: from_raw_os_error( 0 )
3289+ ) ) ) ,
3290+ ErrorKind :: User
3291+ ) ;
3292+ assert_eq ! (
3293+ error_kind( NetworkInterfaceError :: OpenTap ( TapError :: CreateTap (
3294+ io:: Error :: from_raw_os_error( 0 )
3295+ ) ) ) ,
3296+ ErrorKind :: User
3297+ ) ;
3298+ assert_eq ! (
3299+ error_kind( NetworkInterfaceError :: OpenTap ( TapError :: IoctlError (
3300+ io:: Error :: from_raw_os_error( 0 )
3301+ ) ) ) ,
3302+ ErrorKind :: Internal
3303+ ) ;
3304+ assert_eq ! (
3305+ error_kind( NetworkInterfaceError :: OpenTap ( TapError :: NetUtil (
3306+ net_util:: Error :: CreateSocket ( io:: Error :: from_raw_os_error( 0 ) )
3307+ ) ) ) ,
3308+ ErrorKind :: Internal
3309+ ) ;
3310+ assert_eq ! (
3311+ error_kind( NetworkInterfaceError :: OpenTap ( TapError :: InvalidIfname ) ) ,
3312+ ErrorKind :: User
3313+ ) ;
3314+ }
3315+ assert_eq ! (
3316+ error_kind( NetworkInterfaceError :: RateLimiterUpdateFailed (
3317+ devices:: Error :: FailedReadTap
3318+ ) ) ,
3319+ ErrorKind :: Internal
3320+ ) ;
3321+ assert_eq ! (
3322+ error_kind( NetworkInterfaceError :: UpdateNotAllowedPostBoot ) ,
3323+ ErrorKind :: User
3324+ ) ;
3325+
3326+ // Test `StartMicrovmError` conversion
3327+ #[ cfg( target_arch = "x86_64" ) ]
3328+ assert_eq ! (
3329+ error_kind( StartMicrovmError :: ConfigureSystem (
3330+ arch:: Error :: X86_64Setup ( arch:: x86_64:: Error :: ZeroPageSetup )
3331+ ) ) ,
3332+ ErrorKind :: Internal
3333+ ) ;
3334+ assert_eq ! (
3335+ error_kind( StartMicrovmError :: ConfigureVm (
3336+ vstate:: Error :: NotEnoughMemorySlots
3337+ ) ) ,
3338+ ErrorKind :: Internal
3339+ ) ;
3340+ assert_eq ! (
3341+ error_kind( StartMicrovmError :: CreateBlockDevice (
3342+ io:: Error :: from_raw_os_error( 0 )
3343+ ) ) ,
3344+ ErrorKind :: User
3345+ ) ;
3346+ assert_eq ! (
3347+ error_kind( StartMicrovmError :: CreateNetDevice (
3348+ devices:: virtio:: Error :: TapOpen ( TapError :: CreateTap ( io:: Error :: from_raw_os_error(
3349+ 0
3350+ ) ) )
3351+ ) ) ,
3352+ ErrorKind :: User
3353+ ) ;
3354+ assert_eq ! (
3355+ error_kind( StartMicrovmError :: CreateRateLimiter (
3356+ io:: Error :: from_raw_os_error( 0 )
3357+ ) ) ,
3358+ ErrorKind :: Internal
3359+ ) ;
3360+ #[ cfg( feature = "vsock" ) ]
3361+ assert_eq ! (
3362+ error_kind( StartMicrovmError :: CreateVsockDevice (
3363+ devices:: virtio:: vhost:: Error :: PollError ( io:: Error :: from_raw_os_error( 0 ) )
3364+ ) ) ,
3365+ ErrorKind :: User
3366+ ) ;
3367+ assert_eq ! (
3368+ error_kind( StartMicrovmError :: DeviceManager ) ,
3369+ ErrorKind :: Internal
3370+ ) ;
3371+ assert_eq ! ( error_kind( StartMicrovmError :: EventFd ) , ErrorKind :: Internal ) ;
3372+ assert_eq ! (
3373+ error_kind( StartMicrovmError :: GuestMemory (
3374+ memory_model:: GuestMemoryError :: NoMemoryRegions
3375+ ) ) ,
3376+ ErrorKind :: Internal
3377+ ) ;
3378+ assert_eq ! (
3379+ error_kind( StartMicrovmError :: KernelCmdline ( String :: new( ) ) ) ,
3380+ ErrorKind :: User
3381+ ) ;
3382+ assert_eq ! (
3383+ error_kind( StartMicrovmError :: KernelLoader (
3384+ kernel_loader:: Error :: CommandLineOverflow
3385+ ) ) ,
3386+ ErrorKind :: User
3387+ ) ;
3388+ assert_eq ! (
3389+ error_kind( StartMicrovmError :: LegacyIOBus (
3390+ device_manager:: legacy:: Error :: EventFd ( io:: Error :: from_raw_os_error( 0 ) )
3391+ ) ) ,
3392+ ErrorKind :: Internal
3393+ ) ;
3394+ assert_eq ! (
3395+ error_kind( StartMicrovmError :: LoadCommandline (
3396+ kernel_loader:: Error :: CommandLineOverflow
3397+ ) ) ,
3398+ ErrorKind :: User
3399+ ) ;
3400+ assert_eq ! (
3401+ error_kind( StartMicrovmError :: MicroVMAlreadyRunning ) ,
3402+ ErrorKind :: User
3403+ ) ;
3404+ assert_eq ! (
3405+ error_kind( StartMicrovmError :: MissingKernelConfig ) ,
3406+ ErrorKind :: User
3407+ ) ;
3408+ assert_eq ! (
3409+ error_kind( StartMicrovmError :: NetDeviceNotConfigured ) ,
3410+ ErrorKind :: User
3411+ ) ;
3412+ assert_eq ! (
3413+ error_kind( StartMicrovmError :: OpenBlockDevice (
3414+ io:: Error :: from_raw_os_error( 0 )
3415+ ) ) ,
3416+ ErrorKind :: User
3417+ ) ;
3418+ assert_eq ! (
3419+ error_kind( StartMicrovmError :: RegisterBlockDevice (
3420+ device_manager:: mmio:: Error :: IrqsExhausted
3421+ ) ) ,
3422+ ErrorKind :: Internal
3423+ ) ;
3424+ assert_eq ! (
3425+ error_kind( StartMicrovmError :: RegisterEvent ) ,
3426+ ErrorKind :: Internal
3427+ ) ;
3428+ assert_eq ! (
3429+ error_kind( StartMicrovmError :: RegisterNetDevice (
3430+ device_manager:: mmio:: Error :: IrqsExhausted
3431+ ) ) ,
3432+ ErrorKind :: Internal
3433+ ) ;
3434+ #[ cfg( feature = "vsock" ) ]
3435+ assert_eq ! (
3436+ error_kind( StartMicrovmError :: RegisterVsockDevice (
3437+ device_manager:: mmio:: Error :: IrqsExhausted
3438+ ) ) ,
3439+ ErrorKind :: Internal
3440+ ) ;
3441+ assert_eq ! (
3442+ error_kind( StartMicrovmError :: SeccompFilters (
3443+ seccomp:: Error :: InvalidArgumentNumber
3444+ ) ) ,
3445+ ErrorKind :: Internal
3446+ ) ;
3447+ assert_eq ! (
3448+ error_kind( StartMicrovmError :: Vcpu ( vstate:: Error :: VcpuUnhandledKvmExit ) ) ,
3449+ ErrorKind :: Internal
3450+ ) ;
3451+ assert_eq ! (
3452+ error_kind( StartMicrovmError :: VcpuConfigure (
3453+ vstate:: Error :: SetSupportedCpusFailed ( io:: Error :: from_raw_os_error( 0 ) )
3454+ ) ) ,
3455+ ErrorKind :: Internal
3456+ ) ;
3457+ assert_eq ! (
3458+ error_kind( StartMicrovmError :: VcpusNotConfigured ) ,
3459+ ErrorKind :: User
3460+ ) ;
3461+ assert_eq ! (
3462+ error_kind( StartMicrovmError :: VcpuSpawn ( io:: Error :: from_raw_os_error(
3463+ 0
3464+ ) ) ) ,
3465+ ErrorKind :: Internal
3466+ ) ;
3467+ }
3468+
32063469 #[ test]
32073470 fn test_error_messages ( ) {
32083471 // Enum `Error`
0 commit comments