Check-in [70b183f4c0]
Overview
SHA1:70b183f4c0dc451eb45b5c773fd698f5f4405706
Date: 2014-12-22 18:13:37
User: rkeene
Comment:Added support for passing arguments to kernel modules
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | folders | manifest
Tags And Properties
Context
2014-12-22
18:31
[2d04941e48] Updated to try to make scanning smarter (user: rkeene, tags: trunk)
18:13
[70b183f4c0] Added support for passing arguments to kernel modules (user: rkeene, tags: trunk)
2014-12-20
06:47
[77c233b2a4] Fixed typo causing tuapi loading to fail (user: rkeene, tags: trunk)
Changes

Modified tuapi.c from [d5c20667b1] to [2fd850bfb1].

   448    448   	return(TCL_OK);
   449    449   }
   450    450   
   451    451   static int tuapi_insmod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
   452    452   	Tcl_Channel fd;
   453    453   	Tcl_Obj *module_filename, *module_data;
   454    454   	void *module_data_val;
          455  +	const char *module_opts;
   455    456   	int module_data_len;
   456    457   	int read_ret, chk_ret;
   457    458   
   458         -	if (objc < 2) {
   459         -		Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"tuapi::syscall::insmod filename ?args ...?\"", -1));
          459  +	if (objc < 2 || objc > 3) {
          460  +		Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"tuapi::syscall::insmod filename ?args?\"", -1));
   460    461   
   461    462   		return(TCL_ERROR);
   462    463   	}
   463    464   
   464    465   	module_filename = objv[1];
   465    466   
   466    467   	fd = Tcl_FSOpenFileChannel(interp, module_filename, "r", 0600);
................................................................................
   485    486   		Tcl_SetObjResult(interp, Tcl_NewStringObj("read failed", -1));
   486    487   
   487    488   		return(TCL_ERROR);
   488    489   	}
   489    490   
   490    491   	module_data_val = Tcl_GetByteArrayFromObj(module_data, &module_data_len);
   491    492   
   492         -	chk_ret = init_module(module_data_val, module_data_len, "");
          493  +	if (objc == 3) {
          494  +		module_opts = Tcl_GetString(objv[2]);
          495  +	} else {
          496  +		module_opts = "";
          497  +	}
          498  +
          499  +	chk_ret = init_module(module_data_val, module_data_len, module_opts);
   493    500   	if (chk_ret != 0) {
   494    501   		Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));
   495    502   
   496    503   		return(TCL_ERROR);
   497    504   	}
   498    505   
   499    506   	return(TCL_OK);

Modified tuapi.tcl from [d7c3601a8e] to [859e0dd2e7].

   315    315   	}
   316    316   }
   317    317   
   318    318   proc ::tuapi::modprobe args {
   319    319   	# Process arguments
   320    320   	set options(call_insmod) 1
   321    321   	set idx 0
          322  +	set nextIsArgs 0
   322    323   	foreach arg $args {
          324  +		if {$nextIsArgs} {
          325  +			set options(args) $arg
          326  +
          327  +			set nextIsArgs 0
          328  +
          329  +			incr idx
          330  +			continue
          331  +		}
          332  +
   323    333   		switch -- $arg {
   324    334   			"-dontload" {
   325    335   				set options(call_insmod) 0
   326    336   			}
          337  +			"-args" {
          338  +				set nextIsArgs 1
          339  +			}
   327    340   			"--" {
   328    341   				incr idx
   329    342   				break
   330    343   			}
   331    344   			default {
   332    345   				break
   333    346   			}
................................................................................
   402    415   		set ::tuapi::cache::module2deps [array get module2deps]
   403    416   	} else {
   404    417   		array set alias2module $::tuapi::cache::alias2module
   405    418   		array set alias2module_wildcards $::tuapi::cache::alias2module_wildcards
   406    419   		array set module2deps $::::tuapi::cache::module2deps
   407    420   	}
   408    421   
   409         -	# Load modules
          422  +	# Determine list of modules
          423  +	set all_modules [list]
   410    424   	foreach modules $args {
   411    425   		foreach module $modules {
   412         -			# If the module is given as an absolute path, ignore the path
   413         -			# and process just as we would if the name were given alone
   414         -			# This may be wrong, but otherwise dependency matching would
   415         -			# be harder
   416         -			if {[string index $module 0] == "/" && [file exists $module]} {
   417         -				set module [file rootname [file tail $module]]
   418         -			}
   419         -
   420         -			for {set try 0} {$try < 100} {incr try} {
   421         -				if {![info exists alias2module($module)]} {
   422         -					# If no exact match found, process wildcard entries
   423         -					set found_wildcard_match 0
   424         -					foreach alias [array name alias2module_wildcards] {
   425         -						if {[string match $alias $module]} {
   426         -							set module $alias2module_wildcards($alias)
   427         -
   428         -							set found_wildcard_match 1
   429         -
   430         -							break
   431         -						}
   432         -					}
   433         -
   434         -					if {!$found_wildcard_match} {
          426  +			lappend all_modules $module
          427  +		}
          428  +	}
          429  +
          430  +	# Determine what modules to add the arguments to
          431  +	if {[info exists options(args)]} {
          432  +		foreach arg [split $options(args) " "] {
          433  +			if {$arg == ""} {
          434  +				continue
          435  +			}
          436  +
          437  +			if {[string match "*=*" $arg]} {
          438  +				set work [split $arg =]
          439  +
          440  +				set name [lindex $work 0]
          441  +				set value [join [lrange $work 1 end] =]
          442  +			} else {
          443  +				set name $arg
          444  +				unset -nocomplain value
          445  +			}
          446  +
          447  +			if {[string match "*.*" $name]} {
          448  +				set work [split $name .]
          449  +
          450  +				set module [lindex $work 0]
          451  +				if {$module == ""} {
          452  +					set modules [list]
          453  +				} else {
          454  +					set modules [list $module]
          455  +				}
          456  +
          457  +				set name [join [lrange $work 1 end] .]
          458  +			} else {
          459  +				set modules [list]
          460  +			}
          461  +
          462  +			if {[llength $modules] == 0} {
          463  +				set modules $all_modules
          464  +			}
          465  +
          466  +			foreach module $modules {
          467  +				if {[info exists value]} {
          468  +					append modules_args($module) "$name=$value "
          469  +				} else {
          470  +					append modules_args($module) "$name "
          471  +				}
          472  +			}
          473  +		}
          474  +	}
          475  +
          476  +	# Load modules
          477  +	foreach module $all_modules {
          478  +		# If the module is given as an absolute path, ignore the path
          479  +		# and process just as we would if the name were given alone
          480  +		# This may be wrong, but otherwise dependency matching would
          481  +		# be harder
          482  +		if {[string index $module 0] == "/" && [file exists $module]} {
          483  +			set module [file rootname [file tail $module]]
          484  +		}
          485  +
          486  +		for {set try 0} {$try < 100} {incr try} {
          487  +			if {![info exists alias2module($module)]} {
          488  +				# If no exact match found, process wildcard entries
          489  +				set found_wildcard_match 0
          490  +				foreach alias [array name alias2module_wildcards] {
          491  +					if {[string match $alias $module]} {
          492  +						set module $alias2module_wildcards($alias)
          493  +
          494  +						set found_wildcard_match 1
          495  +
   435    496   						break
   436    497   					}
   437    498   				}
   438    499   
   439         -				set module $alias2module($module)
   440         -			}
   441         -
   442         -			if {[info exists module2deps($module)]} {
   443         -				set load $module2deps($module)
   444         -			} else {
   445         -				set load [list]
   446         -			}
   447         -
   448         -			lappend load $module
   449         -
   450         -			foreach module $load {
   451         -				if {[string match "/dev/*" $module]} {
   452         -					return -code error "Unable to lookup device node module for $module"
   453         -				}
   454         -
   455         -				set module [file join $modules_dir $module]
   456         -
   457         -				if {$options(call_insmod)} {
   458         -					if {[catch {
          500  +				if {!$found_wildcard_match} {
          501  +					break
          502  +				}
          503  +			}
          504  +
          505  +			set module $alias2module($module)
          506  +		}
          507  +
          508  +		if {[info exists module2deps($module)]} {
          509  +			set load $module2deps($module)
          510  +		} else {
          511  +			set load [list]
          512  +		}
          513  +
          514  +		lappend load $module
          515  +
          516  +		foreach module $load {
          517  +			if {[string match "/dev/*" $module]} {
          518  +				return -code error "Unable to lookup device node module for $module"
          519  +			}
          520  +
          521  +			set module [file join $modules_dir $module]
          522  +
          523  +			unset -nocomplain module_args
          524  +			set module_short [file rootname [file tail $module]]
          525  +			if {[info exists modules_args($module_short)]} {
          526  +				set module_args [string trim $modules_args($module_short)]
          527  +			}
          528  +
          529  +			if {$options(call_insmod)} {
          530  +				if {[catch {
          531  +					if {[info exists module_args]} {
          532  +						::tuapi::syscall::insmod $module $module_args
          533  +					} else {
   459    534   						::tuapi::syscall::insmod $module
   460         -					}]} {
   461         -						continue
   462    535   					}
          536  +				}]} {
          537  +					continue
   463    538   				}
          539  +			}
   464    540   
   465         -				lappend retval $module
   466         -			}
          541  +			lappend retval $module
   467    542   		}
   468    543   	}
   469    544   
   470    545   	return $retval
   471    546   }
   472    547   
   473    548   # Scan the various buses attached to the system and load the appropriate