home / blog

LVM hackery

Problem. Need to resize a LVM partition inside a Linux RHEL5 VM ware image.

Constraints. A environment where lvresize does not support online resizing. No access to a rescue disk.

First. Add the disk image to another VM image in VM player. Now startup. We can see both volumes.

vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "VolGroup00" using metadata type lvm2
  Found volume group "VolGroup00" using metadata type lvm2

Problem. We cannot address the volumes separately because they have the same name…

# Fix naming conflict, find UUIDs with vgdisplay
vgdisplay

# rename non-mounted one
vgrename abcdef-abcd-abcd-abcd-abcd-abcd-abcdef VolGroupXX

# check
vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "VolGroupXX" using metadata type lvm2
  Found volume group "VolGroup00" using metadata type lvm2

# activate
vgchange -a y
  2 logical volume(s) in volume group "VolGroupXX" now active
  2 logical volume(s) in volume group "VolGroup00" now active

Now we can resize the “guest” disk.

# resize, check first
e2fsck -f /dev/mapper/VolGroupXX-LogVol00

# resize
resize2fs /dev/mapper/VolGroupXX-LogVol00 20G

# check
mkdir m
mount /dev/mapper/VolGroupXX-LogVol00 m
df -h m

Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroupXX-LogVol00
                       20G   14G  4.8G  75% /root/m

# deactivate
umount m
vgchange -a n

Now it gets interesting… We cannot boot the VM image, this is because the boot disk has references to VolGroup00 and we renamed it to VolGroupXX. Unfortunately vgrename prevents renaming to conflicting names.

A solution: Mount the /boot partition. Extract the root disk image, edit, and repack.

sudo su

# access guest boot
mkdir boot
mount /dev/sdb1 boot

# extract
mkdir tmp
cd tmp
gzip -dc ../boot/initrd-2.6.18-53.el5.img | cpio -id

# edit - with your favourite UNIX text editor, replace VolGroup00 with VolGroupXX
emacs -nw init

# repack and replace
find ./ | cpio -H newc -o > ../boot/initrd-2.6.18-53.el5.img.cpio
gzip -c ../boot/initrd-2.6.18-53.el5.img.cpio > ../boot/initrd-2.6.18-53.el5.img

# unmount
umount ../boot
Posted in geek | Tagged , | Leave a comment

Disabling open office registration wizard GOTCHA

There’s a hell of a gotcha with the offical guide to disabling the first-time registration dialog in openoffice 3.3.0. The reference from the META-INF/manifest.xml to the file setup.xcu is broken, because the file in DisableFirstStartWzd_ooo33.oxt is Setup.xcu with a capital S. This will work fine under Windows/NTFS/FAT, but NOT under UNIX systems like Linux, OS X which are traditionally case sensitive.

The fix is simple: Just make the manifest.xml and filenames match exactly in terms of case.

Unfortunately the unopkg tool does not validate this, so the fault is silently ignored and you still get the first-time registration dialog.

Posted in geek | Tagged | Leave a comment

Tomcat7 server in eclipse with ubuntu

Annoyingly there isn’t one “installation directory” for tomcat on ubuntu, instead it is spread across /var/log, /usr/share /var/lib etc. Eclipse expects one directory with log, conf etc. This can be fixed with a few carefully placed symlinks.

sudo apt-get install tomcat7

# fix directories
cd /usr/share/tomcat7
sudo ln -s /var/lib/tomcat6/conf conf
sudo ln -s /var/log/tomcat7 log
sudo ln -s /etc/tomcat7/policy.d/03catalina.policy conf/catalina.policy
sudo chmod -R a+rwx /usr/share/tomcat6/conf

# allow startup from inside eclipse
/etc/init.d/tomcat7 stop
Posted in geek | Tagged , | 1 Comment

Excel, counting multiple conditions

Say you wanted to count how many red horses there are in this data set.

Animal Color
Horse	Red
Cat	Yellow
Frog	Green
Frog	Orange
Cat	Yellow
Horse	Red
Rabbit	Blue
Horse	Pink

COUNTIF sounds likely as it can be used to count occurrences of items in a given range, e.g. =COUNTIF(A2:B9, "=Horse") It cannot however be used to evaluate multiple conditions.

Another approach is to use array formulas. Array formulas require magic key-strokes (Ctrl-Shift-Enter) or non-standard syntax, i.e. {} in excel and different things in open office / google apps.

I prefer this solution using the lesser-known SUMPRODUCT() and –() functions. SUMPRODUCT counts numerical rows with matching values. The –() function converts Boolean true and false to 1 and 0 respectively, this allows SUMPRODUCT to do the counting.

=SUMPRODUCT(--(A2:A9="Horse"),--(B2:B9="Red"))
Posted in geek | Tagged | 1 Comment

Java class-loading woes

Another day, another OSGI headache.

JAXB within OSGI.

This won’t work by default. FYI: I’m more of a DOM / XPath fan, but some people insist on using JAXB.

JAXBContext jc = JAXBContext.newInstance("com.adamish.foo.jaxb");

This error is produced.

"com.adamish.foo.jaxb" doesn't contain ObjectFactory.class or jaxb.index

Workaround, manually pass in a class-loader to the overloaded newInstance() method.

ClassLoader cl = com.adamish.foo.jaxb.ObjectFactory.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance("com.adamish.foo.jaxb", cl);

Resource loading within OSGI.

You may have existing code which loads resources via strings referring to resource names. This will work fine when the class doing the loader is in the same “context” as the resource. With OSGI this might not be the case.

In my nightmare I have resources in one bundle, referenced by XML which are loaded by code in another bundle.

// fine most of the time, but a nightmare with OSGI
public void foo() {
  getClass().getResource("/icons/foo.png");
}

Solutions?

One: Do the resource resolution from the same bundle as the resources. Another variant on this would be to pass an InputStream to foo() instead. This might not always be possible.

// in same bundle as resources, then call foo with resolved resource
URL url = getClass().getResource("/icons/foo.png");
foo(url);

public void foo(URL url) {
   // do stuff
}

Two: Pass in an optional class-loader from the context which has access to the resources.

foo(getClass().getClassLoader());

public void foo(ClassLoader cl) {
  cl.getResource("/icons/foo.png");
}
// default for backwards compatibility
public void foo() {
  foo(getClass().getClassLoader());
}

Three: Put the resources in a fragment bundle. Set the fragment host to the bundle containing the code that does the loading. Node there can only be one fragment bundle per bundle-host.

Other class-loading funnies.

The following two lines are not equivalent, I repeat, not equivalent. The first will successfully resolve foo.png (if it’s in the classpath). The second will not.

getClass().getResource("/foo.png");
getClass().getClassLoader().getResource("/foo.png");

The second getClassLoader() is a different classloader to the one used internally in getClass().getResource(…). It will only accept relative paths. The following _will_ work. Note the removal of the leading slash.

getClass().getClassLoader().getResource("foo.png");
Posted in geek | Tagged , | Leave a comment

More random CLI

Generate random password.

dd if=/dev/random count=8 bs=1  | uuencode -m -

Find executable files that are world-writable – for local privilege escalation exploits…

find /usr -type f -perm -102

FLAC to MP3 conversion on MacOS.

# darwin ports versions of mplayer and LAME if necessary
sudo port install mplayer
sudo port install lame

# FLAC => WAV
mplayer -ao pcm:file=foo.wav foo.flac

# WAV => MP3
lame -q 2 -b 320 foo.wav
Posted in geek | Tagged | Leave a comment

JNI asynchronous callbacks

If you’re using JNI, you may wish to callback a java method asynchronously. For example event handling from a win32 message pump.

package com.adamish;

public class Foo {
  public native void register();
  public void callback(int val) {
    // do stuff
  }
}

Step one is to have a “register” method which lets the C++ code obtain a reference to the java code to enable the callback.

For efficiently we cache the references to the VM, the object, and the method. This means less work per callback.

For the object reference you must convert the local reference to a global reference. Local references only exist for the lifetime of the JNI bound call. Afterwards they cannot be used, and worse than that attempts to use them fail silently – the java code is simply not called.

// cached refs for later callbacks
JavaVM * g_vm;
jobject g_obj;
jmethodID g_mid;

JNIEXPORT jboolean JNICALL Java_com_adamish_Foo_register
	(JNIEnv * env, jobject obj, jlong hwnd) {
                bool returnValue = true;
		// convert local to global reference
                // (local will die after this method call)
		g_obj = env->NewGlobalRef(obj);

		// save refs for callback
		jclass g_clazz = env->GetObjectClass(g_obj);
		if (g_clazz == NULL) {
			std::cout << "Failed to find class" << std::endl;
		}

		g_mid = env->GetMethodID(g_clazz, "callback", "(I)V");
		if (g_mid == NULL) {
			std::cout << "Unable to get method ref" << std::endl;
		}

		return (jboolean)returnValue;
}

Now, the actual callback using our cached references from the register() method. There’s quite a bit going on here. Since the callback is on another thread the VM context must be attached to the current thread.


void callback(int val) {
	JNIEnv * g_env;
	// double check it's all ok
	int getEnvStat = g_vm->GetEnv((void **)&g_env, JNI_VERSION_1_6);
	if (getEnvStat == JNI_EDETACHED) {
		std::cout << "GetEnv: not attached" << std::endl;
		if (g_vm->AttachCurrentThread((void **) &g_env, NULL) != 0) {
			std::cout << "Failed to attach" << std::endl;
		}
	} else if (getEnvStat == JNI_OK) {
		//
	} else if (getEnvStat == JNI_EVERSION) {
		std::cout << "GetEnv: version not supported" << std::endl;
	}

	g_env->CallVoidMethod(g_obj, g_mid, val);

	if (g_env->ExceptionCheck()) {
		g_env->ExceptionDescribe();
	}

	g_vm->DetachCurrentThread();
}
Posted in geek | Tagged , | 3 Comments

JavaFX hidden VM args

I’ve been trying to find a workaround for a NullPointerException in the Quantum render thread (RT-18645). During the process I looked at what VM args are read. I added a conditional breakpoint on System.getProperty(String) with code “System.out.println(arg0); return false”.

Here are the values I found, sorted and with non-JavaFX options removed.

com.sun.scenario.animation.adaptivepulse
com.sun.scenario.animation.AnimationMBean.enabled
com.sun.scenario.animation.nogaps
decora.purgatory
glass.platform
javafx.animation.framerate
javafx.animation.fullspeed
javafx.animation.pulse
javafx.debug
javafx.embed.isEventThread
javafx.sg.warn
javafx.toolkit
javafx.verbose
javafx.version
nativewindow.ws.name
prism.debug
prism.device
prism.dirtyregioncount
prism.disableBadDriverWarning
prism.forcerepaint
prism.multisample
prism.noFallback
prism.order
prism.printallocs
prism.reftype
prism.showcull
prism.showdirty
prism.shutdownHook
prism.tess
prism.tessaa
prism.trace
prism.verbose
quantum.debug
quantum.pulsedebug
quantum.verbose
Posted in geek | Tagged , | Leave a comment

Static IP addresses with Ubuntu 11.10 regression

Static IP addresses. Things have changed slightly, before (11.04 and earlier) you could have a static IP address AND the DNS entry from your DHCP. Now if you have a static interface in /etc/network/interfaces the /etc/resolve.conf file get clobbered by NetworkManager with no content (apart from comment).

# Generated by NetworkManager

This can be solved by using the dns-nameservers directive. Example

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.20
netmask 255.255.255.0
gateway 192.168.1.254
dns-nameservers 192.168.1.254

Now when the machine comes up the /etc/resolve.conf has the correct content:

# Generated by NetworkManager
nameserver 192.168.1.254
Posted in geek | Tagged , , | Leave a comment

Embedding Video in Java

Task: Produce application with embedded video. Must support flash video or similar. Must work on older version of SunOS, Windows and Linux (needs pure java implementation really). Must be tight-integration, i.e. not just open a video in an external player.

Discussions on stack overflow

JMF

Java media framework. Supports older formats, but no mention of anything modern like WebM, H264, VP8 etc. However appears dead now as no updates since 2003.

JavaFX

This is slightly better. FAQ

Audio: MP3; AIFF containing uncompressed PCM; WAV containing uncompressed PCM
Video: FLV containing VP6 video and MP3 audio

However at present you are not free to redistribute the JavaFX jars in your product, due to codec licensing issues – update Mar 2012 – licensing for JavaFX now same as JDK7, as incorporated in JDK/JRE7.

JavaFX 2.0 is available under the same license and business model as Java SE, with the exception of the redistribution clause, which currently does not allow third party developers to distribute the JavaFX Runtime (or SDK) with their application(s)

3rd party offerings.

Xuggle: Sits on top of FFMPEG. xuggle.com. Seems to be intended more for processing, but playback appears possible. Licensing? LGPL, but FFMPEG licensing/patenting is a lot more complex – FFMPEG itself is LGPL, with some optional GPL parts.

Posted in geek | Tagged | Leave a comment