Showing posts with label dev. Show all posts
Showing posts with label dev. Show all posts

Monday, 10 January 2011

Counting lines of source code...

It seems easy at firstly sight (wc anyone?) then there's all the awkward stuff like comments, blank lines, coding style, header files, and stuff....

Anyway I came across a nice tool: sloccount which works on Linux, OSX and probably others, which does a good job of estimating "Source Code Line Count (SLOC)". Plus it also spits out coding time estimates based on some heuristics. There are other tools out there of course but this one just seems good.

Thursday, 6 January 2011

Fixing vmxnet for vmwaretools-7.9.9 on Linux-2.6.32+

I just tried to load up vmwaretools on Ubuntu 10.04 Karmic (Kernel linux-2.6.32 - for later kernels see below) and things went ok till it tried to compile vmxnet.c - things have changed and VMware haven't kept up... So I fixed it - see attached patch below. I took a short cut to get the modified file into the vmware-install.pl build process: It copies the src files to a directory in /tmp/vmware-configX/ (where X is a number) - You'll need to run the vmware-install.pl script and then suspend (hit Ctrl-Z) it once it has got to the very first step of compiling vmxnet (ie before it starts the actual compilation) - then copy in the patched file and put the installer into the foreground (type '%'). I guess it's possible to copy it to a tar file somewhere but I didn't bother locating the correct one.

--- vmxnet.c 2011-01-05 17:46:30.820624430 +0000
+++ vmxnet.c.orig 2010-11-20 02:24:48.000000000 +0000
@@ -162,31 +162,6 @@
#define VMXNET_LOG(msg...)
#endif // VMXNET_DEBUG

-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43)
-/*
- *-----------------------------------------------------------------------------
- *
- * vmxnet_tx_timeout --
- *
- * Network device tx_timeout routine. Called by Linux when the tx
- * queue has been stopped for more than dev->watchdog_timeo jiffies.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Tries to restart the transmit queue.
- *
- *-----------------------------------------------------------------------------
- */
-static void
-vmxnet_tx_timeout(struct net_device *dev)
-{
- netif_wake_queue(dev);
-}
-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) */
-
-
/* Data structure used when determining what hardware the driver supports. */

static const struct pci_device_id vmxnet_chips[] =
@@ -210,26 +185,6 @@
.probe = vmxnet_probe_device,
.remove = vmxnet_remove_device,
};
-static struct net_device_ops
-vmxnet_netdev_ops = {
- .ndo_open = vmxnet_open,
- .ndo_start_xmit = vmxnet_start_tx,
- .ndo_stop = vmxnet_close,
- .ndo_get_stats = vmxnet_get_stats,
- .ndo_set_multicast_list = vmxnet_set_multicast_list,
-#ifdef HAVE_CHANGE_MTU
- .ndo_change_mtu = vmxnet_change_mtu,
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43)
- .ndo_tx_timeout = vmxnet_tx_timeout,
-#endif
-#ifdef VMW_HAVE_POLL_CONTROLLER
- .ndo_poll_controller = vmxnet_netpoll,
-#endif
- /* Do this after ether_setup(), which sets the default value. */
- .ndo_set_mac_address = vmxnet_set_mac_address,
-};
-

#ifdef HAVE_CHANGE_MTU
static int
@@ -373,6 +328,8 @@
.set_tso = vmxnet_set_tso,
#endif
};
+
+
#else /* !defined(SET_ETHTOOL_OPS) */


@@ -649,6 +606,30 @@
}


+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43)
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmxnet_tx_timeout --
+ *
+ * Network device tx_timeout routine. Called by Linux when the tx
+ * queue has been stopped for more than dev->watchdog_timeo jiffies.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Tries to restart the transmit queue.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static void
+vmxnet_tx_timeout(struct net_device *dev)
+{
+ netif_wake_queue(dev);
+}
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) */
+

/*
*-----------------------------------------------------------------------------
@@ -1072,9 +1053,25 @@
#endif

dev->irq = irq_line;
+
+ dev->open = &vmxnet_open;
+ dev->hard_start_xmit = &vmxnet_start_tx;
+ dev->stop = &vmxnet_close;
+ dev->get_stats = &vmxnet_get_stats;
+ dev->set_multicast_list = &vmxnet_set_multicast_list;
+#ifdef HAVE_CHANGE_MTU
+ dev->change_mtu = &vmxnet_change_mtu;
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43)
+ dev->tx_timeout = &vmxnet_tx_timeout;
dev->watchdog_timeo = VMXNET_WATCHDOG_TIMEOUT;
+#endif
+#ifdef VMW_HAVE_POLL_CONTROLLER
+ dev->poll_controller = vmxnet_netpoll;
+#endif

- dev->netdev_ops = &vmxnet_netdev_ops;
+ /* Do this after ether_setup(), which sets the default value. */
+ dev->set_mac_address = &vmxnet_set_mac_address;

#ifdef SET_ETHTOOL_OPS
SET_ETHTOOL_OPS(dev, &vmxnet_ethtool_ops);


If you're running linux-2.6.35 (Ubuntu 10.10 Maverick) then you'll also need to apply the following patch (once you've applied the above one):

--- vmxnet.c 2011-01-06 14:44:41.000000000 +0000
+++ vmxnet.c.linux2.6.32 2011-01-06 14:44:41.000000000 +0000
@@ -2405,10 +2405,9 @@
{
struct Vmxnet_Private *lp = netdev_priv(dev);
volatile u16 *mcast_table = (u16 *)lp->dd->LADRF;
- struct netdev_hw_addr_list *mc_list = &dev->mc;
- struct netdev_hw_addr *ha;
+ struct dev_mc_list *dmi = dev->mc_list;
char *addrs;
- int j, bit, byte;
+ int i, j, bit, byte;
u32 crc, poly = CRC_POLYNOMIAL_LE;

/* clear the multicast filter */
@@ -2416,9 +2415,9 @@
lp->dd->LADRF[1] = 0;

/* Add addresses */
-
- netdev_hw_addr_list_for_each(ha, mc_list) {
- addrs = ha->addr;
+ for (i = 0; i < dev->mc_count; i++){
+ addrs = dmi->dmi_addr;
+ dmi = dmi->next;

/* multicast address? */
if (!(*addrs & 1))
@@ -2441,7 +2440,7 @@
crc = crc >> 26;
mcast_table [crc >> 4] |= 1 << (crc & 0xf); } - return mc_list->count;
+ return i;
}

/*

Tuesday, 9 November 2010

What Linux release am I running?

For every Linux distribution/distro there seems to be a different way to work out which release version/name/codename you're running. Here's a the ways I've found, on the command line, to find out:

Ubuntu
lsb_release -a
cat /etc/lsb-release
cat /etc/debian_version
Note: For Ubuntu /etc/debian_version seems to contain the Debian base from which this version of Ubuntu originates.

Debian
cat /etc/debian_version
cat /etc/lsb-release
lsb_release -a
Note: The latter two are not always available on pure Debian systems.

Redhat/CentOS/Fedora
cat /etc/redhat-release

Gentoo
cat /etc/gentoo-release

Building and using a Linux initramfs

If your kernel needs to do 'stuff' during boot up or load modules that aren't compiled into it then an initramfs provides a way (initramfs supersedes the old initrd approach). Basically it is a file (cpio and gzipped) that contains a directory hierarchy containing all the necessary items to provide for loading of modules etc.

To enable the use of the initramfs you'll need to enable the relevant kernel option (e.g. General Setup --> Initial RAM filesystem and RAM disk (initramfs/initrd) support) and them supply the appropriate boot arguments to your boot loader (e.g. append initrd=my-initrd .....). At the very beginning of boot up you should see [on the console] the initrd being loaded (Loading initrd................), then further down it executes the ./init script within the initrd.

To build an initramfs from a suitably populated directory:
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../my-initrd
To check the contents of an initramfs:
gunzip -c my-initrd | cpio -t
To extract the contents of an initramfs into the current directory (you might want to create a temporary directory to unpack it into mkdir initrd.d ; cd initrd.d):
gunzip -c ../my-initrd | cpio -i -d -H newc --no-absolute-filenames

If you've been trying to use an initramfs and you're getting this error on boot up:
Failed to execute /init
Kernel panic - not syncing: No init found.  Try passing init= option to kernel.
Then maybe your ramfs image doesn't contain init, or it's not executable, or you're trying to use a shell within init that incompatible with your kernel's architecture (e.g. trying to use an amd64 arch shell with an i686 kernel).

There's a good Gentoo guide on building them.

On Ubuntu/debian there's a command to build an initrd called mkinitramfs. When running mkinitramfs whilst you can use an alternative config directory, it can only obtain kernel modules from /lib/modules/<kernel_version>. So you can run it using chroot, though its only a shell script so it can of course be tweaked....

Wednesday, 28 July 2010

Where OSX are kernel modules located?

The OSX uses loadable kernel (like BSD and Linux) modules (or kexts) - each one is stored in its own directory (e.g. Dont Steal Mac OS X.kext ) and these are mostly stored in a couple of directories:
/Library/Extensions
/System/Library/Extensions/
Though some others are stored in some other directories (e.g.  /Library/StartupItems/). You can list the currently loaded kernel modules using the kextstat command.

There also some info more info another post of mine on tracking down problem kernel modules in osx.

Wednesday, 14 April 2010

Finally got my Karmic box working properly!

Ever since I upgraded to Karmic (9.10) my machine has performed like a dog - well as far as keyboard and mouse input went - the mouse would linger and the system would loose my keystrokes. I tried a bunch of things to no avail....

Then I was perusing the web - frustrated by my sluggish machine - I'd read about cpu frequency scaling and wondering if this might be an issue. Well it turned out to be the root of my problem! Though in general I think more modern CPU should operate fine with cpu scaling enabled but these old AMD Opteron CPU's don't seem to be up to it so I've disabled it and the machine behaves a lot better.

To fix it - firstly I installed the cpufrequtils:
sudo aptitude install cpufrequtils
Checked the current state of my machine (You can also do it using any of: cat /proc/cpuinfo, sudo dmidecode -t processor, lshw -C processor):
sudo aptitude install cpufreq-info
 My machine was in 'ondemand' mode - I changed it to 'performance' mode - for each of my two processors:
sudo cpufreq-set -c 0 -g performance
sudo cpufreq-set -c 1 -g performance
This is actually setting the following /sys entries: /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor

There a few more things you can do with the cpufreq utils.

Tuesday, 9 March 2010

Making Karmic more responsive...

As previously mentioned, I've run into problems with Karmic (9.10) on my Opteron 246 box. Here ae details of the possible fixes.
  • As mentioned here you can try: Tweaking the Linux kernel scheduler options:

    echo NEW_FAIR_SLEEPERS > /sys/kernel/debug/sched_features
  • Increase nice-ness of X server:

    sudo renice -10 `pidof X`
  • Use the real-time kernel: linux-image-rt
  • Try messing with the kernel swappiness factor - e.g. see here
Not sure which one is any use....will add more I find 'em.

[14apr2010]: I think I've finally found the fix!

Friday, 19 February 2010

unconnect() a UDP socket

So you've got a UDP socket and you've called connect() on it to make it send or listen to a particular IP address, but then you need to disconnect it again, without destroying it. Why would you want to do that?? Well on some OSes (ie Mac OSX, BSD) if you're connected to UDP socket on a machine you can only do that once with the same address (even when you're using the REUSEADDR stuff). So anyway you can disconnect() or unconnect() your socket by the doing the following:
int disconnect_udp_sock(int fd) {
 struct sockaddr_in sin;        

 memset((char *)&sin, 0, sizeof(sin));
 sin.sin_family = AF_UNSPEC;
 return (connect(fd, (struct sockaddr *)&sin, sizeof(sin)));
}
On some OSes you may get a dodgy return value but according to the connect() man page it's ok.

Thursday, 28 January 2010

Mingw and Visual Studio

Mingw is a great environment for building stuff on Windows especially for apps that came from UNIX environments. It provides a gcc compiler for Windows that links directly against the Windows libraries (as opposed to Cygwin that uses an intermediate library to achieve compatibility).

If you're working on projects that combine Mingw and Microsoft's Visual Studio environment (VS2008 etc) then here are a few things that are useful to know:
  • How to get Mingw/Msys to pick up or import VS environment (e.g. for include paths etc):
    • Add the line below (change version of VS if necessary) to C:\MinGW\msys.bat
      • Call "C:/Program Files/Microsoft Visual Studio 9.0/Common7/Tools/vsvars32.bat"
  • How to add other tools to the path for Mingw/Msys (e.g. Collabnet's svn):
    • Add the line below to /etc/profile (within msys) or C:\MinGW\etc\profile:
      • export PATH="/c/Program Files/CollabNet/Subversion Client:$PATH"

Tuesday, 25 August 2009

Interact with other local Linux terminal sessions

If you're interested in trying to control/inject/view other terminal sessions (e.g. with ssh or telnet on a tty or pts) that you/someone is logged into on that machine then read on. Handy for zapping that vi session you left running at work, or playing havoc with something random ;)

It seems that watch does the trick for FreeBSD, but for Linux there's only things like ttysnoop (for linux-2.6) but that requires you modify your /etc/inittab files which is a bore. There's also conspy but that only works with physical terminal devices not ptys, as far as the docs say...

However you can do it without altering anything:
  • See what's being typed (and subsequent output) in another terminal session by using peekfd - you just need to supply the UID of the shell running on that other terminal (find it using ps). Watch out as the output may well contain some 8-bits chars which can confuse your current terminal - though you can get it back to normal using a terminal reset. (e.g. sudo peekfd /dev/pts/27)
  • Inject characters into a terminal by using the TIOCSTI ioctl() with this neat Perl script (copied below). Find the tty of the process you're interested in (e.g. ps axg | grep vi) and use that as the argument to the perl script e.g. echo 'ZZ' | sudo ./catvt.pl /dev/pts/27
  • #!/usr/bin/perl -w
    use strict;
    use Fcntl;
    use constant TIOCSTI => 0x5412;
    
    unless (@ARGV >= 1) {
    print "usage: $0 [vt] <input>\n";
    exit; }
    my $vt = shift @ARGV;
    my $buf = join '', <>;
    &writevt ($vt, $buf) || die "can't write to $vt: $!\n";
    exit;
    
    sub writevt {
    my ($vt, $buf) = @_;
    sysopen (VT, $vt, O_RDONLY) || return 0;
    for (my $i = 0; $i < length $buf; $i++) {
    ioctl (VT, TIOCSTI, substr ($buf, $i, 1)) || return 0; }
    close (VT) || return 0;
    return 1; } 
[updated 6jan10]

Monday, 8 September 2008

Dynamic library dependencies - direct or not?

So you're looking at some (Linux) binary and wondering what libraries it uses - You can use ldd to list all the dependencies:
ldd /path/to/your/app
However this shows direct and indirect (i.e. those needed by other libraries) dependencies, so you can tell what are just the direct dependencies by using readelf:
readelf -d /path/to/your/app
The direct dependencies are the libraries listed as NEEDED.

Wednesday, 19 March 2008

Linking to different versions of a dynamic library

On Linux there's loads of [dynamic ".so"] libraries in places like /usr/lib. The libraries have version numbers; Major version indicates major (API) changes, whilst the minor version typically relates to bug fixes. These version numbers are firstly enshrined with the library using a special symbol (SONAME) - which is assigned on library creation (using the -soname arg to ld). Also libraries are named with their version numbers libsomething.so.2.3. You can verify this using:
objdump -p libsomething.so.2.3* | grep SONAME

So if you're developing and you want to link to specific version what do you do? Well basically there's no neat trick to get the linker (ld) to link a specific version at compile time :( so you can either:
  • Link using the full path to the specific library version
  • Create a softlink/symlink (ending in ".so" - with NO version) to the specific library version
ldconfig does do some stuff related creating links for libraries but as explained here it won't create the plain ".so" necessary for development - these are usually included as part of a "dev" (usually suffixed by "-dev") package on your system (be it Debian or Red Hat or whatever).

Tuesday, 21 August 2007

gcc version switching

So you need something to switch between gcc versions (e.g. 3.4 and 4.1). There's not a generally accepted gcc version switcher out there. It seems that gcc-config is Gentoo specific. On Ubuntu there appears to be a package ccontrol which allows one to switch gcc versions and also control use of distcc, ccache etc. There's one catch though - it seems to bomb when I try it. Oh well - just use export CC=/usr/bin/gcc-3.4 instead.