Avoid Webhost4Life for Hosting

For a couple years now, I have been using Webhost4Life to host my Chef website, ejichef.com.   At $10-$12/month, they weren’t the cheapest option out there for Microsoft-based shared hosting, but they also weren’t the most expensive.  All-in-all I never had any major problems with them and their support was reasonably responsive (again, given the cost).

I have learned that the company was recently purchased, and I had been getting emails about an impending migration to a new hosting “platform”.  My site’s turn was in the middle of the week last week, and I received an email when it was complete.   I quickly visited my website and navigated around, it all looked ok.   At first.

A day later when I received my daily download report, I saw there was absolutely no traffic to my download (hosted elsewhere).  A little investigation showed that during the migration they had deleted all of my custom DNS records.  Frustrating, for sure, but not terrible.  I logged in and added the records which inexplicably caused my site to go down. 

I chatted with a support rep online, who didn’t even try to solve anything and immediately created a ticket and told me it would be quickly resolved.   8 hours later there had been no change to the ticket so I chatted with someone else and was fed the same 4 auto-response lines I have learned to be the extent of their services.   Once again I was assured it was being worked on right now and will be fixed in 2 hours at most.

10 hours later (around 18 total) I finally received an email that it was fixed.  What complex operation took the skill and expertise of an engineer?  Restarting IIS.  

 Strike 1. 

Another day or two goes by and I go to look at the contents of the database that was migrated, and find that it is completely empty.  The schema was migrated but none of the data.  What were they thinking?  I went to take a backup of the old database, but found that I needed someone in tech support to do it.  After another chat, I was told they had to create a ticket to have the backup and restore done again.  I have never seen this ticket or heard if it has been completed (I had my own backup which I restored elsewhere, so it wasn’t critical).  Strike 1.5.

Shortly after this, a couple Chef purchases came through but the license key generation code failed.  After some digging, I find that the problem is permissions-related and I gather all of the links and information needed to create a very detailed support case.   I created submitted the ticket, and here I sit on day 4 with it still not functioning.  Strike 2.5.

What has thrown me over the edge is my interaction with the support team over these past 4 days.  The only activity I see on the case are my inquiries into the status  – not a single word back about what is going on, an ETA, or a request for further information. 

I have chatted online with support too many times to count, each time being told (after putting me on hold for 4-5 minutes) that they had just personally talked with an engineer and they were working on it as we spoke.  I was repeatedly assured that the fix was at most 2 hours away.  Multiple times I was told they had just escalated the ticket to High Priority, which I’ll note is never reflected in the ticketing system.  During the first conversation the technican was in a hurrty to get off of the support line and told me that they had reproduced the error (and of course it will be fixed in 2 hours..), even though I had not given them instructions on how to reproduce it.  They quickly diverted the conversation when I brought this to their attention.

I had been seriously considering upgrading my Webhost4Life account to a VPS (virtual private server) before all of this happened.   I’m thankful this all happened before I signed a year-long contract because I cannot imagine paying the VPS price and ending up with support like this. 

During the frustration of that first 18 hour outage I opened an account with KickAssVPS.com and just yesterday made the decision to transition everything over to it.  As of right now I am no longer using my Webhost4Life account and am trying to cancel it.  While the cost is obviously more expensive than shared hosting, the KickAssVPS experience has been nothing short of excellent and I’m looking forward to using them for a long time to come.

Hopefully my cancellation will be complete soon and I can say goodbye Webhost4life, and good riddance.

iPhone Objective-C for the C# Developer

If you’re a C# developer making your first foray into the land of iPhone and Objective-C programming, you probably have a question or two.  I recently started working in earnest on an iPhone app, so I figured I would write down some of the tips I’ve picked up thus far.

Here they are in no particular order.  No particular level importance.  Just some things that I had to learn and which may help you as well.

Objective-C

  • It’s a strict super-set of C, so straight C code is compilable in Objective-C
  • Back to the old header and implementation files (.h and .m, respectively)
  • There are two types of methods in classes, instance and class methods.  Denoted by a prepended “+” or “-” on the method prototype.  Class methods are just like static.
  • All methods are public(!).  That’s right, read that again.  There’s a hack/technique having to do with Objective-C categories to help hide them in the IDE, but they are still callable.
  • NSObject is System.Object.
  • No garbage collection on the iPhone, there is  reference counting instead.  More on this later.
  • What we typically think of as constructors are “init” methods.  Destructors are “dealloc”.  There’s nothing special about these methods, it’s just convention.
  • Properties are denoted with @property lines in the header file.  Corresponding @synthesize statements in the implementation file generate the property code.  Special directives in the @property declaration determine the specifics of the implementation (nonatomic, retain, etc.).
  • Use #import over #include – it prevents a file from being indrectly #included more than once.
  • What .Net calls Interfaces are called Protocols in Objective-C.
  • this pointer is called self
  • base is super
  • Methods are referred to as selectors.  Calling a method is referred to as sending a message to an object.
  • Message sending syntax is [recipient method] or [recipient method:paramvalue] or [recipient method:paramValue param2name:param2value]
  • @selector() is for specifying what are essentially delegates.
  • id datatype is basically NSObject*
  • There are C strings and there are NSStrings.  C string constants are defined like “something”, NSString constants are defined like @”something”
  • [[someClass alloc] init] is the typical instantiation pattern. Sometimes there are parameters, as in [[someClass alloc] initWithValue:someValue].   Sometimes you can just call a factory method on the class as in [someClass someClassFromData:data].  The only real difference has to do with the reference counting of the returned object (again, by convention).
  • Events are achieved by what they call delegation – registering/attaching an object that adheres to a protocol (interface) to subscribe to events (called Actions).
  • No namespaces, but there are categories which I haven’t bothered touching.

Reference Counting

  • NSObject implements reference counting.
  • Calling alloc or copy sets the reference count to 1.
  • To decrement the reference count, call release.
  • When the reference count hits 0, NSObject calls dealloc.  NEVER call dealloc yourself.
  • Call retain to increment the ref count.  Basically, if you need to keep hold of an object for longer than the duration of one message event cycle (event handler), call retain.    You don’t need to call retain on an object that you directly created with an alloc or copy call – NSObject called retain for you.
  • Calling release one too many times is bad – dealloc will end up getting called twice and cause a crash. 
  • There is an AutoReleasePool and the ability to call autorelease on NSObject.
  • When you call autorelease, the release  call gets posponed/scheduled in the AutoReleasePool.  This is used when a function needs to return a newly created object to the caller.  If it doesn’t call release, the ref count will be incorrect.  If it does call release, it will immediately be deallocated.    Calling autorelease will give the caller time to call retain to take ownership.
  • When does the autoreleasepool finally call release?  The pool gets drained at the end of every message pump loop, cleaning up any autoreleased objects.
  • So, so summarize… if you call alloc or copy, you need to call release.  If you use a class factory method and need to keep the object around, call retain and be sure to have a matching release later.

Interface Builder

  • I have yet to see why Apple developers fall all over themselves about Interface Builder.  No comparison to Visual Studio.
  • Interface Builder writes to .xib files (which for some unknown reason are called Nib files).
  • It parses your header files for IBAction and IBOutlet on declarations to determine event handlers and variables for interface elements respectively.
  • IBAction is a #define for void.
  • IBOutlet is a #define for blank.
  • Just saving the .h file is sufficient for IB to reparse and pickup the changes.

Ok, I’m tired of typing now.  That ended up a little longer than I intended but I hope it helps you to get up to speed.

More PowerShell – a Cmdlet

This past weekend I spent some time reading up on and writing my first PowerShell cmdlet.   The cmdlet is an easy one, but replaces a PS function I have copy/pasted into several scripts here and there to handle cleaning out directories of old backups or other types of files.  One scenario is my RadioShark which I have setup to make daily radio recordings.  The software doesn’t have any settings for how long to keep the files, so up until now I have just been manually deleting a couple dozen at a time every month or so. 

Enter Remove-OldItems, named after the built-in Remove-Item.

Full Syntax: Remove-OldItems c:\temp -pattern *.mp3 -KeepDays 7 -Leave 2 -Confirm -WhatIf

That will remove all mp3 files in c:\temp which are older than 7 days.  The Leave parameter is for when I use it for dealing with backup files and is a safeguard so that even if all of the files fall out of the date range, they won’t all be deleted. 

I have put together 32-bit and 64-bit installers, feel free to download them.  If you run it on a 64-bit system, the install will register with both the 32 and 64bit PowerShells. I can make the code available if anyone’s interested.

After installing the .msi, you can confirm the new Snapin is on the system by running get-pssnapin -registered. You should see EjiSnapin listed.After Install

Now the Snapin containing the cmdlet(s) is there, but not loaded into the current PowerShell session.  Since I’m going to be running this from a Scheduled Task, I don’t want to have to explicitly run Add-PSSnapin EjiSnapin every time I want to use it.  One quick way around this is to add that command to the system-wide PowerShell Profile located at $pshome\profile.ps1.  That’s easy enough, in an elevated PS prompt, just run notepad $pshome/profile.ps1 and add a single line Add-PSSnapin EjiSnapin and save the file.  Now every PS session will have the cmdlet ready to go.

Here’s the final result, a scheduled task with a simple command being run to clear out old files in my RadioShark directory.

task

Overall it was fairly easy, the most difficult part came with getting the installers to work correctly between 32 and 64-bit installations.  Future enhancements, if I come into a situation where I need it, may be to add processing from the pipeline so a collection of files to be deleted could be passed to the cmdlet instead of a directory path.  Might be useful, might not.

Here’s C# for doing the actual deletions.


    DirectoryInfo rootDir = new DirectoryInfo(Path);

    // anything older than Today minus KeepDays may be deleted
    DateTime protectionDate = DateTime.UtcNow.AddDays(-KeepDays);

    List candidates = rootDir.GetFiles(string.IsNullOrEmpty(Pattern) ? "*.*" : Pattern, SearchOption.TopDirectoryOnly)
        .OrderBy(f => f.LastWriteTimeUtc).ToList();

    if (Leave > 0)
    {
        // pop the last Leave files off the end (the most recent)
        candidates.RemoveRange(candidates.Count - Leave, Leave);
    }

    // now only keep those that are old enough
    candidates.RemoveAll(f => f.LastWriteTimeUtc >= protectionDate);

    // cycle and delete
    candidates.ForEach(f =>
        {
            if (ShouldProcess(f.FullName, "delete"))
            {
                try
                {
                    f.Delete();
                }
                catch (UnauthorizedAccessException ex)
                {
                    WriteWarning(String.Format("Unable to delete '{0}', UnauthorizedAccess", f.FullName));

                    // IOException can also occur, but I want that to be a termanating exception
                }

            }
            else
            {
                    // Nothing to do, ShouldProcess provided any errors/warnings/etc.
            }
        });

In the process of writing this I learned that PowerShell V2 allows you to script cmdlets.  So this could have been greatly simplified (mostly on the deployment side), but that wouldn’t have been nearly as interesting, right? 

That’s all folks. Thanks for reading.

Tracking down a Blue Screen of Death

Since rebuilding my machine with a new motherboard and processor, I’ve gotten a few crashes in the middle of the night. I’ve come downstairs to a rebooted PC with an error message indicating the dreaded Blue Screen of Death has visited. So I decided to figure out what’s causing it, and maybe find a fix.

When a bluescreen happens, Windows will take a snapshot of what is in memory at the time of the crash and store them for analyzing later.  “Mini” crash dumps are stored in c:\windows\minidump and are trimmed down (for space reasons) versions of the full crash dumps.  There’s a great tool called Windows Debugger that can be used to take a peek into these dump files to decipher what may be causing the problem.

First I downloaded the Windows Debugging Tools so that I could get the WinDbg (Windows Debugger). 

After installing the tools, start up WinDbg and you’ll see a very plain looking interface that is essentially a console with tons of menu options/commands.

windbg

The next step is to open one of those crash dump files.  So go to File -> Open Crash Dump and select one of the .dmp files.  It’ll chug away for a few seconds as it opens, and then you’ll be presented with some messages that include:

***** Kernel symbols are WRONG. Please fix symbols to do analysis.

Symbols are files that contain debugging information for your system files.  They are platform and version dependent – meaning symbol files for a 32-bit Windows XP machine won’t help figuring out a 64-bit Windows 7 problem as is the case here.  Luckily, WinDbg will download the appropriate versions of symbols  once you simply tell it where to get them and where to put them.  Select File -> Symbol File Path and enter the following into the window to save the symbols to a path on your C:\:

 SRV*c:\debugsymbols*http://msdl.microsoft.com/download/symbols

Check the Reload box before closing so that the symbols will be downloaded right away:

symbols-path

 When you click OK, the status bar on the main console will read BUSY as the necessary symbols are downloaded.  Then the cursor will sit and blink, waiting for you to tell it what to do.

Now just type in:

!analyze -v

and you’ll be presented with lots of very technical technical text.  In my case, I scanned through and saw a couple important bits of information:

PAGE_FAULT_IN_NONPAGED_AREA (50)

DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT

BUGCHECK_STR:  0×50

PROCESS_NAME:  Robocopy.exe

FAULTING_IP:
nt!MmCopyToCachedPage+215

IMAGE_NAME:  memory_corruption

So it sounds like it’s a bad memory pointer resulting in a fun access violation, happening in a kernel function MmCopyToCachedPage.   And it doesn’t seem to have anything to do with power management, instead it was occurring during one of my nighly backups that uses Robocopy to pull files off of the network.

Now, what to do about it?  I tossed MmCopyToCachedPage into Bing, and the very first hit was for someone running a similar processor on the exact same motherboard. (For the record, Google’s search results didn’t appear to be nearly as useful).  Reading through the thread, a mentioned fix was to change a BIOS setting to accomodate the processor better (CPU Margin Enhancement, whatever the heck that is).   Tonight we’ll see if this has any impact on the system crash, I’ll be crossing my fingers.

So there you have it, using WinDbg to get a look into what part of your machine is blowing up.  Thanks for reading.

When it Rains, it Pours

It started with no video output, and ended with a non-booting computer with an unreadable external hard drive and potentially unusable RAID array.   Yeah that’s not good.

Yesterday evening my monitors went blank.  An hour of troubleshooting left me with the determination that my “good” video card had failed.  I removed it and was able to boot into Vista using the lesser of the video cards. I started the RMA process and figured that was the end of it. 

HA!  Today I was remoted in and noticed I couldn’t access the external USB hard drive (Western Digital MyBook).  The eventlog was showing NTFS errors saying it was corrupt and needed to be scanned, but I couldn’t do anything with the drive; so I rebooted.  And it never came back up! 

All signs indicate the motherboard is toast.

The external drive has all of my videos on it (raw footage and edits), and that is copied nightly to the mirrored RAID array where the first copies of photos live. No biggie, right?  Well I had a little scare when I started reading about moving RAID arrays to new machines – as in, most of the time you have to have the same brand (or compatible) RAID controller or you’re screwed.  I’m using the onboard nvidia NVRaid on a board that is no longer sold, and couldn’t quite find documentation on compatibility between versions.

So, I pulled one of my mirrored drives out and put into my SATA dock attached to my laptop. Big relief –  all of the data is readable as a standalone drive!  Wooo!

Now back to the external MyBook – I plugged it into my Windows 7 laptop and was promptly asked if I wanted to fix it.  30 seconds later, the filesystem was checked/fixed and my data was available.  Wooo Wooo!

If my RAID array would have been unusable, I have backups of the important stuff across my network and across town.  But I definitely didn’t count on my external drive AND the array being down at the same time, so that freaked me out a little bit and I’m thankful that the drives are all fine.   Thinking about it more, I probably would have ended up paying a pretty penny for the out-of-production motherboard or some of the RAID recovery packages out there.

Anyway, when I get my desktop rebuilt I’m going to have to find room for another copy of 100GB of video somewhere.

And finally, the hardware I ordered tonight is as follows:

  • Intel Core 2 Quad Q9400
  • ASUS P5Q motherboard
  • 4 more GB of RAM
  • NVidia 9800GT

You know what they say, a file doesn’t exist unless there are at least 3 copies of it.

VMWare Server 2 and Windows 2003

A couple times now in the past several months I’ve needed to install or upgrade VMWare Server 2 running on Windows 2003 and ran into a problem that takes a little while to re-discover the solution for.  This is for future reference and to help others that may hit this in the future.

The problem is that after installing or upgrading VMWare Server 2, my host machine will no longer be able to be reached across the network.  It can communicate (ping, etc) out, but not the other way around.  Hosted virtual machines also have full connectivity, and they can receive communications from the networks.  It’s very strange, but the solution has been to Disable Routing and Remote Access, reboot, and re-enabled it.

Once that’s done, everything is normal.  Fun Stuff.

FogBugz on Windows Small Business Server 2008

I recently installed FogBugz 6 on 64-bit Windows Small Business Server 2008, and boy was it interesting.  I’ll first note that I’ve had excellent installations and upgrades of FogBugz in the past, so this really caught me off guard and took a while to figure out what was going wrong.

Second, after finding out what the problems were, it’s clear that this applies to far more than just FogBugz.  It all boils down to 32-bit web apps running on the 64 bit platform, and the fact that it’s Small Business Server which has TONS of software preconfigured and running on it.

The first problem I ran into was the app-pool crashing with an error in the event log saying:

The Module DLL C:\Windows\system32\RpcProxy\RpcProxy.dll failed to load. 

Some googling around resulted in learning that RPC over HTTP (a feature used by Outlook Anywhere in Exchange, which is a big part of SBS) is known to break 32-bit worker processes.  One quick solution is to just uninstall the RPC over HTTP Windows feature, and that’s what I did just for speed.

The other fix is to edit applicationhost.config and add preCondition=”bitness64″ for the rpcproxy.dll modules and globalModules entries.  I’ll probably go back and make this change since I’m going to want to use RPC over HTTP.

Anway, I kept getting HTP 500 (500.19 this time) errors when loading the app.  Further investigation revealed that Windows Server Update Services (WSUS), also packaged in Small Business Server, installs a compression module in IIS 7 that, you guessed it, breaks 32 bit app pools.    From the IIS forums, to disable the compression scheme:

%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-[name='xpress']

And, to re-enable if you need:

%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+[name='xpress',doStaticCompression='false',dll='%windir%\system32\inetsrv\suscomp.dll']

And there you have it, after doing those things you can run 32 bit app pools.  As a side-note, I recall that disabling FogBugz’s custom error page was a tremendous help in seeing what was really going on. 

I have very mixed feelings about Small Business Server.  On one hand, there’s so much software configured and running and they all are configured just so to allow them to work.  What’s worse, you really can’t/shouldn’t fight the topology and layout of things that are in place.  If you do, things break and break in very bad ways.  And since there’s so much software installed already, it’s hard to know the side effects of everything.  But on the other hand, it’s thousands and thousands of dollars of software for a fraction of the price.

Aaand finally, if you’re buying a Small Business Server, be sure to get more than 4GB of RAM.  You’ll need it.