#define READ_BUF_LEN 4096
#define READ_RETRIES 10
#define CHR_MAX_FILENAME_SIZE 256
+#define TCP_MAX_FDS 16
/***********************************************************/
/* Socket address helpers */
"% h print this help\n\r",
"% x exit emulator\n\r",
"% s save disk data back to file (if -snapshot)\n\r",
- "% t toggle console timestamps\n\r"
+ "% t toggle console timestamps\n\r",
"% b send break (magic sysrq)\n\r",
"% c switch between console and monitor\n\r",
"% % sends %\n\r",
guint reconnect_timer;
int64_t reconnect_time;
+ bool connect_err_reported;
} TCPCharDriver;
static gboolean socket_reconnect_timeout(gpointer opaque);
socket_reconnect_timeout, chr);
}
+static void check_report_connect_error(CharDriverState *chr,
+ Error *err)
+{
+ TCPCharDriver *s = chr->opaque;
+
+ if (!s->connect_err_reported) {
+ error_report("Unable to connect character device %s: %s",
+ chr->label, error_get_pretty(err));
+ s->connect_err_reported = true;
+ }
+ qemu_chr_socket_restart_timer(chr);
+}
+
static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);
#ifndef _WIN32
TCPCharDriver *s = chr->opaque;
int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;
+ assert(num <= TCP_MAX_FDS);
+
if (to_copy) {
int i;
struct iovec iov[1];
union {
struct cmsghdr cmsg;
- char control[CMSG_SPACE(sizeof(int))];
+ char control[CMSG_SPACE(sizeof(int) * TCP_MAX_FDS)];
} msg_control;
int flags = 0;
ssize_t ret;
}
}
-static void qemu_chr_socket_connected(int fd, void *opaque)
+static void qemu_chr_socket_connected(int fd, Error *err, void *opaque)
{
CharDriverState *chr = opaque;
+ TCPCharDriver *s = chr->opaque;
if (fd < 0) {
- qemu_chr_socket_restart_timer(chr);
+ check_report_connect_error(chr, err);
return;
}
+ s->connect_err_reported = false;
qemu_chr_finish_socket_connection(chr, fd);
}
#endif /* WIN32 */
+static void socket_try_connect(CharDriverState *chr)
+{
+ Error *err = NULL;
+
+ if (!qemu_chr_open_socket_fd(chr, &err)) {
+ check_report_connect_error(chr, err);
+ }
+}
+
static gboolean socket_reconnect_timeout(gpointer opaque)
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
- Error *err;
s->reconnect_timer = 0;
return false;
}
- if (!qemu_chr_open_socket_fd(chr, &err)) {
- error_report("Unable to connect to char device %s\n", chr->label);
- qemu_chr_socket_restart_timer(chr);
- }
+ socket_try_connect(chr);
return false;
}
s->reconnect_time = reconnect;
}
- if (!qemu_chr_open_socket_fd(chr, errp)) {
- if (s->reconnect_time) {
- qemu_chr_socket_restart_timer(chr);
- } else {
- g_free(s);
- g_free(chr->filename);
- g_free(chr);
- return NULL;
- }
+ if (s->reconnect_time) {
+ socket_try_connect(chr);
+ } else if (!qemu_chr_open_socket_fd(chr, errp)) {
+ g_free(s);
+ g_free(chr->filename);
+ g_free(chr);
+ return NULL;
}
if (is_listen && is_waitconnect) {