Citrix

Alternative to xenstore_client.exe: How to Access XenStore Information Using WMI Interface

  • CTX136422
  • Created On  Feb 05, 2013
  • Updated On  May 20, 2013
  • 7 found this helpful
  • Article
  • Topic : Other

Summary

The XenStore_Client.exe is a small executable program that was (in previous versions of XenServer) distributed with the XenServer Tools and enabled users to access the value of parameters contained in XenStore. This program was removed from XenServer 6.1.0 as there was no knowledge of dependencies or other consumers. However, after the program was removed, Citrix noticed that there were users relying on this unsupported tool. XenStore_Client.exe was never officially supported or tested.

XenServer 6.1.0 introduces an alternative mechanism for extracting XenStore information by using Windows Management Instrumentation (WMI), which offers a far richer interface. This article provides information about using WMI for extracting XenStore information.

Background

This article is for XenServer 6.1.0 customers who use the Windows guest WMI interface as for communicating with XenStore and other hypervisor interfaces. The WMI interface can be used in XenServer 6.1.0 as an alternative to XenStore_Client.exe which was available in earlier versions of XenServer.
WMI offers a mechanism to access information about a Windows Virtual Machine from within the guest Virtual Machine (VM), such as the name of the VM or its IP address.

The Windows Guest WMI Interface

The Windows guest WMI interface is provided by the device driver xeniface.sys, which forms part of the XenServer Tools (Windows paravirtualized drivers). This interface is available to users who have been granted access to the root\wmi namespace (that is, the device driver namespace). By default, this is available only for administrators.

The WMI Interface provides a base singleton object (CitrixXenStoreBase) that can be used to generate individual session objects (CitrixXenStoreSession). These session objects represent individual applications (or functions of an application) and are the objects used to interact with XenStore; to read, write, set, and unset watches.

Sessions might also take advantage of the transaction semantics to ensure atomicity of XenStore operations. The lifetime of watches and transactions are limited by the lifetime of the session object which creates them. On driver load, an object CitrixXenStoreBase, is made available through WMI, which is a singleton object representing xenstore Properties: Uint64 XenTime: LocalTime as set by Windows for the VM, and then adjusted by the hypervisor's clock.

WMI Objects

CitrixXenStoreBase

A singleton object representing XenStore:

Properties

Description

Uint64 XenTime

The Local Time set by windows for the VM, and then adjusted by the hypervisor's clock.

Methods

Description

AddSession(String Id)

Add a CitrixXenStoreSession object to the WMI namespace. The returned value (SessionId) is a unique value which can be used to identify the session which has been created (in case multiple sessions have the same string identifier).

Returns SessionId.

CitrixXenStoreSession

Each instance represents a single session of communication with XenStore:

Properties

Description

String ID

A string to identify the use of the session and to determine if any sessions which have been left open can be closed

Uint32 SessionID

An integer, unique amongst all sessions. This integer is the same as the integer value returned when AddSession creates the session.

Methods

Description

StartTransaction

Until the transaction is ended, all activities on this session occur within a transaction (hence activities will not affect XenStore until the transaction is committed).

CommitTransaction

Attempt to commit the current session's transaction. If this fails, the transaction has not succeeded, and may need to be retried.

EndTransaction

Cancel the current transaction without committing

GetValue (String Pathname)

Returns string value. Returns the value stored at the path Pathname in XenStore

GetChildren(String Pathname)

Returns children { UInt32 NoOfChildNodes, String[NoOfChildNodes]ChildNodes}: For a given node (at PathName), this returns an object containing the number of child nodes, and an array of strings, where each string is the full pathname of a child node.

RemoveValue(String Pathname):

Removes an entry from XenStore (and, if they exist, all descendent entries)

SetValue(String Pathname, String value)

Set the value at a given pathname to Value

Log(String):

Outputs a log message to the hypervisor

SetWatch(String Pathname)

Watch a specified XenStore entry for changes.
Note
: Multiple changes of the same XenStore entry, which occur soon after one another, can be merged into one WMI event. The event is received after all the changes referred to by the merged event occur.

RemoveWatch (String Pathname)

Remove the watch, set previously with SetWatch.

EndSession()

Terminate this session. Remove the session object from the WMI namespace. All watches and transactions associated with the session will be ended

Events

CitrixXenStoreWatchEvent

Event is raised when a particular XenStore entry changes. Multiple close changes of a XenStore event might be merged into one CitrixXenStoreWatchEvent. You can register your interest in receiving such an event by calling CitrixXenStoreSession.SetWatch(pathname)

Properties

Description

String EventId

The pathname of the XenStore value which has changed

CitrixXenStoreUnsuspendedEvent

Event is raised whenever a VM resumes from suspended state.

Powershell - Code Example

The following example uses PowerShell to show how you can script the XenStore WMI interface:


# Locate the base object
$base = gwmi -n root\wmi -cl CitrixXenStoreBase
# Create a session
$sid = $base.AddSession("MyNewSession")
$session = gwmi -n root\wmi -q "select * from CitrixXenStoreSession where SessionId=$($sid.SessionId)"
# Write a value
$session.SetValue("data/TempValue","This is a string")
# Read a value
$session.GetValue("data/TempValue").value
# Read the current VM's name
$session.GetValue("name").value
# Remove a value
$session.RemoveValue("data/TempValue")
#Examine Children
$session.GetChildren("data").children
# Set Watch
$watch = Register-WMiEvent -n root\wmi -q "select * from CitrixXenStoreWatchEvent where EventId='data/TempValue'" -action {write $session.getvalue("data/TempValue") }
$session.setvalue("data/TempValue","HELLO")
$session.setvalue("data/TempValue","WORLD")
$watch.action.output


# Copyright (c) Citrix Systems, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1) Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2) Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
#

Visual Basic - Code Example


rem testwmi.vbs
rem a sanity check for the xeniface wmi interface
rem can be called using cscript.exe
rem will set %ERRORLEVEL% to 0 on success and 1 on failure
rem will also output the text 'SUCCESS' or an error message
rem
rem This code was designed to showcase functionality and
rem should not be regarded as production quality.


Set objWMIService = GetObject("winmgmts:\\.\root\wmi")
Set base = objWmiService.InstancesOf("CitrixXenStoreBase")
Dim answer
Dim answer2
Dim objItem


rem Locate the base object

if (base.Count) <> 1 then
   wscript.echo("Too many base objects found")
   wscript.quit(1)
end if
for each itementry in base
   rem is there a more trivial way of getting the only item from a collection in vbscript?
   set objItem = itementry
next

rem Add two sessions

objitem.AddSession "VBSTestSession", answer
objitem.AddSession "AnotherVBSTestSession", answer2

rem locate the first session

query = "select * from CitrixXenStoreSession where SessionId = '" & answer & "'"
Set sessions = objWMIService.ExecQuery(query)
if (sessions.count) <> 1 then
   wscript.echo("Too many session-1 sessions found")
   wscript.quit(1)
end if
for each itementry in sessions
   rem is there a more trivial way of getting the only item from a collection in vbscript?
   set session = itementry
next

rem locate te second session

query = "select * from CitrixXenStoreSession where SessionId = '" & answer2 & "'"
Set sessions2 = objWMIService.ExecQuery(query)
if (sessions2.count) <> 1 then
   wscript.echo("Too many session-2 sessions found")
   wscript.quit(1)
end if
dim session2
for each ses in sessions2
   Set session2=ses
next

rem ensure we located the expected session

if session.Id <> "VBSTestSession" then
   wscript.echo("incorrect session found")
   wscript.quit(1)
end if

rem blank a set of xenstore entries

session.removevalue "data/wmitestrun"

rem and put a known set of values there

session.SetValue "data/wmitestrun/test1", "Testing"
session.SetValue "data/wmitestrun/test2", "123 Testing"
session.SetValue "data/wmitestrun/test3", "456 Testing"
session.SetValue "data/wmitestrun/test4", "789 Testing"

rem read back a value from xenstore, and check that it is right

session.getvalue "data/wmitestrun/test1", res
if res <> "Testing" then
   wscript.echo("failed writing or reading to data/wmitestrun/test1")
   wscript.echo("read = " & res)
   wscript.quit(1)
end if

rem read back a different value from xenstore, and check that it is right

session.getvalue "data/wmitestrun/test2", res
if res <> "123 Testing" then
   wscript.echo("failed writing or reading to data/wmitestrun/test2")
   wscript.echo("read = " & res)
   wscript.quit(1)
end if

rem transactions
rem test that aborted transactions don't do anything

session.starttransaction()
session.SetValue "data/wmitestrun/test1", "WEIRD"
session.getvalue "data/wmitestrun/test1", res
if res <> "WEIRD" then
   wscript.echo("failed writing or reading within transaction to data/wmitestrun/test1")
   wscript.echo("read = " & res)
   wscript.quit(1)
end if
session.aborttransaction()

session.getvalue "data/wmitestrun/test1", res
if res <> "Testing" then
   wscript.echo("failed reading to data/wmitestrun/test1 after aborted transaction ")
   wscript.echo("read = " & res)
   wscript.quit(1)
end if


rem test that 2 overlapping transactions honour commits and aborts, and raise errors when needed

session.starttransaction()
session2.starttransaction()
session.SetValue "data/wmitestrun/test1", "WEIRD"
session2.SetValue "data/wmitestrun/test1", "Fish"
session.getvalue "data/wmitestrun/test1", res
session2.getvalue "data/wmitestrun/test1", res2
if res <> "WEIRD" then
   wscript.echo("failed writing or reading within transaction to data/wmitestrun/test1 session 1")
   wscript.echo("read = " & res)
   wscript.quit(1)
end if
if res2 <> "Fish" then
   wscript.echo("failed writing or reading within transaction to data/wmitestrun/test1 session 2")
   wscript.echo("read = " & res)
   wscript.quit(1)
end if

on error resume next
session.committransaction()
Err.clear()
if Err.Number <> 0 then
   wscript.echo("Could not commit first transaction")
   wscript.quit(1)
end if
session2.committransaction()
if Err.Number = 0 then
   wscript.echo("Both transactions comitted")
   wscript.quit(1)
end if
session2.aborttransaction()
session2.getvalue "data/wmitestrun/test1", res2
if res2 <> "WEIRD" then
   wscript.echo("failed commiting the correct transaction")
   wscript.echo("read = " & res)
   wscript.quit(1)
end if

rem events
rem set up an event sink

dim refsink
set refsink = CreateObject("WBemScripting.SWbemSink")
wscript.ConnectObject refsink, "EVENTSINK_"
stq = "Select * from CitrixXenStoreWatchEvent"
objwmiservice.ExecNotificationQueryAsync refsink, stq

evtcount = 0

rem watch a xenstore entry

allevents=0
session.setwatch "data/wmitestrun/test1"
session.setvalue "data/wmitestrun/test1","MAGIC"
session.removevalue "data/wmitestrun/test1"
session.setvalue "data/wmitestrun/test1","GOLD"
wscript.sleep(5000)
session.removewatch "data/wmitestrun/test1"

rem check we received an event. Also, since events can be coalesced, check
rem that when we receive our final event, the value we read from test1 is the
rem final value we set it to

rem (note the actual work of counting and checking events is done in the
rem EVENTSINK_OnObjectready sub below)
)
if evtcount <= 4 and allevents <> 1 then)
   wscript.echo("Failed to catch all the expected events")
   wscript.quit(1)
end if

session.removevalue "data/wmitestrun/test1"

rem check that we can read the list of children an entry has

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colOperatingSystems = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")

for each os in colOperatingSystems
   rem is there a more trivial way of getting the only item from a collection in vbscript?
   set myos = os
next

wscript.echo(myos.Version)

if Mid(myos.Version, 1 , 3) <> "6.0" then
   dim children
   session.getchildren "data/wmitestrun", children

   if children.noofchildnodes <> 3 then
     wscript.echo("Failed to find all the expected child nodes")
     wscript.quit(1)
   end if
end if

session.getfirstchild "data/wmitestrun", res
session.getnextsibling res, res

rem end both sessions that we created.

session2.EndSession()
session.EndSession()

Wscript.echo("Success")

Sub EVENTSINK_OnObjectReady(re, rc)
   evtcount = evtcount + 1
   session.getvalue "data/wmitestrun/test1", res
   if res = "GOLD" then
     allevents = 1
   else
     allevents = 0
   end if
end sub




rem Copyright (c) Citrix Systems, Inc.
rem All rights reserved.
rem
rem Redistribution and use in source and binary forms, with or without
rem modification, are permitted provided that the following conditions
rem are met:
rem
rem 1) Redistributions of source code must retain the above copyright
rem notice, this list of conditions and the following disclaimer.
rem
rem 2) Redistributions in binary form must reproduce the above
rem copyright notice, this list of conditions and the following
rem disclaimer in the documentation and/or other materials
rem provided with the distribution.
rem
rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
rem FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
rem COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
rem INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
rem (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
rem SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
rem HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
rem STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
rem ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
rem OF THE POSSIBILITY OF SUCH DAMAGE.
rem


More Information

The following command line tools which are shipped with Windows are particularly useful for exploring WMI:

  • Wbemtext.exe provides a graphical user interface (GUI)
  • Wmic.exe is a command line tool which can be used for accessing WMI


There are a number of external WMI explorers available.

Warning! This Web site might contain links to Web sites controlled by parties other than Citrix. Citrix is not responsible for and does not endorse or accept any responsibility for the contents or use of these third party Web sites. Citrix is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement by Citrix of the linked Web site. It is your responsibility to take precautions to ensure that whatever you select for your use is free of viruses or other items of a destructive nature

Disclaimer

The sample code is provided to you AS IS with no representations, warranties or conditions of any kind. You may use, modify and distribute it at your own risk. CITRIX DISCLAIMS ALL WARRANTIES WHATSOEVER, EXPRESS, IMPLIED, WRITTEN, ORAL OR STATUTORY, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NONINFRINGEMENT. Without limiting the generality of the foregoing, you acknowledge and agree that (a) the sample code may exhibit errors, design flaws or other problems, possibly resulting in loss of data or damage to property; (b) it may not be possible to make the sample code fully functional; and (c) Citrix may, without notice or liability to you, cease to make available the current version and/or any future versions of the sample code. In no event should the code be used to support of ultra-hazardous activities, including but not limited to life support or blasting activities. NEITHER CITRIX NOR ITS AFFILIATES OR AGENTS WILL BE LIABLE, UNDER BREACH OF CONTRACT OR ANY OTHER THEORY OF LIABILITY, FOR ANY DAMAGES WHATSOEVER ARISING FROM USE OF THE SAMPLE CODE, INCLUDING WITHOUT LIMITATION DIRECT, SPECIAL, INCIDENTAL, PUNITIVE, CONSEQUENTIAL OR OTHER DAMAGES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Although the copyright in the code belongs to Citrix, any distribution of the code should include only your own standard copyright attribution, and not that of Citrix. You agree to indemnify and defend Citrix against any and all claims arising from your use, modification or distribution of the code.


Applicable Products

Share your comments or find out more about this topic

Citrix Forums

Languages

N/A

Was this helpful?

Thank you for your feedback!


| Terms of Use | Privacy | Governance