Dienstag, 18. Dezember 2007

struct "has no member named first"

Hey,
you see this error message from gcc?
It is defined as a function in include/linux/list.h, line 37.
It is a good idea to look at the linux kernel list implementation:
good examples are:
http://isis.poly.edu/kulesh/stuff/src/klist/ or
http://kernelnewbies.org/FAQ/LinkedLists.

Or you simple tried the hlist_node to be hlist_head.

Montag, 17. Dezember 2007

Kernel source code browsing

Hey,
a quick guide for browsing source code with Vi editor.
At first we need: source code (e.g. kernel-source), the vim editor, ctags (tool for generating tag files) and cscope (tool for browsing C code). This packages are all included in the OpenSUSE 10.3.

Next you need to index all files which should be browse able later, do it with 'find | grep "\.c$\|\.h$" > cscope.files' (of course in the top of your source code directory).

After this you have to build the cscope database, with "cscope -b" (for recursive build, start it in the top directory of your source code).
Afterwards build the tag database with "ctags -L cscope.files" (this is needed for code completion).

Next is to tell vim about it: do this with adding the support (key-bindings) in your vimrc. Download this vim_rc and append it to your vimrc (mostly $HOME/.vimrc). After this, the ctag/cscope key support should be enabled (of course a vi restart is needed).

Ctrl-']' brings you the definition, Ctrl-t brings you back.

The key binding is: (all with CTRL-'\'-'key'):
's' (symbol) find all references to the token under cursor
'g' (global) find global definition(s) of the token under cursor
'c' (calls) find all calls to the function name under cursor
't' (text) find all instances of the text under cursor
'e' (egrep) egrep search for the word under cursor
'f' (file) open the filename under cursor
'i' (includes) find files that include the filename under cursor
'd' (called) find functions that function under cursor calls

So hope this helps.

Mittwoch, 12. Dezember 2007

Connect two virtual machines within Vmware with serial line

Hey,
I recently triggered a problem in Vmware (version 1.0.3, Linux), that it is not possible to use the given "Virtual Machine Settings" -> "Use named pipe" -> "The other end is a virtual machine" feature. There was no serial communication between my two OpenSUSE 10.3 test machines. To workaround this I used the socat tool. With socat unix-connect:./pipe unix-connect:/mnt/vmware-machines/Virtual\ Machines/SUSE\ Linux/pipe it was possible to get the serial communication working. Although Vmware says that it creates a pipe, it is represented as a unix socket. Before setting up the socat proxy, you should configure the serial ports in the virtual machines. Doing this via "Virtual Machine Settings" (right-click in the right bottom of the Window) -> "Use named pipe" -> Enter a name for the named pipe, configure "This end is the server" and important the last option, configure "The other end is an application". After setting this for me a reboot is needed. After reboot your choosen filename is created and available for socat connect.

A nice step for debugging, is "socat unix-connect:./pipe stdout".

Some hint from me, if you see a flooding on the serial line, you probably have enabled the shell with login prompt on both serial lines, so the are trying to login each other :-) .

Freitag, 7. Dezember 2007

VMware fuzzy?!

Hey there,
for the moment I wanted to use the VMware server version 1.0.3 (from 4/26/07, Build 44356) for Linux. And it goes woooh with OpenSUSE 10.3 (x86_64):


Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config1/vmnet-only'
make -C /lib/modules/2.6.22.5-31-default/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-2.6.22.5-31'
CC [M] /tmp/vmware-config1/vmnet-only/driver.o
CC [M] /tmp/vmware-config1/vmnet-only/hub.o
CC [M] /tmp/vmware-config1/vmnet-only/userif.o
/tmp/vmware-config1/vmnet-only/userif.c: In function ‘VNetCopyDatagramToUser’:
/tmp/vmware-config1/vmnet-only/userif.c:630: error: ‘const struct sk_buff’ has no member named ‘h’
/tmp/vmware-config1/vmnet-only/userif.c:630: error: ‘const struct sk_buff’ has no member named ‘nh’
/tmp/vmware-config1/vmnet-only/userif.c:636: error: ‘const struct sk_buff’ has no member named ‘h’
make[2]: *** [/tmp/vmware-config1/vmnet-only/userif.o] Error 1
make[1]: *** [_module_/tmp/vmware-config1/vmnet-only] Error 2
make[1]: Leaving directory `/usr/src/linux-2.6.22.5-31'
make: *** [vmnet.ko] Error 2
make: Leaving directory `/tmp/vmware-config1/vmnet-only'
Unable to build the vmnet module.


Interesting, because in /usr/src/linux/include/linux/skbuff.h is sk_buff defined h as head, so you need to substitute "h" to "head" and "nh" to "network_header" :).

But the story goes on, this error happens in userif.c in you can go on bridge.c ...

By the way the working directory is /usr/lib/vmware/, the interesting archive is: /usr/lib/vmware/modules/source/vmnet.tar . This one you extract with "tar xf vmnet.tar", a directory vmnet-only is created, within the broken files (broken == using wrong skh definition). After the editing of the files (userif.c, bridge.c ...) pack it back with "tar cvf vmnet.tar vmnet-only".


Ok here is a patch which makes the VMware build (but this one has a lot of Warnings), I#m not sure if it hurts stability, so you're on you own.


diff -urN vmnet-only/bridge.c /usr/lib/vmware/modules/source/vmnet-only/bridge.c
--- vmnet-only/bridge.c 2007-04-13 05:24:10.000000000 +0200
+++ /usr/lib/vmware/modules/source/vmnet-only/bridge.c 2007-12-07 23:55:38.000000000 +0100
@@ -1083,12 +1083,12 @@
VNetBridgeComputeHeaderPos(struct sk_buff *skb) // IN: buffer to examine
{
/* Maybe some kernel gets it right... */
- if (skb->h.raw != skb->nh.raw) {
+ if (skb->head != skb->network_header) {
return;
}
switch (be16_to_cpu(skb->protocol)) {
case ETH_P_IP:
- skb->h.raw = skb->nh.raw + (skb->nh.raw[0] & 0x0F) * 4;
+ *(skb->head) = skb->network_header + (skb->network_header & 0x0F) * 4;
return;
default:
LOG(3, (KERN_DEBUG "Unknown EII protocol %04X: csum at %d\n",
@@ -1370,7 +1370,7 @@
# endif

if (bridge->smac) {
- if (VNetCallSMACFunc(bridge->smac, &skb, skb->mac.raw,
+ if (VNetCallSMACFunc(bridge->smac, &skb, skb->mac_header,
SMAC_CheckPacketFromHost) !=
PacketStatusForwardPacket) {
LOG(4, (KERN_NOTICE "bridge-%s: packet dropped .\n",
@@ -1392,7 +1392,7 @@
#endif
#endif

- skb_push(skb, skb->data - skb->mac.raw);
+ skb_push(skb, skb->data - skb->mac_header);
LOG(3, (KERN_DEBUG "bridge-%s: receive %d\n",
bridge->name, (int) skb->len));
if (VNetBridgeIsGSO(skb)) {
diff -urN vmnet-only/userif.c /usr/lib/vmware/modules/source/vmnet-only/userif.c
--- vmnet-only/userif.c 2007-04-13 05:24:10.000000000 +0200
+++ /usr/lib/vmware/modules/source/vmnet-only/userif.c 2007-12-07 23:49:33.000000000 +0100
@@ -627,13 +627,13 @@
*/
if (skb->pkt_type == PACKET_OUTGOING && /* Packet must be outgoing */
skb->ip_summed == VM_CHECKSUM_PARTIAL && /* Without checksum */
- skb->h.raw != skb->nh.raw && /* We must know where header is */
+ (sk_buff_data_t)(skb->head) != (sk_buff_data_t)(skb->network_header) && /* We must know where header is */
skb->len == count) { /* No truncation may occur */
size_t skl;
int csum;
u_int16_t csum16;

- skl = skb->h.raw - skb->data;
+ skl = skb->head - skb->data;
if (VNetCopyDatagram(skb, buf, skl)) {
return -EFAULT;
}
diff -urN vmnet-only/vnetInt.h /usr/lib/vmware/modules/source/vmnet-only/vnetInt.h
--- vmnet-only/vnetInt.h 2007-04-13 05:24:10.000000000 +0200
+++ /usr/lib/vmware/modules/source/vmnet-only/vnetInt.h 2007-12-07 23:40:48.000000000 +0100
@@ -25,8 +25,8 @@
#define DEV_QUEUE_XMIT(skb, dev, pri) ( \
(skb)->dev = (dev), \
(skb)->priority = (pri), \
- (skb)->mac.raw = (skb)->data, \
- (skb)->nh.raw = (skb)->data + sizeof (struct ethhdr), \
+ (skb)->mac_header = (skb)->data, \
+ (skb)->network_header = (skb)->data + sizeof (struct ethhdr), \
dev_queue_xmit(skb) \
)
#ifdef KERNEL_2_3_15

If you have better solution, let me know. I'm going to make it a better patch, which should fix some nasty warnings as

CC [M] /tmp/vmware-config13/vmnet-only/netif.o
CC [M] /tmp/vmware-config13/vmnet-only/bridge.o
/tmp/vmware-config13/vmnet-only/bridge.c: In function ‘VNetBridgeReceiveFromVNet’:
/tmp/vmware-config13/vmnet-only/bridge.c:568: warning: assignment makes integer from pointer without a cast
/tmp/vmware-config13/vmnet-only/bridge.c:568: warning: assignment makes integer from pointer without a cast
/tmp/vmware-config13/vmnet-only/bridge.c: In function ‘VNetBridgeComputeHeaderPos’:
/tmp/vmware-config13/vmnet-only/bridge.c:1086: warning: comparison between pointer and integer
/tmp/vmware-config13/vmnet-only/bridge.c: In function ‘VNetBridgeReceiveFromDev’:
/tmp/vmware-config13/vmnet-only/bridge.c:1374: warning: passing argument 3 of ‘VNetCallSMACFunc’ makes pointer from integer without a cast
/tmp/vmware-config13/vmnet-only/bridge.c:1395: warning: passing argument 2 of ‘skb_push’ makes integer from pointer without a cast


That's all, hopefully VMware tests it software the next time :).