Home » Mailing lists » Devel » [PATCH] cryo: Improve socket support: add UDP and IPv6
[PATCH] cryo: Improve socket support: add UDP and IPv6 [message #31056] |
Mon, 16 June 2008 15:38  |
Benjamin Thery
Messages: 79 Registered: March 2007
|
Member |
|
|
Today, I played a bit with inet sockets and cryo. With few modifications
I managed to "checkpoint-restart" programs that use UDP sockets to listen
and send data.
This patch improves socket checkpointing in cryo:
* Save/restore socket family: we can checkpoint IPv6 sockets now.
* Save/restore socket type: we can checkpoint UDP sockets too.
Simple test programs for UDP sockets available upon request :)
Regards,
Benjamin
Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
---
cr.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 50 insertions(+), 13 deletions(-)
Index: cryodev/cr.c
===================================================================
--- cryodev.orig/cr.c
+++ cryodev/cr.c
@@ -67,11 +67,15 @@ int pagesize = 0;
typedef struct isockinfo_t {
int fdnum;
- int type; /* socket type: UDP, TCP */
+ int type; /* socket type: SOCK_STREAM, SOCK_DGRAM */
+ int family; /* socket family: AF_INET, AF_INET6 */
int mode; /* bind, listen, connect */
int opt; /* various sockopt */
int backlog; /* for listen(2) */
- struct sockaddr_in locaddr; /* for bind(2) */
+ union {
+ struct sockaddr_in saddr4;
+ struct sockaddr_in6 saddr6;
+ } locaddr; /* for bind(2) */
char tcpstate[TPI_LEN];
} isockinfo_t;
@@ -179,7 +183,7 @@ int getmaps(pid_t pid, memseg_t **p)
int getsockinfo(pid_t pid, pinfo_t *pi, int num)
{
- struct sockaddr name;
+ struct sockaddr_storage name;
int namelen = (int)sizeof(name), ret = 0;
int tpi_len = TPI_LEN;
int flag, flaglen;
@@ -188,9 +192,11 @@ int getsockinfo(pid_t pid, pinfo_t *pi,
/* get socketname and see if it is an unix or an inet socket */
memset(&name, 0, sizeof(name));
PT_GETSOCKNAME(pid, num, &name, &namelen);
- t_d(name.sa_family);
+ t_d(name.ss_family);
- if (name.sa_family != (sa_family_t)AF_INET) return ret;
+ if (name.ss_family != (sa_family_t)AF_INET &&
+ name.ss_family != (sa_family_t)AF_INET6)
+ return ret;
if (! (pi->si = (isockinfo_t *)realloc(pi->si, sizeof(isockinfo_t) * (pi->ns+1)))) return -1;
psi = &pi->si[pi->ns];
@@ -198,11 +204,25 @@ int getsockinfo(pid_t pid, pinfo_t *pi,
//pi->si[pi->ns].fdnum = num;
psi->fdnum = num;
+ psi->family = name.ss_family;
psi->mode = ISOCK_UNKNOWN;
- memcpy((void *)&psi->locaddr, (void *)&name, sizeof(name));
- if (psi->locaddr.sin_addr.s_addr != 0 || psi->locaddr.sin_port != 0) psi->mode |= ISOCK_BIND;
-
+ memcpy((void *)&psi->locaddr, (void *)&name, namelen);
+
+ if ((psi->family == AF_INET &&
+ (psi->locaddr.saddr4.sin_addr.s_addr != INADDR_ANY ||
+ psi->locaddr.saddr4.sin_port != 0)) ||
+ (psi->family == AF_INET6 &&
+ (memcmp(&psi->locaddr.saddr6.sin6_addr, &in6addr_any, 16) != 0 ||
+ psi->locaddr.saddr6.sin6_port != 0)))
+ psi->mode |= ISOCK_BIND;
+
+ flag = 0;
+ flaglen = (int)sizeof(flag);
+ PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_TYPE, &flag, &flaglen);
+ if (flag)
+ psi->type = flag;
+
flag = 0;
flaglen = (int)sizeof(flag);
PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_REUSEADDR, &flag, &flaglen);
@@ -866,6 +886,7 @@ int restore_sock(int fd, pid_t pid)
int sock;
size_t bufsz;
isockinfo_t *isockinfo = NULL;
+ int len;
for (;;) {
read_item(fd, item, sizeof(item), &buf, &bufsz);
@@ -873,20 +894,36 @@ int restore_sock(int fd, pid_t pid)
else ITEM_SET(isockinfo, isockinfo_t);
else break; // unknown item
- t_d(sock = PT_SOCKET(pid, AF_INET, SOCK_STREAM, 0));
+ t_d(sock = PT_SOCKET(pid, isockinfo->family, isockinfo->type, 0));
if (sock < 0) {
ERROR("PT_SOCKET(%d, %d, %d, %d) errno=%d: %s",
- pid, AF_INET, SOCK_STREAM, 0, sock, strerror(-sock));
+ pid, isockinfo->family, isockinfo->type, 0,
+ sock, strerror(-sock));
}
t_d(PT_DUP2(pid, sock, isockinfo->fdnum));
if (sock != isockinfo->fdnum) t_d(PT_CLOSE(pid, sock));
if (isockinfo->mode & ISOCK_BIND) {
+ struct sockaddr *sa;
struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
- memcpy((void *)&sin, (void *)&isockinfo->locaddr, sizeof(sin));
- if (isockinfo->mode & ISOCK_CONNECT) sin.sin_port = htons(0);
- t_d(PT_BIND(pid, isockinfo->fdnum, &sin, sizeof(sin)));
+ if (isockinfo->family == AF_INET) {
+ len = sizeof(sin);
+ memcpy((void *)&sin,
+ (void *)&isockinfo->locaddr.saddr4, len);
+ if (isockinfo->mode & ISOCK_CONNECT)
+ sin6.sin6_port = htons(0);
+ sa = (struct sockaddr *) &sin;
+ } else {
+ len = sizeof(sin6);
+ memcpy((void *)&sin6,
+ (void *)&isockinfo->locaddr.saddr6, len);
+ if (isockinfo->mode & ISOCK_CONNECT)
+ sin.sin_port = htons(0);
+ sa = (struct sockaddr *) &sin6;
+ }
+ t_d(PT_BIND(pid, isockinfo->fdnum, sa, len));
}
if (isockinfo->mode & ISOCK_LISTEN) {
t_d(PT_LISTEN(pid, isockinfo->fdnum, 64)); //FIXME: get backlog from TPI_INFO
--
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
|
|
|
Re: [PATCH] cryo: Improve socket support: add UDP and IPv6 [message #31057 is a reply to message #31056] |
Mon, 16 June 2008 16:22   |
Dave Hansen
Messages: 240 Registered: October 2005
|
Senior Member |
|
|
On Mon, 2008-06-16 at 17:38 +0200, Benjamin Thery wrote:
> Today, I played a bit with inet sockets and cryo. With few modifications
> I managed to "checkpoint-restart" programs that use UDP sockets to listen
> and send data.
>
> This patch improves socket checkpointing in cryo:
> * Save/restore socket family: we can checkpoint IPv6 sockets now.
> * Save/restore socket type: we can checkpoint UDP sockets too.
>
> Simple test programs for UDP sockets available upon request :)
>
> Regards,
> Benjamin
>
> Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
> ---
> cr.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------
> 1 file changed, 50 insertions(+), 13 deletions(-)
>
> Index: cryodev/cr.c
> ===================================================================
> --- cryodev.orig/cr.c
> +++ cryodev/cr.c
> @@ -67,11 +67,15 @@ int pagesize = 0;
>
> typedef struct isockinfo_t {
> int fdnum;
> - int type; /* socket type: UDP, TCP */
> + int type; /* socket type: SOCK_STREAM, SOCK_DGRAM */
> + int family; /* socket family: AF_INET, AF_INET6 */
> int mode; /* bind, listen, connect */
> int opt; /* various sockopt */
> int backlog; /* for listen(2) */
> - struct sockaddr_in locaddr; /* for bind(2) */
> + union {
> + struct sockaddr_in saddr4;
> + struct sockaddr_in6 saddr6;
> + } locaddr; /* for bind(2) */
> char tcpstate[TPI_LEN];
> } isockinfo_t;
>
> @@ -179,7 +183,7 @@ int getmaps(pid_t pid, memseg_t **p)
>
> int getsockinfo(pid_t pid, pinfo_t *pi, int num)
> {
> - struct sockaddr name;
> + struct sockaddr_storage name;
> int namelen = (int)sizeof(name), ret = 0;
> int tpi_len = TPI_LEN;
> int flag, flaglen;
> @@ -188,9 +192,11 @@ int getsockinfo(pid_t pid, pinfo_t *pi,
> /* get socketname and see if it is an unix or an inet socket */
> memset(&name, 0, sizeof(name));
> PT_GETSOCKNAME(pid, num, &name, &namelen);
> - t_d(name.sa_family);
> + t_d(name.ss_family);
>
> - if (name.sa_family != (sa_family_t)AF_INET) return ret;
> + if (name.ss_family != (sa_family_t)AF_INET &&
> + name.ss_family != (sa_family_t)AF_INET6)
> + return ret;
>
> if (! (pi->si = (isockinfo_t *)realloc(pi->si, sizeof(isockinfo_t) * (pi->ns+1)))) return -1;
> psi = &pi->si[pi->ns];
> @@ -198,11 +204,25 @@ int getsockinfo(pid_t pid, pinfo_t *pi,
>
> //pi->si[pi->ns].fdnum = num;
> psi->fdnum = num;
> + psi->family = name.ss_family;
>
> psi->mode = ISOCK_UNKNOWN;
> - memcpy((void *)&psi->locaddr, (void *)&name, sizeof(name));
> - if (psi->locaddr.sin_addr.s_addr != 0 || psi->locaddr.sin_port != 0) psi->mode |= ISOCK_BIND;
> -
> + memcpy((void *)&psi->locaddr, (void *)&name, namelen);
> +
> + if ((psi->family == AF_INET &&
> + (psi->locaddr.saddr4.sin_addr.s_addr != INADDR_ANY ||
> + psi->locaddr.saddr4.sin_port != 0)) ||
> + (psi->family == AF_INET6 &&
> + (memcmp(&psi->locaddr.saddr6.sin6_addr, &in6addr_any, 16) != 0 ||
> + psi->locaddr.saddr6.sin6_port != 0)))
> + psi->mode |= ISOCK_BIND;
Could you put this into a little helper? It is getting a little
convoluted.
> + flag = 0;
> + flaglen = (int)sizeof(flag);
> + PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_TYPE, &flag, &flaglen);
> + if (flag)
> + psi->type = flag;
> +
> flag = 0;
> flaglen = (int)sizeof(flag);
Why are you casting this?
> PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_REUSEADDR, &flag, &flaglen);
> @@ -866,6 +886,7 @@ int restore_sock(int fd, pid_t pid)
> int sock;
> size_t bufsz;
> isockinfo_t *isockinfo = NULL;
> + int len;
>
> for (;;) {
> read_item(fd, item, sizeof(item), &buf, &bufsz);
> @@ -873,20 +894,36 @@ int restore_sock(int fd, pid_t pid)
> else ITEM_SET(isockinfo, isockinfo_t);
> else break; // unknown item
>
> - t_d(sock = PT_SOCKET(pid, AF_INET, SOCK_STREAM, 0));
> + t_d(sock = PT_SOCKET(pid, isockinfo->family, isockinfo->type, 0));
> if (sock < 0) {
> ERROR("PT_SOCKET(%d, %d, %d, %d) errno=%d: %s",
> - pid, AF_INET, SOCK_STREAM, 0, sock, strerror(-sock));
> + pid, isockinfo->family, isockinfo->type, 0,
> + sock, strerror(-sock));
> }
> t_d(PT_DUP2(pid, sock, isockinfo->fdnum));
> if (sock != isockinfo->fdnum) t_d(PT_CLOSE(pid, sock));
>
> if (isockinfo->mode & ISOCK_BIND) {
> + struct sockaddr *sa;
> struct sockaddr_in sin;
> + struct sockaddr_in6 sin6;
>
> - memcpy((void *)&sin, (void *)&isockinfo->locaddr, sizeof(sin));
> - if (isockinfo->mode & ISOCK_CONNECT) sin.sin_port = htons(0);
> - t_d(PT_BIND(pid, isockinfo->fdnum, &sin, sizeof(sin)));
> + if (isockinfo->family == AF_INET) {
> + len = sizeof(sin);
> + memcpy((void *)&sin,
> + (void *)&isockinfo->locaddr.saddr4, len);
I see that these casts were there already, but could we kill them since
you're touching it now?
> + if (isockinfo->mode & ISOCK_CONNECT)
> + sin6.sin6_port = htons(0);
> + sa = (struct sockaddr *) &sin;
> + } else {
How about an explicit check for AF_INET6 here?
> + len = sizeof(sin6);
> + memcpy((void *)&sin6,
> + (void *)&isockinfo->locaddr.saddr6, len);
> + if (isockinfo->mode & ISOCK_CONNECT)
> + sin.sin_port = htons(0);
> + sa = (struct sockaddr *) &sin6;
> + }
> + t_d(PT_BIND(pid, isockinfo->fdnum, sa, len));
-- Dave
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
|
|
|
Re: [PATCH] cryo: Improve socket support: add UDP and IPv6 [message #31058 is a reply to message #31057] |
Mon, 16 June 2008 18:22  |
Benjamin Thery
Messages: 79 Registered: March 2007
|
Member |
|
|
Dave Hansen <dave@linux.vnet.ibm.com> a écrit :
> On Mon, 2008-06-16 at 17:38 +0200, Benjamin Thery wrote:
>> Today, I played a bit with inet sockets and cryo. With few modifications
>> I managed to "checkpoint-restart" programs that use UDP sockets to listen
>> and send data.
>>
>> This patch improves socket checkpointing in cryo:
>> * Save/restore socket family: we can checkpoint IPv6 sockets now.
>> * Save/restore socket type: we can checkpoint UDP sockets too.
>>
>> Simple test programs for UDP sockets available upon request :)
>>
>> Regards,
>> Benjamin
>>
>> Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
>> ---
>> cr.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------
>> 1 file changed, 50 insertions(+), 13 deletions(-)
>>
>> Index: cryodev/cr.c
>> ===================================================================
>> --- cryodev.orig/cr.c
>> +++ cryodev/cr.c
>> @@ -67,11 +67,15 @@ int pagesize = 0;
>>
>> typedef struct isockinfo_t {
>> int fdnum;
>> - int type; /* socket type: UDP, TCP */
>> + int type; /* socket type: SOCK_STREAM, SOCK_DGRAM */
>> + int family; /* socket family: AF_INET, AF_INET6 */
>> int mode; /* bind, listen, connect */
>> int opt; /* various sockopt */
>> int backlog; /* for listen(2) */
>> - struct sockaddr_in locaddr; /* for bind(2) */
>> + union {
>> + struct sockaddr_in saddr4;
>> + struct sockaddr_in6 saddr6;
>> + } locaddr; /* for bind(2) */
>> char tcpstate[TPI_LEN];
>> } isockinfo_t;
>>
>> @@ -179,7 +183,7 @@ int getmaps(pid_t pid, memseg_t **p)
>>
>> int getsockinfo(pid_t pid, pinfo_t *pi, int num)
>> {
>> - struct sockaddr name;
>> + struct sockaddr_storage name;
>> int namelen = (int)sizeof(name), ret = 0;
>> int tpi_len = TPI_LEN;
>> int flag, flaglen;
>> @@ -188,9 +192,11 @@ int getsockinfo(pid_t pid, pinfo_t *pi,
>> /* get socketname and see if it is an unix or an inet socket */
>> memset(&name, 0, sizeof(name));
>> PT_GETSOCKNAME(pid, num, &name, &namelen);
>> - t_d(name.sa_family);
>> + t_d(name.ss_family);
>>
>> - if (name.sa_family != (sa_family_t)AF_INET) return ret;
>> + if (name.ss_family != (sa_family_t)AF_INET &&
>> + name.ss_family != (sa_family_t)AF_INET6)
>> + return ret;
>>
>> if (! (pi->si = (isockinfo_t *)realloc(pi->si,
>> sizeof(isockinfo_t) * (pi->ns+1)))) return -1;
>> psi = &pi->si[pi->ns];
>> @@ -198,11 +204,25 @@ int getsockinfo(pid_t pid, pinfo_t *pi,
>>
>> //pi->si[pi->ns].fdnum = num;
>> psi->fdnum = num;
>> + psi->family = name.ss_family;
>>
>> psi->mode = ISOCK_UNKNOWN;
>> - memcpy((void *)&psi->locaddr, (void *)&name, sizeof(name));
>> - if (psi->locaddr.sin_addr.s_addr != 0 || psi->locaddr.sin_port !=
>> 0) psi->mode |= ISOCK_BIND;
>> -
>> + memcpy((void *)&psi->locaddr, (void *)&name, namelen);
>> +
>> + if ((psi->family == AF_INET &&
>> + (psi->locaddr.saddr4.sin_addr.s_addr != INADDR_ANY ||
>> + psi->locaddr.saddr4.sin_port != 0)) ||
>> + (psi->family == AF_INET6 &&
>> + (memcmp(&psi->locaddr.saddr6.sin6_addr, &in6addr_any, 16) != 0 ||
>> + psi->locaddr.saddr6.sin6_port != 0)))
>> + psi->mode |= ISOCK_BIND;
>
> Could you put this into a little helper? It is getting a little
> convoluted.
Yes, sure I can do that.
>> + flag = 0;
>> + flaglen = (int)sizeof(flag);
>> + PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_TYPE, &flag, &flaglen);
>> + if (flag)
>> + psi->type = flag;
>> +
>> flag = 0;
>> flaglen = (int)sizeof(flag);
>
> Why are you casting this?
Um... it was there already. I dumbly copied the code. :)
>
>> PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_REUSEADDR, &flag, &flaglen);
>> @@ -866,6 +886,7 @@ int restore_sock(int fd, pid_t pid)
>> int sock;
>> size_t bufsz;
>> isockinfo_t *isockinfo = NULL;
>> + int len;
>>
>> for (;;) {
>> read_item(fd, item, sizeof(item), &buf, &bufsz);
>> @@ -873,20 +894,36 @@ int restore_sock(int fd, pid_t pid)
>> else ITEM_SET(isockinfo, isockinfo_t);
>> else break; // unknown item
>>
>> - t_d(sock = PT_SOCKET(pid, AF_INET, SOCK_STREAM, 0));
>> + t_d(sock = PT_SOCKET(pid, isockinfo->family, isockinfo->type, 0));
>> if (sock < 0) {
>> ERROR("PT_SOCKET(%d, %d, %d, %d) errno=%d: %s",
>> - pid, AF_INET, SOCK_STREAM, 0, sock, strerror(-sock));
>> + pid, isockinfo->family, isockinfo->type, 0,
>> + sock, strerror(-sock));
>> }
>> t_d(PT_DUP2(pid, sock, isockinfo->fdnum));
>> if (sock != isockinfo->fdnum) t_d(PT_CLOSE(pid, sock));
>>
>> if (isockinfo->mode & ISOCK_BIND) {
>> + struct sockaddr *sa;
>> struct sockaddr_in sin;
>> + struct sockaddr_in6 sin6;
>>
>> - memcpy((void *)&sin, (void *)&isockinfo->locaddr, sizeof(sin));
>> - if (isockinfo->mode & ISOCK_CONNECT) sin.sin_port = htons(0);
>> - t_d(PT_BIND(pid, isockinfo->fdnum, &sin, sizeof(sin)));
>> + if (isockinfo->family == AF_INET) {
>> + len = sizeof(sin);
>> + memcpy((void *)&sin,
>> + (void *)&isockinfo->locaddr.saddr4, len);
>
> I see that these casts were there already, but could we kill them since
> you're touching it now?
Sure.
>> + if (isockinfo->mode & ISOCK_CONNECT)
>> + sin6.sin6_port = htons(0);
>> + sa = (struct sockaddr *) &sin;
>> + } else {
>
> How about an explicit check for AF_INET6 here?
It isn't necessary as we're in restart and we only checkpointed the
family we know about.
But I agree with you, it is misleading. I'll add an explicit check.
Thanks for the review.
-Benjamin
>
>> + len = sizeof(sin6);
>> + memcpy((void *)&sin6,
>> + (void *)&isockinfo->locaddr.saddr6, len);
>> + if (isockinfo->mode & ISOCK_CONNECT)
>> + sin.sin_port = htons(0);
>> + sa = (struct sockaddr *) &sin6;
>> + }
>> + t_d(PT_BIND(pid, isockinfo->fdnum, sa, len));
>
> -- Dave
>
>
>
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
|
|
|
Goto Forum:
Current Time: Mon Aug 04 04:39:42 GMT 2025
Total time taken to generate the page: 0.87521 seconds
|