Skip to content

Commit 84615a1

Browse files
manishmishrJuan Quintela
authored and
Juan Quintela
committed
io: Add support for MSG_PEEK for socket channel
MSG_PEEK peeks at the channel, The data is treated as unread and the next read shall still return this data. This support is currently added only for socket class. Extra parameter 'flags' is added to io_readv calls to pass extra read flags like MSG_PEEK. Reviewed-by: Peter Xu <[email protected]> Reviewed-by: Daniel P. Berrange <[email protected]> Reviewed-by: Juan Quintela <[email protected]> Suggested-by: Daniel P. Berrange <[email protected]> Signed-off-by: manish.mishra <[email protected]> Signed-off-by: Juan Quintela <[email protected]>
1 parent bd9510d commit 84615a1

16 files changed

+50
-10
lines changed

chardev/char-socket.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,11 @@ static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len)
283283
if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
284284
ret = qio_channel_readv_full(s->ioc, &iov, 1,
285285
&msgfds, &msgfds_num,
286-
NULL);
286+
0, NULL);
287287
} else {
288288
ret = qio_channel_readv_full(s->ioc, &iov, 1,
289289
NULL, NULL,
290-
NULL);
290+
0, NULL);
291291
}
292292

293293
if (msgfds_num) {

include/io/channel.h

+6
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,16 @@ OBJECT_DECLARE_TYPE(QIOChannel, QIOChannelClass,
3434

3535
#define QIO_CHANNEL_WRITE_FLAG_ZERO_COPY 0x1
3636

37+
#define QIO_CHANNEL_READ_FLAG_MSG_PEEK 0x1
38+
3739
typedef enum QIOChannelFeature QIOChannelFeature;
3840

3941
enum QIOChannelFeature {
4042
QIO_CHANNEL_FEATURE_FD_PASS,
4143
QIO_CHANNEL_FEATURE_SHUTDOWN,
4244
QIO_CHANNEL_FEATURE_LISTEN,
4345
QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY,
46+
QIO_CHANNEL_FEATURE_READ_MSG_PEEK,
4447
};
4548

4649

@@ -114,6 +117,7 @@ struct QIOChannelClass {
114117
size_t niov,
115118
int **fds,
116119
size_t *nfds,
120+
int flags,
117121
Error **errp);
118122
int (*io_close)(QIOChannel *ioc,
119123
Error **errp);
@@ -188,6 +192,7 @@ void qio_channel_set_name(QIOChannel *ioc,
188192
* @niov: the length of the @iov array
189193
* @fds: pointer to an array that will received file handles
190194
* @nfds: pointer filled with number of elements in @fds on return
195+
* @flags: read flags (QIO_CHANNEL_READ_FLAG_*)
191196
* @errp: pointer to a NULL-initialized error object
192197
*
193198
* Read data from the IO channel, storing it in the
@@ -224,6 +229,7 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
224229
size_t niov,
225230
int **fds,
226231
size_t *nfds,
232+
int flags,
227233
Error **errp);
228234

229235

io/channel-buffer.c

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static ssize_t qio_channel_buffer_readv(QIOChannel *ioc,
5454
size_t niov,
5555
int **fds,
5656
size_t *nfds,
57+
int flags,
5758
Error **errp)
5859
{
5960
QIOChannelBuffer *bioc = QIO_CHANNEL_BUFFER(ioc);

io/channel-command.c

+1
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ static ssize_t qio_channel_command_readv(QIOChannel *ioc,
203203
size_t niov,
204204
int **fds,
205205
size_t *nfds,
206+
int flags,
206207
Error **errp)
207208
{
208209
QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);

io/channel-file.c

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ static ssize_t qio_channel_file_readv(QIOChannel *ioc,
8686
size_t niov,
8787
int **fds,
8888
size_t *nfds,
89+
int flags,
8990
Error **errp)
9091
{
9192
QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);

io/channel-null.c

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ qio_channel_null_readv(QIOChannel *ioc,
6060
size_t niov,
6161
int **fds G_GNUC_UNUSED,
6262
size_t *nfds G_GNUC_UNUSED,
63+
int flags,
6364
Error **errp)
6465
{
6566
QIOChannelNull *nioc = QIO_CHANNEL_NULL(ioc);

io/channel-socket.c

+18-1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ int qio_channel_socket_connect_sync(QIOChannelSocket *ioc,
173173
}
174174
#endif
175175

176+
qio_channel_set_feature(QIO_CHANNEL(ioc),
177+
QIO_CHANNEL_FEATURE_READ_MSG_PEEK);
178+
176179
return 0;
177180
}
178181

@@ -406,6 +409,9 @@ qio_channel_socket_accept(QIOChannelSocket *ioc,
406409
}
407410
#endif /* WIN32 */
408411

412+
qio_channel_set_feature(QIO_CHANNEL(cioc),
413+
QIO_CHANNEL_FEATURE_READ_MSG_PEEK);
414+
409415
trace_qio_channel_socket_accept_complete(ioc, cioc, cioc->fd);
410416
return cioc;
411417

@@ -496,6 +502,7 @@ static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
496502
size_t niov,
497503
int **fds,
498504
size_t *nfds,
505+
int flags,
499506
Error **errp)
500507
{
501508
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
@@ -517,6 +524,10 @@ static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
517524

518525
}
519526

527+
if (flags & QIO_CHANNEL_READ_FLAG_MSG_PEEK) {
528+
sflags |= MSG_PEEK;
529+
}
530+
520531
retry:
521532
ret = recvmsg(sioc->fd, &msg, sflags);
522533
if (ret < 0) {
@@ -624,19 +635,25 @@ static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
624635
size_t niov,
625636
int **fds,
626637
size_t *nfds,
638+
int flags,
627639
Error **errp)
628640
{
629641
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
630642
ssize_t done = 0;
631643
ssize_t i;
644+
int sflags = 0;
645+
646+
if (flags & QIO_CHANNEL_READ_FLAG_MSG_PEEK) {
647+
sflags |= MSG_PEEK;
648+
}
632649

633650
for (i = 0; i < niov; i++) {
634651
ssize_t ret;
635652
retry:
636653
ret = recv(sioc->fd,
637654
iov[i].iov_base,
638655
iov[i].iov_len,
639-
0);
656+
sflags);
640657
if (ret < 0) {
641658
if (errno == EAGAIN) {
642659
if (done) {

io/channel-tls.c

+1
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ static ssize_t qio_channel_tls_readv(QIOChannel *ioc,
260260
size_t niov,
261261
int **fds,
262262
size_t *nfds,
263+
int flags,
263264
Error **errp)
264265
{
265266
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc);

io/channel-websock.c

+1
Original file line numberDiff line numberDiff line change
@@ -1081,6 +1081,7 @@ static ssize_t qio_channel_websock_readv(QIOChannel *ioc,
10811081
size_t niov,
10821082
int **fds,
10831083
size_t *nfds,
1084+
int flags,
10841085
Error **errp)
10851086
{
10861087
QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);

io/channel.c

+12-4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
5252
size_t niov,
5353
int **fds,
5454
size_t *nfds,
55+
int flags,
5556
Error **errp)
5657
{
5758
QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
@@ -63,7 +64,14 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
6364
return -1;
6465
}
6566

66-
return klass->io_readv(ioc, iov, niov, fds, nfds, errp);
67+
if ((flags & QIO_CHANNEL_READ_FLAG_MSG_PEEK) &&
68+
!qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
69+
error_setg_errno(errp, EINVAL,
70+
"Channel does not support peek read");
71+
return -1;
72+
}
73+
74+
return klass->io_readv(ioc, iov, niov, fds, nfds, flags, errp);
6775
}
6876

6977

@@ -146,7 +154,7 @@ int qio_channel_readv_full_all_eof(QIOChannel *ioc,
146154
while ((nlocal_iov > 0) || local_fds) {
147155
ssize_t len;
148156
len = qio_channel_readv_full(ioc, local_iov, nlocal_iov, local_fds,
149-
local_nfds, errp);
157+
local_nfds, 0, errp);
150158
if (len == QIO_CHANNEL_ERR_BLOCK) {
151159
if (qemu_in_coroutine()) {
152160
qio_channel_yield(ioc, G_IO_IN);
@@ -284,7 +292,7 @@ ssize_t qio_channel_readv(QIOChannel *ioc,
284292
size_t niov,
285293
Error **errp)
286294
{
287-
return qio_channel_readv_full(ioc, iov, niov, NULL, NULL, errp);
295+
return qio_channel_readv_full(ioc, iov, niov, NULL, NULL, 0, errp);
288296
}
289297

290298

@@ -303,7 +311,7 @@ ssize_t qio_channel_read(QIOChannel *ioc,
303311
Error **errp)
304312
{
305313
struct iovec iov = { .iov_base = buf, .iov_len = buflen };
306-
return qio_channel_readv_full(ioc, &iov, 1, NULL, NULL, errp);
314+
return qio_channel_readv_full(ioc, &iov, 1, NULL, NULL, 0, errp);
307315
}
308316

309317

migration/channel-block.c

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ qio_channel_block_readv(QIOChannel *ioc,
5353
size_t niov,
5454
int **fds,
5555
size_t *nfds,
56+
int flags,
5657
Error **errp)
5758
{
5859
QIOChannelBlock *bioc = QIO_CHANNEL_BLOCK(ioc);

migration/rdma.c

+1
Original file line numberDiff line numberDiff line change
@@ -2857,6 +2857,7 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
28572857
size_t niov,
28582858
int **fds,
28592859
size_t *nfds,
2860+
int flags,
28602861
Error **errp)
28612862
{
28622863
QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);

scsi/qemu-pr-helper.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ static int coroutine_fn prh_read(PRHelperClient *client, void *buf, int sz,
614614
iov.iov_base = buf;
615615
iov.iov_len = sz;
616616
n_read = qio_channel_readv_full(QIO_CHANNEL(client->ioc), &iov, 1,
617-
&fds, &nfds, errp);
617+
&fds, &nfds, 0, errp);
618618

619619
if (n_read == QIO_CHANNEL_ERR_BLOCK) {
620620
qio_channel_yield(QIO_CHANNEL(client->ioc), G_IO_IN);

tests/qtest/tpm-emu.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ void *tpm_emu_ctrl_thread(void *data)
115115
int *pfd = NULL;
116116
size_t nfd = 0;
117117

118-
qio_channel_readv_full(ioc, &iov, 1, &pfd, &nfd, &error_abort);
118+
qio_channel_readv_full(ioc, &iov, 1, &pfd, &nfd, 0, &error_abort);
119119
cmd = be32_to_cpu(cmd);
120120
g_assert_cmpint(cmd, ==, CMD_SET_DATAFD);
121121
g_assert_cmpint(nfd, ==, 1);

tests/unit/test-io-channel-socket.c

+1
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ static void test_io_channel_unix_fd_pass(void)
460460
G_N_ELEMENTS(iorecv),
461461
&fdrecv,
462462
&nfdrecv,
463+
0,
463464
&error_abort);
464465

465466
g_assert(nfdrecv == G_N_ELEMENTS(fdsend));

util/vhost-user-server.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ vu_message_read(VuDev *vu_dev, int conn_fd, VhostUserMsg *vmsg)
116116
* qio_channel_readv_full may have short reads, keeping calling it
117117
* until getting VHOST_USER_HDR_SIZE or 0 bytes in total
118118
*/
119-
rc = qio_channel_readv_full(ioc, &iov, 1, &fds, &nfds, &local_err);
119+
rc = qio_channel_readv_full(ioc, &iov, 1, &fds, &nfds, 0, &local_err);
120120
if (rc < 0) {
121121
if (rc == QIO_CHANNEL_ERR_BLOCK) {
122122
assert(local_err == NULL);

0 commit comments

Comments
 (0)