mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-23 20:02:21 +00: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;
|
||||
|
||||
VIR_FREE(pdom->uuid);
|
||||
VIR_FREE(pdom->home);
|
||||
VIR_FREE(p);
|
||||
};
|
||||
|
||||
@ -666,6 +667,14 @@ parallelsLoadDomain(parallelsConnPtr privconn, virJSONValuePtr jobj)
|
||||
if (!(pdom->uuid = strdup(tmp)))
|
||||
goto no_memory;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj, "Home"))) {
|
||||
parallelsParseError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(pdom->home = strdup(tmp)))
|
||||
goto no_memory;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(jobj, "OS")))
|
||||
goto cleanup;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "datatypes.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)
|
||||
{
|
||||
parallelsConnPtr privconn = conn->privateData;
|
||||
virStorageDriverStatePtr storageState = conn->storagePrivateData;
|
||||
char *base = NULL;
|
||||
size_t i;
|
||||
struct parallelsPoolsAddData data;
|
||||
|
||||
if ((base = strdup(SYSCONFDIR "/libvirt")) == NULL)
|
||||
goto out_of_memory;
|
||||
@ -143,6 +291,13 @@ static int parallelsLoadPools(virConnectPtr conn)
|
||||
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++) {
|
||||
virStoragePoolObjLock(privconn->pools.objs[i]);
|
||||
virStoragePoolObjPtr pool;
|
||||
|
@ -44,6 +44,7 @@ typedef struct _parallelsConn *parallelsConnPtr;
|
||||
struct parallelsDomObj {
|
||||
int id;
|
||||
char *uuid;
|
||||
char *home;
|
||||
};
|
||||
|
||||
typedef struct parallelsDomObj *parallelsDomObjPtr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user