2007-07-17 13:27:26 +00:00
|
|
|
/*
|
|
|
|
* openvz_conf.c: config functions for managing OpenVZ VEs
|
|
|
|
*
|
2012-04-04 20:30:43 +00:00
|
|
|
* Copyright (C) 2010-2012 Red Hat, Inc.
|
2007-07-17 13:27:26 +00:00
|
|
|
* Copyright (C) 2006, 2007 Binary Karma
|
|
|
|
* Copyright (C) 2006 Shuveb Hussain
|
2007-09-03 15:37:07 +00:00
|
|
|
* Copyright (C) 2007 Anoop Joe Cyriac
|
2007-07-17 13:27:26 +00:00
|
|
|
*
|
|
|
|
* 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
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2007-07-17 13:27:26 +00:00
|
|
|
*
|
2008-02-05 19:27:37 +00:00
|
|
|
* Authors:
|
2007-09-03 15:37:07 +00:00
|
|
|
* Shuveb Hussain <shuveb@binarykarma.com>
|
|
|
|
* Anoop Joe Cyriac <anoop@binarykarma.com>
|
|
|
|
*
|
2007-07-17 13:27:26 +00:00
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2007-12-05 21:40:15 +00:00
|
|
|
|
2007-07-17 13:27:26 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <time.h>
|
2007-09-03 15:37:07 +00:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <errno.h>
|
2008-06-12 13:48:29 +00:00
|
|
|
#include <string.h>
|
2008-10-24 11:32:48 +00:00
|
|
|
#include <sys/wait.h>
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2007-09-03 15:37:07 +00:00
|
|
|
#include "openvz_conf.h"
|
2012-05-07 21:00:28 +00:00
|
|
|
#include "openvz_util.h"
|
2012-12-13 18:01:25 +00:00
|
|
|
#include "viruuid.h"
|
2012-12-04 12:04:07 +00:00
|
|
|
#include "virbuffer.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2008-11-24 19:34:21 +00:00
|
|
|
#include "nodeinfo.h"
|
2011-07-19 18:32:58 +00:00
|
|
|
#include "virfile.h"
|
2012-12-12 16:27:01 +00:00
|
|
|
#include "vircommand.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2009-01-29 12:10:32 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_OPENVZ
|
|
|
|
|
2007-09-03 15:37:07 +00:00
|
|
|
static char *openvzLocateConfDir(void);
|
2009-08-03 11:50:27 +00:00
|
|
|
static int openvzGetVPSUUID(int vpsid, char *uuidstr, size_t len);
|
2008-09-05 14:10:58 +00:00
|
|
|
static int openvzAssignUUIDs(void);
|
2011-05-31 12:58:58 +00:00
|
|
|
static int openvzLocateConfFileDefault(int vpsid, char **conffile, const char *ext);
|
|
|
|
|
|
|
|
openvzLocateConfFileFunc openvzLocateConfFile = openvzLocateConfFileDefault;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2007-09-03 15:37:07 +00:00
|
|
|
int
|
2007-09-03 16:30:00 +00:00
|
|
|
strtoI(const char *str)
|
2007-09-03 15:37:07 +00:00
|
|
|
{
|
|
|
|
int val;
|
|
|
|
|
2008-07-21 13:34:19 +00:00
|
|
|
if (virStrToLong_i(str, NULL, 10, &val) < 0)
|
2010-08-31 22:43:18 +00:00
|
|
|
return 0;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2007-09-03 15:37:07 +00:00
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2008-10-24 11:32:48 +00:00
|
|
|
|
|
|
|
static int
|
2011-05-06 20:21:58 +00:00
|
|
|
openvzExtractVersionInfo(const char *cmdstr, int *retversion)
|
2008-10-24 11:32:48 +00:00
|
|
|
{
|
2011-05-06 20:21:58 +00:00
|
|
|
int ret = -1;
|
2010-03-30 14:15:13 +00:00
|
|
|
unsigned long version;
|
2011-05-06 20:21:58 +00:00
|
|
|
char *help = NULL;
|
2010-03-30 14:15:13 +00:00
|
|
|
char *tmp;
|
2011-05-06 20:21:58 +00:00
|
|
|
virCommandPtr cmd = virCommandNewArgList(cmdstr, "--help", NULL);
|
2008-10-24 11:32:48 +00:00
|
|
|
|
|
|
|
if (retversion)
|
|
|
|
*retversion = 0;
|
|
|
|
|
2011-05-06 20:21:58 +00:00
|
|
|
virCommandAddEnvString(cmd, "LC_ALL=C");
|
|
|
|
virCommandSetOutputBuffer(cmd, &help);
|
2008-10-24 11:32:48 +00:00
|
|
|
|
2011-05-06 20:21:58 +00:00
|
|
|
if (virCommandRun(cmd, NULL) < 0)
|
|
|
|
goto cleanup;
|
2008-10-24 11:32:48 +00:00
|
|
|
|
2010-03-30 14:15:13 +00:00
|
|
|
tmp = help;
|
|
|
|
|
|
|
|
/* expected format: vzctl version <major>.<minor>.<micro> */
|
|
|
|
if ((tmp = STRSKIP(tmp, "vzctl version ")) == NULL)
|
2011-05-06 20:21:58 +00:00
|
|
|
goto cleanup;
|
2008-10-24 11:32:48 +00:00
|
|
|
|
2012-04-04 20:30:43 +00:00
|
|
|
if (virParseVersionString(tmp, &version, true) < 0)
|
2011-05-06 20:21:58 +00:00
|
|
|
goto cleanup;
|
2008-10-24 11:32:48 +00:00
|
|
|
|
|
|
|
if (retversion)
|
|
|
|
*retversion = version;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
2011-05-06 20:21:58 +00:00
|
|
|
cleanup:
|
|
|
|
virCommandFree(cmd);
|
2008-10-24 11:32:48 +00:00
|
|
|
VIR_FREE(help);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-04-03 14:23:45 +00:00
|
|
|
int openvzExtractVersion(struct openvz_driver *driver)
|
2008-10-24 11:32:48 +00:00
|
|
|
{
|
|
|
|
if (driver->version > 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (openvzExtractVersionInfo(VZCTL, &driver->version) < 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Could not extract vzctl version"));
|
2008-10-24 11:32:48 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-25 19:18:16 +00:00
|
|
|
/* Parse config values of the form barrier:limit into barrier and limit */
|
|
|
|
static int
|
|
|
|
openvzParseBarrierLimit(const char* value,
|
|
|
|
unsigned long long *barrier,
|
|
|
|
unsigned long long *limit)
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
char *saveptr = NULL;
|
2013-05-03 12:45:31 +00:00
|
|
|
char *str;
|
2012-04-25 19:18:16 +00:00
|
|
|
|
2013-05-03 12:45:31 +00:00
|
|
|
if (VIR_STRDUP(str, value) < 0)
|
2012-04-25 19:18:16 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
token = strtok_r(str, ":", &saveptr);
|
|
|
|
if (token == NULL) {
|
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
if (barrier != NULL) {
|
|
|
|
if (virStrToLong_ull(token, NULL, 10, barrier))
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
token = strtok_r(NULL, ":", &saveptr);
|
|
|
|
if (token == NULL) {
|
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
if (limit != NULL) {
|
|
|
|
if (virStrToLong_ull(token, NULL, 10, limit))
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
error:
|
|
|
|
VIR_FREE(str);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-05 14:10:58 +00:00
|
|
|
virCapsPtr openvzCapsInit(void)
|
|
|
|
{
|
|
|
|
virCapsPtr caps;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
2012-12-10 22:28:09 +00:00
|
|
|
if ((caps = virCapabilitiesNew(virArchFromHost(),
|
2008-09-05 14:10:58 +00:00
|
|
|
0, 0)) == NULL)
|
|
|
|
goto no_memory;
|
|
|
|
|
2009-06-03 13:28:02 +00:00
|
|
|
if (nodeCapsInitNUMA(caps) < 0)
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
goto no_memory;
|
|
|
|
|
2008-09-05 14:10:58 +00:00
|
|
|
if ((guest = virCapabilitiesAddGuest(caps,
|
|
|
|
"exe",
|
2012-12-10 22:28:09 +00:00
|
|
|
caps->host.arch,
|
2008-09-05 14:10:58 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL)) == NULL)
|
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
|
|
"openvz",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL) == NULL)
|
|
|
|
goto no_memory;
|
|
|
|
|
2011-05-12 20:12:05 +00:00
|
|
|
return caps;
|
2013-03-13 20:39:34 +00:00
|
|
|
|
2008-09-05 14:10:58 +00:00
|
|
|
no_memory:
|
2013-02-01 12:26:18 +00:00
|
|
|
virObjectUnref(caps);
|
2008-09-05 14:10:58 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-31 12:58:58 +00:00
|
|
|
int
|
2010-04-03 14:23:45 +00:00
|
|
|
openvzReadNetworkConf(virDomainDefPtr def,
|
2008-10-10 16:08:01 +00:00
|
|
|
int veid) {
|
2008-09-22 15:21:44 +00:00
|
|
|
int ret;
|
2009-09-03 10:33:11 +00:00
|
|
|
virDomainNetDefPtr net = NULL;
|
2011-04-03 09:21:26 +00:00
|
|
|
char *temp = NULL;
|
2008-09-22 15:21:44 +00:00
|
|
|
char *token, *saveptr = NULL;
|
|
|
|
|
|
|
|
/*parse routing network configuration*
|
|
|
|
* Sample from config:
|
|
|
|
* IP_ADDRESS="1.1.1.1 1.1.1.2"
|
|
|
|
* splited IPs by space
|
|
|
|
*/
|
2011-04-03 09:21:26 +00:00
|
|
|
ret = openvzReadVPSConfigParam(veid, "IP_ADDRESS", &temp);
|
2008-09-22 15:21:44 +00:00
|
|
|
if (ret < 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not read 'IP_ADDRESS' from config for container %d"),
|
|
|
|
veid);
|
2008-09-22 15:21:44 +00:00
|
|
|
goto error;
|
|
|
|
} else if (ret > 0) {
|
|
|
|
token = strtok_r(temp, " ", &saveptr);
|
|
|
|
while (token != NULL) {
|
2008-10-10 16:08:01 +00:00
|
|
|
if (VIR_ALLOC(net) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto error;
|
2008-09-22 15:21:44 +00:00
|
|
|
|
|
|
|
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
|
2013-05-03 12:45:31 +00:00
|
|
|
if (VIR_STRDUP(net->data.ethernet.ipaddr, token) < 0)
|
|
|
|
goto error;
|
2008-09-22 15:21:44 +00:00
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
if (VIR_REALLOC_N(def->nets, def->nnets + 1) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto error;
|
2008-10-10 16:08:01 +00:00
|
|
|
def->nets[def->nnets++] = net;
|
|
|
|
net = NULL;
|
|
|
|
|
2008-09-22 15:21:44 +00:00
|
|
|
token = strtok_r(NULL, " ", &saveptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*parse bridge devices*/
|
|
|
|
/*Sample from config:
|
|
|
|
*NETIF="ifname=eth10,mac=00:18:51:C1:05:EE,host_ifname=veth105.10,host_mac=00:18:51:8F:D9:F3"
|
|
|
|
*devices splited by ';'
|
|
|
|
*/
|
2011-04-03 09:21:26 +00:00
|
|
|
ret = openvzReadVPSConfigParam(veid, "NETIF", &temp);
|
2008-09-22 15:21:44 +00:00
|
|
|
if (ret < 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not read 'NETIF' from config for container %d"),
|
|
|
|
veid);
|
2008-09-22 15:21:44 +00:00
|
|
|
goto error;
|
|
|
|
} else if (ret > 0) {
|
|
|
|
token = strtok_r(temp, ";", &saveptr);
|
|
|
|
while (token != NULL) {
|
|
|
|
/*add new device to list*/
|
2008-10-10 16:08:01 +00:00
|
|
|
if (VIR_ALLOC(net) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto error;
|
2008-09-22 15:21:44 +00:00
|
|
|
|
|
|
|
net->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
|
|
|
|
|
2009-09-08 09:07:32 +00:00
|
|
|
char *p = token;
|
2008-09-22 15:21:44 +00:00
|
|
|
char cpy_temp[32];
|
|
|
|
int len;
|
|
|
|
|
|
|
|
/*parse string*/
|
|
|
|
do {
|
2012-10-17 09:23:12 +00:00
|
|
|
char *next = strchrnul(p, ',');
|
2008-09-22 15:21:44 +00:00
|
|
|
if (STRPREFIX(p, "ifname=")) {
|
2008-11-12 16:35:47 +00:00
|
|
|
/* skip in libvirt */
|
|
|
|
} else if (STRPREFIX(p, "host_ifname=")) {
|
|
|
|
p += 12;
|
2008-09-22 15:21:44 +00:00
|
|
|
len = next - p;
|
|
|
|
if (len > 16) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Too long network device name"));
|
2008-09-22 15:21:44 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2008-11-12 16:35:47 +00:00
|
|
|
if (VIR_ALLOC_N(net->ifname, len+1) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto error;
|
2008-11-12 16:35:47 +00:00
|
|
|
|
2009-08-03 12:37:44 +00:00
|
|
|
if (virStrncpy(net->ifname, p, len, len+1) == NULL) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Network ifname %s too long for destination"), p);
|
2009-08-03 12:37:44 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2008-11-12 16:35:47 +00:00
|
|
|
} else if (STRPREFIX(p, "bridge=")) {
|
|
|
|
p += 7;
|
|
|
|
len = next - p;
|
|
|
|
if (len > 16) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Too long bridge device name"));
|
2008-11-12 16:35:47 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2008-09-22 15:21:44 +00:00
|
|
|
if (VIR_ALLOC_N(net->data.bridge.brname, len+1) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto error;
|
2008-09-22 15:21:44 +00:00
|
|
|
|
2009-08-03 12:37:44 +00:00
|
|
|
if (virStrncpy(net->data.bridge.brname, p, len, len+1) == NULL) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Bridge name %s too long for destination"), p);
|
2009-08-03 12:37:44 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2008-09-22 15:21:44 +00:00
|
|
|
} else if (STRPREFIX(p, "mac=")) {
|
|
|
|
p += 4;
|
|
|
|
len = next - p;
|
2011-01-28 21:38:06 +00:00
|
|
|
if (len != 17) { /* should be 17 */
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Wrong length MAC address"));
|
2008-09-22 15:21:44 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2009-08-03 12:37:44 +00:00
|
|
|
if (virStrncpy(cpy_temp, p, len, sizeof(cpy_temp)) == NULL) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("MAC address %s too long for destination"), p);
|
2009-08-03 12:37:44 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2012-07-17 12:07:59 +00:00
|
|
|
if (virMacAddrParse(cpy_temp, &net->mac) < 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Wrong MAC address"));
|
2008-09-22 15:21:44 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p = ++next;
|
|
|
|
} while (p < token + strlen(token));
|
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
if (VIR_REALLOC_N(def->nets, def->nnets + 1) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto error;
|
2008-10-10 16:08:01 +00:00
|
|
|
def->nets[def->nnets++] = net;
|
|
|
|
net = NULL;
|
|
|
|
|
2008-09-22 15:21:44 +00:00
|
|
|
token = strtok_r(NULL, ";", &saveptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(temp);
|
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
return 0;
|
2013-07-04 10:13:02 +00:00
|
|
|
|
2008-09-22 15:21:44 +00:00
|
|
|
error:
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(temp);
|
2008-09-22 15:21:44 +00:00
|
|
|
virDomainNetDefFree(net);
|
2008-10-10 16:08:01 +00:00
|
|
|
return -1;
|
2008-09-22 15:21:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-24 10:59:13 +00:00
|
|
|
/* utility function to replace 'from' by 'to' in 'str' */
|
|
|
|
static char*
|
|
|
|
openvz_replace(const char* str,
|
|
|
|
const char* from,
|
|
|
|
const char* to) {
|
|
|
|
const char* offset = NULL;
|
|
|
|
const char* str_start = str;
|
2009-11-10 11:56:11 +00:00
|
|
|
int to_len;
|
|
|
|
int from_len;
|
2009-03-24 10:59:13 +00:00
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
|
2009-11-10 11:56:11 +00:00
|
|
|
if ((!from) || (!to))
|
2009-03-24 10:59:13 +00:00
|
|
|
return NULL;
|
2009-11-10 11:56:11 +00:00
|
|
|
from_len = strlen(from);
|
|
|
|
to_len = strlen(to);
|
2009-03-24 10:59:13 +00:00
|
|
|
|
2010-08-31 22:43:18 +00:00
|
|
|
while ((offset = strstr(str_start, from)))
|
2009-03-24 10:59:13 +00:00
|
|
|
{
|
|
|
|
virBufferAdd(&buf, str_start, offset-str_start);
|
|
|
|
virBufferAdd(&buf, to, to_len);
|
|
|
|
str_start = offset + from_len;
|
|
|
|
}
|
|
|
|
|
2009-12-09 23:00:50 +00:00
|
|
|
virBufferAdd(&buf, str_start, -1);
|
2009-03-24 10:59:13 +00:00
|
|
|
|
2009-12-09 23:00:50 +00:00
|
|
|
if (virBufferError(&buf)) {
|
|
|
|
virBufferFreeAndReset(&buf);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-03-24 10:59:13 +00:00
|
|
|
|
|
|
|
return virBufferContentAndReset(&buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-10 12:08:19 +00:00
|
|
|
static int
|
2010-04-03 14:23:45 +00:00
|
|
|
openvzReadFSConf(virDomainDefPtr def,
|
2008-11-10 12:08:19 +00:00
|
|
|
int veid) {
|
|
|
|
int ret;
|
|
|
|
virDomainFSDefPtr fs = NULL;
|
2011-04-03 09:21:26 +00:00
|
|
|
char *veid_str = NULL;
|
|
|
|
char *temp = NULL;
|
2012-04-24 06:39:01 +00:00
|
|
|
const char *param;
|
|
|
|
unsigned long long barrier, limit;
|
2008-11-10 12:08:19 +00:00
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", &temp);
|
2008-11-10 12:08:19 +00:00
|
|
|
if (ret < 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not read 'OSTEMPLATE' from config for container %d"),
|
|
|
|
veid);
|
2008-11-10 12:08:19 +00:00
|
|
|
goto error;
|
|
|
|
} else if (ret > 0) {
|
|
|
|
if (VIR_ALLOC(fs) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto error;
|
2008-11-10 12:08:19 +00:00
|
|
|
|
|
|
|
fs->type = VIR_DOMAIN_FS_TYPE_TEMPLATE;
|
2013-05-03 12:45:31 +00:00
|
|
|
if (VIR_STRDUP(fs->src, temp) < 0)
|
|
|
|
goto error;
|
2009-03-24 10:59:13 +00:00
|
|
|
} else {
|
|
|
|
/* OSTEMPLATE was not found, VE was booted from a private dir directly */
|
2011-04-03 09:21:26 +00:00
|
|
|
ret = openvzReadVPSConfigParam(veid, "VE_PRIVATE", &temp);
|
2009-03-24 10:59:13 +00:00
|
|
|
if (ret <= 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not read 'VE_PRIVATE' from config for container %d"),
|
|
|
|
veid);
|
2009-03-24 10:59:13 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2008-11-10 12:08:19 +00:00
|
|
|
|
2009-03-24 10:59:13 +00:00
|
|
|
if (VIR_ALLOC(fs) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto error;
|
2008-11-10 12:08:19 +00:00
|
|
|
|
2009-11-08 21:08:54 +00:00
|
|
|
if (virAsprintf(&veid_str, "%d", veid) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto error;
|
2009-03-24 10:59:13 +00:00
|
|
|
|
|
|
|
fs->type = VIR_DOMAIN_FS_TYPE_MOUNT;
|
2013-05-03 12:45:31 +00:00
|
|
|
if (!(fs->src = openvz_replace(temp, "$VEID", veid_str)))
|
|
|
|
goto no_memory;
|
2008-11-10 12:08:19 +00:00
|
|
|
|
2009-03-24 10:59:13 +00:00
|
|
|
VIR_FREE(veid_str);
|
2008-11-10 12:08:19 +00:00
|
|
|
}
|
|
|
|
|
2013-05-03 12:45:31 +00:00
|
|
|
if (VIR_STRDUP(fs->dst, "/") < 0)
|
|
|
|
goto error;
|
2009-03-24 10:59:13 +00:00
|
|
|
|
2012-04-24 06:39:01 +00:00
|
|
|
param = "DISKSPACE";
|
|
|
|
ret = openvzReadVPSConfigParam(veid, param, &temp);
|
|
|
|
if (ret > 0) {
|
|
|
|
if (openvzParseBarrierLimit(temp, &barrier, &limit)) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not read '%s' from config for container %d"),
|
|
|
|
param, veid);
|
2012-04-24 06:39:01 +00:00
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
/* Ensure that we can multiply by 1024 without overflowing. */
|
2012-06-29 21:09:57 +00:00
|
|
|
if (barrier > ULLONG_MAX / 1024 ||
|
2012-10-17 09:23:12 +00:00
|
|
|
limit > ULLONG_MAX / 1024) {
|
2012-07-10 21:43:08 +00:00
|
|
|
virReportSystemError(VIR_ERR_OVERFLOW, "%s",
|
|
|
|
_("Unable to parse quota"));
|
2012-04-24 06:39:01 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
fs->space_soft_limit = barrier * 1024; /* unit is bytes */
|
|
|
|
fs->space_hard_limit = limit * 1024; /* unit is bytes */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-24 10:59:13 +00:00
|
|
|
if (VIR_REALLOC_N(def->fss, def->nfss + 1) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto error;
|
2009-03-24 10:59:13 +00:00
|
|
|
def->fss[def->nfss++] = fs;
|
|
|
|
fs = NULL;
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(temp);
|
|
|
|
|
2008-11-10 12:08:19 +00:00
|
|
|
return 0;
|
|
|
|
no_memory:
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-11-10 12:08:19 +00:00
|
|
|
error:
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(temp);
|
2008-11-10 12:08:19 +00:00
|
|
|
virDomainFSDefFree(fs);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-25 19:18:16 +00:00
|
|
|
static int
|
|
|
|
openvzReadMemConf(virDomainDefPtr def, int veid)
|
|
|
|
{
|
2013-01-08 15:40:59 +00:00
|
|
|
int ret = -1;
|
2012-04-25 19:18:16 +00:00
|
|
|
char *temp = NULL;
|
|
|
|
unsigned long long barrier, limit;
|
|
|
|
const char *param;
|
2012-05-07 21:00:28 +00:00
|
|
|
long kb_per_pages;
|
2012-04-25 19:18:16 +00:00
|
|
|
|
2012-05-07 21:00:28 +00:00
|
|
|
kb_per_pages = openvzKBPerPages();
|
|
|
|
if (kb_per_pages < 0)
|
2012-04-25 19:18:16 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
/* Memory allocation guarantee */
|
|
|
|
param = "VMGUARPAGES";
|
|
|
|
ret = openvzReadVPSConfigParam(veid, param, &temp);
|
|
|
|
if (ret < 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not read '%s' from config for container %d"),
|
|
|
|
param, veid);
|
2012-04-25 19:18:16 +00:00
|
|
|
goto error;
|
|
|
|
} else if (ret > 0) {
|
|
|
|
ret = openvzParseBarrierLimit(temp, &barrier, NULL);
|
|
|
|
if (ret < 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not parse barrier of '%s' "
|
|
|
|
"from config for container %d"), param, veid);
|
2012-04-25 19:18:16 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (barrier == LONG_MAX)
|
|
|
|
def->mem.min_guarantee = 0ull;
|
|
|
|
else
|
|
|
|
def->mem.min_guarantee = barrier * kb_per_pages;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Memory hard and soft limits */
|
|
|
|
param = "PRIVVMPAGES";
|
|
|
|
ret = openvzReadVPSConfigParam(veid, param, &temp);
|
|
|
|
if (ret < 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not read '%s' from config for container %d"),
|
|
|
|
param, veid);
|
2012-04-25 19:18:16 +00:00
|
|
|
goto error;
|
|
|
|
} else if (ret > 0) {
|
|
|
|
ret = openvzParseBarrierLimit(temp, &barrier, &limit);
|
|
|
|
if (ret < 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not parse barrier and limit of '%s' "
|
|
|
|
"from config for container %d"), param, veid);
|
2012-04-25 19:18:16 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (barrier == LONG_MAX)
|
|
|
|
def->mem.soft_limit = 0ull;
|
|
|
|
else
|
|
|
|
def->mem.soft_limit = barrier * kb_per_pages;
|
|
|
|
|
|
|
|
if (limit == LONG_MAX)
|
|
|
|
def->mem.hard_limit = 0ull;
|
|
|
|
else
|
|
|
|
def->mem.hard_limit = limit * kb_per_pages;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
error:
|
|
|
|
VIR_FREE(temp);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-03 15:37:07 +00:00
|
|
|
/* Free all memory associated with a openvz_driver structure */
|
|
|
|
void
|
|
|
|
openvzFreeDriver(struct openvz_driver *driver)
|
|
|
|
{
|
|
|
|
if (!driver)
|
|
|
|
return;
|
2008-09-05 15:00:14 +00:00
|
|
|
|
2013-03-31 18:03:42 +00:00
|
|
|
virObjectUnref(driver->xmlopt);
|
2013-01-11 13:54:15 +00:00
|
|
|
virObjectUnref(driver->domains);
|
2013-02-01 12:26:18 +00:00
|
|
|
virObjectUnref(driver->caps);
|
2010-02-15 17:33:38 +00:00
|
|
|
VIR_FREE(driver);
|
2008-09-05 15:00:14 +00:00
|
|
|
}
|
2008-07-28 14:06:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2008-09-05 14:10:58 +00:00
|
|
|
int openvzLoadDomains(struct openvz_driver *driver) {
|
2007-07-17 13:27:26 +00:00
|
|
|
int veid, ret;
|
2010-12-07 19:18:30 +00:00
|
|
|
char *status;
|
2007-07-19 16:22:40 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
2008-10-10 14:20:37 +00:00
|
|
|
virDomainObjPtr dom = NULL;
|
2013-01-11 13:54:15 +00:00
|
|
|
virDomainDefPtr def = NULL;
|
2011-04-03 09:21:26 +00:00
|
|
|
char *temp = NULL;
|
2010-12-03 00:29:34 +00:00
|
|
|
char *outbuf = NULL;
|
|
|
|
char *line;
|
|
|
|
virCommandPtr cmd = NULL;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2008-09-05 14:10:58 +00:00
|
|
|
if (openvzAssignUUIDs() < 0)
|
|
|
|
return -1;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2010-12-03 00:29:34 +00:00
|
|
|
cmd = virCommandNewArgList(VZLIST, "-a", "-ovpsid,status", "-H", NULL);
|
|
|
|
virCommandSetOutputBuffer(cmd, &outbuf);
|
|
|
|
if (virCommandRun(cmd, NULL) < 0)
|
|
|
|
goto cleanup;
|
2008-09-05 15:00:14 +00:00
|
|
|
|
2010-12-07 19:18:30 +00:00
|
|
|
line = outbuf;
|
|
|
|
while (line[0] != '\0') {
|
Merge virDomainObjListIsDuplicate into virDomainObjListAdd
The duplicate VM checking should be done atomically with
virDomainObjListAdd, so shoud not be a separate function.
Instead just use flags to indicate what kind of checks are
required.
This pair, used in virDomainCreateXML:
if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, false)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
NULL)))
goto cleanup;
This pair, used in virDomainRestoreFlags:
if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, true)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
NULL)))
goto cleanup;
This pair, used in virDomainDefineXML:
if (virDomainObjListIsDuplicate(privconn->domains, def, 0) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, false)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
0, NULL)))
goto cleanup;
2013-01-14 14:46:58 +00:00
|
|
|
unsigned int flags = 0;
|
2010-12-07 19:18:30 +00:00
|
|
|
if (virStrToLong_i(line, &status, 10, &veid) < 0 ||
|
|
|
|
*status++ != ' ' ||
|
|
|
|
(line = strchr(status, '\n')) == NULL) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Failed to parse vzlist output"));
|
2008-09-05 14:10:58 +00:00
|
|
|
goto cleanup;
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
2010-12-07 19:18:30 +00:00
|
|
|
*line++ = '\0';
|
2008-09-05 15:00:14 +00:00
|
|
|
|
2013-01-11 13:54:15 +00:00
|
|
|
if (VIR_ALLOC(def) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto cleanup;
|
2008-12-17 21:13:19 +00:00
|
|
|
|
2013-01-11 13:54:15 +00:00
|
|
|
def->virtType = VIR_DOMAIN_VIRT_OPENVZ;
|
2011-06-01 08:36:39 +00:00
|
|
|
|
2013-01-11 13:54:15 +00:00
|
|
|
if (STREQ(status, "stopped"))
|
|
|
|
def->id = -1;
|
2011-05-04 09:07:01 +00:00
|
|
|
else
|
2013-01-11 13:54:15 +00:00
|
|
|
def->id = veid;
|
|
|
|
if (virAsprintf(&def->name, "%i", veid) < 0)
|
2013-07-04 10:13:02 +00:00
|
|
|
goto cleanup;
|
2008-09-05 15:00:14 +00:00
|
|
|
|
2009-08-03 11:50:27 +00:00
|
|
|
openvzGetVPSUUID(veid, uuidstr, sizeof(uuidstr));
|
2013-01-11 13:54:15 +00:00
|
|
|
ret = virUUIDParse(uuidstr, def->uuid);
|
2008-09-05 15:00:14 +00:00
|
|
|
|
2008-09-05 14:10:58 +00:00
|
|
|
if (ret == -1) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("UUID in config file malformed"));
|
2008-09-05 14:10:58 +00:00
|
|
|
goto cleanup;
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
2008-09-05 15:00:14 +00:00
|
|
|
|
2013-05-03 12:45:31 +00:00
|
|
|
if (VIR_STRDUP(def->os.type, "exe") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (VIR_STRDUP(def->os.init, "/sbin/init") < 0)
|
|
|
|
goto cleanup;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
ret = openvzReadVPSConfigParam(veid, "CPUS", &temp);
|
2008-08-20 13:44:03 +00:00
|
|
|
if (ret < 0) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not read config for container %d"),
|
|
|
|
veid);
|
2008-09-05 14:10:58 +00:00
|
|
|
goto cleanup;
|
2008-08-20 13:44:03 +00:00
|
|
|
} else if (ret > 0) {
|
2013-01-11 13:54:15 +00:00
|
|
|
def->maxvcpus = strtoI(temp);
|
2008-08-20 13:44:03 +00:00
|
|
|
}
|
|
|
|
|
2013-01-11 13:54:15 +00:00
|
|
|
if (ret == 0 || def->maxvcpus == 0)
|
|
|
|
def->maxvcpus = openvzGetNodeCPUs();
|
|
|
|
def->vcpus = def->maxvcpus;
|
2008-11-24 19:34:21 +00:00
|
|
|
|
2008-09-05 14:10:58 +00:00
|
|
|
/* XXX load rest of VM config data .... */
|
2008-09-05 15:00:14 +00:00
|
|
|
|
2013-01-11 13:54:15 +00:00
|
|
|
openvzReadNetworkConf(def, veid);
|
|
|
|
openvzReadFSConf(def, veid);
|
|
|
|
openvzReadMemConf(def, veid);
|
2008-09-22 15:21:44 +00:00
|
|
|
|
2013-01-11 13:54:15 +00:00
|
|
|
virUUIDFormat(def->uuid, uuidstr);
|
Merge virDomainObjListIsDuplicate into virDomainObjListAdd
The duplicate VM checking should be done atomically with
virDomainObjListAdd, so shoud not be a separate function.
Instead just use flags to indicate what kind of checks are
required.
This pair, used in virDomainCreateXML:
if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, false)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
NULL)))
goto cleanup;
This pair, used in virDomainRestoreFlags:
if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, true)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
NULL)))
goto cleanup;
This pair, used in virDomainDefineXML:
if (virDomainObjListIsDuplicate(privconn->domains, def, 0) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, false)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
0, NULL)))
goto cleanup;
2013-01-14 14:46:58 +00:00
|
|
|
flags = VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE;
|
|
|
|
if (STRNEQ(status, "stopped"))
|
|
|
|
flags |= VIR_DOMAIN_OBJ_LIST_ADD_LIVE;
|
|
|
|
|
2013-01-11 13:54:15 +00:00
|
|
|
if (!(dom = virDomainObjListAdd(driver->domains,
|
|
|
|
def,
|
2013-03-28 13:55:55 +00:00
|
|
|
driver->xmlopt,
|
Merge virDomainObjListIsDuplicate into virDomainObjListAdd
The duplicate VM checking should be done atomically with
virDomainObjListAdd, so shoud not be a separate function.
Instead just use flags to indicate what kind of checks are
required.
This pair, used in virDomainCreateXML:
if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, false)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
NULL)))
goto cleanup;
This pair, used in virDomainRestoreFlags:
if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, true)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
NULL)))
goto cleanup;
This pair, used in virDomainDefineXML:
if (virDomainObjListIsDuplicate(privconn->domains, def, 0) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, false)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
0, NULL)))
goto cleanup;
2013-01-14 14:46:58 +00:00
|
|
|
flags,
|
|
|
|
NULL)))
|
2011-02-17 21:14:58 +00:00
|
|
|
goto cleanup;
|
2013-01-11 13:54:15 +00:00
|
|
|
|
|
|
|
if (STREQ(status, "stopped")) {
|
|
|
|
virDomainObjSetState(dom, VIR_DOMAIN_SHUTOFF,
|
|
|
|
VIR_DOMAIN_SHUTOFF_UNKNOWN);
|
|
|
|
dom->pid = -1;
|
|
|
|
} else {
|
|
|
|
virDomainObjSetState(dom, VIR_DOMAIN_RUNNING,
|
|
|
|
VIR_DOMAIN_RUNNING_UNKNOWN);
|
|
|
|
dom->pid = veid;
|
2012-07-09 10:11:17 +00:00
|
|
|
}
|
2013-01-11 13:54:15 +00:00
|
|
|
/* XXX OpenVZ doesn't appear to have concept of a transient domain */
|
|
|
|
dom->persistent = 1;
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2013-01-09 21:00:32 +00:00
|
|
|
virObjectUnlock(dom);
|
2008-10-10 14:20:37 +00:00
|
|
|
dom = NULL;
|
2013-01-11 13:54:15 +00:00
|
|
|
def = NULL;
|
2007-09-03 16:30:00 +00:00
|
|
|
}
|
2008-09-05 15:00:14 +00:00
|
|
|
|
2010-12-03 00:29:34 +00:00
|
|
|
virCommandFree(cmd);
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(temp);
|
2010-12-03 00:29:34 +00:00
|
|
|
VIR_FREE(outbuf);
|
2008-09-05 15:00:14 +00:00
|
|
|
|
2008-09-05 14:10:58 +00:00
|
|
|
return 0;
|
2008-09-05 15:00:14 +00:00
|
|
|
|
2008-09-05 14:10:58 +00:00
|
|
|
cleanup:
|
2010-12-03 00:29:34 +00:00
|
|
|
virCommandFree(cmd);
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(temp);
|
2010-12-03 00:29:34 +00:00
|
|
|
VIR_FREE(outbuf);
|
2012-07-11 13:35:46 +00:00
|
|
|
virObjectUnref(dom);
|
2013-01-11 13:54:15 +00:00
|
|
|
virDomainDefFree(def);
|
2008-09-05 14:10:58 +00:00
|
|
|
return -1;
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
|
|
|
|
2008-11-24 19:34:21 +00:00
|
|
|
unsigned int
|
|
|
|
openvzGetNodeCPUs(void)
|
|
|
|
{
|
|
|
|
virNodeInfo nodeinfo;
|
|
|
|
|
2013-04-26 17:21:58 +00:00
|
|
|
if (nodeGetInfo(&nodeinfo) < 0)
|
2008-11-24 19:34:21 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return nodeinfo.cpus;
|
|
|
|
}
|
2008-11-12 16:35:47 +00:00
|
|
|
|
2009-03-24 10:59:13 +00:00
|
|
|
static int
|
|
|
|
openvzWriteConfigParam(const char * conf_file, const char *param, const char *value)
|
2008-11-12 16:35:47 +00:00
|
|
|
{
|
2009-03-24 10:59:13 +00:00
|
|
|
char * temp_file = NULL;
|
2011-04-03 09:21:26 +00:00
|
|
|
int temp_fd = -1;
|
|
|
|
FILE *fp;
|
|
|
|
char *line = NULL;
|
|
|
|
size_t line_size = 0;
|
2008-11-12 16:35:47 +00:00
|
|
|
|
2013-07-04 10:13:02 +00:00
|
|
|
if (virAsprintf(&temp_file, "%s.tmp", conf_file)<0)
|
2008-11-12 16:35:47 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
fp = fopen(conf_file, "r");
|
|
|
|
if (fp == NULL)
|
2009-03-24 10:59:13 +00:00
|
|
|
goto error;
|
2008-11-12 16:35:47 +00:00
|
|
|
temp_fd = open(temp_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
|
|
if (temp_fd == -1) {
|
2009-03-24 10:59:13 +00:00
|
|
|
goto error;
|
2008-11-12 16:35:47 +00:00
|
|
|
}
|
|
|
|
|
2010-08-31 22:43:18 +00:00
|
|
|
while (1) {
|
2011-04-03 09:21:26 +00:00
|
|
|
if (getline(&line, &line_size, fp) <= 0)
|
2008-11-12 16:35:47 +00:00
|
|
|
break;
|
|
|
|
|
2008-11-17 09:55:59 +00:00
|
|
|
if (!(STRPREFIX(line, param) && line[strlen(param)] == '=')) {
|
2008-11-12 16:35:47 +00:00
|
|
|
if (safewrite(temp_fd, line, strlen(line)) !=
|
|
|
|
strlen(line))
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (safewrite(temp_fd, param, strlen(param)) < 0 ||
|
|
|
|
safewrite(temp_fd, "=\"", 2) < 0 ||
|
|
|
|
safewrite(temp_fd, value, strlen(value)) < 0 ||
|
|
|
|
safewrite(temp_fd, "\"\n", 2) < 0)
|
|
|
|
goto error;
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
if (VIR_FCLOSE(fp) < 0)
|
2008-11-12 16:35:47 +00:00
|
|
|
goto error;
|
2010-11-09 20:48:48 +00:00
|
|
|
if (VIR_CLOSE(temp_fd) < 0)
|
2008-11-12 16:35:47 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (rename(temp_file, conf_file) < 0)
|
|
|
|
goto error;
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(line);
|
|
|
|
|
2008-11-12 16:35:47 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(line);
|
|
|
|
VIR_FORCE_FCLOSE(fp);
|
2010-11-09 20:48:48 +00:00
|
|
|
VIR_FORCE_CLOSE(temp_fd);
|
2010-08-31 22:43:18 +00:00
|
|
|
if (temp_file)
|
2009-03-24 10:59:13 +00:00
|
|
|
unlink(temp_file);
|
|
|
|
VIR_FREE(temp_file);
|
2008-11-12 16:35:47 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-07-10 07:52:14 +00:00
|
|
|
int
|
2009-03-24 10:59:13 +00:00
|
|
|
openvzWriteVPSConfigParam(int vpsid, const char *param, const char *value)
|
|
|
|
{
|
2010-08-31 22:56:22 +00:00
|
|
|
char *conf_file;
|
|
|
|
int ret;
|
2009-03-24 10:59:13 +00:00
|
|
|
|
2010-08-31 22:56:22 +00:00
|
|
|
if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0)
|
2009-03-24 10:59:13 +00:00
|
|
|
return -1;
|
|
|
|
|
2010-08-31 22:56:22 +00:00
|
|
|
ret = openvzWriteConfigParam(conf_file, param, value);
|
|
|
|
VIR_FREE(conf_file);
|
|
|
|
return ret;
|
2009-03-24 10:59:13 +00:00
|
|
|
}
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
/*
|
|
|
|
* value will be freed before a new value is assigned to it, the caller is
|
|
|
|
* responsible for freeing it afterwards.
|
2011-05-26 17:28:54 +00:00
|
|
|
*
|
|
|
|
* Returns <0 on error, 0 if not found, 1 if found.
|
2011-04-03 09:21:26 +00:00
|
|
|
*/
|
2011-05-26 17:45:41 +00:00
|
|
|
int
|
2011-04-03 09:21:26 +00:00
|
|
|
openvzReadConfigParam(const char *conf_file, const char *param, char **value)
|
2008-07-10 07:52:14 +00:00
|
|
|
{
|
2011-04-03 09:21:26 +00:00
|
|
|
char *line = NULL;
|
|
|
|
size_t line_size = 0;
|
|
|
|
FILE *fp;
|
2011-05-26 17:28:54 +00:00
|
|
|
int err = 0;
|
|
|
|
char *sf, *token, *saveptr = NULL;
|
2008-07-10 07:52:14 +00:00
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
fp = fopen(conf_file, "r");
|
|
|
|
if (fp == NULL)
|
2008-07-10 07:52:14 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-05-26 17:28:54 +00:00
|
|
|
VIR_FREE(*value);
|
2011-05-27 10:35:50 +00:00
|
|
|
while (1) {
|
|
|
|
if (getline(&line, &line_size, fp) < 0) {
|
|
|
|
err = !feof(fp);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-05-26 17:28:54 +00:00
|
|
|
if (! STREQLEN(line, param, strlen(param)))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
sf = line + strlen(param);
|
|
|
|
if (*sf++ != '=') continue;
|
|
|
|
|
2008-07-10 07:52:14 +00:00
|
|
|
saveptr = NULL;
|
2011-05-26 17:28:54 +00:00
|
|
|
if ((token = strtok_r(sf, "\"\t\n", &saveptr)) != NULL) {
|
|
|
|
VIR_FREE(*value);
|
2013-05-03 12:45:31 +00:00
|
|
|
if (VIR_STRDUP(*value, token) < 0) {
|
2011-05-26 17:28:54 +00:00
|
|
|
err = 1;
|
|
|
|
break;
|
2008-07-10 07:52:14 +00:00
|
|
|
}
|
2011-05-26 17:28:54 +00:00
|
|
|
/* keep going - last entry wins */
|
|
|
|
}
|
2008-07-10 07:52:14 +00:00
|
|
|
}
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(line);
|
|
|
|
VIR_FORCE_FCLOSE(fp);
|
2008-07-10 07:52:14 +00:00
|
|
|
|
2011-05-26 17:28:54 +00:00
|
|
|
return err ? -1 : *value ? 1 : 0;
|
2008-07-10 07:52:14 +00:00
|
|
|
}
|
|
|
|
|
2009-03-24 10:59:13 +00:00
|
|
|
/*
|
2011-04-03 09:21:26 +00:00
|
|
|
* Read parameter from container config
|
|
|
|
*
|
|
|
|
* value will be freed before a new value is assined to it, the caller is
|
|
|
|
* responsible for freeing it afterwards.
|
|
|
|
*
|
|
|
|
* sample: 133, "OSTEMPLATE", &value
|
|
|
|
* return: -1 - error
|
|
|
|
* 0 - don't found
|
|
|
|
* 1 - OK
|
|
|
|
*/
|
2009-03-24 10:59:13 +00:00
|
|
|
int
|
2011-04-03 09:21:26 +00:00
|
|
|
openvzReadVPSConfigParam(int vpsid, const char *param, char **value)
|
2009-03-24 10:59:13 +00:00
|
|
|
{
|
2010-08-31 22:56:22 +00:00
|
|
|
char *conf_file;
|
|
|
|
int ret;
|
2009-03-24 10:59:13 +00:00
|
|
|
|
2010-08-31 22:56:22 +00:00
|
|
|
if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0)
|
2009-03-24 10:59:13 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
ret = openvzReadConfigParam(conf_file, param, value);
|
2010-08-31 22:56:22 +00:00
|
|
|
VIR_FREE(conf_file);
|
|
|
|
return ret;
|
2009-03-24 10:59:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
openvz_copyfile(char* from_path, char* to_path)
|
|
|
|
{
|
2011-04-03 09:21:26 +00:00
|
|
|
char *line = NULL;
|
|
|
|
size_t line_size = 0;
|
|
|
|
FILE *fp;
|
|
|
|
int copy_fd;
|
2009-03-24 10:59:13 +00:00
|
|
|
int bytes_read;
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
fp = fopen(from_path, "r");
|
|
|
|
if (fp == NULL)
|
2009-03-24 10:59:13 +00:00
|
|
|
return -1;
|
|
|
|
copy_fd = open(to_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
|
|
if (copy_fd == -1) {
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FORCE_FCLOSE(fp);
|
2009-03-24 10:59:13 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-08-31 22:43:18 +00:00
|
|
|
while (1) {
|
2011-04-03 09:21:26 +00:00
|
|
|
if (getline(&line, &line_size, fp) <= 0)
|
2009-03-24 10:59:13 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
bytes_read = strlen(line);
|
|
|
|
if (safewrite(copy_fd, line, bytes_read) != bytes_read)
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
if (VIR_FCLOSE(fp) < 0)
|
2009-03-24 10:59:13 +00:00
|
|
|
goto error;
|
2010-11-09 20:48:48 +00:00
|
|
|
if (VIR_CLOSE(copy_fd) < 0)
|
2009-03-24 10:59:13 +00:00
|
|
|
goto error;
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(line);
|
|
|
|
|
2009-03-24 10:59:13 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(line);
|
|
|
|
VIR_FORCE_FCLOSE(fp);
|
2010-11-09 20:48:48 +00:00
|
|
|
VIR_FORCE_CLOSE(copy_fd);
|
2009-03-24 10:59:13 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy the default config to the VE conf file
|
|
|
|
* return: -1 - error
|
|
|
|
* 0 - OK
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
openvzCopyDefaultConfig(int vpsid)
|
|
|
|
{
|
2011-04-03 09:21:26 +00:00
|
|
|
char *confdir = NULL;
|
|
|
|
char *default_conf_file = NULL;
|
|
|
|
char *configfile_value = NULL;
|
2010-08-31 22:56:22 +00:00
|
|
|
char *conf_file = NULL;
|
2009-03-24 10:59:13 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
if (openvzReadConfigParam(VZ_CONF_FILE, "CONFIGFILE", &configfile_value) < 0)
|
2009-03-24 10:59:13 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
confdir = openvzLocateConfDir();
|
|
|
|
if (confdir == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
2010-08-31 22:56:22 +00:00
|
|
|
if (virAsprintf(&default_conf_file, "%s/ve-%s.conf-sample", confdir,
|
2013-07-04 10:13:02 +00:00
|
|
|
configfile_value) < 0)
|
2009-03-24 10:59:13 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2010-08-31 22:56:22 +00:00
|
|
|
if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0)
|
2009-03-24 10:59:13 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (openvz_copyfile(default_conf_file, conf_file)<0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(confdir);
|
|
|
|
VIR_FREE(default_conf_file);
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(configfile_value);
|
2010-08-31 22:56:22 +00:00
|
|
|
VIR_FREE(conf_file);
|
2009-03-24 10:59:13 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-07-11 08:56:16 +00:00
|
|
|
/* Locate config file of container
|
2011-05-31 12:58:58 +00:00
|
|
|
* return -1 - error
|
|
|
|
* 0 - OK */
|
2008-07-11 08:56:16 +00:00
|
|
|
static int
|
2011-05-31 12:58:58 +00:00
|
|
|
openvzLocateConfFileDefault(int vpsid, char **conffile, const char *ext)
|
2008-07-11 08:56:16 +00:00
|
|
|
{
|
2011-05-31 12:58:58 +00:00
|
|
|
char *confdir;
|
2008-07-11 08:56:16 +00:00
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
confdir = openvzLocateConfDir();
|
|
|
|
if (confdir == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2010-08-31 22:56:22 +00:00
|
|
|
if (virAsprintf(conffile, "%s/%d.%s", confdir, vpsid,
|
2013-07-04 10:13:02 +00:00
|
|
|
ext ? ext : "conf") < 0)
|
2008-07-11 08:56:16 +00:00
|
|
|
ret = -1;
|
|
|
|
|
|
|
|
VIR_FREE(confdir);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-05-31 12:58:58 +00:00
|
|
|
static char *
|
|
|
|
openvzLocateConfDir(void)
|
2007-07-17 13:27:26 +00:00
|
|
|
{
|
|
|
|
const char *conf_dir_list[] = {"/etc/vz/conf", "/usr/local/etc/conf", NULL};
|
|
|
|
int i=0;
|
2013-05-03 12:45:31 +00:00
|
|
|
char *ret = NULL;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2010-08-31 22:43:18 +00:00
|
|
|
while (conf_dir_list[i]) {
|
2013-09-13 13:32:43 +00:00
|
|
|
if (virFileExists(conf_dir_list[i])) {
|
2013-05-03 12:45:31 +00:00
|
|
|
ignore_value(VIR_STRDUP(ret, conf_dir_list[i]));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-08-31 22:43:18 +00:00
|
|
|
i++;
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
|
|
|
|
2013-05-03 12:45:31 +00:00
|
|
|
cleanup:
|
|
|
|
return ret;
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Richard Steven's classic readline() function */
|
2008-02-05 19:27:37 +00:00
|
|
|
int
|
2007-07-19 16:22:40 +00:00
|
|
|
openvz_readline(int fd, char *ptr, int maxlen)
|
2007-07-17 13:27:26 +00:00
|
|
|
{
|
|
|
|
int n, rc;
|
|
|
|
char c;
|
|
|
|
|
2010-08-31 22:43:18 +00:00
|
|
|
for (n = 1; n < maxlen; n++) {
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((rc = read(fd, &c, 1)) == 1) {
|
2007-07-17 13:27:26 +00:00
|
|
|
*ptr++ = c;
|
2010-08-31 22:43:18 +00:00
|
|
|
if (c == '\n')
|
2007-07-17 13:27:26 +00:00
|
|
|
break;
|
2010-08-31 22:43:18 +00:00
|
|
|
} else if (rc == 0) {
|
|
|
|
if (n == 1)
|
2007-07-17 13:27:26 +00:00
|
|
|
return 0; /* EOF condition */
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return -1; /* error */
|
|
|
|
}
|
|
|
|
*ptr = 0;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2008-02-05 19:27:37 +00:00
|
|
|
static int
|
2009-08-03 11:50:27 +00:00
|
|
|
openvzGetVPSUUID(int vpsid, char *uuidstr, size_t len)
|
2007-07-17 13:27:26 +00:00
|
|
|
{
|
2010-08-31 22:56:22 +00:00
|
|
|
char *conf_file;
|
2011-04-03 09:21:26 +00:00
|
|
|
char *line = NULL;
|
|
|
|
size_t line_size = 0;
|
2010-04-06 19:33:32 +00:00
|
|
|
char *saveptr = NULL;
|
2010-03-30 14:34:43 +00:00
|
|
|
char *uuidbuf;
|
|
|
|
char *iden;
|
2011-04-03 09:21:26 +00:00
|
|
|
FILE *fp;
|
2010-08-31 22:56:22 +00:00
|
|
|
int retval = -1;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2010-08-31 22:56:22 +00:00
|
|
|
if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0)
|
2010-08-31 22:43:18 +00:00
|
|
|
return -1;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2011-04-03 09:21:26 +00:00
|
|
|
fp = fopen(conf_file, "r");
|
|
|
|
if (fp == NULL)
|
2010-08-31 22:56:22 +00:00
|
|
|
goto cleanup;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2010-08-31 22:43:18 +00:00
|
|
|
while (1) {
|
2011-05-27 11:50:13 +00:00
|
|
|
if (getline(&line, &line_size, fp) < 0) {
|
|
|
|
if (feof(fp)) { /* EOF, UUID was not found */
|
|
|
|
uuidstr[0] = 0;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
|
|
|
|
2010-03-30 14:34:43 +00:00
|
|
|
iden = strtok_r(line, " ", &saveptr);
|
|
|
|
uuidbuf = strtok_r(NULL, "\n", &saveptr);
|
|
|
|
|
|
|
|
if (iden != NULL && uuidbuf != NULL && STREQ(iden, "#UUID:")) {
|
2010-08-31 22:56:22 +00:00
|
|
|
if (virStrcpy(uuidstr, uuidbuf, len) == NULL) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("invalid uuid %s"), uuidbuf);
|
2010-08-31 22:56:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2007-07-17 13:27:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-08-31 22:56:22 +00:00
|
|
|
retval = 0;
|
|
|
|
cleanup:
|
2011-04-03 09:21:26 +00:00
|
|
|
VIR_FREE(line);
|
|
|
|
VIR_FORCE_FCLOSE(fp);
|
2010-08-31 22:56:22 +00:00
|
|
|
VIR_FREE(conf_file);
|
2008-07-10 07:52:14 +00:00
|
|
|
|
2009-08-03 12:37:44 +00:00
|
|
|
return retval;
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Do actual checking for UUID presence in conf file,
|
|
|
|
* assign if not present.
|
|
|
|
*/
|
2008-08-05 10:53:05 +00:00
|
|
|
int
|
|
|
|
openvzSetDefinedUUID(int vpsid, unsigned char *uuid)
|
2007-07-17 13:27:26 +00:00
|
|
|
{
|
2010-08-31 22:56:22 +00:00
|
|
|
char *conf_file;
|
2007-08-09 20:19:12 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
2010-11-17 02:13:29 +00:00
|
|
|
FILE *fp = NULL;
|
2010-08-31 22:56:22 +00:00
|
|
|
int ret = -1;
|
2008-08-05 10:53:05 +00:00
|
|
|
|
|
|
|
if (uuid == NULL)
|
|
|
|
return -1;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2010-08-31 22:56:22 +00:00
|
|
|
if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0)
|
2010-08-31 22:43:18 +00:00
|
|
|
return -1;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2009-08-03 11:50:27 +00:00
|
|
|
if (openvzGetVPSUUID(vpsid, uuidstr, sizeof(uuidstr)))
|
2010-08-31 22:56:22 +00:00
|
|
|
goto cleanup;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2008-02-21 18:48:06 +00:00
|
|
|
if (uuidstr[0] == 0) {
|
2010-11-17 02:13:29 +00:00
|
|
|
fp = fopen(conf_file, "a"); /* append */
|
2008-04-10 16:54:54 +00:00
|
|
|
if (fp == NULL)
|
2010-08-31 22:56:22 +00:00
|
|
|
goto cleanup;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
2007-08-09 20:19:12 +00:00
|
|
|
virUUIDFormat(uuid, uuidstr);
|
|
|
|
|
2010-11-17 02:13:29 +00:00
|
|
|
/* Record failure if fprintf or VIR_FCLOSE fails,
|
2008-04-10 16:54:54 +00:00
|
|
|
and be careful always to close the stream. */
|
2010-11-17 02:13:29 +00:00
|
|
|
if ((fprintf(fp, "\n#UUID: %s\n", uuidstr) < 0) ||
|
|
|
|
(VIR_FCLOSE(fp) == EOF))
|
2010-08-31 22:56:22 +00:00
|
|
|
goto cleanup;
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
|
|
|
|
2010-08-31 22:56:22 +00:00
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
2010-11-17 02:13:29 +00:00
|
|
|
VIR_FORCE_FCLOSE(fp);
|
2010-08-31 22:56:22 +00:00
|
|
|
VIR_FREE(conf_file);
|
|
|
|
return ret;
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
|
|
|
|
2008-08-05 10:53:05 +00:00
|
|
|
static int
|
|
|
|
openvzSetUUID(int vpsid){
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
|
2010-02-17 14:06:01 +00:00
|
|
|
if (virUUIDGenerate(uuid)) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Failed to generate UUID"));
|
2010-02-17 14:06:01 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-08-05 10:53:05 +00:00
|
|
|
|
|
|
|
return openvzSetDefinedUUID(vpsid, uuid);
|
|
|
|
}
|
|
|
|
|
2007-07-17 13:27:26 +00:00
|
|
|
/*
|
|
|
|
* Scan VPS config files and see if they have a UUID.
|
|
|
|
* If not, assign one. Just append one to the config
|
|
|
|
* file as comment so that the OpenVZ tools ignore it.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2008-09-05 14:10:58 +00:00
|
|
|
static int openvzAssignUUIDs(void)
|
2007-07-17 13:27:26 +00:00
|
|
|
{
|
|
|
|
DIR *dp;
|
|
|
|
struct dirent *dent;
|
|
|
|
char *conf_dir;
|
2010-12-07 19:18:30 +00:00
|
|
|
int vpsid;
|
|
|
|
char *ext;
|
|
|
|
int ret = 0;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
|
|
|
conf_dir = openvzLocateConfDir();
|
2008-02-21 18:22:45 +00:00
|
|
|
if (conf_dir == NULL)
|
|
|
|
return -1;
|
2007-07-17 13:27:26 +00:00
|
|
|
|
|
|
|
dp = opendir(conf_dir);
|
2010-08-31 22:43:18 +00:00
|
|
|
if (dp == NULL) {
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(conf_dir);
|
2007-07-17 13:27:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-12-07 19:18:30 +00:00
|
|
|
errno = 0;
|
2010-08-31 22:43:18 +00:00
|
|
|
while ((dent = readdir(dp))) {
|
2010-12-07 19:18:30 +00:00
|
|
|
if (virStrToLong_i(dent->d_name, &ext, 10, &vpsid) < 0 ||
|
|
|
|
*ext++ != '.' ||
|
|
|
|
STRNEQ(ext, "conf"))
|
2007-07-17 13:27:26 +00:00
|
|
|
continue;
|
2010-08-31 22:43:18 +00:00
|
|
|
if (vpsid > 0) /* '0.conf' belongs to the host, ignore it */
|
2007-07-17 13:27:26 +00:00
|
|
|
openvzSetUUID(vpsid);
|
2010-12-07 19:18:30 +00:00
|
|
|
errno = 0;
|
|
|
|
}
|
|
|
|
if (errno) {
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Failed to scan configuration directory"));
|
2010-12-07 19:18:30 +00:00
|
|
|
ret = -1;
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
2010-12-07 19:18:30 +00:00
|
|
|
|
2007-07-17 13:27:26 +00:00
|
|
|
closedir(dp);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(conf_dir);
|
2010-12-07 19:18:30 +00:00
|
|
|
return ret;
|
2007-07-17 13:27:26 +00:00
|
|
|
}
|
2010-02-19 15:49:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return CTID from name
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
int openvzGetVEID(const char *name) {
|
2010-12-03 00:29:34 +00:00
|
|
|
virCommandPtr cmd;
|
|
|
|
char *outbuf;
|
2010-12-07 19:18:30 +00:00
|
|
|
char *temp;
|
2010-02-19 15:49:56 +00:00
|
|
|
int veid;
|
2010-02-25 18:24:50 +00:00
|
|
|
bool ok;
|
2010-02-19 15:49:56 +00:00
|
|
|
|
2010-12-03 00:29:34 +00:00
|
|
|
cmd = virCommandNewArgList(VZLIST, name, "-ovpsid", "-H", NULL);
|
|
|
|
virCommandSetOutputBuffer(cmd, &outbuf);
|
|
|
|
if (virCommandRun(cmd, NULL) < 0) {
|
|
|
|
virCommandFree(cmd);
|
|
|
|
VIR_FREE(outbuf);
|
2010-02-19 15:49:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-12-03 00:29:34 +00:00
|
|
|
virCommandFree(cmd);
|
2010-12-07 19:18:30 +00:00
|
|
|
ok = virStrToLong_i(outbuf, &temp, 10, &veid) == 0 && *temp == '\n';
|
2010-12-03 00:29:34 +00:00
|
|
|
VIR_FREE(outbuf);
|
2010-02-19 15:49:56 +00:00
|
|
|
|
2010-02-25 18:24:50 +00:00
|
|
|
if (ok && veid >= 0)
|
|
|
|
return veid;
|
|
|
|
|
2012-07-18 13:13:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Failed to parse vzlist output"));
|
2010-02-19 15:49:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|