2008-02-20 15:34:52 +00:00
|
|
|
/*
|
|
|
|
* storage_driver.c: core driver for storage APIs
|
|
|
|
*
|
2011-05-03 17:44:04 +00:00
|
|
|
* Copyright (C) 2006-2011 Red Hat, Inc.
|
2008-02-20 15:34:52 +00:00
|
|
|
* Copyright (C) 2006-2008 Daniel P. Berrange
|
|
|
|
*
|
|
|
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/types.h>
|
2010-02-23 03:13:18 +00:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
2008-04-18 08:33:23 +00:00
|
|
|
#if HAVE_PWD_H
|
2010-03-09 18:22:22 +00:00
|
|
|
# include <pwd.h>
|
2008-04-18 08:33:23 +00:00
|
|
|
#endif
|
2008-02-20 15:34:52 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2008-11-04 22:30:33 +00:00
|
|
|
#include "virterror_internal.h"
|
2008-11-04 23:22:06 +00:00
|
|
|
#include "datatypes.h"
|
2008-02-20 15:34:52 +00:00
|
|
|
#include "driver.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "storage_driver.h"
|
|
|
|
#include "storage_conf.h"
|
2008-06-06 11:09:57 +00:00
|
|
|
#include "memory.h"
|
2008-02-20 15:34:52 +00:00
|
|
|
#include "storage_backend.h"
|
2010-01-31 17:12:05 +00:00
|
|
|
#include "logging.h"
|
2011-07-19 18:32:58 +00:00
|
|
|
#include "virfile.h"
|
2009-07-14 15:24:42 +00:00
|
|
|
#include "fdstream.h"
|
2010-11-16 14:54:17 +00:00
|
|
|
#include "configmake.h"
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2009-01-20 17:13:33 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_STORAGE
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
static virStorageDriverStatePtr driverState;
|
|
|
|
|
|
|
|
static int storageDriverShutdown(void);
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
static void storageDriverLock(virStorageDriverStatePtr driver)
|
|
|
|
{
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexLock(&driver->lock);
|
2008-12-04 21:40:42 +00:00
|
|
|
}
|
|
|
|
static void storageDriverUnlock(virStorageDriverStatePtr driver)
|
|
|
|
{
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexUnlock(&driver->lock);
|
2008-12-04 21:40:42 +00:00
|
|
|
}
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
storageDriverAutostart(virStorageDriverStatePtr driver) {
|
2008-10-10 15:13:28 +00:00
|
|
|
unsigned int i;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-10-10 15:13:28 +00:00
|
|
|
for (i = 0 ; i < driver->pools.count ; i++) {
|
|
|
|
virStoragePoolObjPtr pool = driver->pools.objs[i];
|
2010-11-11 20:09:20 +00:00
|
|
|
virStorageBackendPtr backend;
|
|
|
|
bool started = false;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjLock(pool);
|
2010-11-11 20:09:20 +00:00
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL) {
|
|
|
|
VIR_ERROR(_("Missing backend %d"), pool->def->type);
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
continue;
|
|
|
|
}
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2010-11-11 20:09:20 +00:00
|
|
|
if (backend->checkPool &&
|
|
|
|
backend->checkPool(NULL, pool, &started) < 0) {
|
|
|
|
virErrorPtr err = virGetLastError();
|
|
|
|
VIR_ERROR(_("Failed to initialize storage pool '%s': %s"),
|
|
|
|
pool->def->name, err ? err->message :
|
|
|
|
_("no error message found"));
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!started &&
|
|
|
|
pool->autostart &&
|
|
|
|
!virStoragePoolObjIsActive(pool)) {
|
2008-02-20 15:34:52 +00:00
|
|
|
if (backend->startPool &&
|
|
|
|
backend->startPool(NULL, pool) < 0) {
|
|
|
|
virErrorPtr err = virGetLastError();
|
2010-05-20 06:15:46 +00:00
|
|
|
VIR_ERROR(_("Failed to autostart storage pool '%s': %s"),
|
2010-01-31 17:12:05 +00:00
|
|
|
pool->def->name, err ? err->message :
|
2010-11-11 20:09:20 +00:00
|
|
|
_("no error message found"));
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-02-20 15:34:52 +00:00
|
|
|
continue;
|
|
|
|
}
|
2010-11-11 20:09:20 +00:00
|
|
|
started = true;
|
|
|
|
}
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2010-11-11 20:09:20 +00:00
|
|
|
if (started) {
|
2008-02-20 15:34:52 +00:00
|
|
|
if (backend->refreshPool(NULL, pool) < 0) {
|
|
|
|
virErrorPtr err = virGetLastError();
|
|
|
|
if (backend->stopPool)
|
|
|
|
backend->stopPool(NULL, pool);
|
2010-05-20 06:15:46 +00:00
|
|
|
VIR_ERROR(_("Failed to autostart storage pool '%s': %s"),
|
2010-01-31 17:12:05 +00:00
|
|
|
pool->def->name, err ? err->message :
|
2010-11-11 20:09:20 +00:00
|
|
|
_("no error message found"));
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-02-20 15:34:52 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
pool->active = 1;
|
|
|
|
}
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virStorageStartup:
|
|
|
|
*
|
|
|
|
* Initialization function for the QEmu daemon
|
|
|
|
*/
|
|
|
|
static int
|
2011-01-15 16:38:57 +00:00
|
|
|
storageDriverStartup(int privileged)
|
|
|
|
{
|
2008-02-20 15:34:52 +00:00
|
|
|
char *base = NULL;
|
|
|
|
|
2008-06-06 11:09:57 +00:00
|
|
|
if (VIR_ALLOC(driverState) < 0)
|
2008-02-20 15:34:52 +00:00
|
|
|
return -1;
|
|
|
|
|
2009-01-15 19:56:05 +00:00
|
|
|
if (virMutexInit(&driverState->lock) < 0) {
|
|
|
|
VIR_FREE(driverState);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driverState);
|
|
|
|
|
2009-06-12 13:20:13 +00:00
|
|
|
if (privileged) {
|
2010-11-16 14:54:17 +00:00
|
|
|
if ((base = strdup (SYSCONFDIR "/libvirt")) == NULL)
|
2008-02-20 15:34:52 +00:00
|
|
|
goto out_of_memory;
|
|
|
|
} else {
|
2009-06-12 13:20:13 +00:00
|
|
|
uid_t uid = geteuid();
|
2010-02-04 22:41:52 +00:00
|
|
|
char *userdir = virGetUserDirectory(uid);
|
2009-01-22 19:41:48 +00:00
|
|
|
|
|
|
|
if (!userdir)
|
|
|
|
goto error;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2009-01-22 19:41:48 +00:00
|
|
|
if (virAsprintf(&base, "%s/.libvirt", userdir) == -1) {
|
|
|
|
VIR_FREE(userdir);
|
2008-02-20 15:34:52 +00:00
|
|
|
goto out_of_memory;
|
|
|
|
}
|
2009-01-22 19:41:48 +00:00
|
|
|
VIR_FREE(userdir);
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Configuration paths are either ~/.libvirt/storage/... (session) or
|
|
|
|
* /etc/libvirt/storage/... (system).
|
|
|
|
*/
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&driverState->configDir,
|
|
|
|
"%s/storage", base) == -1)
|
2008-02-20 15:34:52 +00:00
|
|
|
goto out_of_memory;
|
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&driverState->autostartDir,
|
|
|
|
"%s/storage/autostart", base) == -1)
|
2008-02-20 15:34:52 +00:00
|
|
|
goto out_of_memory;
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
VIR_FREE(base);
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2010-02-10 11:42:56 +00:00
|
|
|
if (virStoragePoolLoadAllConfigs(&driverState->pools,
|
2008-10-10 15:13:28 +00:00
|
|
|
driverState->configDir,
|
2008-12-04 21:40:42 +00:00
|
|
|
driverState->autostartDir) < 0)
|
|
|
|
goto error;
|
2008-02-20 15:34:52 +00:00
|
|
|
storageDriverAutostart(driverState);
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driverState);
|
2008-02-20 15:34:52 +00:00
|
|
|
return 0;
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
out_of_memory:
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-12-04 21:40:42 +00:00
|
|
|
error:
|
|
|
|
VIR_FREE(base);
|
|
|
|
storageDriverUnlock(driverState);
|
|
|
|
storageDriverShutdown();
|
2008-02-20 15:34:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virStorageReload:
|
|
|
|
*
|
|
|
|
* Function to restart the storage driver, it will recheck the configuration
|
|
|
|
* files and update its state
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
storageDriverReload(void) {
|
2008-10-10 15:13:28 +00:00
|
|
|
if (!driverState)
|
|
|
|
return -1;
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driverState);
|
2010-02-10 11:42:56 +00:00
|
|
|
virStoragePoolLoadAllConfigs(&driverState->pools,
|
2008-10-10 15:13:28 +00:00
|
|
|
driverState->configDir,
|
|
|
|
driverState->autostartDir);
|
2008-02-20 15:34:52 +00:00
|
|
|
storageDriverAutostart(driverState);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driverState);
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virStorageActive:
|
|
|
|
*
|
|
|
|
* Checks if the storage driver is active, i.e. has an active pool
|
|
|
|
*
|
|
|
|
* Returns 1 if active, 0 otherwise
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
storageDriverActive(void) {
|
2008-10-10 15:13:28 +00:00
|
|
|
unsigned int i;
|
2008-12-04 21:40:42 +00:00
|
|
|
int active = 0;
|
2008-10-10 15:13:28 +00:00
|
|
|
|
|
|
|
if (!driverState)
|
|
|
|
return 0;
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driverState);
|
|
|
|
|
|
|
|
for (i = 0 ; i < driverState->pools.count ; i++) {
|
|
|
|
virStoragePoolObjLock(driverState->pools.objs[i]);
|
2008-10-10 15:13:28 +00:00
|
|
|
if (virStoragePoolObjIsActive(driverState->pools.objs[i]))
|
2008-12-04 21:40:42 +00:00
|
|
|
active = 1;
|
|
|
|
virStoragePoolObjUnlock(driverState->pools.objs[i]);
|
|
|
|
}
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driverState);
|
|
|
|
return active;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virStorageShutdown:
|
|
|
|
*
|
|
|
|
* Shutdown the storage driver, it will stop all active storage pools
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
storageDriverShutdown(void) {
|
|
|
|
if (!driverState)
|
|
|
|
return -1;
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driverState);
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
/* free inactive pools */
|
2008-10-10 15:13:28 +00:00
|
|
|
virStoragePoolObjListFree(&driverState->pools);
|
|
|
|
|
|
|
|
VIR_FREE(driverState->configDir);
|
|
|
|
VIR_FREE(driverState->autostartDir);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driverState);
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexDestroy(&driverState->lock);
|
2008-10-10 15:13:28 +00:00
|
|
|
VIR_FREE(driverState);
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static virStoragePoolPtr
|
|
|
|
storagePoolLookupByUUID(virConnectPtr conn,
|
|
|
|
const unsigned char *uuid) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
|
|
|
virStoragePoolPtr ret = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
|
2008-12-04 21:39:45 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-02-20 15:34:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virStoragePoolPtr
|
|
|
|
storagePoolLookupByName(virConnectPtr conn,
|
|
|
|
const char *name) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
|
|
|
virStoragePoolPtr ret = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByName(&driver->pools, name);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2009-07-08 10:01:35 +00:00
|
|
|
_("no pool with matching name '%s'"), name);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
|
2008-12-04 21:39:45 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-02-20 15:34:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virStoragePoolPtr
|
|
|
|
storagePoolLookupByVolume(virStorageVolPtr vol) {
|
|
|
|
return storagePoolLookupByName(vol->conn, vol->pool);
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDrvOpenStatus
|
|
|
|
storageOpen(virConnectPtr conn,
|
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
2011-07-06 22:51:23 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!driverState)
|
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
|
|
|
|
conn->storagePrivateData = driverState;
|
|
|
|
return VIR_DRV_OPEN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storageClose(virConnectPtr conn) {
|
|
|
|
conn->storagePrivateData = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storageNumPools(virConnectPtr conn) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = conn->storagePrivateData;
|
2008-10-10 15:13:28 +00:00
|
|
|
unsigned int i, nactive = 0;
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
|
|
|
for (i = 0 ; i < driver->pools.count ; i++) {
|
|
|
|
virStoragePoolObjLock(driver->pools.objs[i]);
|
2008-10-10 15:13:28 +00:00
|
|
|
if (virStoragePoolObjIsActive(driver->pools.objs[i]))
|
|
|
|
nactive++;
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(driver->pools.objs[i]);
|
|
|
|
}
|
|
|
|
storageDriverUnlock(driver);
|
2008-10-10 15:13:28 +00:00
|
|
|
|
|
|
|
return nactive;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storageListPools(virConnectPtr conn,
|
|
|
|
char **const names,
|
|
|
|
int nnames) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = conn->storagePrivateData;
|
2008-02-20 15:34:52 +00:00
|
|
|
int got = 0, i;
|
2008-10-10 15:13:28 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-10-10 15:13:28 +00:00
|
|
|
for (i = 0 ; i < driver->pools.count && got < nnames ; i++) {
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjLock(driver->pools.objs[i]);
|
2008-10-10 15:13:28 +00:00
|
|
|
if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
|
|
|
|
if (!(names[got] = strdup(driver->pools.objs[i]->def->name))) {
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(driver->pools.objs[i]);
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-02-20 15:34:52 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
got++;
|
|
|
|
}
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(driver->pools.objs[i]);
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
2008-02-20 15:34:52 +00:00
|
|
|
return got;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
for (i = 0 ; i < got ; i++)
|
|
|
|
VIR_FREE(names[i]);
|
2008-12-02 15:59:14 +00:00
|
|
|
memset(names, 0, nnames * sizeof(*names));
|
2008-02-20 15:34:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storageNumDefinedPools(virConnectPtr conn) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = conn->storagePrivateData;
|
2008-10-10 15:13:28 +00:00
|
|
|
unsigned int i, nactive = 0;
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
|
|
|
for (i = 0 ; i < driver->pools.count ; i++) {
|
|
|
|
virStoragePoolObjLock(driver->pools.objs[i]);
|
2008-10-10 15:13:28 +00:00
|
|
|
if (!virStoragePoolObjIsActive(driver->pools.objs[i]))
|
|
|
|
nactive++;
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(driver->pools.objs[i]);
|
|
|
|
}
|
|
|
|
storageDriverUnlock(driver);
|
2008-10-10 15:13:28 +00:00
|
|
|
|
|
|
|
return nactive;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storageListDefinedPools(virConnectPtr conn,
|
|
|
|
char **const names,
|
|
|
|
int nnames) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = conn->storagePrivateData;
|
2008-02-20 15:34:52 +00:00
|
|
|
int got = 0, i;
|
2008-10-10 15:13:28 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-10-10 15:13:28 +00:00
|
|
|
for (i = 0 ; i < driver->pools.count && got < nnames ; i++) {
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjLock(driver->pools.objs[i]);
|
2008-10-10 15:13:28 +00:00
|
|
|
if (!virStoragePoolObjIsActive(driver->pools.objs[i])) {
|
|
|
|
if (!(names[got] = strdup(driver->pools.objs[i]->def->name))) {
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(driver->pools.objs[i]);
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-02-20 15:34:52 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
got++;
|
|
|
|
}
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(driver->pools.objs[i]);
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
2008-02-20 15:34:52 +00:00
|
|
|
return got;
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
2008-02-20 15:34:52 +00:00
|
|
|
for (i = 0 ; i < got ; i++) {
|
2009-12-09 23:00:50 +00:00
|
|
|
VIR_FREE(names[i]);
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-02 15:59:14 +00:00
|
|
|
memset(names, 0, nnames * sizeof(*names));
|
2008-02-20 15:34:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
/* This method is required to be re-entrant / thread safe, so
|
|
|
|
uses no driver lock */
|
2008-08-27 20:05:58 +00:00
|
|
|
static char *
|
|
|
|
storageFindPoolSources(virConnectPtr conn,
|
|
|
|
const char *type,
|
|
|
|
const char *srcSpec,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int backend_type;
|
|
|
|
virStorageBackendPtr backend;
|
2008-12-04 21:39:45 +00:00
|
|
|
char *ret = NULL;
|
2008-08-27 20:05:58 +00:00
|
|
|
|
2008-11-17 11:19:33 +00:00
|
|
|
backend_type = virStoragePoolTypeFromString(type);
|
2009-10-08 14:24:37 +00:00
|
|
|
if (backend_type < 0) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
|
2009-10-08 14:24:37 +00:00
|
|
|
_("unknown storage pool type %s"), type);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2009-10-08 14:24:37 +00:00
|
|
|
}
|
2008-08-27 20:05:58 +00:00
|
|
|
|
|
|
|
backend = virStorageBackendForType(backend_type);
|
|
|
|
if (backend == NULL)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-08-27 20:05:58 +00:00
|
|
|
|
2009-10-08 14:24:37 +00:00
|
|
|
if (!backend->findPoolSources) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_SUPPORT,
|
2009-10-08 14:24:37 +00:00
|
|
|
_("pool type '%s' does not support source "
|
|
|
|
"discovery"), type);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = backend->findPoolSources(conn, srcSpec, flags);
|
2008-08-27 20:05:58 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
|
|
|
return ret;
|
2008-08-27 20:05:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-09 09:38:11 +00:00
|
|
|
static int storagePoolIsActive(virStoragePoolPtr pool)
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
{
|
2009-12-09 09:38:11 +00:00
|
|
|
virStorageDriverStatePtr driver = pool->conn->storagePrivateData;
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
virStoragePoolObjPtr obj;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
storageDriverLock(driver);
|
2009-12-09 09:38:11 +00:00
|
|
|
obj = virStoragePoolObjFindByUUID(&driver->pools, pool->uuid);
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
if (!obj) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL, NULL);
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
ret = virStoragePoolObjIsActive(obj);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (obj)
|
|
|
|
virStoragePoolObjUnlock(obj);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-12-09 09:38:11 +00:00
|
|
|
static int storagePoolIsPersistent(virStoragePoolPtr pool)
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
{
|
2009-12-09 09:38:11 +00:00
|
|
|
virStorageDriverStatePtr driver = pool->conn->storagePrivateData;
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
virStoragePoolObjPtr obj;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
storageDriverLock(driver);
|
2009-12-09 09:38:11 +00:00
|
|
|
obj = virStoragePoolObjFindByUUID(&driver->pools, pool->uuid);
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
if (!obj) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL, NULL);
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
ret = obj->configFile ? 1 : 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (obj)
|
|
|
|
virStoragePoolObjUnlock(obj);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
static virStoragePoolPtr
|
|
|
|
storagePoolCreate(virConnectPtr conn,
|
|
|
|
const char *xml,
|
2011-07-06 22:51:23 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = conn->storagePrivateData;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStoragePoolDefPtr def;
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjPtr pool = NULL;
|
2008-12-04 21:39:45 +00:00
|
|
|
virStoragePoolPtr ret = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageBackendPtr backend;
|
|
|
|
|
2011-07-06 22:51:23 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2010-02-10 11:42:56 +00:00
|
|
|
if (!(def = virStoragePoolDefParseString(xml)))
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2010-05-27 11:41:30 +00:00
|
|
|
if (virStoragePoolObjIsDuplicate(&driver->pools, def, 1) < 0)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2011-09-05 07:52:03 +00:00
|
|
|
if (virStoragePoolSourceFindDuplicate(&driver->pools, def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if ((backend = virStorageBackendForType(def->type)) == NULL)
|
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2010-02-10 11:42:56 +00:00
|
|
|
if (!(pool = virStoragePoolObjAssignDef(&driver->pools, def)))
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
def = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-03-17 15:10:48 +00:00
|
|
|
if (backend->startPool &&
|
2009-09-02 13:02:06 +00:00
|
|
|
backend->startPool(conn, pool) < 0) {
|
|
|
|
virStoragePoolObjRemove(&driver->pools, pool);
|
|
|
|
pool = NULL;
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2009-09-02 13:02:06 +00:00
|
|
|
}
|
2008-12-04 21:39:45 +00:00
|
|
|
|
2008-03-17 15:10:48 +00:00
|
|
|
if (backend->refreshPool(conn, pool) < 0) {
|
|
|
|
if (backend->stopPool)
|
|
|
|
backend->stopPool(conn, pool);
|
2009-09-02 13:02:06 +00:00
|
|
|
virStoragePoolObjRemove(&driver->pools, pool);
|
|
|
|
pool = NULL;
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 15:08:44 +00:00
|
|
|
VIR_INFO("Creating storage pool '%s'", pool->def->name);
|
2008-02-20 15:34:52 +00:00
|
|
|
pool->active = 1;
|
|
|
|
|
|
|
|
ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
|
|
|
virStoragePoolDefFree(def);
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
2009-09-02 13:02:06 +00:00
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
2008-02-20 15:34:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virStoragePoolPtr
|
|
|
|
storagePoolDefine(virConnectPtr conn,
|
|
|
|
const char *xml,
|
2011-07-06 22:51:23 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = conn->storagePrivateData;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStoragePoolDefPtr def;
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjPtr pool = NULL;
|
2008-12-04 21:39:45 +00:00
|
|
|
virStoragePoolPtr ret = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2011-07-06 22:51:23 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2010-02-10 11:42:56 +00:00
|
|
|
if (!(def = virStoragePoolDefParseString(xml)))
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2010-05-27 11:41:30 +00:00
|
|
|
if (virStoragePoolObjIsDuplicate(&driver->pools, def, 0) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2011-09-05 07:52:03 +00:00
|
|
|
if (virStoragePoolSourceFindDuplicate(&driver->pools, def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2009-09-04 15:18:29 +00:00
|
|
|
if (virStorageBackendForType(def->type) == NULL)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2010-02-10 11:42:56 +00:00
|
|
|
if (!(pool = virStoragePoolObjAssignDef(&driver->pools, def)))
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2010-02-10 11:42:56 +00:00
|
|
|
if (virStoragePoolObjSaveDef(driver, pool, def) < 0) {
|
2008-10-10 15:13:28 +00:00
|
|
|
virStoragePoolObjRemove(&driver->pools, pool);
|
2008-12-22 16:30:57 +00:00
|
|
|
def = NULL;
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-22 16:30:57 +00:00
|
|
|
def = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 15:08:44 +00:00
|
|
|
VIR_INFO("Defining storage pool '%s'", pool->def->name);
|
2008-02-20 15:34:52 +00:00
|
|
|
ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
|
2008-12-04 21:39:45 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virStoragePoolDefFree(def);
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
storageDriverUnlock(driver);
|
2008-02-20 15:34:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolUndefine(virStoragePoolPtr obj) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("pool is still active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2009-04-17 19:12:37 +00:00
|
|
|
if (pool->asyncjobs > 0) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
|
2009-04-17 19:12:37 +00:00
|
|
|
_("pool '%s' has asynchronous jobs running."),
|
|
|
|
pool->def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-02-10 11:42:56 +00:00
|
|
|
if (virStoragePoolObjDeleteDef(pool) < 0)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2009-02-05 16:28:30 +00:00
|
|
|
if (unlink(pool->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
|
|
|
|
char ebuf[1024];
|
2010-05-20 06:15:46 +00:00
|
|
|
VIR_ERROR(_("Failed to delete autostart link '%s': %s"),
|
2009-02-05 16:28:30 +00:00
|
|
|
pool->autostartLink, virStrerror(errno, ebuf, sizeof ebuf));
|
|
|
|
}
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-10-10 15:13:28 +00:00
|
|
|
VIR_FREE(pool->configFile);
|
|
|
|
VIR_FREE(pool->autostartLink);
|
2008-02-20 15:34:52 +00:00
|
|
|
|
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 15:08:44 +00:00
|
|
|
VIR_INFO("Undefining storage pool '%s'", pool->def->name);
|
2008-10-10 15:13:28 +00:00
|
|
|
virStoragePoolObjRemove(&driver->pools, pool);
|
2008-12-04 21:40:42 +00:00
|
|
|
pool = NULL;
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
storageDriverUnlock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolStart(virStoragePoolPtr obj,
|
2011-07-06 22:51:23 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageBackendPtr backend;
|
2008-12-04 21:39:45 +00:00
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2011-07-06 22:51:23 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
|
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
if (virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("pool already active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
if (backend->startPool &&
|
|
|
|
backend->startPool(obj->conn, pool) < 0)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (backend->refreshPool(obj->conn, pool) < 0) {
|
|
|
|
if (backend->stopPool)
|
|
|
|
backend->stopPool(obj->conn, pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 15:08:44 +00:00
|
|
|
VIR_INFO("Starting up storage pool '%s'", pool->def->name);
|
2008-02-20 15:34:52 +00:00
|
|
|
pool->active = 1;
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolBuild(virStoragePoolPtr obj,
|
|
|
|
unsigned int flags) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageBackendPtr backend;
|
2008-12-04 21:39:45 +00:00
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
|
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
if (virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is already active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (backend->buildPool &&
|
|
|
|
backend->buildPool(obj->conn, pool, flags) < 0)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolDestroy(virStoragePoolPtr obj) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageBackendPtr backend;
|
2008-12-04 21:39:45 +00:00
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
|
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2009-04-17 19:12:37 +00:00
|
|
|
if (pool->asyncjobs > 0) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
|
2009-04-17 19:12:37 +00:00
|
|
|
_("pool '%s' has asynchronous jobs running."),
|
|
|
|
pool->def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (backend->stopPool &&
|
|
|
|
backend->stopPool(obj->conn, pool) < 0)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
virStoragePoolObjClearVols(pool);
|
|
|
|
|
|
|
|
pool->active = 0;
|
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 15:08:44 +00:00
|
|
|
VIR_INFO("Shutting down storage pool '%s'", pool->def->name);
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool->configFile == NULL) {
|
2008-10-10 15:13:28 +00:00
|
|
|
virStoragePoolObjRemove(&driver->pools, pool);
|
2008-12-04 21:40:42 +00:00
|
|
|
pool = NULL;
|
|
|
|
}
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
storageDriverUnlock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolDelete(virStoragePoolPtr obj,
|
|
|
|
unsigned int flags) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageBackendPtr backend;
|
2008-12-04 21:39:45 +00:00
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
|
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
if (virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is still active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2009-04-17 19:12:37 +00:00
|
|
|
if (pool->asyncjobs > 0) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
|
2009-04-17 19:12:37 +00:00
|
|
|
_("pool '%s' has asynchronous jobs running."),
|
|
|
|
pool->def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!backend->deletePool) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_SUPPORT,
|
2010-03-03 18:46:27 +00:00
|
|
|
"%s", _("pool does not support pool deletion"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
if (backend->deletePool(obj->conn, pool, flags) < 0)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 15:08:44 +00:00
|
|
|
VIR_INFO("Deleting storage pool '%s'", pool->def->name);
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolRefresh(virStoragePoolPtr obj,
|
2011-07-06 22:51:23 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageBackendPtr backend;
|
2008-12-04 21:39:45 +00:00
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2011-07-06 22:51:23 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
|
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2009-04-17 19:12:37 +00:00
|
|
|
if (pool->asyncjobs > 0) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
|
2009-04-17 19:12:37 +00:00
|
|
|
_("pool '%s' has asynchronous jobs running."),
|
|
|
|
pool->def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
virStoragePoolObjClearVols(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
if (backend->refreshPool(obj->conn, pool) < 0) {
|
2008-02-20 15:34:52 +00:00
|
|
|
if (backend->stopPool)
|
|
|
|
backend->stopPool(obj->conn, pool);
|
|
|
|
|
|
|
|
pool->active = 0;
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool->configFile == NULL) {
|
2008-10-10 15:13:28 +00:00
|
|
|
virStoragePoolObjRemove(&driver->pools, pool);
|
2008-12-04 21:40:42 +00:00
|
|
|
pool = NULL;
|
|
|
|
}
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2009-05-19 11:06:25 +00:00
|
|
|
storageDriverUnlock(driver);
|
2008-02-20 15:34:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolGetInfo(virStoragePoolPtr obj,
|
|
|
|
virStoragePoolInfoPtr info) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2009-09-04 15:18:29 +00:00
|
|
|
if (virStorageBackendForType(pool->def->type) == NULL)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
memset(info, 0, sizeof(virStoragePoolInfo));
|
|
|
|
if (pool->active)
|
|
|
|
info->state = VIR_STORAGE_POOL_RUNNING;
|
|
|
|
else
|
|
|
|
info->state = VIR_STORAGE_POOL_INACTIVE;
|
|
|
|
info->capacity = pool->def->capacity;
|
|
|
|
info->allocation = pool->def->allocation;
|
|
|
|
info->available = pool->def->available;
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
2011-05-06 19:53:10 +00:00
|
|
|
storagePoolGetXMLDesc(virStoragePoolPtr obj,
|
2011-07-06 22:51:23 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
|
|
|
char *ret = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2011-07-06 22:51:23 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2010-02-10 11:42:56 +00:00
|
|
|
ret = virStoragePoolDefFormat(pool->def);
|
2008-12-04 21:39:45 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolGetAutostart(virStoragePoolPtr obj,
|
|
|
|
int *autostart) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!pool->configFile) {
|
|
|
|
*autostart = 0;
|
|
|
|
} else {
|
|
|
|
*autostart = pool->autostart;
|
|
|
|
}
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-11 15:00:12 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolSetAutostart(virStoragePoolPtr obj,
|
|
|
|
int autostart) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!pool->configFile) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("pool has no config file"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
autostart = (autostart != 0);
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if (pool->autostart != autostart) {
|
|
|
|
if (autostart) {
|
2011-07-05 21:02:53 +00:00
|
|
|
if (virFileMakePath(driver->autostartDir) < 0) {
|
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("cannot create autostart directory %s"),
|
|
|
|
driver->autostartDir);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if (symlink(pool->configFile, pool->autostartLink) < 0) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("Failed to create symlink '%s' to '%s'"),
|
|
|
|
pool->autostartLink, pool->configFile);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (unlink(pool->autostartLink) < 0 &&
|
|
|
|
errno != ENOENT && errno != ENOTDIR) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("Failed to delete symlink '%s'"),
|
|
|
|
pool->autostartLink);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-04 21:39:45 +00:00
|
|
|
pool->autostart = autostart;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2009-05-19 11:06:25 +00:00
|
|
|
storageDriverUnlock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolNumVolumes(virStoragePoolPtr obj) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = pool->volumes.count;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storagePoolListVolumes(virStoragePoolPtr obj,
|
|
|
|
char **const names,
|
|
|
|
int maxnames) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-10-10 15:13:28 +00:00
|
|
|
int i, n = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
memset(names, 0, maxnames * sizeof(*names));
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2008-10-10 15:13:28 +00:00
|
|
|
for (i = 0 ; i < pool->volumes.count && n < maxnames ; i++) {
|
|
|
|
if ((names[n++] = strdup(pool->volumes.objs[i]->name)) == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-02-20 15:34:52 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-10-10 15:13:28 +00:00
|
|
|
return n;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-10-10 15:13:28 +00:00
|
|
|
for (n = 0 ; n < maxnames ; n++)
|
2008-12-04 21:39:45 +00:00
|
|
|
VIR_FREE(names[n]);
|
2008-10-10 15:13:28 +00:00
|
|
|
|
2008-12-02 15:59:14 +00:00
|
|
|
memset(names, 0, maxnames * sizeof(*names));
|
2008-02-20 15:34:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static virStorageVolPtr
|
|
|
|
storageVolumeLookupByName(virStoragePoolPtr obj,
|
|
|
|
const char *name) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageVolDefPtr vol;
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageVolPtr ret = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vol = virStorageVolDefFindByName(pool, name);
|
|
|
|
|
|
|
|
if (!vol) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
|
|
|
_("no storage vol with matching name '%s'"),
|
2009-07-08 10:01:35 +00:00
|
|
|
name);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = virGetStorageVol(obj->conn, pool->def->name, vol->name, vol->key);
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static virStorageVolPtr
|
|
|
|
storageVolumeLookupByKey(virConnectPtr conn,
|
|
|
|
const char *key) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = conn->storagePrivateData;
|
2008-10-10 15:13:28 +00:00
|
|
|
unsigned int i;
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageVolPtr ret = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
|
|
|
for (i = 0 ; i < driver->pools.count && !ret ; i++) {
|
|
|
|
virStoragePoolObjLock(driver->pools.objs[i]);
|
2008-10-10 15:13:28 +00:00
|
|
|
if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
|
|
|
|
virStorageVolDefPtr vol =
|
|
|
|
virStorageVolDefFindByKey(driver->pools.objs[i], key);
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
if (vol)
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = virGetStorageVol(conn,
|
2008-12-04 21:40:42 +00:00
|
|
|
driver->pools.objs[i]->def->name,
|
|
|
|
vol->name,
|
|
|
|
vol->key);
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(driver->pools.objs[i]);
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if (!ret)
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
2008-12-04 21:39:45 +00:00
|
|
|
"%s", _("no storage vol with matching key"));
|
|
|
|
|
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static virStorageVolPtr
|
|
|
|
storageVolumeLookupByPath(virConnectPtr conn,
|
|
|
|
const char *path) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = conn->storagePrivateData;
|
2008-10-10 15:13:28 +00:00
|
|
|
unsigned int i;
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageVolPtr ret = NULL;
|
2010-05-20 15:41:31 +00:00
|
|
|
char *cleanpath;
|
|
|
|
|
|
|
|
cleanpath = virFileSanitizePath(path);
|
|
|
|
if (!cleanpath)
|
|
|
|
return NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
|
|
|
for (i = 0 ; i < driver->pools.count && !ret ; i++) {
|
|
|
|
virStoragePoolObjLock(driver->pools.objs[i]);
|
2008-10-10 15:13:28 +00:00
|
|
|
if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
|
2008-11-03 11:37:11 +00:00
|
|
|
virStorageVolDefPtr vol;
|
2008-11-17 11:19:33 +00:00
|
|
|
const char *stable_path;
|
|
|
|
|
2010-02-04 20:02:58 +00:00
|
|
|
stable_path = virStorageBackendStablePath(driver->pools.objs[i],
|
2010-05-20 15:41:31 +00:00
|
|
|
cleanpath);
|
2008-11-17 11:19:33 +00:00
|
|
|
/*
|
|
|
|
* virStorageBackendStablePath already does
|
|
|
|
* virStorageReportError if it fails; we just need to keep
|
|
|
|
* propagating the return code
|
|
|
|
*/
|
2008-12-04 21:40:42 +00:00
|
|
|
if (stable_path == NULL) {
|
|
|
|
virStoragePoolObjUnlock(driver->pools.objs[i]);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-12-04 21:40:42 +00:00
|
|
|
}
|
2008-11-17 11:19:33 +00:00
|
|
|
|
|
|
|
vol = virStorageVolDefFindByPath(driver->pools.objs[i],
|
|
|
|
stable_path);
|
|
|
|
VIR_FREE(stable_path);
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
if (vol)
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = virGetStorageVol(conn,
|
|
|
|
driver->pools.objs[i]->def->name,
|
|
|
|
vol->name,
|
|
|
|
vol->key);
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjUnlock(driver->pools.objs[i]);
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if (!ret)
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
2008-12-04 21:39:45 +00:00
|
|
|
"%s", _("no storage vol with matching path"));
|
|
|
|
|
|
|
|
cleanup:
|
2010-05-20 15:41:31 +00:00
|
|
|
VIR_FREE(cleanpath);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2009-04-17 19:12:37 +00:00
|
|
|
static int storageVolumeDelete(virStorageVolPtr obj, unsigned int flags);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
static virStorageVolPtr
|
|
|
|
storageVolumeCreateXML(virStoragePoolPtr obj,
|
|
|
|
const char *xmldesc,
|
2011-07-06 22:51:23 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageBackendPtr backend;
|
2009-04-17 19:12:37 +00:00
|
|
|
virStorageVolDefPtr voldef = NULL;
|
|
|
|
virStorageVolPtr ret = NULL, volobj = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2011-07-06 22:51:23 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2010-02-10 11:42:56 +00:00
|
|
|
voldef = virStorageVolDefParseString(pool->def, xmldesc);
|
2009-04-17 19:12:37 +00:00
|
|
|
if (voldef == NULL)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2009-04-17 19:12:37 +00:00
|
|
|
if (virStorageVolDefFindByName(pool, voldef->name)) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage vol already exists"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2008-10-10 15:13:28 +00:00
|
|
|
if (VIR_REALLOC_N(pool->volumes.objs,
|
|
|
|
pool->volumes.count+1) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-10-10 15:13:28 +00:00
|
|
|
}
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!backend->createVol) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_SUPPORT,
|
2009-04-17 19:12:37 +00:00
|
|
|
"%s", _("storage pool does not support volume "
|
|
|
|
"creation"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2009-04-17 19:12:37 +00:00
|
|
|
if (backend->createVol(obj->conn, pool, voldef) < 0) {
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2009-04-17 19:12:37 +00:00
|
|
|
pool->volumes.objs[pool->volumes.count++] = voldef;
|
|
|
|
volobj = virGetStorageVol(obj->conn, pool->def->name, voldef->name,
|
|
|
|
voldef->key);
|
2011-05-03 17:44:04 +00:00
|
|
|
if (!volobj) {
|
|
|
|
pool->volumes.count--;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2008-12-04 21:39:45 +00:00
|
|
|
|
2011-05-03 17:44:04 +00:00
|
|
|
if (backend->buildVol) {
|
2009-04-17 19:12:37 +00:00
|
|
|
int buildret;
|
|
|
|
virStorageVolDefPtr buildvoldef = NULL;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(buildvoldef) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-04-17 19:12:37 +00:00
|
|
|
voldef = NULL;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make a shallow copy of the 'defined' volume definition, since the
|
|
|
|
* original allocation value will change as the user polls 'info',
|
|
|
|
* but we only need the initial requested values
|
|
|
|
*/
|
|
|
|
memcpy(buildvoldef, voldef, sizeof(*voldef));
|
|
|
|
|
|
|
|
/* Drop the pool lock during volume allocation */
|
|
|
|
pool->asyncjobs++;
|
|
|
|
voldef->building = 1;
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
|
2010-01-20 23:41:52 +00:00
|
|
|
buildret = backend->buildVol(obj->conn, pool, buildvoldef);
|
2009-04-17 19:12:37 +00:00
|
|
|
|
2009-05-19 11:06:25 +00:00
|
|
|
storageDriverLock(driver);
|
2009-04-17 19:12:37 +00:00
|
|
|
virStoragePoolObjLock(pool);
|
2009-05-19 11:06:25 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2009-04-17 19:12:37 +00:00
|
|
|
voldef->building = 0;
|
|
|
|
pool->asyncjobs--;
|
|
|
|
|
|
|
|
voldef = NULL;
|
|
|
|
VIR_FREE(buildvoldef);
|
|
|
|
|
|
|
|
if (buildret < 0) {
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
storageVolumeDelete(volobj, 0);
|
|
|
|
pool = NULL;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 15:08:44 +00:00
|
|
|
VIR_INFO("Creating volume '%s' in storage pool '%s'",
|
2011-03-30 01:19:47 +00:00
|
|
|
volobj->name, pool->def->name);
|
2009-04-17 19:12:37 +00:00
|
|
|
ret = volobj;
|
|
|
|
volobj = NULL;
|
|
|
|
voldef = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2009-04-17 19:12:37 +00:00
|
|
|
if (volobj)
|
|
|
|
virUnrefStorageVol(volobj);
|
|
|
|
virStorageVolDefFree(voldef);
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2009-05-19 13:37:51 +00:00
|
|
|
static virStorageVolPtr
|
|
|
|
storageVolumeCreateXMLFrom(virStoragePoolPtr obj,
|
|
|
|
const char *xmldesc,
|
|
|
|
virStorageVolPtr vobj,
|
2011-07-06 22:51:23 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2009-05-19 13:37:51 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool, origpool = NULL;
|
|
|
|
virStorageBackendPtr backend;
|
|
|
|
virStorageVolDefPtr origvol = NULL, newvol = NULL;
|
|
|
|
virStorageVolPtr ret = NULL, volobj = NULL;
|
2009-09-02 13:02:06 +00:00
|
|
|
int buildret;
|
2009-05-19 13:37:51 +00:00
|
|
|
|
2011-07-06 22:51:23 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2009-05-19 13:37:51 +00:00
|
|
|
storageDriverLock(driver);
|
|
|
|
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
|
2009-09-02 13:02:06 +00:00
|
|
|
if (pool && STRNEQ(obj->name, vobj->pool)) {
|
2009-07-10 16:56:12 +00:00
|
|
|
virStoragePoolObjUnlock(pool);
|
2009-05-19 13:37:51 +00:00
|
|
|
origpool = virStoragePoolObjFindByName(&driver->pools, vobj->pool);
|
2009-07-10 16:56:12 +00:00
|
|
|
virStoragePoolObjLock(pool);
|
2009-09-02 13:02:06 +00:00
|
|
|
}
|
2009-05-19 13:37:51 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2009-05-19 13:37:51 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:02:06 +00:00
|
|
|
if (STRNEQ(obj->name, vobj->pool) && !origpool) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
|
|
|
_("no storage pool with matching name '%s'"),
|
2009-07-08 10:01:35 +00:00
|
|
|
vobj->pool);
|
2009-05-19 13:37:51 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2009-05-19 13:37:51 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2009-09-02 13:02:06 +00:00
|
|
|
if (origpool && !virStoragePoolObjIsActive(origpool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2009-05-19 13:37:51 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
2009-09-02 13:02:06 +00:00
|
|
|
origvol = virStorageVolDefFindByName(origpool ? origpool : pool, vobj->name);
|
2009-05-19 13:37:51 +00:00
|
|
|
if (!origvol) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
|
|
|
_("no storage vol with matching name '%s'"),
|
2009-07-08 10:01:35 +00:00
|
|
|
vobj->name);
|
2009-05-19 13:37:51 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-02-10 11:42:56 +00:00
|
|
|
newvol = virStorageVolDefParseString(pool->def, xmldesc);
|
2009-05-19 13:37:51 +00:00
|
|
|
if (newvol == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virStorageVolDefFindByName(pool, newvol->name)) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
|
2009-05-19 13:37:51 +00:00
|
|
|
_("storage volume name '%s' already in use."),
|
|
|
|
newvol->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Is there ever a valid case for this? */
|
|
|
|
if (newvol->capacity < origvol->capacity)
|
|
|
|
newvol->capacity = origvol->capacity;
|
|
|
|
|
2009-06-22 16:33:24 +00:00
|
|
|
/* Make sure allocation is at least as large as the destination cap,
|
|
|
|
* to make absolutely sure we copy all possible contents */
|
|
|
|
if (newvol->allocation < origvol->capacity)
|
|
|
|
newvol->allocation = origvol->capacity;
|
|
|
|
|
2009-05-19 13:37:51 +00:00
|
|
|
if (!backend->buildVolFrom) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_SUPPORT,
|
2009-05-19 13:37:51 +00:00
|
|
|
"%s", _("storage pool does not support volume creation from an existing volume"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (origvol->building) {
|
2011-07-15 13:47:12 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2009-05-19 13:37:51 +00:00
|
|
|
_("volume '%s' is still being allocated."),
|
|
|
|
origvol->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (backend->refreshVol &&
|
|
|
|
backend->refreshVol(obj->conn, pool, origvol) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (VIR_REALLOC_N(pool->volumes.objs,
|
|
|
|
pool->volumes.count+1) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-05-19 13:37:51 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 'Define' the new volume so we get async progress reporting */
|
|
|
|
if (backend->createVol(obj->conn, pool, newvol) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
pool->volumes.objs[pool->volumes.count++] = newvol;
|
|
|
|
volobj = virGetStorageVol(obj->conn, pool->def->name, newvol->name,
|
|
|
|
newvol->key);
|
|
|
|
|
|
|
|
/* Drop the pool lock during volume allocation */
|
|
|
|
pool->asyncjobs++;
|
|
|
|
origvol->building = 1;
|
|
|
|
newvol->building = 1;
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
|
2009-09-02 13:02:06 +00:00
|
|
|
if (origpool) {
|
2009-05-19 13:37:51 +00:00
|
|
|
origpool->asyncjobs++;
|
|
|
|
virStoragePoolObjUnlock(origpool);
|
|
|
|
}
|
|
|
|
|
2010-01-20 23:41:52 +00:00
|
|
|
buildret = backend->buildVolFrom(obj->conn, pool, newvol, origvol, flags);
|
2009-05-19 13:37:51 +00:00
|
|
|
|
|
|
|
storageDriverLock(driver);
|
|
|
|
virStoragePoolObjLock(pool);
|
2009-09-02 13:02:06 +00:00
|
|
|
if (origpool)
|
2009-05-19 13:37:51 +00:00
|
|
|
virStoragePoolObjLock(origpool);
|
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
|
|
|
origvol->building = 0;
|
|
|
|
newvol->building = 0;
|
|
|
|
newvol = NULL;
|
|
|
|
pool->asyncjobs--;
|
|
|
|
|
2009-09-02 13:02:06 +00:00
|
|
|
if (origpool) {
|
2009-05-19 13:37:51 +00:00
|
|
|
origpool->asyncjobs--;
|
|
|
|
virStoragePoolObjUnlock(origpool);
|
|
|
|
origpool = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buildret < 0) {
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
storageVolumeDelete(volobj, 0);
|
|
|
|
pool = NULL;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 15:08:44 +00:00
|
|
|
VIR_INFO("Creating volume '%s' in storage pool '%s'",
|
2011-03-30 01:19:47 +00:00
|
|
|
volobj->name, pool->def->name);
|
2009-05-19 13:37:51 +00:00
|
|
|
ret = volobj;
|
|
|
|
volobj = NULL;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (volobj)
|
|
|
|
virUnrefStorageVol(volobj);
|
|
|
|
virStorageVolDefFree(newvol);
|
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2009-09-02 13:02:06 +00:00
|
|
|
if (origpool)
|
2009-05-19 13:37:51 +00:00
|
|
|
virStoragePoolObjUnlock(origpool);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-02-23 03:13:18 +00:00
|
|
|
|
2009-07-14 15:24:42 +00:00
|
|
|
static int
|
|
|
|
storageVolumeDownload(virStorageVolPtr obj,
|
|
|
|
virStreamPtr stream,
|
|
|
|
unsigned long long offset,
|
|
|
|
unsigned long long length,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool = NULL;
|
|
|
|
virStorageVolDefPtr vol = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
|
|
|
storageDriverLock(driver);
|
|
|
|
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
|
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
|
|
|
if (!pool) {
|
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
|
|
|
"%s", _("no storage pool with matching uuid"));
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
"%s", _("storage pool is not active"));
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
vol = virStorageVolDefFindByName(pool, obj->name);
|
|
|
|
|
|
|
|
if (vol == NULL) {
|
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
|
|
|
_("no storage vol with matching name '%s'"),
|
|
|
|
obj->name);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vol->building) {
|
2011-06-23 03:28:29 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2009-07-14 15:24:42 +00:00
|
|
|
_("volume '%s' is still being allocated."),
|
|
|
|
vol->name);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virFDStreamOpenFile(stream,
|
|
|
|
vol->target.path,
|
|
|
|
offset, length,
|
2011-08-02 17:19:53 +00:00
|
|
|
O_RDONLY) < 0)
|
2009-07-14 15:24:42 +00:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
storageVolumeUpload(virStorageVolPtr obj,
|
|
|
|
virStreamPtr stream,
|
|
|
|
unsigned long long offset,
|
|
|
|
unsigned long long length,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool = NULL;
|
|
|
|
virStorageVolDefPtr vol = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
|
|
|
storageDriverLock(driver);
|
|
|
|
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
|
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
|
|
|
if (!pool) {
|
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
|
|
|
"%s", _("no storage pool with matching uuid"));
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
"%s", _("storage pool is not active"));
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
vol = virStorageVolDefFindByName(pool, obj->name);
|
|
|
|
|
|
|
|
if (vol == NULL) {
|
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
|
|
|
_("no storage vol with matching name '%s'"),
|
|
|
|
obj->name);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vol->building) {
|
2011-07-15 13:47:12 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2009-07-14 15:24:42 +00:00
|
|
|
_("volume '%s' is still being allocated."),
|
|
|
|
vol->name);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Not using O_CREAT because the file is required to
|
|
|
|
* already exist at this point */
|
|
|
|
if (virFDStreamOpenFile(stream,
|
|
|
|
vol->target.path,
|
|
|
|
offset, length,
|
2011-08-02 17:19:53 +00:00
|
|
|
O_WRONLY) < 0)
|
2009-07-14 15:24:42 +00:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-02-23 03:13:18 +00:00
|
|
|
/* If the volume we're wiping is already a sparse file, we simply
|
|
|
|
* truncate and extend it to its original size, filling it with
|
|
|
|
* zeroes. This behavior is guaranteed by POSIX:
|
|
|
|
*
|
|
|
|
* http://www.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
|
|
|
|
*
|
|
|
|
* If fildes refers to a regular file, the ftruncate() function shall
|
|
|
|
* cause the size of the file to be truncated to length. If the size
|
|
|
|
* of the file previously exceeded length, the extra data shall no
|
|
|
|
* longer be available to reads on the file. If the file previously
|
|
|
|
* was smaller than this size, ftruncate() shall increase the size of
|
|
|
|
* the file. If the file size is increased, the extended area shall
|
|
|
|
* appear as if it were zero-filled.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
storageVolumeZeroSparseFile(virStorageVolDefPtr vol,
|
|
|
|
off_t size,
|
|
|
|
int fd)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
ret = ftruncate(fd, 0);
|
|
|
|
if (ret == -1) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Failed to truncate volume with "
|
|
|
|
"path '%s' to 0 bytes"),
|
|
|
|
vol->target.path);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ftruncate(fd, size);
|
|
|
|
if (ret == -1) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Failed to truncate volume with "
|
2010-04-02 19:44:04 +00:00
|
|
|
"path '%s' to %ju bytes"),
|
2010-12-08 00:31:14 +00:00
|
|
|
vol->target.path, (uintmax_t)size);
|
2010-02-23 03:13:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
storageWipeExtent(virStorageVolDefPtr vol,
|
|
|
|
int fd,
|
|
|
|
off_t extent_start,
|
|
|
|
off_t extent_length,
|
|
|
|
char *writebuf,
|
|
|
|
size_t writebuf_length,
|
|
|
|
size_t *bytes_wiped)
|
|
|
|
{
|
|
|
|
int ret = -1, written = 0;
|
|
|
|
off_t remaining = 0;
|
|
|
|
size_t write_size = 0;
|
|
|
|
|
|
|
|
VIR_DEBUG("extent logical start: %ju len: %ju",
|
2010-12-08 00:31:14 +00:00
|
|
|
(uintmax_t)extent_start, (uintmax_t)extent_length);
|
2010-02-23 03:13:18 +00:00
|
|
|
|
|
|
|
if ((ret = lseek(fd, extent_start, SEEK_SET)) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Failed to seek to position %ju in volume "
|
|
|
|
"with path '%s'"),
|
2010-12-08 00:31:14 +00:00
|
|
|
(uintmax_t)extent_start, vol->target.path);
|
2010-02-23 03:13:18 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
remaining = extent_length;
|
|
|
|
while (remaining > 0) {
|
|
|
|
|
|
|
|
write_size = (writebuf_length < remaining) ? writebuf_length : remaining;
|
|
|
|
written = safewrite(fd, writebuf, write_size);
|
|
|
|
if (written < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Failed to write %zu bytes to "
|
|
|
|
"storage volume with path '%s'"),
|
|
|
|
write_size, vol->target.path);
|
|
|
|
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
*bytes_wiped += written;
|
|
|
|
remaining -= written;
|
|
|
|
}
|
|
|
|
|
2011-08-18 12:40:03 +00:00
|
|
|
if (fdatasync(fd) < 0) {
|
|
|
|
ret = -errno;
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("cannot sync data to volume with path '%s'"),
|
|
|
|
vol->target.path);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2010-02-23 03:13:18 +00:00
|
|
|
VIR_DEBUG("Wrote %zu bytes to volume with path '%s'",
|
|
|
|
*bytes_wiped, vol->target.path);
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
storageVolumeWipeInternal(virStorageVolDefPtr def)
|
|
|
|
{
|
|
|
|
int ret = -1, fd = -1;
|
|
|
|
struct stat st;
|
|
|
|
char *writebuf = NULL;
|
|
|
|
size_t bytes_wiped = 0;
|
|
|
|
|
|
|
|
VIR_DEBUG("Wiping volume with path '%s'", def->target.path);
|
|
|
|
|
|
|
|
fd = open(def->target.path, O_RDWR);
|
|
|
|
if (fd == -1) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Failed to open storage volume with path '%s'"),
|
|
|
|
def->target.path);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fstat(fd, &st) == -1) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Failed to stat storage volume with path '%s'"),
|
|
|
|
def->target.path);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (S_ISREG(st.st_mode) && st.st_blocks < (st.st_size / DEV_BSIZE)) {
|
|
|
|
ret = storageVolumeZeroSparseFile(def, st.st_size, fd);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(writebuf, st.st_blksize) != 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = storageWipeExtent(def,
|
|
|
|
fd,
|
|
|
|
0,
|
|
|
|
def->allocation,
|
|
|
|
writebuf,
|
|
|
|
st.st_blksize,
|
|
|
|
&bytes_wiped);
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
VIR_FREE(writebuf);
|
|
|
|
|
2010-11-09 20:48:48 +00:00
|
|
|
VIR_FORCE_CLOSE(fd);
|
2010-02-23 03:13:18 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
storageVolumeWipe(virStorageVolPtr obj,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool = NULL;
|
|
|
|
virStorageVolDefPtr vol = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
2010-04-16 12:04:31 +00:00
|
|
|
virCheckFlags(0, -1);
|
2010-02-23 03:13:18 +00:00
|
|
|
|
|
|
|
storageDriverLock(driver);
|
|
|
|
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
|
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2010-02-23 03:13:18 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2010-02-23 03:13:18 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
vol = virStorageVolDefFindByName(pool, obj->name);
|
|
|
|
|
|
|
|
if (vol == NULL) {
|
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
|
|
|
_("no storage vol with matching name '%s'"),
|
|
|
|
obj->name);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vol->building) {
|
2011-07-15 13:47:12 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2010-02-23 03:13:18 +00:00
|
|
|
_("volume '%s' is still being allocated."),
|
|
|
|
vol->name);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (storageVolumeWipeInternal(vol) == -1) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (pool) {
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
static int
|
|
|
|
storageVolumeDelete(virStorageVolPtr obj,
|
|
|
|
unsigned int flags) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageBackendPtr backend;
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageVolDefPtr vol = NULL;
|
2008-10-10 15:13:28 +00:00
|
|
|
unsigned int i;
|
2008-12-04 21:39:45 +00:00
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
vol = virStorageVolDefFindByName(pool, obj->name);
|
|
|
|
|
|
|
|
if (!vol) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
2009-07-08 10:01:35 +00:00
|
|
|
_("no storage vol with matching name '%s'"),
|
|
|
|
obj->name);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2009-04-17 19:12:37 +00:00
|
|
|
if (vol->building) {
|
2011-07-15 13:47:12 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2009-04-17 19:12:37 +00:00
|
|
|
_("volume '%s' is still being allocated."),
|
|
|
|
vol->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!backend->deleteVol) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_SUPPORT,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool does not support vol deletion"));
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
if (backend->deleteVol(obj->conn, pool, vol, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2008-10-10 15:13:28 +00:00
|
|
|
for (i = 0 ; i < pool->volumes.count ; i++) {
|
|
|
|
if (pool->volumes.objs[i] == vol) {
|
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 15:08:44 +00:00
|
|
|
VIR_INFO("Deleting volume '%s' from storage pool '%s'",
|
2011-03-30 01:19:47 +00:00
|
|
|
vol->name, pool->def->name);
|
2008-10-10 15:13:28 +00:00
|
|
|
virStorageVolDefFree(vol);
|
2008-12-04 21:39:45 +00:00
|
|
|
vol = NULL;
|
2008-10-10 15:13:28 +00:00
|
|
|
|
|
|
|
if (i < (pool->volumes.count - 1))
|
|
|
|
memmove(pool->volumes.objs + i, pool->volumes.objs + i + 1,
|
|
|
|
sizeof(*(pool->volumes.objs)) * (pool->volumes.count - (i + 1)));
|
|
|
|
|
|
|
|
if (VIR_REALLOC_N(pool->volumes.objs, pool->volumes.count - 1) < 0) {
|
|
|
|
; /* Failure to reduce memory allocation isn't fatal */
|
|
|
|
}
|
|
|
|
pool->volumes.count--;
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
storageVolumeGetInfo(virStorageVolPtr obj,
|
|
|
|
virStorageVolInfoPtr info) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageBackendPtr backend;
|
|
|
|
virStorageVolDefPtr vol;
|
2008-12-04 21:39:45 +00:00
|
|
|
int ret = -1;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vol = virStorageVolDefFindByName(pool, obj->name);
|
|
|
|
|
|
|
|
if (!vol) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
|
|
|
_("no storage vol with matching name '%s'"),
|
2009-07-08 10:01:35 +00:00
|
|
|
obj->name);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
if (backend->refreshVol &&
|
|
|
|
backend->refreshVol(obj->conn, pool, vol) < 0)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
|
|
|
memset(info, 0, sizeof(*info));
|
2008-11-17 11:19:33 +00:00
|
|
|
info->type = vol->type;
|
2008-02-20 15:34:52 +00:00
|
|
|
info->capacity = vol->capacity;
|
|
|
|
info->allocation = vol->allocation;
|
2008-12-04 21:39:45 +00:00
|
|
|
ret = 0;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
storageVolumeGetXMLDesc(virStorageVolPtr obj,
|
2011-07-06 22:51:23 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageBackendPtr backend;
|
|
|
|
virStorageVolDefPtr vol;
|
2008-12-04 21:39:45 +00:00
|
|
|
char *ret = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2011-07-06 22:51:23 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
2008-12-04 21:39:45 +00:00
|
|
|
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverUnlock(driver);
|
|
|
|
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vol = virStorageVolDefFindByName(pool, obj->name);
|
|
|
|
|
|
|
|
if (!vol) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
2009-07-08 10:01:35 +00:00
|
|
|
_("no storage vol with matching name '%s'"),
|
|
|
|
obj->name);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2009-04-03 14:15:30 +00:00
|
|
|
|
|
|
|
if (backend->refreshVol &&
|
|
|
|
backend->refreshVol(obj->conn, pool, vol) < 0)
|
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2010-02-10 11:42:56 +00:00
|
|
|
ret = virStorageVolDefFormat(pool->def, vol);
|
2008-12-04 21:39:45 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
|
|
|
|
2008-12-04 21:39:45 +00:00
|
|
|
return ret;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
storageVolumeGetPath(virStorageVolPtr obj) {
|
2008-12-04 21:39:45 +00:00
|
|
|
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
|
2008-12-04 21:40:42 +00:00
|
|
|
virStoragePoolObjPtr pool;
|
2008-02-20 15:34:52 +00:00
|
|
|
virStorageVolDefPtr vol;
|
2008-12-04 21:39:45 +00:00
|
|
|
char *ret = NULL;
|
2008-02-20 15:34:52 +00:00
|
|
|
|
2008-12-04 21:40:42 +00:00
|
|
|
storageDriverLock(driver);
|
|
|
|
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
|
|
|
|
storageDriverUnlock(driver);
|
2008-02-20 15:34:52 +00:00
|
|
|
if (!pool) {
|
2010-05-27 12:30:34 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("no storage pool with matching uuid"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!virStoragePoolObjIsActive(pool)) {
|
2010-11-12 15:47:37 +00:00
|
|
|
virStorageReportError(VIR_ERR_OPERATION_INVALID,
|
2008-02-22 16:26:13 +00:00
|
|
|
"%s", _("storage pool is not active"));
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vol = virStorageVolDefFindByName(pool, obj->name);
|
|
|
|
|
|
|
|
if (!vol) {
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
|
|
|
|
_("no storage vol with matching name '%s'"),
|
2009-07-08 10:01:35 +00:00
|
|
|
obj->name);
|
2008-12-04 21:39:45 +00:00
|
|
|
goto cleanup;
|
2008-02-20 15:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = strdup(vol->target.path);
|
2008-12-04 21:39:45 +00:00
|
|
|
if (ret == NULL)
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-12-04 21:39:45 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:40:42 +00:00
|
|
|
if (pool)
|
|
|
|
virStoragePoolObjUnlock(pool);
|
2008-02-20 15:34:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virStorageDriver storageDriver = {
|
2008-09-22 19:53:42 +00:00
|
|
|
.name = "storage",
|
2011-05-13 13:35:01 +00:00
|
|
|
.open = storageOpen, /* 0.4.0 */
|
|
|
|
.close = storageClose, /* 0.4.0 */
|
|
|
|
.numOfPools = storageNumPools, /* 0.4.0 */
|
|
|
|
.listPools = storageListPools, /* 0.4.0 */
|
|
|
|
.numOfDefinedPools = storageNumDefinedPools, /* 0.4.0 */
|
|
|
|
.listDefinedPools = storageListDefinedPools, /* 0.4.0 */
|
|
|
|
.findPoolSources = storageFindPoolSources, /* 0.4.0 */
|
|
|
|
.poolLookupByName = storagePoolLookupByName, /* 0.4.0 */
|
|
|
|
.poolLookupByUUID = storagePoolLookupByUUID, /* 0.4.0 */
|
|
|
|
.poolLookupByVolume = storagePoolLookupByVolume, /* 0.4.0 */
|
|
|
|
.poolCreateXML = storagePoolCreate, /* 0.4.0 */
|
|
|
|
.poolDefineXML = storagePoolDefine, /* 0.4.0 */
|
|
|
|
.poolBuild = storagePoolBuild, /* 0.4.0 */
|
|
|
|
.poolUndefine = storagePoolUndefine, /* 0.4.0 */
|
|
|
|
.poolCreate = storagePoolStart, /* 0.4.0 */
|
|
|
|
.poolDestroy = storagePoolDestroy, /* 0.4.0 */
|
|
|
|
.poolDelete = storagePoolDelete, /* 0.4.0 */
|
|
|
|
.poolRefresh = storagePoolRefresh, /* 0.4.0 */
|
|
|
|
.poolGetInfo = storagePoolGetInfo, /* 0.4.0 */
|
|
|
|
.poolGetXMLDesc = storagePoolGetXMLDesc, /* 0.4.0 */
|
|
|
|
.poolGetAutostart = storagePoolGetAutostart, /* 0.4.0 */
|
|
|
|
.poolSetAutostart = storagePoolSetAutostart, /* 0.4.0 */
|
|
|
|
.poolNumOfVolumes = storagePoolNumVolumes, /* 0.4.0 */
|
|
|
|
.poolListVolumes = storagePoolListVolumes, /* 0.4.0 */
|
|
|
|
|
|
|
|
.volLookupByName = storageVolumeLookupByName, /* 0.4.0 */
|
|
|
|
.volLookupByKey = storageVolumeLookupByKey, /* 0.4.0 */
|
|
|
|
.volLookupByPath = storageVolumeLookupByPath, /* 0.4.0 */
|
|
|
|
.volCreateXML = storageVolumeCreateXML, /* 0.4.0 */
|
|
|
|
.volCreateXMLFrom = storageVolumeCreateXMLFrom, /* 0.6.4 */
|
|
|
|
.volDownload = storageVolumeDownload, /* 0.9.0 */
|
|
|
|
.volUpload = storageVolumeUpload, /* 0.9.0 */
|
|
|
|
.volDelete = storageVolumeDelete, /* 0.4.0 */
|
|
|
|
.volWipe = storageVolumeWipe, /* 0.8.0 */
|
|
|
|
.volGetInfo = storageVolumeGetInfo, /* 0.4.0 */
|
|
|
|
.volGetXMLDesc = storageVolumeGetXMLDesc, /* 0.4.0 */
|
|
|
|
.volGetPath = storageVolumeGetPath, /* 0.4.0 */
|
|
|
|
|
|
|
|
.poolIsActive = storagePoolIsActive, /* 0.7.3 */
|
|
|
|
.poolIsPersistent = storagePoolIsPersistent, /* 0.7.3 */
|
2008-02-20 15:34:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static virStateDriver stateDriver = {
|
Fix return value in virStateInitialize impl for LXC
The LXC driver was mistakenly returning -1 for lxcStartup()
in scenarios that are not an error. This caused the libvirtd
to quit for unprivileged users. This fixes the return code
of LXC driver, and also adds a "name" field to the virStateDriver
struct and logging to make it easier to find these problems
in the future
* src/driver.h: Add a 'name' field to state driver to allow
easy identification during failures
* src/libvirt.c: Log name of failed driver for virStateInit
failures
* src/lxc/lxc_driver.c: Don't return a failure code for
lxcStartup() if LXC is not available on this host, simply
disable the driver.
* src/network/bridge_driver.c, src/node_device/node_device_devkit.c,
src/node_device/node_device_hal.c, src/opennebula/one_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/secret/secret_driver.c, src/storage/storage_driver.c,
src/uml/uml_driver.c, src/xen/xen_driver.c: Fill in name
field in virStateDriver struct
2009-11-02 23:18:19 +00:00
|
|
|
.name = "Storage",
|
2008-10-06 15:40:37 +00:00
|
|
|
.initialize = storageDriverStartup,
|
|
|
|
.cleanup = storageDriverShutdown,
|
|
|
|
.reload = storageDriverReload,
|
|
|
|
.active = storageDriverActive,
|
2008-02-20 15:34:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
int storageRegister(void) {
|
|
|
|
virRegisterStorageDriver(&storageDriver);
|
|
|
|
virRegisterStateDriver(&stateDriver);
|
|
|
|
return 0;
|
|
|
|
}
|