mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 14:15:28 +00:00
parallels: get domain info with SDK
Obtain information about domains using parallels sdk instead of prlctl. prlsdkLoadDomains functions behaves as former parallelsLoadDomains with NULL as second parameter (name) - it fills parallelsConn.domains list. prlsdkLoadDomain is now able to update specified domain by given virDomainObjPtr. Signed-off-by: Dmitry Guryanov <dguryanov@parallels.com>
This commit is contained in:
parent
d211ba7c49
commit
7039bb3cd1
@ -49,7 +49,6 @@
|
||||
#include "virfile.h"
|
||||
#include "virstoragefile.h"
|
||||
#include "nodeinfo.h"
|
||||
#include "c-ctype.h"
|
||||
#include "virstring.h"
|
||||
#include "cpu/cpu.h"
|
||||
|
||||
@ -99,21 +98,6 @@ parallelsDriverUnlock(parallelsConnPtr driver)
|
||||
virMutexUnlock(&driver->lock);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
parallelsDomObjFreePrivate(void *p)
|
||||
{
|
||||
parallelsDomObjPtr pdom = p;
|
||||
|
||||
if (!pdom)
|
||||
return;
|
||||
|
||||
virBitmapFree(pdom->cpumask);
|
||||
VIR_FREE(pdom->uuid);
|
||||
VIR_FREE(pdom->home);
|
||||
VIR_FREE(p);
|
||||
};
|
||||
|
||||
static virCapsPtr
|
||||
parallelsBuildCapabilities(void)
|
||||
{
|
||||
@ -190,729 +174,6 @@ parallelsConnectGetCapabilities(virConnectPtr conn)
|
||||
return xml;
|
||||
}
|
||||
|
||||
static int
|
||||
parallelsGetSerialInfo(virDomainChrDefPtr chr,
|
||||
const char *name, virJSONValuePtr value)
|
||||
{
|
||||
const char *tmp;
|
||||
|
||||
chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
|
||||
chr->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
|
||||
if (virStrToLong_i(name + strlen("serial"),
|
||||
NULL, 10, &chr->target.port) < 0) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virJSONValueObjectHasKey(value, "output")) {
|
||||
chr->source.type = VIR_DOMAIN_CHR_TYPE_FILE;
|
||||
|
||||
tmp = virJSONValueObjectGetString(value, "output");
|
||||
if (!tmp) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (VIR_STRDUP(chr->source.data.file.path, tmp) < 0)
|
||||
return -1;
|
||||
} else if (virJSONValueObjectHasKey(value, "socket")) {
|
||||
chr->source.type = VIR_DOMAIN_CHR_TYPE_UNIX;
|
||||
|
||||
tmp = virJSONValueObjectGetString(value, "socket");
|
||||
if (!tmp) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (VIR_STRDUP(chr->source.data.nix.path, tmp) < 0)
|
||||
return -1;
|
||||
chr->source.data.nix.listen = false;
|
||||
} else if (virJSONValueObjectHasKey(value, "real")) {
|
||||
chr->source.type = VIR_DOMAIN_CHR_TYPE_DEV;
|
||||
|
||||
tmp = virJSONValueObjectGetString(value, "real");
|
||||
if (!tmp) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (VIR_STRDUP(chr->source.data.file.path, tmp) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parallelsAddSerialInfo(virDomainChrDefPtr **serials, size_t *nserials,
|
||||
const char *key, virJSONValuePtr value)
|
||||
{
|
||||
virDomainChrDefPtr chr = NULL;
|
||||
|
||||
if (!(chr = virDomainChrDefNew()))
|
||||
goto cleanup;
|
||||
|
||||
if (parallelsGetSerialInfo(chr, key, value))
|
||||
goto cleanup;
|
||||
|
||||
if (VIR_APPEND_ELEMENT(*serials, *nserials, chr) < 0)
|
||||
goto cleanup;
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
virDomainChrDefFree(chr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parallelsAddVideoInfo(virDomainDefPtr def, virJSONValuePtr value)
|
||||
{
|
||||
virDomainVideoDefPtr video = NULL;
|
||||
virDomainVideoAccelDefPtr accel = NULL;
|
||||
const char *tmp;
|
||||
char *endptr;
|
||||
unsigned long mem;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(value, "size"))) {
|
||||
parallelsParseError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (virStrToLong_ul(tmp, &endptr, 10, &mem) < 0) {
|
||||
parallelsParseError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!STREQ(endptr, "Mb")) {
|
||||
parallelsParseError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC(video) < 0)
|
||||
goto error;
|
||||
|
||||
if (VIR_ALLOC(accel) < 0)
|
||||
goto error;
|
||||
|
||||
if (VIR_APPEND_ELEMENT_COPY(def->videos, def->nvideos, video) < 0)
|
||||
goto error;
|
||||
|
||||
video->type = VIR_DOMAIN_VIDEO_TYPE_VGA;
|
||||
video->vram = mem << 20;
|
||||
video->heads = 1;
|
||||
video->accel = accel;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
VIR_FREE(accel);
|
||||
virDomainVideoDefFree(video);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parallelsGetHddInfo(virDomainDefPtr def,
|
||||
virDomainDiskDefPtr disk,
|
||||
const char *key,
|
||||
virJSONValuePtr value)
|
||||
{
|
||||
const char *tmp;
|
||||
unsigned int idx;
|
||||
|
||||
disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
|
||||
|
||||
if (virJSONValueObjectHasKey(value, "real") == 1) {
|
||||
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_BLOCK);
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(value, "real"))) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virDomainDiskSetSource(disk, tmp) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE);
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(value, "image"))) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virDomainDiskSetSource(disk, tmp) < 0)
|
||||
return -1;
|
||||
|
||||
virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_PLOOP);
|
||||
}
|
||||
|
||||
tmp = virJSONValueObjectGetString(value, "port");
|
||||
if (!tmp && !IS_CT(def)) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tmp) {
|
||||
if (STRPREFIX(tmp, "ide")) {
|
||||
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
||||
} else if (STRPREFIX(tmp, "sata")) {
|
||||
disk->bus = VIR_DOMAIN_DISK_BUS_SATA;
|
||||
} else if (STRPREFIX(tmp, "scsi")) {
|
||||
disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
|
||||
} else {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *colonp;
|
||||
unsigned int pos;
|
||||
|
||||
if (!(colonp = strchr(tmp, ':'))) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virStrToLong_ui(colonp + 1, NULL, 10, &pos) < 0) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
|
||||
disk->info.addr.drive.target = pos;
|
||||
} else {
|
||||
/* Actually there are no disk devices in containers, but in
|
||||
* in Parallels Cloud Server we mount disk images as container's
|
||||
* root fs during start, so it looks like a disk device. */
|
||||
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
||||
}
|
||||
|
||||
if (virStrToLong_ui(key + strlen("hdd"), NULL, 10, &idx) < 0) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(disk->dst = virIndexToDiskName(idx, "sd")))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parallelsAddHddInfo(virDomainDefPtr def, const char *key, virJSONValuePtr value)
|
||||
{
|
||||
virDomainDiskDefPtr disk = NULL;
|
||||
|
||||
if (!(disk = virDomainDiskDefNew()))
|
||||
goto error;
|
||||
|
||||
if (parallelsGetHddInfo(def, disk, key, value))
|
||||
goto error;
|
||||
|
||||
if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
virDomainDiskDefFree(disk);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline unsigned char hex2int(char c)
|
||||
{
|
||||
if (c <= '9')
|
||||
return c - '0';
|
||||
else
|
||||
return 10 + c - 'A';
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse MAC address in format XXXXXXXXXXXX.
|
||||
*/
|
||||
static int
|
||||
parallelsMacAddrParse(const char *str, virMacAddrPtr addr)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (strlen(str) != 12)
|
||||
goto error;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (!c_isxdigit(str[2 * i]) || !c_isxdigit(str[2 * i + 1]))
|
||||
goto error;
|
||||
|
||||
addr->addr[i] = (hex2int(str[2 * i]) << 4) + hex2int(str[2 * i + 1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("Invalid MAC address format '%s'"), str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parallelsGetNetInfo(virDomainNetDefPtr net,
|
||||
const char *key,
|
||||
virJSONValuePtr value)
|
||||
{
|
||||
const char *tmp;
|
||||
|
||||
/* use device name, shown by prlctl as target device
|
||||
* for identifying network adapter in virDomainDefineXML */
|
||||
if (VIR_STRDUP(net->ifname, key) < 0)
|
||||
goto error;
|
||||
|
||||
net->type = VIR_DOMAIN_NET_TYPE_NETWORK;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(value, "mac"))) {
|
||||
parallelsParseError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (parallelsMacAddrParse(tmp, &net->mac) < 0) {
|
||||
parallelsParseError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
if (virJSONValueObjectHasKey(value, "network")) {
|
||||
if (!(tmp = virJSONValueObjectGetString(value, "network"))) {
|
||||
parallelsParseError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (VIR_STRDUP(net->data.network.name, tmp) < 0)
|
||||
goto error;
|
||||
} else if (virJSONValueObjectHasKey(value, "type")) {
|
||||
if (!(tmp = virJSONValueObjectGetString(value, "type"))) {
|
||||
parallelsParseError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!STREQ(tmp, "routed")) {
|
||||
parallelsParseError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (VIR_STRDUP(net->data.network.name,
|
||||
PARALLELS_ROUTED_NETWORK_NAME) < 0)
|
||||
goto error;
|
||||
} else {
|
||||
parallelsParseError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP;
|
||||
if ((tmp = virJSONValueObjectGetString(value, "state")) &&
|
||||
STREQ(tmp, "disconnected")) {
|
||||
net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parallelsAddNetInfo(virDomainDefPtr def, const char *key, virJSONValuePtr value)
|
||||
{
|
||||
virDomainNetDefPtr net = NULL;
|
||||
|
||||
if (VIR_ALLOC(net) < 0)
|
||||
goto error;
|
||||
|
||||
if (parallelsGetNetInfo(net, key, value))
|
||||
goto error;
|
||||
|
||||
if (VIR_EXPAND_N(def->nets, def->nnets, 1) < 0)
|
||||
goto error;
|
||||
|
||||
def->nets[def->nnets - 1] = net;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
virDomainNetDefFree(net);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parallelsAddDomainHardware(virDomainDefPtr def, virJSONValuePtr jobj)
|
||||
{
|
||||
int n;
|
||||
size_t i;
|
||||
virJSONValuePtr value;
|
||||
const char *key;
|
||||
|
||||
n = virJSONValueObjectKeysNumber(jobj);
|
||||
if (n < 1)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
key = virJSONValueObjectGetKey(jobj, i);
|
||||
value = virJSONValueObjectGetValue(jobj, i);
|
||||
|
||||
if (STRPREFIX(key, "serial")) {
|
||||
if (parallelsAddSerialInfo(&def->serials,
|
||||
&def->nserials, key, value))
|
||||
goto cleanup;
|
||||
if (def->nconsoles == 0) {
|
||||
if (parallelsAddSerialInfo(&def->consoles,
|
||||
&def->nconsoles, key, value))
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (STREQ(key, "video")) {
|
||||
if (parallelsAddVideoInfo(def, value))
|
||||
goto cleanup;
|
||||
} else if (STRPREFIX(key, "hdd")) {
|
||||
if (parallelsAddHddInfo(def, key, value))
|
||||
goto cleanup;
|
||||
} else if (STRPREFIX(key, "net")) {
|
||||
if (parallelsAddNetInfo(def, key, value))
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parallelsAddVNCInfo(virDomainDefPtr def, virJSONValuePtr jobj_root)
|
||||
{
|
||||
const char *tmp;
|
||||
unsigned int port;
|
||||
virJSONValuePtr jobj;
|
||||
int ret = -1;
|
||||
virDomainGraphicsDefPtr gr = NULL;
|
||||
|
||||
jobj = virJSONValueObjectGet(jobj_root, "Remote display");
|
||||
if (!jobj) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
tmp = virJSONValueObjectGetString(jobj, "mode");
|
||||
if (!tmp) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (STREQ(tmp, "off")) {
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC(gr) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (STREQ(tmp, "auto")) {
|
||||
if (virJSONValueObjectGetNumberUint(jobj, "port", &port) < 0)
|
||||
port = 0;
|
||||
gr->data.vnc.autoport = true;
|
||||
} else {
|
||||
if (virJSONValueObjectGetNumberUint(jobj, "port", &port) < 0) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
gr->data.vnc.autoport = false;
|
||||
}
|
||||
|
||||
gr->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
|
||||
gr->data.vnc.port = port;
|
||||
gr->data.vnc.keymap = NULL;
|
||||
gr->data.vnc.socket = NULL;
|
||||
gr->data.vnc.auth.passwd = NULL;
|
||||
gr->data.vnc.auth.expires = false;
|
||||
gr->data.vnc.auth.connected = 0;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj, "address"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC(gr->listens) < 0)
|
||||
goto cleanup;
|
||||
|
||||
gr->nListens = 1;
|
||||
|
||||
if (VIR_STRDUP(gr->listens[0].address, tmp) < 0)
|
||||
goto cleanup;
|
||||
|
||||
gr->listens[0].type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS;
|
||||
|
||||
if (VIR_APPEND_ELEMENT(def->graphics, def->ngraphics, gr) < 0)
|
||||
goto cleanup;
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
virDomainGraphicsDefFree(gr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must be called with privconn->lock held
|
||||
*/
|
||||
static virDomainObjPtr
|
||||
parallelsLoadDomain(parallelsConnPtr privconn, virJSONValuePtr jobj)
|
||||
{
|
||||
virDomainObjPtr dom = NULL;
|
||||
virDomainDefPtr def = NULL;
|
||||
parallelsDomObjPtr pdom = NULL;
|
||||
virJSONValuePtr jobj2, jobj3;
|
||||
const char *tmp;
|
||||
char *endptr;
|
||||
unsigned long mem;
|
||||
unsigned int x;
|
||||
const char *autostart;
|
||||
const char *state;
|
||||
int hostcpus;
|
||||
|
||||
if (VIR_ALLOC(def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (VIR_ALLOC(pdom) < 0)
|
||||
goto cleanup;
|
||||
|
||||
def->virtType = VIR_DOMAIN_VIRT_PARALLELS;
|
||||
def->id = -1;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj, "Name"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
if (VIR_STRDUP(def->name, tmp) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj, "ID"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virUUIDParse(tmp, def->uuid) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("UUID in config file malformed"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj, "Description"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
if (VIR_STRDUP(def->description, tmp) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(jobj2 = virJSONValueObjectGet(jobj, "Hardware"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(jobj3 = virJSONValueObjectGet(jobj2, "cpu"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virJSONValueObjectGetNumberUint(jobj3, "cpus", &x) == 0) {
|
||||
def->vcpus = x;
|
||||
def->maxvcpus = x;
|
||||
} else if ((tmp = virJSONValueObjectGetString(jobj3, "cpus"))) {
|
||||
if (STREQ(tmp, "unlimited")) {
|
||||
virNodeInfo nodeinfo;
|
||||
|
||||
if (nodeGetInfo(&nodeinfo) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Can't get node info"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
def->vcpus = nodeinfo.cpus;
|
||||
def->maxvcpus = def->vcpus;
|
||||
} else {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((hostcpus = nodeGetCPUCount()) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj3, "mask"))) {
|
||||
/* Absence of this field means that all domains cpus are available */
|
||||
if (!(pdom->cpumask = virBitmapNew(hostcpus)))
|
||||
goto cleanup;
|
||||
virBitmapSetAll(pdom->cpumask);
|
||||
} else {
|
||||
if (virBitmapParse(tmp, 0, &pdom->cpumask, hostcpus) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(jobj3 = virJSONValueObjectGet(jobj2, "memory"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj3, "size"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virStrToLong_ul(tmp, &endptr, 10, &mem) < 0) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!STREQ(endptr, "Mb")) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
def->mem.max_balloon = mem;
|
||||
def->mem.max_balloon <<= 10;
|
||||
def->mem.cur_balloon = def->mem.max_balloon;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj, "Type"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (STREQ(tmp, "CT")) {
|
||||
if (VIR_STRDUP(def->os.type, "exe") < 0)
|
||||
goto cleanup;
|
||||
if (VIR_STRDUP(def->os.init, "/sbin/init") < 0)
|
||||
goto cleanup;
|
||||
} else if (STREQ(tmp, "VM")) {
|
||||
if (VIR_STRDUP(def->os.type, "hvm") < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
def->os.arch = VIR_ARCH_X86_64;
|
||||
|
||||
if (virJSONValueObjectGetNumberUint(jobj, "EnvID", &x) < 0)
|
||||
goto cleanup;
|
||||
pdom->id = x;
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj, "ID"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
if (VIR_STRDUP(pdom->uuid, tmp) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj, "Home"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (VIR_STRDUP(pdom->home, tmp) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(state = virJSONValueObjectGetString(jobj, "State"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(autostart = virJSONValueObjectGetString(jobj, "Autostart"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (parallelsAddDomainHardware(def, jobj2) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (parallelsAddVNCInfo(def, jobj) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(dom = virDomainObjListAdd(privconn->domains, def,
|
||||
privconn->xmlopt,
|
||||
0, NULL)))
|
||||
goto cleanup;
|
||||
/* dom is locked here */
|
||||
|
||||
dom->privateDataFreeFunc = parallelsDomObjFreePrivate;
|
||||
dom->privateData = pdom;
|
||||
dom->persistent = 1;
|
||||
|
||||
/* TODO: handle all possible states */
|
||||
if (STREQ(state, "running")) {
|
||||
virDomainObjSetState(dom, VIR_DOMAIN_RUNNING,
|
||||
VIR_DOMAIN_RUNNING_BOOTED);
|
||||
def->id = pdom->id;
|
||||
}
|
||||
|
||||
if (STREQ(autostart, "on"))
|
||||
dom->autostart = 1;
|
||||
else
|
||||
dom->autostart = 0;
|
||||
|
||||
virObjectUnlock(dom);
|
||||
|
||||
return dom;
|
||||
|
||||
cleanup:
|
||||
virDomainDefFree(def);
|
||||
parallelsDomObjFreePrivate(pdom);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must be called with privconn->lock held
|
||||
*
|
||||
* if domain_name is NULL - load information about all
|
||||
* registered domains.
|
||||
*/
|
||||
static int
|
||||
parallelsLoadDomains(parallelsConnPtr privconn, const char *domain_name)
|
||||
{
|
||||
int count;
|
||||
size_t i;
|
||||
virJSONValuePtr jobj;
|
||||
virJSONValuePtr jobj2;
|
||||
virDomainObjPtr dom = NULL;
|
||||
int ret = -1;
|
||||
|
||||
jobj = parallelsParseOutput(PRLCTL, "list", "-j", "-a", "-i", "-H",
|
||||
"--vmtype", "all", domain_name, NULL);
|
||||
if (!jobj) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
count = virJSONValueArraySize(jobj);
|
||||
if (count < 0) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
jobj2 = virJSONValueArrayGet(jobj, i);
|
||||
if (!jobj2) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dom = parallelsLoadDomain(privconn, jobj2);
|
||||
if (!dom)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
virJSONValueFree(jobj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
parallelsDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
||||
virCapsPtr caps ATTRIBUTE_UNUSED,
|
||||
@ -972,7 +233,7 @@ parallelsOpenDefault(virConnectPtr conn)
|
||||
|
||||
conn->privateData = privconn;
|
||||
|
||||
if (parallelsLoadDomains(privconn, NULL))
|
||||
if (prlsdkLoadDomains(privconn))
|
||||
goto error;
|
||||
|
||||
return VIR_DRV_OPEN_SUCCESS;
|
||||
@ -2292,6 +1553,7 @@ parallelsDomainDefineXML(virConnectPtr conn, const char *xml)
|
||||
virDomainPtr ret = NULL;
|
||||
virDomainDefPtr def;
|
||||
virDomainObjPtr olddom = NULL;
|
||||
virDomainObjPtr dom = NULL;
|
||||
|
||||
parallelsDriverLock(privconn);
|
||||
if ((def = virDomainDefParseString(xml, privconn->caps, privconn->xmlopt,
|
||||
@ -2316,7 +1578,10 @@ parallelsDomainDefineXML(virConnectPtr conn, const char *xml)
|
||||
_("Unsupported OS type: %s"), def->os.type);
|
||||
goto cleanup;
|
||||
}
|
||||
if (parallelsLoadDomains(privconn, def->name))
|
||||
dom = prlsdkAddDomain(privconn, def->uuid);
|
||||
if (dom)
|
||||
virObjectUnlock(dom);
|
||||
else
|
||||
goto cleanup;
|
||||
olddom = virDomainObjListFindByName(privconn->domains, def->name);
|
||||
if (!olddom) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,3 +28,7 @@ int prlsdkInit(parallelsConnPtr privconn);
|
||||
void prlsdkDeinit(void);
|
||||
int prlsdkConnect(parallelsConnPtr privconn);
|
||||
void prlsdkDisconnect(parallelsConnPtr privconn);
|
||||
int
|
||||
prlsdkLoadDomains(parallelsConnPtr privconn);
|
||||
virDomainObjPtr
|
||||
prlsdkAddDomain(parallelsConnPtr privconn, const unsigned char *uuid);
|
||||
|
@ -62,6 +62,7 @@ struct parallelsDomObj {
|
||||
char *uuid;
|
||||
char *home;
|
||||
virBitmapPtr cpumask;
|
||||
PRL_HANDLE sdkdom;
|
||||
};
|
||||
|
||||
typedef struct parallelsDomObj *parallelsDomObjPtr;
|
||||
|
Loading…
Reference in New Issue
Block a user