While traditionally I have been a fan of doing App-V (and before that, SoftGrid) sequencing by using a locally installed virtualization software (CHV, Client Hosted Virtualization) like VMware Workstation, for some time already I have actually resorted to using our Hyper-V environment for the sequencing purposes. This is largely because I’m using a laptop almost 100% of the time, and near ultra-portable laptop is not perhaps the best platform for doing client-side virtualization due to necessity of needing external hard drives and so forth.
But doing sequencing on the server-side has also the unpleasant additional burden of requiring management console for managing the state of my virtual machine. As you know, during sequencing it is kind of good practice to snapshot the packaging machine VM in certain important points; for example in case you need to revert back to an earlier state after something went bit wrong during the sequencing or maybe you forgot to do some preparation actions in the beginning. With client-based virtual machine this is usually no big deal as the controls for the VM are right there in the same window, but not so with RDP connection to the packaging machine sitting in the data center. And even if I used Hyper-V’s remote console to connect to the VM, it has a quite limited functionality for the console itself so for instance reverting back to a state in the snapshot tree is not possible using it.
This whole conundrum kind of led me to start thinking about possible smart ways to solve it. As Microsoft’s own accessories for Hyper-V are, ahem, limited in the fashion I just described, maybe there are some other options? What I really, really, wanted to have is a way to do everything solely inside the VM guest; that way I could just RDP to the machine and handle all the workflow inside the session itself without having to “switch context” between remote session and some other tools. Being a lazy person to look around too much for subpar ready-made solutions, and being a software developer in nature, I immediately saw an opportunity to do some coding of my own. And besides, I have not heard about suitable solution for this problem, at least which would not require extensive infrastructure pieces to be in place (VDI, I’m looking at you). What I primarily wanted, and what I think would be useful for lot of other people as well, is to be able to snapshot and revert to specific snapshot from within the guest operating system session. This would enable fast “backup” and “recovery” in case I need to step back in time or maybe to switch a completely new starting point for my sequencing.
Oh and yes, there’s also one additional problem about using Hyper-V’s management console: since it’s very much tied to the authentication, security, DCOM and whatnot of the Hyper-V server itself, it is truly pain in the ass to make it work remotely; especially if your Hyper-V host is not part of the same security domain as the rest of your machines, like your laptop…
To make it little bit easier there’s even a separate helper application for setting things up correctly both in the server side and on a client (HVRemote), and even then you still need to reboot the Hyper-V host to make some setting changes to take effect! I can only guess that this whole way-too-integrated model is also partially the reason why there’s a separate way for managing DMZ Hyper-V hosts with SCVMM from the ones that are in the same AD domain.
How to have control over Hyper-V from within guest
Okay, so, having ruled out using Hyper-V’s own management tool, the main issue that immediately came into my mind was how and even if it is at all possible to enable such functionality from the guest VM? After all, the purpose of the machine virtualization is to isolate the virtual machine and its operating system from the host system. I was pretty sure that Microsoft has not provided any hooks into controlling the state of the virtual machine from within the virtual machine itself, except of course when it comes to doing rebooting and other normal OS –controlled operations.
The most obvious idea on how to implement such a communication path is to use a network between the guest and the host. That’s pretty standard way of how most software products needing to talk between different hosts are constructed. So in this case it would be one party listening on the Hyper-V server and another party inside the VM. However, even cursory thinking of that model revealed that there are already few pretty obvious issues with this model and I really did not want to start solving those kind of hardships as this was supposed to be a fairly straightforward implementation:
First issue is the distributed usage model that comes from the fact that you may have number of Hyper-V hosts and even greater number of guest VMs: number of named pipes, TCP or whatever network protocol sessions have you could grow quite large and complex to manage. Not to mention all the usual issues of potential loss of network sessions, reconnections etc. which require a lot of synchronization internally and traffic on the wire.
Second, and even more troublesome, issue is of the security. Since you would be talking about direct network connectivity between host and the guest, how does that play out in the situation wherein your Hyper-V hosts are logically fully separated from the guest VM networks? It doesn’t.
And thirdly, when using a network-based communication path, there’s also the issue of in what manner and how easily the client piece could be configured so that it knows to contact its own Hyper-V hosting system using correct network address. Or should it be other way around? And then what about the potential firewall issues?
Because I really wanted as easy as possible configuration and setup for the system, I decided that using network is not an option in this case. And in a way it’s also bit of overkill since you only need to have communication path between the guest and the host: they are, by definition, already on the same box!
After looking around a bit, I remembered that there’s actually a very vaguely named service under Integration Service section in the Hyper-V’s VM settings screen, called “Data Exchange”:
Judging from the name, it does sounds like something that maybe could be used to establish good-enough connection between the host system and the virtual machine. Yes, you would need this service and the Hyper-V Integration Components (IC) installed and enabled inside your VM, but I’m not aware why anyone would purposefully not want to install these as they enhance the operation of the guest operating system. Like in the VMware world: why would you not install VMware Tools?!
Having discovered this potential avenue of enabling the communication flow from guest-based tool to the Hyper-V host –based “controller” software – and back – I really needed to start researching what this Data Exchange service actually enables inside the VM and how to use it from your own code. I haven’t seen it described pretty much anywhere in the UI at least, so there must be documentation about it somewhere, right?
Turns out that in a grand tradition of Microsoft documentation, what I could find was very far and between, not to mention that the official information that exists is in certain critical places not very helpful at all. Some of the stuff was actually more discoverable from various blog articles from the times of release of Hyper-V V1, and even those concentrated mostly on using Powershell to do things. What a disappointment, I must say!
Unlike VMware’s VMCI (that’s “Virtual Machine Communication Interface”) which operates as a separate API, Microsoft’s Hyper-V Data Exchange – on the client side – is actually something called “KVP Exchange” which stands for “Key Value Pair”. As you probably couldn’t guess from the term, that’s exchanging data between host and guest using registry values…
Okay, sounds simple enough for the client, but what about the host side of the equation? Well, that’s a bit more complex beast as the whole programmatic management of Hyper-V Server is not a separate Windows API at all, but rather Hyper-V has its own provider for the WMI. And boy, the WMI as a technology is about the last piece of API I want to interact in the Windows (well, not really, some parts of Win32 are really awful too when using managed code, and especially if there’s COM involved) as it’s probably built on purpose to be as complex as possible; marrying stupid SQL-style syntax to object-oriented extravaganza.
If on the client side it’s simple enough to read and write registry values (please note that usage of registry values does not make a good substitute to stream-oriented socket-interface when you must move data back and forth in large quantities!) to make communication to happen, on the server side there’s no such method available. Everything must be done through WMI interface, including reading and writing those registry values in the virtual machine. And there’s a quite a big number of WMI classes for Hyper-V alone, depending on what you are doing.
This part really was the single biggest time consumer when trying to build working server-side component and the reason is quite simple. While the MSDN gave relatively good code examples for most of the WMI Hyper-V classes and functions, there is a significant lack of textual explanation of what is supposed to happen, how things really relate and especially what the meanings of the possible error conditions are. It’s very nice to get “Invalid parameter (32773)” as a result for some operation when there’s no freaking explanation what the heck was wrong in the method call parameters in the first place!
However, after a number of trials and tribulations I finally managed to make WMI interface as well as the KVP Exchange to do my bidding, as so I’m happy to report that I have almost a completed working solution for managing Hyper-V snapshots from within the VM!
Introducing: HyperSnapshot
We decided to call this new product HyperSnapshot, and its sole purpose in life is to enable fully guest-based operation of a) making snapshots at will and b) reverting to those snapshots at will; all without having to resort to using Hyper-V management tools. The only requirement that the product has is that you install a client piece inside all your virtual machines that you want to enable snapshot –capabilities, as well as service component to each Hyper-V host machine having such guests. But there is absolutely no requirement of re-configuration of virtual machines to use COM port redirection to named pipes, or anything silly like that.
The client will sit in the notification area, once started, and the operation is done from the context menu of that notification area icon. It will auto-discover your Hyper-V host system, if it has Data Exchange enabled for VM as well as the server-side piece of HyperSnapshot installed. No manual configuration what so ever required.
To operate the software, you can take snapshot of the current state:
…after a while the client will notify that the snapshot operation has been completed:
And you can revert back to one of the saved snapshots that the virtual machine has, browsing through the snapshot tree you might have for the VM:
At the moment the client unfortunately requires administrative privileges to run (it’s actually manifested so that the Windows UAC will prompt for elevation if necessary), because the client needs write access to HKLM branch of the registry.
The server-side piece is Windows Service, which can be installed by using provided installation script. The service will run automatically and in the background, communicating with the virtual machines that have the client installed and active:
Again, there’s nothing to configure or actually no need for UI at all!
Please note that HyperSnapshot has been tested mostly with the Windows 2008 R2 version of the Hyper-V (V2), but it should work just as fine with Windows 2008 version of the Hyper-V (V1).
Finally, few words about the availability and licensing aspects of this software:
The current incarnation of the software is provided free of charge by Gridmetric (to be released in our Free Tools –section later this week or early next week).
We will – however – be releasing a licensed version inside a short timeframe, which will have some enhanced capabilities over the free version, and will not require administrative privileges from the end user. More info to come in due time!
Trackbacks/Pingbacks
[…] Last week I wrote about the construction, and the challenges, of the creation of a guest virtual machine -based snapshot management solution (or “tool”) for Hyper-V environments. As promised, it’s now available for downloading. […]