- Wenn du den Kaffee nicht aufschüttest, läuft er nicht durch
- tar cf file.tar --- "cowardly refusing to create empty archive."
Has saved a lot of archives when typing tar cf instead of tar xf ... - Ever found a good editor for this blog system?
- Why am I the only person unable to create a debugging environment for the AVR32?
Tuesday, July 14, 2009
Wisdoms of the day
Posted by
Seb
um
10:50
0
comments
Monday, July 06, 2009
Using module_param_call for Linux kernel module parameters
My first foray into linux kernel programming – writing a module to drive an external buzzer, using the high resolution timer. Not my first action on the linux kernel, though: http://www.lm-sensors.org/changeset/3613/i2c/trunk
Found a nice feature that is not yet well documented.
ushort enabled =0; module_param(enabled, ushort,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); MODULE_PARM_DESC(enabled, " Enabled or not");
- Defines a module parameter that can be set on insmod
- giving it rights (S_*** equals 0664 aka rw-rw-r-- in this case) allows to set the value via /sys/module/modulename/parameters/parameter for both reading and writing
- Unfortunately, the module is not notified when the value is set.
http://lwn.net/Articles/85443/ only says: “It is worth noting, however, that there is no mechanism for notifying a module that one of its parameters has been changed”.
Well, there is a method. module_param_call. Or rather a macro. It’s hard to find anything about it on the web, the only(?) source currently are the linux kernel source files … especially include/linux/moduleparam.h and kernel/params.c.
static int param_set_buzzer_enabled(const char *val,
struct kernel_param *kp);
unsigned int buzzerenabled = 0;
module_param_call(buzzer_enabled, param_set_buzzer_enabled, param_get_int,
&buzzer_enabled, 0664);
MODULE_PARM_DESC(buzzer_enabled, " Buzzer enabled? default: 1 (yY)");
When the value is queried, the pre-defined method param_get_int is called which directly accesses the (&)buzzer_enabled value. When the value is set, the spezial method param_set_buzzer_enabled is called. Of course, it is also possible to do it another way, e.g., to create a read-only parameter which does not have a variable backing.
The role of the param_set_buzzer_enabled method is best passed to one of the predefined methods – in this case, param_set_bool:
static int param_set_buzzer_enabled(const char *val, struct kernel_param *kp)
{
int hr;
// 1yY 0nN
hr = param_set_bool(val, kp);
if (hr!=0) {
printk("Unable to set buzzer_enabled to value '%s'\n", val);
return hr;
}
// do the job, here ;-)
printk("New value: %d\n", buzzer_enabled);
return 0;
}
val is char*, always – in some cases, special care needs to be taken of trailing newlines produced by "echo 0 > /sys/...". At least some implementations of the conversion routine (using simple_strtol) fail in this case – "echo –n 0" needs to be used, then.
I’d say, far easier to use than defining your own kobject instances, attributes and files, and place them in the appropriate /sys/-folders. By the way – the macro used above, module_param, does nothing else than calling the other one with the correct param_set_##type methods based on the given type (ok, I admin, module_param_named also participates).
Yours,
Sebastian
Posted by
Seb
um
15:40
1 comments
Sunday, March 15, 2009
UPnP via python
Controlling your DSL Router via UPnP
When I was looking for a commandline tool to create port mappings on my broadband/DSL router, I detected the miranda.py script on http://www.sourcesec.com/2008/11/07/miranda-upnp-administration-tool/. I needed some functionality not yet provided by the script, namely, the possibility of passing arguments to host send commands. Usually, the script asks nicely for all required arguments; this is hard to automate. Using the patch provided below, a command such ashost send 0 WANConnectionDevice WANIPConnection AddPortMapping ssh2 0 192.168.32.32 1 22 80.80.80.80 tcp 22is now possible. This also allows bash scripting:
cat <<EOF | miranda.py -s ~/.miranda/struct_data.mir host get 0 host send 0 WANConnectionDevice WANIPConnection AddPortMapping ssh2 0 192.168.32.32 1 22 80.80.80.80 tcp 22 EOFI also fixed a nondescript exception message when no host had yet been loaded/found. Have fun with it,
yours,
Sebastian
--- miranda.py.orig 2009-03-15 13:51:03.000000000 +0100
+++ miranda.py 2009-03-15 13:58:37.000000000 +0100
@@ -1065,11 +1065,15 @@
#Send SOAP requests
index = False
inArgCounter = 0
-
- if argc != 6:
+
+ #sbr: allow to pass arguments to the call
+ numReqArgs = 6
+ if argc < numReqArgs:
showHelp(argv[0])
return
+ # number of arguments in addition to the send cmd
else:
+ extraArgs = argc-numReqArgs
try:
index = int(argv[2])
except:
@@ -1078,7 +1082,12 @@
deviceName = argv[3]
serviceName = argv[4]
actionName = argv[5]
- hostInfo = hp.ENUM_HOSTS[index]
+ try:
+ hostInfo = hp.ENUM_HOSTS[index]
+ except Exception, e:
+ print "You need to discover or load some hosts, first"
+ return
+
actionArgs = False
sendArgs = {}
retTags = []
@@ -1106,11 +1115,18 @@
print "Are you sure you've specified the correct action?"
return False
+ extraArgsUsed = 0
for argName,argVals in actionArgs.iteritems():
actionStateVar = argVals['relatedStateVariable']
stateVar = hostInfo['deviceList'][deviceName]['services'][serviceName]['serviceStateVariables'][actionStateVar]
if argVals['direction'].lower() == 'in':
+ if extraArgs-extraArgsUsed > 0:
+ arg = argv[numReqArgs+extraArgsUsed]
+ print "Using ", arg, " for ", argName
+ sendArgs[argName] = (arg,stateVar['dataType'])
+ extraArgsUsed += 1
+ else:
print "Required argument:"
print "\tArgument Name: ",argName
print "\tData Type: ",stateVar['dataType']
Posted by
Seb
um
14:04
6
comments