[libvirt] [PATCH v3 4/4] qemu-config: Add new -add-fd command line option
by Corey Bryant
This option can be used for passing file descriptors on the
command line. It mirrors the existing add-fd QMP command which
allows an fd to be passed to QEMU via SCM_RIGHTS and added to an
fd set.
This can be combined with commands such as -drive to link file
descriptors in an fd set to a drive:
qemu-kvm -add-fd fd=3,set=2,opaque="rdwr:/path/to/file"
-add-fd fd=4,set=2,opaque="rdonly:/path/to/file"
-drive file=/dev/fdset/2,index=0,media=disk
This example adds dups of fds 4 and 5, and the accompanying opaque
strings to the fd set with ID=2. qemu_open() already knows how
to handle a filename of this format. qemu_open() searches the
corresponding fd set for an fd and when it finds a match, QEMU
goes on to use a dup of that fd just like it would have used an
fd that it opened itself.
Signed-off-by: Corey Bryant <coreyb(a)linux.vnet.ibm.com>
---
v2:
- The -add-fd option is new in v2 (eblake(a)redhat.com)
v3:
- Require passed fd to be > stderr (eblake(a)redhat.com)
- Changed fds in examples to fd=3 and fd=4
- Add dup of passed fd to fd set and close passed fds after
processing all -add-fd commands (eblake(a)redhat.com)
qemu-config.c | 22 ++++++++++++++++++
qemu-options.hx | 36 +++++++++++++++++++++++++++++
vl.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 130 insertions(+)
diff --git a/qemu-config.c b/qemu-config.c
index cd1ec21..601237d 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -653,6 +653,27 @@ QemuOptsList qemu_boot_opts = {
},
};
+static QemuOptsList qemu_add_fd_opts = {
+ .name = "add-fd",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_add_fd_opts.head),
+ .desc = {
+ {
+ .name = "fd",
+ .type = QEMU_OPT_NUMBER,
+ .help = "file descriptor of which a duplicate is added to fd set",
+ },{
+ .name = "set",
+ .type = QEMU_OPT_NUMBER,
+ .help = "ID of the fd set to add fd to",
+ },{
+ .name = "opaque",
+ .type = QEMU_OPT_STRING,
+ .help = "free-form string used to describe fd",
+ },
+ { /* end of list */ }
+ },
+};
+
static QemuOptsList *vm_config_groups[32] = {
&qemu_drive_opts,
&qemu_chardev_opts,
@@ -669,6 +690,7 @@ static QemuOptsList *vm_config_groups[32] = {
&qemu_boot_opts,
&qemu_iscsi_opts,
&qemu_sandbox_opts,
+ &qemu_add_fd_opts,
NULL,
};
diff --git a/qemu-options.hx b/qemu-options.hx
index 7d97f96..a70182a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -257,6 +257,14 @@ qemu-system-i386 -drive file=file,index=2,media=disk
qemu-system-i386 -drive file=file,index=3,media=disk
@end example
+You can open an image using pre-opened file descriptors from an fd set:
+@example
+qemu-system-i386
+-add-fd fd=3,set=2,opaque="rdwr:/path/to/file"
+-add-fd fd=4,set=2,opaque="rdonly:/path/to/file"
+-drive file=/dev/fdset/2,index=0,media=disk
+@end example
+
You can connect a CDROM to the slave of ide0:
@example
qemu-system-i386 -drive file=file,if=ide,index=1,media=cdrom
@@ -289,6 +297,34 @@ qemu-system-i386 -hda a -hdb b
@end example
ETEXI
+DEF("add-fd", HAS_ARG, QEMU_OPTION_add_fd,
+ "-add-fd fd=fd,set=set[,opaque=opaque]\n"
+ " Add 'fd' to fd 'set'\n", QEMU_ARCH_ALL)
+STEXI
+@item -add-fd fd=@var{fd},set=@var{set}[,opaque=@var{opaque}]
+@findex -add-fd
+
+Add a file descriptor to an fd set. Valid options are:
+
+@table @option
+@item fd=@var{fd}
+This option defines the file descriptor of which a duplicate is added to fd set.
+The file descriptor cannot be stdin, stdout, or stderr.
+@item set=@var{set}
+This option defines the ID of the fd set to add the file descriptor to.
+@item opaque=@var{opaque}
+This option defines a free-form string that can be used to describe @var{fd}.
+@end table
+
+You can open an image using pre-opened file descriptors from an fd set:
+@example
+qemu-system-i386
+-add-fd fd=3,set=2,opaque="rdwr:/path/to/file"
+-add-fd fd=4,set=2,opaque="rdonly:/path/to/file"
+-drive file=/dev/fdset/2,index=0,media=disk
+@end example
+ETEXI
+
DEF("set", HAS_ARG, QEMU_OPTION_set,
"-set group.id.arg=value\n"
" set <arg> parameter for item <id> of type <group>\n"
diff --git a/vl.c b/vl.c
index 5b357a3..83205c0 100644
--- a/vl.c
+++ b/vl.c
@@ -790,6 +790,65 @@ static int parse_sandbox(QemuOpts *opts, void *opaque)
return 0;
}
+static int parse_add_fd(QemuOpts *opts, void *opaque)
+{
+ int fd, dupfd;
+ int64_t fdset_id;
+ const char *fd_opaque = NULL;
+
+ fd = qemu_opt_get_number(opts, "fd", -1);
+ fdset_id = qemu_opt_get_number(opts, "set", -1);
+ fd_opaque = qemu_opt_get(opts, "opaque");
+
+ if (fd < 0) {
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "fd option is required and must be non-negative");
+ return -1;
+ }
+
+ if (fd <= STDERR_FILENO) {
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "fd cannot be a standard I/O stream");
+ return -1;
+ }
+
+ if (fdset_id < 0) {
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "set option is required and must be non-negative");
+ return -1;
+ }
+
+#ifdef F_DUPFD_CLOEXEC
+ dupfd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
+#else
+ dupfd = dup(fd);
+ if (dupfd != -1) {
+ qemu_set_cloexec(dupfd);
+ }
+#endif
+ if (dupfd == -1) {
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "Error duplicating fd: %s", strerror(errno));
+ return -1;
+ }
+
+ /* add the duplicate fd, and optionally the opaque string, to the fd set */
+ monitor_fdset_add_fd(dupfd, true, fdset_id, fd_opaque ? true : false,
+ fd_opaque, NULL);
+
+ return 0;
+}
+
+static int cleanup_add_fd(QemuOpts *opts, void *opaque)
+{
+ int fd;
+
+ fd = qemu_opt_get_number(opts, "fd", -1);
+ close(fd);
+
+ return 0;
+}
+
/***********************************************************/
/* QEMU Block devices */
@@ -3309,6 +3368,11 @@ int main(int argc, char **argv, char **envp)
exit(0);
}
break;
+ case QEMU_OPTION_add_fd:
+ opts = qemu_opts_parse(qemu_find_opts("add-fd"), optarg, 0);
+ if (!opts) {
+ exit(0);
+ }
default:
os_parse_cmd_args(popt->index, optarg);
}
@@ -3320,6 +3384,14 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
+ if (qemu_opts_foreach(qemu_find_opts("add-fd"), parse_add_fd, NULL, 1)) {
+ exit(1);
+ }
+
+ if (qemu_opts_foreach(qemu_find_opts("add-fd"), cleanup_add_fd, NULL, 1)) {
+ exit(1);
+ }
+
if (machine == NULL) {
fprintf(stderr, "No machine found.\n");
exit(1);
--
1.7.11.4
12 years, 6 months
[libvirt] [PATCHv2 00/16] qemu block-commit support
by Eric Blake
I figured I'd better post this now, while I still iron out the
remaining kinks in my SELinux handling (but I'm certainly a lot
closer, now that I have libvirt actually identifying which files
need the temporary SELinux labels).
With this, you can now do things like 'virsh blockcommit $dom
$disk --top relative_name --shallow' even when the backing
chain refers to an absolute backing file name; the QMP command
passed to qemu will have the correct absolute names.
Patches 1-6:
practically unchanged since v1, although not reviewed yet
https://www.redhat.com/archives/libvir-list/2012-October/msg00075.html
Patches 7-13:
new to this series
Patches 14-15:
minor changes since v1 ACKs; see details in each commit
https://www.redhat.com/archives/libvir-list/2012-October/msg00089.html
Patch 16:
new to this series
Also available at:
http://repo.or.cz/w/libvirt/ericb.git/shortlog/refs/heads/blockjob
git fetch git://repo.or.cz/libvirt/ericb.git blockjob
Eric Blake (16):
storage: list more file types
storage: treat 'aio' like 'raw' at parse time
storage: match RNG to supported driver types
storage: use enum for default driver type
storage: use enum for disk driver type
storage: use enum for snapshot driver type
storage: don't probe non-files
storage: get entire metadata chain in one call
storage: don't require caller to pre-allocate metadata struct
storage: remember relative names in backing chain
storage: make it easier to find file within chain
storage: cache backing chain while qemu domain is live
storage: use cache to walk backing chain
blockjob: manage qemu block-commit monitor command
blockjob: wire up online qemu block-commit
blockjob: implement shallow commit flag in qemu
docs/schemas/domaincommon.rng | 27 +-
docs/schemas/domainsnapshot.rng | 2 +-
src/conf/capabilities.h | 4 +-
src/conf/domain_conf.c | 160 ++++--------
src/conf/domain_conf.h | 8 +-
src/conf/snapshot_conf.c | 23 +-
src/conf/snapshot_conf.h | 2 +-
src/conf/storage_conf.c | 15 +-
src/libvirt.c | 2 -
src/libvirt_private.syms | 1 +
src/libxl/libxl_conf.c | 42 ++--
src/libxl/libxl_driver.c | 6 +-
src/qemu/qemu_capabilities.c | 3 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_cgroup.c | 12 +-
src/qemu/qemu_command.c | 18 +-
src/qemu/qemu_domain.c | 40 ++-
src/qemu/qemu_domain.h | 3 +
src/qemu/qemu_driver.c | 236 +++++++++++------
src/qemu/qemu_hotplug.c | 9 +-
src/qemu/qemu_monitor.c | 30 +++
src/qemu/qemu_monitor.h | 7 +
src/qemu/qemu_monitor_json.c | 34 +++
src/qemu/qemu_monitor_json.h | 7 +
src/qemu/qemu_process.c | 23 ++
src/security/security_dac.c | 7 -
src/security/security_selinux.c | 11 -
src/security/virt-aa-helper.c | 27 +-
src/storage/storage_backend_fs.c | 15 +-
src/util/storage_file.c | 279 ++++++++++++++++-----
src/util/storage_file.h | 43 ++--
src/vbox/vbox_tmpl.c | 6 +-
src/xenxs/xen_sxpr.c | 26 +-
src/xenxs/xen_xm.c | 28 ++-
tests/sexpr2xmldata/sexpr2xml-curmem.xml | 2 +-
.../sexpr2xml-disk-block-shareable.xml | 2 +-
.../sexpr2xml-disk-drv-blktap-raw.xml | 2 +-
.../sexpr2xml-disk-drv-blktap2-raw.xml | 2 +-
38 files changed, 773 insertions(+), 392 deletions(-)
--
1.7.11.7
12 years, 6 months
[libvirt] [PATCH] network: Set to NULL after virNetworkDefFree()
by Michal Privoznik
which frees all allocated memory but doesn't set the passed pointer to
NULL. Therefore, we must do it ourselves. This is causing actual
libvirtd crash: Basically, when doing 'virsh net-edit' the newDef should
be dropped. And the memory is freed, indeed. However, the pointer is
not set to NULL but kept instead. And the next duo of calls 'virsh
net-start' and 'virsh net-destroy' starts the disaster. The latter one
does the same as 'virsh destroy'; it sees that newDef is nonNULL so it
replaces def with newDef (which has been freed already as said a few
lines above). Therefore any subsequent call accessing def will hit the ground.
---
src/conf/network_conf.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 891d48c..0f7470d 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -260,8 +260,9 @@ virNetworkObjAssignDef(virNetworkObjPtr network,
return -1;
}
} else if (!live) {
- virNetworkDefFree(network->newDef); /* should be unnecessary */
+ virNetworkDefFree(network->newDef);
virNetworkDefFree(network->def);
+ network->newDef = NULL;
network->def = def;
} else {
virReportError(VIR_ERR_OPERATION_INVALID,
--
1.7.8.6
12 years, 6 months
[libvirt] [PATCH] selinux: relabel tapfd in qemuPhysIfaceConnect
by Guannan Ren
Relabeling tapfd right after the tap device is created.
qemuPhysIfaceConnect is common function called both for static
netdevs and for hotplug netdevs.
---
src/qemu/qemu_command.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0c0c400..b24e9b1 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -170,6 +170,11 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
vmop, driver->stateDir,
virDomainNetGetActualBandwidth(net));
if (rc >= 0) {
+ if (virSecurityManagerSetTapFDLabel(driver->securityManager,
+ def, rc) < 0) {
+ VIR_FORCE_CLOSE(rc);
+ return -1;
+ }
virDomainAuditNetDevice(def, net, res_ifname, true);
VIR_FREE(net->ifname);
net->ifname = res_ifname;
@@ -5425,10 +5430,6 @@ qemuBuildCommandLine(virConnectPtr conn,
if (tapfd < 0)
goto error;
- if (virSecurityManagerSetTapFDLabel(driver->securityManager,
- def, tapfd) < 0)
- goto error;
-
last_good_net = i;
virCommandTransferFD(cmd, tapfd);
--
1.7.11.4
12 years, 6 months
[libvirt] [PATCH] dist: added cpu/cpu_ppc_data.h to Makefile.am
by Viktor Mihajlovski
Missing entry for cpu_ppc_data.h added to fix RPM build.
Signed-off-by: Viktor Mihajlovski <mihajlov(a)linux.vnet.ibm.com>
---
src/Makefile.am | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 9d3194d..187663f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -660,7 +660,7 @@ CPU_SOURCES = \
cpu/cpu_s390.h cpu/cpu_s390.c \
cpu/cpu_arm.h cpu/cpu_arm.c \
cpu/cpu_map.h cpu/cpu_map.c cpu/cpu_powerpc.h \
- cpu/cpu_powerpc.c
+ cpu/cpu_powerpc.c cpu/cpu_ppc_data.h
VMX_SOURCES = \
vmx/vmx.c vmx/vmx.h
--
1.7.0.4
12 years, 6 months
[libvirt] [PATCH] qemu: Always format CPU topology
by Jiri Denemark
When libvirt cannot find a suitable CPU model for host CPU (easily
reproducible by running libvirt in a guest), it would not provide CPU
topology in capabilities XML either. Even though CPU topology is known
and can be queried by virNodeGetInfo. With this patch, CPU topology will
always be provided in capabilities XML regardless on the presence of CPU
model.
---
src/qemu/qemu_capabilities.c | 6 +++---
src/qemu/qemu_command.c | 1 +
src/qemu/qemu_domain.c | 4 +++-
src/qemu/qemu_driver.c | 3 ++-
4 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 985d4de..7c391b3 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -685,6 +685,7 @@ qemuCapsInitGuest(virCapsPtr caps,
nmachines = 0;
if (caps->host.cpu &&
+ caps->host.cpu->model &&
qemuCapsGetCPUDefinitions(qemubinCaps, NULL) > 0 &&
!virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0))
goto error;
@@ -781,12 +782,11 @@ qemuCapsInitCPU(virCapsPtr caps,
cpu->sockets = nodeinfo.sockets;
cpu->cores = nodeinfo.cores;
cpu->threads = nodeinfo.threads;
+ caps->host.cpu = cpu;
if (!(data = cpuNodeData(arch))
|| cpuDecode(cpu, data, NULL, 0, NULL) < 0)
- goto error;
-
- caps->host.cpu = cpu;
+ goto cleanup;
ret = 0;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9c72c10..9096b3c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4100,6 +4100,7 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
int hasSVM;
if (!host ||
+ !host->model ||
(ncpus = qemuCapsGetCPUDefinitions(caps, &cpus)) == 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("CPU specification not supported by hypervisor"));
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 427258d..cbc621f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1227,7 +1227,9 @@ qemuDomainDefFormatBuf(struct qemud_driver *driver,
if ((flags & VIR_DOMAIN_XML_UPDATE_CPU) &&
def_cpu &&
(def_cpu->mode != VIR_CPU_MODE_CUSTOM || def_cpu->model)) {
- if (!driver->caps || !driver->caps->host.cpu) {
+ if (!driver->caps ||
+ !driver->caps->host.cpu ||
+ !driver->caps->host.cpu->model) {
virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("cannot get host CPU capabilities"));
goto cleanup;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index adfbfa6..76730c6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10180,7 +10180,8 @@ qemuCPUCompare(virConnectPtr conn,
if (!driver->caps) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot get host capabilities"));
- } else if (!driver->caps->host.cpu) {
+ } else if (!driver->caps->host.cpu ||
+ !driver->caps->host.cpu->model) {
VIR_WARN("cannot get host CPU capabilities");
ret = VIR_CPU_COMPARE_INCOMPATIBLE;
} else {
--
1.7.12.4
12 years, 6 months
[libvirt] [PATCH v3 2/4] monitor: Enable adding an inherited fd to an fd set
by Corey Bryant
qmp_add_fd() gets an fd that was received over a socket with
SCM_RIGHTS and adds it to an fd set. This patch adds support
that will enable adding an fd that was inherited on the
command line to an fd set.
Note: All of the code added to monitor_fdset_add_fd(), with the
exception of the error path for non-valid fdset-id, is code motion
from qmp_add_fd().
Signed-off-by: Corey Bryant <coreyb(a)linux.vnet.ibm.com>
---
v2:
-Removed Error** parameter from monitor_fdset_add_fd()
v3:
-Added Error** parameter back to monitor_fdset_add_fd()
-Move 'if (!mon_fdset_cur)' change to patch 1 (kwolf(a)redhat.com)
-Move code that prevents removal of fd from fd set during init
to it's own patch (eblake(a)redhat.com, kwolf(a)redhat.com)
-Mention code motion in commit message (kwolf(a)redhat.com)
monitor.c | 157 +++++++++++++++++++++++++++++++++-----------------------------
monitor.h | 3 ++
2 files changed, 86 insertions(+), 74 deletions(-)
diff --git a/monitor.c b/monitor.c
index 2e3248f..5d5de41 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2135,9 +2135,6 @@ AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque,
{
int fd;
Monitor *mon = cur_mon;
- MonFdset *mon_fdset = NULL;
- MonFdsetFd *mon_fdset_fd;
- AddfdInfo *fdinfo;
fd = qemu_chr_fe_get_msgfd(mon->chr);
if (fd == -1) {
@@ -2145,77 +2142,8 @@ AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque,
goto error;
}
- if (has_fdset_id) {
- QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
- /* Break if match found or match impossible due to ordering by ID */
- if (fdset_id <= mon_fdset->id) {
- if (fdset_id < mon_fdset->id) {
- mon_fdset = NULL;
- }
- break;
- }
- }
- }
-
- if (mon_fdset == NULL) {
- int64_t fdset_id_prev = -1;
- MonFdset *mon_fdset_cur = QLIST_FIRST(&mon_fdsets);
-
- if (has_fdset_id) {
- if (fdset_id < 0) {
- error_set(errp, QERR_INVALID_PARAMETER_VALUE, "fdset-id",
- "a non-negative value");
- goto error;
- }
- /* Use specified fdset ID */
- QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
- mon_fdset_cur = mon_fdset;
- if (fdset_id < mon_fdset_cur->id) {
- break;
- }
- }
- } else {
- /* Use first available fdset ID */
- QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
- mon_fdset_cur = mon_fdset;
- if (fdset_id_prev == mon_fdset_cur->id - 1) {
- fdset_id_prev = mon_fdset_cur->id;
- continue;
- }
- break;
- }
- }
-
- mon_fdset = g_malloc0(sizeof(*mon_fdset));
- if (has_fdset_id) {
- mon_fdset->id = fdset_id;
- } else {
- mon_fdset->id = fdset_id_prev + 1;
- }
-
- /* The fdset list is ordered by fdset ID */
- if (!mon_fdset_cur) {
- QLIST_INSERT_HEAD(&mon_fdsets, mon_fdset, next);
- } else if (mon_fdset->id < mon_fdset_cur->id) {
- QLIST_INSERT_BEFORE(mon_fdset_cur, mon_fdset, next);
- } else {
- QLIST_INSERT_AFTER(mon_fdset_cur, mon_fdset, next);
- }
- }
-
- mon_fdset_fd = g_malloc0(sizeof(*mon_fdset_fd));
- mon_fdset_fd->fd = fd;
- mon_fdset_fd->removed = false;
- if (has_opaque) {
- mon_fdset_fd->opaque = g_strdup(opaque);
- }
- QLIST_INSERT_HEAD(&mon_fdset->fds, mon_fdset_fd, next);
-
- fdinfo = g_malloc0(sizeof(*fdinfo));
- fdinfo->fdset_id = mon_fdset->id;
- fdinfo->fd = mon_fdset_fd->fd;
-
- return fdinfo;
+ return monitor_fdset_add_fd(fd, has_fdset_id, fdset_id,
+ has_opaque, opaque, errp);
error:
if (fd != -1) {
@@ -2301,6 +2229,87 @@ FdsetInfoList *qmp_query_fdsets(Error **errp)
return fdset_list;
}
+AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
+ bool has_opaque, const char *opaque,
+ Error **errp)
+{
+ MonFdset *mon_fdset = NULL;
+ MonFdsetFd *mon_fdset_fd;
+ AddfdInfo *fdinfo;
+
+ if (has_fdset_id) {
+ QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
+ /* Break if match found or match impossible due to ordering by ID */
+ if (fdset_id <= mon_fdset->id) {
+ if (fdset_id < mon_fdset->id) {
+ mon_fdset = NULL;
+ }
+ break;
+ }
+ }
+ }
+
+ if (mon_fdset == NULL) {
+ int64_t fdset_id_prev = -1;
+ MonFdset *mon_fdset_cur = QLIST_FIRST(&mon_fdsets);
+
+ if (has_fdset_id) {
+ if (fdset_id < 0) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, "fdset-id",
+ "a non-negative value");
+ return NULL;
+ }
+ /* Use specified fdset ID */
+ QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
+ mon_fdset_cur = mon_fdset;
+ if (fdset_id < mon_fdset_cur->id) {
+ break;
+ }
+ }
+ } else {
+ /* Use first available fdset ID */
+ QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
+ mon_fdset_cur = mon_fdset;
+ if (fdset_id_prev == mon_fdset_cur->id - 1) {
+ fdset_id_prev = mon_fdset_cur->id;
+ continue;
+ }
+ break;
+ }
+ }
+
+ mon_fdset = g_malloc0(sizeof(*mon_fdset));
+ if (has_fdset_id) {
+ mon_fdset->id = fdset_id;
+ } else {
+ mon_fdset->id = fdset_id_prev + 1;
+ }
+
+ /* The fdset list is ordered by fdset ID */
+ if (!mon_fdset_cur) {
+ QLIST_INSERT_HEAD(&mon_fdsets, mon_fdset, next);
+ } else if (mon_fdset->id < mon_fdset_cur->id) {
+ QLIST_INSERT_BEFORE(mon_fdset_cur, mon_fdset, next);
+ } else {
+ QLIST_INSERT_AFTER(mon_fdset_cur, mon_fdset, next);
+ }
+ }
+
+ mon_fdset_fd = g_malloc0(sizeof(*mon_fdset_fd));
+ mon_fdset_fd->fd = fd;
+ mon_fdset_fd->removed = false;
+ if (has_opaque) {
+ mon_fdset_fd->opaque = g_strdup(opaque);
+ }
+ QLIST_INSERT_HEAD(&mon_fdset->fds, mon_fdset_fd, next);
+
+ fdinfo = g_malloc0(sizeof(*fdinfo));
+ fdinfo->fdset_id = mon_fdset->id;
+ fdinfo->fd = mon_fdset_fd->fd;
+
+ return fdinfo;
+}
+
int monitor_fdset_get_fd(int64_t fdset_id, int flags)
{
#ifndef _WIN32
diff --git a/monitor.h b/monitor.h
index b6e7d95..d4c017e 100644
--- a/monitor.h
+++ b/monitor.h
@@ -90,6 +90,9 @@ int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret);
int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret);
+AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
+ bool has_opaque, const char *opaque,
+ Error **errp);
int monitor_fdset_get_fd(int64_t fdset_id, int flags);
int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd);
int monitor_fdset_dup_fd_remove(int dup_fd);
--
1.7.11.4
12 years, 6 months
[libvirt] [PATCH v3 3/4] monitor: Prevent removing fd from set during init
by Corey Bryant
If an fd is added to an fd set via the command line, and it is not
referenced by another command line option (ie. -drive), then clean
it up after QEMU initialization is complete.
Signed-off-by: Corey Bryant <coreyb(a)linux.vnet.ibm.com>
---
v3:
- This patch was split into it's own patch in v3
(eblake(a)redhat.com, kwolf(a)redhat.com)
monitor.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/monitor.c b/monitor.c
index 5d5de41..0dae7ac 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2105,8 +2105,9 @@ static void monitor_fdset_cleanup(MonFdset *mon_fdset)
MonFdsetFd *mon_fdset_fd_next;
QLIST_FOREACH_SAFE(mon_fdset_fd, &mon_fdset->fds, next, mon_fdset_fd_next) {
- if (mon_fdset_fd->removed ||
- (QLIST_EMPTY(&mon_fdset->dup_fds) && mon_refcount == 0)) {
+ if ((mon_fdset_fd->removed ||
+ (QLIST_EMPTY(&mon_fdset->dup_fds) && mon_refcount == 0)) &&
+ runstate_is_running()) {
close(mon_fdset_fd->fd);
g_free(mon_fdset_fd->opaque);
QLIST_REMOVE(mon_fdset_fd, next);
--
1.7.11.4
12 years, 6 months
[libvirt] [HELP] QEMU guest agent via ISA serial port, or shutdown hooks?
by Thorsten Glaser
Hi,
http://www.redhat.com/archives/libvir-list/2012-January/msg00629.html
added support only for when using the virtio channel to the guest.
However, QEMU Guest Agent support is most useful to guests that do
not implement ACPI shutdown support; these usually don’t have virtio
(especially since I was unable to find a how-to-implement-virtio-in-
a-kernel document, otherwise MirBSD might do virtio-rng at least ☺),
so the serial transport would be best.
The problem is of course the two lines:
+ if (channel->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO)
+ continue;
I’ve done a bit of hacking to allow the name attribute in the domain
XML for any character device (probably half wrong, but this was just
a quick test for me) and commented out these two lines, to see whether
qga support on ISA ports is doable. (You probably would want to allow
the attribute only on virtio and ISA serial ports, then.)
Patch follows, NOT FOR APPLYING AS-IS:
--- libvirt-0.9.12.orig/src/conf/domain_conf.c
+++ libvirt-0.9.12/src/conf/domain_conf.c
@@ -1266,6 +1266,7 @@ void virDomainChrDefFree(virDomainChrDef
break;
default:
+ VIR_FREE(def->target.name);
break;
}
@@ -4954,6 +4955,7 @@ virDomainChrDefParseTargetXML(virCapsPtr
break;
default:
+ def->target.name = virXMLPropString(cur, "name");
portStr = virXMLPropString(cur, "port");
if (portStr == NULL) {
/* Set to negative value to indicate we should set it later */
@@ -11685,11 +11687,16 @@ virDomainChrDefFormat(virBufferPtr buf,
virDomainChrTargetTypeToString(def->deviceType,
def->targetType),
def->target.port);
+ //XXX def->target.name is lost
break;
default:
- virBufferAsprintf(buf, " <target port='%d'/>\n",
+ virBufferAsprintf(buf, " <target port='%d'",
def->target.port);
+ if (def->target.name) {
+ virBufferEscapeString(buf, " name='%s'", def->target.name);
+ }
+ virBufferAddLit(buf, "/>\n");
break;
}
--- libvirt-0.9.12.orig/src/qemu/qemu_process.c
+++ libvirt-0.9.12/src/qemu/qemu_process.c
@@ -191,8 +191,8 @@ qemuFindAgentConfig(virDomainDefPtr def)
for (i = 0 ; i < def->nchannels ; i++) {
virDomainChrDefPtr channel = def->channels[i];
- if (channel->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO)
- continue;
+// if (channel->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO)
+// continue;
if (STREQ_NULLABLE(channel->target.name, "org.qemu.guest_agent.0")) {
config = &channel->source;
Unfortunately, that seems to not be enough: trying to build the
resulting libvirt package segfaults in the testsuite, so I must
have some mistakes in the XML part. I’m really not familiar with
all this, I’d “just” like to have my BSD VMs shut down cleanly
when the host is shut down, so please advice.
Does libvirt (the dæmon, probably) offer a shutdown hook, e.g.
I could tell it to run a shellscript that ssh(1)s to the VM with
a passwordless key to shut it down, instead? (Same for when the
Shutdown or Restart functions in virt-manager are used, or virsh.)
Thanks in advance,
//mirabilos
--
> Hi, does anyone sell openbsd stickers by themselves and not packaged
> with other products?
No, the only way I've seen them sold is for $40 with a free OpenBSD CD.
-- Haroon Khalid and Steve Shockley in gmane.os.openbsd.misc
12 years, 6 months