[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