[Libvir] Autostarting guests and networks
by Mark McLoughlin
Hey,
We need some way to have libvirtd automatically start guests and
networks.
We had said we should have autostart directories containing config
files of guests/networks which should be autostarted. One problem I see
with that is that we'd need a new API to define autostart configs.
So, I suggest we add an "autostart" flag to the toplevel element of the
configs.
We could discuss this one at length and I, for one, don't like using
the XML format as an API like this, but ... comments?
Cheers,
Mark.
17 years, 10 months
Re: [Libvir] [patch 0/9] Revised autostart patches
by Daniel P. Berrange
On Thu, Feb 22, 2007 at 11:04:08AM +0000, Mark McLoughlin wrote:
> Hey,
> Here's the autostart patches again. If you're just
> looking for what's changed, it's probably fine to just look
> at patch 3 (some heavy re-factoring to make the autostart
> stuff easier) and patch 7 (maintains symlinks in the autostart
> dirs instead of config files).
Aside from the note about 'virsh list' command changes, it all looks good
to me. Unless anyone else has objections I'd say commit this to CVS - I
want to re-do the handling of the QEMU monitor to detect errors at startup
and would rather work with your big refactoring already applied..
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, 10 months
[Libvir] PATCH: Don't leave a 'braindead' Xen VM when device hotplug fails
by Daniel P. Berrange
Because of the way Xen guest creation works, the virDomainCreateLinux
implementation for Xen is really a three stage process - first we create
the raw domain, then we have to wait for device hotplug to complete,
finally unpausing the domain.
Currently if the device hotplug fails we error out, leaving a 'braindead'
VM lying around in the paused state. This is rather confusing for users
leading to people thinking everything was OK, and thus unpausing the
guest manually, then filing bug reports when they find they've no devices
in the guest VM !
The xm tool by comparison will tear down the VM if the device hotplug fails
so the user doesn't see the paused domain after the failure. The attached
patch re-arranges the Xen driver for creating new domains to do the same
kind of thing - upon any failure we explicitly destroy the halfdead domain
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, 10 months
[Libvir] [PATCH]Guard for Dom0 by virsh domain stop commands
by Kazuki Mizushima
Hi,
I think Domain0 should NOT stop by virsh domain stop commands.
(like shutdown, reboot, destroy).
But virsh shudown and reboot commands are still available for Dom0.
This patch intends to disable these two commands for Dom0.
Internal processing of these two commands is following
1)Send shutdown or reboot to Xend (Guard of xend)
2)If 1) is failed, shutdown/reboot is executed by xenstore. (Not Guard)
This patch removes 2) ,that is as same as destroy processing.
Signed-off-by: Kazuki Mizushima <mizushima.kazuk(a)jp.fujitsu.com>
Thanks,
Kazuki Mizushima
Index: xs_internal.c (libvirt-0.2.0)
----------------------------------------------------------------------
--- xs_internal.c 2007-02-15 01:11:54.000000000 +0900
+++ xs_internal.c.guard 2007-02-22 00:31:55.000000000 +0900
@@ -54,8 +54,8 @@ static virDriver xenStoreDriver = {
xenStoreDomainLookupByName, /* domainLookupByName */
NULL, /* domainSuspend */
NULL, /* domainResume */
- xenStoreDomainShutdown, /* domainShutdown */
- xenStoreDomainReboot, /* domainReboot */
+ NULL, /* domainShutdown */
+ NULL, /* domainReboot */
NULL, /* domainDestroy */
xenStoreDomainGetOSType, /* domainGetOSType */
xenStoreDomainGetMaxMemory, /* domainGetMaxMemory */
----------------------------------------------------------------------
17 years, 10 months
[Libvir] [patch 9/9] Actually autostart guests and networks
by Mark McLoughlin
Add qemudAutostartConfigs() to autostart guests and
networks.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -1972,11 +1972,49 @@ int qemudScanConfigDir(struct qemud_serv
return 0;
}
+static
+void qemudAutostartConfigs(struct qemud_server *server) {
+ struct qemud_network *network;
+ struct qemud_vm *vm;
+
+ network = server->networks;
+ while (network != NULL) {
+ struct qemud_network *next = network->next;
+
+ if (network->autostart &&
+ !qemudIsActiveNetwork(network) &&
+ qemudStartNetworkDaemon(server, network) < 0)
+ qemudLog(QEMUD_ERR, "Failed to autostart network '%s'",
+ network->def->name);
+
+ network = next;
+ }
+
+ vm = server->vms;
+ while (vm != NULL) {
+ struct qemud_vm *next = vm->next;
+
+ if (vm->autostart &&
+ !qemudIsActiveVM(vm) &&
+ qemudStartVMDaemon(server, vm) < 0)
+ qemudLog(QEMUD_ERR, "Failed to autostart VM '%s'",
+ vm->def->name);
+
+ vm = next;
+ }
+}
+
/* Scan for all guest and network config files */
int qemudScanConfigs(struct qemud_server *server) {
if (qemudScanConfigDir(server, server->configDir, server->autostartDir, 1) < 0)
return -1;
- return qemudScanConfigDir(server, server->networkConfigDir, server->networkAutostartDir, 0);
+
+ if (qemudScanConfigDir(server, server->networkConfigDir, server->networkAutostartDir, 0) < 0)
+ return -1;
+
+ qemudAutostartConfigs(server);
+
+ return 0;
}
/* Simple grow-on-demand string buffer */
--
17 years, 10 months
[Libvir] [patch 8/9] Cleanup configDir members
by Mark McLoughlin
qemudInitPaths() 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_CONFIG = 0,
+ QEMUD_DIR_AUTOSTART,
+ QEMUD_DIR_NETWORK_CONFIG,
+ QEMUD_DIR_NETWORK_AUTOSTART,
+
+ QEMUD_N_CONFIG_DIRS
+} qemudConfigDirType;
+
/* Different types of QEMU acceleration possible */
enum qemud_vm_virt_type {
QEMUD_VIRT_QEMU,
@@ -293,10 +302,11 @@ struct qemud_server {
struct qemud_network *networks;
brControl *brctl;
iptablesContext *iptables;
- char configDir[PATH_MAX];
- char networkConfigDir[PATH_MAX];
- char autostartDir[PATH_MAX];
- char networkAutostartDir[PATH_MAX];
+ char configDirs[QEMUD_N_CONFIG_DIRS][PATH_MAX];
+ char *configDir;
+ char *autostartDir;
+ char *networkConfigDir;
+ char *networkAutostartDir;
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
@@ -354,15 +354,22 @@ static int qemudListenUnix(struct qemud_
return 0;
}
-static int qemudInitPaths(int sys,
- char *configDir,
- char *networkConfigDir,
- char *autostartDir,
- char *networkAutostartDir,
+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;
+ char base[PATH_MAX] = SYSCONF_DIR "/";
+ 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(autostartDir, maxlen, "%s/libvirt/qemu/autostart", SYSCONF_DIR) >= maxlen)
- goto snprintf_error;
-
- if (snprintf(networkAutostartDir, 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;
@@ -394,29 +389,22 @@ static int qemudInitPaths(int sys,
unlink(sockname);
} else {
- struct passwd *pw;
-
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(autostartDir, 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(networkAutostartDir, maxlen, "%s/.libvirt/qemu/networks/autostart", pw->pw_dir) >= maxlen)
+ if (snprintf(base, PATH_MAX, "%s/.", pw->pw_dir) >= PATH_MAX)
goto snprintf_error;
+ }
- 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,11 +431,14 @@ static struct qemud_server *qemudInitial
roSockname[0] = '\0';
- if (qemudInitPaths(sys, server->configDir, server->networkConfigDir,
- server->autostartDir, server->networkAutostartDir,
- sockname, roSockname, PATH_MAX) < 0)
+ if (qemudInitPaths(server, sys, sockname, roSockname, PATH_MAX) < 0)
goto cleanup;
+ server->configDir = server->configDirs[QEMUD_DIR_CONFIG];
+ server->autostartDir = server->configDirs[QEMUD_DIR_AUTOSTART];
+ server->networkConfigDir = server->configDirs[QEMUD_DIR_NETWORK_CONFIG];
+ server->networkAutostartDir = server->configDirs[QEMUD_DIR_NETWORK_AUTOSTART];
+
if (qemudListenUnix(server, sockname, 0) < 0)
goto cleanup;
--
17 years, 10 months
[Libvir] [patch 7/9] Add autostart QEMU implementation
by Mark McLoughlin
Actually implement the autostart API in qemud by creating
symlinks in the autostart directories.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/internal.h
===================================================================
--- libvirt.orig/qemud/internal.h
+++ libvirt/qemud/internal.h
@@ -205,6 +205,7 @@ struct qemud_vm {
int ntapfds;
char configFile[PATH_MAX];
+ char autostartLink[PATH_MAX];
struct qemud_vm_def *def; /* The current definition */
struct qemud_vm_def *newDef; /* New definition to activate at shutdown */
@@ -241,6 +242,7 @@ struct qemud_network_def {
/* Virtual Network runtime state */
struct qemud_network {
char configFile[PATH_MAX];
+ char autostartLink[PATH_MAX];
struct qemud_network_def *def; /* The current definition */
struct qemud_network_def *newDef; /* New definition to activate at shutdown */
@@ -293,6 +295,8 @@ struct qemud_server {
iptablesContext *iptables;
char configDir[PATH_MAX];
char networkConfigDir[PATH_MAX];
+ char autostartDir[PATH_MAX];
+ char networkAutostartDir[PATH_MAX];
char errorMessage[QEMUD_MAX_ERROR_LEN];
int errorCode;
unsigned int shutdown : 1;
Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -137,7 +137,7 @@ qemudMakeConfigPath(const char *configDi
return 0;
}
-static int
+int
qemudEnsureDir(const char *path)
{
struct stat st;
@@ -1287,6 +1287,14 @@ qemudSaveVMDef(struct qemud_server *serv
"cannot construct config file path");
return -1;
}
+
+ if (qemudMakeConfigPath(server->autostartDir, def->name, ".xml",
+ vm->autostartLink, PATH_MAX) < 0) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "cannot construct autostart link path");
+ vm->configFile[0] = '\0';
+ return -1;
+ }
}
return qemudSaveConfig(server, vm, def);
@@ -1666,6 +1674,14 @@ qemudSaveNetworkDef(struct qemud_server
"cannot construct config file path");
return -1;
}
+
+ if (qemudMakeConfigPath(server->networkAutostartDir, def->name, ".xml",
+ network->autostartLink, PATH_MAX) < 0) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "cannot construct autostart link path");
+ network->configFile[0] = '\0';
+ return -1;
+ }
}
return qemudSaveNetworkConfig(server, network, def);
@@ -1735,11 +1751,105 @@ compareFileToNameSuffix(const char *file
return 0;
}
+static int
+checkLinkPointsTo(const char *checkLink,
+ const char *checkDest)
+{
+ char dest[PATH_MAX];
+ char real[PATH_MAX];
+ char checkReal[PATH_MAX];
+ int n;
+ int passed = 0;
+
+ /* read the link destination */
+ if ((n = readlink(checkLink, dest, PATH_MAX)) < 0) {
+ switch (errno) {
+ case ENOENT:
+ case ENOTDIR:
+ break;
+
+ case EINVAL:
+ qemudLog(QEMUD_WARN, "Autostart file '%s' is not a symlink",
+ checkLink);
+ break;
+
+ default:
+ qemudLog(QEMUD_WARN, "Failed to read autostart symlink '%s': %s",
+ checkLink, strerror(errno));
+ break;
+ }
+
+ goto failed;
+ } else if (n >= PATH_MAX) {
+ qemudLog(QEMUD_WARN, "Symlink '%s' contents too long to fit in buffer",
+ checkLink);
+ goto failed;
+ }
+
+ dest[n] = '\0';
+
+ /* make absolute */
+ if (dest[0] != '/') {
+ char dir[PATH_MAX];
+ char tmp[PATH_MAX];
+ char *p;
+
+ strncpy(dir, checkLink, PATH_MAX);
+ dir[PATH_MAX] = '\0';
+
+ if (!(p = strrchr(dir, '/'))) {
+ qemudLog(QEMUD_WARN, "Symlink path '%s' is not absolute", checkLink);
+ goto failed;
+ }
+
+ if (p == dir) /* handle unlikely root dir case */
+ p++;
+
+ *p = '\0';
+
+ if (qemudMakeConfigPath(dir, dest, NULL, tmp, PATH_MAX) < 0) {
+ qemudLog(QEMUD_WARN, "Path '%s/%s' is too long", dir, dest);
+ goto failed;
+ }
+
+ strncpy(dest, tmp, PATH_MAX);
+ dest[PATH_MAX] = '\0';
+ }
+
+ /* canonicalize both paths */
+ if (!realpath(dest, real)) {
+ qemudLog(QEMUD_WARN, "Failed to expand path '%s' :%s",
+ dest, strerror(errno));
+ strncpy(real, dest, PATH_MAX);
+ real[PATH_MAX] = '\0';
+ }
+
+ if (!realpath(checkDest, checkReal)) {
+ qemudLog(QEMUD_WARN, "Failed to expand path '%s' :%s",
+ checkDest, strerror(errno));
+ strncpy(checkReal, checkDest, PATH_MAX);
+ checkReal[PATH_MAX] = '\0';
+ }
+
+ /* compare */
+ if (strcmp(checkReal, real) != 0) {
+ qemudLog(QEMUD_WARN, "Autostart link '%s' is not a symlink to '%s', ignoring",
+ checkLink, checkReal);
+ goto failed;
+ }
+
+ passed = 1;
+
+ failed:
+ return passed;
+}
+
static struct qemud_vm *
qemudLoadConfig(struct qemud_server *server,
const char *file,
const char *path,
- const char *xml) {
+ const char *xml,
+ const char *autostartLink) {
struct qemud_vm_def *def;
struct qemud_vm *vm;
@@ -1765,6 +1875,11 @@ qemudLoadConfig(struct qemud_server *ser
strncpy(vm->configFile, path, PATH_MAX);
vm->configFile[PATH_MAX-1] = '\0';
+ strncpy(vm->autostartLink, autostartLink, PATH_MAX);
+ vm->autostartLink[PATH_MAX-1] = '\0';
+
+ vm->autostart = checkLinkPointsTo(vm->autostartLink, vm->configFile);
+
return vm;
}
@@ -1772,7 +1887,8 @@ static struct qemud_network *
qemudLoadNetworkConfig(struct qemud_server *server,
const char *file,
const char *path,
- const char *xml) {
+ const char *xml,
+ const char *autostartLink) {
struct qemud_network_def *def;
struct qemud_network *network;
@@ -1798,12 +1914,18 @@ qemudLoadNetworkConfig(struct qemud_serv
strncpy(network->configFile, path, PATH_MAX);
network->configFile[PATH_MAX-1] = '\0';
+ strncpy(network->autostartLink, autostartLink, PATH_MAX);
+ network->autostartLink[PATH_MAX-1] = '\0';
+
+ network->autostart = checkLinkPointsTo(network->autostartLink, network->configFile);
+
return network;
}
static
int qemudScanConfigDir(struct qemud_server *server,
const char *configDir,
+ const char *autostartDir,
int isGuest) {
DIR *dir;
struct dirent *entry;
@@ -1819,6 +1941,7 @@ int qemudScanConfigDir(struct qemud_serv
while ((entry = readdir(dir))) {
char xml[QEMUD_MAX_XML_LEN];
char path[PATH_MAX];
+ char autostartLink[PATH_MAX];
if (entry->d_name[0] == '.')
continue;
@@ -1829,13 +1952,19 @@ int qemudScanConfigDir(struct qemud_serv
continue;
}
+ if (qemudMakeConfigPath(autostartDir, entry->d_name, NULL, autostartLink, PATH_MAX) < 0) {
+ qemudLog(QEMUD_WARN, "Autostart link path '%s/%s' is too long",
+ autostartDir, entry->d_name);
+ continue;
+ }
+
if (!qemudReadFile(path, xml, QEMUD_MAX_XML_LEN))
continue;
if (isGuest)
- qemudLoadConfig(server, entry->d_name, path, xml);
+ qemudLoadConfig(server, entry->d_name, path, xml, autostartLink);
else
- qemudLoadNetworkConfig(server, entry->d_name, path, xml);
+ qemudLoadNetworkConfig(server, entry->d_name, path, xml, autostartLink);
}
closedir(dir);
@@ -1845,9 +1974,9 @@ 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, server->autostartDir, 1) < 0)
return -1;
- return qemudScanConfigDir(server, server->networkConfigDir, 0);
+ return qemudScanConfigDir(server, server->networkConfigDir, server->networkAutostartDir, 0);
}
/* Simple grow-on-demand string buffer */
Index: libvirt/qemud/driver.c
===================================================================
--- libvirt.orig/qemud/driver.c
+++ libvirt/qemud/driver.c
@@ -502,7 +502,12 @@ int qemudDomainUndefine(struct qemud_ser
if (qemudDeleteConfig(server, vm->configFile, vm->def->name) < 0)
return -1;
+ if (unlink(vm->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR)
+ qemudLog(QEMUD_WARN, "Failed to delete autostart link '%s': %s",
+ vm->autostartLink, strerror(errno));
+
vm->configFile[0] = '\0';
+ vm->autostartLink[0] = '\0';
qemudRemoveInactiveVM(server, vm);
@@ -539,6 +544,31 @@ int qemudDomainSetAutostart(struct qemud
if (vm->autostart == autostart)
return 0;
+ if (autostart) {
+ int err;
+
+ if ((err = qemudEnsureDir(server->autostartDir))) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "cannot create autostart directory %s: %s",
+ server->autostartDir, strerror(err));
+ return -1;
+ }
+
+ if (symlink(vm->configFile, vm->autostartLink) < 0) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "Failed to create symlink '%s' to '%s': %s",
+ vm->autostartLink, vm->configFile, strerror(errno));
+ return -1;
+ }
+ } else {
+ if (unlink(vm->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "Failed to delete symlink '%s': %s",
+ vm->autostartLink, strerror(errno));
+ return -1;
+ }
+ }
+
vm->autostart = autostart;
return 0;
@@ -657,7 +687,12 @@ int qemudNetworkUndefine(struct qemud_se
if (qemudDeleteConfig(server, network->configFile, network->def->name) < 0)
return -1;
+ if (unlink(network->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR)
+ qemudLog(QEMUD_WARN, "Failed to delete autostart link '%s': %s",
+ network->autostartLink, strerror(errno));
+
network->configFile[0] = '\0';
+ network->autostartLink[0] = '\0';
qemudRemoveInactiveNetwork(server, network);
@@ -750,6 +785,31 @@ int qemudNetworkSetAutostart(struct qemu
if (network->autostart == autostart)
return 0;
+ if (autostart) {
+ int err;
+
+ if ((err = qemudEnsureDir(server->networkAutostartDir))) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "cannot create autostart directory %s: %s",
+ server->networkAutostartDir, strerror(err));
+ return -1;
+ }
+
+ if (symlink(network->configFile, network->autostartLink) < 0) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "Failed to create symlink '%s' to '%s': %s",
+ network->autostartLink, network->configFile, strerror(errno));
+ return -1;
+ }
+ } else {
+ if (unlink(network->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "Failed to delete symlink '%s': %s",
+ network->autostartLink, strerror(errno));
+ return -1;
+ }
+ }
+
network->autostart = autostart;
return 0;
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 *autostartDir,
+ char *networkAutostartDir,
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(autostartDir, maxlen, "%s/libvirt/qemu/autostart", SYSCONF_DIR) >= maxlen)
+ goto snprintf_error;
+
+ if (snprintf(networkAutostartDir, 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(autostartDir, maxlen, "%s/.libvirt/qemu/autostart", pw->pw_dir) >= maxlen)
+ goto snprintf_error;
+
+ if (snprintf(networkAutostartDir, 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->autostartDir, server->networkAutostartDir,
sockname, roSockname, PATH_MAX) < 0)
goto cleanup;
Index: libvirt/qemud/conf.h
===================================================================
--- libvirt.orig/qemud/conf.h
+++ libvirt/qemud/conf.h
@@ -34,6 +34,7 @@ int qemudScanConfigs
int qemudDeleteConfig (struct qemud_server *server,
const char *configFile,
const char *name);
+int qemudEnsureDir (const char *path);
void qemudFreeVMDef (struct qemud_vm_def *vm);
void qemudFreeVM (struct qemud_vm *vm);
--
17 years, 10 months
[Libvir] [patch 6/9] 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
@@ -509,6 +509,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;
@@ -685,6 +720,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
@@ -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 autostart : 1;
+
struct qemud_vm *next;
};
@@ -247,6 +249,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, 10 months
[Libvir] [patch 5/9] Add autostart support to virsh
by Mark McLoughlin
Add "autostart" and "net-autostart" commands
Also, cleanup the "list" and "net-list" commands a bit
and add autostart info to them
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/src/virsh.c
===================================================================
--- libvirt.orig/src/virsh.c
+++ libvirt/src/virsh.c
@@ -292,6 +292,51 @@ cmdHelp(vshControl * ctl, vshCmd * cmd)
}
/*
+ * "autostart" command
+ */
+static vshCmdInfo info_autostart[] = {
+ {"syntax", "autostart [--disable] <domain>"},
+ {"help", gettext_noop("autostart a domain")},
+ {"desc",
+ gettext_noop("Configure a domain to be automatically started at boot.")},
+ {NULL, NULL}
+};
+
+static vshCmdOptDef opts_autostart[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
+ {"disable", VSH_OT_BOOL, 0, gettext_noop("disable autostarting")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdAutostart(vshControl * ctl, vshCmd * cmd)
+{
+ virDomainPtr dom;
+ char *name;
+ int autostart;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", &name)))
+ return FALSE;
+
+ autostart = !vshCommandOptBool(cmd, "disable");
+
+ if (virDomainSetAutostart(dom, autostart) < 0) {
+ vshError(ctl, FALSE, _("Failed to %smark domain %s as autostarted"),
+ autostart ? "" : "un", name);
+ virDomainFree(dom);
+ return FALSE;
+ }
+
+ vshPrint(ctl, _("Domain %s %smarked as autostarted\n"),
+ name, autostart ? "" : "un");
+
+ return TRUE;
+}
+
+/*
* "connect" command
*/
static vshCmdInfo info_connect[] = {
@@ -473,53 +518,59 @@ cmdList(vshControl * ctl, vshCmd * cmd A
qsort(&names[0], maxname, sizeof(char*), namesorter);
}
}
- vshPrintExtra(ctl, "%3s %-20s %s\n", _("Id"), _("Name"), _("State"));
- vshPrintExtra(ctl, "----------------------------------\n");
+ vshPrintExtra(ctl, "%3s %-20s %-10s %-10s\n", _("Id"), _("Name"), _("State"), _("Autostart"));
+ vshPrintExtra(ctl, "---------------------------------------------\n");
for (i = 0; i < maxid; i++) {
- int ret;
virDomainInfo info;
virDomainPtr dom = virDomainLookupByID(ctl->conn, ids[i]);
+ const char *state, *autostartStr;
+ int autostart = 0;
/* this kind of work with domains is not atomic operation */
if (!dom)
continue;
- ret = virDomainGetInfo(dom, &info);
- vshPrint(ctl, "%3d %-20s %s\n",
+ if (virDomainGetInfo(dom, &info) < 0)
+ state = _("no state");
+ else
+ state = _N(vshDomainStateToString(info.state));
+
+ if (virDomainGetAutostart(dom, &autostart) < 0)
+ autostartStr = _("no autostart");
+ else
+ autostartStr = autostart ? "yes" : "no";
+
+ vshPrint(ctl, "%3d %-20s %-10s %-10s\n",
virDomainGetID(dom),
virDomainGetName(dom),
- ret <
- 0 ? _("no state") : _N(vshDomainStateToString(info.state)));
+ state,
+ autostartStr);
virDomainFree(dom);
}
for (i = 0; i < maxname; i++) {
- int ret;
- unsigned int id;
virDomainInfo info;
virDomainPtr dom = virDomainLookupByName(ctl->conn, names[i]);
+ const char *state, *autostartStr;
+ int autostart = 0;
/* this kind of work with domains is not atomic operation */
if (!dom) {
free(names[i]);
continue;
}
- ret = virDomainGetInfo(dom, &info);
- id = virDomainGetID(dom);
- if (id == ((unsigned int)-1)) {
- vshPrint(ctl, "%3s %-20s %s\n",
- "-",
- names[i],
- ret <
- 0 ? "no state" : vshDomainStateToString(info.state));
- } else {
- vshPrint(ctl, "%3d %-20s %s\n",
- id,
- names[i],
- ret <
- 0 ? "no state" : vshDomainStateToString(info.state));
- }
+ if (virDomainGetInfo(dom, &info) < 0)
+ state = _("no state");
+ else
+ state = _N(vshDomainStateToString(info.state));
+
+ if (virDomainGetAutostart(dom, &autostart) < 0)
+ autostartStr = _("no autostart");
+ else
+ autostartStr = autostart ? "yes" : "no";
+
+ vshPrint(ctl, "%3s %-20s %s %s\n", "-", names[i], state, autostartStr);
virDomainFree(dom);
free(names[i]);
@@ -1632,6 +1683,50 @@ cmdDomuuid(vshControl * ctl, vshCmd * cm
return TRUE;
}
+/*
+ * "net-autostart" command
+ */
+static vshCmdInfo info_network_autostart[] = {
+ {"syntax", "net-autostart [--disable] <network>"},
+ {"help", gettext_noop("autostart a network")},
+ {"desc",
+ gettext_noop("Configure a network to be automatically started at boot.")},
+ {NULL, NULL}
+};
+
+static vshCmdOptDef opts_network_autostart[] = {
+ {"network", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("network name or uuid")},
+ {"disable", VSH_OT_BOOL, 0, gettext_noop("disable autostarting")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdNetworkAutostart(vshControl * ctl, vshCmd * cmd)
+{
+ virNetworkPtr network;
+ char *name;
+ int autostart;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(network = vshCommandOptNetwork(ctl, cmd, "network", &name)))
+ return FALSE;
+
+ autostart = !vshCommandOptBool(cmd, "disable");
+
+ if (virNetworkSetAutostart(network, autostart) < 0) {
+ vshError(ctl, FALSE, _("Failed to %smark network %s as autostarted"),
+ autostart ? "" : "un", name);
+ virNetworkFree(network);
+ return FALSE;
+ }
+
+ vshPrint(ctl, _("Network %s %smarked as autostarted\n"),
+ name, autostart ? "" : "un");
+
+ return TRUE;
+}
/*
* "net-create" command
@@ -1895,11 +1990,13 @@ cmdNetworkList(vshControl * ctl, vshCmd
qsort(&inactiveNames[0], maxinactive, sizeof(char*), namesorter);
}
}
- vshPrintExtra(ctl, "%-20s\n", _("Name"));
- vshPrintExtra(ctl, "----------------------------------\n");
+ vshPrintExtra(ctl, "%-20s %-10s %-10s\n", _("Name"), _("State"), _("Autostart"));
+ vshPrintExtra(ctl, "-----------------------------------------\n");
for (i = 0; i < maxactive; i++) {
virNetworkPtr network = virNetworkLookupByName(ctl->conn, activeNames[i]);
+ const char *autostartStr;
+ int autostart = 0;
/* this kind of work with networks is not atomic operation */
if (!network) {
@@ -1907,13 +2004,22 @@ cmdNetworkList(vshControl * ctl, vshCmd
continue;
}
- vshPrint(ctl, "%-20s\n",
- virNetworkGetName(network));
+ if (virNetworkGetAutostart(network, &autostart) < 0)
+ autostartStr = _("no autostart");
+ else
+ autostartStr = autostart ? "yes" : "no";
+
+ vshPrint(ctl, "%-20s %-10s %-10s\n",
+ virNetworkGetName(network),
+ _("active"),
+ autostartStr);
virNetworkFree(network);
free(activeNames[i]);
}
for (i = 0; i < maxinactive; i++) {
virNetworkPtr network = virNetworkLookupByName(ctl->conn, inactiveNames[i]);
+ const char *autostartStr;
+ int autostart = 0;
/* this kind of work with networks is not atomic operation */
if (!network) {
@@ -1921,8 +2027,15 @@ cmdNetworkList(vshControl * ctl, vshCmd
continue;
}
- vshPrint(ctl, "%-20s\n",
- inactiveNames[i]);
+ if (virNetworkGetAutostart(network, &autostart) < 0)
+ autostartStr = _("no autostart");
+ else
+ autostartStr = autostart ? "yes" : "no";
+
+ vshPrint(ctl, "%-20s %s %s\n",
+ inactiveNames[i],
+ _("inactive"),
+ autostartStr);
virNetworkFree(network);
free(inactiveNames[i]);
@@ -2268,6 +2381,7 @@ cmdQuit(vshControl * ctl, vshCmd * cmd A
* Commands
*/
static vshCmdDef commands[] = {
+ {"autostart", cmdAutostart, opts_autostart, info_autostart},
{"connect", cmdConnect, opts_connect, info_connect},
{"console", cmdConsole, opts_console, info_console},
{"create", cmdCreate, opts_create, info_create},
@@ -2282,6 +2396,7 @@ static vshCmdDef commands[] = {
{"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml},
{"help", cmdHelp, opts_help, info_help},
{"list", cmdList, opts_list, info_list},
+ {"net-autostart", cmdNetworkAutostart, opts_network_autostart, info_network_autostart},
{"net-create", cmdNetworkCreate, opts_network_create, info_network_create},
{"net-define", cmdNetworkDefine, opts_network_define, info_network_define},
{"net-destroy", cmdNetworkDestroy, opts_network_destroy, info_network_destroy},
--
17 years, 10 months