[CRIU] Re: [PATCH 2/8] parasite: support sockets queues
Pavel Emelyanov
xemul at parallels.com
Tue Feb 28 06:36:36 EST 2012
> +static int dump_socket_queue(int img_fd, struct sk_queue_item *item, int *err)
> +{
> + struct sk_packet_entry *pe;
> + unsigned long size;
> + socklen_t tmp;
> + int ret, minus_one = -1;
> + int sock_fd = item->fd;
> +
> + /*
> + * Discover max DGRAM size
> + */
> + ret = sys_getsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &ret, &tmp);
NAK. The SO_RCVBUF is not used in unix sockets.
> + if (ret < 0) {
> + sys_write_msg("getsockopt failed\n");
> + *err = ret;
> + return PARASITE_ERR_FAIL;
> + }
> + /*
> + * Note: 32 bytes will be used by kernel for protocol header.
> + */
> + size = ret - 32;
> + /*
> + * Try to alloc buffer for max supported DGRAM + our header.
> + * Note: STREAM queue will be written by chunks of this size.
> + */
> + pe = brk_alloc(size + sizeof(struct sk_packet_entry));
> + if (!pe) {
> + sys_write_msg("not enough mem for skb\n");
> + *err = -ENOMEM;
> + return PARASITE_ERR_MMAP;
> + }
> + /*
> + * Enable peek offset incrementation.
> + */
> + ret = 0;
> + *err = sys_setsockopt(sock_fd, SOL_SOCKET, SO_PEEK_OFF, &ret, sizeof(int));
You should read the previous value first.
> + if (*err < 0) {
> + sys_write_msg("setsockopt fail\n");
> + ret = PARASITE_ERR_FAIL;
> + goto err_brk;
> + }
> +
> + pe->id_for = item->sk_id;
> +
> + while (1) {
> + struct iovec iov = {
> + .iov_base = pe->data,
> + .iov_len = size,
> + };
> + struct msghdr msg = {
> + .msg_name = NULL,
> + .msg_namelen = 0,
> + .msg_iov = &iov,
> + .msg_iovlen = 1,
> + .msg_control = NULL,
> + .msg_controllen = 0,
> + .msg_flags = 0,
> + };
> +
> + *err = pe->length = sys_recvmsg(sock_fd, &msg, MSG_DONTWAIT | MSG_PEEK);
> + if (*err < 0) {
> + if (*err == -EAGAIN)
> + break; /* we're done */
> + sys_write_msg("sys_recvmsg fail: error\n");
> + ret = PARASITE_ERR_FAIL;
> + goto err_set_sock;
> + }
> + if (msg.msg_flags & MSG_TRUNC) {
> + /*
> + * DGRAM thuncated. This should not happen. But we have
> + * to check...
> + */
> + sys_write_msg("sys_recvmsg failed: truncated\n");
> + *err = -E2BIG;
> + goto err_set_sock;
> + }
> + *err = sys_write(img_fd, pe, sizeof(pe) + pe->length);
> + if (*err != sizeof(pe) + pe->length) {
> + sys_write_msg("sys_write failed\n");
> + goto err_set_sock;
> + }
> + }
> + ret = 0;
> +err_set_sock:
> + sys_setsockopt(sock_fd, SOL_SOCKET, SO_PEEK_OFF, &minus_one, sizeof(int));
> +err_brk:
> + brk_free(size + sizeof(struct sk_packet_entry));
> + return ret;
> +}
More information about the CRIU
mailing list