[sheepdog] [PATCH v1, RFC] sheep: writeback cache semantics in backend store

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Wed Aug 29 01:21:36 CEST 2012


At Wed, 29 Aug 2012 01:56:10 +0900,
Hitoshi Mitake wrote:
> 
> v1: differences from v0 are,
> * check syncfs() in configure script
> * send SD_OP_FLUSH_PEER to all sheeps

Please add a scissors line so that we can remove the change log from
the commit log easily.

>  
> +static int flush_all_node(struct request *req)
> +{
> +	int i, ret, err_ret, epfd, waiting, cnt;
> +	struct sd_node *s;
> +	struct node_id *node_sent[SD_MAX_NODES];
> +	struct sockfd *sfd, *sfd_sent[SD_MAX_NODES];
> +	struct sd_req hdr;
> +	struct vnode_info *vinfo = req->vinfo;
> +	struct epoll_event ev;
> +
> +	err_ret = SD_RES_SUCCESS;
> +
> +	epfd = epoll_create(SD_MAX_NODES);
> +	if (epfd == -1) {
> +		eprintf("failed to create epoll file descriptor");
> +		return SD_RES_EIO;
> +	}
> +
> +	sd_init_req(&hdr, SD_OP_FLUSH_PEER);
> +
> +	bzero(&ev, sizeof(struct epoll_event));
> +	ev.events = EPOLLIN;
> +
> +	for (waiting = 0, i = 0; i < vinfo->nr_nodes; i++) {
> +		unsigned int wlen = 0;
> +
> +		s = &vinfo->nodes[i];
> +
> +		if (node_is_local(s)) {
> +			_peer_flush();
> +			continue;
> +		}
> +
> +		sfd = sheep_get_sockfd(&s->nid);
> +		if (!sfd) {
> +			err_ret = SD_RES_NETWORK_ERROR;
> +			goto put_sockfd;
> +		}
> +
> +		node_sent[waiting] = &s->nid;
> +		sfd_sent[waiting] = sfd;
> +
> +		ret = send_req(sfd->fd, &hdr, NULL, &wlen);
> +		if (ret) {
> +			eprintf("failed at send_req()");
> +			sheep_del_sockfd(&s->nid, sfd);
> +			err_ret = SD_RES_NETWORK_ERROR;
> +			goto put_sockfd;
> +		}
> +
> +		ev.data.fd = sfd->fd;
> +		if (epoll_ctl(epfd, EPOLL_CTL_ADD, sfd->fd, &ev) == -1) {
> +			eprintf("failed at epoll_ctl(), errno: %s", strerror(errno));
> +			err_ret = SD_RES_EIO;
> +			goto put_sockfd;
> +		}
> +
> +		waiting++;
> +	}
> +
> +	cnt = waiting;
> +	while (cnt) {
> +		struct epoll_event ev_nodes[SD_MAX_NODES];
> +
> +		bzero(ev_nodes, sizeof(struct epoll_event) * cnt);
> +
> +		ret = epoll_wait(epfd, ev_nodes, cnt, -1);
> +		if (ret == -1) {
> +			eprintf("failed at epoll_wait(), errno: %s", strerror(errno));
> +			err_ret = SD_RES_EIO;
> +			break;
> +		}
> +
> +		cnt -= ret;
> +
> +		for (i = 0; i < ret; i++) {
> +			struct sd_rsp rsp;
> +
> +			if (do_read(ev_nodes[i].data.fd, &rsp, sizeof(struct sd_rsp))) {
> +				eprintf("failed to receive response from node");
> +				err_ret = SD_RES_NETWORK_ERROR;
> +				goto put_sockfd;
> +			}
> +		}
> +	}
> +
> +put_sockfd:
> +	for (i = 0; i < waiting; i++)
> +		sheep_put_sockfd(node_sent[i], sfd_sent[i]);
> +
> +	close(epfd);
> +
> +	return err_ret;
> +}
> +

This code looks like reimplementation of gateway_forward_request.  How
about making SD_OP_FLUSH_VDI a gateway operation, and modifying
gateway_forward_request so that it can forward request to all nodes?


> @@ -904,6 +1017,31 @@ out:
>  	return ret;
>  }
>  
> +int _peer_flush(void)
> +{
> +	int fd;
> +
> +	fd = open(obj_path, O_RDONLY);
> +	if (fd < 0) {
> +		eprintf("error at open() %s, %s\n", obj_path, strerror(errno));
> +		return SD_RES_NO_OBJ;
> +	}
> +
> +	if (syncfs(fd)) {
> +		eprintf("error at syncfs(), %s\n", strerror(errno));
> +		return SD_RES_EIO;
> +	}

Add a new interface sync to a storage driver and call it here because
how to flush data is up to the underlying strage driver.


> diff --git a/sheep/sheep.c b/sheep/sheep.c
> index 10c0501..77e8d7c 100644
> --- a/sheep/sheep.c
> +++ b/sheep/sheep.c
> @@ -52,10 +52,11 @@ static struct option const long_options[] = {
>  	{"enable-cache", required_argument, NULL, 'w'},
>  	{"zone", required_argument, NULL, 'z'},
>  	{"pidfile", required_argument, NULL, 'P'},
> +	{"writeback", no_argument, NULL, 'W'},
>  	{NULL, 0, NULL, 0},
>  };

Adding a 'writeback' option is a bit confusing.  Should we extend a
'-w' option so that we can specify types of caches we want to enable?

Thanks,

Kazutaka



More information about the sheepdog mailing list