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

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

448
449
450
451
452
453
454

455
456
457
458
459
460
461
462
463
464
465
466
	return(TCL_OK);
}

static int tuapi_insmod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
	Tcl_Channel fd;
	Tcl_Obj *module_filename, *module_data;
	void *module_data_val;

	int module_data_len;
	int read_ret, chk_ret;

	if (objc < 2) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"tuapi::syscall::insmod filename ?args ...?\"", -1));

		return(TCL_ERROR);
	}

	module_filename = objv[1];

	fd = Tcl_FSOpenFileChannel(interp, module_filename, "r", 0600);







>



|
|







448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
	return(TCL_OK);
}

static int tuapi_insmod(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
	Tcl_Channel fd;
	Tcl_Obj *module_filename, *module_data;
	void *module_data_val;
	const char *module_opts;
	int module_data_len;
	int read_ret, chk_ret;

	if (objc < 2 || objc > 3) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"tuapi::syscall::insmod filename ?args?\"", -1));

		return(TCL_ERROR);
	}

	module_filename = objv[1];

	fd = Tcl_FSOpenFileChannel(interp, module_filename, "r", 0600);
485
486
487
488
489
490
491






492
493
494
495
496
497
498
499
		Tcl_SetObjResult(interp, Tcl_NewStringObj("read failed", -1));

		return(TCL_ERROR);
	}

	module_data_val = Tcl_GetByteArrayFromObj(module_data, &module_data_len);







	chk_ret = init_module(module_data_val, module_data_len, "");
	if (chk_ret != 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));

		return(TCL_ERROR);
	}

	return(TCL_OK);







>
>
>
>
>
>
|







486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
		Tcl_SetObjResult(interp, Tcl_NewStringObj("read failed", -1));

		return(TCL_ERROR);
	}

	module_data_val = Tcl_GetByteArrayFromObj(module_data, &module_data_len);

	if (objc == 3) {
		module_opts = Tcl_GetString(objv[2]);
	} else {
		module_opts = "";
	}

	chk_ret = init_module(module_data_val, module_data_len, module_opts);
	if (chk_ret != 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));

		return(TCL_ERROR);
	}

	return(TCL_OK);

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

315
316
317
318
319
320
321

322









323
324
325
326



327
328
329
330
331
332
333
	}
}

proc ::tuapi::modprobe args {
	# Process arguments
	set options(call_insmod) 1
	set idx 0

	foreach arg $args {









		switch -- $arg {
			"-dontload" {
				set options(call_insmod) 0
			}



			"--" {
				incr idx
				break
			}
			default {
				break
			}







>

>
>
>
>
>
>
>
>
>




>
>
>







315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
	}
}

proc ::tuapi::modprobe args {
	# Process arguments
	set options(call_insmod) 1
	set idx 0
	set nextIsArgs 0
	foreach arg $args {
		if {$nextIsArgs} {
			set options(args) $arg

			set nextIsArgs 0

			incr idx
			continue
		}

		switch -- $arg {
			"-dontload" {
				set options(call_insmod) 0
			}
			"-args" {
				set nextIsArgs 1
			}
			"--" {
				incr idx
				break
			}
			default {
				break
			}
402
403
404
405
406
407
408

409
410
411




















































412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456






457
458



459

460
461
462
463
464
465
466
467
468
469
470
471
472
473
		set ::tuapi::cache::module2deps [array get module2deps]
	} else {
		array set alias2module $::tuapi::cache::alias2module
		array set alias2module_wildcards $::tuapi::cache::alias2module_wildcards
		array set module2deps $::::tuapi::cache::module2deps
	}


	# Load modules
	foreach modules $args {
		foreach module $modules {




















































			# If the module is given as an absolute path, ignore the path
			# and process just as we would if the name were given alone
			# This may be wrong, but otherwise dependency matching would
			# be harder
			if {[string index $module 0] == "/" && [file exists $module]} {
				set module [file rootname [file tail $module]]
			}

			for {set try 0} {$try < 100} {incr try} {
				if {![info exists alias2module($module)]} {
					# If no exact match found, process wildcard entries
					set found_wildcard_match 0
					foreach alias [array name alias2module_wildcards] {
						if {[string match $alias $module]} {
							set module $alias2module_wildcards($alias)

							set found_wildcard_match 1

							break
						}
					}

					if {!$found_wildcard_match} {
						break
					}
				}

				set module $alias2module($module)
			}

			if {[info exists module2deps($module)]} {
				set load $module2deps($module)
			} else {
				set load [list]
			}

			lappend load $module

			foreach module $load {
				if {[string match "/dev/*" $module]} {
					return -code error "Unable to lookup device node module for $module"
				}

				set module [file join $modules_dir $module]







				if {$options(call_insmod)} {
					if {[catch {



						::tuapi::syscall::insmod $module

					}]} {
						continue
					}
				}

				lappend retval $module
			}
		}
	}

	return $retval
}

# Scan the various buses attached to the system and load the appropriate







>
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|

|
|
|

|
|
|
|

|
|

|
|
|
|
|

|

|
|
|
|

|

>
>
>
>
>
>
|
|
>
>
>

>
|
|
|
|

|
<







415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541

542
543
544
545
546
547
548
		set ::tuapi::cache::module2deps [array get module2deps]
	} else {
		array set alias2module $::tuapi::cache::alias2module
		array set alias2module_wildcards $::tuapi::cache::alias2module_wildcards
		array set module2deps $::::tuapi::cache::module2deps
	}

	# Determine list of modules
	set all_modules [list]
	foreach modules $args {
		foreach module $modules {
			lappend all_modules $module
		}
	}

	# Determine what modules to add the arguments to
	if {[info exists options(args)]} {
		foreach arg [split $options(args) " "] {
			if {$arg == ""} {
				continue
			}

			if {[string match "*=*" $arg]} {
				set work [split $arg =]

				set name [lindex $work 0]
				set value [join [lrange $work 1 end] =]
			} else {
				set name $arg
				unset -nocomplain value
			}

			if {[string match "*.*" $name]} {
				set work [split $name .]

				set module [lindex $work 0]
				if {$module == ""} {
					set modules [list]
				} else {
					set modules [list $module]
				}

				set name [join [lrange $work 1 end] .]
			} else {
				set modules [list]
			}

			if {[llength $modules] == 0} {
				set modules $all_modules
			}

			foreach module $modules {
				if {[info exists value]} {
					append modules_args($module) "$name=$value "
				} else {
					append modules_args($module) "$name "
				}
			}
		}
	}

	# Load modules
	foreach module $all_modules {
		# If the module is given as an absolute path, ignore the path
		# and process just as we would if the name were given alone
		# This may be wrong, but otherwise dependency matching would
		# be harder
		if {[string index $module 0] == "/" && [file exists $module]} {
			set module [file rootname [file tail $module]]
		}

		for {set try 0} {$try < 100} {incr try} {
			if {![info exists alias2module($module)]} {
				# If no exact match found, process wildcard entries
				set found_wildcard_match 0
				foreach alias [array name alias2module_wildcards] {
					if {[string match $alias $module]} {
						set module $alias2module_wildcards($alias)

						set found_wildcard_match 1

						break
					}
				}

				if {!$found_wildcard_match} {
					break
				}
			}

			set module $alias2module($module)
		}

		if {[info exists module2deps($module)]} {
			set load $module2deps($module)
		} else {
			set load [list]
		}

		lappend load $module

		foreach module $load {
			if {[string match "/dev/*" $module]} {
				return -code error "Unable to lookup device node module for $module"
			}

			set module [file join $modules_dir $module]

			unset -nocomplain module_args
			set module_short [file rootname [file tail $module]]
			if {[info exists modules_args($module_short)]} {
				set module_args [string trim $modules_args($module_short)]
			}

			if {$options(call_insmod)} {
				if {[catch {
					if {[info exists module_args]} {
						::tuapi::syscall::insmod $module $module_args
					} else {
						::tuapi::syscall::insmod $module
					}
				}]} {
					continue
				}
			}

			lappend retval $module

		}
	}

	return $retval
}

# Scan the various buses attached to the system and load the appropriate