[libvirt] [PATCH] Make tcp_chr_read() use recvmsg()
by Mark McLoughlin
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
---
qemu-char.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index 287e0cd..e0d7220 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1911,15 +1911,25 @@ static void tcp_chr_read(void *opaque)
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
+ struct msghdr msg = { 0, };
+ struct iovec iov[1];
uint8_t buf[1024];
int len, size;
if (!s->connected || s->max_size <= 0)
return;
+
len = sizeof(buf);
if (len > s->max_size)
len = s->max_size;
- size = recv(s->fd, (void *)buf, len, 0);
+
+ iov[0].iov_base = buf;
+ iov[0].iov_len = len;
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+
+ size = recvmsg(s->fd, &msg, 0);
if (size == 0) {
/* connection closed */
s->connected = 0;
--
1.6.2.5
15 years, 4 months
[libvirt] [PATCH] Add support for fd=name to tap and socket networking
by Mark McLoughlin
This allows a program to initialize a host networking device using a
file descriptor passed over a unix monitor socket.
The program must first pass the file descriptor using SCM_RIGHTS
ancillary data with the getfd monitor command. It then may do
"host_net_add tap fd=name" to use the named file descriptor.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
---
net.c | 42 +++++++++++++++++++++++++++++++++++-------
1 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/net.c b/net.c
index 90cf912..1838692 100644
--- a/net.c
+++ b/net.c
@@ -2410,6 +2410,23 @@ void qemu_check_nic_model_list(NICInfo *nd, const char * const *models,
exit(exit_status);
}
+static int net_handle_fd_param(Monitor *mon, const char *param)
+{
+ if (!qemu_isdigit(param[0])) {
+ int fd;
+
+ fd = monitor_get_fd(mon, param);
+ if (fd == -1) {
+ config_error(mon, "No file descriptor named %s found", param);
+ return -1;
+ }
+
+ return fd;
+ } else {
+ return strtol(param, NULL, 0);
+ }
+}
+
int net_client_init(Monitor *mon, const char *device, const char *p)
{
char buf[1024];
@@ -2650,14 +2667,20 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
static const char * const fd_params[] = {
"vlan", "name", "fd", "sndbuf", NULL
};
+ ret = -1;
if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) {
config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
- ret = -1;
goto out;
}
- fd = strtol(buf, NULL, 0);
+ fd = net_handle_fd_param(mon, buf);
+ if (fd == -1) {
+ goto out;
+ }
fcntl(fd, F_SETFL, O_NONBLOCK);
s = net_tap_fd_init(vlan, device, name, fd);
+ if (!s) {
+ close(fd);
+ }
} else {
static const char * const tap_params[] = {
"vlan", "name", "ifname", "script", "downscript", "sndbuf", NULL
@@ -2697,15 +2720,20 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
"vlan", "name", "fd", NULL
};
int fd;
+ ret = -1;
if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) {
config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
- ret = -1;
goto out;
}
- fd = strtol(buf, NULL, 0);
- ret = -1;
- if (net_socket_fd_init(vlan, device, name, fd, 1))
- ret = 0;
+ fd = net_handle_fd_param(mon, buf);
+ if (fd == -1) {
+ goto out;
+ }
+ if (!net_socket_fd_init(vlan, device, name, fd, 1)) {
+ close(fd);
+ goto out;
+ }
+ ret = 0;
} else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
static const char * const listen_params[] = {
"vlan", "name", "listen", NULL
--
1.6.2.5
15 years, 4 months
[libvirt] [PATCH] Add monitor_get_fd() command for fetching named fds
by Mark McLoughlin
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
---
monitor.c | 24 ++++++++++++++++++++++++
monitor.h | 2 ++
2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/monitor.c b/monitor.c
index 817e4b7..6ad2e14 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1774,6 +1774,30 @@ static void do_closefd(Monitor *mon, const char *fdname)
fdname);
}
+int monitor_get_fd(Monitor *mon, const char *fdname)
+{
+ mon_fd_t *monfd;
+
+ LIST_FOREACH(monfd, &mon->fds, next) {
+ int fd;
+
+ if (strcmp(monfd->name, fdname) != 0) {
+ continue;
+ }
+
+ fd = monfd->fd;
+
+ /* caller takes ownership of fd */
+ LIST_REMOVE(monfd, next);
+ qemu_free(monfd->name);
+ qemu_free(monfd);
+
+ return fd;
+ }
+
+ return -1;
+}
+
static const mon_cmd_t mon_cmds[] = {
#include "qemu-monitor.h"
{ NULL, NULL, },
diff --git a/monitor.h b/monitor.h
index 13e8cc7..f6a43c0 100644
--- a/monitor.h
+++ b/monitor.h
@@ -20,6 +20,8 @@ void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
BlockDriverCompletionFunc *completion_cb,
void *opaque);
+int monitor_get_fd(Monitor *mon, const char *fdname);
+
void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap);
void monitor_printf(Monitor *mon, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
--
1.6.2.5
15 years, 4 months
[libvirt] [PATCH] Add getfd and closefd monitor commands
by Mark McLoughlin
Add monitor commands to support passing file descriptors via
SCM_RIGHTS.
getfd assigns the passed file descriptor a name for use with other
monitor commands.
closefd allows passed file descriptors to be closed. If a monitor
command actually uses a named file descriptor, closefd will not be
required.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
---
monitor.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
qemu-monitor.hx | 18 ++++++++++++++
2 files changed, 87 insertions(+), 0 deletions(-)
diff --git a/monitor.c b/monitor.c
index e38c86e..817e4b7 100644
--- a/monitor.c
+++ b/monitor.c
@@ -70,6 +70,14 @@ typedef struct mon_cmd_t {
const char *help;
} mon_cmd_t;
+/* file descriptors passed via SCM_RIGHTS */
+typedef struct mon_fd_t mon_fd_t;
+struct mon_fd_t {
+ char *name;
+ int fd;
+ LIST_ENTRY(mon_fd_t) next;
+};
+
struct Monitor {
CharDriverState *chr;
int flags;
@@ -80,6 +88,7 @@ struct Monitor {
CPUState *mon_cpu;
BlockDriverCompletionFunc *password_completion_cb;
void *password_opaque;
+ LIST_HEAD(,mon_fd_t) fds;
LIST_ENTRY(Monitor) entry;
};
@@ -1705,6 +1714,66 @@ static void do_inject_mce(Monitor *mon,
}
#endif
+static void do_getfd(Monitor *mon, const char *fdname)
+{
+ mon_fd_t *monfd;
+ int fd;
+
+ fd = qemu_chr_get_msgfd(mon->chr);
+ if (fd == -1) {
+ monitor_printf(mon, "getfd: no file descriptor supplied via SCM_RIGHTS\n");
+ return;
+ }
+
+ if (qemu_isdigit(fdname[0])) {
+ monitor_printf(mon, "getfd: monitor names may not begin with a number\n");
+ return;
+ }
+
+ fd = dup(fd);
+ if (fd == -1) {
+ monitor_printf(mon, "Failed to dup() file descriptor: %s\n",
+ strerror(errno));
+ return;
+ }
+
+ LIST_FOREACH(monfd, &mon->fds, next) {
+ if (strcmp(monfd->name, fdname) != 0) {
+ continue;
+ }
+
+ close(monfd->fd);
+ monfd->fd = fd;
+ return;
+ }
+
+ monfd = qemu_mallocz(sizeof(mon_fd_t));
+ monfd->name = qemu_strdup(fdname);
+ monfd->fd = fd;
+
+ LIST_INSERT_HEAD(&mon->fds, monfd, next);
+}
+
+static void do_closefd(Monitor *mon, const char *fdname)
+{
+ mon_fd_t *monfd;
+
+ LIST_FOREACH(monfd, &mon->fds, next) {
+ if (strcmp(monfd->name, fdname) != 0) {
+ continue;
+ }
+
+ LIST_REMOVE(monfd, next);
+ close(monfd->fd);
+ qemu_free(monfd->name);
+ qemu_free(monfd);
+ return;
+ }
+
+ monitor_printf(mon, "Failed to find file descriptor named %s\n",
+ fdname);
+}
+
static const mon_cmd_t mon_cmds[] = {
#include "qemu-monitor.h"
{ NULL, NULL, },
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 70e2475..11bdb2c 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -628,6 +628,24 @@ STEXI
Inject an MCE on the given CPU (x86 only).
ETEXI
+ { "getfd", "s", do_getfd, "getfd name",
+ "receive a file descriptor via SCM rights and assign it a name" },
+STEXI
+@item getfd @var{fdname}
+If a file descriptor is passed alongside this command using the SCM_RIGHTS
+mechanism on unix sockets, it is stored using the name @var{fdname} for
+later use by other monitor commands.
+ETEXI
+
+ { "closefd", "s", do_closefd, "closefd name",
+ "close a file descriptor previously passed via SCM rights" },
+STEXI
+@item closefd @var{fdname}
+Close the file descriptor previously assigned to @var{fdname} using the
+@code{getfd} command. This is only needed if the file descriptor was never
+used by another monitor command.
+ETEXI
+
STEXI
@end table
ETEXI
--
1.6.2.5
15 years, 4 months
[libvirt] [PATCH] Add SCM_RIGHTS support to unix socket character devices
by Mark McLoughlin
If a file descriptor is passed via a message with SCM_RIGHTS ancillary
data on a unix socket, store the file descriptor for use in the
chr_read() handler. Close the file descriptor if it was not used.
The qemu_chr_get_msgfd() API provides access to the passed descriptor.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
---
qemu-char.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
qemu-char.h | 2 ++
2 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index e0d7220..f06a614 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -168,6 +168,11 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
s->chr_read(s->handler_opaque, buf, len);
}
+int qemu_chr_get_msgfd(CharDriverState *s)
+{
+ return s->get_msgfd ? s->get_msgfd(s) : -1;
+}
+
void qemu_chr_accept_input(CharDriverState *s)
{
if (s->chr_accept_input)
@@ -1832,6 +1837,7 @@ typedef struct {
int do_telnetopt;
int do_nodelay;
int is_unix;
+ int msgfd;
} TCPCharDriver;
static void tcp_chr_accept(void *opaque);
@@ -1907,12 +1913,46 @@ static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
*size = j;
}
+static int tcp_get_msgfd(CharDriverState *chr)
+{
+ TCPCharDriver *s = chr->opaque;
+
+ return s->msgfd;
+}
+
+static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg)
+{
+ TCPCharDriver *s = chr->opaque;
+ struct cmsghdr *cmsg;
+
+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ int fd;
+
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
+ cmsg->cmsg_level != SOL_SOCKET ||
+ cmsg->cmsg_type != SCM_RIGHTS)
+ continue;
+
+ fd = *((int *)CMSG_DATA(cmsg));
+ if (fd < 0)
+ continue;
+
+ if (s->msgfd != -1)
+ close(s->msgfd);
+ s->msgfd = fd;
+ }
+}
+
static void tcp_chr_read(void *opaque)
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
struct msghdr msg = { 0, };
struct iovec iov[1];
+ union {
+ struct cmsghdr cmsg;
+ char control[CMSG_SPACE(sizeof(int))];
+ } msg_control;
uint8_t buf[1024];
int len, size;
@@ -1928,6 +1968,8 @@ static void tcp_chr_read(void *opaque)
msg.msg_iov = iov;
msg.msg_iovlen = 1;
+ msg.msg_control = &msg_control;
+ msg.msg_controllen = sizeof(msg_control);
size = recvmsg(s->fd, &msg, 0);
if (size == 0) {
@@ -1940,10 +1982,16 @@ static void tcp_chr_read(void *opaque)
closesocket(s->fd);
s->fd = -1;
} else if (size > 0) {
+ if (s->is_unix)
+ unix_process_msgfd(chr, &msg);
if (s->do_telnetopt)
tcp_chr_process_IAC_bytes(chr, s, buf, &size);
if (size > 0)
qemu_chr_read(chr, buf, size);
+ if (s->msgfd != -1) {
+ close(s->msgfd);
+ s->msgfd = -1;
+ }
}
}
@@ -2105,12 +2153,14 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
s->connected = 0;
s->fd = -1;
s->listen_fd = -1;
+ s->msgfd = -1;
s->is_unix = is_unix;
s->do_nodelay = do_nodelay && !is_unix;
chr->opaque = s;
chr->chr_write = tcp_chr_write;
chr->chr_close = tcp_chr_close;
+ chr->get_msgfd = tcp_get_msgfd;
if (is_listen) {
s->listen_fd = fd;
diff --git a/qemu-char.h b/qemu-char.h
index e1aa8db..77d4eda 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -51,6 +51,7 @@ struct CharDriverState {
int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
void (*chr_update_read_handler)(struct CharDriverState *s);
int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
+ int (*get_msgfd)(struct CharDriverState *s);
IOEventHandler *chr_event;
IOCanRWHandler *chr_can_read;
IOReadHandler *chr_read;
@@ -81,6 +82,7 @@ void qemu_chr_reset(CharDriverState *s);
void qemu_chr_initial_reset(void);
int qemu_chr_can_read(CharDriverState *s);
void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
+int qemu_chr_get_msgfd(CharDriverState *s);
void qemu_chr_accept_input(CharDriverState *s);
void qemu_chr_info(Monitor *mon);
--
1.6.2.5
15 years, 4 months
[libvirt] libvirt-java, deprecated methods?
by Thomas Treutner
Hi,
I'm playing around with libvirt-0.6.5 and libvirt-java-0.2.1 these days.
It looks very interesting, but I think I may have found a bug:
....
conn = new Connect("xen://node02", false);
....
conn.setDom0Memory(512000)
gives:
exception caught:org.libvirt.LibvirtException: invalid domain pointer in
virDomainSetMemory
level:VIR_ERR_ERROR
code:VIR_ERR_INVALID_DOMAIN
domain:VIR_FROM_DOM
hasConn:false
hasDom:false
hasNet:false
message:invalid domain pointer in virDomainSetMemory
str1:invalid domain pointer in %s
str2:virDomainSetMemory
str3:null
int1:0
int2:0
Furthermore, f.e. conn.GetHypervisorVersion(conn.getType()) gives:
exception caught:org.libvirt.LibvirtException: this function is not supported
by the hypervisor: Xen
level:VIR_ERR_ERROR
code:VIR_ERR_NO_SUPPORT
domain:VIR_FROM_NONE
hasConn:false
hasDom:false
hasNet:false
message:this function is not supported by the hypervisor: Xen
str1:this function is not supported by the hypervisor: %s
str2:Xen
str3:null
int1:0
int2:0
But
Domain dom0=conn.domainLookupByID(0); //domainLookupByName("Domain-0"); too
DomainInfo dom0info = dom0.getInfo();
....
dom0.setMemory(256000);
....
works without glitches and does the job (btw, I can't see any effect of
setMaxMemory() on Xen?)
Is it possible that there are some inconsistences between libvirt-java and
libvirt? Since libvirt-java wasn't updated approx. 1y, I assume that.
Thanks for feedback,
kr,
thomas
15 years, 4 months
[libvirt] [PATCH] Extra filesystem options during backend filesystem mount.
by Harshavardhana
New option index added to support -o options for various netfs.
Currently added an option for glusterfs.
---
src/storage_backend_fs.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/src/storage_backend_fs.c b/src/storage_backend_fs.c
index c3d66b5..606fb47 100644
--- a/src/storage_backend_fs.c
+++ b/src/storage_backend_fs.c
@@ -604,6 +604,7 @@ static int
virStorageBackendFileSystemMount(virConnectPtr conn,
virStoragePoolObjPtr pool) {
char *src;
+ char *options;
const char **mntargv;
/* 'mount -t auto' doesn't seem to auto determine nfs (or cifs),
@@ -611,6 +612,10 @@ virStorageBackendFileSystemMount(virConnectPtr conn,
* accommodate this */
int netauto = (pool->def->type == VIR_STORAGE_POOL_NETFS &&
pool->def->source.format == VIR_STORAGE_POOL_NETFS_AUTO);
+ int glusterfs = (pool->def->type == VIR_STORAGE_POOL_NETFS &&
+ pool->def->source.format == VIR_STORAGE_POOL_NETFS_GLUSTERFS);
+
+ int option_index;
int source_index;
const char *netfs_auto_argv[] = {
@@ -632,9 +637,26 @@ virStorageBackendFileSystemMount(virConnectPtr conn,
NULL,
};
+ const char *glusterfs_argv[] = {
+ MOUNT,
+ "-t",
+ pool->def->type == VIR_STORAGE_POOL_FS ?
+ virStoragePoolFormatFileSystemTypeToString(pool->def->source.format) :
+ virStoragePoolFormatFileSystemNetTypeToString(pool->def->source.format),
+ NULL,
+ "-o",
+ NULL,
+ pool->def->target.path,
+ NULL,
+ };
+
if (netauto) {
mntargv = netfs_auto_argv;
source_index = 1;
+ } else if (glusterfs) {
+ mntargv = glusterfs_argv;
+ source_index = 3;
+ option_index = 5;
} else {
mntargv = fs_argv;
source_index = 3;
@@ -670,6 +692,12 @@ virStorageBackendFileSystemMount(virConnectPtr conn,
}
if (pool->def->type == VIR_STORAGE_POOL_NETFS) {
+ if (pool->def->source.format = VIR_STORAGE_POOL_NETFS_GLUSTERFS) {
+ if (virAsprintf(&options, "direct-io-mode=1") == -1) {
+ virReportOOMError(conn);
+ return -1;
+ }
+ }
if (virAsprintf(&src, "%s:%s",
pool->def->source.host.name,
pool->def->source.dir) == -1) {
@@ -685,6 +713,10 @@ virStorageBackendFileSystemMount(virConnectPtr conn,
}
mntargv[source_index] = src;
+ if (glusterfs) {
+ mntargv[option_index] = options;
+ }
+
if (virRun(conn, mntargv, NULL) < 0) {
VIR_FREE(src);
return -1;
--
1.6.0.6
15 years, 4 months
[libvirt] Workaround to start xen inside a buggy kvm
by Thomas Fricke
Buggy kvm crashes with kernel panic if xen started inside a kvm machine.
kvm needs the -no-kvm-pit, this argument is not available with libvirt.
I have tested the following workaround on ubuntu 9.04
Rename kvm
cd /usr/bin
mv kvm kvm.orig
Use the following script instead the original kvm
#!/bin/sh
exec kvm.orig -no-kvm-pit $*
Do not forget chmod +x kvm
Have fun,
Thomas
15 years, 4 months