Compare commits
273 Commits
0.10.5
...
lock_unloc
Author | SHA1 | Date | |
---|---|---|---|
cd30bedd2b | |||
|
fa0178cd47 | ||
|
778a47b957 | ||
|
86909e5bcb | ||
|
0fd3cd2fae | ||
|
ad81cf7f78 | ||
|
0a500a19ff | ||
|
b9f34d93ad | ||
|
2f5d8cc188 | ||
|
b56c0f5609 | ||
|
cd1994b007 | ||
|
1fd780befc | ||
|
8847a471c5 | ||
|
c0c144bd56 | ||
|
1d962916b9 | ||
|
bda6668f00 | ||
|
0f828db9a3 | ||
|
5970000589 | ||
|
7870fa8c9d | ||
|
b4d45306b2 | ||
|
3c2b5e6636 | ||
|
bf743b3060 | ||
|
3b98be7788 | ||
|
746685023f | ||
|
a0fcbb16d6 | ||
|
f63fa39a2d | ||
|
0ae90f3b22 | ||
|
dee67b964a | ||
|
05062188f1 | ||
|
5405fc9d0d | ||
|
c7f327bb89 | ||
|
71e2b2bddb | ||
|
8fac253214 | ||
|
e19fd09664 | ||
|
4a25948b53 | ||
|
f5cc75299a | ||
|
f816819c6d | ||
|
5f688a0a21 | ||
|
f92dcb7968 | ||
|
bb71f5e072 | ||
|
ed512c1cac | ||
|
94f8e00054 | ||
|
b5cb942acb | ||
|
de38ac5c98 | ||
|
dfc5f2627f | ||
|
057e8094d5 | ||
|
15b50d4712 | ||
|
dda5032296 | ||
|
d675638776 | ||
|
61e3595520 | ||
|
4f76283917 | ||
|
9c4aca6c9a | ||
|
13dc11abf3 | ||
|
9ba25550a1 | ||
|
81ffa056bd | ||
|
8c804a1124 | ||
|
0a46b32c88 | ||
|
fac805dc11 | ||
|
94ea0b99ea | ||
|
56a80d84cf | ||
|
00c9174da4 | ||
|
ec8742c9ba | ||
|
b3b09aeb19 | ||
|
481d98c0b5 | ||
|
f30727a675 | ||
|
fc4efb086b | ||
|
5383bd1f07 | ||
|
e1305937e6 | ||
|
20c4653ecf | ||
|
43c6da06a5 | ||
|
7ab84601c3 | ||
|
a24b23663c | ||
|
91fe744bd2 | ||
|
eb8fc045ee | ||
|
ba83b2871f | ||
|
f36821f7ce | ||
|
97fe210760 | ||
|
c6400f7751 | ||
|
f6647634f0 | ||
|
837d3d3622 | ||
|
1063a4b9ee | ||
|
081f77a102 | ||
|
41289286ca | ||
|
d50a4069a6 | ||
|
be0c9c56e4 | ||
|
6467f06656 | ||
|
7a05e63fcc | ||
|
ca6f97d050 | ||
|
d086bca9e4 | ||
|
d25f18776f | ||
|
c583b77cdb | ||
|
ed4d5fac4c | ||
|
40429204ba | ||
|
d72d54be59 | ||
|
373c7ecbd9 | ||
|
31c46c7051 | ||
|
66ec7d805c | ||
|
2563896f89 | ||
|
94a242cc58 | ||
|
5b159fcf56 | ||
|
a9e8940132 | ||
|
cf194ab85e | ||
|
33bc5fc63d | ||
|
09f6a279ef | ||
|
e8c8b811fe | ||
|
f5ecc05d62 | ||
|
66a2f00679 | ||
|
14cad6f7c3 | ||
|
6f188bd5d4 | ||
|
41832ab19e | ||
|
672e4c07af | ||
|
be53013431 | ||
|
c30fc51b03 | ||
|
b429eaab84 | ||
|
e0104e6d93 | ||
|
7bf9712724 | ||
|
78b0f82918 | ||
|
987aa21883 | ||
|
47ac4f6931 | ||
|
f8aa7a43b8 | ||
|
2fe0b0b2a8 | ||
|
19ce7ac849 | ||
|
477053ffde | ||
|
eb0d2dbfa3 | ||
|
18caa5bf07 | ||
|
a27bbb912f | ||
|
3b2af743bd | ||
|
995bc63abe | ||
|
a28f870302 | ||
|
a3357c273c | ||
|
080c698ec2 | ||
|
afbf1dbb3a | ||
|
a275e18533 | ||
|
cf3baa8805 | ||
|
ed84bcef04 | ||
|
7d8b29e597 | ||
|
4eaaa5c927 | ||
|
536f8acf2a | ||
|
9605b5edf2 | ||
|
42153edbbc | ||
|
650a239fdb | ||
|
3e47c09b41 | ||
|
d4c617fc23 | ||
|
9441586229 | ||
|
be62a1df66 | ||
|
c093e44049 | ||
|
be68a8e5cc | ||
|
58b4de8093 | ||
|
ae3676096c | ||
|
a548b557ed | ||
|
a9c132a706 | ||
|
c3c4b86a3b | ||
|
44142ff8af | ||
|
e9529ede44 | ||
|
4b5b801171 | ||
|
551cbb1e5d | ||
|
3c93938f8a | ||
|
f61c08c246 | ||
|
571903cec6 | ||
|
bdbd1930ed | ||
|
cc75a943ba | ||
|
fc77ba6355 | ||
|
7cfa0df7c4 | ||
|
58f0dadaf9 | ||
|
1ab530f157 | ||
|
13e4b77130 | ||
|
54c62cbb70 | ||
|
c8e864fef5 | ||
|
60a3377e7c | ||
|
5527f09778 | ||
|
54a64454b9 | ||
|
0e70d4f01f | ||
|
af8e590575 | ||
|
40d943fb7a | ||
|
248536a5cd | ||
|
4ed1d03c97 | ||
|
057ab37364 | ||
|
182241c8d3 | ||
|
edced59fa6 | ||
|
9be836df31 | ||
|
4e54447b8e | ||
|
999c38b09b | ||
|
06d13de5c3 | ||
|
5b0903d162 | ||
|
10669be7c0 | ||
|
2edae741e1 | ||
|
ea90e553d1 | ||
|
b0cfd86902 | ||
|
565a9540c9 | ||
|
fd10e27b99 | ||
|
39763d772c | ||
|
ee69b77bfb | ||
|
353444e56d | ||
|
112ba1e31f | ||
|
9c3cd9e69c | ||
|
685d8317bc | ||
|
f42d102b26 | ||
|
c944e9ef94 | ||
|
f10d6e8bef | ||
|
f3f3af79fd | ||
|
0e63aa0f6b | ||
|
b254e17e89 | ||
|
5c059b66f0 | ||
|
c628bef666 | ||
|
2270db3f7a | ||
|
d0d467813d | ||
|
123f111efe | ||
|
521ecfdab5 | ||
|
6d0fdf1a47 | ||
|
ffc54b028c | ||
|
420f7cf202 | ||
|
624df676d0 | ||
|
75ed8dacf9 | ||
|
dcaabe4d4a | ||
|
92c57423ba | ||
|
7447e133c9 | ||
|
4e466c12da | ||
|
333468dba3 | ||
|
55c3a793ad | ||
|
eca51031c8 | ||
|
19522bcb82 | ||
|
62248ea33d | ||
|
d2a19cc86d | ||
|
08131ffab1 | ||
|
4a0019c669 | ||
|
3275ead1ec | ||
|
32b6a55724 | ||
|
6c43644369 | ||
|
e6593d49e6 | ||
|
ab752b239f | ||
|
0742e4d357 | ||
|
78f586ec9e | ||
|
6f91b76d79 | ||
|
5c80ccacc4 | ||
|
44fdf95d99 | ||
|
0a62614eec | ||
|
97758b343b | ||
|
fb6f52b360 | ||
|
786cd2a539 | ||
|
45793f1254 | ||
|
b621756d92 | ||
|
a5b5c700a6 | ||
|
ea95920f31 | ||
|
d7602f3c08 | ||
|
a20addd05e | ||
|
d9d89a6fa0 | ||
|
3c26376326 | ||
|
d3294bcb86 | ||
|
dda314b518 | ||
|
055a3c339a | ||
|
51f37100a1 | ||
|
88e8265cd6 | ||
|
6e2db882e6 | ||
|
3e2823df1b | ||
|
46cb51cf91 | ||
|
1a6cee5305 | ||
|
d02aa18839 | ||
|
e9bda98b54 | ||
|
badc874b74 | ||
|
c9e8c887b8 | ||
|
8be307de49 | ||
|
562c474275 | ||
|
b6062f0644 | ||
|
c5fada6e69 | ||
|
5c5834863b | ||
|
44f0a949c5 | ||
|
106c4e7a2c | ||
|
6c1ba590aa | ||
|
45da664c59 | ||
|
2a71551ef2 | ||
|
84e1cb3242 | ||
|
5214ead926 | ||
|
e2c24c4cef |
14
.travis.yml
14
.travis.yml
@@ -1,10 +1,12 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.3
|
||||
- 1.2
|
||||
|
||||
install:
|
||||
- go get code.google.com/p/go.tools/cmd/cover
|
||||
sudo: false
|
||||
matrix:
|
||||
include:
|
||||
- go: 1.4
|
||||
install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get golang.org/x/tools/cmd/vet
|
||||
- go: 1.5
|
||||
|
||||
script:
|
||||
- ./test
|
||||
|
38
Documentation/cloud-config-deprecated.md
Normal file
38
Documentation/cloud-config-deprecated.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Deprecated Cloud-Config Features
|
||||
|
||||
## Retrieving SSH Authorized Keys
|
||||
|
||||
### From a GitHub User
|
||||
|
||||
Using the `coreos-ssh-import-github` field, we can import public SSH keys from a GitHub user to use as authorized keys to a server.
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
users:
|
||||
- name: elroy
|
||||
coreos-ssh-import-github: elroy
|
||||
```
|
||||
|
||||
### From an HTTP Endpoint
|
||||
|
||||
We can also pull public SSH keys from any HTTP endpoint which matches [GitHub's API response format](https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user).
|
||||
For example, if you have an installation of GitHub Enterprise, you can provide a complete URL with an authentication token:
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
users:
|
||||
- name: elroy
|
||||
coreos-ssh-import-url: https://github-enterprise.example.com/api/v3/users/elroy/keys?access_token=<TOKEN>
|
||||
```
|
||||
|
||||
You can also specify any URL whose response matches the JSON format for public keys:
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
users:
|
||||
- name: elroy
|
||||
coreos-ssh-import-url: https://example.com/public-keys
|
||||
```
|
26
Documentation/cloud-config-locations.md
Normal file
26
Documentation/cloud-config-locations.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Cloud-Config Locations
|
||||
|
||||
On every boot, coreos-cloudinit looks for a config file to configure your host. Here is a list of locations which are used by the Cloud-Config utility, depending on your CoreOS platform:
|
||||
|
||||
Location | Description
|
||||
--- | --- | ---
|
||||
|`/media/configvirtfs/openstack/latest/user_data`|`/media/configvirtfs` mount point with [config-2](/os/docs/latest/config-drive.html#contents-and-format) label. It should contain a `openstack/latest/user_data` relative path. Usually used by cloud providers or in VM installations.|
|
||||
|`/media/configdrive/openstack/latest/user_data`|FAT or ISO9660 filesystem with [config-2](/os/docs/latest/config-drive.html#qemu-virtfs) label and `/media/configdrive/` mount point. It should also contain a `openstack/latest/user_data` relative path. Usually used in installations which are configured by USB Flash sticks or CDROM media.|
|
||||
|Kernel command line: `cloud-config-url=http://example.com/user_data`.| You can find this string using this command `cat /proc/cmdline`. Usually used in [PXE](/os/docs/latest/booting-with-pxe.html) or [iPXE](/os/docs/latest/booting-with-ipxe.html) boots.|
|
||||
|`/var/lib/coreos-install/user_data`| When you install CoreOS manually using the [coreos-install](/os/docs/latest/installing-to-disk.html) tool. Usually used in bare metal installations.|
|
||||
|`/usr/share/oem/cloud-config.yml`| Path for OEM images.|
|
||||
|`/var/lib/coreos-vagrant/vagrantfile-user-data`| Vagrant OEM scripts automatically store Cloud-Config into this path. |
|
||||
|`/var/lib/waagent/CustomData`| Azure platform uses OEM path for first Cloud-Config initialization and then `/var/lib/waagent/CustomData` to apply your settings.|
|
||||
|`http://169.254.169.254/metadata/v1/user-data` `http://169.254.169.254/2009-04-04/user-data` `https://metadata.packet.net/userdata`|DigitalOcean, EC2 and Packet cloud providers correspondingly use these URLs to download Cloud-Config.|
|
||||
|`/usr/share/oem/bin/vmtoolsd --cmd "info-get guestinfo.coreos.config.data"`|Cloud-Config provided by [VMware Guestinfo][VMware Guestinfo]|
|
||||
|`/usr/share/oem/bin/vmtoolsd --cmd "info-get guestinfo.coreos.config.url"`|Cloud-Config URL provided by [VMware Guestinfo][VMware Guestinfo]|
|
||||
|
||||
[VMware Guestinfo]: vmware-guestinfo.md
|
||||
|
||||
You can also run the `coreos-cloudinit` tool manually and provide a path to your custom Cloud-Config file:
|
||||
|
||||
```sh
|
||||
sudo coreos-cloudinit --from-file=/home/core/cloud-config.yaml
|
||||
```
|
||||
|
||||
This command will apply your custom cloud-config.
|
@@ -17,11 +17,11 @@ For example, the following cloud-config document...
|
||||
#cloud-config
|
||||
coreos:
|
||||
oem:
|
||||
id: rackspace
|
||||
name: Rackspace Cloud Servers
|
||||
version-id: 168.0.0
|
||||
home-url: https://www.rackspace.com/cloud/servers/
|
||||
bug-report-url: https://github.com/coreos/coreos-overlay
|
||||
id: "rackspace"
|
||||
name: "Rackspace Cloud Servers"
|
||||
version-id: "168.0.0"
|
||||
home-url: "https://www.rackspace.com/cloud/servers/"
|
||||
bug-report-url: "https://github.com/coreos/coreos-overlay"
|
||||
```
|
||||
|
||||
...would be rendered to the following `/etc/oem-release`:
|
||||
|
@@ -1,6 +1,16 @@
|
||||
# Using Cloud-Config
|
||||
|
||||
CoreOS allows you to declaratively customize various OS-level items, such as network configuration, user accounts, and systemd units. This document describes the full list of items we can configure. The `coreos-cloudinit` program uses these files as it configures the OS after startup or during runtime. Your cloud-config is processed during each boot.
|
||||
CoreOS allows you to declaratively customize various OS-level items, such as network configuration, user accounts, and systemd units. This document describes the full list of items we can configure. The `coreos-cloudinit` program uses these files as it configures the OS after startup or during runtime.
|
||||
|
||||
Your cloud-config is processed during each boot. Invalid cloud-config won't be processed but will be logged in the journal. You can validate your cloud-config with the [CoreOS validator]({{site.url}}/validate) or by running `coreos-cloudinit -validate`.
|
||||
|
||||
In addition to `coreos-cloudinit -validate` command and https://coreos.com/validate/ online service you can debug `coreos-cloudinit` system output through the `journalctl` tool:
|
||||
|
||||
```sh
|
||||
journalctl _EXE=/usr/bin/coreos-cloudinit
|
||||
```
|
||||
|
||||
It will show `coreos-cloudinit` run output which was triggered by system boot.
|
||||
|
||||
## Configuration File
|
||||
|
||||
@@ -16,7 +26,7 @@ We've designed our implementation to allow the same cloud-config file to work ac
|
||||
|
||||
The cloud-config file uses the [YAML][yaml] file format, which uses whitespace and new-lines to delimit lists, associative arrays, and values.
|
||||
|
||||
A cloud-config file should contain `#cloud-config`, followed by an associative array which has zero or more of the following keys:
|
||||
A cloud-config file must contain a header: either `#cloud-config` for processing as cloud-config (suggested) or `#!` for processing as a shell script (advanced). If cloud-config has #cloud-config header, it should followed by an associative array which has zero or more of the following keys:
|
||||
|
||||
- `coreos`
|
||||
- `ssh_authorized_keys`
|
||||
@@ -27,6 +37,8 @@ A cloud-config file should contain `#cloud-config`, followed by an associative a
|
||||
|
||||
The expected values for these keys are defined in the rest of this document.
|
||||
|
||||
If cloud-config header starts on `#!` then coreos-cloudinit will recognize it as shell script which is interpreted by bash and run it as transient systemd service.
|
||||
|
||||
[yaml]: https://en.wikipedia.org/wiki/YAML
|
||||
|
||||
### Providing Cloud-Config with Config-Drive
|
||||
@@ -37,7 +49,7 @@ CoreOS tries to conform to each platform's native method to provide user data. E
|
||||
|
||||
### coreos
|
||||
|
||||
#### etcd
|
||||
#### etcd (deprecated. see etcd2)
|
||||
|
||||
The `coreos.etcd.*` parameters will be translated to a partial systemd unit acting as an etcd configuration file.
|
||||
If the platform environment supports the templating feature of coreos-cloudinit it is possible to automate etcd configuration with the `$private_ipv4` and `$public_ipv4` fields. For example, the following cloud-config document...
|
||||
@@ -47,15 +59,15 @@ If the platform environment supports the templating feature of coreos-cloudinit
|
||||
|
||||
coreos:
|
||||
etcd:
|
||||
name: node001
|
||||
name: "node001"
|
||||
# generate a new token for each unique cluster from https://discovery.etcd.io/new
|
||||
discovery: https://discovery.etcd.io/<token>
|
||||
discovery: "https://discovery.etcd.io/<token>"
|
||||
# multi-region and multi-cloud deployments need to use $public_ipv4
|
||||
addr: $public_ipv4:4001
|
||||
peer-addr: $private_ipv4:7001
|
||||
addr: "$public_ipv4:4001"
|
||||
peer-addr: "$private_ipv4:7001"
|
||||
```
|
||||
|
||||
...will generate a systemd unit drop-in like this:
|
||||
...will generate a systemd unit drop-in for etcd.service with the following contents:
|
||||
|
||||
```yaml
|
||||
[Service]
|
||||
@@ -66,23 +78,62 @@ Environment="ETCD_PEER_ADDR=192.0.2.13:7001"
|
||||
```
|
||||
|
||||
For more information about the available configuration parameters, see the [etcd documentation][etcd-config].
|
||||
Note that hyphens in the coreos.etcd.* keys are mapped to underscores.
|
||||
|
||||
_Note: The `$private_ipv4` and `$public_ipv4` substitution variables referenced in other documents are only supported on Amazon EC2, Google Compute Engine, OpenStack, Rackspace, DigitalOcean, and Vagrant._
|
||||
|
||||
[etcd-config]: https://github.com/coreos/etcd/blob/master/Documentation/configuration.md
|
||||
[etcd-config]: https://github.com/coreos/etcd/blob/release-0.4/Documentation/configuration.md
|
||||
|
||||
#### etcd2
|
||||
|
||||
The `coreos.etcd2.*` parameters will be translated to a partial systemd unit acting as an etcd configuration file.
|
||||
If the platform environment supports the templating feature of coreos-cloudinit it is possible to automate etcd configuration with the `$private_ipv4` and `$public_ipv4` fields. When generating a [discovery token](https://discovery.etcd.io/new?size=3), set the `size` parameter, since etcd uses this to determine if all members have joined the cluster. After the cluster is bootstrapped, it can grow or shrink from this configured size.
|
||||
|
||||
For example, the following cloud-config document...
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
coreos:
|
||||
etcd2:
|
||||
# generate a new token for each unique cluster from https://discovery.etcd.io/new?size=3
|
||||
discovery: "https://discovery.etcd.io/<token>"
|
||||
# multi-region and multi-cloud deployments need to use $public_ipv4
|
||||
advertise-client-urls: "http://$public_ipv4:2379"
|
||||
initial-advertise-peer-urls: "http://$private_ipv4:2380"
|
||||
# listen on both the official ports and the legacy ports
|
||||
# legacy ports can be omitted if your application doesn't depend on them
|
||||
listen-client-urls: "http://0.0.0.0:2379,http://0.0.0.0:4001"
|
||||
listen-peer-urls: "http://$private_ipv4:2380,http://$private_ipv4:7001"
|
||||
```
|
||||
|
||||
...will generate a systemd unit drop-in for etcd2.service with the following contents:
|
||||
|
||||
```yaml
|
||||
[Service]
|
||||
Environment="ETCD_DISCOVERY=https://discovery.etcd.io/<token>"
|
||||
Environment="ETCD_ADVERTISE_CLIENT_URLS=http://203.0.113.29:2379"
|
||||
Environment="ETCD_INITIAL_ADVERTISE_PEER_URLS=http://192.0.2.13:2380"
|
||||
Environment="ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379,http://0.0.0.0:4001"
|
||||
Environment="ETCD_LISTEN_PEER_URLS=http://192.0.2.13:2380,http://192.0.2.13:7001"
|
||||
```
|
||||
|
||||
For more information about the available configuration parameters, see the [etcd2 documentation][etcd2-config].
|
||||
|
||||
_Note: The `$private_ipv4` and `$public_ipv4` substitution variables referenced in other documents are only supported on Amazon EC2, Google Compute Engine, OpenStack, Rackspace, DigitalOcean, and Vagrant._
|
||||
|
||||
[etcd2-config]: https://github.com/coreos/etcd/blob/master/Documentation/configuration.md
|
||||
|
||||
#### fleet
|
||||
|
||||
The `coreos.fleet.*` parameters work very similarly to `coreos.etcd.*`, and allow for the configuration of fleet through environment variables. For example, the following cloud-config document...
|
||||
The `coreos.fleet.*` parameters work very similarly to `coreos.etcd2.*`, and allow for the configuration of fleet through environment variables. For example, the following cloud-config document...
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
coreos:
|
||||
fleet:
|
||||
public-ip: $public_ipv4
|
||||
metadata: region=us-west
|
||||
public-ip: "$public_ipv4"
|
||||
metadata: "region=us-west"
|
||||
```
|
||||
|
||||
...will generate a systemd unit drop-in like this:
|
||||
@@ -93,10 +144,92 @@ Environment="FLEET_PUBLIC_IP=203.0.113.29"
|
||||
Environment="FLEET_METADATA=region=us-west"
|
||||
```
|
||||
|
||||
List of fleet configuration parameters:
|
||||
|
||||
- **agent_ttl**: An Agent will be considered dead if it exceeds this amount of time to communicate with the Registry
|
||||
- **engine_reconcile_interval**: Interval in seconds at which the engine should reconcile the cluster schedule in etcd
|
||||
- **etcd_cafile**: Path to CA file used for TLS communication with etcd
|
||||
- **etcd_certfile**: Provide TLS configuration when SSL certificate authentication is enabled in etcd endpoints
|
||||
- **etcd_keyfile**: Path to private key file used for TLS communication with etcd
|
||||
- **etcd_key_prefix**: etcd prefix path to be used for fleet keys
|
||||
- **etcd_request_timeout**: Amount of time in seconds to allow a single etcd request before considering it failed
|
||||
- **etcd_servers**: Comma separated list of etcd endpoints
|
||||
- **metadata**: Comma separated key/value pairs that are published with the local to the fleet registry
|
||||
- **public_ip**: IP accessible by other nodes for inter-host communication
|
||||
- **verbosity**: Enable debug logging by setting this to an integer value greater than zero
|
||||
|
||||
For more information on fleet configuration, see the [fleet documentation][fleet-config].
|
||||
|
||||
[fleet-config]: https://github.com/coreos/fleet/blob/master/Documentation/deployment-and-configuration.md#configuration
|
||||
|
||||
#### flannel
|
||||
|
||||
The `coreos.flannel.*` parameters also work very similarly to `coreos.etcd2.*`
|
||||
and `coreos.fleet.*`. They can be used to set environment variables for
|
||||
flanneld. For example, the following cloud-config...
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
coreos:
|
||||
flannel:
|
||||
etcd_prefix: "/coreos.com/network2"
|
||||
```
|
||||
|
||||
...will generate a systemd unit drop-in like so:
|
||||
|
||||
```
|
||||
[Service]
|
||||
Environment="FLANNELD_ETCD_PREFIX=/coreos.com/network2"
|
||||
```
|
||||
|
||||
List of flannel configuration parameters:
|
||||
|
||||
- **etcd_endpoints**: Comma separated list of etcd endpoints
|
||||
- **etcd_cafile**: Path to CA file used for TLS communication with etcd
|
||||
- **etcd_certfile**: Path to certificate file used for TLS communication with etcd
|
||||
- **etcd_keyfile**: Path to private key file used for TLS communication with etcd
|
||||
- **etcd_prefix**: etcd prefix path to be used for flannel keys
|
||||
- **ip_masq**: Install IP masquerade rules for traffic outside of flannel subnet
|
||||
- **subnet_file**: Path to flannel subnet file to write out
|
||||
- **interface**: Interface (name or IP) that should be used for inter-host communication
|
||||
- **public_ip**: IP accessible by other nodes for inter-host communication
|
||||
|
||||
For more information on flannel configuration, see the [flannel documentation][flannel-readme].
|
||||
|
||||
[flannel-readme]: https://github.com/coreos/flannel/blob/master/README.md
|
||||
|
||||
#### locksmith
|
||||
|
||||
The `coreos.locksmith.*` parameters can be used to set environment variables
|
||||
for locksmith. For example, the following cloud-config...
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
coreos:
|
||||
locksmith:
|
||||
endpoint: "http://example.com:2379"
|
||||
```
|
||||
|
||||
...will generate a systemd unit drop-in like so:
|
||||
|
||||
```
|
||||
[Service]
|
||||
Environment="LOCKSMITHD_ENDPOINT=http://example.com:2379"
|
||||
```
|
||||
|
||||
List of locksmith configuration parameters:
|
||||
|
||||
- **endpoint**: Comma separated list of etcd endpoints
|
||||
- **etcd_cafile**: Path to CA file used for TLS communication with etcd
|
||||
- **etcd_certfile**: Path to certificate file used for TLS communication with etcd
|
||||
- **etcd_keyfile**: Path to private key file used for TLS communication with etcd
|
||||
|
||||
For the complete list of locksmith configuration parameters, see the [locksmith documentation][locksmith-readme].
|
||||
|
||||
[locksmith-readme]: https://github.com/coreos/locksmith/blob/master/README.md
|
||||
|
||||
#### update
|
||||
|
||||
The `coreos.update.*` parameters manipulate settings related to how CoreOS instances are updated.
|
||||
@@ -109,9 +242,12 @@ The `reboot-strategy` parameter also affects the behaviour of [locksmith](https:
|
||||
- _etcd-lock_: Reboot after first taking a distributed lock in etcd, this guarantees that only one host will reboot concurrently and that the cluster will remain available during the update.
|
||||
- _best-effort_ - If etcd is running, "etcd-lock", otherwise simply "reboot".
|
||||
- _off_ - Disable rebooting after updates are applied (not recommended).
|
||||
- **server**: is the omaha endpoint URL which will be queried for updates.
|
||||
- **server**: The location of the [CoreUpdate][coreupdate] server which will be queried for updates. Also known as the [omaha][omaha-docs] server endpoint.
|
||||
- **group**: signifies the channel which should be used for automatic updates. This value defaults to the version of the image initially downloaded. (one of "master", "alpha", "beta", "stable")
|
||||
|
||||
[coreupdate]: https://coreos.com/products/coreupdate
|
||||
[omaha-docs]: https://coreos.com/docs/coreupdate/custom-apps/coreupdate-protocol/
|
||||
|
||||
*Note: cloudinit will only manipulate the locksmith unit file in the systemd runtime directory (`/run/systemd/system/locksmithd.service`). If any manual modifications are made to an overriding unit configuration file (e.g. `/etc/systemd/system/locksmithd.service`), cloudinit will no longer be able to control the locksmith service unit.*
|
||||
|
||||
##### Example
|
||||
@@ -120,7 +256,7 @@ The `reboot-strategy` parameter also affects the behaviour of [locksmith](https:
|
||||
#cloud-config
|
||||
coreos:
|
||||
update:
|
||||
reboot-strategy: etcd-lock
|
||||
reboot-strategy: "etcd-lock"
|
||||
```
|
||||
|
||||
#### units
|
||||
@@ -135,6 +271,10 @@ Each item is an object with the following fields:
|
||||
- **content**: Plaintext string representing entire unit file. If no value is provided, the unit is assumed to exist already.
|
||||
- **command**: Command to execute on unit: start, stop, reload, restart, try-restart, reload-or-restart, reload-or-try-restart. The default behavior is to not execute any commands.
|
||||
- **mask**: Whether to mask the unit file by symlinking it to `/dev/null` (analogous to `systemctl mask <name>`). Note that unlike `systemctl mask`, **this will destructively remove any existing unit file** located at `/etc/systemd/system/<unit>`, to ensure that the mask succeeds. The default value is false.
|
||||
- **drop-ins**: A list of unit drop-ins with the following fields:
|
||||
- **name**: String representing unit's name. Required.
|
||||
- **content**: Plaintext string representing entire file. Required.
|
||||
|
||||
|
||||
**NOTE:** The command field is ignored for all network, netdev, and link units. The systemd-networkd.service unit will be restarted in their place.
|
||||
|
||||
@@ -147,8 +287,8 @@ Write a unit to disk, automatically starting it.
|
||||
|
||||
coreos:
|
||||
units:
|
||||
- name: docker-redis.service
|
||||
command: start
|
||||
- name: "docker-redis.service"
|
||||
command: "start"
|
||||
content: |
|
||||
[Unit]
|
||||
Description=Redis container
|
||||
@@ -161,17 +301,32 @@ coreos:
|
||||
ExecStop=/usr/bin/docker stop -t 2 redis_server
|
||||
```
|
||||
|
||||
Start the built-in `etcd` and `fleet` services:
|
||||
Add the DOCKER_OPTS environment variable to docker.service.
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
coreos:
|
||||
units:
|
||||
- name: etcd.service
|
||||
command: start
|
||||
- name: fleet.service
|
||||
command: start
|
||||
- name: "docker.service"
|
||||
drop-ins:
|
||||
- name: "50-insecure-registry.conf"
|
||||
content: |
|
||||
[Service]
|
||||
Environment=DOCKER_OPTS='--insecure-registry="10.0.1.0/24"'
|
||||
```
|
||||
|
||||
Start the built-in `etcd2` and `fleet` services:
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
coreos:
|
||||
units:
|
||||
- name: "etcd2.service"
|
||||
command: "start"
|
||||
- name: "fleet.service"
|
||||
command: "start"
|
||||
```
|
||||
|
||||
### ssh_authorized_keys
|
||||
@@ -185,7 +340,7 @@ Override this by using the `--ssh-key-name` flag when calling `coreos-cloudinit`
|
||||
#cloud-config
|
||||
|
||||
ssh_authorized_keys:
|
||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h...
|
||||
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h..."
|
||||
```
|
||||
|
||||
### hostname
|
||||
@@ -196,7 +351,7 @@ This is the local part of a fully-qualified domain name (i.e. `foo` in `foo.exam
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
hostname: coreos1
|
||||
hostname: "coreos1"
|
||||
```
|
||||
|
||||
### users
|
||||
@@ -213,10 +368,12 @@ All but the `passwd` and `ssh-authorized-keys` fields will be ignored if the use
|
||||
- **groups**: Add user to these additional groups
|
||||
- **no-user-group**: Boolean. Skip default group creation.
|
||||
- **ssh-authorized-keys**: List of public SSH keys to authorize for this user
|
||||
- **coreos-ssh-import-github**: Authorize SSH keys from Github user
|
||||
- **coreos-ssh-import-url**: Authorize SSH keys imported from a url endpoint.
|
||||
- **coreos-ssh-import-github** [DEPRECATED]: Authorize SSH keys from GitHub user
|
||||
- **coreos-ssh-import-github-users** [DEPRECATED]: Authorize SSH keys from a list of GitHub users
|
||||
- **coreos-ssh-import-url** [DEPRECATED]: Authorize SSH keys imported from a url endpoint.
|
||||
- **system**: Create the user as a system user. No home directory will be created.
|
||||
- **no-log-init**: Boolean. Skip initialization of lastlog and faillog databases.
|
||||
- **shell**: User's login shell.
|
||||
|
||||
The following fields are not yet implemented:
|
||||
|
||||
@@ -230,13 +387,13 @@ The following fields are not yet implemented:
|
||||
#cloud-config
|
||||
|
||||
users:
|
||||
- name: elroy
|
||||
passwd: $6$5s2u6/jR$un0AvWnqilcgaNB3Mkxd5yYv6mTlWfOoCYHZmfi3LDKVltj.E8XNKEcwWm...
|
||||
- name: "elroy"
|
||||
passwd: "$6$5s2u6/jR$un0AvWnqilcgaNB3Mkxd5yYv6mTlWfOoCYHZmfi3LDKVltj.E8XNKEcwWm..."
|
||||
groups:
|
||||
- sudo
|
||||
- docker
|
||||
- "sudo"
|
||||
- "docker"
|
||||
ssh-authorized-keys:
|
||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h...
|
||||
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h..."
|
||||
```
|
||||
|
||||
#### Generating a password hash
|
||||
@@ -259,43 +416,6 @@ perl -e 'print crypt("password","\$6\$SALT\$") . "\n"'
|
||||
|
||||
Using a higher number of rounds will help create more secure passwords, but given enough time, password hashes can be reversed. On most RPM based distributions there is a tool called mkpasswd available in the `expect` package, but this does not handle "rounds" nor advanced hashing algorithms.
|
||||
|
||||
#### Retrieving SSH Authorized Keys
|
||||
|
||||
##### From a GitHub User
|
||||
|
||||
Using the `coreos-ssh-import-github` field, we can import public SSH keys from a GitHub user to use as authorized keys to a server.
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
users:
|
||||
- name: elroy
|
||||
coreos-ssh-import-github: elroy
|
||||
```
|
||||
|
||||
##### From an HTTP Endpoint
|
||||
|
||||
We can also pull public SSH keys from any HTTP endpoint which matches [GitHub's API response format](https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user).
|
||||
For example, if you have an installation of GitHub Enterprise, you can provide a complete URL with an authentication token:
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
users:
|
||||
- name: elroy
|
||||
coreos-ssh-import-url: https://github-enterprise.example.com/api/v3/users/elroy/keys?access_token=<TOKEN>
|
||||
```
|
||||
|
||||
You can also specify any URL whose response matches the JSON format for public keys:
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
users:
|
||||
- name: elroy
|
||||
coreos-ssh-import-url: https://example.com/public-keys
|
||||
```
|
||||
|
||||
### write_files
|
||||
|
||||
The `write_files` directive defines a set of files to create on the local filesystem.
|
||||
@@ -303,25 +423,45 @@ Each item in the list may have the following keys:
|
||||
|
||||
- **path**: Absolute location on disk where contents should be written
|
||||
- **content**: Data to write at the provided `path`
|
||||
- **permissions**: String representing file permissions in octal notation (i.e. '0644')
|
||||
- **permissions**: Integer representing file permissions, typically in octal notation (i.e. 0644)
|
||||
- **owner**: User and group that should own the file written to disk. This is equivalent to the `<user>:<group>` argument to `chown <user>:<group> <path>`.
|
||||
- **encoding**: Optional. The encoding of the data in content. If not specified this defaults to the yaml document encoding (usually utf-8). Supported encoding types are:
|
||||
- **b64, base64**: Base64 encoded content
|
||||
- **gz, gzip**: gzip encoded content, for use with the !!binary tag
|
||||
- **gz+b64, gz+base64, gzip+b64, gzip+base64**: Base64 encoded gzip content
|
||||
|
||||
Explicitly not implemented is the **encoding** attribute.
|
||||
The **content** field must represent exactly what should be written to disk.
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
write_files:
|
||||
- path: /etc/resolv.conf
|
||||
permissions: 0644
|
||||
owner: root
|
||||
- path: "/etc/resolv.conf"
|
||||
permissions: "0644"
|
||||
owner: "root"
|
||||
content: |
|
||||
nameserver 8.8.8.8
|
||||
- path: /etc/motd
|
||||
permissions: 0644
|
||||
owner: root
|
||||
- path: "/etc/motd"
|
||||
permissions: "0644"
|
||||
owner: "root"
|
||||
content: |
|
||||
Good news, everyone!
|
||||
- path: "/tmp/like_this"
|
||||
permissions: "0644"
|
||||
owner: "root"
|
||||
encoding: "gzip"
|
||||
content: !!binary |
|
||||
H4sIAKgdh1QAAwtITM5WyK1USMqvUCjPLMlQSMssS1VIya9KzVPIySwszS9SyCpNLwYARQFQ5CcAAAA=
|
||||
- path: "/tmp/or_like_this"
|
||||
permissions: "0644"
|
||||
owner: "root"
|
||||
encoding: "gzip+base64"
|
||||
content: |
|
||||
H4sIAKgdh1QAAwtITM5WyK1USMqvUCjPLMlQSMssS1VIya9KzVPIySwszS9SyCpNLwYARQFQ5CcAAAA=
|
||||
- path: "/tmp/todolist"
|
||||
permissions: "0644"
|
||||
owner: "root"
|
||||
encoding: "base64"
|
||||
content: |
|
||||
UGFjayBteSBib3ggd2l0aCBmaXZlIGRvemVuIGxpcXVvciBqdWdz
|
||||
```
|
||||
|
||||
### manage_etc_hosts
|
||||
@@ -334,5 +474,5 @@ infrastructure in place to resolve its own hostname, for example, when using Vag
|
||||
```yaml
|
||||
#cloud-config
|
||||
|
||||
manage_etc_hosts: localhost
|
||||
manage_etc_hosts: "localhost"
|
||||
```
|
||||
|
@@ -4,7 +4,7 @@ CoreOS supports providing configuration data via [config drive][config-drive]
|
||||
disk images. Currently only providing a single script or cloud config file is
|
||||
supported.
|
||||
|
||||
[config-drive]: http://docs.openstack.org/user-guide/content/enable_config_drive.html#config_drive_contents
|
||||
[config-drive]: http://docs.openstack.org/user-guide/cli_config_drive.html
|
||||
|
||||
## Contents and Format
|
||||
|
||||
@@ -21,6 +21,12 @@ mkisofs -R -V config-2 -o configdrive.iso /tmp/new-drive
|
||||
rm -r /tmp/new-drive
|
||||
```
|
||||
|
||||
If on OS X, replace the `mkisofs` invocation with:
|
||||
|
||||
```sh
|
||||
hdiutil makehybrid -iso -joliet -default-volume-name config-2 -o configdrive.iso /tmp/new-drive
|
||||
```
|
||||
|
||||
## QEMU virtfs
|
||||
|
||||
One exception to the above, when using QEMU it is possible to skip creating an
|
||||
|
35
Documentation/vmware-guestinfo.md
Normal file
35
Documentation/vmware-guestinfo.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# VMWare Guestinfo Interface
|
||||
|
||||
## Cloud-Config VMWare Guestinfo Variables
|
||||
|
||||
coreos-cloudinit accepts configuration from the VMware RPC API's *guestinfo*
|
||||
facility. This datasource can be enabled with the `--from-vmware-guestinfo`
|
||||
flag to coreos-cloudinit.
|
||||
|
||||
The following guestinfo variables are recognized and processed by cloudinit
|
||||
when passed from the hypervisor to the virtual machine at boot time. Note that
|
||||
property names are prefixed with `guestinfo.` in the VMX, e.g., `guestinfo.hostname`.
|
||||
|
||||
| guestinfo variable | type |
|
||||
|:--------------------------------------|:--------------------------------|
|
||||
| `hostname` | `hostname` |
|
||||
| `interface.<n>.name` | `string` |
|
||||
| `interface.<n>.mac` | `MAC address` |
|
||||
| `interface.<n>.dhcp` | `{"yes", "no"}` |
|
||||
| `interface.<n>.role` | `{"public", "private"}` |
|
||||
| `interface.<n>.ip.<m>.address` | `CIDR IP address` |
|
||||
| `interface.<n>.route.<l>.gateway` | `IP address` |
|
||||
| `interface.<n>.route.<l>.destination` | `CIDR IP address` |
|
||||
| `dns.server.<x>` | `IP address` |
|
||||
| `coreos.config.data` | `string` |
|
||||
| `coreos.config.data.encoding` | `{"", "base64", "gzip+base64"}` |
|
||||
| `coreos.config.url` | `URL` |
|
||||
|
||||
Note: "n", "m", "l", and "x" are 0-indexed, incrementing integers. The
|
||||
identifier for an `interface` does not correspond to anything outside of this
|
||||
configuration; it serves only to distinguish between multiple `interface`s.
|
||||
|
||||
The guide to [booting on VMWare][bootvmware] is the starting point for more
|
||||
information about configuring and running CoreOS on VMWare.
|
||||
|
||||
[bootvmware]: https://github.com/coreos/docs/blob/master/os/booting-on-vmware.md
|
38
Godeps/Godeps.json
generated
Normal file
38
Godeps/Godeps.json
generated
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"ImportPath": "github.com/coreos/coreos-cloudinit",
|
||||
"GoVersion": "go1.3.3",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/cloudsigma/cepgo",
|
||||
"Rev": "1bfc4895bf5c4d3b599f3f6ee142299488c8739b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/go-systemd/dbus",
|
||||
"Rev": "4fbc5060a317b142e6c7bfbedb65596d5f0ab99b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/yaml",
|
||||
"Rev": "6b16a5714269b2f70720a45406b1babd947a17ef"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dotcloud/docker/pkg/netlink",
|
||||
"Comment": "v0.11.1-359-g55d41c3e21e1",
|
||||
"Rev": "55d41c3e21e1593b944c06196ffb2ac57ab7f653"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/guelfey/go.dbus",
|
||||
"Rev": "f6a3a2366cc39b8479cadc499d3c735fb10fbdda"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/tarm/goserial",
|
||||
"Rev": "cdabc8d44e8e84f58f18074ae44337e1f2f375b9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/sigma/vmw-guestinfo",
|
||||
"Rev": "de573afc542e0268fe8478d46e237fad9d6f7aec"
|
||||
}
|
||||
]
|
||||
}
|
5
Godeps/Readme
generated
Normal file
5
Godeps/Readme
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
This directory tree is generated automatically by godep.
|
||||
|
||||
Please do not edit.
|
||||
|
||||
See https://github.com/tools/godep for more information.
|
2
Godeps/_workspace/.gitignore
generated
vendored
Normal file
2
Godeps/_workspace/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/pkg
|
||||
/bin
|
23
Godeps/_workspace/src/github.com/cloudsigma/cepgo/.gitignore
generated
vendored
Normal file
23
Godeps/_workspace/src/github.com/cloudsigma/cepgo/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
@@ -48,7 +48,7 @@ import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/tarm/goserial"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/tarm/goserial"
|
||||
)
|
||||
|
||||
const (
|
@@ -23,7 +23,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
|
||||
)
|
||||
|
||||
const signalBuffer = 100
|
@@ -18,7 +18,7 @@ package dbus
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
|
||||
)
|
||||
|
||||
func (c *Conn) initJobs() {
|
||||
@@ -208,7 +208,7 @@ func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Proper
|
||||
}
|
||||
|
||||
func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) {
|
||||
return c.getProperty(unit, "org.freedesktop.systemd1." + unitType, propertyName)
|
||||
return c.getProperty(unit, "org.freedesktop.systemd1."+unitType, propertyName)
|
||||
}
|
||||
|
||||
// ListUnits returns an array with all currently loaded units. Note that
|
@@ -18,7 +18,7 @@ package dbus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
package dbus
|
||||
|
||||
import (
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
|
||||
)
|
||||
|
||||
// From the systemd docs:
|
@@ -20,7 +20,7 @@ import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -101,7 +101,7 @@ func (c *Conn) SubscribeUnits(interval time.Duration) (<-chan map[string]*UnitSt
|
||||
// SubscribeUnitsCustom is like SubscribeUnits but lets you specify the buffer
|
||||
// size of the channels, the comparison function for detecting changes and a filter
|
||||
// function for cutting down on the noise that your channel receives.
|
||||
func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func (string) bool) (<-chan map[string]*UnitStatus, <-chan error) {
|
||||
func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func(string) bool) (<-chan map[string]*UnitStatus, <-chan error) {
|
||||
old := make(map[string]*UnitStatus)
|
||||
statusChan := make(chan map[string]*UnitStatus, buffer)
|
||||
errChan := make(chan error, buffer)
|
@@ -1,3 +1,6 @@
|
||||
|
||||
Copyright (c) 2011-2014 - Canonical Inc.
|
||||
|
||||
This software is licensed under the LGPLv3, included below.
|
||||
|
||||
As a special exception to the GNU Lesser General Public License version 3
|
@@ -1,3 +1,6 @@
|
||||
Note: This is a fork of https://github.com/go-yaml/yaml. The following README
|
||||
doesn't necessarily apply to this fork.
|
||||
|
||||
# YAML support for the Go language
|
||||
|
||||
Introduction
|
||||
@@ -12,10 +15,10 @@ C library to parse and generate YAML data quickly and reliably.
|
||||
Compatibility
|
||||
-------------
|
||||
|
||||
The yaml package is almost compatible with YAML 1.1, including support for
|
||||
anchors, tags, etc. There are still a few missing bits, such as document
|
||||
merging, base-60 floats (huh?), and multi-document unmarshalling. These
|
||||
features are not hard to add, and will be introduced as necessary.
|
||||
The yaml package supports most of YAML 1.1 and 1.2, including support for
|
||||
anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
|
||||
implemented, and base-60 floats from YAML 1.1 are purposefully not
|
||||
supported since they're a poor design and are gone in YAML 1.2.
|
||||
|
||||
Installation and usage
|
||||
----------------------
|
@@ -1,6 +1,8 @@
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -31,10 +33,12 @@ type parser struct {
|
||||
parser yaml_parser_t
|
||||
event yaml_event_t
|
||||
doc *node
|
||||
transform transformString
|
||||
}
|
||||
|
||||
func newParser(b []byte) *parser {
|
||||
p := parser{}
|
||||
func newParser(b []byte, t transformString) *parser {
|
||||
p := parser{transform: t}
|
||||
|
||||
if !yaml_parser_initialize(&p.parser) {
|
||||
panic("Failed to initialize YAML emitter")
|
||||
}
|
||||
@@ -63,7 +67,7 @@ func (p *parser) destroy() {
|
||||
func (p *parser) skip() {
|
||||
if p.event.typ != yaml_NO_EVENT {
|
||||
if p.event.typ == yaml_STREAM_END_EVENT {
|
||||
panic("Attempted to go past the end of stream. Corrupted value?")
|
||||
fail("Attempted to go past the end of stream. Corrupted value?")
|
||||
}
|
||||
yaml_event_delete(&p.event)
|
||||
}
|
||||
@@ -89,7 +93,7 @@ func (p *parser) fail() {
|
||||
} else {
|
||||
msg = "Unknown problem parsing YAML content"
|
||||
}
|
||||
panic(where + msg)
|
||||
fail(where + msg)
|
||||
}
|
||||
|
||||
func (p *parser) anchor(n *node, anchor []byte) {
|
||||
@@ -114,10 +118,9 @@ func (p *parser) parse() *node {
|
||||
// Happens when attempting to decode an empty buffer.
|
||||
return nil
|
||||
default:
|
||||
panic("Attempted to parse unknown event: " +
|
||||
strconv.Itoa(int(p.event.typ)))
|
||||
panic("Attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
|
||||
}
|
||||
panic("Unreachable")
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func (p *parser) node(kind int) *node {
|
||||
@@ -135,8 +138,7 @@ func (p *parser) document() *node {
|
||||
p.skip()
|
||||
n.children = append(n.children, p.parse())
|
||||
if p.event.typ != yaml_DOCUMENT_END_EVENT {
|
||||
panic("Expected end of document event but got " +
|
||||
strconv.Itoa(int(p.event.typ)))
|
||||
panic("Expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
|
||||
}
|
||||
p.skip()
|
||||
return n
|
||||
@@ -175,7 +177,10 @@ func (p *parser) mapping() *node {
|
||||
p.anchor(n, p.event.anchor)
|
||||
p.skip()
|
||||
for p.event.typ != yaml_MAPPING_END_EVENT {
|
||||
n.children = append(n.children, p.parse(), p.parse())
|
||||
key := p.parse()
|
||||
key.value = p.transform(key.value)
|
||||
value := p.parse()
|
||||
n.children = append(n.children, key, value)
|
||||
}
|
||||
p.skip()
|
||||
return n
|
||||
@@ -218,7 +223,7 @@ func (d *decoder) setter(tag string, out *reflect.Value, good *bool) (set func()
|
||||
var arg interface{}
|
||||
*out = reflect.ValueOf(&arg).Elem()
|
||||
return func() {
|
||||
*good = setter.SetYAML(tag, arg)
|
||||
*good = setter.SetYAML(shortTag(tag), arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,7 +231,7 @@ func (d *decoder) setter(tag string, out *reflect.Value, good *bool) (set func()
|
||||
for again {
|
||||
again = false
|
||||
setter, _ := (*out).Interface().(Setter)
|
||||
if tag != "!!null" || setter != nil {
|
||||
if tag != yaml_NULL_TAG || setter != nil {
|
||||
if pv := (*out); pv.Kind() == reflect.Ptr {
|
||||
if pv.IsNil() {
|
||||
*out = reflect.New(pv.Type().Elem()).Elem()
|
||||
@@ -242,7 +247,7 @@ func (d *decoder) setter(tag string, out *reflect.Value, good *bool) (set func()
|
||||
var arg interface{}
|
||||
*out = reflect.ValueOf(&arg).Elem()
|
||||
return func() {
|
||||
*good = setter.SetYAML(tag, arg)
|
||||
*good = setter.SetYAML(shortTag(tag), arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,10 +284,10 @@ func (d *decoder) document(n *node, out reflect.Value) (good bool) {
|
||||
func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
|
||||
an, ok := d.doc.anchors[n.value]
|
||||
if !ok {
|
||||
panic("Unknown anchor '" + n.value + "' referenced")
|
||||
fail("Unknown anchor '" + n.value + "' referenced")
|
||||
}
|
||||
if d.aliases[n.value] {
|
||||
panic("Anchor '" + n.value + "' value contains itself")
|
||||
fail("Anchor '" + n.value + "' value contains itself")
|
||||
}
|
||||
d.aliases[n.value] = true
|
||||
good = d.unmarshal(an, out)
|
||||
@@ -290,23 +295,50 @@ func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
|
||||
return good
|
||||
}
|
||||
|
||||
var zeroValue reflect.Value
|
||||
|
||||
func resetMap(out reflect.Value) {
|
||||
for _, k := range out.MapKeys() {
|
||||
out.SetMapIndex(k, zeroValue)
|
||||
}
|
||||
}
|
||||
|
||||
var durationType = reflect.TypeOf(time.Duration(0))
|
||||
|
||||
func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
||||
var tag string
|
||||
var resolved interface{}
|
||||
if n.tag == "" && !n.implicit {
|
||||
tag = "!!str"
|
||||
tag = yaml_STR_TAG
|
||||
resolved = n.value
|
||||
} else {
|
||||
tag, resolved = resolve(n.tag, n.value)
|
||||
if tag == yaml_BINARY_TAG {
|
||||
data, err := base64.StdEncoding.DecodeString(resolved.(string))
|
||||
if err != nil {
|
||||
fail("!!binary value contains invalid base64 data")
|
||||
}
|
||||
resolved = string(data)
|
||||
}
|
||||
}
|
||||
if set := d.setter(tag, &out, &good); set != nil {
|
||||
defer set()
|
||||
}
|
||||
if resolved == nil {
|
||||
if out.Kind() == reflect.Map && !out.CanAddr() {
|
||||
resetMap(out)
|
||||
} else {
|
||||
out.Set(reflect.Zero(out.Type()))
|
||||
}
|
||||
good = true
|
||||
return
|
||||
}
|
||||
switch out.Kind() {
|
||||
case reflect.String:
|
||||
if resolved != nil {
|
||||
if tag == yaml_BINARY_TAG {
|
||||
out.SetString(resolved.(string))
|
||||
good = true
|
||||
} else if resolved != nil {
|
||||
out.SetString(n.value)
|
||||
good = true
|
||||
}
|
||||
@@ -380,11 +412,6 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
||||
good = true
|
||||
}
|
||||
case reflect.Ptr:
|
||||
switch resolved.(type) {
|
||||
case nil:
|
||||
out.Set(reflect.Zero(out.Type()))
|
||||
good = true
|
||||
default:
|
||||
if out.Type().Elem() == reflect.TypeOf(resolved) {
|
||||
elem := reflect.New(out.Type().Elem())
|
||||
elem.Elem().Set(reflect.ValueOf(resolved))
|
||||
@@ -392,7 +419,6 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
||||
good = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return good
|
||||
}
|
||||
|
||||
@@ -404,7 +430,7 @@ func settableValueOf(i interface{}) reflect.Value {
|
||||
}
|
||||
|
||||
func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
|
||||
if set := d.setter("!!seq", &out, &good); set != nil {
|
||||
if set := d.setter(yaml_SEQ_TAG, &out, &good); set != nil {
|
||||
defer set()
|
||||
}
|
||||
var iface reflect.Value
|
||||
@@ -433,7 +459,7 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
|
||||
}
|
||||
|
||||
func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
|
||||
if set := d.setter("!!map", &out, &good); set != nil {
|
||||
if set := d.setter(yaml_MAP_TAG, &out, &good); set != nil {
|
||||
defer set()
|
||||
}
|
||||
if out.Kind() == reflect.Struct {
|
||||
@@ -465,6 +491,13 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
|
||||
}
|
||||
k := reflect.New(kt).Elem()
|
||||
if d.unmarshal(n.children[i], k) {
|
||||
kkind := k.Kind()
|
||||
if kkind == reflect.Interface {
|
||||
kkind = k.Elem().Kind()
|
||||
}
|
||||
if kkind == reflect.Map || kkind == reflect.Slice {
|
||||
fail(fmt.Sprintf("invalid map key: %#v", k.Interface()))
|
||||
}
|
||||
e := reflect.New(et).Elem()
|
||||
if d.unmarshal(n.children[i+1], e) {
|
||||
out.SetMapIndex(k, e)
|
||||
@@ -511,28 +544,28 @@ func (d *decoder) merge(n *node, out reflect.Value) {
|
||||
case aliasNode:
|
||||
an, ok := d.doc.anchors[n.value]
|
||||
if ok && an.kind != mappingNode {
|
||||
panic(wantMap)
|
||||
fail(wantMap)
|
||||
}
|
||||
d.unmarshal(n, out)
|
||||
case sequenceNode:
|
||||
// Step backwards as earlier nodes take precedence.
|
||||
for i := len(n.children)-1; i >= 0; i-- {
|
||||
for i := len(n.children) - 1; i >= 0; i-- {
|
||||
ni := n.children[i]
|
||||
if ni.kind == aliasNode {
|
||||
an, ok := d.doc.anchors[ni.value]
|
||||
if ok && an.kind != mappingNode {
|
||||
panic(wantMap)
|
||||
fail(wantMap)
|
||||
}
|
||||
} else if ni.kind != mappingNode {
|
||||
panic(wantMap)
|
||||
fail(wantMap)
|
||||
}
|
||||
d.unmarshal(ni, out)
|
||||
}
|
||||
default:
|
||||
panic(wantMap)
|
||||
fail(wantMap)
|
||||
}
|
||||
}
|
||||
|
||||
func isMerge(n *node) bool {
|
||||
return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == "!!merge" || n.tag == "tag:yaml.org,2002:merge")
|
||||
return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
|
||||
}
|
@@ -1,10 +1,11 @@
|
||||
package yaml_test
|
||||
|
||||
import (
|
||||
"github.com/coreos/yaml"
|
||||
. "gopkg.in/check.v1"
|
||||
"gopkg.in/yaml.v1"
|
||||
"math"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -316,7 +317,10 @@ var unmarshalTests = []struct {
|
||||
map[string]*string{"foo": new(string)},
|
||||
}, {
|
||||
"foo: null",
|
||||
map[string]string{},
|
||||
map[string]string{"foo": ""},
|
||||
}, {
|
||||
"foo: null",
|
||||
map[string]interface{}{"foo": nil},
|
||||
},
|
||||
|
||||
// Ignored field
|
||||
@@ -377,6 +381,24 @@ var unmarshalTests = []struct {
|
||||
"a: <foo>",
|
||||
map[string]string{"a": "<foo>"},
|
||||
},
|
||||
|
||||
// Base 60 floats are obsolete and unsupported.
|
||||
{
|
||||
"a: 1:1\n",
|
||||
map[string]string{"a": "1:1"},
|
||||
},
|
||||
|
||||
// Binary data.
|
||||
{
|
||||
"a: !!binary gIGC\n",
|
||||
map[string]string{"a": "\x80\x81\x82"},
|
||||
}, {
|
||||
"a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n",
|
||||
map[string]string{"a": strings.Repeat("\x90", 54)},
|
||||
}, {
|
||||
"a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n",
|
||||
map[string]string{"a": strings.Repeat("\x00", 52)},
|
||||
},
|
||||
}
|
||||
|
||||
type inlineB struct {
|
||||
@@ -424,12 +446,15 @@ func (s *S) TestUnmarshalNaN(c *C) {
|
||||
var unmarshalErrorTests = []struct {
|
||||
data, error string
|
||||
}{
|
||||
{"v: !!float 'error'", "YAML error: Can't decode !!str 'error' as a !!float"},
|
||||
{"v: !!float 'error'", "YAML error: cannot decode !!str `error` as a !!float"},
|
||||
{"v: [A,", "YAML error: line 1: did not find expected node content"},
|
||||
{"v:\n- [A,", "YAML error: line 2: did not find expected node content"},
|
||||
{"a: *b\n", "YAML error: Unknown anchor 'b' referenced"},
|
||||
{"a: &a\n b: *a\n", "YAML error: Anchor 'a' value contains itself"},
|
||||
{"value: -", "YAML error: block sequence entries are not allowed in this context"},
|
||||
{"a: !!binary ==", "YAML error: !!binary value contains invalid base64 data"},
|
||||
{"{[.]}", `YAML error: invalid map key: \[\]interface \{\}\{"\."\}`},
|
||||
{"{{.}}", `YAML error: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
|
||||
}
|
||||
|
||||
func (s *S) TestUnmarshalErrors(c *C) {
|
||||
@@ -532,6 +557,23 @@ func (s *S) TestUnmarshalWithFalseSetterIgnoresValue(c *C) {
|
||||
c.Assert(m["ghi"].value, Equals, 3)
|
||||
}
|
||||
|
||||
func (s *S) TestUnmarshalWithTransform(c *C) {
|
||||
data := `{a_b: 1, c-d: 2, e-f_g: 3, h_i-j: 4}`
|
||||
expect := map[string]int{
|
||||
"a_b": 1,
|
||||
"c_d": 2,
|
||||
"e_f_g": 3,
|
||||
"h_i_j": 4,
|
||||
}
|
||||
m := map[string]int{}
|
||||
yaml.UnmarshalMappingKeyTransform = func(i string) string {
|
||||
return strings.Replace(i, "-", "_", -1)
|
||||
}
|
||||
err := yaml.Unmarshal([]byte(data), m)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(m, DeepEquals, expect)
|
||||
}
|
||||
|
||||
// From http://yaml.org/type/merge.html
|
||||
var mergeTests = `
|
||||
anchors:
|
||||
@@ -624,6 +666,30 @@ func (s *S) TestMergeStruct(c *C) {
|
||||
}
|
||||
}
|
||||
|
||||
var unmarshalNullTests = []func() interface{}{
|
||||
func() interface{} { var v interface{}; v = "v"; return &v },
|
||||
func() interface{} { var s = "s"; return &s },
|
||||
func() interface{} { var s = "s"; sptr := &s; return &sptr },
|
||||
func() interface{} { var i = 1; return &i },
|
||||
func() interface{} { var i = 1; iptr := &i; return &iptr },
|
||||
func() interface{} { m := map[string]int{"s": 1}; return &m },
|
||||
func() interface{} { m := map[string]int{"s": 1}; return m },
|
||||
}
|
||||
|
||||
func (s *S) TestUnmarshalNull(c *C) {
|
||||
for _, test := range unmarshalNullTests {
|
||||
item := test()
|
||||
zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface()
|
||||
err := yaml.Unmarshal([]byte("null"), item)
|
||||
c.Assert(err, IsNil)
|
||||
if reflect.TypeOf(item).Kind() == reflect.Map {
|
||||
c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface())
|
||||
} else {
|
||||
c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//var data []byte
|
||||
//func init() {
|
||||
// var err error
|
@@ -973,9 +973,9 @@ func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
|
||||
if bytes.HasPrefix(tag, tag_directive.prefix) {
|
||||
emitter.tag_data.handle = tag_directive.handle
|
||||
emitter.tag_data.suffix = tag[len(tag_directive.prefix):]
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
emitter.tag_data.suffix = tag
|
||||
return true
|
||||
}
|
||||
@@ -1279,6 +1279,9 @@ func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_
|
||||
for k := 0; k < w; k++ {
|
||||
octet := value[i]
|
||||
i++
|
||||
if !put(emitter, '%') {
|
||||
return false
|
||||
}
|
||||
|
||||
c := octet >> 4
|
||||
if c < 10 {
|
@@ -2,8 +2,10 @@ package yaml
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -50,14 +52,19 @@ func (e *encoder) must(ok bool) {
|
||||
if msg == "" {
|
||||
msg = "Unknown problem generating YAML content"
|
||||
}
|
||||
panic(msg)
|
||||
fail(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *encoder) marshal(tag string, in reflect.Value) {
|
||||
if !in.IsValid() {
|
||||
e.nilv()
|
||||
return
|
||||
}
|
||||
var value interface{}
|
||||
if getter, ok := in.Interface().(Getter); ok {
|
||||
tag, value = getter.GetYAML()
|
||||
tag = longTag(tag)
|
||||
if value == nil {
|
||||
e.nilv()
|
||||
return
|
||||
@@ -98,7 +105,7 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
|
||||
case reflect.Bool:
|
||||
e.boolv(tag, in)
|
||||
default:
|
||||
panic("Can't marshal type yet: " + in.Type().String())
|
||||
panic("Can't marshal type: " + in.Type().String())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,11 +174,46 @@ func (e *encoder) slicev(tag string, in reflect.Value) {
|
||||
e.emit()
|
||||
}
|
||||
|
||||
// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
|
||||
//
|
||||
// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
|
||||
// in YAML 1.2 and by this package, but these should be marshalled quoted for
|
||||
// the time being for compatibility with other parsers.
|
||||
func isBase60Float(s string) (result bool) {
|
||||
// Fast path.
|
||||
if s == "" {
|
||||
return false
|
||||
}
|
||||
c := s[0]
|
||||
if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
|
||||
return false
|
||||
}
|
||||
// Do the full match.
|
||||
return base60float.MatchString(s)
|
||||
}
|
||||
|
||||
// From http://yaml.org/type/float.html, except the regular expression there
|
||||
// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
|
||||
var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
|
||||
|
||||
func (e *encoder) stringv(tag string, in reflect.Value) {
|
||||
var style yaml_scalar_style_t
|
||||
s := in.String()
|
||||
if rtag, _ := resolve("", s); rtag != "!!str" {
|
||||
rtag, rs := resolve("", s)
|
||||
if rtag == yaml_BINARY_TAG {
|
||||
if tag == "" || tag == yaml_STR_TAG {
|
||||
tag = rtag
|
||||
s = rs.(string)
|
||||
} else if tag == yaml_BINARY_TAG {
|
||||
fail("explicitly tagged !!binary data must be base64-encoded")
|
||||
} else {
|
||||
fail("cannot marshal invalid UTF-8 data as " + shortTag(tag))
|
||||
}
|
||||
}
|
||||
if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
|
||||
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
|
||||
} else if strings.Contains(s, "\n") {
|
||||
style = yaml_LITERAL_SCALAR_STYLE
|
||||
} else {
|
||||
style = yaml_PLAIN_SCALAR_STYLE
|
||||
}
|
||||
@@ -218,9 +260,6 @@ func (e *encoder) nilv() {
|
||||
|
||||
func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
|
||||
implicit := tag == ""
|
||||
if !implicit {
|
||||
style = yaml_PLAIN_SCALAR_STYLE
|
||||
}
|
||||
e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
|
||||
e.emit()
|
||||
}
|
@@ -2,12 +2,13 @@ package yaml_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gopkg.in/yaml.v1"
|
||||
. "gopkg.in/check.v1"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/yaml"
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
var marshalIntTest = 123
|
||||
@@ -17,6 +18,9 @@ var marshalTests = []struct {
|
||||
data string
|
||||
}{
|
||||
{
|
||||
nil,
|
||||
"null\n",
|
||||
}, {
|
||||
&struct{}{},
|
||||
"{}\n",
|
||||
}, {
|
||||
@@ -87,7 +91,7 @@ var marshalTests = []struct {
|
||||
"v:\n- A\n- B\n",
|
||||
}, {
|
||||
map[string][]string{"v": []string{"A", "B\nC"}},
|
||||
"v:\n- A\n- 'B\n\n C'\n",
|
||||
"v:\n- A\n- |-\n B\n C\n",
|
||||
}, {
|
||||
map[string][]interface{}{"v": []interface{}{"A", 1, map[string][]int{"B": []int{2, 3}}}},
|
||||
"v:\n- A\n- 1\n- B:\n - 2\n - 3\n",
|
||||
@@ -220,11 +224,39 @@ var marshalTests = []struct {
|
||||
"a: 3s\n",
|
||||
},
|
||||
|
||||
// Issue #24.
|
||||
// Issue #24: bug in map merging logic.
|
||||
{
|
||||
map[string]string{"a": "<foo>"},
|
||||
"a: <foo>\n",
|
||||
},
|
||||
|
||||
// Issue #34: marshal unsupported base 60 floats quoted for compatibility
|
||||
// with old YAML 1.1 parsers.
|
||||
{
|
||||
map[string]string{"a": "1:1"},
|
||||
"a: \"1:1\"\n",
|
||||
},
|
||||
|
||||
// Binary data.
|
||||
{
|
||||
map[string]string{"a": "\x00"},
|
||||
"a: \"\\0\"\n",
|
||||
}, {
|
||||
map[string]string{"a": "\x80\x81\x82"},
|
||||
"a: !!binary gIGC\n",
|
||||
}, {
|
||||
map[string]string{"a": strings.Repeat("\x90", 54)},
|
||||
"a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n",
|
||||
}, {
|
||||
map[string]interface{}{"a": typeWithGetter{"!!str", "\x80\x81\x82"}},
|
||||
"a: !!binary gIGC\n",
|
||||
},
|
||||
|
||||
// Escaping of tags.
|
||||
{
|
||||
map[string]interface{}{"a": typeWithGetter{"foo!bar", 1}},
|
||||
"a: !<foo%21bar> 1\n",
|
||||
},
|
||||
}
|
||||
|
||||
func (s *S) TestMarshal(c *C) {
|
||||
@@ -238,21 +270,30 @@ func (s *S) TestMarshal(c *C) {
|
||||
var marshalErrorTests = []struct {
|
||||
value interface{}
|
||||
error string
|
||||
}{
|
||||
{
|
||||
&struct {
|
||||
panic string
|
||||
}{{
|
||||
value: &struct {
|
||||
B int
|
||||
inlineB ",inline"
|
||||
}{1, inlineB{2, inlineC{3}}},
|
||||
`Duplicated key 'b' in struct struct \{ B int; .*`,
|
||||
},
|
||||
}
|
||||
panic: `Duplicated key 'b' in struct struct \{ B int; .*`,
|
||||
}, {
|
||||
value: typeWithGetter{"!!binary", "\x80"},
|
||||
error: "YAML error: explicitly tagged !!binary data must be base64-encoded",
|
||||
}, {
|
||||
value: typeWithGetter{"!!float", "\x80"},
|
||||
error: `YAML error: cannot marshal invalid UTF-8 data as !!float`,
|
||||
}}
|
||||
|
||||
func (s *S) TestMarshalErrors(c *C) {
|
||||
for _, item := range marshalErrorTests {
|
||||
if item.panic != "" {
|
||||
c.Assert(func() { yaml.Marshal(item.value) }, PanicMatches, item.panic)
|
||||
} else {
|
||||
_, err := yaml.Marshal(item.value)
|
||||
c.Assert(err, ErrorMatches, item.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var marshalTaggedIfaceTest interface{} = &struct{ A string }{"B"}
|
190
Godeps/_workspace/src/github.com/coreos/yaml/resolve.go
generated
vendored
Normal file
190
Godeps/_workspace/src/github.com/coreos/yaml/resolve.go
generated
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// TODO: merge, timestamps, base 60 floats, omap.
|
||||
|
||||
type resolveMapItem struct {
|
||||
value interface{}
|
||||
tag string
|
||||
}
|
||||
|
||||
var resolveTable = make([]byte, 256)
|
||||
var resolveMap = make(map[string]resolveMapItem)
|
||||
|
||||
func init() {
|
||||
t := resolveTable
|
||||
t[int('+')] = 'S' // Sign
|
||||
t[int('-')] = 'S'
|
||||
for _, c := range "0123456789" {
|
||||
t[int(c)] = 'D' // Digit
|
||||
}
|
||||
for _, c := range "yYnNtTfFoO~" {
|
||||
t[int(c)] = 'M' // In map
|
||||
}
|
||||
t[int('.')] = '.' // Float (potentially in map)
|
||||
|
||||
var resolveMapList = []struct {
|
||||
v interface{}
|
||||
tag string
|
||||
l []string
|
||||
}{
|
||||
{true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}},
|
||||
{true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}},
|
||||
{true, yaml_BOOL_TAG, []string{"on", "On", "ON"}},
|
||||
{false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}},
|
||||
{false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}},
|
||||
{false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}},
|
||||
{nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}},
|
||||
{math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}},
|
||||
{math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}},
|
||||
{math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}},
|
||||
{math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}},
|
||||
{"<<", yaml_MERGE_TAG, []string{"<<"}},
|
||||
}
|
||||
|
||||
m := resolveMap
|
||||
for _, item := range resolveMapList {
|
||||
for _, s := range item.l {
|
||||
m[s] = resolveMapItem{item.v, item.tag}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const longTagPrefix = "tag:yaml.org,2002:"
|
||||
|
||||
func shortTag(tag string) string {
|
||||
// TODO This can easily be made faster and produce less garbage.
|
||||
if strings.HasPrefix(tag, longTagPrefix) {
|
||||
return "!!" + tag[len(longTagPrefix):]
|
||||
}
|
||||
return tag
|
||||
}
|
||||
|
||||
func longTag(tag string) string {
|
||||
if strings.HasPrefix(tag, "!!") {
|
||||
return longTagPrefix + tag[2:]
|
||||
}
|
||||
return tag
|
||||
}
|
||||
|
||||
func resolvableTag(tag string) bool {
|
||||
switch tag {
|
||||
case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func resolve(tag string, in string) (rtag string, out interface{}) {
|
||||
if !resolvableTag(tag) {
|
||||
return tag, in
|
||||
}
|
||||
|
||||
defer func() {
|
||||
switch tag {
|
||||
case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
|
||||
return
|
||||
}
|
||||
fail(fmt.Sprintf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)))
|
||||
}()
|
||||
|
||||
// Any data is accepted as a !!str or !!binary.
|
||||
// Otherwise, the prefix is enough of a hint about what it might be.
|
||||
hint := byte('N')
|
||||
if in != "" {
|
||||
hint = resolveTable[in[0]]
|
||||
}
|
||||
if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG {
|
||||
// Handle things we can lookup in a map.
|
||||
if item, ok := resolveMap[in]; ok {
|
||||
return item.tag, item.value
|
||||
}
|
||||
|
||||
// Base 60 floats are a bad idea, were dropped in YAML 1.2, and
|
||||
// are purposefully unsupported here. They're still quoted on
|
||||
// the way out for compatibility with other parser, though.
|
||||
|
||||
switch hint {
|
||||
case 'M':
|
||||
// We've already checked the map above.
|
||||
|
||||
case '.':
|
||||
// Not in the map, so maybe a normal float.
|
||||
floatv, err := strconv.ParseFloat(in, 64)
|
||||
if err == nil {
|
||||
return yaml_FLOAT_TAG, floatv
|
||||
}
|
||||
|
||||
case 'D', 'S':
|
||||
// Int, float, or timestamp.
|
||||
plain := strings.Replace(in, "_", "", -1)
|
||||
intv, err := strconv.ParseInt(plain, 0, 64)
|
||||
if err == nil {
|
||||
if intv == int64(int(intv)) {
|
||||
return yaml_INT_TAG, int(intv)
|
||||
} else {
|
||||
return yaml_INT_TAG, intv
|
||||
}
|
||||
}
|
||||
floatv, err := strconv.ParseFloat(plain, 64)
|
||||
if err == nil {
|
||||
return yaml_FLOAT_TAG, floatv
|
||||
}
|
||||
if strings.HasPrefix(plain, "0b") {
|
||||
intv, err := strconv.ParseInt(plain[2:], 2, 64)
|
||||
if err == nil {
|
||||
return yaml_INT_TAG, int(intv)
|
||||
}
|
||||
} else if strings.HasPrefix(plain, "-0b") {
|
||||
intv, err := strconv.ParseInt(plain[3:], 2, 64)
|
||||
if err == nil {
|
||||
return yaml_INT_TAG, -int(intv)
|
||||
}
|
||||
}
|
||||
// XXX Handle timestamps here.
|
||||
|
||||
default:
|
||||
panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
|
||||
}
|
||||
}
|
||||
if tag == yaml_BINARY_TAG {
|
||||
return yaml_BINARY_TAG, in
|
||||
}
|
||||
if utf8.ValidString(in) {
|
||||
return yaml_STR_TAG, in
|
||||
}
|
||||
return yaml_BINARY_TAG, encodeBase64(in)
|
||||
}
|
||||
|
||||
// encodeBase64 encodes s as base64 that is broken up into multiple lines
|
||||
// as appropriate for the resulting length.
|
||||
func encodeBase64(s string) string {
|
||||
const lineLen = 70
|
||||
encLen := base64.StdEncoding.EncodedLen(len(s))
|
||||
lines := encLen/lineLen + 1
|
||||
buf := make([]byte, encLen*2+lines)
|
||||
in := buf[0:encLen]
|
||||
out := buf[encLen:]
|
||||
base64.StdEncoding.Encode(in, []byte(s))
|
||||
k := 0
|
||||
for i := 0; i < len(in); i += lineLen {
|
||||
j := i + lineLen
|
||||
if j > len(in) {
|
||||
j = len(in)
|
||||
}
|
||||
k += copy(out[k:], in[i:j])
|
||||
if lines > 1 {
|
||||
out[k] = '\n'
|
||||
k++
|
||||
}
|
||||
}
|
||||
return string(out[:k])
|
||||
}
|
@@ -10,23 +10,20 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type yamlError string
|
||||
|
||||
func fail(msg string) {
|
||||
panic(yamlError(msg))
|
||||
}
|
||||
|
||||
func handleErr(err *error) {
|
||||
if r := recover(); r != nil {
|
||||
if _, ok := r.(runtime.Error); ok {
|
||||
panic(r)
|
||||
} else if _, ok := r.(*reflect.ValueError); ok {
|
||||
panic(r)
|
||||
} else if _, ok := r.(externalPanic); ok {
|
||||
panic(r)
|
||||
} else if s, ok := r.(string); ok {
|
||||
*err = errors.New("YAML error: " + s)
|
||||
} else if e, ok := r.(error); ok {
|
||||
*err = e
|
||||
if e, ok := r.(yamlError); ok {
|
||||
*err = errors.New("YAML error: " + string(e))
|
||||
} else {
|
||||
panic(r)
|
||||
}
|
||||
@@ -78,7 +75,7 @@ type Getter interface {
|
||||
// F int `yaml:"a,omitempty"`
|
||||
// B int
|
||||
// }
|
||||
// var T t
|
||||
// var t T
|
||||
// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
|
||||
//
|
||||
// See the documentation of Marshal for the format of tags and a list of
|
||||
@@ -87,11 +84,15 @@ type Getter interface {
|
||||
func Unmarshal(in []byte, out interface{}) (err error) {
|
||||
defer handleErr(&err)
|
||||
d := newDecoder()
|
||||
p := newParser(in)
|
||||
p := newParser(in, UnmarshalMappingKeyTransform)
|
||||
defer p.destroy()
|
||||
node := p.parse()
|
||||
if node != nil {
|
||||
d.unmarshal(node, reflect.ValueOf(out))
|
||||
v := reflect.ValueOf(out)
|
||||
if v.Kind() == reflect.Ptr && !v.IsNil() {
|
||||
v = v.Elem()
|
||||
}
|
||||
d.unmarshal(node, v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -145,6 +146,17 @@ func Marshal(in interface{}) (out []byte, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalMappingKeyTransform is a string transformation that is applied to
|
||||
// each mapping key in a YAML document before it is unmarshalled. By default,
|
||||
// UnmarshalMappingKeyTransform is an identity transform (no modification).
|
||||
var UnmarshalMappingKeyTransform transformString = identityTransform
|
||||
|
||||
type transformString func(in string) (out string)
|
||||
|
||||
func identityTransform(in string) (out string) {
|
||||
return in
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Maintain a mapping of keys to structure field indexes
|
||||
|
||||
@@ -174,12 +186,6 @@ type fieldInfo struct {
|
||||
var structMap = make(map[reflect.Type]*structInfo)
|
||||
var fieldMapMutex sync.RWMutex
|
||||
|
||||
type externalPanic string
|
||||
|
||||
func (e externalPanic) String() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
func getStructInfo(st reflect.Type) (*structInfo, error) {
|
||||
fieldMapMutex.RLock()
|
||||
sinfo, found := structMap[st]
|
||||
@@ -220,8 +226,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
||||
case "inline":
|
||||
inline = true
|
||||
default:
|
||||
msg := fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st)
|
||||
panic(externalPanic(msg))
|
||||
return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st))
|
||||
}
|
||||
}
|
||||
tag = fields[0]
|
||||
@@ -229,6 +234,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
||||
|
||||
if inline {
|
||||
switch field.Type.Kind() {
|
||||
// TODO: Implement support for inline maps.
|
||||
//case reflect.Map:
|
||||
// if inlineMap >= 0 {
|
||||
// return nil, errors.New("Multiple ,inline maps in struct " + st.String())
|
||||
@@ -256,8 +262,8 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
||||
fieldsList = append(fieldsList, finfo)
|
||||
}
|
||||
default:
|
||||
//panic("Option ,inline needs a struct value or map field")
|
||||
panic("Option ,inline needs a struct value field")
|
||||
//return nil, errors.New("Option ,inline needs a struct value or map field")
|
||||
return nil, errors.New("Option ,inline needs a struct value field")
|
||||
}
|
||||
continue
|
||||
}
|
@@ -294,6 +294,10 @@ const (
|
||||
yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences.
|
||||
yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping.
|
||||
|
||||
// Not in original libyaml.
|
||||
yaml_BINARY_TAG = "tag:yaml.org,2002:binary"
|
||||
yaml_MERGE_TAG = "tag:yaml.org,2002:merge"
|
||||
|
||||
yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str.
|
||||
yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq.
|
||||
yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map.
|
@@ -2,7 +2,7 @@ package introspect
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
|
||||
"strings"
|
||||
)
|
||||
|
@@ -2,7 +2,7 @@ package introspect
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
|
||||
"reflect"
|
||||
)
|
||||
|
@@ -3,8 +3,8 @@
|
||||
package prop
|
||||
|
||||
import (
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
|
||||
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus/introspect"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus/introspect"
|
||||
"sync"
|
||||
)
|
||||
|
502
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/COPYING
generated
vendored
Normal file
502
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/COPYING
generated
vendored
Normal file
@@ -0,0 +1,502 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
272
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/backdoor.c
generated
vendored
Normal file
272
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/backdoor.c
generated
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1999-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*********************************************************
|
||||
* The contents of this file are subject to the terms of the Common
|
||||
* Development and Distribution License (the "License") version 1.0
|
||||
* and no later version. You may not use this file except in
|
||||
* compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the License at
|
||||
* http://www.opensource.org/licenses/cddl1.php
|
||||
*
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* backdoor.c --
|
||||
*
|
||||
* First layer of the internal communication channel between guest
|
||||
* applications and vmware
|
||||
*
|
||||
* This is the backdoor. By using special ports of the virtual I/O space,
|
||||
* and the virtual CPU registers, a guest application can send a
|
||||
* synchroneous basic request to vmware, and vmware can reply to it.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "backdoor_def.h"
|
||||
#include "backdoor.h"
|
||||
#include "backdoorInt.h"
|
||||
|
||||
#if defined(BACKDOOR_DEBUG) && defined(USERLEVEL)
|
||||
#if defined(__KERNEL__) || defined(_KERNEL)
|
||||
#else
|
||||
# include "debug.h"
|
||||
#endif
|
||||
# include <stdio.h>
|
||||
# define BACKDOOR_LOG(args) Debug args
|
||||
# define BACKDOOR_LOG_PROTO_STRUCT(x) BackdoorPrintProtoStruct((x))
|
||||
# define BACKDOOR_LOG_HB_PROTO_STRUCT(x) BackdoorPrintHbProtoStruct((x))
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
*
|
||||
* BackdoorPrintProtoStruct --
|
||||
* BackdoorPrintHbProtoStruct --
|
||||
*
|
||||
* Print the contents of the specified backdoor protocol structure via
|
||||
* printf.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Output to stdout.
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
BackdoorPrintProtoStruct(Backdoor_proto *myBp)
|
||||
{
|
||||
Debug("magic 0x%08x, command %d, size %"FMTSZ"u, port %d\n",
|
||||
myBp->in.ax.word, myBp->in.cx.halfs.low,
|
||||
myBp->in.size, myBp->in.dx.halfs.low);
|
||||
|
||||
#ifndef VM_X86_64
|
||||
Debug("ax %#x, "
|
||||
"bx %#x, "
|
||||
"cx %#x, "
|
||||
"dx %#x, "
|
||||
"si %#x, "
|
||||
"di %#x\n",
|
||||
myBp->out.ax.word,
|
||||
myBp->out.bx.word,
|
||||
myBp->out.cx.word,
|
||||
myBp->out.dx.word,
|
||||
myBp->out.si.word,
|
||||
myBp->out.di.word);
|
||||
#else
|
||||
Debug("ax %#"FMT64"x, "
|
||||
"bx %#"FMT64"x, "
|
||||
"cx %#"FMT64"x, "
|
||||
"dx %#"FMT64"x, "
|
||||
"si %#"FMT64"x, "
|
||||
"di %#"FMT64"x\n",
|
||||
myBp->out.ax.quad,
|
||||
myBp->out.bx.quad,
|
||||
myBp->out.cx.quad,
|
||||
myBp->out.dx.quad,
|
||||
myBp->out.si.quad,
|
||||
myBp->out.di.quad);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BackdoorPrintHbProtoStruct(Backdoor_proto_hb *myBp)
|
||||
{
|
||||
Debug("magic 0x%08x, command %d, size %"FMTSZ"u, port %d, "
|
||||
"srcAddr %"FMTSZ"u, dstAddr %"FMTSZ"u\n",
|
||||
myBp->in.ax.word, myBp->in.bx.halfs.low, myBp->in.size,
|
||||
myBp->in.dx.halfs.low, myBp->in.srcAddr, myBp->in.dstAddr);
|
||||
|
||||
#ifndef VM_X86_64
|
||||
Debug("ax %#x, "
|
||||
"bx %#x, "
|
||||
"cx %#x, "
|
||||
"dx %#x, "
|
||||
"si %#x, "
|
||||
"di %#x, "
|
||||
"bp %#x\n",
|
||||
myBp->out.ax.word,
|
||||
myBp->out.bx.word,
|
||||
myBp->out.cx.word,
|
||||
myBp->out.dx.word,
|
||||
myBp->out.si.word,
|
||||
myBp->out.di.word,
|
||||
myBp->out.bp.word);
|
||||
#else
|
||||
Debug("ax %#"FMT64"x, "
|
||||
"bx %#"FMT64"x, "
|
||||
"cx %#"FMT64"x, "
|
||||
"dx %#"FMT64"x, "
|
||||
"si %#"FMT64"x, "
|
||||
"di %#"FMT64"x, "
|
||||
"bp %#"FMT64"x\n",
|
||||
myBp->out.ax.quad,
|
||||
myBp->out.bx.quad,
|
||||
myBp->out.cx.quad,
|
||||
myBp->out.dx.quad,
|
||||
myBp->out.si.quad,
|
||||
myBp->out.di.quad,
|
||||
myBp->out.bp.quad);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
# define BACKDOOR_LOG(args)
|
||||
# define BACKDOOR_LOG_PROTO_STRUCT(x)
|
||||
# define BACKDOOR_LOG_HB_PROTO_STRUCT(x)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Backdoor --
|
||||
*
|
||||
* Send a low-bandwidth basic request (16 bytes) to vmware, and return its
|
||||
* reply (24 bytes).
|
||||
*
|
||||
* Result:
|
||||
* None
|
||||
*
|
||||
* Side-effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
Backdoor(Backdoor_proto *myBp) // IN/OUT
|
||||
{
|
||||
ASSERT(myBp);
|
||||
|
||||
myBp->in.ax.word = BDOOR_MAGIC;
|
||||
myBp->in.dx.halfs.low = BDOOR_PORT;
|
||||
|
||||
BACKDOOR_LOG(("Backdoor: before "));
|
||||
BACKDOOR_LOG_PROTO_STRUCT(myBp);
|
||||
|
||||
Backdoor_InOut(myBp);
|
||||
|
||||
BACKDOOR_LOG(("Backdoor: after "));
|
||||
BACKDOOR_LOG_PROTO_STRUCT(myBp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Backdoor_HbOut --
|
||||
*
|
||||
* Send a high-bandwidth basic request to vmware, and return its
|
||||
* reply.
|
||||
*
|
||||
* Result:
|
||||
* The host-side response is returned via the IN/OUT parameter.
|
||||
*
|
||||
* Side-effects:
|
||||
* Pokes the high-bandwidth backdoor.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
Backdoor_HbOut(Backdoor_proto_hb *myBp) // IN/OUT
|
||||
{
|
||||
ASSERT(myBp);
|
||||
|
||||
myBp->in.ax.word = BDOOR_MAGIC;
|
||||
myBp->in.dx.halfs.low = BDOORHB_PORT;
|
||||
|
||||
BACKDOOR_LOG(("Backdoor_HbOut: before "));
|
||||
BACKDOOR_LOG_HB_PROTO_STRUCT(myBp);
|
||||
|
||||
BackdoorHbOut(myBp);
|
||||
|
||||
BACKDOOR_LOG(("Backdoor_HbOut: after "));
|
||||
BACKDOOR_LOG_HB_PROTO_STRUCT(myBp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Backdoor_HbIn --
|
||||
*
|
||||
* Send a basic request to vmware, and return its high-bandwidth
|
||||
* reply
|
||||
*
|
||||
* Result:
|
||||
* Host-side response returned via the IN/OUT parameter.
|
||||
*
|
||||
* Side-effects:
|
||||
* Pokes the high-bandwidth backdoor.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
Backdoor_HbIn(Backdoor_proto_hb *myBp) // IN/OUT
|
||||
{
|
||||
ASSERT(myBp);
|
||||
|
||||
myBp->in.ax.word = BDOOR_MAGIC;
|
||||
myBp->in.dx.halfs.low = BDOORHB_PORT;
|
||||
|
||||
BACKDOOR_LOG(("Backdoor_HbIn: before "));
|
||||
BACKDOOR_LOG_HB_PROTO_STRUCT(myBp);
|
||||
|
||||
BackdoorHbIn(myBp);
|
||||
|
||||
BACKDOOR_LOG(("Backdoor_HbIn: after "));
|
||||
BACKDOOR_LOG_HB_PROTO_STRUCT(myBp);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
235
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/backdoor_386.c
generated
vendored
Normal file
235
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/backdoor_386.c
generated
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2005-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*********************************************************
|
||||
* The contents of this file are subject to the terms of the Common
|
||||
* Development and Distribution License (the "License") version 1.0
|
||||
* and no later version. You may not use this file except in
|
||||
* compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the License at
|
||||
* http://www.opensource.org/licenses/cddl1.php
|
||||
*
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* backdoorGcc32.c --
|
||||
*
|
||||
* Implements the real work for guest-side backdoor for GCC, 32-bit
|
||||
* target (supports inline ASM, GAS syntax). The asm sections are marked
|
||||
* volatile since vmware can change the registers content without the
|
||||
* compiler knowing it.
|
||||
*
|
||||
* XXX
|
||||
* I tried to write this more cleanly, but:
|
||||
* - There is no way to specify an "ebp" constraint
|
||||
* - "ebp" is ignored when specified as cloberred register
|
||||
* - gas barfs when there is more than 10 operands
|
||||
* - gas 2.7.2.3, depending on the order of the operands, can
|
||||
* mis-assemble without any warning
|
||||
* --hpreg
|
||||
*
|
||||
* Note that the problems with gas noted above might longer be relevant
|
||||
* now that we've upgraded most of our compiler versions.
|
||||
* --rrdharan
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "backdoor.h"
|
||||
#include "backdoorInt.h"
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
*
|
||||
* Backdoor_InOut --
|
||||
*
|
||||
* Send a low-bandwidth basic request (16 bytes) to vmware, and return its
|
||||
* reply (24 bytes).
|
||||
*
|
||||
* Results:
|
||||
* Host-side response returned in bp IN/OUT parameter.
|
||||
*
|
||||
* Side effects:
|
||||
* Pokes the backdoor.
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
Backdoor_InOut(Backdoor_proto *myBp) // IN/OUT
|
||||
{
|
||||
uint32 dummy;
|
||||
|
||||
__asm__ __volatile__(
|
||||
#ifdef __PIC__
|
||||
"pushl %%ebx" "\n\t"
|
||||
#endif
|
||||
"pushl %%eax" "\n\t"
|
||||
"movl 20(%%eax), %%edi" "\n\t"
|
||||
"movl 16(%%eax), %%esi" "\n\t"
|
||||
"movl 12(%%eax), %%edx" "\n\t"
|
||||
"movl 8(%%eax), %%ecx" "\n\t"
|
||||
"movl 4(%%eax), %%ebx" "\n\t"
|
||||
"movl (%%eax), %%eax" "\n\t"
|
||||
"inl %%dx, %%eax" "\n\t"
|
||||
"xchgl %%eax, (%%esp)" "\n\t"
|
||||
"movl %%edi, 20(%%eax)" "\n\t"
|
||||
"movl %%esi, 16(%%eax)" "\n\t"
|
||||
"movl %%edx, 12(%%eax)" "\n\t"
|
||||
"movl %%ecx, 8(%%eax)" "\n\t"
|
||||
"movl %%ebx, 4(%%eax)" "\n\t"
|
||||
"popl (%%eax)" "\n\t"
|
||||
#ifdef __PIC__
|
||||
"popl %%ebx" "\n\t"
|
||||
#endif
|
||||
: "=a" (dummy)
|
||||
: "0" (myBp)
|
||||
/*
|
||||
* vmware can modify the whole VM state without the compiler knowing
|
||||
* it. So far it does not modify EFLAGS. --hpreg
|
||||
*/
|
||||
:
|
||||
#ifndef __PIC__
|
||||
"ebx",
|
||||
#endif
|
||||
"ecx", "edx", "esi", "edi", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* BackdoorHbIn --
|
||||
* BackdoorHbOut --
|
||||
*
|
||||
* Send a high-bandwidth basic request to vmware, and return its
|
||||
* reply.
|
||||
*
|
||||
* Results:
|
||||
* Host-side response returned in bp IN/OUT parameter.
|
||||
*
|
||||
* Side-effects:
|
||||
* Pokes the high-bandwidth backdoor port.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
BackdoorHbIn(Backdoor_proto_hb *myBp) // IN/OUT
|
||||
{
|
||||
uint32 dummy;
|
||||
|
||||
__asm__ __volatile__(
|
||||
#ifdef __PIC__
|
||||
"pushl %%ebx" "\n\t"
|
||||
#endif
|
||||
"pushl %%ebp" "\n\t"
|
||||
|
||||
"pushl %%eax" "\n\t"
|
||||
"movl 24(%%eax), %%ebp" "\n\t"
|
||||
"movl 20(%%eax), %%edi" "\n\t"
|
||||
"movl 16(%%eax), %%esi" "\n\t"
|
||||
"movl 12(%%eax), %%edx" "\n\t"
|
||||
"movl 8(%%eax), %%ecx" "\n\t"
|
||||
"movl 4(%%eax), %%ebx" "\n\t"
|
||||
"movl (%%eax), %%eax" "\n\t"
|
||||
"cld" "\n\t"
|
||||
"rep; insb" "\n\t"
|
||||
"xchgl %%eax, (%%esp)" "\n\t"
|
||||
"movl %%ebp, 24(%%eax)" "\n\t"
|
||||
"movl %%edi, 20(%%eax)" "\n\t"
|
||||
"movl %%esi, 16(%%eax)" "\n\t"
|
||||
"movl %%edx, 12(%%eax)" "\n\t"
|
||||
"movl %%ecx, 8(%%eax)" "\n\t"
|
||||
"movl %%ebx, 4(%%eax)" "\n\t"
|
||||
"popl (%%eax)" "\n\t"
|
||||
|
||||
"popl %%ebp" "\n\t"
|
||||
#ifdef __PIC__
|
||||
"popl %%ebx" "\n\t"
|
||||
#endif
|
||||
: "=a" (dummy)
|
||||
: "0" (myBp)
|
||||
/*
|
||||
* vmware can modify the whole VM state without the compiler knowing
|
||||
* it. --hpreg
|
||||
*/
|
||||
:
|
||||
#ifndef __PIC__
|
||||
"ebx",
|
||||
#endif
|
||||
"ecx", "edx", "esi", "edi", "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BackdoorHbOut(Backdoor_proto_hb *myBp) // IN/OUT
|
||||
{
|
||||
uint32 dummy;
|
||||
|
||||
__asm__ __volatile__(
|
||||
#ifdef __PIC__
|
||||
"pushl %%ebx" "\n\t"
|
||||
#endif
|
||||
"pushl %%ebp" "\n\t"
|
||||
|
||||
"pushl %%eax" "\n\t"
|
||||
"movl 24(%%eax), %%ebp" "\n\t"
|
||||
"movl 20(%%eax), %%edi" "\n\t"
|
||||
"movl 16(%%eax), %%esi" "\n\t"
|
||||
"movl 12(%%eax), %%edx" "\n\t"
|
||||
"movl 8(%%eax), %%ecx" "\n\t"
|
||||
"movl 4(%%eax), %%ebx" "\n\t"
|
||||
"movl (%%eax), %%eax" "\n\t"
|
||||
"cld" "\n\t"
|
||||
"rep; outsb" "\n\t"
|
||||
"xchgl %%eax, (%%esp)" "\n\t"
|
||||
"movl %%ebp, 24(%%eax)" "\n\t"
|
||||
"movl %%edi, 20(%%eax)" "\n\t"
|
||||
"movl %%esi, 16(%%eax)" "\n\t"
|
||||
"movl %%edx, 12(%%eax)" "\n\t"
|
||||
"movl %%ecx, 8(%%eax)" "\n\t"
|
||||
"movl %%ebx, 4(%%eax)" "\n\t"
|
||||
"popl (%%eax)" "\n\t"
|
||||
|
||||
"popl %%ebp" "\n\t"
|
||||
#ifdef __PIC__
|
||||
"popl %%ebx" "\n\t"
|
||||
#endif
|
||||
: "=a" (dummy)
|
||||
: "0" (myBp)
|
||||
:
|
||||
#ifndef __PIC__
|
||||
"ebx",
|
||||
#endif
|
||||
"ecx", "edx", "esi", "edi", "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
243
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/backdoor_amd64.c
generated
vendored
Normal file
243
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/backdoor_amd64.c
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2005-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*********************************************************
|
||||
* The contents of this file are subject to the terms of the Common
|
||||
* Development and Distribution License (the "License") version 1.0
|
||||
* and no later version. You may not use this file except in
|
||||
* compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the License at
|
||||
* http://www.opensource.org/licenses/cddl1.php
|
||||
*
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* backdoorGcc64.c --
|
||||
*
|
||||
* Implements the real work for guest-side backdoor for GCC, 64-bit
|
||||
* target (supports inline ASM, GAS syntax). The asm sections are marked
|
||||
* volatile since vmware can change the registers content without the
|
||||
* compiler knowing it.
|
||||
*
|
||||
* See backdoorGCC32.c (from which this code was mostly copied) for
|
||||
* details on why the ASM is written this way. Also note that it might be
|
||||
* possible to write the asm blocks using the symbolic operand specifiers
|
||||
* in such a way that the same asm would generate correct code for both
|
||||
* 32-bit and 64-bit targets, but I'm too lazy to figure it all out.
|
||||
* --rrdharan
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "backdoor.h"
|
||||
#include "backdoorInt.h"
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
*
|
||||
* Backdoor_InOut --
|
||||
*
|
||||
* Send a low-bandwidth basic request (16 bytes) to vmware, and return its
|
||||
* reply (24 bytes).
|
||||
*
|
||||
* Results:
|
||||
* Host-side response returned in bp IN/OUT parameter.
|
||||
*
|
||||
* Side effects:
|
||||
* Pokes the backdoor.
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
Backdoor_InOut(Backdoor_proto *myBp) // IN/OUT
|
||||
{
|
||||
uint64 dummy;
|
||||
|
||||
__asm__ __volatile__(
|
||||
#ifdef __APPLE__
|
||||
/*
|
||||
* Save %rbx on the stack because the Mac OS GCC doesn't want us to
|
||||
* clobber it - it erroneously thinks %rbx is the PIC register.
|
||||
* (Radar bug 7304232)
|
||||
*/
|
||||
"pushq %%rbx" "\n\t"
|
||||
#endif
|
||||
"pushq %%rax" "\n\t"
|
||||
"movq 40(%%rax), %%rdi" "\n\t"
|
||||
"movq 32(%%rax), %%rsi" "\n\t"
|
||||
"movq 24(%%rax), %%rdx" "\n\t"
|
||||
"movq 16(%%rax), %%rcx" "\n\t"
|
||||
"movq 8(%%rax), %%rbx" "\n\t"
|
||||
"movq (%%rax), %%rax" "\n\t"
|
||||
"inl %%dx, %%eax" "\n\t" /* NB: There is no inq instruction */
|
||||
"xchgq %%rax, (%%rsp)" "\n\t"
|
||||
"movq %%rdi, 40(%%rax)" "\n\t"
|
||||
"movq %%rsi, 32(%%rax)" "\n\t"
|
||||
"movq %%rdx, 24(%%rax)" "\n\t"
|
||||
"movq %%rcx, 16(%%rax)" "\n\t"
|
||||
"movq %%rbx, 8(%%rax)" "\n\t"
|
||||
"popq (%%rax)" "\n\t"
|
||||
#ifdef __APPLE__
|
||||
"popq %%rbx" "\n\t"
|
||||
#endif
|
||||
: "=a" (dummy)
|
||||
: "0" (myBp)
|
||||
/*
|
||||
* vmware can modify the whole VM state without the compiler knowing
|
||||
* it. So far it does not modify EFLAGS. --hpreg
|
||||
*/
|
||||
:
|
||||
#ifndef __APPLE__
|
||||
/* %rbx is unchanged at the end of the function on Mac OS. */
|
||||
"rbx",
|
||||
#endif
|
||||
"rcx", "rdx", "rsi", "rdi", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* BackdoorHbIn --
|
||||
* BackdoorHbOut --
|
||||
*
|
||||
* Send a high-bandwidth basic request to vmware, and return its
|
||||
* reply.
|
||||
*
|
||||
* Results:
|
||||
* Host-side response returned in bp IN/OUT parameter.
|
||||
*
|
||||
* Side-effects:
|
||||
* Pokes the high-bandwidth backdoor port.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
BackdoorHbIn(Backdoor_proto_hb *myBp) // IN/OUT
|
||||
{
|
||||
uint64 dummy;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"pushq %%rbp" "\n\t"
|
||||
#ifdef __APPLE__
|
||||
/*
|
||||
* Save %rbx on the stack because the Mac OS GCC doesn't want us to
|
||||
* clobber it - it erroneously thinks %rbx is the PIC register.
|
||||
* (Radar bug 7304232)
|
||||
*/
|
||||
"pushq %%rbx" "\n\t"
|
||||
#endif
|
||||
"pushq %%rax" "\n\t"
|
||||
"movq 48(%%rax), %%rbp" "\n\t"
|
||||
"movq 40(%%rax), %%rdi" "\n\t"
|
||||
"movq 32(%%rax), %%rsi" "\n\t"
|
||||
"movq 24(%%rax), %%rdx" "\n\t"
|
||||
"movq 16(%%rax), %%rcx" "\n\t"
|
||||
"movq 8(%%rax), %%rbx" "\n\t"
|
||||
"movq (%%rax), %%rax" "\n\t"
|
||||
"cld" "\n\t"
|
||||
"rep; insb" "\n\t"
|
||||
"xchgq %%rax, (%%rsp)" "\n\t"
|
||||
"movq %%rbp, 48(%%rax)" "\n\t"
|
||||
"movq %%rdi, 40(%%rax)" "\n\t"
|
||||
"movq %%rsi, 32(%%rax)" "\n\t"
|
||||
"movq %%rdx, 24(%%rax)" "\n\t"
|
||||
"movq %%rcx, 16(%%rax)" "\n\t"
|
||||
"movq %%rbx, 8(%%rax)" "\n\t"
|
||||
"popq (%%rax)" "\n\t"
|
||||
#ifdef __APPLE__
|
||||
"popq %%rbx" "\n\t"
|
||||
#endif
|
||||
"popq %%rbp"
|
||||
: "=a" (dummy)
|
||||
: "0" (myBp)
|
||||
/*
|
||||
* vmware can modify the whole VM state without the compiler knowing
|
||||
* it. --hpreg
|
||||
*/
|
||||
:
|
||||
#ifndef __APPLE__
|
||||
/* %rbx is unchanged at the end of the function on Mac OS. */
|
||||
"rbx",
|
||||
#endif
|
||||
"rcx", "rdx", "rsi", "rdi", "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BackdoorHbOut(Backdoor_proto_hb *myBp) // IN/OUT
|
||||
{
|
||||
uint64 dummy;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"pushq %%rbp" "\n\t"
|
||||
#ifdef __APPLE__
|
||||
/*
|
||||
* Save %rbx on the stack because the Mac OS GCC doesn't want us to
|
||||
* clobber it - it erroneously thinks %rbx is the PIC register.
|
||||
* (Radar bug 7304232)
|
||||
*/
|
||||
"pushq %%rbx" "\n\t"
|
||||
#endif
|
||||
"pushq %%rax" "\n\t"
|
||||
"movq 48(%%rax), %%rbp" "\n\t"
|
||||
"movq 40(%%rax), %%rdi" "\n\t"
|
||||
"movq 32(%%rax), %%rsi" "\n\t"
|
||||
"movq 24(%%rax), %%rdx" "\n\t"
|
||||
"movq 16(%%rax), %%rcx" "\n\t"
|
||||
"movq 8(%%rax), %%rbx" "\n\t"
|
||||
"movq (%%rax), %%rax" "\n\t"
|
||||
"cld" "\n\t"
|
||||
"rep; outsb" "\n\t"
|
||||
"xchgq %%rax, (%%rsp)" "\n\t"
|
||||
"movq %%rbp, 48(%%rax)" "\n\t"
|
||||
"movq %%rdi, 40(%%rax)" "\n\t"
|
||||
"movq %%rsi, 32(%%rax)" "\n\t"
|
||||
"movq %%rdx, 24(%%rax)" "\n\t"
|
||||
"movq %%rcx, 16(%%rax)" "\n\t"
|
||||
"movq %%rbx, 8(%%rax)" "\n\t"
|
||||
"popq (%%rax)" "\n\t"
|
||||
#ifdef __APPLE__
|
||||
"popq %%rbx" "\n\t"
|
||||
#endif
|
||||
"popq %%rbp"
|
||||
: "=a" (dummy)
|
||||
: "0" (myBp)
|
||||
:
|
||||
#ifndef __APPLE__
|
||||
/* %rbx is unchanged at the end of the function on Mac OS. */
|
||||
"rbx",
|
||||
#endif
|
||||
"rcx", "rdx", "rsi", "rdi", "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
60
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/bridge.go
generated
vendored
Normal file
60
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/bridge.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
package bridge
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -I../include
|
||||
#include <stdlib.h>
|
||||
#include "message.h"
|
||||
#include "vmcheck.h"
|
||||
void Warning(const char *fmt, ...) {}
|
||||
void Debug(const char *fmt, ...) {}
|
||||
void Panic(const char *fmt, ...) {}
|
||||
void Log(const char *fmt, ...) {}
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
// MessageChannel provides a channel to pass information from/to the hypervisor
|
||||
type MessageChannel *C.struct_Message_Channel
|
||||
|
||||
// MessageOpen creates a new MessageChannel
|
||||
func MessageOpen(proto uint32) MessageChannel {
|
||||
return C.Message_Open(C.uint32(proto))
|
||||
}
|
||||
|
||||
// MessageClose closes a MessageChannel
|
||||
func MessageClose(c MessageChannel) bool {
|
||||
status := C.Message_Close(c)
|
||||
return status != 0
|
||||
}
|
||||
|
||||
// MessageSend sends a request through a MessageChannel
|
||||
func MessageSend(c MessageChannel, request []byte) bool {
|
||||
buffer := (*C.uchar)(unsafe.Pointer(&request[0]))
|
||||
status := C.Message_Send(c, buffer, (C.size_t)(C.int(len(request))))
|
||||
return status != 0
|
||||
}
|
||||
|
||||
// MessageReceive receives a response through a MessageChannel
|
||||
func MessageReceive(c MessageChannel) ([]byte, bool) {
|
||||
var reply *C.uchar
|
||||
var replyLen C.size_t
|
||||
defer C.free(unsafe.Pointer(reply))
|
||||
|
||||
status := C.Message_Receive(c, &reply, &replyLen)
|
||||
|
||||
res := C.GoBytes(unsafe.Pointer(reply), (C.int)(replyLen))
|
||||
return res, status != 0
|
||||
}
|
||||
|
||||
// VMCheckIsVirtualWorld checks if current code is running in a VMware virtual machine
|
||||
func VMCheckIsVirtualWorld() bool {
|
||||
return C.VmCheck_IsVirtualWorld() != 0
|
||||
}
|
||||
|
||||
// VMCheckGetVersion returns the identifiers of the current hypervisor
|
||||
func VMCheckGetVersion() (uint32, uint32) {
|
||||
var version C.uint32
|
||||
var typ C.uint32
|
||||
C.VmCheck_GetVersion(&version, &typ)
|
||||
return uint32(version), uint32(typ)
|
||||
}
|
439
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/dynbuf.c
generated
vendored
Normal file
439
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/dynbuf.c
generated
vendored
Normal file
@@ -0,0 +1,439 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* dynbuf.c --
|
||||
*
|
||||
* Dynamic buffers --hpreg
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "vmware.h"
|
||||
#include "dynbuf.h"
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBuf_Init --
|
||||
*
|
||||
* Dynamic buffer constructor --hpreg
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DynBuf_Init(DynBuf *b) // OUT:
|
||||
{
|
||||
ASSERT(b);
|
||||
|
||||
b->data = NULL;
|
||||
b->size = 0;
|
||||
b->allocated = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBuf_Destroy --
|
||||
*
|
||||
* Dynamic buffer destructor --hpreg
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DynBuf_Destroy(DynBuf *b) // IN/OUT:
|
||||
{
|
||||
ASSERT(b);
|
||||
|
||||
free(b->data);
|
||||
DynBuf_Init(b);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBuf_AllocGet --
|
||||
*
|
||||
* Retrieve a pointer to the data contained in a dynamic buffer. Return
|
||||
* a copy of that data.
|
||||
*
|
||||
* Results:
|
||||
* The pointer to the data. NULL on out of memory failure.
|
||||
*
|
||||
* Side effects:
|
||||
* Allocates memory.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void *
|
||||
DynBuf_AllocGet(DynBuf const *b) // IN
|
||||
{
|
||||
void *new_data;
|
||||
ASSERT(b);
|
||||
|
||||
new_data = malloc(b->size);
|
||||
if (new_data) {
|
||||
memcpy(new_data, b->data, b->size);
|
||||
}
|
||||
|
||||
return new_data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBuf_Attach --
|
||||
*
|
||||
* Grants ownership of the specified buffer to the DynBuf
|
||||
* object. If there is an existing buffer, it is freed.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DynBuf_Attach(DynBuf *b, // IN
|
||||
size_t size, // IN
|
||||
void *data) // IN
|
||||
{
|
||||
ASSERT(b);
|
||||
ASSERT((size == 0) == (data == NULL));
|
||||
|
||||
free(b->data);
|
||||
b->data = data;
|
||||
b->size = b->allocated = size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBuf_Detach --
|
||||
*
|
||||
* Releases ownership of the buffer stored in the DynBuf object,
|
||||
* and returns a pointer to it.
|
||||
*
|
||||
* Results:
|
||||
* The pointer to the data.
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void *
|
||||
DynBuf_Detach(DynBuf *b) // IN
|
||||
{
|
||||
void *data;
|
||||
|
||||
ASSERT(b);
|
||||
|
||||
data = b->data;
|
||||
b->data = NULL;
|
||||
b->allocated = 0;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBufRealloc --
|
||||
*
|
||||
* Reallocate a dynamic buffer --hpreg
|
||||
*
|
||||
* Results:
|
||||
* TRUE on success
|
||||
* FALSE on failure (not enough memory)
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static Bool
|
||||
DynBufRealloc(DynBuf *b, // IN:
|
||||
size_t newAllocated) // IN:
|
||||
{
|
||||
void *new_data;
|
||||
|
||||
ASSERT(b);
|
||||
|
||||
new_data = realloc(b->data, newAllocated);
|
||||
if (new_data == NULL && newAllocated) {
|
||||
/* Not enough memory */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
b->data = new_data;
|
||||
b->allocated = newAllocated;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBuf_Enlarge --
|
||||
*
|
||||
* Enlarge a dynamic buffer. The resulting dynamic buffer is guaranteed to
|
||||
* be larger than the one you passed, and at least 'minSize' bytes
|
||||
* large --hpreg
|
||||
*
|
||||
* Results:
|
||||
* TRUE on success
|
||||
* FALSE on failure (not enough memory)
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
DynBuf_Enlarge(DynBuf *b, // IN:
|
||||
size_t minSize) // IN:
|
||||
{
|
||||
size_t newAllocated;
|
||||
|
||||
ASSERT(b);
|
||||
|
||||
newAllocated = b->allocated
|
||||
?
|
||||
#if defined(DYNBUF_DEBUG)
|
||||
b->allocated + 1
|
||||
#else
|
||||
/*
|
||||
* Double the previously allocated size if it is less
|
||||
* than 256KB; otherwise grow it linearly by 256KB
|
||||
*/
|
||||
(b->allocated < 256 * 1024 ? b->allocated * 2
|
||||
: b->allocated + 256 * 1024)
|
||||
#endif
|
||||
:
|
||||
#if defined(DYNBUF_DEBUG)
|
||||
1
|
||||
#else
|
||||
/*
|
||||
* Initial size: 1 KB. Most buffers are smaller than
|
||||
* that --hpreg
|
||||
*/
|
||||
1 << 10
|
||||
#endif
|
||||
;
|
||||
|
||||
if (minSize > newAllocated) {
|
||||
newAllocated = minSize;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevent integer overflow. We can use this form of checking specifically
|
||||
* because a multiple by 2 is used (in the worst case). This type of
|
||||
* checking does not work in the general case.
|
||||
*/
|
||||
|
||||
if (newAllocated < b->allocated) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return DynBufRealloc(b, newAllocated);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBuf_Append --
|
||||
*
|
||||
* Append data at the end of a dynamic buffer. 'size' is the size of the
|
||||
* data. If it is <= 0, no operation is performed --hpreg
|
||||
*
|
||||
* Results:
|
||||
* TRUE on success
|
||||
* FALSE on failure (not enough memory)
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
DynBuf_Append(DynBuf *b, // IN
|
||||
void const *data, // IN
|
||||
size_t size) // IN
|
||||
{
|
||||
size_t new_size;
|
||||
|
||||
ASSERT(b);
|
||||
|
||||
if (size <= 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ASSERT(data);
|
||||
|
||||
new_size = b->size + size;
|
||||
|
||||
if (new_size < b->size) { // Prevent integer overflow
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (new_size > b->allocated) {
|
||||
/* Not enough room */
|
||||
if (DynBuf_Enlarge(b, new_size) == FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(b->data + b->size, data, size);
|
||||
b->size = new_size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBuf_SafeInternalAppend --
|
||||
*
|
||||
* Append data at the end of a dynamic buffer. Memory allocation failure
|
||||
* are handled the same way as Util_SafeMalloc, that is to say, with a
|
||||
* Panic.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DynBuf_SafeInternalAppend(DynBuf *b, // IN
|
||||
void const *data, // IN
|
||||
size_t size, // IN
|
||||
char const *file, // IN
|
||||
unsigned int lineno) // IN
|
||||
{
|
||||
if (!DynBuf_Append(b, data, size)) {
|
||||
Panic("Unrecoverable memory allocation failure at %s:%u\n",
|
||||
file, lineno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBuf_Trim --
|
||||
*
|
||||
* Reallocate a dynamic buffer to the exact size it occupies --hpreg
|
||||
*
|
||||
* Results:
|
||||
* TRUE on success
|
||||
* FALSE on failure (not enough memory)
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
DynBuf_Trim(DynBuf *b) // IN
|
||||
{
|
||||
ASSERT(b);
|
||||
|
||||
return DynBufRealloc(b, b->size);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DynBuf_Copy --
|
||||
*
|
||||
* Copies all data and metadata from src dynbuff to dest dynbuf.
|
||||
*
|
||||
* Dest should be an initialized DynBuf of alloced length zero
|
||||
* to prevent memory leaks.
|
||||
*
|
||||
* Results:
|
||||
* TRUE on success, FALSE on failure.
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
DynBuf_Copy(DynBuf *src, // IN
|
||||
DynBuf *dest) // OUT
|
||||
{
|
||||
ASSERT(src);
|
||||
ASSERT(dest);
|
||||
ASSERT(!dest->data);
|
||||
|
||||
dest->data = malloc(src->allocated);
|
||||
|
||||
if (dest->data == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dest->size = src->size;
|
||||
dest->allocated = src->allocated;
|
||||
|
||||
memcpy(dest->data, src->data, src->size);
|
||||
|
||||
return TRUE;
|
||||
}
|
336
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/hostinfo.c
generated
vendored
Normal file
336
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/hostinfo.c
generated
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* hostinfo.c --
|
||||
*
|
||||
* Platform-independent code that calls into hostinfo<OS>-specific
|
||||
* code.
|
||||
*/
|
||||
|
||||
#include "vmware.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#include "cpuid_info.h"
|
||||
#endif
|
||||
#include "hostinfo.h"
|
||||
#include "hostinfoInt.h"
|
||||
#include "util.h"
|
||||
/* #include "str.h" */
|
||||
#include <stdio.h>
|
||||
#define Str_Sprintf snprintf
|
||||
#include "dynbuf.h"
|
||||
#include "backdoor_def.h"
|
||||
|
||||
/*
|
||||
* #define LOGLEVEL_MODULE hostinfo
|
||||
* #include "loglevel_user.h"
|
||||
*/
|
||||
#define LGPFX "HOSTINFO:"
|
||||
|
||||
|
||||
/*
|
||||
* HostinfoOSData caches its returned value.
|
||||
*/
|
||||
|
||||
volatile Bool HostinfoOSNameCacheValid = FALSE;
|
||||
char HostinfoCachedOSName[MAX_OS_NAME_LEN];
|
||||
char HostinfoCachedOSFullName[MAX_OS_FULLNAME_LEN];
|
||||
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* HostInfoGetCpuidStrSection --
|
||||
*
|
||||
* Append a section (either low or high) of CPUID as a string in DynBuf.
|
||||
* E.g.
|
||||
* 00000000:00000005756E65476C65746E49656E69-
|
||||
* 00000001:00000F4A000208000000649DBFEBFBFF-
|
||||
* or
|
||||
* 80000000:80000008000000000000000000000000-
|
||||
* 80000001:00000000000000000000000120100000-
|
||||
* 80000008:00003024000000000000000000000000-
|
||||
*
|
||||
* The returned eax of args[0] is used to determine the upper bound for
|
||||
* the following input arguments. And the input args should be in
|
||||
* ascending order.
|
||||
*
|
||||
* Results:
|
||||
* None. The string will be appended in buf.
|
||||
*
|
||||
* Side effect:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
HostInfoGetCpuidStrSection(const uint32 args[], // IN: input eax arguments
|
||||
const size_t args_size, // IN: size of the argument array
|
||||
DynBuf *buf) // IN/OUT: result string in DynBuf
|
||||
{
|
||||
static const char format[] = "%08X:%08X%08X%08X%08X-";
|
||||
CPUIDRegs reg;
|
||||
uint32 max_arg;
|
||||
char temp[64];
|
||||
int i;
|
||||
|
||||
__GET_CPUID(args[0], ®);
|
||||
max_arg = reg.eax;
|
||||
if (max_arg < args[0]) {
|
||||
Warning(LGPFX" No CPUID information available. Based = %08X.\n",
|
||||
args[0]);
|
||||
return;
|
||||
}
|
||||
DynBuf_Append(buf, temp,
|
||||
Str_Sprintf(temp, sizeof temp, format, args[0], reg.eax,
|
||||
reg.ebx, reg.ecx, reg.edx));
|
||||
|
||||
for (i = 1; i < args_size && args[i] <= max_arg; i++) {
|
||||
ASSERT(args[i] > args[i - 1]); // Ascending order.
|
||||
__GET_CPUID(args[i], ®);
|
||||
|
||||
DynBuf_Append(buf, temp,
|
||||
Str_Sprintf(temp, sizeof temp, format, args[i], reg.eax,
|
||||
reg.ebx, reg.ecx, reg.edx));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_GetCpuidStr --
|
||||
*
|
||||
* Get the basic and extended CPUID as a string. E.g.
|
||||
* 00000000:00000005756E65476C65746E49656E69-
|
||||
* 00000001:00000F4A000208000000649DBFEBFBFF-
|
||||
* 80000000:80000008000000000000000000000000-
|
||||
* 80000001:00000000000000000000000120100000-
|
||||
* 80000008:00003024000000000000000000000000
|
||||
*
|
||||
* If the extended CPUID is not available, only returns the basic CPUID.
|
||||
*
|
||||
* Results:
|
||||
* The CPUID string if the processor supports the CPUID instruction and
|
||||
* this is a processor we recognize. It should never fail, since it
|
||||
* would at least return leaf 0. Caller needs to free the returned string.
|
||||
*
|
||||
* Side effect:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
Hostinfo_GetCpuidStr(void)
|
||||
{
|
||||
static const uint32 basic_args[] = {0x0, 0x1, 0xa};
|
||||
static const uint32 extended_args[] = {0x80000000, 0x80000001, 0x80000008};
|
||||
DynBuf buf;
|
||||
char *result;
|
||||
|
||||
DynBuf_Init(&buf);
|
||||
|
||||
HostInfoGetCpuidStrSection(basic_args, ARRAYSIZE(basic_args), &buf);
|
||||
HostInfoGetCpuidStrSection(extended_args, ARRAYSIZE(extended_args), &buf);
|
||||
|
||||
// Trim buffer and set NULL character to replace last '-'.
|
||||
DynBuf_Trim(&buf);
|
||||
result = (char*)DynBuf_Get(&buf);
|
||||
ASSERT(result && result[0]); // We should at least get result from eax = 0x0.
|
||||
result[DynBuf_GetSize(&buf) - 1] = '\0';
|
||||
|
||||
return DynBuf_Detach(&buf);
|
||||
}
|
||||
#endif // defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_GetCpuid --
|
||||
*
|
||||
* Get cpuid information for a CPU. Which CPU the information is for
|
||||
* depends on the OS scheduler. We are assuming that all CPUs in
|
||||
* the system have identical numbers of cores and threads.
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the processor supports the cpuid instruction and this
|
||||
* is a process we recognize, FALSE otherwise.
|
||||
*
|
||||
* Side effect:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_GetCpuid(HostinfoCpuIdInfo *info) // OUT
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
CPUIDSummary cpuid;
|
||||
CPUIDRegs id0;
|
||||
|
||||
/*
|
||||
* Can't do cpuid = {0} as an initializer above because gcc throws
|
||||
* some idiotic warning.
|
||||
*/
|
||||
|
||||
memset(&cpuid, 0, sizeof(cpuid));
|
||||
|
||||
/*
|
||||
* Get basic and extended CPUID info.
|
||||
*/
|
||||
|
||||
__GET_CPUID(0, &id0);
|
||||
|
||||
cpuid.id0.numEntries = id0.eax;
|
||||
|
||||
if (0 == cpuid.id0.numEntries) {
|
||||
Warning(LGPFX" No CPUID information available.\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*(uint32*)(cpuid.id0.name + 0) = id0.ebx;
|
||||
*(uint32*)(cpuid.id0.name + 4) = id0.edx;
|
||||
*(uint32*)(cpuid.id0.name + 8) = id0.ecx;
|
||||
*(uint32*)(cpuid.id0.name + 12) = 0;
|
||||
|
||||
__GET_CPUID(1, (CPUIDRegs*)&cpuid.id1);
|
||||
__GET_CPUID(0xa, (CPUIDRegs*)&cpuid.ida);
|
||||
__GET_CPUID(0x80000000, (CPUIDRegs*)&cpuid.id80);
|
||||
__GET_CPUID(0x80000001, (CPUIDRegs*)&cpuid.id81);
|
||||
__GET_CPUID(0x80000008, (CPUIDRegs*)&cpuid.id88);
|
||||
|
||||
/*
|
||||
* Calculate vendor information.
|
||||
*/
|
||||
|
||||
if (0 == strcmp(cpuid.id0.name, CPUID_INTEL_VENDOR_STRING_FIXED)) {
|
||||
info->vendor = CPUID_VENDOR_INTEL;
|
||||
} else if (strcmp(cpuid.id0.name, CPUID_AMD_VENDOR_STRING_FIXED) == 0) {
|
||||
info->vendor = CPUID_VENDOR_AMD;
|
||||
} else {
|
||||
info->vendor = CPUID_VENDOR_UNKNOWN;
|
||||
}
|
||||
/*
|
||||
* Pull out versioning and feature information.
|
||||
*/
|
||||
|
||||
info->version = cpuid.id1.version;
|
||||
info->family = CPUID_GET(1, EAX, FAMILY, cpuid.id1.version);
|
||||
info->model = CPUID_GET(1, EAX, MODEL, cpuid.id1.version);
|
||||
info->stepping = CPUID_GET(1, EAX, STEPPING, cpuid.id1.version);
|
||||
info->type = (cpuid.id1.version >> 12) & 0x0003;
|
||||
|
||||
info->extfeatures = cpuid.id1.ecxFeatures;
|
||||
info->features = cpuid.id1.edxFeatures;
|
||||
|
||||
return TRUE;
|
||||
#else // defined(__i386__) || defined(__x86_64__)
|
||||
return FALSE;
|
||||
#endif // defined(__i386__) || defined(__x86_64__)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_GetOSName --
|
||||
*
|
||||
* Query the operating system and build a string to identify it.
|
||||
*
|
||||
* Examples:
|
||||
* Windows: <OS NAME> <SERVICE PACK> (Build <BUILD_NUMBER>)
|
||||
* example: Windows XP Professional Service Pack 2 (Build 2600)
|
||||
*
|
||||
* Linux: <OS NAME> <OS RELEASE> <SPECIFIC_DISTRO_INFO>
|
||||
* example: Linux 2.4.18-3 Red Hat Linux release 7.3 (Valhalla)
|
||||
*
|
||||
* Mac OS: <OS NAME> <OS VERSION> (<BUILD VERSION>) <KERNEL NAME> <KERNEL RELEASE>
|
||||
* example: Mac OS X 10.8.5 (12F45) Darwin 12.5.0
|
||||
*
|
||||
* Return value:
|
||||
* NULL Unable to obtain the OS name.
|
||||
* !NULL The OS name. The caller is responsible for freeing it.
|
||||
*
|
||||
* Side effects:
|
||||
* Memory is allocated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* char *
|
||||
* Hostinfo_GetOSName(void)
|
||||
* {
|
||||
* char *name;
|
||||
* Bool data = HostinfoOSNameCacheValid ? TRUE : HostinfoOSData();
|
||||
*
|
||||
* if (data) {
|
||||
* name = Util_SafeStrdup(HostinfoCachedOSFullName);
|
||||
* } else {
|
||||
* name = NULL;
|
||||
* }
|
||||
*
|
||||
* return name;
|
||||
* }
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_GetOSGuestString --
|
||||
*
|
||||
* Query the operating system and build a string to identify it. The
|
||||
* returned string is the same as you'd see in a VM's .vmx file.
|
||||
*
|
||||
* Return value:
|
||||
* NULL Unable to obtain the OS name.
|
||||
* !NULL The OS name. The caller is responsible for freeing it.
|
||||
*
|
||||
* Side effects:
|
||||
* Memory is allocated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* char *
|
||||
* Hostinfo_GetOSGuestString(void)
|
||||
* {
|
||||
* char *name;
|
||||
* Bool data = HostinfoOSNameCacheValid ? TRUE : HostinfoOSData();
|
||||
*
|
||||
* if (data) {
|
||||
* name = Util_SafeStrdup(HostinfoCachedOSName);
|
||||
* } else {
|
||||
* name = NULL;
|
||||
* }
|
||||
*
|
||||
* return name;
|
||||
* }
|
||||
*/
|
||||
|
686
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/hostinfoHV.c
generated
vendored
Normal file
686
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/hostinfoHV.c
generated
vendored
Normal file
@@ -0,0 +1,686 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2011-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* hostinfoHV.c --
|
||||
*
|
||||
* Code to detect different hypervisors and features.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "vmware.h"
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
# include "cpuid_info.h"
|
||||
# include "backdoor_def.h"
|
||||
# include "backdoor_types.h"
|
||||
#endif
|
||||
#include "hostinfo.h"
|
||||
#include "util.h"
|
||||
|
||||
#define LGPFX "HOSTINFO:"
|
||||
/*
|
||||
* #define LOGLEVEL_MODULE hostinfo
|
||||
* #include "loglevel_user.h"
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_HypervisorCPUIDSig --
|
||||
*
|
||||
* Get the hypervisor signature string from CPUID.
|
||||
*
|
||||
* Results:
|
||||
* Unqualified 16 byte nul-terminated hypervisor string
|
||||
* String may contain garbage and caller must free
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
Hostinfo_HypervisorCPUIDSig(void)
|
||||
{
|
||||
uint32 *name = NULL;
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
CPUIDRegs regs;
|
||||
|
||||
__GET_CPUID(1, ®s);
|
||||
if (!CPUID_ISSET(1, ECX, HYPERVISOR, regs.ecx)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
regs.ebx = 0;
|
||||
regs.ecx = 0;
|
||||
regs.edx = 0;
|
||||
|
||||
__GET_CPUID(0x40000000, ®s);
|
||||
|
||||
if (regs.eax < 0x40000000) {
|
||||
Log(LGPFX" CPUID hypervisor bit is set, but no "
|
||||
"hypervisor vendor signature is present\n");
|
||||
}
|
||||
|
||||
name = Util_SafeMalloc(4 * sizeof *name);
|
||||
|
||||
name[0] = regs.ebx;
|
||||
name[1] = regs.ecx;
|
||||
name[2] = regs.edx;
|
||||
name[3] = 0;
|
||||
#endif // defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
return (char *)name;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_TouchXen --
|
||||
*
|
||||
* Check for Xen.
|
||||
*
|
||||
* Official way is to call Hostinfo_HypervisorCPUIDSig(), which
|
||||
* returns a hypervisor string. This is a secondary check
|
||||
* that guards against a backdoor failure. See PR156185,
|
||||
* http://xenbits.xensource.com/xen-unstable.hg?file/6a383beedf83/tools/misc/xen-detect.c
|
||||
* (Canonical way is /proc/xen, but CPUID is better).
|
||||
*
|
||||
* Results:
|
||||
* TRUE if we are running in a Xen dom0 or domU.
|
||||
* Linux:
|
||||
* Illegal instruction exception on real hardware.
|
||||
* Obscure Xen implementations might return FALSE.
|
||||
* Windows:
|
||||
* FALSE on real hardware.
|
||||
*
|
||||
* Side effects:
|
||||
* Linux: Will raise exception on native hardware.
|
||||
* Windows: None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_TouchXen(void)
|
||||
{
|
||||
#if defined(linux) && (defined(__i386__) || defined(__x86_64__))
|
||||
#define XEN_CPUID 0x40000000
|
||||
CPUIDRegs regs;
|
||||
uint32 name[4];
|
||||
|
||||
/*
|
||||
* PV mode: ud2a "xen" cpuid (faults on native hardware).
|
||||
* (Only Linux can run PV, so skip others here).
|
||||
* Since PV cannot trap CPUID, this is a Xen hook.
|
||||
*/
|
||||
|
||||
regs.eax = XEN_CPUID;
|
||||
__asm__ __volatile__(
|
||||
"xchgl %%ebx, %0" "\n\t"
|
||||
"ud2a ; .ascii \"xen\" ; cpuid" "\n\t"
|
||||
"xchgl %%ebx, %0"
|
||||
: "=&r" (regs.ebx), "=&c" (regs.ecx), "=&d" (regs.edx)
|
||||
: "a" (regs.eax)
|
||||
);
|
||||
|
||||
name[0] = regs.ebx;
|
||||
name[1] = regs.ecx;
|
||||
name[2] = regs.edx;
|
||||
name[3] = 0;
|
||||
|
||||
if (0 == strcmp(CPUID_XEN_HYPERVISOR_VENDOR_STRING, (const char*)name)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Passed checks. But native and anything non-Xen would #UD before here. */
|
||||
NOT_TESTED();
|
||||
Log("Xen detected but hypervisor unrecognized (Xen variant?)\n");
|
||||
Log("CPUID 0x4000 0000: eax=%x ebx=%x ecx=%x edx=%x\n",
|
||||
regs.eax, regs.ebx, regs.ecx, regs.edx);
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_SLC64Supported --
|
||||
*
|
||||
* Access the backdoor with an SLC64 control query. This is used
|
||||
* to determine if we are running in a VM that supports SLC64.
|
||||
* This function should only be called after determining that the
|
||||
* backdoor is present with Hostinfo_TouchBackdoor().
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the outer VM supports SLC64.
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM, so don't do that!
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_SLC64Supported(void)
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
return Hostinfo_VCPUInfoBackdoor(BDOOR_CMD_VCPU_SLC64);
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_NestedHVReplaySupported --
|
||||
*
|
||||
* Access the backdoor with a HV replay control query. This is used
|
||||
* to determine if we are running in a VM that supports nested HV replay.
|
||||
* This function should only be called after determining that the
|
||||
* backdoor is present with Hostinfo_TouchBackdoor().
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the outer VM supports nexted HV replay.
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM, so don't do that!
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_NestedHVReplaySupported(void)
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
return Hostinfo_VCPUInfoBackdoor(BDOOR_CMD_VCPU_HV_REPLAY_OK);
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_SynchronizedVTSCs --
|
||||
*
|
||||
* Access the backdoor to determine if the VCPUs' TSCs are
|
||||
* synchronized.
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the outer VM provides synchronized VTSCs.
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM, so don't do that!
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_SynchronizedVTSCs(void)
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
return Hostinfo_VCPUInfoBackdoor(BDOOR_CMD_VCPU_SYNC_VTSCS);
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#if defined(_WIN64)
|
||||
// from touchBackdoorMasm64.asm
|
||||
void Hostinfo_BackdoorInOut(Backdoor_proto *myBp);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_TouchBackDoor --
|
||||
*
|
||||
* Access the backdoor. This is used to determine if we are
|
||||
* running in a VM or on a physical host. On a physical host
|
||||
* this should generate a GP which we catch and thereby determine
|
||||
* that we are not in a VM. However some OSes do not handle the
|
||||
* GP correctly and the process continues running returning garbage.
|
||||
* In this case we check the EBX register which should be
|
||||
* BDOOR_MAGIC if the IN was handled in a VM. Based on this we
|
||||
* return either TRUE or FALSE.
|
||||
*
|
||||
* Results:
|
||||
* TRUE if we succesfully accessed the backdoor, FALSE or segfault
|
||||
* if not.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_TouchBackDoor(void)
|
||||
{
|
||||
uint32 ebxval;
|
||||
|
||||
#if defined(_WIN64)
|
||||
Backdoor_proto bp;
|
||||
|
||||
bp.in.ax.quad = BDOOR_MAGIC;
|
||||
bp.in.size = ~BDOOR_MAGIC;
|
||||
bp.in.cx.quad = BDOOR_CMD_GETVERSION;
|
||||
bp.in.dx.quad = BDOOR_PORT;
|
||||
|
||||
Hostinfo_BackdoorInOut(&bp);
|
||||
|
||||
ebxval = bp.out.bx.words.low;
|
||||
#else // _WIN64
|
||||
_asm {
|
||||
push edx
|
||||
push ecx
|
||||
push ebx
|
||||
mov ecx, BDOOR_CMD_GETVERSION
|
||||
mov ebx, ~BDOOR_MAGIC
|
||||
mov eax, BDOOR_MAGIC
|
||||
mov dx, BDOOR_PORT
|
||||
in eax, dx
|
||||
mov ebxval, ebx
|
||||
pop ebx
|
||||
pop ecx
|
||||
pop edx
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
return (ebxval == BDOOR_MAGIC) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_TouchVirtualPC --
|
||||
*
|
||||
* Access MS Virtual PC's backdoor. This is used to determine if
|
||||
* we are running in a MS Virtual PC or on a physical host. Works
|
||||
* the same as Hostinfo_TouchBackDoor, except the entry to MS VPC
|
||||
* is an invalid opcode instead or writing to a port. Since
|
||||
* MS VPC is 32-bit only, the WIN64 path returns FALSE.
|
||||
* See: See: http://www.codeproject.com/KB/system/VmDetect.aspx
|
||||
*
|
||||
* Results:
|
||||
* TRUE if we succesfully accessed MS Virtual PC, FALSE or
|
||||
* segfault if not.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_TouchVirtualPC(void)
|
||||
{
|
||||
#if defined(_WIN64)
|
||||
return FALSE; // MS Virtual PC is 32-bit only
|
||||
#else // _WIN32
|
||||
uint32 ebxval;
|
||||
|
||||
_asm {
|
||||
push ebx
|
||||
mov ebx, 0
|
||||
|
||||
mov eax, 1 // Virtual PC function number
|
||||
|
||||
// execute invalid opcode to call into MS Virtual PC
|
||||
|
||||
__emit 0Fh
|
||||
__emit 3Fh
|
||||
__emit 07h
|
||||
__emit 0Bh
|
||||
|
||||
mov ebxval, ebx
|
||||
pop ebx
|
||||
}
|
||||
return !ebxval; // ebx is zero if inside Virtual PC
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_NestingSupported --
|
||||
*
|
||||
* Access the backdoor with a nesting control query. This is used
|
||||
* to determine if we are running in a VM that supports nesting.
|
||||
* This function should only be called after determining that the
|
||||
* backdoor is present with Hostinfo_TouchBackdoor().
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the outer VM supports nesting.
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM, so don't do that!
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_NestingSupported(void)
|
||||
{
|
||||
uint32 cmd = NESTING_CONTROL_QUERY << 16 | BDOOR_CMD_NESTING_CONTROL;
|
||||
uint32 result;
|
||||
|
||||
#if defined(_WIN64)
|
||||
Backdoor_proto bp;
|
||||
|
||||
bp.in.ax.quad = BDOOR_MAGIC;
|
||||
bp.in.cx.quad = cmd;
|
||||
bp.in.dx.quad = BDOOR_PORT;
|
||||
|
||||
Hostinfo_BackdoorInOut(&bp);
|
||||
|
||||
result = bp.out.ax.words.low;
|
||||
#else
|
||||
_asm {
|
||||
push edx
|
||||
push ecx
|
||||
mov ecx, cmd
|
||||
mov eax, BDOOR_MAGIC
|
||||
mov dx, BDOOR_PORT
|
||||
in eax, dx
|
||||
mov result, eax
|
||||
pop ecx
|
||||
pop edx
|
||||
}
|
||||
#endif
|
||||
|
||||
if (result >= NESTING_CONTROL_QUERY && result != ~0U) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_VCPUInfoBackdoor --
|
||||
*
|
||||
* Access the backdoor with an VCPU info query. This is used to
|
||||
* determine whether a VCPU supports a particular feature,
|
||||
* determined by 'bit'. This function should only be called after
|
||||
* determining that the backdoor is present with
|
||||
* Hostinfo_TouchBackdoor().
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the outer VM supports the feature.
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM, so don't do that!
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_VCPUInfoBackdoor(unsigned bit)
|
||||
{
|
||||
uint32 cmd = BDOOR_CMD_GET_VCPU_INFO;
|
||||
uint32 result;
|
||||
|
||||
#if defined(_WIN64)
|
||||
Backdoor_proto bp;
|
||||
|
||||
bp.in.ax.quad = BDOOR_MAGIC;
|
||||
bp.in.cx.quad = cmd;
|
||||
bp.in.dx.quad = BDOOR_PORT;
|
||||
|
||||
Hostinfo_BackdoorInOut(&bp);
|
||||
|
||||
result = bp.out.ax.words.low;
|
||||
#else
|
||||
_asm {
|
||||
push edx
|
||||
push ecx
|
||||
mov ecx, cmd
|
||||
mov eax, BDOOR_MAGIC
|
||||
mov dx, BDOOR_PORT
|
||||
in eax, dx
|
||||
mov result, eax
|
||||
pop ecx
|
||||
pop edx
|
||||
}
|
||||
#endif
|
||||
/* If reserved bit is 1, this command wasn't implemented. */
|
||||
return (result & (1 << BDOOR_CMD_VCPU_RESERVED)) == 0 &&
|
||||
(result & (1 << bit)) != 0;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_TouchBackDoor --
|
||||
*
|
||||
* Access the backdoor. This is used to determine if we are
|
||||
* running in a VM or on a physical host. On a physical host
|
||||
* this should generate a GP which we catch and thereby determine
|
||||
* that we are not in a VM. However some OSes do not handle the
|
||||
* GP correctly and the process continues running returning garbage.
|
||||
* In this case we check the EBX register which should be
|
||||
* BDOOR_MAGIC if the IN was handled in a VM. Based on this we
|
||||
* return either TRUE or FALSE.
|
||||
*
|
||||
* Results:
|
||||
* TRUE if we succesfully accessed the backdoor, FALSE or segfault
|
||||
* if not.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_TouchBackDoor(void)
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
uint32 eax;
|
||||
uint32 ebx;
|
||||
uint32 ecx;
|
||||
|
||||
__asm__ __volatile__(
|
||||
# if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
|
||||
"xchgl %%ebx, %1" "\n\t"
|
||||
"inl %%dx, %%eax" "\n\t"
|
||||
"xchgl %%ebx, %1"
|
||||
: "=a" (eax),
|
||||
"=&rm" (ebx),
|
||||
# else
|
||||
"inl %%dx, %%eax"
|
||||
: "=a" (eax),
|
||||
"=b" (ebx),
|
||||
# endif
|
||||
"=c" (ecx)
|
||||
: "0" (BDOOR_MAGIC),
|
||||
"1" (~BDOOR_MAGIC),
|
||||
"2" (BDOOR_CMD_GETVERSION),
|
||||
"d" (BDOOR_PORT)
|
||||
);
|
||||
if (ebx == BDOOR_MAGIC) {
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_TouchVirtualPC --
|
||||
*
|
||||
* Access MS Virtual PC's backdoor. This is used to determine if
|
||||
* we are running in a MS Virtual PC or on a physical host. Works
|
||||
* the same as Hostinfo_TouchBackDoor, except the entry to MS VPC
|
||||
* is an invalid opcode instead or writing to a port. Since
|
||||
* MS VPC is 32-bit only, the 64-bit path returns FALSE.
|
||||
* See: http://www.codeproject.com/KB/system/VmDetect.aspx
|
||||
*
|
||||
* Results:
|
||||
* TRUE if we succesfully accessed MS Virtual PC, FALSE or
|
||||
* segfault if not.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_TouchVirtualPC(void)
|
||||
{
|
||||
#if defined vm_x86_64
|
||||
return FALSE;
|
||||
#else
|
||||
|
||||
uint32 ebxval;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
# if defined __PIC__ // %ebx is reserved by the compiler.
|
||||
"xchgl %%ebx, %1" "\n\t"
|
||||
".long 0x0B073F0F" "\n\t"
|
||||
"xchgl %%ebx, %1"
|
||||
: "=&rm" (ebxval)
|
||||
: "a" (1),
|
||||
"0" (0)
|
||||
# else
|
||||
".long 0x0B073F0F"
|
||||
: "=b" (ebxval)
|
||||
: "a" (1),
|
||||
"b" (0)
|
||||
# endif
|
||||
);
|
||||
return !ebxval; // %%ebx is zero if inside Virtual PC
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_NestingSupported --
|
||||
*
|
||||
* Access the backdoor with a nesting control query. This is used
|
||||
* to determine if we are running inside a VM that supports nesting.
|
||||
* This function should only be called after determining that the
|
||||
* backdoor is present with Hostinfo_TouchBackdoor().
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the outer VM supports nesting.
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM, so don't do that!
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_NestingSupported(void)
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
uint32 cmd = NESTING_CONTROL_QUERY << 16 | BDOOR_CMD_NESTING_CONTROL;
|
||||
uint32 result;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"inl %%dx, %%eax"
|
||||
: "=a" (result)
|
||||
: "0" (BDOOR_MAGIC),
|
||||
"c" (cmd),
|
||||
"d" (BDOOR_PORT)
|
||||
);
|
||||
|
||||
if (result >= NESTING_CONTROL_QUERY && result != ~0U) {
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Hostinfo_VCPUInfoBackdoor --
|
||||
*
|
||||
* Access the backdoor with an VCPU info query. This is used to
|
||||
* determine whether a VCPU supports a particular feature,
|
||||
* determined by 'bit'. This function should only be called after
|
||||
* determining that the backdoor is present with
|
||||
* Hostinfo_TouchBackdoor().
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the outer VM supports the feature.
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Exception if not in a VM, so don't do that!
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Hostinfo_VCPUInfoBackdoor(unsigned bit)
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
uint32 result;
|
||||
__asm__ __volatile__(
|
||||
"inl %%dx, %%eax"
|
||||
: "=a" (result)
|
||||
: "0" (BDOOR_MAGIC),
|
||||
"c" (BDOOR_CMD_GET_VCPU_INFO),
|
||||
"d" (BDOOR_PORT)
|
||||
);
|
||||
/* If reserved bit is 1, this command wasn't implemented. */
|
||||
return (result & (1 << BDOOR_CMD_VCPU_RESERVED)) == 0 &&
|
||||
(result & (1 << bit)) != 0;
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
605
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/message.c
generated
vendored
Normal file
605
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/message.c
generated
vendored
Normal file
@@ -0,0 +1,605 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1999-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*********************************************************
|
||||
* The contents of this file are subject to the terms of the Common
|
||||
* Development and Distribution License (the "License") version 1.0
|
||||
* and no later version. You may not use this file except in
|
||||
* compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the License at
|
||||
* http://www.opensource.org/licenses/cddl1.php
|
||||
*
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* message.c --
|
||||
*
|
||||
* Second layer of the internal communication channel between guest
|
||||
* applications and vmware
|
||||
*
|
||||
* Build a generic messaging system between guest applications and vmware.
|
||||
*
|
||||
* The protocol is not completely symmetrical, because:
|
||||
* . basic requests can only be sent by guest applications (when vmware
|
||||
* wants to post a message to a guest application, the message will be
|
||||
* really fetched only when the guest application will poll for new
|
||||
* available messages)
|
||||
* . several guest applications can talk to vmware, while the contrary is
|
||||
* not true
|
||||
*
|
||||
* Operations that are not atomic (in terms of number of backdoor calls)
|
||||
* can be aborted by vmware if a checkpoint/restore occurs in the middle of
|
||||
* such an operation. This layer takes care of retrying those operations.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__KERNEL__) || defined(_KERNEL) || defined(KERNEL)
|
||||
# include "kernelStubs.h"
|
||||
#else
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include "debug.h"
|
||||
#endif
|
||||
|
||||
#include "backdoor_def.h"
|
||||
#include "guest_msg_def.h"
|
||||
#include "backdoor.h"
|
||||
#include "message.h"
|
||||
|
||||
|
||||
#if defined(MESSAGE_DEBUG)
|
||||
# define MESSAGE_LOG(...) Warning(__VA_ARGS__)
|
||||
#else
|
||||
# define MESSAGE_LOG(...)
|
||||
#endif
|
||||
|
||||
/* The channel object */
|
||||
struct Message_Channel {
|
||||
/* Identifier */
|
||||
uint16 id;
|
||||
|
||||
/* Reception buffer */
|
||||
/* Data */
|
||||
unsigned char *in;
|
||||
/* Allocated size */
|
||||
size_t inAlloc;
|
||||
|
||||
/* The cookie */
|
||||
uint32 cookieHigh;
|
||||
uint32 cookieLow;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Message_Open --
|
||||
*
|
||||
* Open a communication channel
|
||||
*
|
||||
* Result:
|
||||
* An allocated Message_Channel on success
|
||||
* NULL on failure
|
||||
*
|
||||
* Side-effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Message_Channel *
|
||||
Message_Open(uint32 proto) // IN
|
||||
{
|
||||
Message_Channel *chan;
|
||||
uint32 flags;
|
||||
Backdoor_proto bp;
|
||||
|
||||
chan = (Message_Channel *)malloc(sizeof(*chan));
|
||||
if (chan == NULL) {
|
||||
goto error_quit;
|
||||
}
|
||||
|
||||
flags = GUESTMSG_FLAG_COOKIE;
|
||||
retry:
|
||||
/* IN: Type */
|
||||
bp.in.cx.halfs.high = MESSAGE_TYPE_OPEN;
|
||||
/* IN: Magic number of the protocol and flags */
|
||||
bp.in.size = proto | flags;
|
||||
|
||||
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
|
||||
Backdoor(&bp);
|
||||
|
||||
/* OUT: Status */
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
if (flags) {
|
||||
/* Cookies not supported. Fall back to no cookie. --hpreg */
|
||||
flags = 0;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
MESSAGE_LOG("Message: Unable to open a communication channel\n");
|
||||
goto error_quit;
|
||||
}
|
||||
|
||||
/* OUT: Id and cookie */
|
||||
chan->id = bp.in.dx.halfs.high;
|
||||
chan->cookieHigh = bp.out.si.word;
|
||||
chan->cookieLow = bp.out.di.word;
|
||||
|
||||
/* Initialize the channel */
|
||||
chan->in = NULL;
|
||||
chan->inAlloc = 0;
|
||||
|
||||
return chan;
|
||||
|
||||
error_quit:
|
||||
free(chan);
|
||||
chan = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Message_Send --
|
||||
*
|
||||
* Send a message over a communication channel
|
||||
*
|
||||
* Result:
|
||||
* TRUE on success
|
||||
* FALSE on failure (the message is discarded by vmware)
|
||||
*
|
||||
* Side-effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Message_Send(Message_Channel *chan, // IN/OUT
|
||||
const unsigned char *buf, // IN
|
||||
size_t bufSize) // IN
|
||||
{
|
||||
const unsigned char *myBuf;
|
||||
size_t myBufSize;
|
||||
Backdoor_proto bp;
|
||||
|
||||
retry:
|
||||
myBuf = buf;
|
||||
myBufSize = bufSize;
|
||||
|
||||
/*
|
||||
* Send the size.
|
||||
*/
|
||||
|
||||
/* IN: Type */
|
||||
bp.in.cx.halfs.high = MESSAGE_TYPE_SENDSIZE;
|
||||
/* IN: Id and cookie */
|
||||
bp.in.dx.halfs.high = chan->id;
|
||||
bp.in.si.word = chan->cookieHigh;
|
||||
bp.in.di.word = chan->cookieLow;
|
||||
/* IN: Size */
|
||||
bp.in.size = myBufSize;
|
||||
|
||||
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
|
||||
Backdoor(&bp);
|
||||
|
||||
/* OUT: Status */
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
MESSAGE_LOG("Message: Unable to send a message over the communication "
|
||||
"channel %u\n", chan->id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (bp.in.cx.halfs.high & MESSAGE_STATUS_HB) {
|
||||
/*
|
||||
* High-bandwidth backdoor port supported. Send the message in one
|
||||
* backdoor operation. --hpreg
|
||||
*/
|
||||
|
||||
if (myBufSize) {
|
||||
Backdoor_proto_hb bphb;
|
||||
|
||||
bphb.in.bx.halfs.low = BDOORHB_CMD_MESSAGE;
|
||||
bphb.in.bx.halfs.high = MESSAGE_STATUS_SUCCESS;
|
||||
bphb.in.dx.halfs.high = chan->id;
|
||||
bphb.in.bp.word = chan->cookieHigh;
|
||||
bphb.in.dstAddr = chan->cookieLow;
|
||||
bphb.in.size = myBufSize;
|
||||
bphb.in.srcAddr = (uintptr_t) myBuf;
|
||||
Backdoor_HbOut(&bphb);
|
||||
if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
|
||||
/* A checkpoint occurred. Retry the operation. --hpreg */
|
||||
goto retry;
|
||||
}
|
||||
|
||||
MESSAGE_LOG("Message: Unable to send a message over the "
|
||||
"communication channel %u\n", chan->id);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* High-bandwidth backdoor port not supported. Send the message, 4 bytes
|
||||
* at a time. --hpreg
|
||||
*/
|
||||
|
||||
for (;;) {
|
||||
if (myBufSize == 0) {
|
||||
/* We are done */
|
||||
break;
|
||||
}
|
||||
|
||||
/* IN: Type */
|
||||
bp.in.cx.halfs.high = MESSAGE_TYPE_SENDPAYLOAD;
|
||||
/* IN: Id and cookie */
|
||||
bp.in.dx.halfs.high = chan->id;
|
||||
bp.in.si.word = chan->cookieHigh;
|
||||
bp.in.di.word = chan->cookieLow;
|
||||
/* IN: Piece of message */
|
||||
/*
|
||||
* Beware in case we are not allowed to read extra bytes beyond the
|
||||
* end of the buffer.
|
||||
*/
|
||||
switch (myBufSize) {
|
||||
case 1:
|
||||
bp.in.size = myBuf[0];
|
||||
myBufSize -= 1;
|
||||
break;
|
||||
case 2:
|
||||
bp.in.size = myBuf[0] | myBuf[1] << 8;
|
||||
myBufSize -= 2;
|
||||
break;
|
||||
case 3:
|
||||
bp.in.size = myBuf[0] | myBuf[1] << 8 | myBuf[2] << 16;
|
||||
myBufSize -= 3;
|
||||
break;
|
||||
default:
|
||||
bp.in.size = *(const uint32 *)myBuf;
|
||||
myBufSize -= 4;
|
||||
break;
|
||||
}
|
||||
|
||||
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
|
||||
Backdoor(&bp);
|
||||
|
||||
/* OUT: Status */
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
|
||||
/* A checkpoint occurred. Retry the operation. --hpreg */
|
||||
goto retry;
|
||||
}
|
||||
|
||||
MESSAGE_LOG("Message: Unable to send a message over the "
|
||||
"communication channel %u\n", chan->id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
myBuf += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Message_Receive --
|
||||
*
|
||||
* If vmware has posted a message for this channel, retrieve it
|
||||
*
|
||||
* Result:
|
||||
* TRUE on success (bufSize is 0 if there is no message)
|
||||
* FALSE on failure
|
||||
*
|
||||
* Side-effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Message_Receive(Message_Channel *chan, // IN/OUT
|
||||
unsigned char **buf, // OUT
|
||||
size_t *bufSize) // OUT
|
||||
{
|
||||
Backdoor_proto bp;
|
||||
size_t myBufSize;
|
||||
unsigned char *myBuf;
|
||||
|
||||
retry:
|
||||
/*
|
||||
* Is there a message waiting for our retrieval?
|
||||
*/
|
||||
|
||||
/* IN: Type */
|
||||
bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSIZE;
|
||||
/* IN: Id and cookie */
|
||||
bp.in.dx.halfs.high = chan->id;
|
||||
bp.in.si.word = chan->cookieHigh;
|
||||
bp.in.di.word = chan->cookieLow;
|
||||
|
||||
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
|
||||
Backdoor(&bp);
|
||||
|
||||
/* OUT: Status */
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
MESSAGE_LOG("Message: Unable to poll for messages over the "
|
||||
"communication channel %u\n", chan->id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_DORECV) == 0) {
|
||||
/* No message to retrieve */
|
||||
*bufSize = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive the size.
|
||||
*/
|
||||
|
||||
/* OUT: Type */
|
||||
if (bp.in.dx.halfs.high != MESSAGE_TYPE_SENDSIZE) {
|
||||
MESSAGE_LOG("Message: Protocol error. Expected a "
|
||||
"MESSAGE_TYPE_SENDSIZE request from vmware\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* OUT: Size */
|
||||
myBufSize = bp.out.bx.word;
|
||||
|
||||
/*
|
||||
* Allocate an extra byte for a trailing NUL character. The code that will
|
||||
* deal with this message may not know about binary strings, and may expect
|
||||
* a C string instead. --hpreg
|
||||
*/
|
||||
if (myBufSize + 1 > chan->inAlloc) {
|
||||
myBuf = (unsigned char *)realloc(chan->in, myBufSize + 1);
|
||||
if (myBuf == NULL) {
|
||||
MESSAGE_LOG("Message: Not enough memory to receive a message over "
|
||||
"the communication channel %u\n", chan->id);
|
||||
goto error_quit;
|
||||
}
|
||||
|
||||
chan->in = myBuf;
|
||||
chan->inAlloc = myBufSize + 1;
|
||||
}
|
||||
*bufSize = myBufSize;
|
||||
myBuf = *buf = chan->in;
|
||||
|
||||
if (bp.in.cx.halfs.high & MESSAGE_STATUS_HB) {
|
||||
/*
|
||||
* High-bandwidth backdoor port supported. Receive the message in one
|
||||
* backdoor operation. --hpreg
|
||||
*/
|
||||
|
||||
if (myBufSize) {
|
||||
Backdoor_proto_hb bphb;
|
||||
|
||||
bphb.in.bx.halfs.low = BDOORHB_CMD_MESSAGE;
|
||||
bphb.in.bx.halfs.high = MESSAGE_STATUS_SUCCESS;
|
||||
bphb.in.dx.halfs.high = chan->id;
|
||||
bphb.in.srcAddr = chan->cookieHigh;
|
||||
bphb.in.bp.word = chan->cookieLow;
|
||||
bphb.in.size = myBufSize;
|
||||
bphb.in.dstAddr = (uintptr_t) myBuf;
|
||||
Backdoor_HbIn(&bphb);
|
||||
if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
|
||||
/* A checkpoint occurred. Retry the operation. --hpreg */
|
||||
goto retry;
|
||||
}
|
||||
|
||||
MESSAGE_LOG("Message: Unable to receive a message over the "
|
||||
"communication channel %u\n", chan->id);
|
||||
goto error_quit;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* High-bandwidth backdoor port not supported. Receive the message, 4
|
||||
* bytes at a time. --hpreg
|
||||
*/
|
||||
|
||||
for (;;) {
|
||||
if (myBufSize == 0) {
|
||||
/* We are done */
|
||||
break;
|
||||
}
|
||||
|
||||
/* IN: Type */
|
||||
bp.in.cx.halfs.high = MESSAGE_TYPE_RECVPAYLOAD;
|
||||
/* IN: Id and cookie */
|
||||
bp.in.dx.halfs.high = chan->id;
|
||||
bp.in.si.word = chan->cookieHigh;
|
||||
bp.in.di.word = chan->cookieLow;
|
||||
/* IN: Status for the previous request (that succeeded) */
|
||||
bp.in.size = MESSAGE_STATUS_SUCCESS;
|
||||
|
||||
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
|
||||
Backdoor(&bp);
|
||||
|
||||
/* OUT: Status */
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
|
||||
/* A checkpoint occurred. Retry the operation. --hpreg */
|
||||
goto retry;
|
||||
}
|
||||
|
||||
MESSAGE_LOG("Message: Unable to receive a message over the "
|
||||
"communication channel %u\n", chan->id);
|
||||
goto error_quit;
|
||||
}
|
||||
|
||||
/* OUT: Type */
|
||||
if (bp.in.dx.halfs.high != MESSAGE_TYPE_SENDPAYLOAD) {
|
||||
MESSAGE_LOG("Message: Protocol error. Expected a "
|
||||
"MESSAGE_TYPE_SENDPAYLOAD from vmware\n");
|
||||
goto error_quit;
|
||||
}
|
||||
|
||||
/* OUT: Piece of message */
|
||||
/*
|
||||
* Beware in case we are not allowed to write extra bytes beyond the
|
||||
* end of the buffer. --hpreg
|
||||
*/
|
||||
switch (myBufSize) {
|
||||
case 1:
|
||||
myBuf[0] = bp.out.bx.word & 0xff;
|
||||
myBufSize -= 1;
|
||||
break;
|
||||
case 2:
|
||||
myBuf[0] = bp.out.bx.word & 0xff;
|
||||
myBuf[1] = (bp.out.bx.word >> 8) & 0xff;
|
||||
myBufSize -= 2;
|
||||
break;
|
||||
case 3:
|
||||
myBuf[0] = bp.out.bx.word & 0xff;
|
||||
myBuf[1] = (bp.out.bx.word >> 8) & 0xff;
|
||||
myBuf[2] = (bp.out.bx.word >> 16) & 0xff;
|
||||
myBufSize -= 3;
|
||||
break;
|
||||
default:
|
||||
*(uint32 *)myBuf = bp.out.bx.word;
|
||||
myBufSize -= 4;
|
||||
break;
|
||||
}
|
||||
|
||||
myBuf += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write a trailing NUL just after the message. --hpreg */
|
||||
chan->in[*bufSize] = '\0';
|
||||
|
||||
/* IN: Type */
|
||||
bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSTATUS;
|
||||
/* IN: Id and cookie */
|
||||
bp.in.dx.halfs.high = chan->id;
|
||||
bp.in.si.word = chan->cookieHigh;
|
||||
bp.in.di.word = chan->cookieLow;
|
||||
/* IN: Status for the previous request (that succeeded) */
|
||||
bp.in.size = MESSAGE_STATUS_SUCCESS;
|
||||
|
||||
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
|
||||
Backdoor(&bp);
|
||||
|
||||
/* OUT: Status */
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
|
||||
/* A checkpoint occurred. Retry the operation. --hpreg */
|
||||
goto retry;
|
||||
}
|
||||
|
||||
MESSAGE_LOG("Message: Unable to receive a message over the "
|
||||
"communication channel %u\n", chan->id);
|
||||
goto error_quit;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
error_quit:
|
||||
/* IN: Type */
|
||||
if (myBufSize == 0) {
|
||||
bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSTATUS;
|
||||
} else {
|
||||
bp.in.cx.halfs.high = MESSAGE_TYPE_RECVPAYLOAD;
|
||||
}
|
||||
/* IN: Id and cookie */
|
||||
bp.in.dx.halfs.high = chan->id;
|
||||
bp.in.si.word = chan->cookieHigh;
|
||||
bp.in.di.word = chan->cookieLow;
|
||||
/* IN: Status for the previous request (that failed) */
|
||||
bp.in.size = 0;
|
||||
|
||||
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
|
||||
Backdoor(&bp);
|
||||
|
||||
/* OUT: Status */
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
MESSAGE_LOG("Message: Unable to signal an error of reception over the "
|
||||
"communication channel %u\n", chan->id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Message_Close --
|
||||
*
|
||||
* Close a communication channel
|
||||
*
|
||||
* Result:
|
||||
* TRUE on success, the channel is destroyed
|
||||
* FALSE on failure
|
||||
*
|
||||
* Side-effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
Message_Close(Message_Channel *chan) // IN/OUT
|
||||
{
|
||||
Backdoor_proto bp;
|
||||
Bool ret = TRUE;
|
||||
|
||||
/* IN: Type */
|
||||
bp.in.cx.halfs.high = MESSAGE_TYPE_CLOSE;
|
||||
/* IN: Id and cookie */
|
||||
bp.in.dx.halfs.high = chan->id;
|
||||
bp.in.si.word = chan->cookieHigh;
|
||||
bp.in.di.word = chan->cookieLow;
|
||||
|
||||
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
|
||||
Backdoor(&bp);
|
||||
|
||||
/* OUT: Status */
|
||||
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
MESSAGE_LOG("Message: Unable to close the communication channel %u\n",
|
||||
chan->id);
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
free(chan->in);
|
||||
chan->in = NULL;
|
||||
|
||||
free(chan);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
416
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/utilMem.c
generated
vendored
Normal file
416
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/utilMem.c
generated
vendored
Normal file
@@ -0,0 +1,416 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2009-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* utilMem.c --
|
||||
*
|
||||
* misc util functions
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "vm_assert.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#if !defined TARGET_OS_IPHONE
|
||||
#define TARGET_OS_IPHONE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static NORETURN void UtilAllocationFailure0(void);
|
||||
static NORETURN void UtilAllocationFailure1(int bugNumber,
|
||||
const char *file, int lineno);
|
||||
|
||||
|
||||
static void
|
||||
UtilAllocationFailure0(void)
|
||||
{
|
||||
Panic("Unrecoverable memory allocation failure\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
UtilAllocationFailure1(int bugNumber, const char *file, int lineno)
|
||||
{
|
||||
if (bugNumber == -1) {
|
||||
Panic("Unrecoverable memory allocation failure at %s:%d\n",
|
||||
file, lineno);
|
||||
} else {
|
||||
Panic("Unrecoverable memory allocation failure at %s:%d. Bug "
|
||||
"number: %d\n", file, lineno, bugNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* UtilSafeMalloc0 --
|
||||
* UtilSafeMalloc1 --
|
||||
* Helper function for malloc
|
||||
*
|
||||
* Results:
|
||||
* Pointer to the dynamically allocated memory.
|
||||
*
|
||||
* Side effects:
|
||||
* May Panic if ran out of memory.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void *
|
||||
UtilSafeMalloc0(size_t size) // IN:
|
||||
{
|
||||
void *result = malloc(size);
|
||||
if (result == NULL && size != 0) {
|
||||
UtilAllocationFailure0();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
UtilSafeMalloc1(size_t size, // IN:
|
||||
int bugNumber, // IN:
|
||||
const char *file, // IN:
|
||||
int lineno) // IN:
|
||||
{
|
||||
void *result = malloc(size);
|
||||
if (result == NULL && size != 0) {
|
||||
UtilAllocationFailure1(bugNumber, file, lineno);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* UtilSafeRealloc0 --
|
||||
* UtilSafeRealloc1 --
|
||||
* Helper function for realloc
|
||||
*
|
||||
* Results:
|
||||
* Pointer to the dynamically allocated memory.
|
||||
*
|
||||
* Side effects:
|
||||
* May Panic if ran out of memory.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void *
|
||||
UtilSafeRealloc0(void *ptr, // IN:
|
||||
size_t size) // IN:
|
||||
{
|
||||
void *result = realloc(ptr, size);
|
||||
if (result == NULL && size != 0) {
|
||||
UtilAllocationFailure0();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
UtilSafeRealloc1(void *ptr, // IN:
|
||||
size_t size, // IN:
|
||||
int bugNumber, // IN:
|
||||
const char *file, // IN:
|
||||
int lineno) // IN:
|
||||
{
|
||||
void *result = realloc(ptr, size);
|
||||
if (result == NULL && size != 0) {
|
||||
UtilAllocationFailure1(bugNumber, file, lineno);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* UtilSafeCalloc0 --
|
||||
* UtilSafeCalloc1 --
|
||||
* Helper function for calloc
|
||||
*
|
||||
* Results:
|
||||
* Pointer to the dynamically allocated memory.
|
||||
*
|
||||
* Side effects:
|
||||
* May Panic if ran out of memory.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void *
|
||||
UtilSafeCalloc0(size_t nmemb, // IN:
|
||||
size_t size) // IN:
|
||||
{
|
||||
void *result = calloc(nmemb, size);
|
||||
if (result == NULL && nmemb != 0 && size != 0) {
|
||||
UtilAllocationFailure0();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
UtilSafeCalloc1(size_t nmemb, // IN:
|
||||
size_t size, // IN:
|
||||
int bugNumber, // IN:
|
||||
const char *file, // IN:
|
||||
int lineno) // IN:
|
||||
{
|
||||
void *result = calloc(nmemb, size);
|
||||
if (result == NULL && nmemb != 0 && size != 0) {
|
||||
UtilAllocationFailure1(bugNumber, file, lineno);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Util_SafeStrdup --
|
||||
* Helper function for strdup
|
||||
*
|
||||
* Results:
|
||||
* Pointer to the dynamically allocated, duplicate string
|
||||
*
|
||||
* Side effects:
|
||||
* May Panic if ran out of memory.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
UtilSafeStrdup0(const char *s) // IN:
|
||||
{
|
||||
char *result;
|
||||
if (s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
if ((result = _strdup(s)) == NULL) {
|
||||
#else
|
||||
if ((result = strdup(s)) == NULL) {
|
||||
#endif
|
||||
UtilAllocationFailure0();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
UtilSafeStrdup1(const char *s, // IN:
|
||||
int bugNumber, // IN:
|
||||
const char *file, // IN:
|
||||
int lineno) // IN:
|
||||
{
|
||||
char *result;
|
||||
if (s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
if ((result = _strdup(s)) == NULL) {
|
||||
#else
|
||||
if ((result = strdup(s)) == NULL) {
|
||||
#endif
|
||||
UtilAllocationFailure1(bugNumber, file, lineno);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Util_SafeStrndup --
|
||||
*
|
||||
* Returns a string consisting of first n characters of 's' if 's' has
|
||||
* length >= 'n', otherwise returns a string duplicate of 's'.
|
||||
*
|
||||
* Results:
|
||||
* Pointer to the duplicated string.
|
||||
*
|
||||
* Side effects:
|
||||
* May Panic if ran out of memory.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
UtilSafeStrndup0(const char *s, // IN:
|
||||
size_t n) // IN:
|
||||
{
|
||||
size_t size;
|
||||
char *copy;
|
||||
const char *null;
|
||||
size_t newSize;
|
||||
|
||||
if (s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
null = memchr(s, '\0', n);
|
||||
size = null ? (size_t)(null - s) : n;
|
||||
newSize = size + 1;
|
||||
if (newSize < size) { // Prevent integer overflow
|
||||
copy = NULL;
|
||||
} else {
|
||||
copy = malloc(newSize);
|
||||
}
|
||||
|
||||
if (copy == NULL) {
|
||||
UtilAllocationFailure0();
|
||||
}
|
||||
|
||||
copy[size] = '\0';
|
||||
|
||||
return (char *) memcpy(copy, s, size);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
UtilSafeStrndup1(const char *s, // IN:
|
||||
size_t n, // IN:
|
||||
int bugNumber, // IN:
|
||||
const char *file, // IN:
|
||||
int lineno) // IN:
|
||||
{
|
||||
size_t size;
|
||||
char *copy;
|
||||
const char *null;
|
||||
size_t newSize;
|
||||
|
||||
if (s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
null = memchr(s, '\0', n);
|
||||
size = null ? (size_t)(null - s) : n;
|
||||
newSize = size + 1;
|
||||
if (newSize < size) { // Prevent integer overflow
|
||||
copy = NULL;
|
||||
} else {
|
||||
copy = malloc(newSize);
|
||||
}
|
||||
|
||||
if (copy == NULL) {
|
||||
UtilAllocationFailure1(bugNumber, file, lineno);
|
||||
}
|
||||
|
||||
copy[size] = '\0';
|
||||
|
||||
return (char *) memcpy(copy, s, size);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
Util_Memcpy(void *dest,
|
||||
const void *src,
|
||||
size_t count)
|
||||
{
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
uintptr_t align = ((uintptr_t)dest | (uintptr_t)src | count);
|
||||
|
||||
#if defined __GNUC__
|
||||
|
||||
#if defined(__x86_64__)
|
||||
|
||||
size_t dummy0;
|
||||
void *dummy1;
|
||||
void *dummy2;
|
||||
|
||||
if ((align & 7) == 0) {
|
||||
__asm__ __volatile__("\t"
|
||||
"cld" "\n\t"
|
||||
"rep ; movsq" "\n"
|
||||
: "=c" (dummy0), "=D" (dummy1), "=S" (dummy2)
|
||||
: "0" (count >> 3), "1" (dest), "2" (src)
|
||||
: "memory", "cc"
|
||||
);
|
||||
return dest;
|
||||
} else if ((align & 3) == 0) {
|
||||
__asm__ __volatile__("\t"
|
||||
"cld" "\n\t"
|
||||
"rep ; movsd" "\n"
|
||||
: "=c" (dummy0), "=D" (dummy1), "=S" (dummy2)
|
||||
: "0" (count >> 2), "1" (dest), "2" (src)
|
||||
: "memory", "cc"
|
||||
);
|
||||
return dest;
|
||||
}
|
||||
|
||||
#elif defined(__i386__)
|
||||
|
||||
size_t dummy0;
|
||||
void *dummy1;
|
||||
void *dummy2;
|
||||
|
||||
if ((align & 3) == 0) {
|
||||
__asm__ __volatile__("\t"
|
||||
"cld" "\n\t"
|
||||
"rep ; movsd" "\n"
|
||||
: "=c" (dummy0), "=D" (dummy1), "=S" (dummy2)
|
||||
: "0" (count >> 2), "1" (dest), "2" (src)
|
||||
: "memory", "cc"
|
||||
);
|
||||
return dest;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined _MSC_VER
|
||||
|
||||
#if defined(__x86_64__)
|
||||
|
||||
if ((align & 7) == 0) {
|
||||
__movsq((uint64 *)dest, (uint64 *)src, count >> 3);
|
||||
return dest;
|
||||
} else if ((align & 3) == 0) {
|
||||
__movsd((unsigned long *)dest, (unsigned long *)src, count >> 2);
|
||||
return dest;
|
||||
}
|
||||
|
||||
#elif defined(__i386__)
|
||||
|
||||
if ((((uintptr_t)dest | (uintptr_t)src | count) & 3) == 0) {
|
||||
__movsd((unsigned long *)dest, (unsigned long *)src, count >> 2);
|
||||
return dest;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
memcpy(dest, src, count);
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
300
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/vmcheck.c
generated
vendored
Normal file
300
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/vmcheck.c
generated
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* vmcheck.c --
|
||||
*
|
||||
* Utility functions for discovering our virtualization status.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WINNT_DDK
|
||||
# include <ntddk.h>
|
||||
#endif
|
||||
|
||||
#include "vmware.h"
|
||||
/*
|
||||
* #include "vm_version.h"
|
||||
* #include "vm_tools_version.h"
|
||||
*/
|
||||
#define VMX_TYPE_UNSET 0
|
||||
#define VERSION_MAGIC 0x6
|
||||
|
||||
#if !defined(WINNT_DDK)
|
||||
# include "hostinfo.h"
|
||||
/* # include "str.h" */
|
||||
# define Str_Strcmp(s1, s2) strcmp(s1, s2)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* backdoor.h includes some files which redefine constants in ntddk.h. Ignore
|
||||
* warnings about these redefinitions for WIN32 platform.
|
||||
*/
|
||||
#ifdef WINNT_DDK
|
||||
#pragma warning (push)
|
||||
// Warning: Conditional expression is constant.
|
||||
#pragma warning( disable:4127 )
|
||||
#endif
|
||||
|
||||
#include "backdoor.h"
|
||||
|
||||
#ifdef WINNT_DDK
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#include "backdoor_def.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
typedef Bool (*SafeCheckFn)(void);
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# include "vmsignal.h"
|
||||
# include "setjmp.h"
|
||||
|
||||
static sigjmp_buf jmpBuf;
|
||||
static Bool jmpIsSet;
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* VmCheckSegvHandler --
|
||||
*
|
||||
* Signal handler for segv. Return to the program state saved
|
||||
* by a previous call to sigsetjmp, or Panic if sigsetjmp hasn't
|
||||
* been called yet. This function never returns;
|
||||
*
|
||||
* Return Value:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* See the manpage for sigsetjmp for details.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
VmCheckSegvHandler(int clientData) // UNUSED
|
||||
{
|
||||
if (jmpIsSet) {
|
||||
siglongjmp(jmpBuf, 1);
|
||||
} else {
|
||||
Panic("Received SEGV, exiting.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* VmCheckSafe --
|
||||
*
|
||||
* Calls a potentially unsafe function, trapping possible exceptions.
|
||||
*
|
||||
* Results:
|
||||
*
|
||||
* Return value of the passed function, or FALSE in case of exception.
|
||||
*
|
||||
* Side effects:
|
||||
*
|
||||
* Temporarily suppresses signals / SEH exceptions
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static Bool
|
||||
VmCheckSafe(SafeCheckFn checkFn)
|
||||
{
|
||||
Bool result = FALSE;
|
||||
|
||||
/*
|
||||
* On a real host this call should cause a GP and we catch
|
||||
* that and set result to FALSE.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32)
|
||||
__try {
|
||||
result = checkFn();
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
/* no op */
|
||||
}
|
||||
#else
|
||||
do {
|
||||
int signals[] = {
|
||||
SIGILL,
|
||||
SIGSEGV,
|
||||
};
|
||||
struct sigaction olds[ARRAYSIZE(signals)];
|
||||
|
||||
if (Signal_SetGroupHandler(signals, olds, ARRAYSIZE(signals),
|
||||
VmCheckSegvHandler) == 0) {
|
||||
Warning("%s: Failed to set signal handlers.\n", __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
|
||||
if (sigsetjmp(jmpBuf, TRUE) == 0) {
|
||||
jmpIsSet = TRUE;
|
||||
result = checkFn();
|
||||
} else {
|
||||
jmpIsSet = FALSE;
|
||||
}
|
||||
|
||||
if (Signal_ResetGroupHandler(signals, olds, ARRAYSIZE(signals)) == 0) {
|
||||
Warning("%s: Failed to reset signal handlers.\n", __FUNCTION__);
|
||||
}
|
||||
} while (0);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* VmCheck_GetVersion --
|
||||
*
|
||||
* Retrieve the version of VMware that's running on the
|
||||
* other side of the backdoor.
|
||||
*
|
||||
* Return value:
|
||||
* TRUE on success
|
||||
* *version contains the VMX version
|
||||
* *type contains the VMX type
|
||||
* FALSE on failure
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
VmCheck_GetVersion(uint32 *version, // OUT
|
||||
uint32 *type) // OUT
|
||||
{
|
||||
Backdoor_proto bp;
|
||||
|
||||
ASSERT(version);
|
||||
ASSERT(type);
|
||||
|
||||
/* Make sure EBX does not contain BDOOR_MAGIC */
|
||||
bp.in.size = ~BDOOR_MAGIC;
|
||||
/* Make sure ECX does not contain any known VMX type */
|
||||
bp.in.cx.halfs.high = 0xFFFF;
|
||||
|
||||
bp.in.cx.halfs.low = BDOOR_CMD_GETVERSION;
|
||||
Backdoor(&bp);
|
||||
if (bp.out.ax.word == 0xFFFFFFFF) {
|
||||
/*
|
||||
* No backdoor device there. This code is not executing in a VMware
|
||||
* virtual machine. --hpreg
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (bp.out.bx.word != BDOOR_MAGIC) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*version = bp.out.ax.word;
|
||||
|
||||
/*
|
||||
* Old VMXs (workstation and express) didn't set their type. In that case,
|
||||
* our special pattern will still be there. --hpreg
|
||||
*/
|
||||
|
||||
/*
|
||||
* Need to expand this out since the toolchain's gcc doesn't like mixing
|
||||
* integral types and enums in the same trinary operator.
|
||||
*/
|
||||
if (bp.in.cx.halfs.high == 0xFFFF)
|
||||
*type = VMX_TYPE_UNSET;
|
||||
else
|
||||
*type = bp.out.cx.word;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* VmCheck_IsVirtualWorld --
|
||||
*
|
||||
* Verify that we're running in a VM & we're version compatible with our
|
||||
* environment.
|
||||
*
|
||||
* Return value:
|
||||
* TRUE if we're in a virtual machine, FALSE otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
VmCheck_IsVirtualWorld(void)
|
||||
{
|
||||
uint32 version;
|
||||
uint32 dummy;
|
||||
|
||||
#if !defined(WINNT_DDK)
|
||||
if (VmCheckSafe(Hostinfo_TouchXen)) {
|
||||
Debug("%s: detected Xen.\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (VmCheckSafe(Hostinfo_TouchVirtualPC)) {
|
||||
Debug("%s: detected Virtual PC.\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!VmCheckSafe(Hostinfo_TouchBackDoor)) {
|
||||
Debug("%s: backdoor not detected.\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* It should be safe to use the backdoor without a crash handler now. */
|
||||
VmCheck_GetVersion(&version, &dummy);
|
||||
#else
|
||||
/*
|
||||
* The Win32 vmwvaudio driver uses this function, so keep the old,
|
||||
* VMware-only check.
|
||||
*/
|
||||
__try {
|
||||
VmCheck_GetVersion(&version, &dummy);
|
||||
} __except (GetExceptionCode() == STATUS_PRIVILEGED_INSTRUCTION) {
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (version != VERSION_MAGIC) {
|
||||
Debug("The version of this program is incompatible with your platform.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
123
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/vmsignal.c
generated
vendored
Normal file
123
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/bridge/vmsignal.c
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* vmsignal.c --
|
||||
*
|
||||
* Posix signal handling utility functions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef VMX86_DEVEL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "vmsignal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Signal_SetGroupHandler --
|
||||
*
|
||||
* Set a signal handler for a group of signals.
|
||||
* We carefully ensure that if the handler is only used to handle the
|
||||
* signals of the group, the handling of all the signals of the group is
|
||||
* serialized, which means that the handler is not re-entrant.
|
||||
*
|
||||
* Return value:
|
||||
* 1 on success
|
||||
* 0 on failure (detail is displayed)
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
Signal_SetGroupHandler(int const *signals, // IN
|
||||
struct sigaction *olds, // OUT
|
||||
unsigned int nr, // IN
|
||||
void (*handler)(int signal)) // IN
|
||||
{
|
||||
unsigned int i;
|
||||
struct sigaction new;
|
||||
|
||||
new.sa_handler = handler;
|
||||
if (sigemptyset(&new.sa_mask)) {
|
||||
fprintf(stderr, "Unable to empty a signal set: %s.\n\n", strerror(errno));
|
||||
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (sigaddset(&new.sa_mask, signals[i])) {
|
||||
fprintf(stderr, "Unable to add a signal to a signal set: %s.\n\n", strerror(errno));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
new.sa_flags = 0;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (sigaction(signals[i], &new, &olds[i])) {
|
||||
fprintf(stderr, "Unable to modify the handler of the signal %d: %s.\n\n", signals[i], strerror(errno));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Signal_ResetGroupHandler --
|
||||
*
|
||||
* Reset the handler of each signal of a group of signals
|
||||
*
|
||||
* Return value:
|
||||
* 1 on success
|
||||
* 0 on failure (detail is displayed)
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
Signal_ResetGroupHandler(int const *signals, // IN
|
||||
struct sigaction const *olds, // IN
|
||||
unsigned int nr) // IN
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (sigaction(signals[i], &olds[i], NULL)) {
|
||||
fprintf(stderr, "Unable to reset the handler of the signal %d: %s.\n\n", signals[i], strerror(errno));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
22
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/examples/main.go
generated
vendored
Normal file
22
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/examples/main.go
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/rpcvmx"
|
||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/vmcheck"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if !vmcheck.IsVirtualWorld() {
|
||||
fmt.Println("not in a virtual world... :(")
|
||||
return
|
||||
}
|
||||
|
||||
version, typ := vmcheck.GetVersion()
|
||||
fmt.Println(version, typ)
|
||||
|
||||
config := rpcvmx.NewConfig()
|
||||
fmt.Println(config.GetString("foo", "foo"))
|
||||
fmt.Println(config.GetString("bar", "foo"))
|
||||
}
|
60
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/include/backdoor.h
generated
vendored
Normal file
60
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/include/backdoor.h
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1999-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*********************************************************
|
||||
* The contents of this file are subject to the terms of the Common
|
||||
* Development and Distribution License (the "License") version 1.0
|
||||
* and no later version. You may not use this file except in
|
||||
* compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the License at
|
||||
* http://www.opensource.org/licenses/cddl1.php
|
||||
*
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* backdoor.h --
|
||||
*
|
||||
* First layer of the internal communication channel between guest
|
||||
* applications and vmware
|
||||
*/
|
||||
|
||||
#ifndef _BACKDOOR_H_
|
||||
#define _BACKDOOR_H_
|
||||
|
||||
#include "vm_basic_types.h"
|
||||
#include "vm_assert.h"
|
||||
|
||||
#include "backdoor_types.h"
|
||||
|
||||
void
|
||||
Backdoor(Backdoor_proto *bp); // IN/OUT
|
||||
|
||||
void
|
||||
Backdoor_InOut(Backdoor_proto *bp); // IN/OUT
|
||||
|
||||
void
|
||||
Backdoor_HbOut(Backdoor_proto_hb *bp); // IN/OUT
|
||||
|
||||
void
|
||||
Backdoor_HbIn(Backdoor_proto_hb *bp); // IN/OUT
|
||||
|
||||
#endif /* _BACKDOOR_H_ */
|
40
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/include/backdoorInt.h
generated
vendored
Normal file
40
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/include/backdoorInt.h
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2005-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*********************************************************
|
||||
* The contents of this file are subject to the terms of the Common
|
||||
* Development and Distribution License (the "License") version 1.0
|
||||
* and no later version. You may not use this file except in
|
||||
* compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the License at
|
||||
* http://www.opensource.org/licenses/cddl1.php
|
||||
*
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* backdoorInt.h --
|
||||
*
|
||||
* Internal function prototypes for the real backdoor work.
|
||||
*/
|
||||
|
||||
void BackdoorHbIn(Backdoor_proto_hb *bp);
|
||||
void BackdoorHbOut(Backdoor_proto_hb *bp);
|
261
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/include/backdoor_def.h
generated
vendored
Normal file
261
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/include/backdoor_def.h
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*********************************************************
|
||||
* The contents of this file are subject to the terms of the Common
|
||||
* Development and Distribution License (the "License") version 1.0
|
||||
* and no later version. You may not use this file except in
|
||||
* compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the License at
|
||||
* http://www.opensource.org/licenses/cddl1.php
|
||||
*
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* backdoor_def.h --
|
||||
*
|
||||
* This contains backdoor defines that can be included from
|
||||
* an assembly language file.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _BACKDOOR_DEF_H_
|
||||
#define _BACKDOOR_DEF_H_
|
||||
|
||||
/*
|
||||
* If you want to add a new low-level backdoor call for a guest userland
|
||||
* application, please consider using the GuestRpc mechanism instead. --hpreg
|
||||
*/
|
||||
|
||||
#define BDOOR_MAGIC 0x564D5868
|
||||
|
||||
/* Low-bandwidth backdoor port. --hpreg */
|
||||
|
||||
#define BDOOR_PORT 0x5658
|
||||
|
||||
#define BDOOR_CMD_GETMHZ 1
|
||||
/*
|
||||
* BDOOR_CMD_APMFUNCTION is used by:
|
||||
*
|
||||
* o The FrobOS code, which instead should either program the virtual chipset
|
||||
* (like the new BIOS code does, matthias offered to implement that), or not
|
||||
* use any VM-specific code (which requires that we correctly implement
|
||||
* "power off on CLI HLT" for SMP VMs, boris offered to implement that)
|
||||
*
|
||||
* o The old BIOS code, which will soon be jettisoned
|
||||
*
|
||||
* --hpreg
|
||||
*/
|
||||
#define BDOOR_CMD_APMFUNCTION 2 /* CPL0 only. */
|
||||
#define BDOOR_CMD_GETDISKGEO 3
|
||||
#define BDOOR_CMD_GETPTRLOCATION 4
|
||||
#define BDOOR_CMD_SETPTRLOCATION 5
|
||||
#define BDOOR_CMD_GETSELLENGTH 6
|
||||
#define BDOOR_CMD_GETNEXTPIECE 7
|
||||
#define BDOOR_CMD_SETSELLENGTH 8
|
||||
#define BDOOR_CMD_SETNEXTPIECE 9
|
||||
#define BDOOR_CMD_GETVERSION 10
|
||||
#define BDOOR_CMD_GETDEVICELISTELEMENT 11
|
||||
#define BDOOR_CMD_TOGGLEDEVICE 12
|
||||
#define BDOOR_CMD_GETGUIOPTIONS 13
|
||||
#define BDOOR_CMD_SETGUIOPTIONS 14
|
||||
#define BDOOR_CMD_GETSCREENSIZE 15
|
||||
#define BDOOR_CMD_MONITOR_CONTROL 16 /* Disabled by default. */
|
||||
#define BDOOR_CMD_GETHWVERSION 17
|
||||
#define BDOOR_CMD_OSNOTFOUND 18 /* CPL0 only. */
|
||||
#define BDOOR_CMD_GETUUID 19
|
||||
#define BDOOR_CMD_GETMEMSIZE 20
|
||||
#define BDOOR_CMD_HOSTCOPY 21 /* Devel only. */
|
||||
//#define BDOOR_CMD_SERVICE_VM 22 /* Not in use. Never shipped. */
|
||||
#define BDOOR_CMD_GETTIME 23 /* Deprecated -> GETTIMEFULL. */
|
||||
#define BDOOR_CMD_STOPCATCHUP 24
|
||||
#define BDOOR_CMD_PUTCHR 25 /* Disabled by default. */
|
||||
#define BDOOR_CMD_ENABLE_MSG 26 /* Devel only. */
|
||||
#define BDOOR_CMD_GOTO_TCL 27 /* Devel only. */
|
||||
#define BDOOR_CMD_INITPCIOPROM 28 /* CPL 0 only. */
|
||||
//#define BDOOR_CMD_INT13 29 /* Not in use. */
|
||||
#define BDOOR_CMD_MESSAGE 30
|
||||
#define BDOOR_CMD_SIDT 31
|
||||
#define BDOOR_CMD_SGDT 32
|
||||
#define BDOOR_CMD_SLDT_STR 33
|
||||
#define BDOOR_CMD_ISACPIDISABLED 34
|
||||
//#define BDOOR_CMD_TOE 35 /* Not in use. */
|
||||
#define BDOOR_CMD_ISMOUSEABSOLUTE 36
|
||||
#define BDOOR_CMD_PATCH_SMBIOS_STRUCTS 37 /* CPL 0 only. */
|
||||
#define BDOOR_CMD_MAPMEM 38 /* Devel only */
|
||||
#define BDOOR_CMD_ABSPOINTER_DATA 39
|
||||
#define BDOOR_CMD_ABSPOINTER_STATUS 40
|
||||
#define BDOOR_CMD_ABSPOINTER_COMMAND 41
|
||||
//#define BDOOR_CMD_TIMER_SPONGE 42 /* Not in use. */
|
||||
#define BDOOR_CMD_PATCH_ACPI_TABLES 43 /* CPL 0 only. */
|
||||
//#define BDOOR_CMD_DEVEL_FAKEHARDWARE 44 /* Not in use. */
|
||||
#define BDOOR_CMD_GETHZ 45
|
||||
#define BDOOR_CMD_GETTIMEFULL 46
|
||||
#define BDOOR_CMD_STATELOGGER 47 /* Disabled by default. */
|
||||
#define BDOOR_CMD_CHECKFORCEBIOSSETUP 48 /* CPL 0 only. */
|
||||
#define BDOOR_CMD_LAZYTIMEREMULATION 49 /* CPL 0 only. */
|
||||
#define BDOOR_CMD_BIOSBBS 50 /* CPL 0 only. */
|
||||
//#define BDOOR_CMD_VASSERT 51 /* Not in use. */
|
||||
#define BDOOR_CMD_ISGOSDARWIN 52
|
||||
#define BDOOR_CMD_DEBUGEVENT 53
|
||||
#define BDOOR_CMD_OSNOTMACOSXSERVER 54 /* CPL 0 only. */
|
||||
#define BDOOR_CMD_GETTIMEFULL_WITH_LAG 55
|
||||
#define BDOOR_CMD_ACPI_HOTPLUG_DEVICE 56 /* Devel only. */
|
||||
#define BDOOR_CMD_ACPI_HOTPLUG_MEMORY 57 /* Devel only. */
|
||||
#define BDOOR_CMD_ACPI_HOTPLUG_CBRET 58 /* Devel only. */
|
||||
//#define BDOOR_CMD_GET_HOST_VIDEO_MODES 59 /* Not in use. */
|
||||
#define BDOOR_CMD_ACPI_HOTPLUG_CPU 60 /* Devel only. */
|
||||
//#define BDOOR_CMD_USB_HOTPLUG_MOUSE 61 /* Not in use. Never shipped. */
|
||||
#define BDOOR_CMD_XPMODE 62 /* CPL 0 only. */
|
||||
#define BDOOR_CMD_NESTING_CONTROL 63
|
||||
#define BDOOR_CMD_FIRMWARE_INIT 64 /* CPL 0 only. */
|
||||
#define BDOOR_CMD_FIRMWARE_ACPI_SERVICES 65 /* CPL 0 only. */
|
||||
# define BDOOR_CMD_FAS_GET_TABLE_SIZE 0
|
||||
# define BDOOR_CMD_FAS_GET_TABLE_DATA 1
|
||||
# define BDOOR_CMD_FAS_GET_PLATFORM_NAME 2
|
||||
# define BDOOR_CMD_FAS_GET_PCIE_OSC_MASK 3
|
||||
# define BDOOR_CMD_FAS_GET_APIC_ROUTING 4
|
||||
# define BDOOR_CMD_FAS_GET_TABLE_SKIP 5
|
||||
# define BDOOR_CMD_FAS_GET_SLEEP_ENABLES 6
|
||||
# define BDOOR_CMD_FAS_GET_HARD_RESET_ENABLE 7
|
||||
#define BDOOR_CMD_SENDPSHAREHINTS 66
|
||||
#define BDOOR_CMD_ENABLE_USB_MOUSE 67
|
||||
#define BDOOR_CMD_GET_VCPU_INFO 68
|
||||
# define BDOOR_CMD_VCPU_SLC64 0
|
||||
# define BDOOR_CMD_VCPU_SYNC_VTSCS 1
|
||||
# define BDOOR_CMD_VCPU_HV_REPLAY_OK 2
|
||||
# define BDOOR_CMD_VCPU_LEGACY_X2APIC_OK 3
|
||||
# define BDOOR_CMD_VCPU_RESERVED 31
|
||||
#define BDOOR_CMD_EFI_SERIALCON_CONFIG 69 /* CPL 0 only. */
|
||||
#define BDOOR_CMD_BUG328986 70 /* CPL 0 only. */
|
||||
#define BDOOR_CMD_FIRMWARE_ERROR 71 /* CPL 0 only. */
|
||||
# define BDOOR_CMD_FE_INSUFFICIENT_MEM 0
|
||||
# define BDOOR_CMD_FE_EXCEPTION 1
|
||||
#define BDOOR_CMD_VMK_INFO 72
|
||||
#define BDOOR_CMD_EFI_BOOT_CONFIG 73 /* CPL 0 only. */
|
||||
# define BDOOR_CMD_EBC_LEGACYBOOT_ENABLED 0
|
||||
# define BDOOR_CMD_EBC_GET_ORDER 1
|
||||
# define BDOOR_CMD_EBC_SHELL_ACTIVE 2
|
||||
# define BDOOR_CMD_EBC_GET_NETWORK_BOOT_PROTOCOL 3
|
||||
#define BDOOR_CMD_GET_HW_MODEL 74 /* CPL 0 only. */
|
||||
#define BDOOR_CMD_GET_SVGA_CAPABILITIES 75 /* CPL 0 only. */
|
||||
#define BDOOR_CMD_GET_FORCE_X2APIC 76 /* CPL 0 only */
|
||||
#define BDOOR_CMD_SET_PCI_HOLE 77 /* CPL 0 only */
|
||||
#define BDOOR_CMD_GET_PCI_HOLE 78 /* CPL 0 only */
|
||||
#define BDOOR_CMD_GET_PCI_BAR 79 /* CPL 0 only */
|
||||
#define BDOOR_CMD_SHOULD_GENERATE_SYSTEMID 80 /* CPL 0 only */
|
||||
#define BDOOR_CMD_READ_DEBUG_FILE 81 /* Devel only. */
|
||||
#define BDOOR_CMD_MAX 82
|
||||
|
||||
|
||||
/*
|
||||
* IMPORTANT NOTE: When modifying the behavior of an existing backdoor command,
|
||||
* you must adhere to the semantics expected by the oldest Tools who use that
|
||||
* command. Specifically, do not alter the way in which the command modifies
|
||||
* the registers. Otherwise backwards compatibility will suffer.
|
||||
*/
|
||||
|
||||
/* Processing mode for guest pshare hints (SENDPSHAREHINTS cmd) */
|
||||
#define BDOOR_PSHARE_HINTS_ASYNC 0
|
||||
#define BDOOR_PSHARE_HINTS_SYNC 1
|
||||
|
||||
#define BDOOR_PSHARE_HINTS_TYPE(ecx) (((ecx) >> 16) & 0x1)
|
||||
|
||||
/* Version of backdoor pshare hints protocol */
|
||||
#define BDOOR_PSHARE_HINTS_VERSION 1
|
||||
#define BDOOR_PSHARE_HINTS_VER(ecx) (((ecx) >> 17) & 0x7f)
|
||||
|
||||
/* Task applied to backdoor pshare hints */
|
||||
#define BDOOR_PSHARE_HINTS_CMD_SHARE 0
|
||||
#define BDOOR_PSHARE_HINTS_CMD_DROP 1
|
||||
#define BDOOR_PSHARE_HINTS_CMD_MAX 2
|
||||
|
||||
#define BDOOR_PSHARE_HINTS_CMD(ecx) (((ecx) >> 24) & 0xff)
|
||||
|
||||
/* Nesting control operations */
|
||||
|
||||
#define NESTING_CONTROL_RESTRICT_BACKDOOR 0
|
||||
#define NESTING_CONTROL_OPEN_BACKDOOR 1
|
||||
#define NESTING_CONTROL_QUERY 2
|
||||
#define NESTING_CONTROL_MAX 2
|
||||
|
||||
/* EFI Boot Order options, nibble-sized. */
|
||||
#define EFI_BOOT_ORDER_TYPE_EFI 0x0
|
||||
#define EFI_BOOT_ORDER_TYPE_LEGACY 0x1
|
||||
#define EFI_BOOT_ORDER_TYPE_NONE 0xf
|
||||
|
||||
#define BDOOR_NETWORK_BOOT_PROTOCOL_NONE 0x0
|
||||
#define BDOOR_NETWORK_BOOT_PROTOCOL_IPV4 0x1
|
||||
#define BDOOR_NETWORK_BOOT_PROTOCOL_IPV6 0x2
|
||||
|
||||
/* High-bandwidth backdoor port. --hpreg */
|
||||
|
||||
#define BDOORHB_PORT 0x5659
|
||||
|
||||
#define BDOORHB_CMD_MESSAGE 0
|
||||
#define BDOORHB_CMD_VASSERT 1
|
||||
#define BDOORHB_CMD_MAX 2
|
||||
|
||||
/*
|
||||
* There is another backdoor which allows access to certain TSC-related
|
||||
* values using otherwise illegal PMC indices when the pseudo_perfctr
|
||||
* control flag is set.
|
||||
*/
|
||||
|
||||
#define BDOOR_PMC_HW_TSC 0x10000
|
||||
#define BDOOR_PMC_REAL_NS 0x10001
|
||||
#define BDOOR_PMC_APPARENT_NS 0x10002
|
||||
#define BDOOR_PMC_PSEUDO_TSC 0x10003
|
||||
|
||||
#define IS_BDOOR_PMC(index) (((index) | 3) == 0x10003)
|
||||
#define BDOOR_CMD(ecx) ((ecx) & 0xffff)
|
||||
|
||||
/* Sub commands for BDOOR_CMD_VMK_INFO */
|
||||
#define BDOOR_CMD_VMK_INFO_ENTRY 1
|
||||
|
||||
#ifdef VMM
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Backdoor_CmdRequiresFullyValidVCPU --
|
||||
*
|
||||
* A few backdoor commands require the full VCPU to be valid
|
||||
* (including GDTR, IDTR, TR and LDTR). The rest get read/write
|
||||
* access to GPRs and read access to Segment registers (selectors).
|
||||
*
|
||||
* Result:
|
||||
* True iff VECX contains a command that require the full VCPU to
|
||||
* be valid.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
static INLINE Bool
|
||||
Backdoor_CmdRequiresFullyValidVCPU(unsigned cmd)
|
||||
{
|
||||
return cmd == BDOOR_CMD_SIDT ||
|
||||
cmd == BDOOR_CMD_SGDT ||
|
||||
cmd == BDOOR_CMD_SLDT_STR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
132
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/include/backdoor_types.h
generated
vendored
Normal file
132
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/include/backdoor_types.h
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1999-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*********************************************************
|
||||
* The contents of this file are subject to the terms of the Common
|
||||
* Development and Distribution License (the "License") version 1.0
|
||||
* and no later version. You may not use this file except in
|
||||
* compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the License at
|
||||
* http://www.opensource.org/licenses/cddl1.php
|
||||
*
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* backdoor_types.h --
|
||||
*
|
||||
* Type definitions for backdoor interaction code.
|
||||
*/
|
||||
|
||||
#ifndef _BACKDOOR_TYPES_H_
|
||||
#define _BACKDOOR_TYPES_H_
|
||||
|
||||
#ifndef VM_I386
|
||||
#error The backdoor protocol is only supported on x86 architectures.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These #defines are intended for defining register structs as part of
|
||||
* existing named unions. If the union should encapsulate the register
|
||||
* (and nothing else), use DECLARE_REG_NAMED_STRUCT defined below.
|
||||
*/
|
||||
|
||||
#define DECLARE_REG32_STRUCT \
|
||||
struct { \
|
||||
uint16 low; \
|
||||
uint16 high; \
|
||||
} halfs; \
|
||||
uint32 word
|
||||
|
||||
#define DECLARE_REG64_STRUCT \
|
||||
DECLARE_REG32_STRUCT; \
|
||||
struct { \
|
||||
uint32 low; \
|
||||
uint32 high; \
|
||||
} words; \
|
||||
uint64 quad
|
||||
|
||||
#ifndef VM_X86_64
|
||||
#define DECLARE_REG_STRUCT DECLARE_REG32_STRUCT
|
||||
#else
|
||||
#define DECLARE_REG_STRUCT DECLARE_REG64_STRUCT
|
||||
#endif
|
||||
|
||||
#define DECLARE_REG_NAMED_STRUCT(_r) \
|
||||
union { DECLARE_REG_STRUCT; } _r
|
||||
|
||||
/*
|
||||
* Some of the registers are expressed by semantic name, because if they were
|
||||
* expressed as register structs declared above, we could only address them
|
||||
* by fixed size (half-word, word, quad, etc.) instead of by varying size
|
||||
* (size_t, uintptr_t).
|
||||
*
|
||||
* To be cleaner, these registers are expressed ONLY by semantic name,
|
||||
* rather than by a union of the semantic name and a register struct.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
DECLARE_REG_NAMED_STRUCT(ax);
|
||||
size_t size; /* Register bx. */
|
||||
DECLARE_REG_NAMED_STRUCT(cx);
|
||||
DECLARE_REG_NAMED_STRUCT(dx);
|
||||
DECLARE_REG_NAMED_STRUCT(si);
|
||||
DECLARE_REG_NAMED_STRUCT(di);
|
||||
} in;
|
||||
struct {
|
||||
DECLARE_REG_NAMED_STRUCT(ax);
|
||||
DECLARE_REG_NAMED_STRUCT(bx);
|
||||
DECLARE_REG_NAMED_STRUCT(cx);
|
||||
DECLARE_REG_NAMED_STRUCT(dx);
|
||||
DECLARE_REG_NAMED_STRUCT(si);
|
||||
DECLARE_REG_NAMED_STRUCT(di);
|
||||
} out;
|
||||
} Backdoor_proto;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
DECLARE_REG_NAMED_STRUCT(ax);
|
||||
DECLARE_REG_NAMED_STRUCT(bx);
|
||||
size_t size; /* Register cx. */
|
||||
DECLARE_REG_NAMED_STRUCT(dx);
|
||||
uintptr_t srcAddr; /* Register si. */
|
||||
uintptr_t dstAddr; /* Register di. */
|
||||
DECLARE_REG_NAMED_STRUCT(bp);
|
||||
} in;
|
||||
struct {
|
||||
DECLARE_REG_NAMED_STRUCT(ax);
|
||||
DECLARE_REG_NAMED_STRUCT(bx);
|
||||
DECLARE_REG_NAMED_STRUCT(cx);
|
||||
DECLARE_REG_NAMED_STRUCT(dx);
|
||||
DECLARE_REG_NAMED_STRUCT(si);
|
||||
DECLARE_REG_NAMED_STRUCT(di);
|
||||
DECLARE_REG_NAMED_STRUCT(bp);
|
||||
} out;
|
||||
} Backdoor_proto_hb;
|
||||
|
||||
MY_ASSERTS(BACKDOOR_STRUCT_SIZES,
|
||||
ASSERT_ON_COMPILE(sizeof(Backdoor_proto) == 6 * sizeof(uintptr_t));
|
||||
ASSERT_ON_COMPILE(sizeof(Backdoor_proto_hb) == 7 * sizeof(uintptr_t));
|
||||
)
|
||||
|
||||
#undef DECLARE_REG_STRUCT
|
||||
|
||||
#endif /* _BACKDOOR_TYPES_H_ */
|
69
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/include/community_source.h
generated
vendored
Normal file
69
Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/include/community_source.h
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2009-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation version 2.1 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*********************************************************
|
||||
* The contents of this file are subject to the terms of the Common
|
||||
* Development and Distribution License (the "License") version 1.0
|
||||
* and no later version. You may not use this file except in
|
||||
* compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the License at
|
||||
* http://www.opensource.org/licenses/cddl1.php
|
||||
*
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* community_source.h --
|
||||
*
|
||||
* Macros for excluding source code from community.
|
||||
*/
|
||||
|
||||
#ifndef _COMMUNITY_SOURCE_H_
|
||||
#define _COMMUNITY_SOURCE_H_
|
||||
/*
|
||||
* Convenience macro for COMMUNITY_SOURCE
|
||||
*/
|
||||
#undef EXCLUDE_COMMUNITY_SOURCE
|
||||
#ifdef COMMUNITY_SOURCE
|
||||
#define EXCLUDE_COMMUNITY_SOURCE(x)
|
||||
#else
|
||||
#define EXCLUDE_COMMUNITY_SOURCE(x) x
|
||||
#endif
|
||||
|
||||
#undef COMMUNITY_SOURCE_AMD_SECRET
|
||||
#if !defined(COMMUNITY_SOURCE) || defined(AMD_SOURCE)
|
||||
/*
|
||||
* It's ok to include AMD_SECRET source code for non-Community Source,
|
||||
* or for drops directed at AMD.
|
||||
*/
|
||||
#define COMMUNITY_SOURCE_AMD_SECRET
|
||||
#endif
|
||||
|
||||
#undef COMMUNITY_SOURCE_INTEL_SECRET
|
||||
#if !defined(COMMUNITY_SOURCE) || defined(INTEL_SOURCE)
|
||||
/*
|
||||
* It's ok to include INTEL_SECRET source code for non-Community Source,
|
||||
* or for drops directed at Intel.
|
||||
*/
|
||||
#define COMMUNITY_SOURCE_INTEL_SECRET
|
||||
#endif
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user