[Libvir] [patch 5/7] Cleanup configDir members
by Mark McLoughlin
server->autostartNetworkConfigDir etc. is starting to
get a little unwieldly so put the config directory
paths in an array.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/internal.h
===================================================================
--- libvirt.orig/qemud/internal.h
+++ libvirt/qemud/internal.h
@@ -54,6 +54,15 @@ typedef enum {
#endif
} qemudLogPriority;
+typedef enum {
+ QEMUD_DIR_DOMAINS = 0,
+ QEMUD_DIR_AUTO_DOMAINS,
+ QEMUD_DIR_NETWORKS,
+ QEMUD_DIR_AUTO_NETWORKS,
+
+ QEMUD_N_CONFIG_DIRS
+} qemudConfigDirType;
+
/* Different types of QEMU acceleration possible */
enum qemud_vm_virt_type {
QEMUD_VIRT_QEMU,
@@ -292,14 +301,15 @@ struct qemud_server {
struct qemud_network *networks;
brControl *brctl;
iptablesContext *iptables;
- char configDir[PATH_MAX];
- char networkConfigDir[PATH_MAX];
- char autostartConfigDir[PATH_MAX];
- char autostartNetworkConfigDir[PATH_MAX];
+ char configDirs[QEMUD_N_CONFIG_DIRS][PATH_MAX];
char errorMessage[QEMUD_MAX_ERROR_LEN];
int errorCode;
unsigned int shutdown : 1;
};
+#define domainsDir configDirs[QEMUD_DIR_DOMAINS]
+#define autoDomainsDir configDirs[QEMUD_DIR_AUTO_DOMAINS]
+#define networksDir configDirs[QEMUD_DIR_NETWORKS]
+#define autoNetworksDir configDirs[QEMUD_DIR_AUTO_NETWORKS]
int qemudStartVMDaemon(struct qemud_server *server,
struct qemud_vm *vm);
Index: libvirt/qemud/qemud.c
===================================================================
--- libvirt.orig/qemud/qemud.c
+++ libvirt/qemud/qemud.c
@@ -354,15 +354,22 @@ static int qemudListenUnix(struct qemud_
return 0;
}
-static int qemudInitPaths(int sys,
- char *configDir,
- char *networkConfigDir,
- char *autostartConfigDir,
- char *autostartNetworkConfigDir,
+static int qemudInitPaths(struct qemud_server *server,
+ int sys,
char *sockname,
char *roSockname,
int maxlen) {
+ const char *paths[] = {
+ "libvirt/qemu", /* QEMUD_DIR_DOMAINS */
+ "libvirt/qemu/autostart", /* QEMUD_DIR_AUTO_DOMAINS */
+ "libvirt/qemu/networks", /* QEMUD_DIR_NETWORKS */
+ "libvirt/qemu/networks/autostart", /* QEMUD_DIR_AUTO_NETWORKS */
+ };
+
uid_t uid;
+ struct passwd *pw;
+ const char *base = NULL;
+ int i;
uid = geteuid();
@@ -372,18 +379,6 @@ static int qemudInitPaths(int sys,
return -1;
}
- if (snprintf(configDir, maxlen, "%s/libvirt/qemu", SYSCONF_DIR) >= maxlen)
- goto snprintf_error;
-
- if (snprintf(networkConfigDir, maxlen, "%s/libvirt/qemu/networks", SYSCONF_DIR) >= maxlen)
- goto snprintf_error;
-
- if (snprintf(autostartConfigDir, maxlen, "%s/libvirt/qemu/autostart", SYSCONF_DIR) >= maxlen)
- goto snprintf_error;
-
- if (snprintf(autostartNetworkConfigDir, maxlen, "%s/libvirt/qemu/networks/autostart", SYSCONF_DIR) >= maxlen)
- goto snprintf_error;
-
if (snprintf(sockname, maxlen, "%s/run/libvirt/qemud-sock", LOCAL_STATE_DIR) >= maxlen)
goto snprintf_error;
@@ -393,30 +388,24 @@ static int qemudInitPaths(int sys,
goto snprintf_error;
unlink(sockname);
- } else {
- struct passwd *pw;
+ base = SYSCONF_DIR;
+ } else {
if (!(pw = getpwuid(uid))) {
qemudLog(QEMUD_ERR, "Failed to find user record for uid '%d': %s",
uid, strerror(errno));
return -1;
}
- if (snprintf(configDir, maxlen, "%s/.libvirt/qemu", pw->pw_dir) >= maxlen)
- goto snprintf_error;
-
- if (snprintf(networkConfigDir, maxlen, "%s/.libvirt/qemu/networks", pw->pw_dir) >= maxlen)
- goto snprintf_error;
-
- if (snprintf(autostartConfigDir, maxlen, "%s/.libvirt/qemu/autostart", pw->pw_dir) >= maxlen)
+ if (snprintf(sockname, maxlen, "@%s/.libvirt/qemud-sock", pw->pw_dir) >= maxlen)
goto snprintf_error;
- if (snprintf(autostartNetworkConfigDir, maxlen, "%s/.libvirt/qemu/networks/autostart", pw->pw_dir) >= maxlen)
- goto snprintf_error;
+ base = pw->pw_dir;
+ }
- if (snprintf(sockname, maxlen, "@%s/.libvirt/qemud-sock", pw->pw_dir) >= maxlen)
+ for (i = 0; i < QEMUD_N_CONFIG_DIRS; i++)
+ if (snprintf(server->configDirs[i], PATH_MAX, "%s/%s", base, paths[i]) >= PATH_MAX)
goto snprintf_error;
- }
return 0;
@@ -443,9 +432,7 @@ static struct qemud_server *qemudInitial
roSockname[0] = '\0';
- if (qemudInitPaths(sys, server->configDir, server->networkConfigDir,
- server->autostartConfigDir, server->autostartNetworkConfigDir,
- sockname, roSockname, PATH_MAX) < 0)
+ if (qemudInitPaths(server, sys, sockname, roSockname, PATH_MAX) < 0)
goto cleanup;
if (qemudListenUnix(server, sockname, 0) < 0)
Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -1137,7 +1137,8 @@ int qemudBuildCommandLine(struct qemud_s
/* Save a guest's config data into a persistent file */
static int qemudSaveConfig(struct qemud_server *server,
- struct qemud_vm *vm) {
+ struct qemud_vm *vm,
+ const char *configDir) {
char *xml;
int fd = -1, ret = -1;
int towrite;
@@ -1147,10 +1148,10 @@ static int qemudSaveConfig(struct qemud_
return -1;
}
- if ((err = qemudEnsureDir(!vm->autostart ? server->configDir : server->autostartConfigDir))) {
+ if ((err = qemudEnsureDir(configDir))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot create config directory %s: %s",
- server->configDir, strerror(err));
+ configDir, strerror(err));
goto cleanup;
}
@@ -1247,7 +1248,7 @@ struct qemud_vm *qemudLoadConfigXML(stru
vm->configFile[PATH_MAX-1] = '\0';
} else {
if (save) {
- if (qemudMakeConfigPath(!vm->autostart ? server->configDir : server->autostartConfigDir,
+ if (qemudMakeConfigPath(!vm->autostart ? server->domainsDir : server->autoDomainsDir,
vm->def->name, ".xml", vm->configFile, PATH_MAX) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot construct config file path");
@@ -1256,7 +1257,8 @@ struct qemud_vm *qemudLoadConfigXML(stru
return NULL;
}
- if (qemudSaveConfig(server, vm) < 0) {
+ if (qemudSaveConfig(server, vm,
+ !vm->autostart ? server->domainsDir : server->autoDomainsDir) < 0) {
if (newVM)
qemudFreeVM(vm);
return NULL;
@@ -1277,7 +1279,8 @@ struct qemud_vm *qemudLoadConfigXML(stru
static int qemudSaveNetworkConfig(struct qemud_server *server,
- struct qemud_network *network) {
+ struct qemud_network *network,
+ const char *configDir) {
char *xml;
int fd, ret = -1;
int towrite;
@@ -1287,10 +1290,10 @@ static int qemudSaveNetworkConfig(struct
return -1;
}
- if ((err = qemudEnsureDir(!network->autostart ? server->networkConfigDir : server->autostartNetworkConfigDir))) {
+ if ((err = qemudEnsureDir(configDir))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot create config directory %s: %s",
- server->networkConfigDir, strerror(err));
+ configDir, strerror(err));
goto cleanup;
}
@@ -1600,7 +1603,7 @@ struct qemud_network *qemudLoadNetworkCo
network->configFile[PATH_MAX-1] = '\0';
} else {
if (save) {
- if (qemudMakeConfigPath(!network->autostart ? server->networkConfigDir : server->autostartNetworkConfigDir,
+ if (qemudMakeConfigPath(!network->autostart ? server->networksDir : server->autoNetworksDir,
network->def->name, ".xml", network->configFile, PATH_MAX) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot construct config file path");
if (newNetwork)
@@ -1608,7 +1611,8 @@ struct qemud_network *qemudLoadNetworkCo
return NULL;
}
- if (qemudSaveNetworkConfig(server, network) < 0) {
+ if (qemudSaveNetworkConfig(server, network,
+ !network->autostart ? server->networksDir : server->autoNetworksDir) < 0) {
if (newNetwork)
qemudFreeNetwork(network);
return NULL;
@@ -1703,12 +1707,20 @@ int qemudScanConfigDir(struct qemud_serv
/* Scan for all guest and network config files */
int qemudScanConfigs(struct qemud_server *server) {
- if (qemudScanConfigDir(server, server->configDir, 1, 0) < 0 ||
- qemudScanConfigDir(server, server->autostartConfigDir, 1, 1) < 0)
- return -1;
- if (qemudScanConfigDir(server, server->networkConfigDir, 0, 0) < 0 ||
- qemudScanConfigDir(server, server->autostartNetworkConfigDir, 0, 1) < 0)
- return -1;
+ int i;
+
+ for (i = 0; i < QEMUD_N_CONFIG_DIRS; i++) {
+ int isGuest = 0, isAutostart = 0;
+
+ if (i == QEMUD_DIR_DOMAINS || i == QEMUD_DIR_AUTO_DOMAINS)
+ isGuest = 1;
+ if (i == QEMUD_DIR_AUTO_DOMAINS || i == QEMUD_DIR_AUTO_NETWORKS)
+ isAutostart = 1;
+
+ if (qemudScanConfigDir(server, server->configDirs[i], isGuest, isAutostart) < 0)
+ return -1;
+ }
+
return 0;
}
--
17 years, 9 months
[Libvir] [patch 4/7] Add autostart QEMU implementation
by Mark McLoughlin
Actually implement the autostart API in qemud by saving
autostart configs to a specific directory.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -1147,7 +1147,7 @@ static int qemudSaveConfig(struct qemud_
return -1;
}
- if ((err = qemudEnsureDir(server->configDir))) {
+ if ((err = qemudEnsureDir(!vm->autostart ? server->configDir : server->autostartConfigDir))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot create config directory %s: %s",
server->configDir, strerror(err));
@@ -1195,7 +1195,8 @@ static int qemudSaveConfig(struct qemud_
struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
const char *file,
const char *doc,
- int save) {
+ int save,
+ int isAutostart) {
struct qemud_vm_def *def = NULL;
struct qemud_vm *vm = NULL;
xmlDocPtr xml;
@@ -1239,12 +1240,15 @@ struct qemud_vm *qemudLoadConfigXML(stru
newVM = 1;
}
+ vm->autostart = (isAutostart != 0);
+
if (file) {
strncpy(vm->configFile, file, PATH_MAX);
vm->configFile[PATH_MAX-1] = '\0';
} else {
if (save) {
- if (qemudMakeConfigPath(server->configDir, vm->def->name, ".xml", vm->configFile, PATH_MAX) < 0) {
+ if (qemudMakeConfigPath(!vm->autostart ? server->configDir : server->autostartConfigDir,
+ vm->def->name, ".xml", vm->configFile, PATH_MAX) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot construct config file path");
if (newVM)
@@ -1283,7 +1287,7 @@ static int qemudSaveNetworkConfig(struct
return -1;
}
- if ((err = qemudEnsureDir(server->networkConfigDir))) {
+ if ((err = qemudEnsureDir(!network->autostart ? server->networkConfigDir : server->autostartNetworkConfigDir))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot create config directory %s: %s",
server->networkConfigDir, strerror(err));
@@ -1550,7 +1554,8 @@ static struct qemud_network_def *qemudPa
struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
const char *file,
const char *doc,
- int save) {
+ int save,
+ int isAutostart) {
struct qemud_network_def *def = NULL;
struct qemud_network *network = NULL;
xmlDocPtr xml;
@@ -1588,12 +1593,15 @@ struct qemud_network *qemudLoadNetworkCo
newNetwork = 1;
}
+ network->autostart = (isAutostart != 0);
+
if (file) {
strncpy(network->configFile, file, PATH_MAX);
network->configFile[PATH_MAX-1] = '\0';
} else {
if (save) {
- if (qemudMakeConfigPath(server->networkConfigDir, network->def->name, ".xml", network->configFile, PATH_MAX) < 0) {
+ if (qemudMakeConfigPath(!network->autostart ? server->networkConfigDir : server->autostartNetworkConfigDir,
+ network->def->name, ".xml", network->configFile, PATH_MAX) < 0) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot construct config file path");
if (newNetwork)
qemudFreeNetwork(network);
@@ -1623,7 +1631,8 @@ struct qemud_network *qemudLoadNetworkCo
/* Load a guest from its persistent config file */
static void qemudLoadConfig(struct qemud_server *server,
const char *file,
- int isGuest) {
+ int isGuest,
+ int isAutostart) {
FILE *fh;
struct stat st;
char xml[QEMUD_MAX_XML_LEN];
@@ -1651,9 +1660,9 @@ static void qemudLoadConfig(struct qemud
xml[st.st_size] = '\0';
if (isGuest) {
- qemudLoadConfigXML(server, file, xml, 1);
+ qemudLoadConfigXML(server, file, xml, 1, isAutostart);
} else {
- qemudLoadNetworkConfigXML(server, file, xml, 1);
+ qemudLoadNetworkConfigXML(server, file, xml, 1, isAutostart);
}
cleanup:
fclose(fh);
@@ -1663,7 +1672,8 @@ static void qemudLoadConfig(struct qemud
static
int qemudScanConfigDir(struct qemud_server *server,
const char *configDir,
- int isGuest) {
+ int isGuest,
+ int isAutostart) {
DIR *dir;
struct dirent *entry;
@@ -1683,7 +1693,7 @@ int qemudScanConfigDir(struct qemud_serv
if (qemudMakeConfigPath(configDir, entry->d_name, NULL, file, PATH_MAX) < 0)
continue;
- qemudLoadConfig(server, file, isGuest);
+ qemudLoadConfig(server, file, isGuest, isAutostart);
}
closedir(dir);
@@ -1693,9 +1703,13 @@ int qemudScanConfigDir(struct qemud_serv
/* Scan for all guest and network config files */
int qemudScanConfigs(struct qemud_server *server) {
- if (qemudScanConfigDir(server, server->configDir, 1) < 0)
+ if (qemudScanConfigDir(server, server->configDir, 1, 0) < 0 ||
+ qemudScanConfigDir(server, server->autostartConfigDir, 1, 1) < 0)
return -1;
- return qemudScanConfigDir(server, server->networkConfigDir, 0);
+ if (qemudScanConfigDir(server, server->networkConfigDir, 0, 0) < 0 ||
+ qemudScanConfigDir(server, server->autostartNetworkConfigDir, 0, 1) < 0)
+ return -1;
+ return 0;
}
/* Simple grow-on-demand string buffer */
Index: libvirt/qemud/conf.h
===================================================================
--- libvirt.orig/qemud/conf.h
+++ libvirt/qemud/conf.h
@@ -40,7 +40,8 @@ void qemudFreeVM(struct qemud_vm *vm);
struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
const char *file,
const char *doc,
- int persist);
+ int persist,
+ int isAutostart);
char *qemudGenerateXML(struct qemud_server *server,
struct qemud_vm *vm, int live);
@@ -49,7 +50,8 @@ void qemudFreeNetwork(struct qemud_netwo
struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
const char *file,
const char *doc,
- int persist);
+ int persist,
+ int isAutostart);
char *qemudGenerateNetworkXML(struct qemud_server *server,
struct qemud_network *network,
int live);
Index: libvirt/qemud/internal.h
===================================================================
--- libvirt.orig/qemud/internal.h
+++ libvirt/qemud/internal.h
@@ -294,6 +294,8 @@ struct qemud_server {
iptablesContext *iptables;
char configDir[PATH_MAX];
char networkConfigDir[PATH_MAX];
+ char autostartConfigDir[PATH_MAX];
+ char autostartNetworkConfigDir[PATH_MAX];
char errorMessage[QEMUD_MAX_ERROR_LEN];
int errorCode;
unsigned int shutdown : 1;
Index: libvirt/qemud/qemud.c
===================================================================
--- libvirt.orig/qemud/qemud.c
+++ libvirt/qemud/qemud.c
@@ -357,6 +357,8 @@ static int qemudListenUnix(struct qemud_
static int qemudInitPaths(int sys,
char *configDir,
char *networkConfigDir,
+ char *autostartConfigDir,
+ char *autostartNetworkConfigDir,
char *sockname,
char *roSockname,
int maxlen) {
@@ -376,6 +378,12 @@ static int qemudInitPaths(int sys,
if (snprintf(networkConfigDir, maxlen, "%s/libvirt/qemu/networks", SYSCONF_DIR) >= maxlen)
goto snprintf_error;
+ if (snprintf(autostartConfigDir, maxlen, "%s/libvirt/qemu/autostart", SYSCONF_DIR) >= maxlen)
+ goto snprintf_error;
+
+ if (snprintf(autostartNetworkConfigDir, maxlen, "%s/libvirt/qemu/networks/autostart", SYSCONF_DIR) >= maxlen)
+ goto snprintf_error;
+
if (snprintf(sockname, maxlen, "%s/run/libvirt/qemud-sock", LOCAL_STATE_DIR) >= maxlen)
goto snprintf_error;
@@ -400,6 +408,12 @@ static int qemudInitPaths(int sys,
if (snprintf(networkConfigDir, maxlen, "%s/.libvirt/qemu/networks", pw->pw_dir) >= maxlen)
goto snprintf_error;
+ if (snprintf(autostartConfigDir, maxlen, "%s/.libvirt/qemu/autostart", pw->pw_dir) >= maxlen)
+ goto snprintf_error;
+
+ if (snprintf(autostartNetworkConfigDir, maxlen, "%s/.libvirt/qemu/networks/autostart", pw->pw_dir) >= maxlen)
+ goto snprintf_error;
+
if (snprintf(sockname, maxlen, "@%s/.libvirt/qemud-sock", pw->pw_dir) >= maxlen)
goto snprintf_error;
}
@@ -430,6 +444,7 @@ static struct qemud_server *qemudInitial
roSockname[0] = '\0';
if (qemudInitPaths(sys, server->configDir, server->networkConfigDir,
+ server->autostartConfigDir, server->autostartNetworkConfigDir,
sockname, roSockname, PATH_MAX) < 0)
goto cleanup;
Index: libvirt/qemud/driver.c
===================================================================
--- libvirt.orig/qemud/driver.c
+++ libvirt/qemud/driver.c
@@ -281,7 +281,7 @@ int qemudNumDomains(struct qemud_server
struct qemud_vm *qemudDomainCreate(struct qemud_server *server, const char *xml) {
struct qemud_vm *vm;
- if (!(vm = qemudLoadConfigXML(server, NULL, xml, 0))) {
+ if (!(vm = qemudLoadConfigXML(server, NULL, xml, 0, 0))) {
return NULL;
}
@@ -464,7 +464,7 @@ int qemudDomainStart(struct qemud_server
struct qemud_vm *qemudDomainDefine(struct qemud_server *server, const char *xml) {
- return qemudLoadConfigXML(server, NULL, xml, 1);
+ return qemudLoadConfigXML(server, NULL, xml, 1, 0);
}
int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid) {
@@ -525,6 +525,9 @@ int qemudDomainSetAutostart(struct qemud
const unsigned char *uuid,
int autostart) {
struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
+ char oldConfig[PATH_MAX];
+ char *xml;
+ int ret = -1;
if (!vm) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
@@ -536,9 +539,35 @@ int qemudDomainSetAutostart(struct qemud
if (vm->autostart == autostart)
return 0;
+ if (!(xml = qemudGenerateXML(server, vm, 0)))
+ goto error;
+
+ strncpy(oldConfig, vm->configFile, PATH_MAX);
+ oldConfig[PATH_MAX-1] = '\0';
+
+ if (!qemudLoadConfigXML(server, NULL, xml, 1, autostart))
+ goto error;
+
+ if (oldConfig[0] && qemudDeleteConfig(server, oldConfig, vm->def->name) < 0) {
+ if (unlink(vm->configFile) < 0)
+ qemudLog(QEMUD_ERR, "Failed to unlink '%s' in order to roll "
+ "back in qemudDomainSetAutostart(): %s", strerror(errno));
+
+ strncpy(vm->configFile, oldConfig, PATH_MAX);
+ vm->configFile[PATH_MAX-1] = '\0';
+
+ goto error;
+ }
+
vm->autostart = autostart;
- return 0;
+ ret = 0;
+
+ error:
+ if (xml)
+ free(xml);
+
+ return ret;
}
struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
@@ -606,7 +635,7 @@ int qemudListDefinedNetworks(struct qemu
struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char *xml) {
struct qemud_network *network;
- if (!(network = qemudLoadNetworkConfigXML(server, NULL, xml, 0))) {
+ if (!(network = qemudLoadNetworkConfigXML(server, NULL, xml, 0, 0))) {
return NULL;
}
@@ -619,7 +648,7 @@ struct qemud_network *qemudNetworkCreate
}
struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) {
- return qemudLoadNetworkConfigXML(server, NULL, xml, 1);
+ return qemudLoadNetworkConfigXML(server, NULL, xml, 1, 0);
}
int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) {
@@ -730,6 +759,9 @@ int qemudNetworkSetAutostart(struct qemu
const unsigned char *uuid,
int autostart) {
struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
+ char oldConfig[PATH_MAX];
+ char *xml;
+ int ret = -1;
if (!network) {
qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
@@ -741,9 +773,35 @@ int qemudNetworkSetAutostart(struct qemu
if (network->autostart == autostart)
return 0;
+ if (!(xml = qemudGenerateNetworkXML(server, network, 0)))
+ goto error;
+
+ strncpy(oldConfig, network->configFile, PATH_MAX);
+ oldConfig[PATH_MAX-1] = '\0';
+
+ if (!qemudLoadNetworkConfigXML(server, NULL, xml, 1, autostart))
+ goto error;
+
+ if (oldConfig[0] && qemudDeleteConfig(server, oldConfig, network->def->name) < 0) {
+ if (unlink(network->configFile) < 0)
+ qemudLog(QEMUD_ERR, "Failed to unlink '%s' in order to roll "
+ "back in qemudNetworkSetAutostart(): %s", strerror(errno));
+
+ strncpy(network->configFile, oldConfig, PATH_MAX);
+ network->configFile[PATH_MAX-1] = '\0';
+
+ goto error;
+ }
+
network->autostart = autostart;
- return 0;
+ ret = 0;
+
+ error:
+ if (xml)
+ free(xml);
+
+ return ret;
}
/*
--
17 years, 9 months
[Libvir] [patch 3/7] Add autostart QEMU stubs
by Mark McLoughlin
Add the obvious parts of the QEMU implementation of
the autostart API.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/dispatch.c
===================================================================
--- libvirt.orig/qemud/dispatch.c
+++ libvirt/qemud/dispatch.c
@@ -717,6 +717,97 @@ static int qemudDispatchNetworkGetBridge
return 0;
}
+static int qemudDispatchDomainGetAutostart(struct qemud_server *server, struct qemud_client *client,
+ struct qemud_packet *in, struct qemud_packet *out)
+{
+ int ret;
+ int autostart;
+
+ if (in->header.dataSize != sizeof(in->data.domainGetAutostartRequest))
+ return -1;
+
+ autostart = 0;
+
+ ret = qemudDomainGetAutostart(server,
+ in->data.domainGetAutostartRequest.uuid,
+ &autostart);
+ if (ret < 0) {
+ if (qemudDispatchFailure(server, client, out) < 0)
+ return -1;
+ } else {
+ out->header.type = QEMUD_PKT_DOMAIN_GET_AUTOSTART;
+ out->header.dataSize = sizeof(out->data.networkGetAutostartReply);
+ out->data.networkGetAutostartReply.autostart = (autostart != 0);
+ }
+ return 0;
+}
+
+static int qemudDispatchDomainSetAutostart(struct qemud_server *server, struct qemud_client *client,
+ struct qemud_packet *in, struct qemud_packet *out)
+{
+ int ret;
+
+ if (in->header.dataSize != sizeof(in->data.domainSetAutostartRequest))
+ return -1;
+
+ ret = qemudDomainSetAutostart(server,
+ in->data.domainGetAutostartRequest.uuid,
+ in->data.domainSetAutostartRequest.autostart);
+ if (ret < 0) {
+ if (qemudDispatchFailure(server, client, out) < 0)
+ return -1;
+ } else {
+ out->header.type = QEMUD_PKT_DOMAIN_SET_AUTOSTART;
+ out->header.dataSize = 0;
+ }
+ return 0;
+}
+
+static int qemudDispatchNetworkGetAutostart(struct qemud_server *server, struct qemud_client *client,
+ struct qemud_packet *in, struct qemud_packet *out)
+{
+ int ret;
+ int autostart;
+
+ if (in->header.dataSize != sizeof(in->data.networkGetAutostartRequest))
+ return -1;
+
+ autostart = 0;
+
+ ret = qemudNetworkGetAutostart(server,
+ in->data.networkGetAutostartRequest.uuid,
+ &autostart);
+ if (ret < 0) {
+ if (qemudDispatchFailure(server, client, out) < 0)
+ return -1;
+ } else {
+ out->header.type = QEMUD_PKT_NETWORK_GET_AUTOSTART;
+ out->header.dataSize = sizeof(out->data.networkGetAutostartReply);
+ out->data.networkGetAutostartReply.autostart = (autostart != 0);
+ }
+ return 0;
+}
+
+static int qemudDispatchNetworkSetAutostart(struct qemud_server *server, struct qemud_client *client,
+ struct qemud_packet *in, struct qemud_packet *out)
+{
+ int ret;
+
+ if (in->header.dataSize != sizeof(in->data.networkSetAutostartRequest))
+ return -1;
+
+ ret = qemudNetworkSetAutostart(server,
+ in->data.networkGetAutostartRequest.uuid,
+ in->data.networkSetAutostartRequest.autostart);
+ if (ret < 0) {
+ if (qemudDispatchFailure(server, client, out) < 0)
+ return -1;
+ } else {
+ out->header.type = QEMUD_PKT_NETWORK_SET_AUTOSTART;
+ out->header.dataSize = 0;
+ }
+ return 0;
+}
typedef int (*clientFunc)(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out);
@@ -759,6 +850,10 @@ clientFunc funcsTransmitRW[QEMUD_PKT_MAX
qemudDispatchNetworkDestroy,
qemudDispatchNetworkDumpXML,
qemudDispatchNetworkGetBridgeName,
+ qemudDispatchDomainGetAutostart,
+ qemudDispatchDomainSetAutostart,
+ qemudDispatchNetworkGetAutostart,
+ qemudDispatchNetworkSetAutostart,
};
clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = {
@@ -796,6 +891,10 @@ clientFunc funcsTransmitRO[QEMUD_PKT_MAX
NULL,
qemudDispatchNetworkDumpXML,
qemudDispatchNetworkGetBridgeName,
+ qemudDispatchDomainGetAutostart,
+ NULL,
+ qemudDispatchNetworkGetAutostart,
+ NULL,
};
/*
Index: libvirt/qemud/driver.c
===================================================================
--- libvirt.orig/qemud/driver.c
+++ libvirt/qemud/driver.c
@@ -506,6 +506,41 @@ int qemudDomainUndefine(struct qemud_ser
return 0;
}
+int qemudDomainGetAutostart(struct qemud_server *server,
+ const unsigned char *uuid,
+ int *autostart) {
+ struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
+
+ if (!vm) {
+ qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
+ return -1;
+ }
+
+ *autostart = vm->autostart;
+
+ return 0;
+}
+
+int qemudDomainSetAutostart(struct qemud_server *server,
+ const unsigned char *uuid,
+ int autostart) {
+ struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
+
+ if (!vm) {
+ qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
+ return -1;
+ }
+
+ autostart = (autostart != 0);
+
+ if (vm->autostart == autostart)
+ return 0;
+
+ vm->autostart = autostart;
+
+ return 0;
+}
+
struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
const unsigned char *uuid) {
struct qemud_network *network = server->networks;
@@ -676,6 +711,41 @@ int qemudNetworkGetBridgeName(struct qem
return 0;
}
+int qemudNetworkGetAutostart(struct qemud_server *server,
+ const unsigned char *uuid,
+ int *autostart) {
+ struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
+
+ if (!network) {
+ qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
+ return -1;
+ }
+
+ *autostart = network->autostart;
+
+ return 0;
+}
+
+int qemudNetworkSetAutostart(struct qemud_server *server,
+ const unsigned char *uuid,
+ int autostart) {
+ struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
+
+ if (!network) {
+ qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
+ return -1;
+ }
+
+ autostart = (autostart != 0);
+
+ if (network->autostart == autostart)
+ return 0;
+
+ network->autostart = autostart;
+
+ return 0;
+}
+
/*
* Local variables:
* indent-tabs-mode: nil
Index: libvirt/qemud/driver.h
===================================================================
--- libvirt.orig/qemud/driver.h
+++ libvirt/qemud/driver.h
@@ -85,6 +85,12 @@ struct qemud_vm *qemudDomainDefine(struc
const char *xml);
int qemudDomainUndefine(struct qemud_server *server,
const unsigned char *uuid);
+int qemudDomainGetAutostart(struct qemud_server *server,
+ const unsigned char *uuid,
+ int *autostart);
+int qemudDomainSetAutostart(struct qemud_server *server,
+ const unsigned char *uuid,
+ int autostart);
struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
const unsigned char *uuid);
@@ -117,6 +123,12 @@ int qemudNetworkGetBridgeName(struct qem
const unsigned char *uuid,
char *ifname,
int ifnamelen);
+int qemudNetworkGetAutostart(struct qemud_server *server,
+ const unsigned char *uuid,
+ int *autostart);
+int qemudNetworkSetAutostart(struct qemud_server *server,
+ const unsigned char *uuid,
+ int autostart);
#endif
Index: libvirt/qemud/internal.h
===================================================================
--- libvirt.orig/qemud/internal.h
+++ libvirt/qemud/internal.h
@@ -210,6 +210,7 @@ struct qemud_vm {
struct qemud_vm_def *newDef; /* New definition to activate at shutdown */
unsigned int active : 1;
+ unsigned int autostart : 1;
struct qemud_vm *next;
};
@@ -249,6 +250,7 @@ struct qemud_network {
int dnsmasqPid;
unsigned int active : 1;
+ unsigned int autostart : 1;
struct qemud_network *next;
};
Index: libvirt/qemud/protocol.h
===================================================================
--- libvirt.orig/qemud/protocol.h
+++ libvirt/qemud/protocol.h
@@ -64,6 +64,10 @@ enum {
QEMUD_PKT_NETWORK_DESTROY,
QEMUD_PKT_NETWORK_DUMP_XML,
QEMUD_PKT_NETWORK_GET_BRIDGE_NAME,
+ QEMUD_PKT_DOMAIN_GET_AUTOSTART,
+ QEMUD_PKT_DOMAIN_SET_AUTOSTART,
+ QEMUD_PKT_NETWORK_GET_AUTOSTART,
+ QEMUD_PKT_NETWORK_SET_AUTOSTART,
QEMUD_PKT_MAX,
} qemud_packet_type;
@@ -279,6 +283,26 @@ union qemud_packet_data {
struct {
char ifname[QEMUD_MAX_IFNAME_LEN];
} networkGetBridgeNameReply;
+ struct {
+ unsigned char uuid[QEMUD_UUID_RAW_LEN];
+ } domainGetAutostartRequest;
+ struct {
+ int autostart;
+ } domainGetAutostartReply;
+ struct {
+ unsigned char uuid[QEMUD_UUID_RAW_LEN];
+ unsigned int autostart : 1;
+ } domainSetAutostartRequest;
+ struct {
+ unsigned char uuid[QEMUD_UUID_RAW_LEN];
+ } networkGetAutostartRequest;
+ struct {
+ unsigned int autostart : 1;
+ } networkGetAutostartReply;
+ struct {
+ unsigned char uuid[QEMUD_UUID_RAW_LEN];
+ unsigned int autostart : 1;
+ } networkSetAutostartRequest;
};
/* Each packet has header & data */
Index: libvirt/src/qemu_internal.c
===================================================================
--- libvirt.orig/src/qemu_internal.c
+++ libvirt/src/qemu_internal.c
@@ -806,6 +806,39 @@ static int qemuUndefine(virDomainPtr dom
return ret;
}
+static int qemuDomainGetAutostart(virDomainPtr dom,
+ int *autostart) {
+ struct qemud_packet req, reply;
+
+ req.header.type = QEMUD_PKT_DOMAIN_GET_AUTOSTART;
+ req.header.dataSize = sizeof(req.data.domainGetAutostartRequest);
+ memmove(req.data.domainGetAutostartRequest.uuid, dom->uuid, QEMUD_UUID_RAW_LEN);
+
+ if (qemuProcessRequest(dom->conn, NULL, &req, &reply) < 0) {
+ return -1;
+ }
+
+ *autostart = reply.data.domainGetAutostartReply.autostart;
+
+ return 0;
+}
+
+static int qemuDomainSetAutostart(virDomainPtr dom,
+ int autostart) {
+ struct qemud_packet req, reply;
+
+ req.header.type = QEMUD_PKT_DOMAIN_SET_AUTOSTART;
+ req.header.dataSize = sizeof(req.data.domainSetAutostartRequest);
+ req.data.domainSetAutostartRequest.autostart = (autostart != 0);
+ memmove(req.data.domainSetAutostartRequest.uuid, dom->uuid, QEMUD_UUID_RAW_LEN);
+
+ if (qemuProcessRequest(dom->conn, NULL, &req, &reply) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
static int qemuNetworkOpen(virConnectPtr conn,
const char *name,
int flags) {
@@ -1093,6 +1126,39 @@ static char * qemuNetworkGetBridgeName(v
return strdup(reply.data.networkGetBridgeNameReply.ifname);
}
+static int qemuNetworkGetAutostart(virNetworkPtr network,
+ int *autostart) {
+ struct qemud_packet req, reply;
+
+ req.header.type = QEMUD_PKT_NETWORK_GET_AUTOSTART;
+ req.header.dataSize = sizeof(req.data.networkGetAutostartRequest);
+ memmove(req.data.networkGetAutostartRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
+
+ if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+ return -1;
+ }
+
+ *autostart = reply.data.networkGetAutostartReply.autostart;
+
+ return 0;
+}
+
+static int qemuNetworkSetAutostart(virNetworkPtr network,
+ int autostart) {
+ struct qemud_packet req, reply;
+
+ req.header.type = QEMUD_PKT_NETWORK_SET_AUTOSTART;
+ req.header.dataSize = sizeof(req.data.networkSetAutostartRequest);
+ req.data.networkSetAutostartRequest.autostart = (autostart != 0);
+ memmove(req.data.networkSetAutostartRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
+
+ if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
static virDriver qemuDriver = {
VIR_DRV_QEMU,
"QEMU",
@@ -1132,8 +1198,8 @@ static virDriver qemuDriver = {
qemuUndefine, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
- NULL, /* domainGetAutostart */
- NULL, /* domainSetAutostart */
+ qemuDomainGetAutostart, /* domainGetAutostart */
+ qemuDomainSetAutostart, /* domainSetAutostart */
};
static virNetworkDriver qemuNetworkDriver = {
@@ -1152,8 +1218,8 @@ static virNetworkDriver qemuNetworkDrive
qemuNetworkDestroy, /* networkDestroy */
qemuNetworkDumpXML, /* networkDumpXML */
qemuNetworkGetBridgeName, /* networkGetBridgeName */
- NULL, /* networkGetAutostart */
- NULL, /* networkSetAutostart */
+ qemuNetworkGetAutostart, /* networkGetAutostart */
+ qemuNetworkSetAutostart, /* networkSetAutostart */
};
void qemuRegister(void) {
--
17 years, 9 months
[Libvir] [patch 2/7] Add autostart API
by Mark McLoughlin
Add virDomainGetAutostart(), virDomainSetAutostart(),
virNetworkGetAutostart() and virNetworkSetAutostart().
Add the methods to the drivers' vtables, but don't
actually implement it anywhere.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/include/libvirt/libvirt.h.in
===================================================================
--- libvirt.orig/include/libvirt/libvirt.h.in
+++ libvirt/include/libvirt/libvirt.h.in
@@ -328,6 +328,11 @@ int virConnectListDefinedDomains (virC
int maxnames);
int virDomainCreate (virDomainPtr domain);
+int virDomainGetAutostart (virDomainPtr domain,
+ int *autostart);
+int virDomainSetAutostart (virDomainPtr domain,
+ int autostart);
+
/**
* virVcpuInfo: structure for information about a virtual CPU in a domain.
*/
@@ -528,6 +533,11 @@ char * virNetworkGetXMLDesc (virNetwor
int flags);
char * virNetworkGetBridgeName (virNetworkPtr network);
+int virNetworkGetAutostart (virNetworkPtr network,
+ int *autostart);
+int virNetworkSetAutostart (virNetworkPtr network,
+ int autostart);
+
#ifdef __cplusplus
}
#endif
Index: libvirt/src/libvirt.c
===================================================================
--- libvirt.orig/src/libvirt.c
+++ libvirt/src/libvirt.c
@@ -1862,6 +1862,69 @@ virDomainCreate(virDomainPtr domain) {
}
/**
+ * virDomainGetAutostart:
+ * @domain: a domain object
+ *
+ * Return a boolean value indicating whether the domain
+ * configured to be automatically started when the host
+ * machine boots.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virDomainGetAutostart(virDomainPtr domain,
+ int *autostart) {
+ int i;
+
+ if (!VIR_IS_DOMAIN(domain)) {
+ virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (!autostart) {
+ virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ for (i = 0;i < domain->conn->nb_drivers;i++) {
+ if ((domain->conn->drivers[i] != NULL) &&
+ (domain->conn->drivers[i]->domainGetAutostart != NULL) &&
+ (domain->conn->drivers[i]->domainGetAutostart(domain, autostart) == 0))
+ return (0);
+ }
+ virLibConnError(domain->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return (-1);
+}
+
+/**
+ * virDomainSetAutostart:
+ * @domain: a domain object
+ *
+ * Configure the domain to be automatically started
+ * when the host machine boots.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virDomainSetAutostart(virDomainPtr domain,
+ int autostart) {
+ int i;
+
+ if (!VIR_IS_DOMAIN(domain)) {
+ virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+
+ for (i = 0;i < domain->conn->nb_drivers;i++) {
+ if ((domain->conn->drivers[i] != NULL) &&
+ (domain->conn->drivers[i]->domainSetAutostart != NULL) &&
+ (domain->conn->drivers[i]->domainSetAutostart(domain, autostart) == 0))
+ return (0);
+ }
+ virLibConnError(domain->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return (-1);
+}
+
+/**
* virDomainSetVcpus:
* @domain: pointer to domain object, or NULL for Domain0
* @nvcpus: the new number of virtual CPUs for this domain
@@ -2766,3 +2829,66 @@ virNetworkGetBridgeName(virNetworkPtr ne
}
return(ret);
}
+
+/**
+ * virNetworkGetAutostart:
+ * @network: a network object
+ *
+ * Return a boolean value indicating whether the network
+ * configured to be automatically started when the host
+ * machine boots.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virNetworkGetAutostart(virNetworkPtr network,
+ int *autostart) {
+ int i;
+
+ if (!VIR_IS_NETWORK(network)) {
+ virLibNetworkError(network, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
+ return (-1);
+ }
+ if (!autostart) {
+ virLibNetworkError(network, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ for (i = 0;i < network->conn->nb_network_drivers;i++) {
+ if ((network->conn->networkDrivers[i] != NULL) &&
+ (network->conn->networkDrivers[i]->networkGetAutostart != NULL) &&
+ (network->conn->networkDrivers[i]->networkGetAutostart(network, autostart) == 0))
+ return (0);
+ }
+ virLibConnError(network->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return (-1);
+}
+
+/**
+ * virNetworkSetAutostart:
+ * @network: a network object
+ *
+ * Configure the network to be automatically started
+ * when the host machine boots.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virNetworkSetAutostart(virNetworkPtr network,
+ int autostart) {
+ int i;
+
+ if (!VIR_IS_NETWORK(network)) {
+ virLibNetworkError(network, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
+ return (-1);
+ }
+
+ for (i = 0;i < network->conn->nb_network_drivers;i++) {
+ if ((network->conn->networkDrivers[i] != NULL) &&
+ (network->conn->networkDrivers[i]->networkSetAutostart != NULL) &&
+ (network->conn->networkDrivers[i]->networkSetAutostart(network, autostart) == 0))
+ return (0);
+ }
+ virLibConnError(network->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return (-1);
+}
Index: libvirt/src/driver.h
===================================================================
--- libvirt.orig/src/driver.h
+++ libvirt/src/driver.h
@@ -134,6 +134,12 @@ typedef int
typedef int
(*virDrvDomainDetachDevice) (virDomainPtr domain,
char *xml);
+typedef int
+ (*virDrvDomainGetAutostart) (virDomainPtr domain,
+ int *autostart);
+typedef int
+ (*virDrvDomainSetAutostart) (virDomainPtr domain,
+ int autostart);
typedef struct _virDriver virDriver;
typedef virDriver *virDriverPtr;
@@ -183,6 +189,8 @@ struct _virDriver {
virDrvDomainUndefine domainUndefine;
virDrvDomainAttachDevice domainAttachDevice;
virDrvDomainDetachDevice domainDetachDevice;
+ virDrvDomainGetAutostart domainGetAutostart;
+ virDrvDomainSetAutostart domainSetAutostart;
};
typedef int
@@ -219,6 +227,13 @@ typedef char *
int flags);
typedef char *
(*virDrvNetworkGetBridgeName) (virNetworkPtr network);
+typedef int
+ (*virDrvNetworkGetAutostart) (virNetworkPtr network,
+ int *autostart);
+typedef int
+ (*virDrvNetworkSetAutostart) (virNetworkPtr network,
+ int autostart);
+
typedef struct _virNetworkDriver virNetworkDriver;
typedef virNetworkDriver *virNetworkDriverPtr;
@@ -245,6 +260,8 @@ struct _virNetworkDriver {
virDrvNetworkDestroy networkDestroy;
virDrvNetworkDumpXML networkDumpXML;
virDrvNetworkGetBridgeName networkGetBridgeName;
+ virDrvNetworkGetAutostart networkGetAutostart;
+ virDrvNetworkSetAutostart networkSetAutostart;
};
Index: libvirt/src/proxy_internal.c
===================================================================
--- libvirt.orig/src/proxy_internal.c
+++ libvirt/src/proxy_internal.c
@@ -81,6 +81,8 @@ static virDriver xenProxyDriver = {
NULL, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
+ NULL, /* domainGetAutostart */
+ NULL, /* domainSetAutostart */
};
/**
Index: libvirt/src/qemu_internal.c
===================================================================
--- libvirt.orig/src/qemu_internal.c
+++ libvirt/src/qemu_internal.c
@@ -1132,6 +1132,8 @@ static virDriver qemuDriver = {
qemuUndefine, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
+ NULL, /* domainGetAutostart */
+ NULL, /* domainSetAutostart */
};
static virNetworkDriver qemuNetworkDriver = {
@@ -1150,6 +1152,8 @@ static virNetworkDriver qemuNetworkDrive
qemuNetworkDestroy, /* networkDestroy */
qemuNetworkDumpXML, /* networkDumpXML */
qemuNetworkGetBridgeName, /* networkGetBridgeName */
+ NULL, /* networkGetAutostart */
+ NULL, /* networkSetAutostart */
};
void qemuRegister(void) {
Index: libvirt/src/test.c
===================================================================
--- libvirt.orig/src/test.c
+++ libvirt/src/test.c
@@ -125,6 +125,8 @@ static virDriver testDriver = {
testDomainUndefine, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
+ NULL, /* domainGetAutostart */
+ NULL, /* domainSetAutostart */
};
typedef struct _testDev {
Index: libvirt/src/xen_internal.c
===================================================================
--- libvirt.orig/src/xen_internal.c
+++ libvirt/src/xen_internal.c
@@ -454,6 +454,8 @@ static virDriver xenHypervisorDriver = {
NULL, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
+ NULL, /* domainGetAutostart */
+ NULL, /* domainSetAutostart */
};
#endif /* !PROXY */
Index: libvirt/src/xend_internal.c
===================================================================
--- libvirt.orig/src/xend_internal.c
+++ libvirt/src/xend_internal.c
@@ -96,7 +96,9 @@ static virDriver xenDaemonDriver = {
xenDaemonDomainDefineXML, /* domainDefineXML */
xenDaemonDomainUndefine, /* domainUndefine */
xenDaemonAttachDevice, /* domainAttachDevice */
- xenDaemonDetachDevice /* domainDetachDevice */
+ xenDaemonDetachDevice, /* domainDetachDevice */
+ NULL, /* domainGetAutostart */
+ NULL, /* domainSetAutostart */
};
/**
Index: libvirt/src/xm_internal.c
===================================================================
--- libvirt.orig/src/xm_internal.c
+++ libvirt/src/xm_internal.c
@@ -104,6 +104,8 @@ static virDriver xenXMDriver = {
xenXMDomainUndefine, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
+ NULL, /* domainGetAutostart */
+ NULL, /* domainSetAutostart */
};
static void
Index: libvirt/src/xs_internal.c
===================================================================
--- libvirt.orig/src/xs_internal.c
+++ libvirt/src/xs_internal.c
@@ -75,6 +75,8 @@ static virDriver xenStoreDriver = {
NULL, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
+ NULL, /* domainGetAutostart */
+ NULL, /* domainSetAutostart */
};
/**
Index: libvirt/src/libvirt_sym.version
===================================================================
--- libvirt.orig/src/libvirt_sym.version
+++ libvirt/src/libvirt_sym.version
@@ -37,6 +37,8 @@
virConnectListDefinedDomains;
virConnectNumOfDefinedDomains;
virDomainUndefine;
+ virDomainGetAutostart;
+ virDomainSetAutostart;
virGetVersion;
virCopyLastError;
virConnSetErrorFunc;
@@ -76,6 +78,8 @@
virNetworkGetUUIDString;
virNetworkGetXMLDesc;
virNetworkGetBridgeName;
+ virNetworkGetAutostart;
+ virNetworkSetAutostart;
local: *;
};
--
17 years, 9 months
[Libvir] [patch 1/7] Merge the active and inactive network/guest lists
by Mark McLoughlin
Merge the ->activevms and ->inactivevms into a single
->vms list where each VM has a "active" flag in order
to make things easier to manage.
Likewise for networks.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -1215,7 +1215,7 @@ struct qemud_vm *qemudLoadConfigXML(stru
xmlFreeDoc(xml);
if ((vm = qemudFindVMByName(server, def->name))) {
- if (vm->id == -1) {
+ if (!vm->active) {
qemudFreeVMDef(vm->def);
vm->def = def;
} else {
@@ -1263,8 +1263,8 @@ struct qemud_vm *qemudLoadConfigXML(stru
}
if (newVM) {
- vm->next = server->inactivevms;
- server->inactivevms = vm;
+ vm->next = server->vms;
+ server->vms = vm;
server->ninactivevms++;
}
@@ -1611,8 +1611,8 @@ struct qemud_network *qemudLoadNetworkCo
}
if (newNetwork) {
- network->next = server->inactivenetworks;
- server->inactivenetworks = network;
+ network->next = server->networks;
+ server->networks = network;
server->ninactivenetworks++;
}
Index: libvirt/qemud/driver.c
===================================================================
--- libvirt.orig/qemud/driver.c
+++ libvirt/qemud/driver.c
@@ -222,10 +222,10 @@ static int qemudGetProcessInfo(unsigned
}
struct qemud_vm *qemudFindVMByID(const struct qemud_server *server, int id) {
- struct qemud_vm *vm = server->activevms;
+ struct qemud_vm *vm = server->vms;
while (vm) {
- if (vm->id == id)
+ if (vm->active && vm->id == id)
return vm;
vm = vm->next;
}
@@ -235,7 +235,7 @@ struct qemud_vm *qemudFindVMByID(const s
struct qemud_vm *qemudFindVMByUUID(const struct qemud_server *server,
const unsigned char *uuid) {
- struct qemud_vm *vm = server->activevms;
+ struct qemud_vm *vm = server->vms;
while (vm) {
if (!memcmp(vm->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
@@ -243,19 +243,12 @@ struct qemud_vm *qemudFindVMByUUID(const
vm = vm->next;
}
- vm = server->inactivevms;
- while (vm) {
- if (!memcmp(vm->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
- return vm;
- vm = vm->next;
- }
-
return NULL;
}
struct qemud_vm *qemudFindVMByName(const struct qemud_server *server,
const char *name) {
- struct qemud_vm *vm = server->activevms;
+ struct qemud_vm *vm = server->vms;
while (vm) {
if (!strcmp(vm->def->name, name))
@@ -263,13 +256,6 @@ struct qemud_vm *qemudFindVMByName(const
vm = vm->next;
}
- vm = server->inactivevms;
- while (vm) {
- if (!strcmp(vm->def->name, name))
- return vm;
- vm = vm->next;
- }
-
return NULL;
}
@@ -278,12 +264,14 @@ int qemudGetVersion(struct qemud_server
}
int qemudListDomains(struct qemud_server *server, int *ids, int nids) {
- struct qemud_vm *vm = server->activevms;
+ struct qemud_vm *vm = server->vms;
int got = 0;
while (vm && got < nids) {
- ids[got] = vm->id;
+ if (vm->active) {
+ ids[got] = vm->id;
+ got++;
+ }
vm = vm->next;
- got++;
}
return got;
}
@@ -444,13 +432,15 @@ int qemudDomainDumpXML(struct qemud_serv
int qemudListDefinedDomains(struct qemud_server *server, char *const*names, int nnames) {
- struct qemud_vm *vm = server->inactivevms;
+ struct qemud_vm *vm = server->vms;
int got = 0;
while (vm && got < nnames) {
- strncpy(names[got], vm->def->name, QEMUD_MAX_NAME_LEN-1);
- names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+ if (!vm->active) {
+ strncpy(names[got], vm->def->name, QEMUD_MAX_NAME_LEN-1);
+ names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+ got++;
+ }
vm = vm->next;
- got++;
}
return got;
}
@@ -462,26 +452,10 @@ int qemudNumDefinedDomains(struct qemud_
int qemudDomainStart(struct qemud_server *server, struct qemud_vm *vm) {
- struct qemud_vm *prev = NULL, *curr = server->inactivevms;
- if (qemudStartVMDaemon(server, vm) < 0) {
+ if (qemudStartVMDaemon(server, vm) < 0)
return 1;
- }
-
- while (curr) {
- if (curr == vm) {
- if (prev)
- prev->next = curr->next;
- else
- server->inactivevms = curr->next;
- server->ninactivevms--;
- break;
- }
- prev = curr;
- curr = curr->next;
- }
- vm->next = server->activevms;
- server->activevms = vm;
+ server->ninactivevms--;
server->nactivevms++;
server->nvmfds += 2;
@@ -495,14 +469,14 @@ struct qemud_vm *qemudDomainDefine(struc
int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid) {
struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
- struct qemud_vm *prev = NULL, *curr = server->inactivevms;
+ struct qemud_vm *prev = NULL, *curr = server->vms;
if (!vm) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
return -1;
}
- if (vm->pid != -1) {
+ if (vm->active) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot delete active domain");
return -1;
}
@@ -517,7 +491,7 @@ int qemudDomainUndefine(struct qemud_ser
if (prev) {
prev->next = curr->next;
} else {
- server->inactivevms = curr->next;
+ server->vms = curr->next;
}
server->ninactivevms--;
break;
@@ -534,7 +508,7 @@ int qemudDomainUndefine(struct qemud_ser
struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
const unsigned char *uuid) {
- struct qemud_network *network = server->activenetworks;
+ struct qemud_network *network = server->networks;
while (network) {
if (!memcmp(network->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
@@ -542,19 +516,12 @@ struct qemud_network *qemudFindNetworkBy
network = network->next;
}
- network = server->inactivenetworks;
- while (network) {
- if (!memcmp(network->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
- return network;
- network = network->next;
- }
-
return NULL;
}
struct qemud_network *qemudFindNetworkByName(const struct qemud_server *server,
const char *name) {
- struct qemud_network *network = server->activenetworks;
+ struct qemud_network *network = server->networks;
while (network) {
if (!strcmp(network->def->name, name))
@@ -562,13 +529,6 @@ struct qemud_network *qemudFindNetworkBy
network = network->next;
}
- network = server->inactivenetworks;
- while (network) {
- if (!strcmp(network->def->name, name))
- return network;
- network = network->next;
- }
-
return NULL;
}
@@ -577,13 +537,15 @@ int qemudNumNetworks(struct qemud_server
}
int qemudListNetworks(struct qemud_server *server, char *const*names, int nnames) {
- struct qemud_network *network = server->activenetworks;
+ struct qemud_network *network = server->networks;
int got = 0;
while (network && got < nnames) {
- strncpy(names[got], network->def->name, QEMUD_MAX_NAME_LEN-1);
- names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+ if (network->active) {
+ strncpy(names[got], network->def->name, QEMUD_MAX_NAME_LEN-1);
+ names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+ got++;
+ }
network = network->next;
- got++;
}
return got;
}
@@ -593,13 +555,15 @@ int qemudNumDefinedNetworks(struct qemud
}
int qemudListDefinedNetworks(struct qemud_server *server, char *const*names, int nnames) {
- struct qemud_network *network = server->inactivenetworks;
+ struct qemud_network *network = server->networks;
int got = 0;
while (network && got < nnames) {
- strncpy(names[got], network->def->name, QEMUD_MAX_NAME_LEN-1);
- names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+ if (!network->active) {
+ strncpy(names[got], network->def->name, QEMUD_MAX_NAME_LEN-1);
+ names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
+ got++;
+ }
network = network->next;
- got++;
}
return got;
}
@@ -625,7 +589,7 @@ struct qemud_network *qemudNetworkDefine
int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) {
struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
- struct qemud_network *prev = NULL, *curr = server->inactivenetworks;
+ struct qemud_network *prev = NULL, *curr = server->networks;
if (!network) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no network with matching uuid");
@@ -642,7 +606,7 @@ int qemudNetworkUndefine(struct qemud_se
if (prev) {
prev->next = curr->next;
} else {
- server->inactivenetworks = curr->next;
+ server->networks = curr->next;
}
server->ninactivenetworks--;
break;
@@ -658,26 +622,10 @@ int qemudNetworkUndefine(struct qemud_se
}
int qemudNetworkStart(struct qemud_server *server, struct qemud_network *network) {
- struct qemud_network *prev = NULL, *curr = server->inactivenetworks;
- if (qemudStartNetworkDaemon(server, network) < 0) {
+ if (qemudStartNetworkDaemon(server, network) < 0)
return 1;
- }
-
- while (curr) {
- if (curr == network) {
- if (prev)
- prev->next = curr->next;
- else
- server->inactivenetworks = curr->next;
- server->ninactivenetworks--;
- break;
- }
- prev = curr;
- curr = curr->next;
- }
- network->next = server->activenetworks;
- server->activenetworks = network;
+ server->ninactivenetworks--;
server->nactivenetworks++;
return 0;
Index: libvirt/qemud/internal.h
===================================================================
--- libvirt.orig/qemud/internal.h
+++ libvirt/qemud/internal.h
@@ -209,6 +209,8 @@ struct qemud_vm {
struct qemud_vm_def *def; /* The current definition */
struct qemud_vm_def *newDef; /* New definition to activate at shutdown */
+ unsigned int active : 1;
+
struct qemud_vm *next;
};
@@ -280,14 +282,12 @@ struct qemud_server {
int sigread;
int nvmfds;
int nactivevms;
- struct qemud_vm *activevms;
int ninactivevms;
- struct qemud_vm *inactivevms;
+ struct qemud_vm *vms;
int nextvmid;
int nactivenetworks;
- struct qemud_network *activenetworks;
int ninactivenetworks;
- struct qemud_network *inactivenetworks;
+ struct qemud_network *networks;
brControl *brctl;
iptablesContext *iptables;
char configDir[PATH_MAX];
Index: libvirt/qemud/qemud.c
===================================================================
--- libvirt.orig/qemud/qemud.c
+++ libvirt/qemud/qemud.c
@@ -95,39 +95,43 @@ static int qemudDispatchSignal(struct qe
qemudLog(QEMUD_WARN, "Shutting down on signal %d", sigc);
/* shutdown active VMs */
- vm = server->activevms;
+ vm = server->vms;
while (vm) {
struct qemud_vm *next = vm->next;
- qemudShutdownVMDaemon(server, vm);
+ if (vm->active)
+ qemudShutdownVMDaemon(server, vm);
vm = next;
}
/* free inactive VMs */
- vm = server->inactivevms;
+ vm = server->vms;
while (vm) {
struct qemud_vm *next = vm->next;
qemudFreeVM(vm);
vm = next;
}
- server->inactivevms = NULL;
+ server->vms = NULL;
+ server->nactivevms = 0;
server->ninactivevms = 0;
/* shutdown active networks */
- network = server->activenetworks;
+ network = server->networks;
while (network) {
struct qemud_network *next = network->next;
- qemudShutdownNetworkDaemon(server, network);
+ if (network->active)
+ qemudShutdownNetworkDaemon(server, network);
network = next;
}
/* free inactive networks */
- network = server->inactivenetworks;
+ network = server->networks;
while (network) {
struct qemud_network *next = network->next;
qemudFreeNetwork(network);
network = next;
}
- server->inactivenetworks = NULL;
+ server->networks = NULL;
+ server->nactivenetworks = 0;
server->ninactivenetworks = 0;
server->shutdown = 1;
@@ -586,6 +590,7 @@ int qemudStartVMDaemon(struct qemud_serv
if (qemudExec(server, argv, &vm->pid, &vm->stdout, &vm->stderr) == 0) {
vm->id = server->nextvmid++;
+ vm->active = 1;
ret = 0;
}
@@ -805,50 +810,24 @@ qemudNetworkIfaceDisconnect(struct qemud
}
int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
- struct qemud_vm *prev = NULL, *curr = server->activevms;
struct qemud_vm_net_def *net;
- qemudLog(QEMUD_INFO, "Shutting down VM '%s'", vm->def->name);
-
- /* Already cleaned-up */
- if (vm->pid < 0)
+ if (!vm->active)
return 0;
- kill(vm->pid, SIGTERM);
-
- /* Move it to inactive vm list */
- while (curr) {
- if (curr == vm) {
- if (prev) {
- prev->next = curr->next;
- } else {
- server->activevms = curr->next;
- }
- server->nactivevms--;
-
- curr->next = server->inactivevms;
- server->inactivevms = curr;
- server->ninactivevms++;
- break;
- }
- prev = curr;
- curr = curr->next;
- }
+ qemudLog(QEMUD_INFO, "Shutting down VM '%s'", vm->def->name);
- if (!curr) {
- qemudDebug("Could not find VM to shutdown");
- return 0;
- }
+ kill(vm->pid, SIGTERM);
- qemudVMData(server, vm, curr->stdout);
- qemudVMData(server, vm, curr->stderr);
- close(curr->stdout);
- close(curr->stderr);
- if (curr->monitor != -1)
- close(curr->monitor);
- curr->stdout = -1;
- curr->stderr = -1;
- curr->monitor = -1;
+ qemudVMData(server, vm, vm->stdout);
+ qemudVMData(server, vm, vm->stderr);
+ close(vm->stdout);
+ close(vm->stderr);
+ if (vm->monitor != -1)
+ close(vm->monitor);
+ vm->stdout = -1;
+ vm->stderr = -1;
+ vm->monitor = -1;
server->nvmfds -= 2;
net = vm->def->nets;
@@ -867,6 +846,7 @@ int qemudShutdownVMDaemon(struct qemud_s
vm->pid = -1;
vm->id = -1;
+ vm->active = 0;
if (vm->newDef) {
qemudFreeVMDef(vm->def);
@@ -874,6 +854,9 @@ int qemudShutdownVMDaemon(struct qemud_s
vm->newDef = NULL;
}
+ server->nactivevms--;
+ server->ninactivevms++;
+
return 0;
}
@@ -1209,7 +1192,6 @@ int qemudStartNetworkDaemon(struct qemud
int qemudShutdownNetworkDaemon(struct qemud_server *server,
struct qemud_network *network) {
- struct qemud_network *prev, *curr;
int err;
qemudLog(QEMUD_INFO, "Shutting down network '%s'", network->def->name);
@@ -1233,27 +1215,6 @@ int qemudShutdownNetworkDaemon(struct qe
network->bridge, strerror(err));
}
- /* Move it to inactive networks list */
- prev = NULL;
- curr = server->activenetworks;
- while (curr) {
- if (curr == network) {
- if (prev) {
- prev->next = curr->next;
- } else {
- server->activenetworks = curr->next;
- }
- server->nactivenetworks--;
-
- curr->next = server->inactivenetworks;
- server->inactivenetworks = curr;
- server->ninactivenetworks++;
- break;
- }
- prev = curr;
- curr = curr->next;
- }
-
if (network->dnsmasqPid > 0 &&
waitpid(network->dnsmasqPid, NULL, WNOHANG) != network->dnsmasqPid) {
kill(network->dnsmasqPid, SIGKILL);
@@ -1271,6 +1232,9 @@ int qemudShutdownNetworkDaemon(struct qe
network->newDef = NULL;
}
+ server->nactivenetworks--;
+ server->ninactivenetworks++;
+
return 0;
}
@@ -1278,7 +1242,7 @@ int qemudShutdownNetworkDaemon(struct qe
static int qemudDispatchPoll(struct qemud_server *server, struct pollfd *fds) {
struct qemud_socket *sock = server->sockets;
struct qemud_client *client = server->clients;
- struct qemud_vm *vm = server->activevms;
+ struct qemud_vm *vm;
struct qemud_vm *tmp;
struct qemud_network *network, *prevnet;
int ret = 0;
@@ -1314,12 +1278,18 @@ static int qemudDispatchPoll(struct qemu
fd++;
client = next;
}
+ vm = server->vms;
while (vm) {
struct qemud_vm *next = vm->next;
int failed = 0,
stdoutfd = vm->stdout,
stderrfd = vm->stderr;
+ if (!vm->active) {
+ vm = next;
+ continue;
+ }
+
if (stdoutfd != -1) {
if (fds[fd].revents) {
if (fds[fd].revents == POLLIN) {
@@ -1353,17 +1323,18 @@ static int qemudDispatchPoll(struct qemu
/* Cleanup any VMs which shutdown & dont have an associated
config file */
- vm = server->inactivevms;
+ vm = server->vms;
tmp = NULL;
while (vm) {
- if (!vm->configFile[0]) {
+ if (!vm->active && !vm->configFile[0]) {
struct qemud_vm *next = vm->next;
if (tmp) {
tmp->next = next;
} else {
- server->inactivevms = next;
+ server->vms = next;
}
qemudFreeVM(vm);
+ server->ninactivevms--;
vm = next;
} else {
tmp = vm;
@@ -1372,17 +1343,18 @@ static int qemudDispatchPoll(struct qemu
}
/* Cleanup any networks too */
- network = server->inactivenetworks;
+ network = server->networks;
prevnet = NULL;
while (network) {
- if (!network->configFile[0]) {
+ if (!network->active && !network->configFile[0]) {
struct qemud_network *next = network->next;
if (prevnet) {
prevnet->next = next;
} else {
- server->inactivenetworks = next;
+ server->networks = next;
}
qemudFreeNetwork(network);
+ server->ninactivenetworks--;
network = next;
} else {
prevnet = network;
@@ -1419,7 +1391,9 @@ static void qemudPreparePoll(struct qemu
fds[fd].events = POLLIN | POLLERR | POLLHUP;
fd++;
}
- for (vm = server->activevms ; vm ; vm = vm->next) {
+ for (vm = server->vms ; vm ; vm = vm->next) {
+ if (!vm->active)
+ continue;
if (vm->stdout != -1) {
fds[fd].fd = vm->stdout;
fds[fd].events = POLLIN | POLLERR | POLLHUP;
--
17 years, 9 months
[Libvir] [patch 0/7] Autostart API patches
by Mark McLoughlin
Hey,
So, this took a bit longer than I expected.
I think these patches do pretty much what we discussed
for autostart, instead of have the flag in the XML.
Appreciate people looking over the patches.
Thanks,
Mark.
--
17 years, 9 months
[Libvir] support for VMware
by "René Castillo"
Hi,
I am looking for a library that handles features of multiple
virtualization environments. libvirt can manage Xen, QEMU and KVM,
but what other hypervisors are planned to be supported? Are there
plans to support basic functionality of VMware virtualized nodes,
e.g. ESX Server?
bye, Rene
--
"Feel free" - 10 GB Mailbox, 100 FreeSMS/Monat ...
Jetzt GMX TopMail testen: www.gmx.net/de/go/mailfooter/topmail-out
17 years, 9 months
[Libvir] [patch 0/9] More miscellaneous qemud patches
by Mark McLoughlin
Hey,
Okay, here's another batch of qemud patches I've
committed.
The most significant ones are the signal handling
and error reporting ones at the end. Appreciate someone
looking over them.
Thanks,
Mark.
--
17 years, 9 months
[Libvir] [PATCH] to run on IA64
by Atsushi SAKAI
Hi,
This patch intends to run libvirt 0.2.0 on IA64.
Signed-off-by: Atsushi SAKAI <sakaia(a)jp.fujitsu.com>
Just one question, is there any plan to support big/little
endian for libvirt? (related to network)
Thanks
Atsushi SAKAI
17 years, 9 months
[Libvir] PATCH: Update the AUTHORS file to reflect contributions
by Daniel P. Berrange
Just noticed that the AUTHORS file is empty aside from Daniel & Karel. So
I've gone through the ChangeLog file and built a list of everyone who has
contributed patches to libvirt since inception. I'm attaching a patch
which updates the AUTHORS file to include these people. I've also broken
out folks who've contributed major drivers / subsystems to identify the
areas of particular expertise for ongoing maintenance. All the ordering
is chronological ie based on where in the ChangeLog I found the respective
names.
If anyone knows of folks who contributed patches, but whom I've missed
from the list let me know so I can rectify it...
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 9 months