Project

General

Profile

Actions

Feature #14278

open

report missing major number during driver module install

Added by Ryan Zezeski 10 months ago. Updated 10 months ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
kernel
Start date:
Due date:
% Done:

0%

Estimated time:
Difficulty:
Bite-size
Tags:
Gerrit CR:
External Bug:

Description

Recently while trying to load a module I was getting the following error.

rpz@kalm:~/oxidecomputer/omicron$ pfexec modload /usr/kernel/drv/amd64/viona 
can't load module: No such device or address

Note that I was at first using `modctl -p` like one normally would, but since I was hitting this error I thought perhaps the search path was wrong. Anyways, the real issue wasn't with loading viona, but my own driver module that it now relies upon.

rpz@kalm:~$ pfexec dtrace -Fqn 'mod_load:entry,modinstall:entry,mod_install_requisites:entry,mod_installdrv:entry,ddi_name_to_major:entry { pr[42/895$
"); } mod_load:return,modinstall:return,mod_install_requisites:return,mod_installdrv:return,ddi_name_to_major:return { printf("%s => %d\n", probefunc,
 arg1); } modinstall:entry { print(stringof(args[0]->mod_filename)); } mod_install:entry { print(*((struct modlmisc *)args[0]->ml_linkage[0])->misc_mo
dops) }'                                                                                                                                              
CPU FUNCTION                                                                                                                                          
  0  -> mod_load                                                                                                                                      
  0    -> mod_load                                                                                                                                    
  0    <- mod_load                            mod_load => 0                                                                                           
  0    -> mod_load                                                                                                                                    
  0    <- mod_load                            mod_load => 0                                                                                           
  0    -> mod_load                                                                                                                                    
  0    <- mod_load                            mod_load => 0                                                                                           
  0    -> mod_load                                                                                                                                    
  0    <- mod_load                            mod_load => 0                                                                                           
  0    -> mod_load                                                                                                                                    
  0    <- mod_load                            mod_load => 0     
  0    -> mod_load                                           
  0    <- mod_load                            mod_load => 0                                                                                           
  0    -> mod_load                                               
  0    <- mod_load                            mod_load => 0  
  5  <- mod_load                              mod_load => 0              
 5  -> modinstall                             
  5   | modinstall:entry                      string "/usr/kernel/drv/amd64/viona" 
  5    -> mod_install_requisites               
  5      -> modinstall                         
  5       | modinstall:entry                  string "misc/dls" 
  5      <- modinstall                        modinstall => 0
  5      -> modinstall                         
  5       | modinstall:entry                  string "misc/mac" 
  5      <- modinstall                        modinstall => 0
  5      -> modinstall                         
  5       | modinstall:entry                  string "drv/dld" 
  5      <- modinstall                        modinstall => 0
  5      -> modinstall                         
  5       | modinstall:entry                  string "misc/hook" 
  5      <- modinstall                        modinstall => 0
  5      -> modinstall                         
  5       | modinstall:entry                  string "misc/neti" 
  5      <- modinstall                        modinstall => 0
  5      -> modinstall                         
  5       | modinstall:entry                  string "drv/vmm" 
  5      <- modinstall                        modinstall => 0
  5      -> modinstall                         
  5       | modinstall:entry                  string "drv/opte" 
  5        -> mod_install_requisites           
  5          -> modinstall                     
  5           | modinstall:entry              string "misc/mac" 
  5          <- modinstall                    modinstall => 0
  5        <- mod_install_requisites          mod_install_requisites => 0
  5        -> mod_install                     struct mod_ops {
    int (*)() modm_install = genunix`mod_installdrv
    int (*)() modm_remove = genunix`mod_removedrv
    int (*)() modm_info = genunix`mod_infodrv
}  5          -> mod_installdrv                 
  5            -> ddi_name_to_major            
  5            <- ddi_name_to_major           ddi_name_to_major => 4294967295
  5          <- mod_installdrv                mod_installdrv => 6
  5        <- modinstall                      modinstall => 6
  5      <- mod_install_requisites            mod_install_requisites => 6
  5    <- modinstall                          modinstall => 6

A further delve into mod_installdrv() shows the following code:

    /* Sanity check modname */
    if ((major = ddi_name_to_major(modname)) == DDI_MAJOR_T_NONE) {
#ifdef DEBUG
        cmn_err(CE_WARN,
            "mod_installdrv: no major number for %s", modname);
#endif
        err = ENXIO;
        goto done;
    }

Sure enough, dtrace reveals this is coming back as none.

rpz@kalm:~$ pfexec dtrace -qn 'ddi_name_to_major:entry /stringof(arg0) == "opte"/ { printf("%s ", stringof(arg0)); self->t = 1; } ddi_name_to_major:return /self->t/ { printf("=> %d\n", (int)arg1); }'
opte => -1

It took me a while to dig through all this to figure out what was going on. However, the helpful error message hidden behind DEBUG would have saved me A LOT of time as the first thing I did was check the system log. I see no reason to hide that message behind DEBUG, especially when the user-visible error message gives no real idea as to what is failing.

Now, as for why the major number is missing, I'm not 100% sure yet. I installed the driver, and it has an entry in /etc/name_to_major. Figuring that mystery out is next on the agenda.

Actions #1

Updated by Electric Monk 10 months ago

  • Gerrit CR set to 1837
Actions

Also available in: Atom PDF