mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
parallels: create storage pools by VM list
There are no storage pools in Parallels Cloud Server - All VM data stored in a single directory: config, snapshots, memory dump together with disk images. Let's look through list of VMs and create a storage pool for each directory, containing VMs. So if you have 3 vms: /var/parallels/vm-1.pvm, /var/parallels/vm-2.pvm and /root/test.pvm - 2 storage pools appear: -var-parallels and -root. xml descriptions of the pools will be saved in /etc/libvirt/parallels-storage, so UUIDs will not change netween connections to libvirt. Signed-off-by: Dmitry Guryanov <dguryanov@parallels.com>
This commit is contained in:
parent
4dc52e1e2f
commit
766e0c91d7
@ -104,6 +104,7 @@ parallelsDomObjFreePrivate(void *p)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
VIR_FREE(pdom->uuid);
|
VIR_FREE(pdom->uuid);
|
||||||
|
VIR_FREE(pdom->home);
|
||||||
VIR_FREE(p);
|
VIR_FREE(p);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -666,6 +667,14 @@ parallelsLoadDomain(parallelsConnPtr privconn, virJSONValuePtr jobj)
|
|||||||
if (!(pdom->uuid = strdup(tmp)))
|
if (!(pdom->uuid = strdup(tmp)))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
|
if (!(tmp = virJSONValueObjectGetString(jobj, "Home"))) {
|
||||||
|
parallelsParseError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pdom->home = strdup(tmp)))
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
if (!(tmp = virJSONValueObjectGetString(jobj, "OS")))
|
if (!(tmp = virJSONValueObjectGetString(jobj, "OS")))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
#include "datatypes.h"
|
#include "datatypes.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
@ -114,12 +115,159 @@ cleanup:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct parallelsPoolsAddData {
|
||||||
|
virConnectPtr conn;
|
||||||
|
bool failed;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate unique pool name by path
|
||||||
|
*/
|
||||||
|
static char *parallelsMakePoolName(virConnectPtr conn, const char *path)
|
||||||
|
{
|
||||||
|
parallelsConnPtr privconn = conn->privateData;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < UINT_MAX; i++) {
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (!(name = strdup(path))) {
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
name = strdup(path);
|
||||||
|
else
|
||||||
|
virAsprintf(&name, "%s-%u", path, i);
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
virReportOOMError();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < strlen(name); j++)
|
||||||
|
if (name[j] == '/')
|
||||||
|
name[j] = '-';
|
||||||
|
|
||||||
|
for (int j = 0; j < privconn->pools.count; j++) {
|
||||||
|
if (STREQ(name, privconn->pools.objs[j]->def->name)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
return name;
|
||||||
|
|
||||||
|
VIR_FREE(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virStoragePoolObjPtr
|
||||||
|
parallelsPoolCreateByPath(virConnectPtr conn, const char *path)
|
||||||
|
{
|
||||||
|
parallelsConnPtr privconn = conn->privateData;
|
||||||
|
virStoragePoolObjListPtr pools = &privconn->pools;
|
||||||
|
virStoragePoolDefPtr def;
|
||||||
|
virStoragePoolObjPtr pool = NULL;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(def) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (!(def->name = parallelsMakePoolName(conn, path)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(def->uuid, VIR_UUID_BUFLEN))
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (virUUIDGenerate(def->uuid)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Can't generate UUID"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
def->type = VIR_STORAGE_POOL_DIR;
|
||||||
|
def->target.path = strdup(path);
|
||||||
|
|
||||||
|
if (!(pool = virStoragePoolObjAssignDef(pools, def)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virStoragePoolObjSaveDef(conn->storagePrivateData, pool, def) < 0) {
|
||||||
|
virStoragePoolObjRemove(pools, pool);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
virStoragePoolObjUnlock(pool);
|
||||||
|
|
||||||
|
return pool;
|
||||||
|
no_memory:
|
||||||
|
virReportOOMError();
|
||||||
|
error:
|
||||||
|
virStoragePoolDefFree(def);
|
||||||
|
if (pool)
|
||||||
|
virStoragePoolObjUnlock(pool);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create pool of type VIR_STORAGE_POOL_DIR with
|
||||||
|
* path to the VM, if it's not exists.
|
||||||
|
*/
|
||||||
|
static virStoragePoolObjPtr
|
||||||
|
parallelsPoolAddByDomain(virConnectPtr conn, virDomainObjPtr dom)
|
||||||
|
{
|
||||||
|
parallelsConnPtr privconn = conn->privateData;
|
||||||
|
parallelsDomObjPtr pdom = dom->privateData;
|
||||||
|
virStoragePoolObjListPtr pools = &privconn->pools;
|
||||||
|
char *poolPath;
|
||||||
|
virStoragePoolObjPtr pool = NULL;
|
||||||
|
|
||||||
|
if (!(poolPath = strdup(pdom->home))) {
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
poolPath = dirname(poolPath);
|
||||||
|
|
||||||
|
for (int j = 0; j < pools->count; j++) {
|
||||||
|
if (STREQ(poolPath, pools->objs[j]->def->target.path)) {
|
||||||
|
pool = pools->objs[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pool)
|
||||||
|
pool = parallelsPoolCreateByPath(conn, poolPath);
|
||||||
|
|
||||||
|
VIR_FREE(poolPath);
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parallelsPoolsAdd(void *payload,
|
||||||
|
const void *name ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
struct parallelsPoolsAddData *data = (struct parallelsPoolsAddData *)opaque;
|
||||||
|
virDomainObjPtr dom = payload;
|
||||||
|
virStoragePoolObjPtr pool;
|
||||||
|
|
||||||
|
if (!(pool = parallelsPoolAddByDomain(data->conn, dom)))
|
||||||
|
data->failed = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static int parallelsLoadPools(virConnectPtr conn)
|
static int parallelsLoadPools(virConnectPtr conn)
|
||||||
{
|
{
|
||||||
parallelsConnPtr privconn = conn->privateData;
|
parallelsConnPtr privconn = conn->privateData;
|
||||||
virStorageDriverStatePtr storageState = conn->storagePrivateData;
|
virStorageDriverStatePtr storageState = conn->storagePrivateData;
|
||||||
char *base = NULL;
|
char *base = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
struct parallelsPoolsAddData data;
|
||||||
|
|
||||||
if ((base = strdup(SYSCONFDIR "/libvirt")) == NULL)
|
if ((base = strdup(SYSCONFDIR "/libvirt")) == NULL)
|
||||||
goto out_of_memory;
|
goto out_of_memory;
|
||||||
@ -143,6 +291,13 @@ static int parallelsLoadPools(virConnectPtr conn)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.conn = conn;
|
||||||
|
data.failed = false;
|
||||||
|
virHashForEach(privconn->domains.objs, parallelsPoolsAdd, &data);
|
||||||
|
|
||||||
|
if (data.failed)
|
||||||
|
goto error;
|
||||||
|
|
||||||
for (i = 0; i < privconn->pools.count; i++) {
|
for (i = 0; i < privconn->pools.count; i++) {
|
||||||
virStoragePoolObjLock(privconn->pools.objs[i]);
|
virStoragePoolObjLock(privconn->pools.objs[i]);
|
||||||
virStoragePoolObjPtr pool;
|
virStoragePoolObjPtr pool;
|
||||||
|
@ -44,6 +44,7 @@ typedef struct _parallelsConn *parallelsConnPtr;
|
|||||||
struct parallelsDomObj {
|
struct parallelsDomObj {
|
||||||
int id;
|
int id;
|
||||||
char *uuid;
|
char *uuid;
|
||||||
|
char *home;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct parallelsDomObj *parallelsDomObjPtr;
|
typedef struct parallelsDomObj *parallelsDomObjPtr;
|
||||||
|
Loading…
Reference in New Issue
Block a user