Re: [Xen-devel] [PATCH RFC V2 7/7] COLO-Proxy: Use socket to get checkpoint event.
On 02/16/2017 12:24 AM, Konrad Rzeszutek Wilk wrote: On Wed, Feb 15, 2017 at 05:54:33PM +0800, Zhang Chen wrote: We use kernel colo proxy's way to get the checkpoint event from qemu colo-compare. Qemu colo-compare need add a API to support this(I will add this in qemu). Signed-off-by: Zhang Chen--- tools/libxl/libxl_colo.h | 2 + tools/libxl/libxl_colo_proxy.c | 84 +--- tools/libxl/libxl_colo_restore.c | 11 -- tools/libxl/libxl_colo_save.c| 22 +++ tools/libxl/libxl_nic.c | 4 ++ tools/libxl/libxl_types.idl | 4 +- tools/libxl/xl_cmdimpl.c | 4 ++ 7 files changed, 113 insertions(+), 18 deletions(-) diff --git a/tools/libxl/libxl_colo.h b/tools/libxl/libxl_colo.h index 4746d8c..6c01b55 100644 --- a/tools/libxl/libxl_colo.h +++ b/tools/libxl/libxl_colo.h @@ -69,6 +69,8 @@ struct libxl__colo_proxy_state { * False means use kernel colo proxy. */ bool is_userspace_proxy; +const char *checkpoint_host; +const char *checkpoint_port; }; struct libxl__colo_save_state { diff --git a/tools/libxl/libxl_colo_proxy.c b/tools/libxl/libxl_colo_proxy.c index dd902fc..9d21cf1 100644 --- a/tools/libxl/libxl_colo_proxy.c +++ b/tools/libxl/libxl_colo_proxy.c @@ -18,6 +18,9 @@ #include "libxl_internal.h" #include +#include +#include +#include /* Consistent with the new COLO netlink channel in kernel side */ #define NETLINK_COLO 28 @@ -76,6 +79,26 @@ static int colo_proxy_send(libxl__colo_proxy_state *cps, uint8_t *buff, return ret; } +static int colo_userspace_proxy_recv(libxl__colo_proxy_state *cps, + char *buff, + unsigned int timeout_us) +{ +struct timeval tv; +int ret; + +STATE_AO_GC(cps->ao); + +if (timeout_us) { +tv.tv_sec = timeout_us / 100; +tv.tv_usec = timeout_us % 100; +setsockopt(cps->sock_fd, SOL_SOCKET, SO_RCVTIMEO, , sizeof(tv)); +} + +ret = recv(cps->sock_fd, buff, sizeof(buff),0); + +return ret; +} + /* error: return -1, otherwise return 0 */ static int64_t colo_proxy_recv(libxl__colo_proxy_state *cps, uint8_t **buff, unsigned int timeout_us) @@ -153,8 +176,45 @@ int colo_proxy_setup(libxl__colo_proxy_state *cps) STATE_AO_GC(cps->ao); /* If enable userspace proxy mode, we don't need setup kernel proxy */ -if (cps->is_userspace_proxy) +if (cps->is_userspace_proxy) { +struct sockaddr_in addr; +int port; +char recvbuff[1024]; + +memset(, 0, sizeof(addr)); +port = atoi(cps->checkpoint_port); +addr.sin_family = AF_INET; +addr.sin_port = htons(port); +addr.sin_addr.s_addr = inet_addr(cps->checkpoint_host); + +skfd = socket(AF_INET, SOCK_STREAM, 0); +if (skfd < 0) { +LOGD(ERROR, ao->domid, "can not create a TCP socket: %s", + strerror(errno)); +goto out; +} + +cps->sock_fd = skfd; + +if (connect(skfd, (struct sockaddr *), sizeof(addr)) < 0) { +LOGD(ERROR, ao->domid, "connect error"); +goto out; +} + +char sendbuf[] = "COLO_USERSPACE_PROXY_INIT"; Um, could you move it right around 'char recvbuff' ? OK, I will move it in next version. +ret = send(skfd, sendbuf, strlen(sendbuf),0); +if (ret < 0) +goto out; + +ret = colo_userspace_proxy_recv(cps, recvbuff, 50); That 50 looks like a good candidate for a #define? I will add a macro "#define COLO_DEFAULT_WAIT_TIME 50". Thanks Zhang Chen +if (size < 0) { s/size/ret +LOGD(ERROR, ao->domid, "Can't recv msg from qemu colo-compare: %s", + strerror(errno)); +goto out; +} + return 0; +} skfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_COLO); if (skfd < 0) { @@ -247,8 +307,11 @@ void colo_proxy_preresume(libxl__colo_proxy_state *cps) * If enable userspace proxy mode, * we don't need preresume kernel proxy */ -if (cps->is_userspace_proxy) +if (cps->is_userspace_proxy) { +char sendbuf[] = "COLO_CHECKPOINT"; +send(cps->sock_fd, sendbuf, strlen(sendbuf),0); return; +} colo_proxy_send(cps, NULL, 0, COLO_CHECKPOINT); /* TODO: need to handle if the call fails... */ @@ -277,16 +340,25 @@ int colo_proxy_checkpoint(libxl__colo_proxy_state *cps, struct nlmsghdr *h; struct colo_msg *m; int ret = -1; +char recvbuff[1024]; STATE_AO_GC(cps->ao); /* - * enable userspace proxy mode, tmp sleep. - * then we will add qemu API support this func. + * enable userspace proxy mode. + * Then we will add qemu API support for this func. */ if
Re: [Xen-devel] [PATCH RFC V2 7/7] COLO-Proxy: Use socket to get checkpoint event.
On Wed, Feb 15, 2017 at 05:54:33PM +0800, Zhang Chen wrote: > We use kernel colo proxy's way to get the checkpoint event > from qemu colo-compare. > Qemu colo-compare need add a API to support this(I will add this in qemu). > > Signed-off-by: Zhang Chen> --- > tools/libxl/libxl_colo.h | 2 + > tools/libxl/libxl_colo_proxy.c | 84 > +--- > tools/libxl/libxl_colo_restore.c | 11 -- > tools/libxl/libxl_colo_save.c| 22 +++ > tools/libxl/libxl_nic.c | 4 ++ > tools/libxl/libxl_types.idl | 4 +- > tools/libxl/xl_cmdimpl.c | 4 ++ > 7 files changed, 113 insertions(+), 18 deletions(-) > > diff --git a/tools/libxl/libxl_colo.h b/tools/libxl/libxl_colo.h > index 4746d8c..6c01b55 100644 > --- a/tools/libxl/libxl_colo.h > +++ b/tools/libxl/libxl_colo.h > @@ -69,6 +69,8 @@ struct libxl__colo_proxy_state { > * False means use kernel colo proxy. > */ > bool is_userspace_proxy; > +const char *checkpoint_host; > +const char *checkpoint_port; > }; > > struct libxl__colo_save_state { > diff --git a/tools/libxl/libxl_colo_proxy.c b/tools/libxl/libxl_colo_proxy.c > index dd902fc..9d21cf1 100644 > --- a/tools/libxl/libxl_colo_proxy.c > +++ b/tools/libxl/libxl_colo_proxy.c > @@ -18,6 +18,9 @@ > #include "libxl_internal.h" > > #include > +#include > +#include > +#include > > /* Consistent with the new COLO netlink channel in kernel side */ > #define NETLINK_COLO 28 > @@ -76,6 +79,26 @@ static int colo_proxy_send(libxl__colo_proxy_state *cps, > uint8_t *buff, > return ret; > } > > +static int colo_userspace_proxy_recv(libxl__colo_proxy_state *cps, > + char *buff, > + unsigned int timeout_us) > +{ > +struct timeval tv; > +int ret; > + > +STATE_AO_GC(cps->ao); > + > +if (timeout_us) { > +tv.tv_sec = timeout_us / 100; > +tv.tv_usec = timeout_us % 100; > +setsockopt(cps->sock_fd, SOL_SOCKET, SO_RCVTIMEO, , sizeof(tv)); > +} > + > +ret = recv(cps->sock_fd, buff, sizeof(buff),0); > + > +return ret; > +} > + > /* error: return -1, otherwise return 0 */ > static int64_t colo_proxy_recv(libxl__colo_proxy_state *cps, uint8_t **buff, > unsigned int timeout_us) > @@ -153,8 +176,45 @@ int colo_proxy_setup(libxl__colo_proxy_state *cps) > STATE_AO_GC(cps->ao); > > /* If enable userspace proxy mode, we don't need setup kernel proxy */ > -if (cps->is_userspace_proxy) > +if (cps->is_userspace_proxy) { > +struct sockaddr_in addr; > +int port; > +char recvbuff[1024]; > + > +memset(, 0, sizeof(addr)); > +port = atoi(cps->checkpoint_port); > +addr.sin_family = AF_INET; > +addr.sin_port = htons(port); > +addr.sin_addr.s_addr = inet_addr(cps->checkpoint_host); > + > +skfd = socket(AF_INET, SOCK_STREAM, 0); > +if (skfd < 0) { > +LOGD(ERROR, ao->domid, "can not create a TCP socket: %s", > + strerror(errno)); > +goto out; > +} > + > +cps->sock_fd = skfd; > + > +if (connect(skfd, (struct sockaddr *), sizeof(addr)) < 0) { > +LOGD(ERROR, ao->domid, "connect error"); > +goto out; > +} > + > +char sendbuf[] = "COLO_USERSPACE_PROXY_INIT"; Um, could you move it right around 'char recvbuff' ? > +ret = send(skfd, sendbuf, strlen(sendbuf),0); > +if (ret < 0) > +goto out; > + > +ret = colo_userspace_proxy_recv(cps, recvbuff, 50); That 50 looks like a good candidate for a #define? > +if (size < 0) { > +LOGD(ERROR, ao->domid, "Can't recv msg from qemu colo-compare: > %s", > + strerror(errno)); > +goto out; > +} > + > return 0; > +} > > skfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_COLO); > if (skfd < 0) { > @@ -247,8 +307,11 @@ void colo_proxy_preresume(libxl__colo_proxy_state *cps) > * If enable userspace proxy mode, > * we don't need preresume kernel proxy > */ > -if (cps->is_userspace_proxy) > +if (cps->is_userspace_proxy) { > +char sendbuf[] = "COLO_CHECKPOINT"; > +send(cps->sock_fd, sendbuf, strlen(sendbuf),0); > return; > +} > > colo_proxy_send(cps, NULL, 0, COLO_CHECKPOINT); > /* TODO: need to handle if the call fails... */ > @@ -277,16 +340,25 @@ int colo_proxy_checkpoint(libxl__colo_proxy_state *cps, > struct nlmsghdr *h; > struct colo_msg *m; > int ret = -1; > +char recvbuff[1024]; > > STATE_AO_GC(cps->ao); > > /* > - * enable userspace proxy mode, tmp sleep. > - * then we will add qemu API support this func. > + * enable userspace proxy mode. > + * Then we will add qemu API
[Xen-devel] [PATCH RFC V2 7/7] COLO-Proxy: Use socket to get checkpoint event.
We use kernel colo proxy's way to get the checkpoint event from qemu colo-compare. Qemu colo-compare need add a API to support this(I will add this in qemu). Signed-off-by: Zhang Chen--- tools/libxl/libxl_colo.h | 2 + tools/libxl/libxl_colo_proxy.c | 84 +--- tools/libxl/libxl_colo_restore.c | 11 -- tools/libxl/libxl_colo_save.c| 22 +++ tools/libxl/libxl_nic.c | 4 ++ tools/libxl/libxl_types.idl | 4 +- tools/libxl/xl_cmdimpl.c | 4 ++ 7 files changed, 113 insertions(+), 18 deletions(-) diff --git a/tools/libxl/libxl_colo.h b/tools/libxl/libxl_colo.h index 4746d8c..6c01b55 100644 --- a/tools/libxl/libxl_colo.h +++ b/tools/libxl/libxl_colo.h @@ -69,6 +69,8 @@ struct libxl__colo_proxy_state { * False means use kernel colo proxy. */ bool is_userspace_proxy; +const char *checkpoint_host; +const char *checkpoint_port; }; struct libxl__colo_save_state { diff --git a/tools/libxl/libxl_colo_proxy.c b/tools/libxl/libxl_colo_proxy.c index dd902fc..9d21cf1 100644 --- a/tools/libxl/libxl_colo_proxy.c +++ b/tools/libxl/libxl_colo_proxy.c @@ -18,6 +18,9 @@ #include "libxl_internal.h" #include +#include +#include +#include /* Consistent with the new COLO netlink channel in kernel side */ #define NETLINK_COLO 28 @@ -76,6 +79,26 @@ static int colo_proxy_send(libxl__colo_proxy_state *cps, uint8_t *buff, return ret; } +static int colo_userspace_proxy_recv(libxl__colo_proxy_state *cps, + char *buff, + unsigned int timeout_us) +{ +struct timeval tv; +int ret; + +STATE_AO_GC(cps->ao); + +if (timeout_us) { +tv.tv_sec = timeout_us / 100; +tv.tv_usec = timeout_us % 100; +setsockopt(cps->sock_fd, SOL_SOCKET, SO_RCVTIMEO, , sizeof(tv)); +} + +ret = recv(cps->sock_fd, buff, sizeof(buff),0); + +return ret; +} + /* error: return -1, otherwise return 0 */ static int64_t colo_proxy_recv(libxl__colo_proxy_state *cps, uint8_t **buff, unsigned int timeout_us) @@ -153,8 +176,45 @@ int colo_proxy_setup(libxl__colo_proxy_state *cps) STATE_AO_GC(cps->ao); /* If enable userspace proxy mode, we don't need setup kernel proxy */ -if (cps->is_userspace_proxy) +if (cps->is_userspace_proxy) { +struct sockaddr_in addr; +int port; +char recvbuff[1024]; + +memset(, 0, sizeof(addr)); +port = atoi(cps->checkpoint_port); +addr.sin_family = AF_INET; +addr.sin_port = htons(port); +addr.sin_addr.s_addr = inet_addr(cps->checkpoint_host); + +skfd = socket(AF_INET, SOCK_STREAM, 0); +if (skfd < 0) { +LOGD(ERROR, ao->domid, "can not create a TCP socket: %s", + strerror(errno)); +goto out; +} + +cps->sock_fd = skfd; + +if (connect(skfd, (struct sockaddr *), sizeof(addr)) < 0) { +LOGD(ERROR, ao->domid, "connect error"); +goto out; +} + +char sendbuf[] = "COLO_USERSPACE_PROXY_INIT"; +ret = send(skfd, sendbuf, strlen(sendbuf),0); +if (ret < 0) +goto out; + +ret = colo_userspace_proxy_recv(cps, recvbuff, 50); +if (size < 0) { +LOGD(ERROR, ao->domid, "Can't recv msg from qemu colo-compare: %s", + strerror(errno)); +goto out; +} + return 0; +} skfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_COLO); if (skfd < 0) { @@ -247,8 +307,11 @@ void colo_proxy_preresume(libxl__colo_proxy_state *cps) * If enable userspace proxy mode, * we don't need preresume kernel proxy */ -if (cps->is_userspace_proxy) +if (cps->is_userspace_proxy) { +char sendbuf[] = "COLO_CHECKPOINT"; +send(cps->sock_fd, sendbuf, strlen(sendbuf),0); return; +} colo_proxy_send(cps, NULL, 0, COLO_CHECKPOINT); /* TODO: need to handle if the call fails... */ @@ -277,16 +340,25 @@ int colo_proxy_checkpoint(libxl__colo_proxy_state *cps, struct nlmsghdr *h; struct colo_msg *m; int ret = -1; +char recvbuff[1024]; STATE_AO_GC(cps->ao); /* - * enable userspace proxy mode, tmp sleep. - * then we will add qemu API support this func. + * enable userspace proxy mode. + * Then we will add qemu API support for this func. */ if (cps->is_userspace_proxy) { -sleep(timeout_us / 100); -return 0; +ret = colo_userspace_proxy_recv(cps, recvbuff, timeout_us); +if (ret <= 0) +return 0; + +if (!strcmp(recvbuff, "DO_CHECKPOINT")) { +return 1; +} else { +LOGD(ERROR, ao->domid, "receive qemu colo-compare checkpoint error"); +return -1; +} }