Posts filed under 'Uncategorized'
Last month I was given a task to create a small application for viewing and marking up graphical data. This data is provided by a set of web services.
This is a Windows only application, so I decided to use C# and WPF. The C# web service support was the deciding factor; I’ve used it in the past and it’s quite painless. If I had decided on C++, I would have spent several hours building soap wrappers.
The pleasant surprises were how quickly the WFP UI came together and the ease that background operation integrated with the UI.
I really enjoy editing the UI in XML as opposed to using the GUI. It kind of reminded me of the dark old days when we would hand craft Dialog Boxes in the .rc files. Overall, the development experience was very nice.
The worker thread integration was my second nice surprise. My Click Events simply create a delegate, and then call BeginInvoke.
The only gotcha is that updating UI Object from the BG thread is a no-no. Here is the pattern that I used to handle it:
// Update a TextBox Message
private delegate void UpdateTextBoxDel(string strText);
private void UpdateTextBox(string strText)
{
txtView.Text = strText;
}
private void DoUpdateTextBox(string strText)
{
if(txtView.Dispatcher.CheckAccess())
{
UpdateTextBox(strText);
}
else
{
// Invocation required
UpdateTextBoxDel del = new UpdateTextBoxDel(UpdateTextBox);
txtView.Dispatcher.Invoke(DispatcherPriority.Normal, del, strText);
}
}
Not too bad, and works like a champ!
October 6th, 2011
We’ve finished a “port” of one of our larger Windows/Linux projects from Visual Studio 2003, to Visual Studio 2010(sp1) in order to create a Windows x64 version.
We had stayed with Visual Studio 2003 due to the performance advantage. Visual Studio 2005, and 2008 both generated slower binaries. Also, we were required to maintain support for Windows 98 and 2000!
Now we’re finally biting the bullet and saying that Windows XP(SP3) (or XPx64 SP2) is the minimum supported platform.
Performance Numbers for our “rule of thumb” benchmark:
- Visual Studio 2003 (x86)
- Time: 117.497235 ms
- Time: 1136.909457 ms
- Time: 126.083901 ms
- Time: 1133.747273 ms
- Visual Studio 2010 (x86) with PGO
- Time: 112.262443 ms
- Time: 893.446397 ms
- Time: 129.282765 ms
- Time: 882.757780 ms
- Visual Studio 2010 (x64) with PGO
- Time: 108.315252 ms
- Time: 880.750309 ms
- Time: 137.448487 ms
- Time: 885.515196 ms
Without PGO, the execution times for Visual Studio 2010 are 25% longer. So, PGO is well worth doing!
How we did the port
The process itself was fairly painless. We started by updating all out 3rd party libraries: boost, Qt, etc. Then we converted each of our projects to VS2010. After converting them, we reviewed the project files to ensure that we understood each and every setting that was being applied. This seemed to be the longest part of the process!
We did think about using qmake to abstract the build process another level. The rewards just didn’t outweigh the effort. We have a set of makefiles for Linux already, and we’re stuck with VS2010 for the conceivable future.
After the x86 projects were converted, we built and fixed a handful of issues from VS2003 being a bit more forgiving than VS2010. We also added a number of #pragma’s around code blocks to prevent warnings that were understood, but not wanted.
Adding a x64 Target was accomplished by several clicks, followed by another trip through the project files.
Building the x64 version ended up being fairly painless. We had to replace some x86 assembly:
align 16
public _AFTOL@8
_AFTOL@8:
fld qword ptr FVAL
fistp dword ptr IVAL
mov eax, IVAL
ret RETSIZE
inline int iFTOL(double d)
{
return _mm_cvttsd_si32(_mm_load_sd(&d));
}
We also discovered that fopen() under VS2010 is much more strict than fopen() under VS2003 (unit tests are worth their weight in gold). Yes we still use FILE’s, our testing shows that they are faster than HANDLE’s for file IO (likely because they buffer in User mode memory).
The entire process was fairly easy, but also time consuming. Our codebase is over 1 MLOC. From start to beta was 6 man weeks including unit testing, manual testing, and building the PGO scripts.
The wisdom I can pass along is to plan your port, take your time, and invest in unit tests.
July 14th, 2011
My experiment with Mono for Android was going quite well when Attachmate decided to fire the entire development team. That didn’t scare me, I had a feeling that they would pop up again. What made me pause was the thought of what Nokia might do.
I realize that this is old news. At the time it happened I hadn’t been giving Qt much thought.
Nokia purchased Trolltech (the makers of Qt) a while ago. The vision was to use Qt to provide an enterprise wide SDK for all the Nokia mobile OS’s. This was to include the old Symbian, as well as MeeGo.
The Nokia/Microsoft press release read: “Microsoft development tools will be used to create applications to run on Nokia Windows Phones, allowing developers to easily leverage the ecosystem’s global reach. “
IMHO, there is absolutely no business reason for Nokia to hang on to Trolltech. Qt makes it entirely too easy to create multi-platform applications for Windows, Mac, Linux and Mobile Platforms; but not Windows Phone 7.
May 31st, 2011
Yes, it would be easier to use Java. This is research, which means I’m not getting paid for it, so I can do what I like.
The main reason for using MonoDroid is that several of my OEMs know C# and have large code bases. Providing a path to reuse the existing code is a big win.
My goal is to use the Sybase UltraliteJ (SQL Anywhere v12) with a MonoDroid application. This will include Connecting, Querying, Adding records and syncing with a PC Database server. This will show an ability to load data to the device from a Database Server, go offline, edit the data, reconnect and sync the data back to the Server.
This is useful for “airplane mode”, going into the field where there is limited to no connectivity, and data security.
Getting started
I have the Java, Android SDK, Visual Studio 2010, MonoDroid and Sybase 12.01 installed.
Create a MonoDroid Project, build it and make sure that it runs! I’m using an Android Tablet for my testing, though an emulator would work fine.
Setup Sybase UltraliteJ
Copy the files from “C:\Program Files\SQL Anywhere 12\UltraLite\UltraLiteJ\Android” to my project folder. Yes, I didn’t have to do this. I want to have everything in the same place so I can stuff it into subversion.
Rename the ‘ARM’ folder to ‘armeabi’. This is important! By doing this, we inform the Mono compiler that the ABI for the shared libraries is armeabi.
Add a folder to the Visual Studio project named armabi, and add the shared object to it.
For each shared library, set the properties: ‘Build Action’ to AndroidNativeLibrary.
Add the UltraLiteJNI12.jar file to the project. Set the properties: ‘Build Action’ to AndroidJavaSource.
Create a new Java file. I named mine jni_helper.java. Add this to the project and Set the properties: ‘Build Action’ to AndroidJavaSource.
Now we’re ready to start adding code.
Build the JNI Layer
At some point in time MonoDroid is going to have a tool for using arbitrary Jar files. There isn’t one now, so we’ll have to use JNI to talk to UltraliteJ. Greg Shackles has a good blog entry about this. I used the same style (and shameless copied his code!), which is using class static methods. My test application is database driven, so this is a good model.
To start, I created a Java class with connect, disconnect and isConnected static methods.
package monoultralite.helper;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.util.Log;
import com.ianywhere.ultralitejni12.*;
public class jni_helper {
private static final String TAG = "jni_helper";
private static Connection conn_ = null;
private jni_helper()
{}
public static void connectDB(android.app.Activity act)
{
Log.v(TAG, "connectDB: E");
try {
Log.v(TAG, "connectDB: DatabaseManager.createConfigurationFileAndroid");
ConfigFileAndroid config = DatabaseManager.createConfigurationFileAndroid("MonoUltralite.udb", act);
// Connect, or if the database does not exist, create it and connect
try {
Log.v(TAG, "connectDB: DatabaseManager.connect");
conn_ = DatabaseManager.connect(config);
} catch (ULjException e) {
Log.v(TAG, "connectDB: DatabaseManager.createDatabase(config)");
conn_ = DatabaseManager.createDatabase(config);
}
} catch (ULjException e) {
conn_ = null;
Log.v(TAG, "connectDB: **catch** cannot create DB");
}
Log.v(TAG, "connectDB: X");
}
public static void disconnectDB()
{
Log.v(TAG, "disconnectDB: E");
if (null != conn_) {
Log.v(TAG, "disconnectDB: DatabaseManager.release");
try {
DatabaseManager.release();
} catch (ULjException e) {
Log.v(TAG, "disconnectDB: **catch** DatabaseManager.release");
}
conn_ = null;
}
Log.v(TAG, "disconnectDB: X");
}
public static boolean isConnected()
{
Log.v(TAG, "isConnected: E");
boolean fConnected = false;
if (null != conn_) {
fConnected = true;
Log.v(TAG, "isConnected: IsConnected");
}
if(fConnected)
Log.v(TAG, "isConnected: Return true");
else
Log.v(TAG, "isConnected: Return false");
return fConnected;
}
}
This will be used by this C# class:
public static class MonoUltraliteHelper
{
private static IntPtr _helperClass = JNIEnv.FindClass("monoultralite/helper/jni_helper");
// Generate Sigs with: javap -classpath "C:\Program Files (x86)\Android\android-sdk\platforms\android-8\android.jar;UltraLiteJNI12.jar" -s -p jni_helper
public static void connectDB(Activity act)
{
IntPtr methodId = JNIEnv.GetStaticMethodID(_helperClass, "connectDB", "(Landroid/app/Activity;)V");
if (null != methodId)
JNIEnv.CallStaticVoidMethod(_helperClass, methodId, new JValue(act));
}
public static void disconnectDB()
{
IntPtr methodId = JNIEnv.GetStaticMethodID(_helperClass, "disconnectDB", "()V");
if (null != methodId)
JNIEnv.CallStaticVoidMethod(_helperClass, methodId);
}
public static Boolean isConnected()
{
Boolean ret = false;
IntPtr methodId = JNIEnv.GetStaticMethodID(_helperClass, "isConnected", "()Z");
if (null != methodId)
ret = JNIEnv.CallStaticBooleanMethod(_helperClass, methodId);
return ret;
}
}
The method signatures are generated via javap:
javac jni_helper.java
javap -s -p jni_helper
Compiled from "jni_helper.java"
public class monoultralite.helper.jni_helper extends java.lang.Object{
private static final java.lang.String TAG;
Signature: Ljava/lang/String;
private static com.ianywhere.ultralitejni12.Connection conn_;
Signature: Lcom/ianywhere/ultralitejni12/Connection;
private monoultralite.helper.jni_helper();
Signature: ()V
public static void connectDB(android.app.Activity);
Signature: (Landroid/app/Activity;)V
public static void disconnectDB();
Signature: ()V
public static boolean isConnected();
Signature: ()Z
static {};
Signature: ()V
}
This keeps us from having “method not found” exceptions!
First GUI
I added a few buttons that call the static methods to test the App->JNI->JAR->Shared Object.
[Activity(Label = "MonoUltralite", MainLauncher = true, Icon = "@drawable/icon")]
public class UltraliteActivity1 : Activity
{
int count = 1;
JValue obj = JValue.Zero;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += delegate { button.Text = string.Format("{0} clicks!", count++); };
Button buttonConnect = FindViewById<Button>(Resource.Id.MyButtonConnect);
buttonConnect.Click += delegate
{
if(!MonoUltraliteHelper.isConnected())
MonoUltraliteHelper.connectDB(this);
};
Button buttonDisconnect = FindViewById<Button>(Resource.Id.MyButtonDisconnect);
buttonDisconnect.Click += delegate
{
if (MonoUltraliteHelper.isConnected())
MonoUltraliteHelper.disconnectDB();
};
Button buttonSync = FindViewById<Button>(Resource.Id.MyButtonSync);
buttonSync.Click += delegate { button.Text = string.Format("{0} clicks!", count++); };
}
}
As you see, the Query and Sync buttons don’t do anything yet.
Building any running confirms that the C# code may easily call into Java code, which may use a native library. It ended up being fairly simple to build this.
Update May 6:
The Disconnect Native method was not implemented in the 12.0.1 release of UltraliteJ, I’ve reported it to Sybase and they tell me it’ll be fixed.
The bigger news is that MonoDroids’ future may be in doubt. The Novel sale has resulted in an unknown number of Mono developers being let-go. This leaves the future of MonoDroid in doubt to me; until their is an official announcement I’m going to hold off on my MonoDroid research.
I have no doubt that I can get the UltraliteJ database syncing to a Sybase server and executing local queries and such. The JNI part is the “magic” that makes this go. Even that isn’t too challenging with the help of javap.
May 3rd, 2011
Woot! had a sale on Viewsonic gTablets last week and I couldn’t resist. The gTablet is built with the NVIDIA Tegra 2 and has a dual core A9 processor. Battery life is “ok”, I see about 4 hours with Wi-Fi enabled.
My previous tablet (a wow! pad) was unable to connect to my development system via USB. This coupled with a Google Wi-Fi ADB bug prevented me from debugging MonoDroid using the Visual Studio debugger. DDMS worked, but wasn’t nearly as nice to use.
Anyway, I moved forward on a proof of concept to see just how much code I could share between Windows, Linux and Android.
My testing was done using Visual Studio 2010, .NET 4, Mono 2.1 on Suse, and MonoDroid (9779).
I was extremely pleased on the code sharing between Windows and Linux. I managed to share 99.9% of my UI (Windows Forms), Network (SOAP calls), and Rendering (using OpenTK). The only issue I ran into was the Microsoft generated web service wrapper, which would not run under Mono unless I set the Nullable = false.
I had high hopes for the MonoDroid version, but these died fast.
The Android Activity is different enough to require custom code. This wasn’t too bad, I kind of expected that.
The SOAP code worked, which was nice.
The rendering code is where I got a dose of reality. I expected OpenTK to provide the same interface for OpenGL ES as it provided for the standard OpenGL (in hindsight, I should have known better). Well, that isn’t the case.
For example; if I want to render a yellow triangle using OpenTK under Windows or Linux, I would do this:
GL.Color3(Color.Yellow);
GL.Begin(BeginMode.Triangles);
GL.Vertex2(0.0, 0.0);
GL.Vertex2(1.0, 0.0);
GL.Vertex2(0.5, 1.0);
GL.End();
Using OpenGL ES, you would do something like this:
float[] vertices = {
0.0f, 0.0f,
1.0f, 0.0f,
0.5f, 1.0f };
GL.Color4(255, 255, 0, 255);
GL.VertexPointer(2, All.Float, 0, square_vertices);
GL.EnableClientState(All.VertexArray);
GL.DrawArrays(All.Triangles, 0, 4);
So, the rendering code would need to be specialized for the ES API. This is a bit of a bummer.
I checked back into the Qt Lighthouse (Android) project it has progressed a bit. For example Qt Creator is up and running, and there is a system wide shared Qt .so installer. But, it still seems a bit young for commercial development right now.
My current mindset is that MonoDroid will help get a Desktop App over to Android, but will require a great deal of custom code (which means more testing).
March 30th, 2011
Last week the *first* service pack for Visual Studio 2010 (VC10) has been released. This is exciting because now we can (finally) build a working x64 Qt with it! The initial release of VC10 would create buggy x64 release binaries.
As a background task, we’re porting a large codebase from Visual Studio 2003 (VC7.1) to VC10 in order to create a x64 version. Yes we could have used Visual Studio 2008, but we wanted to use the latest and greatest.
We’ll still build the x86 version using VC7.1, since we have customers who use Windows 2000. Actually, the code base still supports Windows 98!
The actual VC7.1->VC10 work hasn’t been too bad. We are using “/D_CRT_SECURE_NO_WARNINGS” to disable the warnings about the “_s” functions. There were a handful of C++ classes that needed fixing to build, but nothing really bad so far.
The PITA for us has been getting the performance of the x86 versions to be as good as the VC7.1 x86 binaries. To do this, we’ve needed to use profile guided optimization (PGO). I don’t want to have multiple configurations within the project file, so we’re using a feature of MSBUILD to create the PGI binaries, run the profiling applications, then do the final build using PGO.
In our “rebuild.cmd” file we do something like this:
SET OPT_LINK=/property:OPT_LINK=/LTCG:PGI
msbuild /m /p:Configuration="Release";Platform=Win32 %OPT_LINK% Project.vc10.vcxproj
del *.pgc
del *.pgd
benchmark.exe
SET OPT_LINK=/property:OPT_LINK=/LTCG:PGO
msbuild /m /p:Configuration="Release";Platform=Win32 %OPT_LINK% Project.vc10.vcxproj
In the Project Settings: Linker->Command Line we have added: $(OPT_LINK).
So, the batch file will pass the PGI setting into MSBUILD to create the first binary. Run the benchmark to generate the .pgc files, then do the final build.
I view this as a much better solution than having separate targets for Release/PGI/PGO.
March 18th, 2011
Over the past few weeks I’ve spent time with the Qt Lighthouse branch. I’m still very impressed, but, it feels to be about a year away from being useable for end-user software. This may have to do with the speed of the new Android Releases. Honeycomb (v3) should be out by the middle of April!
As a software developer, deciding on the supported platforms and OS versions is always difficult. Obviously the more OS’s you support, the bigger the market. But, every OS adds a development, maintenance and support cost. Even supporting multiple versions of the different OS’s leads to some pain.
Most of the applications we develop cannot be replicated via web pages. They require fairly snappy graphics and local computation ability. We’ve have some success with rich client + fat server development; but that doesn’t scale as well as we would like. Maybe in another year or two when the cloud space settles down it’ll be a better choice.
The lure of Qt is the ability to rebuild and run it on multiple platforms without the configurations issues of Java (I *like* Java on the Server side, but not on the client).
When I started trying out Qt under Android, I was hopping that it was further along. Also, it seems that the Qt iPad branch is even farther behind.
In any case, this brings me to the next experiment. I had put together a proof of concept using Python as a meta language for development. The Application core would be an existing (or new) statically typed module, and the UI and business logic would be in a dynamic language. I was working in Python, so that was a good place to start.
I used SWIG to generate binding for a C++ module, and used Python to drive it. This ended up being a huge pain to get working. I also tried using Iron Python and an ActiveX module. This ended up being extremely easy to put together, and it worked very well.
Back to platform support; I decided it was time to check out MonoDroid. I cloned a VM, installed the Visual Studio 2010 plugin, and had an Android 2.2 apk running about 5 minutes later. I ran into an issue trying to deploy via the IDE, but was able to manually install and run it on a device.
I’ve been leery of Mono, mainly because I don’t know many (any) companies that use it for commercial software. I’ve read the list on the mono website, and haven’t used any of that software.
Assuming that mono works “well enough”, it would allow us to create common modules across all the platforms that we care about:
| Windows XP |
Microsoft |
| Windows 2003, Vista, 2008, 7 x86/x64 |
Microsoft |
| Windows CE |
Microsoft |
| Windows Mobile |
Microsoft |
| Max OS X x86/x64 |
Mono |
| Linux x86/x64 |
Mono |
| Android |
MonoDroid |
| iPad/iPhone |
MonoTouch |
The major drawback is that the mobile platforms would not be able to share common UI modules (note: this was the big win for Qt).
But it does allow us to share the business logic, database, and network code. It also handles the 32/64 bit for us.
We’re definitely not going to move this way until we’ve done more homework. The story is tempting though. To imagine that a small team can leverage .Net to support just about every platform out there…
January 6th, 2011
I haven’t had much time to work on interesting development projects for a while. This weekend I updated my phone to Android 2.1, and decided to try creating a simple application. I wanted to leverage my Qt experience, so I decided to try the android-lighthouse project.
Development Setup
I want to run apps on my actual phone, so I setup my development VM locally using VMware Workstation (vSphere won’t connect to a local usb device).
I choose Suse 11.3 as my development distro because the Android SDK needs new versions of glibc which Centos doesn’t have.
Once I had all the tools installed, Java configuration was a chore for some reason, I installed the Android SDK. Important: I had to install an older version of the Android SDK to get android lighthouse to work. I installed android-sdk_r06-linux_x86.tgz, then ran android and updated to SDK Platform Android 2.1-update1, API7. revision 2.
I can’t stress enough the importance of getting the Android SDK properly configured before starting any work with Qt Android Lighthouse!
android-lighthouse
I followed the instructions from android-lighthouse. I configured my qmake.conf:
NDK_ROOT = /usr/local/qadk-r4
#NDK_ROOT = $(ANDROID_NDK_ROOT)
NDK_TOOLCHAIN = arm-eabi-4.4.0
ANDROID_PLATFORM = android-5 # 4 - android 1.6
# 5 - android 2.0 & 2.1
# 8 - android 2.2
I also updated my .basrc:
# Android SDK
export PATH=/usr/local/AndroidSDK/tools:/usr/local/AndroidSDK/platform-tools:$PATH
# Custom NDK
export NDK_ROOT=/usr/local/qadk-r4
# Qt for Android
export PATH=~/qt.lighthouse/bin:$PATH
Then I built Qt. An hour later I was ready to test it out.
I edited the create_android_lighthouse_project.sh with my local paths. Next I create a folder “qttest”, and built a test app.
That built with no errors, so I pushed up my Qt .so’s and ran into a problem. The instructions for pushing the so’s were not actually pushing the so’s. I discovered this when the test failed on the emulator due to a missing so file. The Android ddms utility is quite helpful for seeing what is happening on the emulator!
My next attempt resulted in an “out of space” error. I fixed that by starting the emulator via: “emulator -avd my_avd -partition-size 512”. After that I had plenty of space on my device.
The small sample ran, but was boring. I copied the “examples\dialogs\tabdialog” to my test, built that, and here is the result:

I shut down my emulator, and plugged in my phone (a Motorola cliq). I restarted adb as root so it could talk to my device, and ran my test successfully there.
Conclusions
Getting this configured and running took much longer than I expected. Getting a working development environment took me a couple of days! This was due to several factors:
- My choice of the Linux distro. Centos will not work, Ubuntu had strange issues with Slickedit 2009, and Suse always takes longer to configure then it should.
- Using the current Android SDK bit me in the ass. Maybe it can be used without problems, but I couldn’t figure that out.
- Qt Build speed. It takes 1-2 hours to build Qt before you can try a sample. Also, I had errors due to libcloog, missing –lQtOpenGL, etc. These were cleaned up by re-giting the source and building from scratch.
- Getting Sun Java 1.6 JDK configured under Suse seemed much harder than it needed to be. The whole “update-alternatives” seems like a train wreck waiting to happen. I’m sure if I did Java development I would use and like it, but I just wanted a single JDK and it bit me.
Once I had it built and configured, I was impressed. At one level it’s just a library built for Arm using the NDK, at another level it’s a cross platform solution that lets me create native applications for Windows, Linux, Mac, and now Android. That’s old school impressive.
I had hoped that Silverlight would be this solution, but Microsoft managed to bungle that by dropping the ball on the cross platform support. If the solution is Qt, that isn’t too bad at all.
December 7th, 2010
My issue with Veeam Backup not sending emails was resolved by using a different email server. Veeam support was OK; they responded to my emails, but they don’t see too technically savvy. They do respond within a few hours though! In todays world, that makes them top 10%.
Veeam is running nightly and backing up 6TB of VM’s. The ESX “dirty block” tracking does a good job, so this is taking between 30 min and 2 hours to complete. The resulting files are fairly small.
I tested Veeams “instant recovery”; note: this is the feature that disables NFS shares on Windows Servers. It allows you to select the backup date of the VM that you want to restore, then you pick your vSphere Server and say go.
After it’s restored, the VM runs off the Veeam image via NFS (read only) and you may use it directly. There is an option to store disk edits locally or on your vSphere server.
The restored VM runs a little slower, as you would expect, but it does work. It’s a very nice feature.
Sure Backup is the primary reason that I picked Veeam as my vendor. What is does is mount the backup image, boot it up inside of a private network, and verify it works (ping and script).
I’m running into issues with some of my VM’s because they have static IP’s. I’ll get those figured out one by one.
The second issue I ran into was a group of broken disks I received from Newegg. I should be getting replacements next week, so once they are in, the backup server will be fully populated. I do have confidence that the disks in the drive array now are fine.
The end of all this IT work is in sight now!
December 4th, 2010
Over the holiday, I finished the big office reorganization.
VMware ESX (vSphere) 4.1 has operated nicely on the new Dell Server. The search for useable ESX Backup software is not going that well.
Veeam Backup
I started with Veeam. I’ve used their fastSCP tool, and decided to try their backup software first.
Getting a price quote is next to impossible. I emailed them 3 times, and even after calling them and being assured I would have a quote – nothing.
Installing Veeam on my spare server went smoothly. The first backup went well, then I wanted to test the speed of the nightly backup. That failed with a strange network error. The next several tries also failed, even when I rebooted.
Their support department was fairly quick to respond to my request, but did not have any good solutions for the error I was seeing.
I moved the software to run on my backup server, that way there would not be any network issues. My backup server hosts a 12TB disk array, and that is all it does. However, it exports shares via SMB and NFS (using the Windows NFS Server). Veeam grabs UDP port 111, which prevents the Microsoft NFS Server from running. So, if you want to run Veeam on a system that exports NFS shares, you are out of luck.
Veeam support said that they need the port for their own internal NFS Server – so I can’t host NFS Shares on the same system that Veeam is installed on.
That’s aggravating, but not a deal killer. I was using the NFS share for a different backup solution (ghettoVCB).
Anyway, I’m about 20 hours into my first backup and only 61% complete. I have a feeling that my backup server doesn’t have the horsepower to run Veeam.
In any case, I’ll run the incremental backup using the block-change detection and see how long that takes. I’m hoping it’ll be useable.
ghettoVCB
ghettoVCB is a free script that uses the ESX host to backup VM’s to a different datastore. Because you may mount a NFS share as a datastore, you have a great deal of flexibility.
It operates by taking a snapshot of the VM, then cloning the base disk, then rolling back the snapshot. So, you can backup running VM’s without any problems.
Configuration and setup is very easy; just edit the script.
Running it is also easy, and it’s fast.
This is my fallback solution. I really want to get a “professional” backup solution that uses the block-change API.
November 26th, 2010
Previous Posts