pax_global_header00006660000000000000000000000064132546510430014515gustar00rootroot0000000000000052 comment=1ea5634256b9a30dde3f86bfce08e4269899b884 xe-guest-utilities-7.10.0/000077500000000000000000000000001325465104300153545ustar00rootroot00000000000000xe-guest-utilities-7.10.0/.gitignore000066400000000000000000000004161325465104300173450ustar00rootroot00000000000000# Compiled Object files, Static and Dynamic libs (Shared Objects) *.o *.a *.so # Folders _obj _test bin # Architecture specific extensions/prefixes *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* _testmain.go *.exe *.test *.prof xe-guest-utilities-7.10.0/.travis.yml000066400000000000000000000004331325465104300174650ustar00rootroot00000000000000language: go sudo: false go: # Used for building XenServer Dundee - 1.4.2 # Forwards compatibility - tip script: - gofmtresult=$(gofmt -s -l .); if [[ -n $gofmtresult ]]; then echo -e "Please run \"gofmt -s -w .\" before committing for the below:\n$gofmtresult"; false; fi xe-guest-utilities-7.10.0/LICENSE000066400000000000000000000024211325465104300163600ustar00rootroot00000000000000Copyright (c) 2015, Citrix Systems 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. xe-guest-utilities-7.10.0/Makefile000066400000000000000000000055101325465104300170150ustar00rootroot00000000000000PRODUCT_MAJOR_VERSION=6 PRODUCT_MINOR_VERSION=6 PRODUCT_MICRO_VERSION=80 PRODUCT_VERSION = $(PRODUCT_MAJOR_VERSION).$(PRODUCT_MINOR_VERSION).$(PRODUCT_MICRO_VERSION) GO_BUILD = go build GO_FLAGS = -v REPO = $(shell pwd) SOURCEDIR = $(REPO)/mk BUILDDIR = $(REPO)/build GOBUILDDIR = $(BUILDDIR)/gobuild STAGEDIR = $(BUILDDIR)/stage OBJECTDIR = $(BUILDDIR)/obj DISTDIR = $(BUILDDIR)/dist OBJECTS := OBJECTS += $(OBJECTDIR)/xe-daemon OBJECTS += $(OBJECTDIR)/xenstore PACKAGE = xe-guest-utilities VERSION = $(PRODUCT_VERSION) RELEASE := $(shell git rev-list HEAD | wc -l) ARCH := $(shell go version|awk -F'/' '{print $$2}') ifeq ($(ARCH), amd64) ARCH = x86_64 endif XE_DAEMON_SOURCES := XE_DAEMON_SOURCES += ./xe-daemon/xe-daemon.go XE_DAEMON_SOURCES += ./syslog/syslog.go XE_DAEMON_SOURCES += ./system/system.go XE_DAEMON_SOURCES += ./guestmetric/guestmetric.go XE_DAEMON_SOURCES += ./guestmetric/guestmetric_linux.go XE_DAEMON_SOURCES += ./xenstoreclient/xenstore.go XENSTORE_SOURCES := XENSTORE_SOURCES += ./xenstore/xenstore.go XENSTORE_SOURCES += ./xenstoreclient/xenstore.go .PHONY: build build: $(DISTDIR)/$(PACKAGE)_$(VERSION)-$(RELEASE)_$(ARCH).tgz .PHONY: clean clean: $(RM) -rf $(BUILDDIR) $(DISTDIR)/$(PACKAGE)_$(VERSION)-$(RELEASE)_$(ARCH).tgz: $(OBJECTS) ( mkdir -p $(DISTDIR) ; \ install -d $(STAGEDIR)/etc/init.d/ ; \ install -m 755 $(SOURCEDIR)/xe-linux-distribution.init $(STAGEDIR)/etc/init.d/xe-linux-distribution ; \ install -d $(STAGEDIR)/usr/sbin/ ; \ install -m 755 $(SOURCEDIR)/xe-linux-distribution $(STAGEDIR)/usr/sbin/xe-linux-distribution ; \ install -m 755 $(OBJECTDIR)/xe-daemon $(STAGEDIR)/usr/sbin/xe-daemon ; \ install -d $(STAGEDIR)/usr/bin/ ; \ install -m 755 $(OBJECTDIR)/xenstore $(STAGEDIR)/usr/bin/xenstore ; \ ln -sf /usr/bin/xenstore $(STAGEDIR)/usr/bin/xenstore-read ; \ ln -sf /usr/bin/xenstore $(STAGEDIR)/usr/bin/xenstore-write ; \ ln -sf /usr/bin/xenstore $(STAGEDIR)/usr/bin/xenstore-exists ; \ ln -sf /usr/bin/xenstore $(STAGEDIR)/usr/bin/xenstore-rm ; \ ln -sf /usr/bin/xenstore $(STAGEDIR)/usr/bin/xenstore-list ; \ install -d $(STAGEDIR)/etc/udev/rules.d/ ; \ install -m 644 $(SOURCEDIR)/xen-vcpu-hotplug.rules $(STAGEDIR)/etc/udev/rules.d/z10_xen-vcpu-hotplug.rules ; \ cd $(STAGEDIR) ; \ tar cf $@ * \ ) $(OBJECTDIR)/xe-daemon: $(XE_DAEMON_SOURCES:%=$(GOBUILDDIR)/%) mkdir -p $(OBJECTDIR) $(GO_BUILD) $(GO_FLAGS) -o $@ $< $(OBJECTDIR)/xenstore: $(XENSTORE_SOURCES:%=$(GOBUILDDIR)/%) $(GOROOT) mkdir -p $(OBJECTDIR) $(GO_BUILD) $(GO_FLAGS) -o $@ $< $(GOBUILDDIR)/%: $(REPO)/% mkdir -p $$(dirname $@) cat $< | \ sed -e "s/@PRODUCT_MAJOR_VERSION@/$(PRODUCT_MAJOR_VERSION)/g" | \ sed -e "s/@PRODUCT_MINOR_VERSION@/$(PRODUCT_MINOR_VERSION)/g" | \ sed -e "s/@PRODUCT_MICRO_VERSION@/$(PRODUCT_MICRO_VERSION)/g" | \ sed -e "s/@NUMERIC_BUILD_NUMBER@/$(RELEASE)/g" \ > $@ xe-guest-utilities-7.10.0/README.md000066400000000000000000000010721325465104300166330ustar00rootroot00000000000000[![Build Status](https://travis-ci.org/xenserver/xe-guest-utilities.svg?branch=master)](https://travis-ci.org/xenserver/xe-guest-utilities) go-guest-utilites =================== This is the golang guest utilites for XenServer XenStore CLI ----------- xe-guest-utilities.git/xenstore XenServer Guest Utilities ----------- xe-guest-utilities.git/xe-daemon Build Instructions =================== [Go development environment](https://golang.org/doc/install) is required to build the guest utilities. Type `make` or `make build` to build the xenstore and xe-daemon. xe-guest-utilities-7.10.0/guestmetric/000077500000000000000000000000001325465104300177075ustar00rootroot00000000000000xe-guest-utilities-7.10.0/guestmetric/guestmetric.go000066400000000000000000000013651325465104300225760ustar00rootroot00000000000000package guestmetric import ( "bytes" "os/exec" ) type GuestMetric map[string]string type CollectFunc func() (GuestMetric, error) type GuestMetricsCollector interface { CollectOS() (GuestMetric, error) CollectMisc() (GuestMetric, error) CollectNetworkAddr() (GuestMetric, error) CollectDisk() (GuestMetric, error) CollectMemory() (GuestMetric, error) } func runCmd(name string, args ...string) (output string, err error) { cmd := exec.Command(name, args...) var out bytes.Buffer cmd.Stdout = &out err = cmd.Run() if err != nil { return "", err } output = out.String() return output, nil } func prefixKeys(prefix string, m GuestMetric) GuestMetric { m1 := make(GuestMetric, 0) for k, v := range m { m1[prefix+k] = v } return m1 } xe-guest-utilities-7.10.0/guestmetric/guestmetric_linux.go000066400000000000000000000214621325465104300240150ustar00rootroot00000000000000package guestmetric import ( xenstoreclient "../xenstoreclient" "bufio" "bytes" "fmt" "os" "path/filepath" "regexp" "sort" "strconv" "strings" ) type Collector struct { Client xenstoreclient.XenStoreClient Ballon bool Debug bool } func (c *Collector) CollectOS() (GuestMetric, error) { current := make(GuestMetric, 0) f, err := os.OpenFile("/var/cache/xe-linux-distribution", os.O_RDONLY, 0666) if err != nil { return nil, err } defer f.Close() scanner := bufio.NewScanner(f) for scanner.Scan() { line := scanner.Text() if strings.Contains(line, "=") { parts := strings.SplitN(line, "=", 2) k := strings.TrimSpace(parts[0]) v := strings.TrimSpace(strings.Trim(strings.TrimSpace(parts[1]), "\"")) current[k] = v } } return prefixKeys("data/", current), nil } func (c *Collector) CollectMisc() (GuestMetric, error) { current := make(GuestMetric, 0) if c.Ballon { current["control/feature-balloon"] = "1" } else { current["control/feature-balloon"] = "0" } current["attr/PVAddons/Installed"] = "1" current["attr/PVAddons/MajorVersion"] = "@PRODUCT_MAJOR_VERSION@" current["attr/PVAddons/MinorVersion"] = "@PRODUCT_MINOR_VERSION@" current["attr/PVAddons/MicroVersion"] = "@PRODUCT_MICRO_VERSION@" current["attr/PVAddons/BuildVersion"] = "@NUMERIC_BUILD_NUMBER@" return current, nil } func (c *Collector) CollectMemory() (GuestMetric, error) { current := make(GuestMetric, 0) f, err := os.OpenFile("/proc/meminfo", os.O_RDONLY, 0666) if err != nil { return nil, err } defer f.Close() scanner := bufio.NewScanner(f) for scanner.Scan() { parts := regexp.MustCompile(`\w+`).FindAllString(scanner.Text(), -1) switch parts[0] { case "MemTotal": current["meminfo_total"] = parts[1] case "MemFree": current["meminfo_free"] = parts[1] } } return prefixKeys("data/", current), nil } func enumNetworkAddresses(iface string) (GuestMetric, error) { const ( IP_RE string = `(\d{1,3}\.){3}\d{1,3}` IPV6_RE string = `[\da-f:]+[\da-f]` ) var ( IP_IPV4_ADDR_RE = regexp.MustCompile(`inet\s*(` + IP_RE + `).*\se[a-zA-Z0-9]+[\s\n]`) IP_IPV6_ADDR_RE = regexp.MustCompile(`inet6\s*(` + IPV6_RE + `)`) IFCONFIG_IPV4_ADDR_RE = regexp.MustCompile(`inet addr:\s*(` + IP_RE + `)`) IFCONFIG_IPV6_ADDR_RE = regexp.MustCompile(`inet6 addr:\s*(` + IPV6_RE + `)`) ) d := make(GuestMetric, 0) var v4re, v6re *regexp.Regexp var out string var err error if out, err = runCmd("ip", "addr", "show", iface); err == nil { v4re = IP_IPV4_ADDR_RE v6re = IP_IPV6_ADDR_RE } else if out, err = runCmd("ifconfig", iface); err == nil { v4re = IFCONFIG_IPV4_ADDR_RE v6re = IFCONFIG_IPV6_ADDR_RE } else { return nil, fmt.Errorf("Cannot find ip/ifconfig command") } m := v4re.FindAllStringSubmatch(out, -1) if m != nil { for i, parts := range m { d[fmt.Sprintf("ipv4/%d", i)] = parts[1] } } m = v6re.FindAllStringSubmatch(out, -1) if m != nil { for i, parts := range m { d[fmt.Sprintf("ipv6/%d", i)] = parts[1] } } return d, nil } func getPlainVifId(path string) (string, error) { nodenamePath := fmt.Sprintf("%s/device/nodename", path) strLine, err := readSysfs(nodenamePath) if err != nil { return "", err } vifId := "" reNodename := regexp.MustCompile(`^device\/vif\/(\d+)$`) if matched := reNodename.FindStringSubmatch(strLine); matched != nil { vifId = matched[1] } if vifId == "" { return "", fmt.Errorf("Not found string like \"device/vif/[id]\" in file %s", nodenamePath) } else { return vifId, nil } } func (c *Collector) getSriovVifId(path string) (string, error) { sriovDevicePath := "xenserver/device/net-sriov-vf" macAddress, err := readSysfs(path + "/address") if err != nil { return "", err } subPaths, err := c.Client.List(sriovDevicePath) if err != nil { return "", err } for _, subPath := range subPaths { iterMac, err := c.Client.Read(fmt.Sprintf("%s/%s/mac", sriovDevicePath, subPath)) if err != nil { continue } if iterMac == macAddress { return subPath, nil } } return "", fmt.Errorf("Cannot find a MAC address to map with %s", path) } // return vif_xenstore_prefix * vif_id * error where // `vif_xenstore_prefix` could be either `attr/vif` for plain VIF or // `xenserver/attr/net-sriov-vf` for SR-IOV VIF func (c *Collector) getTargetXenstorePath(path string) (string, string, error) { plainVifPrefix := "attr/vif" sriovVifPrefix := "xenserver/attr/net-sriov-vf" // try to get `vif_id` from nodename interface, only a plain VIF have the nodename interface. vifId, err1 := getPlainVifId(path) if vifId != "" { return plainVifPrefix, vifId, nil } // not a plain VIF, it could possible be an SR-IOV VIF, try to get vif_id from MAC address mapping vifId, err2 := c.getSriovVifId(path) if vifId != "" { return sriovVifPrefix, vifId, nil } return "", "", fmt.Errorf("Failed to get VIF ID, errors: %s | %s", err1.Error(), err2.Error()) } func (c *Collector) CollectNetworkAddr() (GuestMetric, error) { current := make(GuestMetric, 0) var paths []string vifNamePrefixList := [...]string{"eth", "eno", "ens", "emp", "enx"} for _, prefix := range vifNamePrefixList { prefixPaths, err := filepath.Glob(fmt.Sprintf("/sys/class/net/%s*", prefix)) if err != nil { return nil, err } paths = append(paths, prefixPaths...) } for _, path := range paths { // a path is going to be like "/sys/class/net/eth0" prefix, vifId, err := c.getTargetXenstorePath(path) if err != nil { continue } iface := filepath.Base(path) if addrs, err := enumNetworkAddresses(iface); err == nil { for tag, addr := range addrs { current[fmt.Sprintf("%s/%s/%s", prefix, vifId, tag)] = addr } } } return current, nil } func readSysfs(filename string) (string, error) { f, err := os.OpenFile(filename, os.O_RDONLY, 0666) if err != nil { return "", err } defer f.Close() scanner := bufio.NewScanner(f) scanner.Scan() return scanner.Text(), nil } func (c *Collector) CollectDisk() (GuestMetric, error) { pi := make(GuestMetric, 0) disks := make([]string, 0) paths, err := filepath.Glob("/sys/block/*/device") if err != nil { return nil, err } for _, path := range paths { disk := filepath.Base(strings.TrimSuffix(filepath.Dir(path), "/")) disks = append(disks, disk) } var sortedDisks sort.StringSlice = disks sortedDisks.Sort() part_idx := 0 for _, disk := range sortedDisks[:] { paths, err = filepath.Glob(fmt.Sprintf("/dev/%s?*", disk)) if err != nil { return nil, err } for _, path := range paths { p := filepath.Base(path) line, err := readSysfs(fmt.Sprintf("/sys/block/%s/%s/size", disk, p)) if err != nil { return nil, err } size, err := strconv.ParseInt(line, 10, 64) if err != nil { return nil, err } blocksize := 512 if bs, err := readSysfs(fmt.Sprintf("/sys/block/%s/queue/physical_block_size", p)); err == nil { if bs1, err := strconv.Atoi(bs); err == nil { blocksize = bs1 } } real_dev := "" if c.Client != nil { nodename, err := readSysfs(fmt.Sprintf("/sys/block/%s/device/nodename", disk)) if err == nil { backend, err := c.Client.Read(fmt.Sprintf("%s/backend", nodename)) if err != nil { return nil, err } real_dev, err = c.Client.Read(fmt.Sprintf("%s/dev", backend)) if err != nil { return nil, err } } } name := path blkid, err := runCmd("blkid", "-s", "UUID", path) if err != nil { // ignore blkid errors blkid = "" } if strings.Contains(blkid, "=") { parts := strings.SplitN(strings.TrimSpace(blkid), "=", 2) name = fmt.Sprintf("%s(%s)", name, strings.Trim(parts[1], "\"")) } i := map[string]string{ "extents/0": real_dev, "name": name, "size": strconv.FormatInt(size*int64(blocksize), 10), } output, err := runCmd("pvs", "--noheadings", "--units", "b", path) if err == nil && output != "" { parts := regexp.MustCompile(`\s+`).Split(output, -1)[1:] i["free"] = strings.TrimSpace(parts[5])[:len(parts[5])-1] i["filesystem"] = strings.TrimSpace(parts[2]) i["mount_points/0"] = "[LVM]" } else { output, err = runCmd("mount") if err == nil { m := regexp.MustCompile(`(?m)^(\S+) on (\S+) type (\S+)`).FindAllStringSubmatch(output, -1) if m != nil { for _, parts := range m { if parts[1] == path { i["mount_points/0"] = parts[2] i["filesystem"] = parts[3] break } } } } output, err = runCmd("df", path) if err == nil { scanner := bufio.NewScanner(bytes.NewReader([]byte(output))) scanner.Scan() scanner.Scan() parts := regexp.MustCompile(`\s+`).Split(scanner.Text(), -1) free, err := strconv.ParseInt(parts[3], 10, 64) if err == nil { i["free"] = strconv.FormatInt(free*1024, 10) } } } for k, v := range i { pi[fmt.Sprintf("data/volumes/%d/%s", part_idx, k)] = v } part_idx += 1 } } return pi, nil } xe-guest-utilities-7.10.0/guestmetric/guestmetric_test.go000066400000000000000000000020111325465104300236220ustar00rootroot00000000000000package guestmetric import ( "testing" ) func TestCollector(t *testing.T) { c := Collector{ Client: nil, } funcs := []CollectFunc{ c.CollectDisk, c.CollectMemory, c.CollectMisc, c.CollectNetworkAddr, } for _, f := range funcs { metric, err := f() if err != nil { t.Errorf("%#v error: %#v\n", f, err) } t.Logf("%#v return %#v", f, metric) } } func doBenchmark(b *testing.B, f CollectFunc) { b.Logf("doBenchmark 1000 for %#v", f) for i := 0; i < 1000; i++ { if _, err := f(); err != nil { b.Errorf("%#v error: %#v\n", f, err) } } } func BenchmarkCollectorDisk(b *testing.B) { c := Collector{ Client: nil, } doBenchmark(b, c.CollectDisk) } func BenchmarkCollectMemory(b *testing.B) { c := Collector{ Client: nil, } doBenchmark(b, c.CollectMemory) } func BenchmarkCollectMisc(b *testing.B) { c := Collector{ Client: nil, } doBenchmark(b, c.CollectMisc) } func BenchmarkCollectNetwork(b *testing.B) { c := Collector{ Client: nil, } doBenchmark(b, c.CollectNetworkAddr) } xe-guest-utilities-7.10.0/mk/000077500000000000000000000000001325465104300157635ustar00rootroot00000000000000xe-guest-utilities-7.10.0/mk/Citrix.repo000066400000000000000000000005371325465104300201210ustar00rootroot00000000000000[citrix] name=@PRODUCT_BRAND@ @PRODUCT_VERSION@ updates for ^DISTRO^ mirrorlist=http://updates.vmd.citrix.com/@PRODUCT_BRAND@/@PRODUCT_VERSION@/^DISTRO^/mirrorlist #baseurl=http://updates.vmd.citrix.com/@PRODUCT_BRAND@/@PRODUCT_VERSION@/^DISTRO^/ gpgcheck=1 gpgkey=http://updates.vmd.citrix.com/@PRODUCT_BRAND@/RPM-GPG-KEY-@PRODUCT_VERSION@ enabled=1 xe-guest-utilities-7.10.0/mk/Makefile000066400000000000000000000003131325465104300174200ustar00rootroot00000000000000ifeq ($(COMPONENT),guest-utilities-rpm) include Makefile.rpm endif ifeq ($(COMPONENT),guest-utilities-deb) include Makefile.deb endif ifeq ($(COMPONENT),guest-utilities-tgz) include Makefile.tgz endif xe-guest-utilities-7.10.0/mk/Makefile.deb000066400000000000000000000136111325465104300201560ustar00rootroot00000000000000# -*- makefile -*- USE_BRANDING := yes IMPORT_VERSIONS := yes include $(B_BASE)/common.mk REPO= $(call git_loc,xe-guest-utilities) REPOSTAMP= $(call git_req,xe-guest-utilities) ARCHS = i386 amd64 DISTROS = lenny DEB_BUILT_COOKIE = $(MY_OBJ_DIR)/.deb_built_cookie DEB_REPO_COOKIE = $(MY_OBJ_DIR)/.deb_%_repo_cookie DEB_REPO_COOKIES = $(DISTROS:%=$(DEB_REPO_COOKIE)) STAGING_DIR = $(MY_OBJ_DIR)/staging INSTALL_DIR = $(STAGING_DIR)/Linux/ VERSIONS_FILE = $(MY_OBJ_DIR)/versions TOOLS_TARBALL = $(MY_OUTPUT_DIR)/tools-files.tar.bz2 PACKAGE = xe-guest-utilities VERSION = $(PRODUCT_VERSION) RELEASE := $(shell git --git-dir="$(REPO)/.git" rev-list HEAD | wc -l) SOURCEDIR := $(MY_OBJ_DIR)/$(PACKAGE)-$(VERSION)/ DEBIANDIR := $(SOURCEDIR)/debian/ DEBPOOLDIR := debian/pool/main/x/xe-guest-utilities GOTARBALL = /distfiles/golang/go1.4.2.linux-386.tar.gz GOROOT = $(MY_OBJ_DIR)/go GOBIN = GOROOT=$(GOROOT) $(GOROOT)/bin/go GOFLAGS = -v -ldflags="-s -w" GOBUILDDIR = $(MY_OBJ_DIR)/gobuild GO_SOURCE_REPO = $(call git_loc,xe-guest-utilities) XE_DAEMON_GO_SOURCES := XE_DAEMON_GO_SOURCES += ./xe-daemon/xe-daemon.go # this should be the first one XE_DAEMON_GO_SOURCES += ./syslog/syslog.go XE_DAEMON_GO_SOURCES += ./system/system.go XE_DAEMON_GO_SOURCES += ./guestmetric/guestmetric.go XE_DAEMON_GO_SOURCES += ./guestmetric/guestmetric_linux.go XE_DAEMON_GO_SOURCES += ./xenstoreclient/xenstore.go XENSTORE_GO_SOURCES := XENSTORE_GO_SOURCES += ./xenstore/xenstore.go # this should be the first one XENSTORE_GO_SOURCES += ./xenstoreclient/xenstore.go SOURCES := SOURCES += $(SOURCEDIR)/xe-linux-distribution SOURCES += $(SOURCEDIR)/xe-daemon SOURCES += $(SOURCEDIR)/xenstore SOURCES += $(SOURCEDIR)/LICENSE SOURCES += $(SOURCEDIR)/citrix.list SOURCES += $(SOURCEDIR)/xen-vcpu-hotplug.rules SOURCES += $(DEBIANDIR)/xe-linux-distribution.init SOURCES += $(DEBIANDIR)/xe-guest-utilities.postinst SOURCES += $(DEBIANDIR)/xe-guest-utilities.prerm SOURCES += $(DEBIANDIR)/control SOURCES += $(DEBIANDIR)/changelog SOURCES += $(DEBIANDIR)/rules SOURCES += $(DEBIANDIR)/compat SOURCES += $(DEBIANDIR)/copyright SOURCES += $(DEBIANDIR)/$(PACKAGE).dirs 822_DATE := $(shell date -R) .PHONY: build build: $(TOOLS_TARBALL) $(DEB_BUILT_COOKIE) $(DEB_REPO_COOKIES) $(ARCHS:%=$(MY_OUTPUT_DIR)/xe-guest-utilities.%.inc) $(MY_SOURCES)/MANIFEST @ : .PHONY: clean clean: rm -f $(DEB_BUILT_COOKIE) rm -f $(DEB_REPO_COOKIES) rm -rf $(GOROOT) rm -rf $(SOURCEDIR) rm -rf $(DEBIANDIR) rm -f $(MY_OBJ_DIR)/overrides local-brand := sed -e 's,@VERSION@,$(VERSION),g' \ -e 's,@RELEASE@,$(RELEASE),g' \ -e "s!@822DATE@!$(822_DATE)!g" $(DEBIANDIR)/%: $(REPO)/% mkdir -p $(DEBIANDIR) $(call brand,$<) | $(call local-brand) > $@ $(DEBIANDIR)/xe-linux-distribution.init: $(REPO)/mk/xe-linux-distribution.init mkdir -p $(DEBIANDIR) $(call brand,$<) | $(call local-brand) > $@ $(SOURCEDIR)/%: $(REPO)/mk/% mkdir -p $(SOURCEDIR) $(call brand,$<) | $(call local-brand) > $@ $(SOURCEDIR)/citrix.list: citrix.list $(call brand,$<) > $@ $(SOURCEDIR)/xe-daemon: $(XE_DAEMON_GO_SOURCES:%=$(GOBUILDDIR)/%) $(GOROOT) $(GOBIN) build $(GOFLAGS) -o $@ $< $(SOURCEDIR)/xenstore: $(XENSTORE_GO_SOURCES:%=$(GOBUILDDIR)/%) $(GOROOT) $(GOBIN) build $(GOFLAGS) -o $@ $< $(SOURCEDIR)/LICENSE: $(REPO)/LICENSE $(call brand,$<) > $@ $(GOBUILDDIR)/%: $(GO_SOURCE_REPO)/% mkdir -p $$(dirname $@) $(call brand,$<) > $@ $(MY_OUTPUT_DIR)/xe-guest-utilities.%.inc: $(MY_OUTPUT_DIR)/.dirstamp ( echo XE_GUEST_UTILITIES_PKG_NAME := xe-guest-utilities ; \ echo XE_GUEST_UTILITIES_PKG_VERSION := $(VERSION)-$(RELEASE) ; \ echo XE_GUEST_UTILITIES_PKG_ARCH := $* ; \ echo XE_GUEST_UTILITIES_PKG_FILE_i386 := $(DEBPOOLDIR)/$(PACKAGE)_$(VERSION)-$(RELEASE)_i386.deb ; \ echo XE_GUEST_UTILITIES_PKG_FILE_amd64 := $(DEBPOOLDIR)/$(PACKAGE)_$(VERSION)-$(RELEASE)_amd64.deb ; \ )>$@ $(DEB_BUILT_COOKIE): $(SOURCES) mkdir -p $(MY_OUTPUT_DIR)/$(DEBPOOLDIR) chmod +x $(DEBIANDIR)/rules cd $(SOURCEDIR) && dpkg-buildpackage -Zgzip -S -us -uc cp $(MY_OBJ_DIR)/$(PACKAGE)_$(VERSION)-$(RELEASE).dsc $(MY_OUTPUT_DIR)/$(DEBPOOLDIR) cp $(MY_OBJ_DIR)/$(PACKAGE)_$(VERSION)-$(RELEASE).tar.gz $(MY_OUTPUT_DIR)/$(DEBPOOLDIR) set -xe ; for arch in $(ARCHS) ; do \ ( cd $(SOURCEDIR) && dpkg-buildpackage -Zgzip -b -a$${arch} -us -uc ) ; \ cp $(MY_OBJ_DIR)/$(PACKAGE)_$(VERSION)-$(RELEASE)_$${arch}.deb $(MY_OUTPUT_DIR)/$(DEBPOOLDIR) ; \ done touch $@ $(MY_SOURCES)/MANIFEST: $(MY_SOURCES_DIRSTAMP) ( echo "$(COMPONENT) BSD file $(MY_OUTPUT_DIR)/$(DEBPOOLDIR)/$(PACKAGE)_$(VERSION)-$(RELEASE).dsc" ; \ echo "$(COMPONENT) BSD file $(MY_OUTPUT_DIR)/$(DEBPOOLDIR)/$(PACKAGE)_$(VERSION)-$(RELEASE).tar.gz" ; \ ) >$@ .PHONY: sources sources: $(MY_SOURCES)/MANIFEST @ : $(MY_OBJ_DIR)/overrides: echo xe-guest-utilities optional base >$@ $(DEB_REPO_COOKIE): $(DEB_BUILT_COOKIE) $(MY_OBJ_DIR)/overrides mkdir -p $(MY_OUTPUT_DIR)/$(DEBPOOLDIR) cp -La $(MY_OBJ_DIR)/*.deb $(MY_OUTPUT_DIR)/$(DEBPOOLDIR) set -ex ; for arch in $(ARCHS) ; do \ bindir=debian/dists/$*/main/binary-$${arch} ; \ mkdir -p $(MY_OUTPUT_DIR)/$${bindir} ; \ ( cd $(MY_OUTPUT_DIR)/debian/ && \ dpkg-scanpackages -a$${arch} pool $(MY_OBJ_DIR)/overrides \ ) > $(MY_OUTPUT_DIR)/$${bindir}/Packages ; \ done mkdir -p $(MY_OUTPUT_DIR)/debian/dists/$*/main/source ( cd $(MY_OUTPUT_DIR)/debian/ && \ dpkg-scansources pool \ ) > $(MY_OUTPUT_DIR)/debian/dists/$*/main/source/Sources touch $@ # package up in a tools tarball so it gets on the ISO $(TOOLS_TARBALL): $(DEB_BUILT_COOKIE) mkdir -p $(INSTALL_DIR) rm -f $(INSTALL_DIR)/versions.deb $(foreach arch,$(ARCHS),\ echo XE_GUEST_UTILITIES_PKG_FILE_$(arch)=\'xe-guest-utilities_$(VERSION)-$(RELEASE)_$(arch).deb\' >> $(INSTALL_DIR)/versions.deb ; cp -v $(MY_OBJ_DIR)/xe-guest-utilities_$(VERSION)-$(RELEASE)_$(arch).deb $(INSTALL_DIR)/ ;) tar -C $(STAGING_DIR) -cjf $@ . $(GOROOT): mkdir -p $(GOROOT) ( cd $(GOROOT)/.. ; \ tar xf $(GOTARBALL) ;\ ) xe-guest-utilities-7.10.0/mk/Makefile.rpm000066400000000000000000000102461325465104300202230ustar00rootroot00000000000000# -*- makefile -*- USE_BRANDING := yes IMPORT_VERSIONS := yes include $(B_BASE)/common.mk RPM_LOCAL_RPMBUILD_OPTIONS := -D '_source_payload w9.gzdio' -D '_binary_payload w9.gzdio' \ -D '_source_filedigest_algorithm 0' -D '_binary_filedigest_algorithm 0' include $(B_BASE)/rpmbuild.mk RPM_BUILT_COOKIE = $(MY_OBJ_DIR)/.rpm_built_cookie REPO= $(call git_loc,xe-guest-utilities) REPOSTAMP= $(call git_req,xe-guest-utilities) STAGING_DIR = $(MY_OBJ_DIR)/staging INSTALL_DIR = $(STAGING_DIR)/Linux/ VERSIONS_FILE = $(MY_OBJ_DIR)/versions ARCHS = i386 x86_64 VERSION = $(PRODUCT_VERSION) RELEASE := $(shell git --git-dir="$(REPO)/.git" rev-list HEAD | wc -l) SPEC= xe-guest-utilities.spec SRPM= xe-guest-utilities-$(VERSION)-$(RELEASE).src.rpm GOTARBALL = /distfiles/golang/go1.4.2.linux-386.tar.gz GOROOT = $(MY_OBJ_DIR)/go GOBIN = GOROOT=$(GOROOT) $(GOROOT)/bin/go GOFLAGS = -a -x -ldflags="-s -w" GOBUILDDIR = $(MY_OBJ_DIR)/gobuild GO_SOURCE_REPO = $(call git_loc,xe-guest-utilities) XE_DAEMON_GO_SOURCES := XE_DAEMON_GO_SOURCES += ./xe-daemon/xe-daemon.go # this should be the first one XE_DAEMON_GO_SOURCES += ./syslog/syslog.go XE_DAEMON_GO_SOURCES += ./system/system.go XE_DAEMON_GO_SOURCES += ./guestmetric/guestmetric.go XE_DAEMON_GO_SOURCES += ./guestmetric/guestmetric_linux.go XE_DAEMON_GO_SOURCES += ./xenstoreclient/xenstore.go XENSTORE_GO_SOURCES := XENSTORE_GO_SOURCES += ./xenstore/xenstore.go # this should be the first one XENSTORE_GO_SOURCES += ./xenstoreclient/xenstore.go SOURCES := SOURCES += $(RPM_SOURCESDIR)/xe-linux-distribution SOURCES += $(RPM_SOURCESDIR)/xe-linux-distribution.init SOURCES += $(RPM_SOURCESDIR)/xe-daemon SOURCES += $(RPM_SOURCESDIR)/xenstore SOURCES += $(RPM_SOURCESDIR)/Citrix.repo SOURCES += $(RPM_SOURCESDIR)/xen-vcpu-hotplug.rules SOURCES += $(RPM_SOURCESDIR)/LICENSE TOOLS_TARBALL = $(MY_OUTPUT_DIR)/tools-files.tar.bz2 .PHONY: build build: $(RPM_BUILT_COOKIE) $(RPM_DIRECTORIES) $(TOOLS_TARBALL) $(ARCHS:%=$(MY_OUTPUT_DIR)/xe-guest-utilities.%.inc) $(MY_SOURCES)/MANIFEST @ : .PHONY: clean clean: rm -f $(RPM_SPECSDIR)/$(SPEC) rm -rf $(RPM_BUILDDIR) $(RPM_SOURCESDIR) $(RPM_SPECSDIR) rm -f $(RPM_BUILT_COOKIE) rm -rf $(GOROOT) rm -rf $(DESTDIR) $(RPM_SPECSDIR)/$(SPEC): $(SPEC).in $(call brand,$<) | \ sed -e 's,@VERSION@,$(VERSION),g' \ -e 's,@RELEASE@,$(RELEASE),g' \ > $@ $(MY_OUTPUT_DIR)/xe-guest-utilities.%.inc: $(MY_OUTPUT_DIR)/.dirstamp ( echo XE_GUEST_UTILITIES_PKG_NAME := xe-guest-utilities ; \ echo XE_GUEST_UTILITIES_PKG_VERSION := $(VERSION)-$(RELEASE) ; \ echo XE_GUEST_UTILITIES_PKG_ARCH := $* ; \ echo XE_GUEST_UTILITIES_PKG_FILE := RPMS/$*/xe-guest-utilities-$(VERSION)-$(RELEASE).$*.rpm ; \ )>$@ $(RPM_BUILT_COOKIE): $(RPM_DIRECTORIES) $(RPM_SPECSDIR)/$(SPEC) $(SOURCES) $(RPMBUILD) -bs $(RPM_SPECSDIR)/$(SPEC) set -ex ; for arch in $(ARCHS) ; do \ $(RPMBUILD) --target=$${arch} --rebuild $(RPM_SRPMSDIR)/$(SRPM) ; \ done $(MY_SOURCES)/MANIFEST: $(MY_SOURCES_DIRSTAMP) ( echo "$(COMPONENT) BSD file $(RPM_SRPMSDIR)/$(SRPM)" ; \ ) >$@ .PHONY: sources sources: $(MY_SOURCES)/MANIFEST @ : $(RPM_SOURCESDIR)/%: $(REPO)/mk/% mkdir -p $(RPM_SOURCESDIR) $(call brand,$<) > $@ $(RPM_SOURCESDIR)/xe-daemon: $(XE_DAEMON_GO_SOURCES:%=$(GOBUILDDIR)/%) $(GOROOT) $(GOBIN) build $(GOFLAGS) -o $@ $< $(RPM_SOURCESDIR)/xenstore: $(XENSTORE_GO_SOURCES:%=$(GOBUILDDIR)/%) $(GOROOT) $(GOBIN) build $(GOFLAGS) -o $@ $< $(RPM_SOURCESDIR)/LICENSE: $(REPO)/LICENSE $(call brand,$<) > $@ $(GOBUILDDIR)/%: $(GO_SOURCE_REPO)/% mkdir -p $$(dirname $@) $(call brand,$<) > $@ $(TOOLS_TARBALL): $(RPM_BUILT_COOKIE) mkdir -p $(INSTALL_DIR) rm -f $(INSTALL_DIR)/versions.rpm $(foreach arch,$(ARCHS),\ echo XE_GUEST_UTILITIES_PKG_FILE_$(arch)=\'xe-guest-utilities-$(VERSION)-$(RELEASE).$(arch).rpm xe-guest-utilities-xenstore-$(VERSION)-$(RELEASE).$(arch).rpm\' >> $(INSTALL_DIR)/versions.rpm ;\ cp -v $(MY_OUTPUT_DIR)/RPMS/$(arch)/xe-guest-utilities-$(VERSION)-$(RELEASE).$(arch).rpm $(INSTALL_DIR)/ ;\ cp -v $(MY_OUTPUT_DIR)/RPMS/$(arch)/xe-guest-utilities-xenstore-$(VERSION)-$(RELEASE).$(arch).rpm $(INSTALL_DIR)/ ;\ ) tar -C $(STAGING_DIR) -cjf $@ . $(GOROOT): mkdir -p $(GOROOT) ( cd $(GOROOT)/.. ; \ tar xf $(GOTARBALL) ;\ ) xe-guest-utilities-7.10.0/mk/Makefile.tgz000066400000000000000000000114401325465104300202260ustar00rootroot00000000000000# -*- makefile -*- USE_BRANDING := yes IMPORT_VERSIONS := yes include $(B_BASE)/common.mk REPO= $(call git_loc,xe-guest-utilities) REPOSTAMP= $(call git_req,xe-guest-utilities) ARCHS = i386 amd64 DISTROS = linux TGZ_BUILT_COOKIE = $(MY_OBJ_DIR)/.tgz_built_cookie TGZ_REPO_COOKIE = $(MY_OBJ_DIR)/.tgz_%_repo_cookie TGZ_REPO_COOKIES = $(DISTROS:%=$(TGZ_REPO_COOKIE)) STAGING_DIR = $(MY_OBJ_DIR)/staging INSTALL_DIR = $(STAGING_DIR)/Linux/ VERSIONS_FILE = $(MY_OBJ_DIR)/versions TOOLS_TARBALL = $(MY_OUTPUT_DIR)/tools-files.tar.bz2 PACKAGE = xe-guest-utilities VERSION = $(PRODUCT_VERSION) RELEASE := $(shell git --git-dir="$(REPO)/.git" rev-list HEAD | wc -l) SOURCEDIR := $(MY_OBJ_DIR)/$(PACKAGE)-$(VERSION)/ DESTDIR := $(MY_OBJ_DIR)/$(PACKAGE)/ GOTARBALL = /distfiles/golang/go1.4.2.linux-386.tar.gz GOROOT = $(MY_OBJ_DIR)/go GOBIN = GOROOT=$(GOROOT) $(GOROOT)/bin/go GOFLAGS = -v -ldflags="-s -w" GOBUILDDIR = $(MY_OBJ_DIR)/gobuild GO_SOURCE_REPO = $(call git_loc,xe-guest-utilities) XE_DAEMON_GO_SOURCES := XE_DAEMON_GO_SOURCES += ./xe-daemon/xe-daemon.go # this should be the first one XE_DAEMON_GO_SOURCES += ./syslog/syslog.go XE_DAEMON_GO_SOURCES += ./system/system.go XE_DAEMON_GO_SOURCES += ./guestmetric/guestmetric.go XE_DAEMON_GO_SOURCES += ./guestmetric/guestmetric_linux.go XE_DAEMON_GO_SOURCES += ./xenstoreclient/xenstore.go XENSTORE_GO_SOURCES := XENSTORE_GO_SOURCES += ./xenstore/xenstore.go # this should be the first one XENSTORE_GO_SOURCES += ./xenstoreclient/xenstore.go SOURCES := SOURCES += $(REPO)/LICENSE SOURCES += $(SOURCEDIR)/xe-linux-distribution SOURCES += $(SOURCEDIR)/xe-linux-distribution.init SOURCES += $(SOURCEDIR)/xe-daemon SOURCES += $(SOURCEDIR)/xenstore SOURCES += $(SOURCEDIR)/citrix.list SOURCES += $(SOURCEDIR)/xen-vcpu-hotplug.rules 822_DATE := $(shell date -R) .PHONY: build build: $(TOOLS_TARBALL) $(TGZ_BUILT_COOKIE) $(TGZ_REPO_COOKIES) $(ARCHS:%=$(MY_OUTPUT_DIR)/xe-guest-utilities.%.inc) $(MY_SOURCES)/MANIFEST @ : .PHONY: clean clean: rm -f $(TGZ_BUILT_COOKIE) rm -f $(TGZ_REPO_COOKIES) rm -rf $(GOROOT) rm -rf $(SOURCEDIR) rm -rf $(DESTDIR) local-brand := sed -e 's,@VERSION@,$(VERSION),g' \ -e 's,@RELEASE@,$(RELEASE),g' \ -e "s!@822DATE@!$(822_DATE)!g" $(SOURCEDIR)/%: $(REPO)/mk/% mkdir -p $(SOURCEDIR) $(call brand,$<) | $(call local-brand) > $@ $(SOURCEDIR)/citrix.list: citrix.list $(call brand,$<) > $@ $(SOURCEDIR)/xe-daemon: $(XE_DAEMON_GO_SOURCES:%=$(GOBUILDDIR)/%) $(GOROOT) $(GOBIN) build $(GOFLAGS) -o $@ $< $(SOURCEDIR)/xenstore: $(XENSTORE_GO_SOURCES:%=$(GOBUILDDIR)/%) $(GOROOT) $(GOBIN) build $(GOFLAGS) -o $@ $< $(GOBUILDDIR)/%: $(GO_SOURCE_REPO)/% mkdir -p $$(dirname $@) $(call brand,$<) > $@ $(MY_OUTPUT_DIR)/xe-guest-utilities.%.inc: $(MY_OUTPUT_DIR)/.dirstamp ( echo XE_GUEST_UTILITIES_PKG_NAME := xe-guest-utilities ; \ echo XE_GUEST_UTILITIES_PKG_VERSION := $(VERSION)-$(RELEASE) ; \ echo XE_GUEST_UTILITIES_PKG_ARCH := $* ; \ echo XE_GUEST_UTILITIES_PKG_FILE := $(MY_OBJ_DIR)/$(PACKAGE)_$(VERSION)-$(RELEASE)_all.tgz ; \ )>$@ $(TGZ_BUILT_COOKIE): $(SOURCES) ( cd $(SOURCEDIR) ; \ install -d $(DESTDIR)/etc/init.d/ ; \ install -m 755 xe-linux-distribution.init $(DESTDIR)/etc/init.d/xe-linux-distribution ; \ install -d $(DESTDIR)/usr/sbin/ ; \ install -m 755 xe-linux-distribution $(DESTDIR)/usr/sbin/xe-linux-distribution ; \ install -m 755 xe-daemon $(DESTDIR)/usr/sbin/xe-daemon ; \ install -d $(DESTDIR)/usr/bin/ ; \ install -m 755 xenstore $(DESTDIR)/usr/bin/xenstore ; \ ln -s /usr/bin/xenstore $(DESTDIR)/usr/bin/xenstore-read ; \ ln -s /usr/bin/xenstore $(DESTDIR)/usr/bin/xenstore-write ; \ ln -s /usr/bin/xenstore $(DESTDIR)/usr/bin/xenstore-exists ; \ ln -s /usr/bin/xenstore $(DESTDIR)/usr/bin/xenstore-rm ; \ install -d $(DESTDIR)/etc/udev/rules.d/ ; \ install -m 644 xen-vcpu-hotplug.rules $(DESTDIR)/etc/udev/rules.d/z10_xen-vcpu-hotplug.rules ; \ install -d $(DESTDIR)/usr/share/doc/$(PACKAGE)_$(VERSION)/ ; \ install -m 644 $(REPO)/LICENSE $(DESTDIR)/usr/share/doc/$(PACKAGE)_$(VERSION)/LICENSE ; \ cd $(DESTDIR) ; \ tar czvf $(MY_OBJ_DIR)/$(PACKAGE)_$(VERSION)-$(RELEASE)_all.tgz * \ )>$@ $(MY_SOURCES)/MANIFEST: $(MY_SOURCES_DIRSTAMP) touch $@ .PHONY: sources sources: $(MY_SOURCES)/MANIFEST @ : $(TGZ_REPO_COOKIE): $(TGZ_BUILT_COOKIE) touch $@ # package up in a tools tarball so it gets on the ISO $(TOOLS_TARBALL): $(TGZ_BUILT_COOKIE) mkdir -p $(INSTALL_DIR) rm -f $(INSTALL_DIR)/versions.tgz $(foreach arch,$(ARCHS),\ echo XE_GUEST_UTILITIES_PKG_FILE_$(arch)=\'xe-guest-utilities_$(VERSION)-$(RELEASE)_all.tgz\' >> $(INSTALL_DIR)/versions.tgz ; cp -v $(MY_OBJ_DIR)/xe-guest-utilities_$(VERSION)-$(RELEASE)_all.tgz $(INSTALL_DIR)/ ;) tar -C $(STAGING_DIR) -cjf $@ . $(GOROOT): mkdir -p $(GOROOT) ( cd $(GOROOT)/.. ; \ tar xf $(GOTARBALL) ;\ ) xe-guest-utilities-7.10.0/mk/citrix.list000066400000000000000000000002741325465104300201650ustar00rootroot00000000000000deb http://updates.vmd.citrix.com/@PRODUCT_BRAND@/@PRODUCT_VERSION@/debian/ ^DISTRO^ main deb-src http://updates.vmd.citrix.com/@PRODUCT_BRAND@/@PRODUCT_VERSION@/debian/ ^DISTRO^ main xe-guest-utilities-7.10.0/mk/debian/000077500000000000000000000000001325465104300172055ustar00rootroot00000000000000xe-guest-utilities-7.10.0/mk/debian/changelog000066400000000000000000000002641325465104300210610ustar00rootroot00000000000000xe-guest-utilities (@VERSION@-@RELEASE@) etch; urgency=low * Build for @PRODUCT_NAME@ @PRODUCT_VERSION@-@BUILD_NUMBER@. -- @COMPANY_NAME_LEGAL@ @BUILD_DATE@ xe-guest-utilities-7.10.0/mk/debian/compat000066400000000000000000000000021325465104300204030ustar00rootroot000000000000005 xe-guest-utilities-7.10.0/mk/debian/control000066400000000000000000000006451325465104300206150ustar00rootroot00000000000000Source: xe-guest-utilities Section: main/admin Priority: optional Maintainer: Citrix Systems, Inc. Standards-Version: 3.7.2 Build-Depends: debhelper (>= 4.0.0) Package: xe-guest-utilities Architecture: any Conflicts: xengmond Replaces: xengmond Description: @BRAND_GUEST@ Monitoring Scripts Scripts for monitoring @BRAND_GUESTS@. . Writes distribution version information and IP address to XenStore. xe-guest-utilities-7.10.0/mk/debian/copyright000066400000000000000000000000761325465104300211430ustar00rootroot00000000000000See the LICENSE file in the /usr/share/doc/xe-guest-utilities xe-guest-utilities-7.10.0/mk/debian/overrides000066400000000000000000000000411325465104300211250ustar00rootroot00000000000000xengmond optional non-free/admin xe-guest-utilities-7.10.0/mk/debian/rules000066400000000000000000000021621325465104300202630ustar00rootroot00000000000000#!/usr/bin/make -f build: build-stamp build-stamp: touch $@ clean: dh_testdir dh_testroot dh_clean binary: binary-arch binary-indep binary-arch: DESTDIR=debian/xe-guest-utilities binary-arch: build dh_testdir dh_testroot dh_clean -k dh_installdirs cp xe-linux-distribution $(DESTDIR)/usr/sbin/xe-linux-distribution chmod 0755 $(DESTDIR)/usr/sbin/xe-linux-distribution install -d $(DESTDIR)/usr/bin/ install -m 755 xenstore $(DESTDIR)/usr/bin/xenstore ln -s /usr/bin/xenstore $(DESTDIR)/usr/bin/xenstore-read ln -s /usr/bin/xenstore $(DESTDIR)/usr/bin/xenstore-write ln -s /usr/bin/xenstore $(DESTDIR)/usr/bin/xenstore-exists ln -s /usr/bin/xenstore $(DESTDIR)/usr/bin/xenstore-rm cp xe-daemon $(DESTDIR)/usr/sbin/xe-daemon chmod 0755 $(DESTDIR)/usr/sbin/xe-daemon cp xen-vcpu-hotplug.rules $(DESTDIR)/lib/udev/rules.d/z10_xen-vcpu-hotplug.rules dh_installinit --name xe-linux-distribution dh_install citrix.list /usr/share/xe-guest-utilities dh_installdocs LICENSE dh_strip dh_compress dh_fixperms dh_makeshlibs dh_shlibdeps dh_installdeb dh_gencontrol dh_md5sums dh_builddeb binary-indep: xe-guest-utilities-7.10.0/mk/debian/xe-guest-utilities.dirs000066400000000000000000000000451325465104300236410ustar00rootroot00000000000000etc/init.d lib/udev/rules.d usr/sbin xe-guest-utilities-7.10.0/mk/debian/xe-guest-utilities.postinst000077500000000000000000000011131325465104300245630ustar00rootroot00000000000000#!/bin/sh #DEBHELPER# if [ X"$1" = X"configure" ] ; then eval $(/usr/sbin/xe-linux-distribution) if [ -d /etc/apt/sources.list.d ] && [ X"${os_distro}" = X"debian" ] \ && [ -n "${os_majorver}" ] && [ -n "${os_minorver}" ] ; then case "${os_majorver}${os_minorver}" in 50) distro="lenny" ;; *) ;; esac if [ -n "${distro}" ] ; then rm -f /etc/apt/sources.list.d/xensource.list # contains deprecated urls sed -e "s/\^DISTRO\^/${distro}/g" \ < /usr/share/xe-guest-utilities/citrix.list \ > /etc/apt/sources.list.d/citrix.list fi fi fi xe-guest-utilities-7.10.0/mk/debian/xe-guest-utilities.prerm000077500000000000000000000002241325465104300240270ustar00rootroot00000000000000#!/bin/sh if [ X"$1" = X"remove" ] && [ -e /etc/apt/sources.list.d/citrix.list ] ; then rm /etc/apt/sources.list.d/citrix.list fi #DEBHELPER# xe-guest-utilities-7.10.0/mk/testcases/000077500000000000000000000000001325465104300177615ustar00rootroot00000000000000xe-guest-utilities-7.10.0/mk/testcases/centos4000066400000000000000000000000331325465104300212570ustar00rootroot00000000000000CentOS release 4.0 (Final) xe-guest-utilities-7.10.0/mk/testcases/centos5000066400000000000000000000000311325465104300212560ustar00rootroot00000000000000CentOS release 5 (Final) xe-guest-utilities-7.10.0/mk/testcases/ddk-0.5.6-2991c000066400000000000000000000000541325465104300216560ustar00rootroot00000000000000Rio DDK release 0.5.6-2991c (xenenterprise) xe-guest-utilities-7.10.0/mk/testcases/debian-sarge000066400000000000000000000000041325465104300222170ustar00rootroot000000000000003.1 xe-guest-utilities-7.10.0/mk/testcases/debian-sid000066400000000000000000000000121325465104300216740ustar00rootroot00000000000000lenny/sid xe-guest-utilities-7.10.0/mk/testcases/fc3000066400000000000000000000000431325465104300203540ustar00rootroot00000000000000Fedora Core release 3 (Heidelberg) xe-guest-utilities-7.10.0/mk/testcases/lsb000077500000000000000000000012001325465104300204600ustar00rootroot00000000000000#!/bin/sh set -e if [ $1 != "--short" ] ; then echo "Invalid parameter: $1" 1>&2 exit 1 fi if [ ! -f "${TESTCASE}" ] ; then echo "Testcase ${TESTCASE} not found" 1>&2 exit 1 fi case $(basename ${TESTCASE}) in lsb-*) ;; *) exit 1 esac . ${TESTCASE} if [ -z "$ID" ] ; then ID="$DISTRIB_ID" fi if [ -z "$DESCRIPTION" ] ; then DESCRIPTION="$DISTRIB_DESCRIPTION" fi if [ -z "$RELEASE" ] ; then RELEASE="$DISTRIB_RELEASE" fi case $2 in --id) echo ${ID} ;; --description) echo ${DESCRIPTION} ;; --release) echo ${RELEASE} ;; *) echo "Invalid paramter: $2" 1>&2 exit 1;; esac exit 0 xe-guest-utilities-7.10.0/mk/testcases/lsb-coreos-367.1.0000066400000000000000000000001511325465104300225630ustar00rootroot00000000000000DISTRIB_ID=CoreOS DISTRIB_RELEASE=367.1.0 DISTRIB_CODENAME="Red Dog" DISTRIB_DESCRIPTION="CoreOS 367.1.0"xe-guest-utilities-7.10.0/mk/testcases/lsb-ubuntu-6.10000066400000000000000000000000641325465104300223660ustar00rootroot00000000000000ID="Ubuntu" DESCRPITON="Ubuntu 6.10" RELEASE="6.10" xe-guest-utilities-7.10.0/mk/testcases/lsb-ubuntu-7.04000066400000000000000000000000651325465104300223730ustar00rootroot00000000000000ID="Ubuntu" DESCRIPTION="Ubuntu 7.04" RELEASE="7.04" xe-guest-utilities-7.10.0/mk/testcases/oracle-5000066400000000000000000000000761325465104300213160ustar00rootroot00000000000000Enterprise Linux Enterprise Linux Server release 5 (Carthage) xe-guest-utilities-7.10.0/mk/testcases/oracle-5u1000066400000000000000000000001001325465104300215500ustar00rootroot00000000000000Enterprise Linux Enterprise Linux Server release 5.1 (Carthage) xe-guest-utilities-7.10.0/mk/testcases/rhel-3u6000066400000000000000000000000701325465104300212460ustar00rootroot00000000000000Red Hat Enterprise Linux AS release 3 (Taroon Update 6) xe-guest-utilities-7.10.0/mk/testcases/rhel-3u8000066400000000000000000000000701325465104300212500ustar00rootroot00000000000000Red Hat Enterprise Linux AS release 3 (Taroon Update 8) xe-guest-utilities-7.10.0/mk/testcases/rhel-4000066400000000000000000000000571325465104300210010ustar00rootroot00000000000000Red Hat Enterprise Linux AS release 4 (Nahant) xe-guest-utilities-7.10.0/mk/testcases/rhel-4u1000066400000000000000000000000701325465104300212420ustar00rootroot00000000000000Red Hat Enterprise Linux AS release 4 (Nahant Update 1) xe-guest-utilities-7.10.0/mk/testcases/rhel-4u2000066400000000000000000000000701325465104300212430ustar00rootroot00000000000000Red Hat Enterprise Linux AS release 4 (Nahant Update 2) xe-guest-utilities-7.10.0/mk/testcases/rhel-4u3000066400000000000000000000000701325465104300212440ustar00rootroot00000000000000Red Hat Enterprise Linux AS release 4 (Nahant Update 3) xe-guest-utilities-7.10.0/mk/testcases/rhel-4u4000066400000000000000000000000701325465104300212450ustar00rootroot00000000000000Red Hat Enterprise Linux AS release 4 (Nahant Update 4) xe-guest-utilities-7.10.0/mk/testcases/rhel-4u5000066400000000000000000000000701325465104300212460ustar00rootroot00000000000000Red Hat Enterprise Linux ES release 4 (Nahant Update 5) xe-guest-utilities-7.10.0/mk/testcases/rhel-4u6000066400000000000000000000000701325465104300212470ustar00rootroot00000000000000Red Hat Enterprise Linux AS release 4 (Nahant Update 6) xe-guest-utilities-7.10.0/mk/testcases/rhel-5000066400000000000000000000000641325465104300210000ustar00rootroot00000000000000Red Hat Enterprise Linux Server release 5 (Tikanga) xe-guest-utilities-7.10.0/mk/testcases/rhel-5beta000066400000000000000000000000671325465104300216370ustar00rootroot00000000000000Red Hat Enterprise Linux Server release 4.92 (Tikanga) xe-guest-utilities-7.10.0/mk/testcases/rhel-5u1000066400000000000000000000000661325465104300212500ustar00rootroot00000000000000Red Hat Enterprise Linux Server release 5.1 (Tikanga) xe-guest-utilities-7.10.0/mk/testcases/rhel-5u1beta000066400000000000000000000000731325465104300221020ustar00rootroot00000000000000Red Hat Enterprise Linux Server release 5.1 Beta (Tikanga) xe-guest-utilities-7.10.0/mk/testcases/sdk-0.5.6-2991c000066400000000000000000000000541325465104300216750ustar00rootroot00000000000000Rio SDK release 0.5.6-2991c (xenenterprise) xe-guest-utilities-7.10.0/mk/testcases/sles-10sp2000066400000000000000000000001031325465104300215070ustar00rootroot00000000000000SUSE Linux Enterprise Server 10 (i586) VERSION = 10 PATCHLEVEL = 2 xe-guest-utilities-7.10.0/mk/testcases/sles-11000066400000000000000000000001031325465104300210630ustar00rootroot00000000000000SUSE Linux Enterprise Server 11 (i586) VERSION = 11 PATCHLEVEL = 0 xe-guest-utilities-7.10.0/mk/testcases/sles-9000066400000000000000000000000621325465104300210160ustar00rootroot00000000000000SUSE LINUX Enterprise Server 9 (i586) VERSION = 9 xe-guest-utilities-7.10.0/mk/testcases/sles-9sp3000066400000000000000000000001011325465104300214360ustar00rootroot00000000000000SUSE LINUX Enterprise Server 9 (i586) VERSION = 9 PATCHLEVEL = 3 xe-guest-utilities-7.10.0/mk/xe-guest-utilities.spec.in000066400000000000000000000070051325465104300230200ustar00rootroot00000000000000# -*- rpm-spec -*- Summary: @BRAND_GUEST@ Monitoring Scripts Name: xe-guest-utilities Version: @VERSION@ Release: @RELEASE@ License: BSD Group: Xen URL: http://www.citrix.com Vendor: @COMPANY_NAME_LEGAL@ Source0: xe-linux-distribution Source1: xe-linux-distribution.init Source3: xe-daemon Source5: Citrix.repo Source6: xenstore Source8: LICENSE Source9: xen-vcpu-hotplug.rules BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot BuildRequires: golang Obsoletes: xengmond %description Scripts for monitoring @BRAND_GUESTS@. Writes distribution version information and IP address to XenStore. %package xenstore Summary: @BRAND_GUEST@ XenStore utilities Group: Xen %description xenstore Utilities for interacting with XenStore from with a Xen virtual machine %prep # Nothing to do %build # Nothing to do %install rm -rf %{buildroot} mkdir -p %{buildroot}/usr/sbin/ mkdir -p %{buildroot}/usr/share/doc/%{name}-%{version}/examples/ mkdir -p %{buildroot}/etc/init.d mkdir -p %{buildroot}/etc/udev/rules.d cp %{SOURCE0} %{buildroot}/usr/sbin/xe-linux-distribution chmod 755 %{buildroot}/usr/sbin/xe-linux-distribution cp %{SOURCE1} %{buildroot}/etc/init.d/xe-linux-distribution chmod 755 %{buildroot}/etc/init.d/xe-linux-distribution cp %{SOURCE3} %{buildroot}/usr/sbin/xe-daemon chmod 755 %{buildroot}/usr/sbin/xe-daemon cp %{SOURCE5} %{buildroot}/usr/share/doc/%{name}-%{version}/examples/ install -d %{buildroot}/usr/bin/ install -m 755 %{SOURCE6} %{buildroot}/usr/bin/xenstore ln -s /usr/bin/xenstore %{buildroot}/usr/bin/xenstore-read ln -s /usr/bin/xenstore %{buildroot}/usr/bin/xenstore-write ln -s /usr/bin/xenstore %{buildroot}/usr/bin/xenstore-exists ln -s /usr/bin/xenstore %{buildroot}/usr/bin/xenstore-rm cp %{SOURCE9} %{buildroot}/etc/udev/rules.d/z10-xen-vcpu-hotplug.rules cp %{SOURCE8} %{buildroot}/usr/share/doc/%{name}-%{version}/ mkdir -p %{buildroot}/usr/share/doc/%{name}-xenstore-%{version} cp %{SOURCE8} %{buildroot}/usr/share/doc/%{name}-xenstore-%{version}/ %clean rm -rf %{buildroot} %post /sbin/chkconfig --add xe-linux-distribution >/dev/null [ -n "${EXTERNAL_P2V}" ] || service xe-linux-distribution start >/dev/null 2>&1 eval $(/usr/sbin/xe-linux-distribution) if [ -d /etc/yum.repos.d ] && [ -n "${os_distro}" ] && [ -n "${os_majorver}" ] ; then distro="${os_distro}${os_majorver}x" case "${distro}" in rhel4x|centos4x) if [ -f /etc/yum.repos.d/XenSource.repo ] ; then rm -f /etc/yum.repos.d/XenSource.repo # contains deprecated urls fi sed -e "s/\^DISTRO\^/${distro}/g" \ < /usr/share/doc/%{name}-%{version}/examples/Citrix.repo \ > /etc/yum.repos.d/Citrix.repo ;; rhel3x|rhel5x|centos5x|oracle5x) # No vendor kernel any more. Remove Citrix.repo if [ -f /etc/yum.repos.d/Citrix.repo ] ; then rm -f /etc/yum.repos.d/Citrix.repo fi ;; *) ;; esac fi %preun if [ $1 -eq 0 ] ; then service xe-linux-distribution stop >/dev/null 2>&1 /sbin/chkconfig --del xe-linux-distribution >/dev/null rm -f /etc/yum.repos.d/Citrix.repo || /bin/true fi %files %defattr(-,root,root,-) /usr/sbin/xe-linux-distribution /etc/init.d/xe-linux-distribution /usr/sbin/xe-daemon /etc/udev/rules.d/z10-xen-vcpu-hotplug.rules /usr/share/doc/%{name}-%{version}/examples/Citrix.repo /usr/share/doc/%{name}-%{version}/LICENSE %files xenstore %defattr(-,root,root,-) /usr/bin/xenstore-* /usr/bin/xenstore /usr/share/doc/%{name}-xenstore-%{version}/LICENSE %changelog * Tue Jun 5 2007 - Xen monitor scripts xe-guest-utilities-7.10.0/mk/xe-linux-distribution000077500000000000000000000323251325465104300222040ustar00rootroot00000000000000#! /bin/sh # Copyright (c) 2015, Citrix Systems # 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. # Script to write information about the current distribution to stdout or a file. # Information collected: # - Distribution name # - Distribution version (major and minor) # - Kernel version (uname) LANG="C" export LANG write_to_output() { local distro="$1" local major="$2" local minor="$3" local name="$4" local uname=$(uname -r) if [ -n "${TEST_RESULT}" ] ; then MAJOR=$major MINOR=$minor DISTRO=$distro UNAME=$uname return 0 fi echo "os_distro=\"${distro}\"" echo "os_majorver=\"${major}\"" echo "os_minorver=\"${minor}\"" echo "os_uname=\"${uname}\"" echo "os_name=\"${name}\"" return 0 } identify_debian() { local debian_version="$1" local major local minor # 3.1 # 4.0 # Ignores testing and unstable which contain ".*/sid". if [ ! -f "${debian_version}" ] ; then return 1 fi eval $(awk -F. '/^[0-9]*\.[0-9]*/ \ { print "major="$1 ; print "minor="$2 ; exit 0 }' \ "${debian_version}") if [ -z "${major}" ] && [ -z "${minor}" ] && ! grep -q /sid "${debian_version}" ; then return 1 fi write_to_output "debian" "${major}" "${minor}" "Debian $(head -n 1 $debian_version)" return 0 } identify_redhat() { redhat_release="$1" local distro local major local minor local beta # distro=rhel # Red Hat Enterprise Linux AS release 3 (Taroon Update 6) # Red Hat Enterprise Linux AS release 3 (Taroon Update 8) # Red Hat Enterprise Linux AS release 4 (Nahant) # Red Hat Enterprise Linux AS release 4 (Nahant Update 1) # Red Hat Enterprise Linux AS release 4 (Nahant Update 2) # Red Hat Enterprise Linux AS release 4 (Nahant Update 3) # Red Hat Enterprise Linux AS release 4 (Nahant Update 4) # Red Hat Enterprise Linux Server release 4.92 (Tikanga) # Red Hat Enterprise Linux Server release 5 (Tikanga) # Red Hat Enterprise Linux Server release 5.1 Beta (Tikanga) # Red Hat Enterprise Linux release 6.0 Beta (Santiago) # distro=xe-ddk # \@PRODUCT_BRAND\@ DDK release \@PRODUCT_VERSION\@-\@BUILD_NUMBER\@ (\@PRODUCT_NAME\@) # Rio DDK release 0.5.6-2991c (xenenterprise) # distro=xe-sdk # \@PRODUCT_BRAND\@ SDK release \@PRODUCT_VERSION\@-\@BUILD_NUMBER\@ (\@PRODUCT_NAME\@) # Rio SDK release 0.5.6-2991c (xenenterprise) # distro=fedora # Fedora Core release 3 (Heidelberg) # distro=centos # CentOS release 4.0 (Final) # CentOS release 5 (Final) # CentOS Linux release 7.0.1406 (Core) # distro=scientific # Scientific Linux release 6.5 (Carbon) # distro=oracle # Enterprise Linux Enterprise Linux Server release 5 (Carthage) # Enterprise Linux Enterprise Linux Server release 5.5 (Carthage) # Oracle Linux Server release 5.6 if [ ! -f "${redhat_release}" ] ; then return 1 fi eval $(sed -nr \ 's/^(.*) DDK release ([^-]*)(-(.*))? (.*)$/distro=xe-ddk;major=\2;minor=\4/gp;' \ "${redhat_release}") eval $(sed -n \ -e 's/^\(.*\) SDK release \(.*\)-\(.*\) (.*)$/distro=xe-sdk;major=\2;minor=\3/gp;' \ -e 's/^Red Hat Enterprise Linux.* release \([0-9]*\) (.* Update \(.*\))$/distro=rhel;major=\1;minor=\2/gp;'\ -e 's/^Red Hat Enterprise Linux.* release \([0-9]*\) (.*)$/distro=rhel;major=\1/gp;' \ -e 's/^Red Hat Enterprise Linux.* release \([0-9]*\)\.\([0-9]*\) \([Bb]eta \)\?(.*)$/distro=rhel;major=\1;minor=\2;beta=\3;/gp;' \ -e 's/^Fedora.*release \([0-9]*\) (.*)$/distro=fedora;major=\1/gp;' \ -e 's/^CentOS release \([0-9]*\)\.\([0-9]*\) (.*)/distro=centos;major=\1;minor=\2/gp;' \ -e 's/^CentOS release \([0-9]*\) (.*)/distro=centos;major=\1/gp;' \ -e 's/^CentOS Linux release \([0-9]*\)\.\([0-9]*\)\(\.[0-9]*\)\? (.*)/distro=centos;major=\1;minor=\2/gp;' \ -e 's/^Enterprise Linux Enterprise Linux .* release \([0-9]*\)\.\([0-9]*\) (.*)$/distro=oracle;major=\1;minor=\2;/gp;' \ -e 's/^Enterprise Linux Enterprise Linux .* release \([0-9]*\) (.*)$/distro=oracle;major=\1/gp;' \ -e 's/^Oracle Linux Server release \([0-9]*\)\.\([0-9]*\)$/distro=oracle;major=\1;minor=\2/gp;' \ -e 's/^Scientific Linux SL release \([0-9]*\)\.\([0-9]*\) (.*)$/distro=scientific;major=\1;minor=\2;/gp;' \ -e 's/^Scientific Linux release \([0-9]*\)\.\([0-9]*\) (.*)$/distro=scientific;major=\1;minor=\2;/gp;' \ "${redhat_release}") if [ -z "${major}" -o -z "${distro}" ] ; then return 1 fi if [ -z "${minor}" ] ; then minor=0 fi # HACK to handle RHEL betas if [ "${distro}" == "rhel" ] && [ ${minor} -gt 90 ] ; then major=$(expr ${major} + 1 ) minor=0 beta=Beta fi if [ -n "${beta}" ] ; then minor="${minor}beta" fi write_to_output "${distro}" "${major}" "${minor}" "$(head -n 1 ${redhat_release})" } identify_sles() { suse_release="$1" local major local minor local _major # SUSE LINUX Enterprise Server 9 (i586) # VERSION = 9 # # SUSE LINUX Enterprise Server 9 (i586) # VERSION = 9 # PATCHLEVEL = 2 # # SUSE LINUX Enterprise Server 9 (i586) # VERSION = 9 # PATCHLEVEL = 3 # # SUSE Linux Enterprise Server 10 (i586) # VERSION = 10 # # SUSE Linux Enterprise Server 10 (i586) # VERSION = 10 # PATCHLEVEL = 1 # # SUSE Linux Enterprise Server 11 (i586) # VERSION = 11 # PATCHLEVEL = 0 if [ ! -f "${suse_release}" ] ; then return 1 fi eval $(sed -n \ -e 's/^SUSE L\(inux\|INUX\) Enterprise \([a-zA-Z0-9_]*\) \([0-9]*\) (.*)/_major=\3;/gp;' \ -e 's/^VERSION = \([0-9]*\)$/major=\1;/gp;' \ -e 's/^PATCHLEVEL = \([0-9]*\)$/minor=\1;/gp;' \ "${suse_release}") if [ -z "${major}" -o -z "${_major}" ] ; then return 1 fi if [ "${major}" != "${_major}" ] ; then return 1 fi if [ -z "${minor}" ] ; then minor=0 fi write_to_output "sles" "${major}" "${minor}" "$(head -n 1 ${suse_release})" } identify_lsb() { lsb_release="$1" if [ ! -x "${lsb_release}" ] ; then saved_IFS=$IFS IFS=: for i in $PATH ; do if [ -x "${i}/${lsb_release}" ] ; then lsb_release="${i}/${lsb_release}" break fi done IFS=$saved_IFS fi if [ -x "${lsb_release}" ] ; then distro=$(${lsb_release} --short --id | tr 'A-Z' 'a-z') description=$(${lsb_release} --short --description | sed -e 's/^"\(.*\)"$/\1/g') release=$(${lsb_release} --short --release) else if [ -f /etc/lsb-release ] ; then source /etc/lsb-release distro="$DISTRIB_ID" description="$DISTRIB_DESCRIPTION" release="$DISTRIB_RELEASE" else return 1 fi fi if [ -z "${distro}" -o -z "${release}" ] ; then return 1 fi eval $(echo $release | awk -F. -- '{ subindex = index($0,"."); \ print "major=\"" $1 "\""; \ print "minor=\"" substr($0,subindex+1) "\"" }') if [ -z "${major}" -o -z "${distro}" ] ; then return 1 fi write_to_output "${distro}" "${major}" "${minor}" "${description}" } identify_kylin() { kylin_release="$1" local distro local major local minor # distro # NeoKylin Linux Security OS V5.0 (Update8) # Neokylin Linux Security OS Server release V5 (Santiago) # NeoKylin Linux Advanced Server release 6.5 (Berryllium) # NeoKylin Linux Advanced Server release 7.0 if [ ! -f "${kylin_release}" ] ; then return 1 fi eval $(sed -rn \ 's/^Neo[kK]ylin Linux[^0-9]+([0-9]+)\.?([0-9]+)?.*$/distro=neokylin;major=\1;minor=\2;/gp;' \ "${kylin_release}") if [ -z "${major}" -o -z "${distro}" ] ; then return 1 fi if [ -z "${minor}" ] ; then minor=0 fi write_to_output "${distro}" "${major}" "${minor}" "$(head -n 1 ${kylin_release})" } identify_asianux() { asianux_release="$1" local distro local major local minor # distro # 'Asianux Server 4.5 (Final)' # 'Asianux Server 4 (Hiranya SP2)' # 'Asianux Server 4 (Hiranya SP4)' if [ ! -f "${asianux_release}" ] ; then return 1 fi eval $(sed -rn \ 's/^Asianux Server ([0-9]*)\.([0-9]*) .*$/distro=asianux;major=\1;minor=\2;/gp;'` `'s/^Asianux Server ([0-9]*) \([^0-9]*([0-9]*)\)$/distro=asianux;major=\1;minor=\2;/gp;' \ "${asianux_release}") if [ -z "${major}" -o -z "${distro}" ] ; then return 1 fi if [ -z "${minor}" ] ; then minor=0 fi write_to_output "${distro}" "${major}" "${minor}" "$(head -n 1 ${asianux_release})" } identify_turbo() { turbo_release="$1" local distro local major local minor # distro # GreatTurbo Enterprise Server release 12.2 (Theseus) if [ ! -f "${turbo_release}" ] ; then return 1 fi eval $(sed -rn \ 's/^GreatTurbo[^0-9]*([0-9]*)\.?([0-9]*)?.*$/distro=turbo;major=\1;minor=\2;/gp;' \ "${turbo_release}") if [ -z "${major}" -o -z "${distro}" ] ; then return 1 fi if [ -z "${minor}" ] ; then minor=0 fi write_to_output "${distro}" "${major}" "${minor}" "$(head -n 1 ${turbo_release})" } identify_linx() { linx_release="$1" local distro local major local minor # distro # '6.0.60.4' corresponds to Linx Linux 6 # '6.0.80' corresponds to Linx Linux 8 if [ ! -f "${linx_release}" ] ; then return 1 fi eval $(sed -rn \ 's/^6.0.([0-9])0.*$/distro=linx;major=\1;minor=0;/gp;' \ "${linx_release}") if [ -z "${major}" -o -z "${distro}" ] ; then return 1 fi if [ -z "${minor}" ] ; then minor=0 fi linx_osname="Linx Linux ${major}.${minor}" write_to_output "${distro}" "${major}" "${minor}" "${linx_osname}" } identify_yinhe() { yinhe_release="$1" local distro local major local minor # distro # Kylin 4.0 if [ ! -f "${yinhe_release}" ] ; then return 1 fi eval $(sed -rn \ 's/^Kylin ([0-9]).([0-9])$/distro=yinhe;major=\1;minor=\2;/gp;' \ "${yinhe_release}") if [ -z "${major}" -o -z "${distro}" ] ; then return 1 fi if [ -z "${minor}" ] ; then minor=0 fi yinhe_osname="Yinhe Kylin Linux ${major}.${minor}" write_to_output "${distro}" "${major}" "${minor}" "${yinhe_osname}" } identify_boot2docker() { boot2docker_release="$1" local major local minor if [ ! -f "${boot2docker_release}" ] ; then return 1 fi major=$(awk -F. '{printf("%s", $1)}' /etc/version) minor=$(awk -F. '{printf("%s.%s", $2, $3)}' /etc/version) write_to_output "boot2docker" "${major}" "${minor}" "boot2docker $(head -n 1 /etc/version)" } if [ $# -eq 1 ] ; then exec 1>"$1" fi if [ -z "${TEST}" ] ; then #identify kylin disto before redhat, as kylin has both kylin_release and redhat_release. identify_asianux /etc/asianux-release && exit 0 identify_turbo /etc/turbo-release && exit 0 identify_kylin /etc/neokylin-release && exit 0 identify_redhat /etc/oracle-release && exit 0 identify_redhat /etc/enterprise-release && exit 0 identify_redhat /etc/centos-release && exit 0 identify_redhat /etc/redhat-release && exit 0 identify_sles /etc/SuSE-release && exit 0 #identify Linx disto before debian, as Linx has both linx_release and debian_version. identify_yinhe /etc/kylin-build && exit 0 identify_linx /etc/linx-release && exit 0 identify_lsb lsb_release && exit 0 identify_debian /etc/debian_version && exit 0 identify_boot2docker /etc/boot2docker && exit 0 if [ $# -eq 1 ] ; then rm -f "$1" fi exit 1 fi xe-guest-utilities-7.10.0/mk/xe-linux-distribution-test000077500000000000000000000050401325465104300231530ustar00rootroot00000000000000#!/bin/sh LANG="C" export LANG TEST=yes . xe-linux-distribution test_identify() { export TESTCASE=$1 identify_lsb testcases/lsb || \ identify_debian "${1}" || \ identify_redhat "${1}" || \ identify_sles "${1}" || \ return 1 } do_test() { TC=$1 ; shift TEST_RESULT=$@ if test_identify ${TC} ; then if [ X"${TEST_RESULT}" = X"FAIL" ] ; then echo "FAILED: ${TC}: should fail to parse" 1>&2 else set ${TEST_RESULT} if [ "$1" != "${DISTRO}" ] ; then echo "FAILED: ${TC}: $1 $2.$3: distro ${DISTRO} != $1" 1>&2 exit 1 fi if [ "$2" != "${MAJOR}" ] ; then echo "FAILED: ${TC}: $1 $2.$3: major ${MAJOR} != $2" 1>&2 exit 1 fi if [ "$3" != "${MINOR}" ] ; then echo "FAILED: ${TC} $1 $2.$3: minor ${MINOR} != $3" 1>&2 exit 1 fi echo "PASSED: ${TC}: ${DISTRO} ${MAJOR} ${MINOR} correctly detected" 1>&2 fi else if [ X"${TEST_RESULT}" = X"FAIL" ] ; then echo "PASSED: ${TC}: correctly failed to parse" 1>&2 else echo "FAILED: ${TC}: unable to parse" 1>&2 fi fi } do_test "testcases/debian-sid" "debian" do_test "testcases/rhel-3u6" "rhel 3 6" do_test "testcases/rhel-3u8" "rhel 3 8" do_test "testcases/rhel-4" "rhel 4 0" do_test "testcases/rhel-4u1" "rhel 4 1" do_test "testcases/rhel-4u2" "rhel 4 2" do_test "testcases/rhel-4u3" "rhel 4 3" do_test "testcases/rhel-4u4" "rhel 4 4" do_test "testcases/rhel-4u5" "rhel 4 5" do_test "testcases/rhel-4u6" "rhel 4 6" do_test "testcases/rhel-5beta" "rhel 5 0beta" do_test "testcases/rhel-5" "rhel 5 0" do_test "testcases/rhel-5u1beta" "rhel 5 1beta" do_test "testcases/rhel-5u1" "rhel 5 1" do_test "testcases/fc3" "fedora 3 0" do_test "testcases/sles-9" "sles 9 0" do_test "testcases/sles-9sp3" "sles 9 3" do_test "testcases/sles-10sp2" "sles 10 2" do_test "testcases/sles-11" "sles 11 0" do_test "testcases/ddk-0.5.6-2991c" "xe-ddk 0.5.6 2991c" do_test "testcases/sdk-0.5.6-2991c" "xe-sdk 0.5.6 2991c" do_test "testcases/centos4" "centos 4 0" do_test "testcases/centos5" "centos 5 0" do_test "testcases/lsb-ubuntu-6.10" "ubuntu 6 10" do_test "testcases/lsb-ubuntu-7.04" "ubuntu 7 04" do_test "testcases/oracle-5" "oracle 5 0" do_test "testcases/oracle-5u1" "oracle 5 1" do_test "testcases/lsb-coreos-367.1.0" "coreos 367 1.0" exit 0 xe-guest-utilities-7.10.0/mk/xe-linux-distribution.init000066400000000000000000000053621325465104300231440ustar00rootroot00000000000000#!/bin/sh # # xe-linux-distribution Write Linux distribution information to XenStore. # # chkconfig: 2345 14 86 # description: Writes Linux distribution version information to XenStore. # ### BEGIN INIT INFO # Provides: xe-linux-distribution # Required-Start: $remote_fs # Required-Stop: $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: @BRAND_GUEST@ daemon providing host integration services # Description: Writes Linux distribution version information to XenStore. ### END INIT INFO LANG="C" export LANG if [ -f /etc/init.d/functions ] ; then . /etc/init.d/functions else action() { descr=$1 ; shift cmd=$@ echo -n "$descr " $cmd ret=$? if [ $ret -eq 0 ] ; then echo "OK" else echo "Failed" fi return $ret } fi XE_LINUX_DISTRIBUTION=/usr/sbin/xe-linux-distribution XE_LINUX_DISTRIBUTION_CACHE=/var/cache/xe-linux-distribution XE_DAEMON=/usr/sbin/xe-daemon XE_DAEMON_PIDFILE=/var/run/xe-daemon.pid if [ ! -x "${XE_LINUX_DISTRIBUTION}" ] ; then exit 0 fi start() { if [ ! -e /proc/xen/xenbus ] ; then if [ ! -d /proc/xen ] ; then action $"Mounting xenfs on /proc/xen:" /bin/false echo "Could not find /proc/xen directory." echo "You need a post 2.6.29-rc1 kernel with CONFIG_XEN_COMPAT_XENFS=y and CONFIG_XENFS=y|m" exit 1 else # This is needed post 2.6.29-rc1 when /proc/xen support was pushed upstream as a xen filesystem action $"Mounting xenfs on /proc/xen:" mount -t xenfs none /proc/xen fi fi if [ -e /proc/xen/capabilities ] && grep -q control_d /proc/xen/capabilities ; then # Do not want daemon in domain 0 exit 0 fi action $"Detecting Linux distribution version:" \ ${XE_LINUX_DISTRIBUTION} ${XE_LINUX_DISTRIBUTION_CACHE} action $"Starting xe daemon: " /bin/true mkdir -p $(dirname ${XE_DAEMON_PIDFILE}) if start-stop-daemon --start --background --exec ${XE_DAEMON} -- -p ${XE_DAEMON_PIDFILE} 1>/dev/null 2>/dev/null; then exit 0 else # This is equivalent to daemon() in C ( exec &>/dev/null ; ${XE_DAEMON} -p ${XE_DAEMON_PIDFILE} 2>/dev/null & ) fi } stop() { [ ! -f "${XE_DAEMON_PIDFILE}" ] && return 0 action $"Stopping xe daemon: " kill -TERM $(cat ${XE_DAEMON_PIDFILE}) rm -f "${XE_DAEMON_PIDFILE}" return 0 } status() { cat ${XE_LINUX_DISTRIBUTION_CACHE} } # fail silently if not running xen if [ ! -d /proc/xen ]; then exit fi case "$1" in start) start ;; stop) stop ;; status) status ;; force-reload|restart) stop start ;; *) # do not advertise unreasonable commands that there is no reason # to use with this device echo $"Usage: $0 start|restart|status" exit 1 esac exit $? xe-guest-utilities-7.10.0/mk/xe-linux-distribution.service000066400000000000000000000003211325465104300236270ustar00rootroot00000000000000[Unit] Description=Linux Guest Agent [Service] ExecStartPre=/usr/share/oem/xs/xe-linux-distribution /var/cache/xe-linux-distribution ExecStart=/usr/share/oem/xs/xe-daemon [Install] WantedBy=multi-user.targetxe-guest-utilities-7.10.0/mk/xen-vcpu-hotplug.rules000066400000000000000000000001621325465104300222630ustar00rootroot00000000000000ACTION=="add", SUBSYSTEM=="cpu", RUN+="/bin/sh -c '[ ! -e /sys$devpath/online ] || echo 1 > /sys$devpath/online'" xe-guest-utilities-7.10.0/syslog/000077500000000000000000000000001325465104300166745ustar00rootroot00000000000000xe-guest-utilities-7.10.0/syslog/syslog.go000066400000000000000000000017061325465104300205470ustar00rootroot00000000000000// To run 32bit xe-daemon under 64bit system, // Here we re-implement a syslog writer base on logger CLI. package syslog import ( "io" "os" "os/exec" "time" ) const ( waitLoggerQuitSeconds = 5 ) type SysLoggerWriter struct { cmd *exec.Cmd stdin io.WriteCloser } func NewSyslogWriter(topic string) (io.Writer, error) { cmd := exec.Command("logger", "-t", topic) stdin, err := cmd.StdinPipe() if err != nil { return nil, err } err = cmd.Start() if err != nil { return nil, err } return &SysLoggerWriter{cmd, stdin}, nil } func (s *SysLoggerWriter) Write(data []byte) (int, error) { return s.stdin.Write(data) } func (s *SysLoggerWriter) Close() error { s.stdin.Close() s.cmd.Process.Signal(os.Interrupt) done := make(chan error, 1) go func(c chan<- error) { c <- s.cmd.Wait() }(done) select { case <-done: return nil case <-time.After(waitLoggerQuitSeconds * time.Second): return s.cmd.Process.Kill() } return nil } xe-guest-utilities-7.10.0/system/000077500000000000000000000000001325465104300167005ustar00rootroot00000000000000xe-guest-utilities-7.10.0/system/system.go000066400000000000000000000034001325465104300205500ustar00rootroot00000000000000package sys import ( "math" "syscall" "time" "unsafe" ) const ( CLOCK_REALTIME = 0 TFD_CLOEXEC = 02000000 TFD_TIMER_ABSTIME = 1 TFD_TIMER_CANCEL_ON_SET = 2 ) type ITimerSpec struct { Interval syscall.Timespec Value syscall.Timespec } // System call wrapper for timerfd_create, generated with mksyscall.pl func timerfdCreate(clockid int, flags int) (fd int, err error) { r0, _, e1 := syscall.Syscall(syscall.SYS_TIMERFD_CREATE, uintptr(clockid), uintptr(flags), 0) fd = int(r0) if e1 != 0 { err = e1 } return } // System call wrapper for timerfd_settime, generated with mksyscall.pl func timerfdSettime(fd int, flags int, new_value *ITimerSpec, old_value *ITimerSpec) (err error) { _, _, e1 := syscall.Syscall6(syscall.SYS_TIMERFD_SETTIME, uintptr(fd), uintptr(flags), uintptr(unsafe.Pointer(new_value)), uintptr(unsafe.Pointer(old_value)), 0, 0) if e1 != 0 { err = e1 } return } /* * Send a notification on @c when the system has just been resumed after * sleep. This is implemented by watching for a change in real time compared * with monotonic time. This may cause a spurious notification if the time * is changed by a user or NTP jump. */ func NotifyResumed(c chan int) { ts := ITimerSpec{Interval: syscall.Timespec{math.MaxInt32, 0}, Value: syscall.Timespec{0, 0}} buf := make([]byte, 8) for { fd, err := timerfdCreate(CLOCK_REALTIME, TFD_CLOEXEC) if err != nil { return } err = timerfdSettime(fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &ts, nil) if err != nil { return } _, err = syscall.Read(fd, buf) if err == syscall.ECANCELED { // Wait a bit for the system to settle down after resuming time.Sleep(time.Duration(1) * time.Second) c <- 1 } syscall.Close(fd) } } xe-guest-utilities-7.10.0/xe-daemon/000077500000000000000000000000001325465104300172315ustar00rootroot00000000000000xe-guest-utilities-7.10.0/xe-daemon/xe-daemon.go000066400000000000000000000100571325465104300214400ustar00rootroot00000000000000package main import ( guestmetric "../guestmetric" syslog "../syslog" system "../system" xenstoreclient "../xenstoreclient" "flag" "fmt" "io" "io/ioutil" "log" "os" "os/signal" "strconv" "syscall" "time" ) const ( LoggerName string = "xe-daemon" DivisorOne int = 1 DivisorTwo int = 2 DivisorLeastMultiple int = 2 // The least common multiple, ensure every collector done before executing InvalidCacheFlush. ) func main() { var err error sleepInterval := flag.Int("i", 60, "Interval between updates (in seconds)") debugFlag := flag.Bool("d", false, "Update to stdout rather than xenstore") balloonFlag := flag.Bool("B", true, "Do not report that ballooning is supported") pid := flag.String("p", "", "Write the PID to FILE") flag.Parse() if *pid != "" { if err = ioutil.WriteFile(*pid, []byte(strconv.Itoa(os.Getpid())), 0644); err != nil { fmt.Fprintf(os.Stderr, "Write pid to %s error: %s\n", *pid, err) return } } var loggerWriter io.Writer = os.Stderr var topic string = LoggerName if w, err := syslog.NewSyslogWriter(topic); err == nil { loggerWriter = w topic = "" } else { fmt.Fprintf(os.Stderr, "NewSyslogWriter(%s) error: %s, use stderr logging\n", topic, err) topic = LoggerName + ": " } logger := log.New(loggerWriter, topic, 0) exitChannel := make(chan os.Signal, 1) signal.Notify(exitChannel, syscall.SIGTERM, syscall.SIGINT) resumedChannel := make(chan int) go system.NotifyResumed(resumedChannel) xs, err := xenstoreclient.NewCachedXenstore(0) if err != nil { message := fmt.Sprintf("NewCachedXenstore error: %v\n", err) logger.Print(message) fmt.Fprint(os.Stderr, message) return } collector := &guestmetric.Collector{ Client: xs, Ballon: *balloonFlag, Debug: *debugFlag, } collectors := []struct { divisor int name string Collect func() (guestmetric.GuestMetric, error) }{ {DivisorOne, "CollectOS", collector.CollectOS}, {DivisorOne, "CollectMisc", collector.CollectMisc}, {DivisorOne, "CollectNetworkAddr", collector.CollectNetworkAddr}, {DivisorOne, "CollectDisk", collector.CollectDisk}, {DivisorTwo, "CollectMemory", collector.CollectMemory}, } lastUniqueID, err := xs.Read("unique-domain-id") if err != nil { logger.Printf("xenstore.Read unique-domain-id error: %v\n", err) } for count := 0; ; count += 1 { uniqueID, err := xs.Read("unique-domain-id") if err != nil { logger.Printf("xenstore.Read unique-domain-id error: %v\n", err) return } if uniqueID != lastUniqueID { // VM has just resume, cache state now invalid lastUniqueID = uniqueID if cx, ok := xs.(*xenstoreclient.CachedXenStore); ok { cx.Clear() } } // invoke collectors updated := false for _, collector := range collectors { if count%collector.divisor == 0 { if *debugFlag { logger.Printf("Running %s ...\n", collector.name) } result, err := collector.Collect() if err != nil { logger.Printf("%s error: %#v\n", collector.name, err) } else { for name, value := range result { err := xs.Write(name, value) if err != nil { logger.Printf("xenstore.Write error: %v\n", err) } else { if *debugFlag { logger.Printf("xenstore.Write OK: %#v: %#v\n", name, value) } updated = true } } } } } if count%DivisorLeastMultiple == 0 { if cx, ok := xs.(*xenstoreclient.CachedXenStore); ok { err := cx.InvalidCacheFlush() if err != nil { logger.Printf("InvalidCacheFlush error: %#v\n", err) } } } if updated { xs.Write("data/updated", time.Now().Format("Mon Jan _2 15:04:05 2006")) } select { case <-exitChannel: logger.Printf("Received an interrupt, stopping services...\n") if c, ok := loggerWriter.(io.Closer); ok { if err := c.Close(); err != nil { fmt.Fprintf(os.Stderr, "logger close error: %s\n", err) } } return case <-resumedChannel: logger.Printf("Trigger refresh after system resume\n") continue case <-time.After(time.Duration(*sleepInterval) * time.Second): continue } } } xe-guest-utilities-7.10.0/xenstore/000077500000000000000000000000001325465104300172235ustar00rootroot00000000000000xe-guest-utilities-7.10.0/xenstore/xenstore.go000066400000000000000000000053171325465104300214270ustar00rootroot00000000000000package main import ( xenstoreclient "../xenstoreclient" "fmt" "os" "strings" ) func die(format string, a ...interface{}) { fmt.Fprintf(os.Stderr, format, a...) fmt.Fprintln(os.Stderr) os.Exit(1) } func usage() { die( `Usage: xenstore read key [ key ... ] write key value [ key value ... ] rm key [ key ... ] exists key [ key ... ]`) } func new_xs() xenstoreclient.XenStoreClient { xs, err := xenstoreclient.NewXenstore(0) if err != nil { die("xenstore.Open error: %v", err) } return xs } func xs_read(script_name string, args []string) { if len(args) == 0 || args[0] == "-h" { die("Usage: %s key [ key ... ]", script_name) } xs := new_xs() for _, key := range args[:] { result, err := xs.Read(key) if err != nil { die("%s error: %v", script_name, err) } fmt.Println(result) } } func xs_list(script_name string, args []string) { if len(args) == 0 || args[0] == "-h" { die("Usage: %s key [ key ... ]", script_name) } xs := new_xs() for _, key := range args[:] { result, err := xs.List(key) if err != nil { die("%s error: %v", script_name, err) } for _, subPath := range result { fmt.Println(subPath) } } } func xs_write(script_name string, args []string) { if len(args) == 0 || args[0] == "-h" || len(args)%2 != 0 { die("Usage: %s key value [ key value ... ]", script_name) } xs := new_xs() for i := 0; i < len(args); i += 2 { key := args[i] value := args[i+1] err := xs.Write(key, value) if err != nil { die("%s error: %v", script_name, err) } } } func xs_rm(script_name string, args []string) { if len(args) == 0 || args[0] == "-h" { die("Usage: %s key [ key ... ]", script_name) } xs := new_xs() for _, key := range args[:] { err := xs.Rm(key) if err != nil { die("%s error: %v", script_name, err) } } } func xs_exists(script_name string, args []string) { if len(args) == 0 || args[0] == "-h" { die("Usage: %s key [ key ... ]", script_name) } xs := new_xs() for _, key := range args[:] { _, err := xs.Read(key) if err != nil { die("%s error: %v", script_name, err) } } } func main() { var operation string var args []string script_name := os.Args[0] if strings.Contains(script_name, "-") { operation = script_name[strings.LastIndex(script_name, "-")+1:] args = os.Args[1:] } else { if len(os.Args) < 2 { usage() } operation = os.Args[1] script_name = script_name + " " + operation args = os.Args[2:] } switch operation { case "read": xs_read(script_name, args) case "list": xs_list(script_name, args) case "write": xs_write(script_name, args) case "rm": xs_rm(script_name, args) case "exists": xs_exists(script_name, args) default: usage() } } xe-guest-utilities-7.10.0/xenstoreclient/000077500000000000000000000000001325465104300204225ustar00rootroot00000000000000xe-guest-utilities-7.10.0/xenstoreclient/xenstore.go000066400000000000000000000307701325465104300226270ustar00rootroot00000000000000package xenstoreclient import ( syslog "../syslog" "bufio" "bytes" "encoding/binary" "errors" "fmt" "io" "log" "os" "strconv" "strings" "sync" "time" ) type Permission int const ( PERM_NONE Permission = iota PERM_READ PERM_WRITE PERM_READWRITE ) type Operation uint32 const ( XS_DEBUG Operation = 0 XS_DIRECTORY Operation = 1 XS_READ Operation = 2 XS_GET_PERMS Operation = 3 XS_WATCH Operation = 4 XS_UNWATCH Operation = 5 XS_TRANSACTION_START Operation = 6 XS_TRANSACTION_END Operation = 7 XS_INTRODUCE Operation = 8 XS_RELEASE Operation = 9 XS_GET_DOMAIN_PATH Operation = 10 XS_WRITE Operation = 11 XS_MKDIR Operation = 12 XS_RM Operation = 13 XS_SET_PERMS Operation = 14 XS_WATCH_EVENT Operation = 15 XS_ERROR Operation = 16 XS_IS_DOMAIN_INTRODUCED Operation = 17 XS_RESUME Operation = 18 XS_SET_TARGET Operation = 19 XS_RESTRICT Operation = 128 ) type Packet struct { OpCode Operation Req uint32 TxID uint32 Length uint32 Value []byte } type XenStoreClient interface { Close() error DO(packet *Packet) (*Packet, error) Read(path string) (string, error) List(path string) ([]string, error) Mkdir(path string) error Rm(path string) error Write(path string, value string) error GetPermission(path string) (map[int]Permission, error) Watch(path string, token string) error WatchEvent(key string) (token string, ok bool) UnWatch(path string, token string) error StopWatch() error } func ReadPacket(r io.Reader) (packet *Packet, err error) { packet = &Packet{} err = binary.Read(r, binary.LittleEndian, &packet.OpCode) if err != nil { return nil, err } err = binary.Read(r, binary.LittleEndian, &packet.Req) if err != nil { return nil, err } err = binary.Read(r, binary.LittleEndian, &packet.TxID) if err != nil { return nil, err } err = binary.Read(r, binary.LittleEndian, &packet.Length) if err != nil { return nil, err } if packet.Length > 0 { packet.Value = make([]byte, packet.Length) _, err = io.ReadFull(r, packet.Value) if err != nil { return nil, err } if packet.OpCode == XS_ERROR { return nil, errors.New(strings.Split(string(packet.Value), "\x00")[0]) } } return packet, nil } func (p *Packet) Write(w io.Writer) (err error) { var bw *bufio.Writer if w1, ok := w.(*bufio.Writer); ok { bw = w1 } else { bw = bufio.NewWriter(w) } defer bw.Flush() err = binary.Write(bw, binary.LittleEndian, p.OpCode) if err != nil { return err } err = binary.Write(bw, binary.LittleEndian, p.Req) if err != nil { return err } err = binary.Write(bw, binary.LittleEndian, p.TxID) if err != nil { return err } err = binary.Write(bw, binary.LittleEndian, p.Length) if err != nil { return err } if p.Length > 0 { _, err = bw.Write(p.Value) if err != nil { return err } } return nil } type WatchQueueManager struct { watchQueues map[string]chan string rwlocker *sync.RWMutex } func (wq *WatchQueueManager) RemoveByKey(key string) { wq.rwlocker.Lock() defer wq.rwlocker.Unlock() delete(wq.watchQueues, key) return } func (wq *WatchQueueManager) SetEventByKey(key string, token string) (ok bool) { wq.rwlocker.RLock() defer wq.rwlocker.RUnlock() wq.watchQueues[key] <- token return } func (wq *WatchQueueManager) GetEventByKey(key string) (token string, ok bool) { wq.rwlocker.RLock() defer wq.rwlocker.RUnlock() ec, ok := wq.watchQueues[key] if len(ec) != 0 { return <-ec, ok } else { ok = false } return } func (wq *WatchQueueManager) AddChanByKey(key string) { wq.rwlocker.Lock() defer wq.rwlocker.Unlock() wq.watchQueues[key] = make(chan string, 100) } type XenStore struct { tx uint32 xbFile io.ReadWriteCloser xbFileReader *bufio.Reader muWatch *sync.Mutex onceWatch *sync.Once watchQueue WatchQueueManager watchStopChan chan struct{} watchStoppedChan chan struct{} nonWatchQueue chan []byte xbFileReaderLocker *sync.Mutex logger *log.Logger } func NewXenstore(tx uint32) (XenStoreClient, error) { devPath, err := getDevPath() if err != nil { return nil, err } xbFile, err := os.OpenFile(devPath, os.O_RDWR, 0666) if err != nil { return nil, err } return newXenstore(tx, xbFile) } const ( LoggerName string = "xenstore" ) func newXenstore(tx uint32, rwc io.ReadWriteCloser) (XenStoreClient, error) { var loggerWriter io.Writer = os.Stderr var topic string = LoggerName if w, err := syslog.NewSyslogWriter(topic); err == nil { loggerWriter = w topic = "" } else { fmt.Fprintf(os.Stderr, "NewSyslogWriter(%s) error: %s, use stderr logging\n", topic, err) topic = LoggerName + ": " } logger := log.New(loggerWriter, topic, 0) return &XenStore{ tx: tx, xbFile: rwc, xbFileReader: bufio.NewReader(rwc), watchQueue: WatchQueueManager{ watchQueues: make(map[string]chan string, 0), rwlocker: &sync.RWMutex{}, }, nonWatchQueue: nil, watchStopChan: make(chan struct{}, 1), watchStoppedChan: make(chan struct{}, 1), onceWatch: &sync.Once{}, muWatch: &sync.Mutex{}, xbFileReaderLocker: &sync.Mutex{}, logger: logger, }, nil } func (xs *XenStore) Close() error { return xs.xbFile.Close() } func (xs *XenStore) DO(req *Packet) (resp *Packet, err error) { xs.xbFileReaderLocker.Lock() defer xs.xbFileReaderLocker.Unlock() err = req.Write(xs.xbFile) if err != nil { return nil, err } var r io.Reader if xs.nonWatchQueue != nil { data := <-xs.nonWatchQueue r = bytes.NewReader(data) } else { r = xs.xbFileReader } resp, err = ReadPacket(r) return resp, err } func (xs *XenStore) Read(path string) (string, error) { v := []byte(path + "\x00") req := &Packet{ OpCode: XS_READ, Req: 0, TxID: xs.tx, Length: uint32(len(v)), Value: v, } resp, err := xs.DO(req) if err != nil { return "", err } return string(resp.Value), nil } func (xs *XenStore) List(path string) ([]string, error) { v := []byte(path + "\x00") req := &Packet{ OpCode: XS_DIRECTORY, Req: 0, TxID: xs.tx, Length: uint32(len(v)), Value: v, } resp, err := xs.DO(req) if err != nil { return []string{}, err } subItems := strings.Split( string(bytes.Trim(resp.Value, "\x00")), "\x00") return subItems, nil } func (xs *XenStore) Mkdir(path string) error { v := []byte(path + "\x00") req := &Packet{ OpCode: XS_WRITE, Req: 0, TxID: xs.tx, Length: uint32(len(v)), Value: v, } _, err := xs.DO(req) return err } func (xs *XenStore) Rm(path string) error { v := []byte(path + "\x00") req := &Packet{ OpCode: XS_RM, Req: 0, TxID: xs.tx, Length: uint32(len(v)), Value: v, } _, err := xs.DO(req) return err } func (xs *XenStore) Write(path string, value string) error { v := []byte(path + "\x00" + value) req := &Packet{ OpCode: XS_WRITE, Req: 0, TxID: xs.tx, Length: uint32(len(v)), Value: v, } _, err := xs.DO(req) return err } func (xs *XenStore) GetPermission(path string) (map[int]Permission, error) { perm := make(map[int]Permission, 0) v := []byte(path + "\x00") req := &Packet{ OpCode: XS_GET_PERMS, Req: 0, TxID: xs.tx, Length: uint32(len(v)), Value: v, } resp, err := xs.DO(req) if err != nil { return nil, err } for _, e := range strings.Split(string(resp.Value[:len(resp.Value)-1]), "\x00") { k, err := strconv.Atoi(e[1:]) if err != nil { return nil, err } var p Permission switch e[0] { case 'n': p = PERM_NONE case 'r': p = PERM_READ case 'w': p = PERM_WRITE case 'b': p = PERM_READWRITE } perm[k] = p } return perm, nil } func (xs *XenStore) UnWatch(path string, token string) (err error) { v := []byte(path + "\x00" + token + "\x00") req := &Packet{ OpCode: XS_UNWATCH, Req: 0, TxID: xs.tx, Length: uint32(len(v)), Value: v, } _, err = xs.DO(req) if err != nil { return } xs.watchQueue.RemoveByKey(path) return nil } func (xs *XenStore) Watch(path string, token string) error { watcher := func() { xs.logger.Printf("Watch: Start") type XSData struct { *Packet Error error } xsDataChan := make(chan XSData, 100) xsReadStop := make(chan bool) go func(r io.Reader, out chan<- XSData, c <-chan bool) { for { // The read will return at once if no data in r p, err := ReadPacket(r) ticker := time.Tick(1 * time.Second) if err != nil { select { case <-c: return case <-ticker: continue } } out <- XSData{Packet: p, Error: err} } }(xs.xbFileReader, xsDataChan, xsReadStop) xs.nonWatchQueue = make(chan []byte, 100) for { select { case <-xs.watchStopChan: xs.logger.Printf("Watch: receive stop signal, quit.\n") xs.watchStoppedChan <- struct{}{} xsReadStop <- true return case xsdata := <-xsDataChan: if xsdata.Error != nil { xs.logger.Printf("Watch: receive error: %#v", xsdata.Error) return } switch xsdata.Packet.OpCode { case XS_WATCH_EVENT: parts := strings.SplitN(string(xsdata.Value), "\x00", 2) path := parts[0] token := parts[1] xs.logger.Printf("Get XS_WATCH_EVENT key:%s, token:%s\n", path, token) xs.watchQueue.SetEventByKey(path, token) default: xs.logger.Printf("Get non watch event %#v\n", xsdata.Packet.OpCode) var b bytes.Buffer xsdata.Packet.Write(&b) xs.nonWatchQueue <- b.Bytes() } } } } xs.muWatch.Lock() defer xs.muWatch.Unlock() v := []byte(path + "\x00" + token + "\x00") req := &Packet{ OpCode: XS_WATCH, Req: 0, TxID: xs.tx, Length: uint32(len(v)), Value: v, } _, err := xs.DO(req) if err != nil { xs.logger.Printf("Watch failed with error %#v\n", err) return err } xs.watchQueue.AddChanByKey(path) go xs.onceWatch.Do(watcher) return nil } func (xs *XenStore) WatchEvent(key string) (token string, ok bool) { return xs.watchQueue.GetEventByKey(key) } func (xs *XenStore) StopWatch() error { xs.watchStopChan <- struct{}{} xs.nonWatchQueue = nil <-xs.watchStoppedChan return nil } type Content struct { value string keepalive bool } type CachedXenStore struct { xs XenStoreClient writeCache map[string]Content } func NewCachedXenstore(tx uint32) (XenStoreClient, error) { xs, err := NewXenstore(tx) if err != nil { return nil, err } return &CachedXenStore{ xs: xs, writeCache: make(map[string]Content, 0), }, nil } func (xs *CachedXenStore) Write(path string, value string) error { if v, ok := xs.writeCache[path]; ok && v.value == value { v.keepalive = true xs.writeCache[path] = v return nil } err := xs.xs.Write(path, value) if err == nil { xs.writeCache[path] = Content{value: value, keepalive: true} } return err } func (xs *CachedXenStore) Close() error { return xs.xs.Close() } func (xs *CachedXenStore) DO(req *Packet) (resp *Packet, err error) { return xs.xs.DO(req) } func (xs *CachedXenStore) Read(path string) (string, error) { return xs.xs.Read(path) } func (xs *CachedXenStore) List(path string) ([]string, error) { return xs.xs.List(path) } func (xs *CachedXenStore) Mkdir(path string) error { return xs.xs.Mkdir(path) } func (xs *CachedXenStore) Rm(path string) error { return xs.xs.Rm(path) } func (xs *CachedXenStore) GetPermission(path string) (map[int]Permission, error) { return xs.xs.GetPermission(path) } func (xs *CachedXenStore) Watch(path string, token string) error { return xs.xs.Watch(path, token) } func (xs *CachedXenStore) WatchEvent(key string) (token string, ok bool) { return xs.xs.WatchEvent(key) } func (xs *CachedXenStore) UnWatch(path string, token string) error { return xs.xs.UnWatch(path, token) } func (xs *CachedXenStore) StopWatch() error { return xs.xs.StopWatch() } func (xs *CachedXenStore) Clear() { xs.writeCache = make(map[string]Content, 0) } func (xs *CachedXenStore) InvalidCacheFlush() error { for key, value := range xs.writeCache { if value.keepalive { value.keepalive = false xs.writeCache[key] = value } else { err := xs.Rm(key) if err != nil { return err } else { delete(xs.writeCache, key) } } } return nil } func getDevPath() (devPath string, err error) { devPaths := []string{ "/proc/xen/xenbus", "/dev/xen/xenbus", "/kern/xen/xenbus", } for _, devPath = range devPaths { if _, err = os.Stat(devPath); err == nil { return devPath, err } } return "", fmt.Errorf("Cannot locate xenbus dev path in %v", devPaths) } xe-guest-utilities-7.10.0/xenstoreclient/xenstore_test.go000066400000000000000000000033531325465104300236630ustar00rootroot00000000000000package xenstoreclient import ( "bytes" "fmt" "io" "testing" "time" ) type mockFile struct { r io.Reader w io.Writer watchKeys map[string]struct{} t *testing.T } func NewMockFile(t *testing.T) io.ReadWriteCloser { var b bytes.Buffer return &mockFile{ r: &b, w: &b, t: t, watchKeys: make(map[string]struct{}), } } func (f *mockFile) Read(p []byte) (n int, err error) { for i := 0; i < 1; i++ { n, err = f.r.Read(p) if err == io.EOF { fmt.Printf("Read sleep %#v second\n", i) time.Sleep(1 * time.Second) } else { fmt.Printf("Read=%#v err %#v\n", n, err) return } } return 0, io.EOF } func (f *mockFile) Write(b []byte) (n int, err error) { n, err = f.w.Write(b) fmt.Printf("Write=%#v err %#v\n", n, err) return } func (f *mockFile) Close() error { f.t.Logf("Close()") return nil } func TestXenStore(t *testing.T) { xs, err := newXenstore(0, NewMockFile(t)) if err != nil { t.Errorf("newXenstore error: %#v\n", err) } defer xs.Close() if err := xs.Write("foo", "bar"); err != nil { t.Errorf("xs.Write error: %#v\n", err) } if _, err := xs.Read("foo"); err != nil { t.Errorf("xs.Read error: %#v\n", err) } } func TestXenStoreWatch2(t *testing.T) { xs, err := newXenstore(0, NewMockFile(t)) if err != nil { t.Errorf("newXenstore error: %#v\n", err) } defer xs.Close() go func() { time.Sleep(5 * time.Second) if err := xs.StopWatch(); err != nil { t.Errorf("xs.StopWatch error: %#v\n", err) } }() go func() { for i := 0; i < 5; i++ { xs.Write("foo", "bar") time.Sleep(1 * time.Second) } }() err = xs.Watch("foo", "test") if err != nil { t.Errorf("xs.Watch(\"foo\") error: %#v\n", err) } time.Sleep(6 * time.Second) }