qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project
@ 2019-02-08 18:11 marcandre.lureau
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 1/5] Extract slirp/ from qemu repository marcandre.lureau
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: marcandre.lureau @ 2019-02-08 18:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: samuel.thibault, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Hi,

As discussed earlier in "[PATCH for-3.2 00/41] RFC: slirp: make it
again a standalone project" and other threads, it would be useful to
make slirp a separate project (the submodule approach was discarded)
for various projects to share.

The first patch describes how to filter the qemu repository for the
slirp/ content, and initial layout.

The following patches add meson build system (if necessary for older
distros, autotools could be added - however I believe python & ninja
are generally available on the QEMU supported platforms)

Finally, to be able to provide migration handling (currently handled
by QEMU), I ported a subset of the QEMU state saving/loading code in
"slirp: add state saving/loading" and added some slirp API.

Where should this new project be hosted? (I suggest some gitlab
instance, because of the nice ui/CI/issues/milestone...)

thanks

Marc-André Lureau (5):
  Extract slirp/ from qemu repository
  build-sys: add a meson build
  build-sys: add version tooling
  slirp: add state saving/loading
  Add .gitlab-ci.yml

 .gitlab-ci.yml                   |  20 ++
 Makefile.objs                    |  34 ---
 meson.build                      | 127 ++++++++++
 arp_table.c => src/arp_table.c   |   0
 bootp.c => src/bootp.c           |   0
 bootp.h => src/bootp.h           |   0
 cksum.c => src/cksum.c           |   0
 debug.h => src/debug.h           |   0
 dhcpv6.c => src/dhcpv6.c         |   0
 dhcpv6.h => src/dhcpv6.h         |   0
 dnssearch.c => src/dnssearch.c   |   0
 if.c => src/if.c                 |   0
 if.h => src/if.h                 |   0
 ip.h => src/ip.h                 |   0
 ip6.h => src/ip6.h               |   0
 ip6_icmp.c => src/ip6_icmp.c     |   0
 ip6_icmp.h => src/ip6_icmp.h     |   0
 ip6_input.c => src/ip6_input.c   |   0
 ip6_output.c => src/ip6_output.c |   0
 ip_icmp.c => src/ip_icmp.c       |   0
 ip_icmp.h => src/ip_icmp.h       |   0
 ip_input.c => src/ip_input.c     |   0
 ip_output.c => src/ip_output.c   |   0
 src/libslirp-version.h.in        |  22 ++
 libslirp.h => src/libslirp.h     |  13 +
 src/libslirp.map                 |  21 ++
 main.h => src/main.h             |   0
 mbuf.c => src/mbuf.c             |   0
 mbuf.h => src/mbuf.h             |   0
 misc.c => src/misc.c             |   0
 misc.h => src/misc.h             |   0
 ncsi-pkt.h => src/ncsi-pkt.h     |   0
 ncsi.c => src/ncsi.c             |   0
 ndp_table.c => src/ndp_table.c   |   0
 qtailq.h => src/qtailq.h         |   0
 sbuf.c => src/sbuf.c             |   0
 sbuf.h => src/sbuf.h             |   0
 slirp.c => src/slirp.c           |   9 -
 slirp.h => src/slirp.h           |   0
 socket.c => src/socket.c         |   0
 socket.h => src/socket.h         |   0
 state.c => src/state.c           |  50 ++--
 src/state.h                      |   0
 src/stream.c                     | 119 +++++++++
 src/stream.h                     |  34 +++
 tcp.h => src/tcp.h               |   0
 tcp_input.c => src/tcp_input.c   |   0
 tcp_output.c => src/tcp_output.c |   0
 tcp_subr.c => src/tcp_subr.c     |   0
 tcp_timer.c => src/tcp_timer.c   |   0
 tcp_timer.h => src/tcp_timer.h   |   0
 tcp_var.h => src/tcp_var.h       |   0
 tcpip.h => src/tcpip.h           |   0
 tftp.c => src/tftp.c             |   0
 tftp.h => src/tftp.h             |   0
 udp.c => src/udp.c               |   0
 udp.h => src/udp.h               |   0
 udp6.c => src/udp6.c             |   0
 util.c => src/util.c             |   0
 util.h => src/util.h             |   3 +
 src/version.c                    |  33 +++
 src/vmstate.c                    | 401 +++++++++++++++++++++++++++++++
 src/vmstate.h                    | 396 ++++++++++++++++++++++++++++++
 state.h                          |   9 -
 64 files changed, 1211 insertions(+), 80 deletions(-)
 create mode 100644 .gitlab-ci.yml
 delete mode 100644 Makefile.objs
 create mode 100644 meson.build
 rename arp_table.c => src/arp_table.c (100%)
 rename bootp.c => src/bootp.c (100%)
 rename bootp.h => src/bootp.h (100%)
 rename cksum.c => src/cksum.c (100%)
 rename debug.h => src/debug.h (100%)
 rename dhcpv6.c => src/dhcpv6.c (100%)
 rename dhcpv6.h => src/dhcpv6.h (100%)
 rename dnssearch.c => src/dnssearch.c (100%)
 rename if.c => src/if.c (100%)
 rename if.h => src/if.h (100%)
 rename ip.h => src/ip.h (100%)
 rename ip6.h => src/ip6.h (100%)
 rename ip6_icmp.c => src/ip6_icmp.c (100%)
 rename ip6_icmp.h => src/ip6_icmp.h (100%)
 rename ip6_input.c => src/ip6_input.c (100%)
 rename ip6_output.c => src/ip6_output.c (100%)
 rename ip_icmp.c => src/ip_icmp.c (100%)
 rename ip_icmp.h => src/ip_icmp.h (100%)
 rename ip_input.c => src/ip_input.c (100%)
 rename ip_output.c => src/ip_output.c (100%)
 create mode 100644 src/libslirp-version.h.in
 rename libslirp.h => src/libslirp.h (91%)
 create mode 100644 src/libslirp.map
 rename main.h => src/main.h (100%)
 rename mbuf.c => src/mbuf.c (100%)
 rename mbuf.h => src/mbuf.h (100%)
 rename misc.c => src/misc.c (100%)
 rename misc.h => src/misc.h (100%)
 rename ncsi-pkt.h => src/ncsi-pkt.h (100%)
 rename ncsi.c => src/ncsi.c (100%)
 rename ndp_table.c => src/ndp_table.c (100%)
 rename qtailq.h => src/qtailq.h (100%)
 rename sbuf.c => src/sbuf.c (100%)
 rename sbuf.h => src/sbuf.h (100%)
 rename slirp.c => src/slirp.c (99%)
 rename slirp.h => src/slirp.h (100%)
 rename socket.c => src/socket.c (100%)
 rename socket.h => src/socket.h (100%)
 rename state.c => src/state.c (93%)
 create mode 100644 src/state.h
 create mode 100644 src/stream.c
 create mode 100644 src/stream.h
 rename tcp.h => src/tcp.h (100%)
 rename tcp_input.c => src/tcp_input.c (100%)
 rename tcp_output.c => src/tcp_output.c (100%)
 rename tcp_subr.c => src/tcp_subr.c (100%)
 rename tcp_timer.c => src/tcp_timer.c (100%)
 rename tcp_timer.h => src/tcp_timer.h (100%)
 rename tcp_var.h => src/tcp_var.h (100%)
 rename tcpip.h => src/tcpip.h (100%)
 rename tftp.c => src/tftp.c (100%)
 rename tftp.h => src/tftp.h (100%)
 rename udp.c => src/udp.c (100%)
 rename udp.h => src/udp.h (100%)
 rename udp6.c => src/udp6.c (100%)
 rename util.c => src/util.c (100%)
 rename util.h => src/util.h (98%)
 create mode 100644 src/version.c
 create mode 100644 src/vmstate.c
 create mode 100644 src/vmstate.h
 delete mode 100644 state.h

-- 
2.21.0.rc0.1.g036caf7885

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH slirp 1/5] Extract slirp/ from qemu repository
  2019-02-08 18:11 [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project marcandre.lureau
@ 2019-02-08 18:11 ` marcandre.lureau
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 2/5] build-sys: add a meson build marcandre.lureau
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: marcandre.lureau @ 2019-02-08 18:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: samuel.thibault, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

$ git filter-branch --tree-filter "git ls-files '*.c' '*.h' | xargs
clang-format -i" -f --subdirectory-filter "slirp" --prune-empty
--tag-name-filter cat -- --all
$ git rm Makefiles.objs
$ mkdir src && git mv *.c *.h src/
$ git tag --no-merged | xargs git tag -d
$ git reflog expire --expire=now --all
$ git gc --prune=now --aggressive

This results in a 1.3M repostory with the tags, previewed here:
https://gitlab.freedesktop.org/elmarco/slirp

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 Makefile.objs                    | 34 --------------------------------
 arp_table.c => src/arp_table.c   |  0
 bootp.c => src/bootp.c           |  0
 bootp.h => src/bootp.h           |  0
 cksum.c => src/cksum.c           |  0
 debug.h => src/debug.h           |  0
 dhcpv6.c => src/dhcpv6.c         |  0
 dhcpv6.h => src/dhcpv6.h         |  0
 dnssearch.c => src/dnssearch.c   |  0
 if.c => src/if.c                 |  0
 if.h => src/if.h                 |  0
 ip.h => src/ip.h                 |  0
 ip6.h => src/ip6.h               |  0
 ip6_icmp.c => src/ip6_icmp.c     |  0
 ip6_icmp.h => src/ip6_icmp.h     |  0
 ip6_input.c => src/ip6_input.c   |  0
 ip6_output.c => src/ip6_output.c |  0
 ip_icmp.c => src/ip_icmp.c       |  0
 ip_icmp.h => src/ip_icmp.h       |  0
 ip_input.c => src/ip_input.c     |  0
 ip_output.c => src/ip_output.c   |  0
 libslirp.h => src/libslirp.h     |  0
 main.h => src/main.h             |  0
 mbuf.c => src/mbuf.c             |  0
 mbuf.h => src/mbuf.h             |  0
 misc.c => src/misc.c             |  0
 misc.h => src/misc.h             |  0
 ncsi-pkt.h => src/ncsi-pkt.h     |  0
 ncsi.c => src/ncsi.c             |  0
 ndp_table.c => src/ndp_table.c   |  0
 qtailq.h => src/qtailq.h         |  0
 sbuf.c => src/sbuf.c             |  0
 sbuf.h => src/sbuf.h             |  0
 slirp.c => src/slirp.c           |  0
 slirp.h => src/slirp.h           |  0
 socket.c => src/socket.c         |  0
 socket.h => src/socket.h         |  0
 state.c => src/state.c           |  0
 state.h => src/state.h           |  0
 tcp.h => src/tcp.h               |  0
 tcp_input.c => src/tcp_input.c   |  0
 tcp_output.c => src/tcp_output.c |  0
 tcp_subr.c => src/tcp_subr.c     |  0
 tcp_timer.c => src/tcp_timer.c   |  0
 tcp_timer.h => src/tcp_timer.h   |  0
 tcp_var.h => src/tcp_var.h       |  0
 tcpip.h => src/tcpip.h           |  0
 tftp.c => src/tftp.c             |  0
 tftp.h => src/tftp.h             |  0
 udp.c => src/udp.c               |  0
 udp.h => src/udp.h               |  0
 udp6.c => src/udp6.c             |  0
 util.c => src/util.c             |  0
 util.h => src/util.h             |  0
 54 files changed, 34 deletions(-)
 delete mode 100644 Makefile.objs
 rename arp_table.c => src/arp_table.c (100%)
 rename bootp.c => src/bootp.c (100%)
 rename bootp.h => src/bootp.h (100%)
 rename cksum.c => src/cksum.c (100%)
 rename debug.h => src/debug.h (100%)
 rename dhcpv6.c => src/dhcpv6.c (100%)
 rename dhcpv6.h => src/dhcpv6.h (100%)
 rename dnssearch.c => src/dnssearch.c (100%)
 rename if.c => src/if.c (100%)
 rename if.h => src/if.h (100%)
 rename ip.h => src/ip.h (100%)
 rename ip6.h => src/ip6.h (100%)
 rename ip6_icmp.c => src/ip6_icmp.c (100%)
 rename ip6_icmp.h => src/ip6_icmp.h (100%)
 rename ip6_input.c => src/ip6_input.c (100%)
 rename ip6_output.c => src/ip6_output.c (100%)
 rename ip_icmp.c => src/ip_icmp.c (100%)
 rename ip_icmp.h => src/ip_icmp.h (100%)
 rename ip_input.c => src/ip_input.c (100%)
 rename ip_output.c => src/ip_output.c (100%)
 rename libslirp.h => src/libslirp.h (100%)
 rename main.h => src/main.h (100%)
 rename mbuf.c => src/mbuf.c (100%)
 rename mbuf.h => src/mbuf.h (100%)
 rename misc.c => src/misc.c (100%)
 rename misc.h => src/misc.h (100%)
 rename ncsi-pkt.h => src/ncsi-pkt.h (100%)
 rename ncsi.c => src/ncsi.c (100%)
 rename ndp_table.c => src/ndp_table.c (100%)
 rename qtailq.h => src/qtailq.h (100%)
 rename sbuf.c => src/sbuf.c (100%)
 rename sbuf.h => src/sbuf.h (100%)
 rename slirp.c => src/slirp.c (100%)
 rename slirp.h => src/slirp.h (100%)
 rename socket.c => src/socket.c (100%)
 rename socket.h => src/socket.h (100%)
 rename state.c => src/state.c (100%)
 rename state.h => src/state.h (100%)
 rename tcp.h => src/tcp.h (100%)
 rename tcp_input.c => src/tcp_input.c (100%)
 rename tcp_output.c => src/tcp_output.c (100%)
 rename tcp_subr.c => src/tcp_subr.c (100%)
 rename tcp_timer.c => src/tcp_timer.c (100%)
 rename tcp_timer.h => src/tcp_timer.h (100%)
 rename tcp_var.h => src/tcp_var.h (100%)
 rename tcpip.h => src/tcpip.h (100%)
 rename tftp.c => src/tftp.c (100%)
 rename tftp.h => src/tftp.h (100%)
 rename udp.c => src/udp.c (100%)
 rename udp.h => src/udp.h (100%)
 rename udp6.c => src/udp6.c (100%)
 rename util.c => src/util.c (100%)
 rename util.h => src/util.h (100%)

diff --git a/Makefile.objs b/Makefile.objs
deleted file mode 100644
index 88340a5..0000000
--- a/Makefile.objs
+++ /dev/null
@@ -1,34 +0,0 @@
-slirp-obj-y = slirp.mo
-
-slirp.mo-objs = \
-	arp_table.o \
-	bootp.o \
-	cksum.o \
-	dhcpv6.o \
-	dnssearch.o \
-	if.o \
-	ip6_icmp.o \
-	ip6_input.o \
-	ip6_output.o \
-	ip_icmp.o \
-	ip_input.o \
-	ip_output.o \
-	mbuf.o \
-	misc.o \
-	ncsi.o \
-	ndp_table.o \
-	sbuf.o \
-	slirp.o \
-	socket.o \
-	state.o \
-	tcp_input.o \
-	tcp_output.o \
-	tcp_subr.o \
-	tcp_timer.o \
-	tftp.o \
-	udp.o \
-	udp6.o \
-	util.o \
-	$(NULL)
-
-slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU
diff --git a/arp_table.c b/src/arp_table.c
similarity index 100%
rename from arp_table.c
rename to src/arp_table.c
diff --git a/bootp.c b/src/bootp.c
similarity index 100%
rename from bootp.c
rename to src/bootp.c
diff --git a/bootp.h b/src/bootp.h
similarity index 100%
rename from bootp.h
rename to src/bootp.h
diff --git a/cksum.c b/src/cksum.c
similarity index 100%
rename from cksum.c
rename to src/cksum.c
diff --git a/debug.h b/src/debug.h
similarity index 100%
rename from debug.h
rename to src/debug.h
diff --git a/dhcpv6.c b/src/dhcpv6.c
similarity index 100%
rename from dhcpv6.c
rename to src/dhcpv6.c
diff --git a/dhcpv6.h b/src/dhcpv6.h
similarity index 100%
rename from dhcpv6.h
rename to src/dhcpv6.h
diff --git a/dnssearch.c b/src/dnssearch.c
similarity index 100%
rename from dnssearch.c
rename to src/dnssearch.c
diff --git a/if.c b/src/if.c
similarity index 100%
rename from if.c
rename to src/if.c
diff --git a/if.h b/src/if.h
similarity index 100%
rename from if.h
rename to src/if.h
diff --git a/ip.h b/src/ip.h
similarity index 100%
rename from ip.h
rename to src/ip.h
diff --git a/ip6.h b/src/ip6.h
similarity index 100%
rename from ip6.h
rename to src/ip6.h
diff --git a/ip6_icmp.c b/src/ip6_icmp.c
similarity index 100%
rename from ip6_icmp.c
rename to src/ip6_icmp.c
diff --git a/ip6_icmp.h b/src/ip6_icmp.h
similarity index 100%
rename from ip6_icmp.h
rename to src/ip6_icmp.h
diff --git a/ip6_input.c b/src/ip6_input.c
similarity index 100%
rename from ip6_input.c
rename to src/ip6_input.c
diff --git a/ip6_output.c b/src/ip6_output.c
similarity index 100%
rename from ip6_output.c
rename to src/ip6_output.c
diff --git a/ip_icmp.c b/src/ip_icmp.c
similarity index 100%
rename from ip_icmp.c
rename to src/ip_icmp.c
diff --git a/ip_icmp.h b/src/ip_icmp.h
similarity index 100%
rename from ip_icmp.h
rename to src/ip_icmp.h
diff --git a/ip_input.c b/src/ip_input.c
similarity index 100%
rename from ip_input.c
rename to src/ip_input.c
diff --git a/ip_output.c b/src/ip_output.c
similarity index 100%
rename from ip_output.c
rename to src/ip_output.c
diff --git a/libslirp.h b/src/libslirp.h
similarity index 100%
rename from libslirp.h
rename to src/libslirp.h
diff --git a/main.h b/src/main.h
similarity index 100%
rename from main.h
rename to src/main.h
diff --git a/mbuf.c b/src/mbuf.c
similarity index 100%
rename from mbuf.c
rename to src/mbuf.c
diff --git a/mbuf.h b/src/mbuf.h
similarity index 100%
rename from mbuf.h
rename to src/mbuf.h
diff --git a/misc.c b/src/misc.c
similarity index 100%
rename from misc.c
rename to src/misc.c
diff --git a/misc.h b/src/misc.h
similarity index 100%
rename from misc.h
rename to src/misc.h
diff --git a/ncsi-pkt.h b/src/ncsi-pkt.h
similarity index 100%
rename from ncsi-pkt.h
rename to src/ncsi-pkt.h
diff --git a/ncsi.c b/src/ncsi.c
similarity index 100%
rename from ncsi.c
rename to src/ncsi.c
diff --git a/ndp_table.c b/src/ndp_table.c
similarity index 100%
rename from ndp_table.c
rename to src/ndp_table.c
diff --git a/qtailq.h b/src/qtailq.h
similarity index 100%
rename from qtailq.h
rename to src/qtailq.h
diff --git a/sbuf.c b/src/sbuf.c
similarity index 100%
rename from sbuf.c
rename to src/sbuf.c
diff --git a/sbuf.h b/src/sbuf.h
similarity index 100%
rename from sbuf.h
rename to src/sbuf.h
diff --git a/slirp.c b/src/slirp.c
similarity index 100%
rename from slirp.c
rename to src/slirp.c
diff --git a/slirp.h b/src/slirp.h
similarity index 100%
rename from slirp.h
rename to src/slirp.h
diff --git a/socket.c b/src/socket.c
similarity index 100%
rename from socket.c
rename to src/socket.c
diff --git a/socket.h b/src/socket.h
similarity index 100%
rename from socket.h
rename to src/socket.h
diff --git a/state.c b/src/state.c
similarity index 100%
rename from state.c
rename to src/state.c
diff --git a/state.h b/src/state.h
similarity index 100%
rename from state.h
rename to src/state.h
diff --git a/tcp.h b/src/tcp.h
similarity index 100%
rename from tcp.h
rename to src/tcp.h
diff --git a/tcp_input.c b/src/tcp_input.c
similarity index 100%
rename from tcp_input.c
rename to src/tcp_input.c
diff --git a/tcp_output.c b/src/tcp_output.c
similarity index 100%
rename from tcp_output.c
rename to src/tcp_output.c
diff --git a/tcp_subr.c b/src/tcp_subr.c
similarity index 100%
rename from tcp_subr.c
rename to src/tcp_subr.c
diff --git a/tcp_timer.c b/src/tcp_timer.c
similarity index 100%
rename from tcp_timer.c
rename to src/tcp_timer.c
diff --git a/tcp_timer.h b/src/tcp_timer.h
similarity index 100%
rename from tcp_timer.h
rename to src/tcp_timer.h
diff --git a/tcp_var.h b/src/tcp_var.h
similarity index 100%
rename from tcp_var.h
rename to src/tcp_var.h
diff --git a/tcpip.h b/src/tcpip.h
similarity index 100%
rename from tcpip.h
rename to src/tcpip.h
diff --git a/tftp.c b/src/tftp.c
similarity index 100%
rename from tftp.c
rename to src/tftp.c
diff --git a/tftp.h b/src/tftp.h
similarity index 100%
rename from tftp.h
rename to src/tftp.h
diff --git a/udp.c b/src/udp.c
similarity index 100%
rename from udp.c
rename to src/udp.c
diff --git a/udp.h b/src/udp.h
similarity index 100%
rename from udp.h
rename to src/udp.h
diff --git a/udp6.c b/src/udp6.c
similarity index 100%
rename from udp6.c
rename to src/udp6.c
diff --git a/util.c b/src/util.c
similarity index 100%
rename from util.c
rename to src/util.c
diff --git a/util.h b/src/util.h
similarity index 100%
rename from util.h
rename to src/util.h
-- 
2.21.0.rc0.1.g036caf7885

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH slirp 2/5] build-sys: add a meson build
  2019-02-08 18:11 [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project marcandre.lureau
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 1/5] Extract slirp/ from qemu repository marcandre.lureau
@ 2019-02-08 18:11 ` marcandre.lureau
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 3/5] build-sys: add version tooling marcandre.lureau
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: marcandre.lureau @ 2019-02-08 18:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: samuel.thibault, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Build a shared library, exporting only slirp_* symbols.

Install API headers and a slirp.pc pkg-config.

It has been tested to build on Linux and with mingw64 cross-compilation.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 meson.build      | 111 +++++++++++++++++++++++++++++++++++++++++++++++
 src/libslirp.map |  21 +++++++++
 2 files changed, 132 insertions(+)
 create mode 100644 meson.build
 create mode 100644 src/libslirp.map

diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..d53d17a
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,111 @@
+project('slirp', 'c',
+  version : '4.0.0',
+  license : 'BSD-3-Clause',
+  default_options : ['warning_level=1', 'c_std=gnu99']
+)
+
+version = meson.project_version()
+varr = version.split('.')
+major_version = varr[0]
+minor_version = varr[1]
+micro_version = varr[2]
+
+# libtool versioning - this applies to libpackagekit
+#
+# See http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 for details
+#
+# - If interfaces have been changed or added, but binary compatibility
+#   has been preserved, change:
+#      CURRENT += 1
+#      REVISION = 0
+#      AGE += 1
+# - If binary compatibility has been broken (eg removed or changed
+#   interfaces), change:
+#      CURRENT += 1
+#      REVISION = 0
+#      AGE = 0
+# - If the interface is the same as the previous version, but bugs are
+#   fixed, change:
+#      REVISION += 1
+lt_current = '0'
+lt_revision = '0'
+lt_age = '0'
+lt_version = '@0@.@1@.@2@'.format(lt_current, lt_age, lt_revision)
+
+host_system = host_machine.system()
+
+glib_dep = dependency('glib-2.0')
+
+cc = meson.get_compiler('c')
+
+platform_deps = []
+
+if host_system == 'windows'
+  platform_deps += [
+    cc.find_library('ws2_32'),
+    cc.find_library('iphlpapi')
+  ]
+endif
+
+cargs = [
+  '-DG_LOG_DOMAIN="Slirp"',
+]
+
+sources = [
+  'src/arp_table.c',
+  'src/bootp.c',
+  'src/cksum.c',
+  'src/dhcpv6.c',
+  'src/dnssearch.c',
+  'src/if.c',
+  'src/ip6_icmp.c',
+  'src/ip6_input.c',
+  'src/ip6_output.c',
+  'src/ip_icmp.c',
+  'src/ip_input.c',
+  'src/ip_output.c',
+  'src/mbuf.c',
+  'src/misc.c',
+  'src/ncsi.c',
+  'src/ndp_table.c',
+  'src/sbuf.c',
+  'src/slirp.c',
+  'src/socket.c',
+  'src/tcp_input.c',
+  'src/tcp_output.c',
+  'src/tcp_subr.c',
+  'src/tcp_timer.c',
+  'src/tftp.c',
+  'src/udp.c',
+  'src/udp6.c',
+  'src/util.c',
+]
+
+mapfile = 'src/libslirp.map'
+vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
+
+lib = shared_library('slirp', sources,
+  soversion : lt_current,
+  version : lt_version,
+  c_args : cargs,
+  link_args : vflag,
+  link_depends : mapfile,
+  dependencies : [glib_dep, platform_deps],
+  install : true
+)
+
+install_headers(['src/libslirp.h'], subdir : 'slirp')
+
+pkg = import('pkgconfig')
+
+pkg.generate(
+  version : version,
+  libraries : lib,
+  requires : [
+    'glib-2.0',
+  ],
+  name : 'slirp',
+  description : 'User-space network stack',
+  filebase : 'slirp',
+  subdirs : 'slirp',
+)
diff --git a/src/libslirp.map b/src/libslirp.map
new file mode 100644
index 0000000..3eb730a
--- /dev/null
+++ b/src/libslirp.map
@@ -0,0 +1,21 @@
+SLIRP_4.0 {
+global:
+    slirp_add_exec;
+    slirp_add_guestfwd;
+    slirp_add_hostfwd;
+    slirp_cleanup;
+    slirp_connection_info;
+    slirp_init;
+    slirp_input;
+    slirp_pollfds_fill;
+    slirp_pollfds_poll;
+    slirp_remove_hostfwd;
+    slirp_socket_can_recv;
+    slirp_socket_recv;
+    slirp_state_load;
+    slirp_state_save;
+    slirp_state_version;
+    slirp_version_string;
+local:
+    *;
+};
-- 
2.21.0.rc0.1.g036caf7885

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH slirp 3/5] build-sys: add version tooling
  2019-02-08 18:11 [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project marcandre.lureau
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 1/5] Extract slirp/ from qemu repository marcandre.lureau
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 2/5] build-sys: add a meson build marcandre.lureau
@ 2019-02-08 18:11 ` marcandre.lureau
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading marcandre.lureau
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: marcandre.lureau @ 2019-02-08 18:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: samuel.thibault, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Add SLIRP_CHECK_VERSION() macro, and a slirp_version_string() helpers.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 meson.build               | 13 +++++++++++++
 src/libslirp-version.h.in | 22 ++++++++++++++++++++++
 src/libslirp.h            |  5 +++++
 src/util.h                |  3 +++
 src/version.c             | 33 +++++++++++++++++++++++++++++++++
 5 files changed, 76 insertions(+)
 create mode 100644 src/libslirp-version.h.in
 create mode 100644 src/version.c

diff --git a/meson.build b/meson.build
index d53d17a..ec0a0dd 100644
--- a/meson.build
+++ b/meson.build
@@ -10,6 +10,11 @@ major_version = varr[0]
 minor_version = varr[1]
 micro_version = varr[2]
 
+conf = configuration_data()
+conf.set('SLIRP_MAJOR_VERSION', major_version)
+conf.set('SLIRP_MINOR_VERSION', minor_version)
+conf.set('SLIRP_MICRO_VERSION', micro_version)
+
 # libtool versioning - this applies to libpackagekit
 #
 # See http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 for details
@@ -79,11 +84,19 @@ sources = [
   'src/udp.c',
   'src/udp6.c',
   'src/util.c',
+  'src/version.c',
 ]
 
 mapfile = 'src/libslirp.map'
 vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
 
+configure_file(
+  input : 'src/libslirp-version.h.in',
+  output : 'libslirp-version.h',
+  install_dir : join_paths(get_option('includedir'), 'slirp'),
+  configuration : conf
+)
+
 lib = shared_library('slirp', sources,
   soversion : lt_current,
   version : lt_version,
diff --git a/src/libslirp-version.h.in b/src/libslirp-version.h.in
new file mode 100644
index 0000000..e7d56f1
--- /dev/null
+++ b/src/libslirp-version.h.in
@@ -0,0 +1,22 @@
+#ifndef LIBSLIRP_VERSION_H_
+#define LIBSLIRP_VERSION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SLIRP_MAJOR_VERSION @SLIRP_MAJOR_VERSION@
+#define SLIRP_MINOR_VERSION @SLIRP_MINOR_VERSION@
+#define SLIRP_MICRO_VERSION @SLIRP_MICRO_VERSION@
+
+#define SLIRP_CHECK_VERSION(major,minor,micro)                          \
+    (SLIRP_MAJOR_VERSION > (major) ||                                   \
+     (SLIRP_MAJOR_VERSION == (major) && SLIRP_MINOR_VERSION > (minor)) || \
+     (SLIRP_MAJOR_VERSION == (major) && SLIRP_MINOR_VERSION == (minor) && \
+      SLIRP_MICRO_VERSION >= (micro)))
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LIBSLIRP_VERSION_H_ */
diff --git a/src/libslirp.h b/src/libslirp.h
index c6cb6a9..8008bd9 100644
--- a/src/libslirp.h
+++ b/src/libslirp.h
@@ -12,6 +12,8 @@
 #include <arpa/inet.h>
 #endif
 
+#include "libslirp-version.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -97,6 +99,9 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
                        const uint8_t *buf, int size);
 size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
                              int guest_port);
+
+const char *slirp_version_string(void);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/src/util.h b/src/util.h
index a9c4e32..82b1901 100644
--- a/src/util.h
+++ b/src/util.h
@@ -71,6 +71,9 @@ struct iovec {
 #include <sys/uio.h>
 #endif
 
+#define stringify(s) tostring(s)
+#define tostring(s) #s
+
 #define SCALE_MS 1000000
 
 #define ETH_ALEN 6
diff --git a/src/version.c b/src/version.c
new file mode 100644
index 0000000..1a1d51e
--- /dev/null
+++ b/src/version.c
@@ -0,0 +1,33 @@
+/*
+ * libslirp version
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "libslirp.h"
+#include "util.h"
+
+const char *
+slirp_version_string(void)
+{
+    return stringify(SLIRP_MAJOR_VERSION) "."
+        stringify(SLIRP_MINOR_VERSION) "."
+        stringify(SLIRP_MICRO_VERSION);
+}
-- 
2.21.0.rc0.1.g036caf7885

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading
  2019-02-08 18:11 [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project marcandre.lureau
                   ` (2 preceding siblings ...)
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 3/5] build-sys: add version tooling marcandre.lureau
@ 2019-02-08 18:11 ` marcandre.lureau
  2019-02-09 11:40   ` Samuel Thibault
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 5/5] Add .gitlab-ci.yml marcandre.lureau
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: marcandre.lureau @ 2019-02-08 18:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: samuel.thibault, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Based on qemu vmstate serialization code. At this point it should
produce the same result. However, with future state versions, slirp
should be free to change its format, by bumping the reported state
version.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 meson.build    |   3 +
 src/libslirp.h |   8 +
 src/slirp.c    |   9 --
 src/state.c    |  50 +++---
 src/state.h    |   9 --
 src/stream.c   | 119 +++++++++++++++
 src/stream.h   |  34 +++++
 src/vmstate.c  | 401 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/vmstate.h  | 396 ++++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 983 insertions(+), 46 deletions(-)
 create mode 100644 src/stream.c
 create mode 100644 src/stream.h
 create mode 100644 src/vmstate.c
 create mode 100644 src/vmstate.h

diff --git a/meson.build b/meson.build
index ec0a0dd..8ac40e4 100644
--- a/meson.build
+++ b/meson.build
@@ -76,6 +76,8 @@ sources = [
   'src/sbuf.c',
   'src/slirp.c',
   'src/socket.c',
+  'src/state.c',
+  'src/stream.c',
   'src/tcp_input.c',
   'src/tcp_output.c',
   'src/tcp_subr.c',
@@ -85,6 +87,7 @@ sources = [
   'src/udp6.c',
   'src/util.c',
   'src/version.c',
+  'src/vmstate.c',
 ]
 
 mapfile = 'src/libslirp.map'
diff --git a/src/libslirp.h b/src/libslirp.h
index 8008bd9..0f07489 100644
--- a/src/libslirp.h
+++ b/src/libslirp.h
@@ -28,6 +28,7 @@ enum {
     SLIRP_POLL_HUP = 1 << 4,
 };
 
+typedef ssize_t (*SlirpReadCb)(void *buf, size_t len, void *opaque);
 typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
 typedef void (*SlirpTimerCb)(void *opaque);
 typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
@@ -102,6 +103,13 @@ size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
 
 const char *slirp_version_string(void);
 
+void slirp_state_save(Slirp *s, SlirpWriteCb write_cb, void *opaque);
+
+int slirp_state_load(Slirp *s, int version_id,
+                     SlirpReadCb read_cb, void *opaque);
+
+int slirp_state_version(void);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/src/slirp.c b/src/slirp.c
index ab531e9..0604270 100644
--- a/src/slirp.c
+++ b/src/slirp.c
@@ -23,9 +23,6 @@
  */
 #include "slirp.h"
 
-#ifdef WITH_QEMU
-#include "state.h"
-#endif
 
 #ifndef _WIN32
 #include <net/if.h>
@@ -321,9 +318,6 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
         translate_dnssearch(slirp, vdnssearch);
     }
 
-#ifdef WITH_QEMU
-    slirp_state_register(slirp);
-#endif
     return slirp;
 }
 
@@ -337,9 +331,6 @@ void slirp_cleanup(Slirp *slirp)
         g_free(e);
     }
 
-#ifdef WITH_QEMU
-    slirp_state_unregister(slirp);
-#endif
     ip_cleanup(slirp);
     ip6_cleanup(slirp);
     m_cleanup(slirp);
diff --git a/src/state.c b/src/state.c
index 32eec6f..53b0a03 100644
--- a/src/state.c
+++ b/src/state.c
@@ -21,13 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "qemu/osdep.h"
-
 #include "slirp.h"
+#include "vmstate.h"
 #include "state.h"
-#include "migration/vmstate.h"
-#include "migration/qemu-file-types.h"
-#include "migration/register.h"
+#include "stream.h"
 
 static int slirp_tcp_post_load(void *opaque, int version)
 {
@@ -314,10 +311,13 @@ static const VMStateDescription vmstate_slirp = {
                                 VMSTATE_END_OF_LIST() }
 };
 
-static void slirp_state_save(QEMUFile *f, void *opaque)
+void slirp_state_save(Slirp *slirp, SlirpWriteCb write_cb, void *opaque)
 {
-    Slirp *slirp = opaque;
     struct gfwd_list *ex_ptr;
+    SlirpOStream f = {
+        .write_cb = write_cb,
+        .opaque = opaque,
+    };
 
     for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
         if (ex_ptr->write_cb) {
@@ -328,25 +328,29 @@ static void slirp_state_save(QEMUFile *f, void *opaque)
                 continue;
             }
 
-            qemu_put_byte(f, 42);
-            vmstate_save_state(f, &vmstate_slirp_socket, so, NULL);
+            slirp_ostream_write_u8(&f, 42);
+            vmstate_save_state(&f, &vmstate_slirp_socket, so);
         }
-    qemu_put_byte(f, 0);
+    slirp_ostream_write_u8(&f, 0);
 
-    vmstate_save_state(f, &vmstate_slirp, slirp, NULL);
+    vmstate_save_state(&f, &vmstate_slirp, slirp);
 }
 
 
-static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
+int slirp_state_load(Slirp *slirp, int version_id,
+                     SlirpReadCb read_cb, void *opaque)
 {
-    Slirp *slirp = opaque;
     struct gfwd_list *ex_ptr;
+    SlirpIStream f = {
+        .read_cb = read_cb,
+        .opaque = opaque,
+    };
 
-    while (qemu_get_byte(f)) {
+    while (slirp_istream_read_u8(&f)) {
         int ret;
         struct socket *so = socreate(slirp);
 
-        ret = vmstate_load_state(f, &vmstate_slirp_socket, so, version_id);
+        ret = vmstate_load_state(&f, &vmstate_slirp_socket, so, version_id);
         if (ret < 0) {
             return ret;
         }
@@ -367,20 +371,10 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
         }
     }
 
-    return vmstate_load_state(f, &vmstate_slirp, slirp, version_id);
-}
-
-void slirp_state_register(Slirp *slirp)
-{
-    static SaveVMHandlers savevm_slirp_state = {
-        .save_state = slirp_state_save,
-        .load_state = slirp_state_load,
-    };
-
-    register_savevm_live(NULL, "slirp", 0, 4, &savevm_slirp_state, slirp);
+    return vmstate_load_state(&f, &vmstate_slirp, slirp, version_id);
 }
 
-void slirp_state_unregister(Slirp *slirp)
+int slirp_state_version(void)
 {
-    unregister_savevm(NULL, "slirp", slirp);
+    return 4;
 }
diff --git a/src/state.h b/src/state.h
index 1548668..e69de29 100644
--- a/src/state.h
+++ b/src/state.h
@@ -1,9 +0,0 @@
-#ifndef SLIRP_STATE_H_
-#define SLIRP_STATE_H_
-
-#include "libslirp.h"
-
-void slirp_state_register(Slirp *slirp);
-void slirp_state_unregister(Slirp *slirp);
-
-#endif /* SLIRP_STATE_H_ */
diff --git a/src/stream.c b/src/stream.c
new file mode 100644
index 0000000..b1060b4
--- /dev/null
+++ b/src/stream.c
@@ -0,0 +1,119 @@
+/*
+ * libslirp glue
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "stream.h"
+#include <glib.h>
+
+bool slirp_istream_read(SlirpIStream *f, void *buf, size_t size)
+{
+    return f->read_cb(buf, size, f->opaque) == size;
+}
+
+bool slirp_ostream_write(SlirpOStream *f, const void *buf, size_t size)
+{
+    return f->write_cb(buf, size, f->opaque) == size;
+}
+
+uint8_t slirp_istream_read_u8(SlirpIStream *f)
+{
+    uint8_t b;
+
+    if (slirp_istream_read(f, &b, sizeof(b))) {
+        return b;
+    }
+
+    return 0;
+}
+
+bool slirp_ostream_write_u8(SlirpOStream *f, uint8_t b)
+{
+    return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+uint16_t slirp_istream_read_u16(SlirpIStream *f)
+{
+    uint16_t b;
+
+    if (slirp_istream_read(f, &b, sizeof(b))) {
+        return GUINT16_FROM_BE(b);
+    }
+
+    return 0;
+}
+
+bool slirp_ostream_write_u16(SlirpOStream *f, uint16_t b)
+{
+    b =  GUINT16_TO_BE(b);
+    return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+uint32_t slirp_istream_read_u32(SlirpIStream *f)
+{
+    uint32_t b;
+
+    if (slirp_istream_read(f, &b, sizeof(b))) {
+        return GUINT32_FROM_BE(b);
+    }
+
+    return 0;
+}
+
+bool slirp_ostream_write_u32(SlirpOStream *f, uint32_t b)
+{
+    b = GUINT32_TO_BE(b);
+    return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+int16_t slirp_istream_read_i16(SlirpIStream *f)
+{
+    int16_t b;
+
+    if (slirp_istream_read(f, &b, sizeof(b))) {
+        return GINT16_FROM_BE(b);
+    }
+
+    return 0;
+}
+
+bool slirp_ostream_write_i16(SlirpOStream *f, int16_t b)
+{
+    b = GINT16_TO_BE(b);
+    return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+int32_t slirp_istream_read_i32(SlirpIStream *f)
+{
+    int32_t b;
+
+    if (slirp_istream_read(f, &b, sizeof(b))) {
+        return GINT32_FROM_BE(b);
+    }
+
+    return 0;
+}
+
+bool slirp_ostream_write_i32(SlirpOStream *f, int32_t b)
+{
+    b = GINT32_TO_BE(b);
+    return slirp_ostream_write(f, &b, sizeof(b));
+}
diff --git a/src/stream.h b/src/stream.h
new file mode 100644
index 0000000..985334c
--- /dev/null
+++ b/src/stream.h
@@ -0,0 +1,34 @@
+#ifndef STREAM_H_
+#define STREAM_H_
+
+#include "libslirp.h"
+
+typedef struct SlirpIStream {
+    SlirpReadCb read_cb;
+    void *opaque;
+} SlirpIStream;
+
+typedef struct SlirpOStream {
+    SlirpWriteCb write_cb;
+    void *opaque;
+} SlirpOStream;
+
+bool slirp_istream_read(SlirpIStream *f, void *buf, size_t size);
+bool slirp_ostream_write(SlirpOStream *f, const void *buf, size_t size);
+
+uint8_t slirp_istream_read_u8(SlirpIStream *f);
+bool slirp_ostream_write_u8(SlirpOStream *f, uint8_t b);
+
+uint16_t slirp_istream_read_u16(SlirpIStream *f);
+bool slirp_ostream_write_u16(SlirpOStream *f, uint16_t b);
+
+uint32_t slirp_istream_read_u32(SlirpIStream *f);
+bool slirp_ostream_write_u32(SlirpOStream *f, uint32_t b);
+
+int16_t slirp_istream_read_i16(SlirpIStream *f);
+bool slirp_ostream_write_i16(SlirpOStream *f, int16_t b);
+
+int32_t slirp_istream_read_i32(SlirpIStream *f);
+bool slirp_ostream_write_i32(SlirpOStream *f, int32_t b);
+
+#endif /* STREAM_H_ */
diff --git a/src/vmstate.c b/src/vmstate.c
new file mode 100644
index 0000000..2f58d1c
--- /dev/null
+++ b/src/vmstate.c
@@ -0,0 +1,401 @@
+/*
+ * VMState interpreter
+ *
+ * Copyright (c) 2009-2018 Red Hat Inc
+ *
+ * Authors:
+ *  Juan Quintela <quintela@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <glib.h>
+
+#include "stream.h"
+#include "vmstate.h"
+
+static int get_nullptr(SlirpIStream *f, void *pv, size_t size,
+                       VMStateField *field)
+{
+    if (slirp_istream_read_u8(f) == VMS_NULLPTR_MARKER) {
+        return  0;
+    }
+    g_warning("vmstate: get_nullptr expected VMS_NULLPTR_MARKER");
+    return -EINVAL;
+}
+
+static int put_nullptr(SlirpOStream *f, void *pv, size_t size,
+                       VMStateField *field)
+
+{
+    if (pv == NULL) {
+        slirp_ostream_write_u8(f, VMS_NULLPTR_MARKER);
+        return 0;
+    }
+    g_warning("vmstate: put_nullptr must be called with pv == NULL");
+    return -EINVAL;
+}
+
+const VMStateInfo vmstate_info_nullptr = {
+    .name = "uint64",
+    .get  = get_nullptr,
+    .put  = put_nullptr,
+};
+
+static int get_uint8(SlirpIStream *f, void *pv, size_t size, VMStateField *field)
+{
+    uint8_t *v = pv;
+    *v = slirp_istream_read_u8(f);
+    return 0;
+}
+
+static int put_uint8(SlirpOStream *f, void *pv, size_t size, VMStateField *field)
+{
+    uint8_t *v = pv;
+    slirp_ostream_write_u8(f, *v);
+    return 0;
+}
+
+const VMStateInfo vmstate_info_uint8 = {
+    .name = "uint8",
+    .get  = get_uint8,
+    .put  = put_uint8,
+};
+
+static int get_uint16(SlirpIStream *f, void *pv, size_t size,
+                      VMStateField *field)
+{
+    uint16_t *v = pv;
+    *v = slirp_istream_read_u16(f);
+    return 0;
+}
+
+static int put_uint16(SlirpOStream *f, void *pv, size_t size,
+                      VMStateField *field)
+{
+    uint16_t *v = pv;
+    slirp_ostream_write_u16(f, *v);
+    return 0;
+}
+
+const VMStateInfo vmstate_info_uint16 = {
+    .name = "uint16",
+    .get  = get_uint16,
+    .put  = put_uint16,
+};
+
+static int get_uint32(SlirpIStream *f, void *pv, size_t size,
+                      VMStateField *field)
+{
+    uint32_t *v = pv;
+    *v = slirp_istream_read_u32(f);
+    return 0;
+}
+
+static int put_uint32(SlirpOStream *f, void *pv, size_t size,
+                      VMStateField *field)
+{
+    uint32_t *v = pv;
+    slirp_ostream_write_u32(f, *v);
+    return 0;
+}
+
+const VMStateInfo vmstate_info_uint32 = {
+    .name = "uint32",
+    .get  = get_uint32,
+    .put  = put_uint32,
+};
+
+static int get_int16(SlirpIStream *f, void *pv, size_t size, VMStateField *field)
+{
+    int16_t *v = pv;
+    *v = slirp_istream_read_i16(f);
+    return 0;
+}
+
+static int put_int16(SlirpOStream *f, void *pv, size_t size, VMStateField *field)
+{
+    int16_t *v = pv;
+    slirp_ostream_write_i16(f, *v);
+    return 0;
+}
+
+const VMStateInfo vmstate_info_int16 = {
+    .name = "int16",
+    .get  = get_int16,
+    .put  = put_int16,
+};
+
+static int get_int32(SlirpIStream *f, void *pv, size_t size, VMStateField *field)
+{
+    int32_t *v = pv;
+    *v = slirp_istream_read_i32(f);
+    return 0;
+}
+
+static int put_int32(SlirpOStream *f, void *pv, size_t size, VMStateField *field)
+{
+    int32_t *v = pv;
+    slirp_ostream_write_i32(f, *v);
+    return 0;
+}
+
+const VMStateInfo vmstate_info_int32 = {
+    .name = "int32",
+    .get  = get_int32,
+    .put  = put_int32,
+};
+
+/* vmstate_info_tmp, see VMSTATE_WITH_TMP, the idea is that we allocate
+ * a temporary buffer and the pre_load/pre_save methods in the child vmsd
+ * copy stuff from the parent into the child and do calculations to fill
+ * in fields that don't really exist in the parent but need to be in the
+ * stream.
+ */
+static int get_tmp(SlirpIStream *f, void *pv, size_t size, VMStateField *field)
+{
+    int ret;
+    const VMStateDescription *vmsd = field->vmsd;
+    int version_id = field->version_id;
+    void *tmp = g_malloc(size);
+
+    /* Writes the parent field which is at the start of the tmp */
+    *(void **)tmp = pv;
+    ret = vmstate_load_state(f, vmsd, tmp, version_id);
+    g_free(tmp);
+    return ret;
+}
+
+static int put_tmp(SlirpOStream *f, void *pv, size_t size, VMStateField *field)
+{
+    const VMStateDescription *vmsd = field->vmsd;
+    void *tmp = g_malloc(size);
+    int ret;
+
+    /* Writes the parent field which is at the start of the tmp */
+    *(void **)tmp = pv;
+    ret = vmstate_save_state(f, vmsd, tmp);
+    g_free(tmp);
+
+    return ret;
+}
+
+const VMStateInfo vmstate_info_tmp = {
+    .name = "tmp",
+    .get = get_tmp,
+    .put = put_tmp,
+};
+
+static int get_buffer(SlirpIStream *f, void *pv, size_t size,
+                      VMStateField *field)
+{
+    slirp_istream_read(f, pv, size);
+    return 0;
+}
+
+static int put_buffer(SlirpOStream *f, void *pv, size_t size,
+                      VMStateField *field)
+{
+    slirp_ostream_write(f, pv, size);
+    return 0;
+}
+
+const VMStateInfo vmstate_info_buffer = {
+    .name = "buffer",
+    .get  = get_buffer,
+    .put  = put_buffer,
+};
+
+static int vmstate_n_elems(void *opaque, VMStateField *field)
+{
+    int n_elems = 1;
+
+    if (field->flags & VMS_ARRAY) {
+        n_elems = field->num;
+    } else if (field->flags & VMS_VARRAY_INT32) {
+        n_elems = *(int32_t *)(opaque + field->num_offset);
+    } else if (field->flags & VMS_VARRAY_UINT32) {
+        n_elems = *(uint32_t *)(opaque + field->num_offset);
+    } else if (field->flags & VMS_VARRAY_UINT16) {
+        n_elems = *(uint16_t *)(opaque + field->num_offset);
+    } else if (field->flags & VMS_VARRAY_UINT8) {
+        n_elems = *(uint8_t *)(opaque + field->num_offset);
+    }
+
+    if (field->flags & VMS_MULTIPLY_ELEMENTS) {
+        n_elems *= field->num;
+    }
+
+    return n_elems;
+}
+
+static int vmstate_size(void *opaque, VMStateField *field)
+{
+    int size = field->size;
+
+    if (field->flags & VMS_VBUFFER) {
+        size = *(int32_t *)(opaque + field->size_offset);
+        if (field->flags & VMS_MULTIPLY) {
+            size *= field->size;
+        }
+    }
+
+    return size;
+}
+
+static int
+vmstate_save_state_v(SlirpOStream *f, const VMStateDescription *vmsd,
+                     void *opaque, int version_id)
+{
+    int ret = 0;
+    VMStateField *field = vmsd->fields;
+
+    if (vmsd->pre_save) {
+        ret = vmsd->pre_save(opaque);
+        if (ret) {
+            g_warning("pre-save failed: %s", vmsd->name);
+            return ret;
+        }
+    }
+
+    while (field->name) {
+        if ((field->field_exists &&
+             field->field_exists(opaque, version_id)) ||
+            (!field->field_exists &&
+             field->version_id <= version_id)) {
+            void *first_elem = opaque + field->offset;
+            int i, n_elems = vmstate_n_elems(opaque, field);
+            int size = vmstate_size(opaque, field);
+
+            if (field->flags & VMS_POINTER) {
+                first_elem = *(void **)first_elem;
+                assert(first_elem || !n_elems || !size);
+            }
+            for (i = 0; i < n_elems; i++) {
+                void *curr_elem = first_elem + size * i;
+                ret = 0;
+
+                if (field->flags & VMS_ARRAY_OF_POINTER) {
+                    assert(curr_elem);
+                    curr_elem = *(void **)curr_elem;
+                }
+                if (!curr_elem && size) {
+                    /* if null pointer write placeholder and do not follow */
+                    assert(field->flags & VMS_ARRAY_OF_POINTER);
+                    ret = vmstate_info_nullptr.put(f, curr_elem, size, NULL);
+                } else if (field->flags & VMS_STRUCT) {
+                    ret = vmstate_save_state(f, field->vmsd, curr_elem);
+                } else if (field->flags & VMS_VSTRUCT) {
+                    ret = vmstate_save_state_v(f, field->vmsd, curr_elem,
+                                               field->struct_version_id);
+                } else {
+                    ret = field->info->put(f, curr_elem, size, field);
+                }
+                if (ret) {
+                    g_warning("Save of field %s/%s failed",
+                              vmsd->name, field->name);
+                    return ret;
+                }
+            }
+        } else {
+            if (field->flags & VMS_MUST_EXIST) {
+                g_warning("Output state validation failed: %s/%s",
+                          vmsd->name, field->name);
+                assert(!(field->flags & VMS_MUST_EXIST));
+            }
+        }
+        field++;
+    }
+
+    return 0;
+}
+
+int vmstate_save_state(SlirpOStream *f, const VMStateDescription *vmsd,
+                       void *opaque)
+{
+    return vmstate_save_state_v(f, vmsd, opaque, vmsd->version_id);
+}
+
+static void vmstate_handle_alloc(void *ptr, VMStateField *field, void *opaque)
+{
+    if (field->flags & VMS_POINTER && field->flags & VMS_ALLOC) {
+        size_t size = vmstate_size(opaque, field);
+        size *= vmstate_n_elems(opaque, field);
+        if (size) {
+            *(void **)ptr = g_malloc(size);
+        }
+    }
+}
+
+int vmstate_load_state(SlirpIStream *f, const VMStateDescription *vmsd,
+                       void *opaque, int version_id)
+{
+    VMStateField *field = vmsd->fields;
+    int ret = 0;
+
+    if (version_id > vmsd->version_id) {
+        g_warning("%s: incoming version_id %d is too new "
+                  "for local version_id %d",
+                  vmsd->name, version_id, vmsd->version_id);
+        return -EINVAL;
+    }
+    if (vmsd->pre_load) {
+        int ret = vmsd->pre_load(opaque);
+        if (ret) {
+            return ret;
+        }
+    }
+    while (field->name) {
+        if ((field->field_exists &&
+             field->field_exists(opaque, version_id)) ||
+            (!field->field_exists &&
+             field->version_id <= version_id)) {
+            void *first_elem = opaque + field->offset;
+            int i, n_elems = vmstate_n_elems(opaque, field);
+            int size = vmstate_size(opaque, field);
+
+            vmstate_handle_alloc(first_elem, field, opaque);
+            if (field->flags & VMS_POINTER) {
+                first_elem = *(void **)first_elem;
+                assert(first_elem || !n_elems || !size);
+            }
+            for (i = 0; i < n_elems; i++) {
+                void *curr_elem = first_elem + size * i;
+
+                if (field->flags & VMS_ARRAY_OF_POINTER) {
+                    curr_elem = *(void **)curr_elem;
+                }
+                if (!curr_elem && size) {
+                    /* if null pointer check placeholder and do not follow */
+                    assert(field->flags & VMS_ARRAY_OF_POINTER);
+                    ret = vmstate_info_nullptr.get(f, curr_elem, size, NULL);
+                } else if (field->flags & VMS_STRUCT) {
+                    ret = vmstate_load_state(f, field->vmsd, curr_elem,
+                                             field->vmsd->version_id);
+                } else if (field->flags & VMS_VSTRUCT) {
+                    ret = vmstate_load_state(f, field->vmsd, curr_elem,
+                                             field->struct_version_id);
+                } else {
+                    ret = field->info->get(f, curr_elem, size, field);
+                }
+                if (ret < 0) {
+                    g_warning("Failed to load %s:%s", vmsd->name,
+                              field->name);
+                    return ret;
+                }
+            }
+        } else if (field->flags & VMS_MUST_EXIST) {
+            g_warning("Input validation failed: %s/%s",
+                      vmsd->name, field->name);
+            return -1;
+        }
+        field++;
+    }
+    if (vmsd->post_load) {
+        ret = vmsd->post_load(opaque, version_id);
+    }
+    return ret;
+}
diff --git a/src/vmstate.h b/src/vmstate.h
new file mode 100644
index 0000000..c99cc02
--- /dev/null
+++ b/src/vmstate.h
@@ -0,0 +1,396 @@
+/*
+ * QEMU migration/snapshot declarations
+ *
+ * Copyright (c) 2009-2011 Red Hat, Inc.
+ *
+ * Original author: Juan Quintela <quintela@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef VMSTATE_H_
+#define VMSTATE_H_
+
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "slirp.h"
+#include "stream.h"
+
+#define stringify(s) tostring(s)
+#define tostring(s) #s
+
+typedef struct VMStateInfo VMStateInfo;
+typedef struct VMStateDescription VMStateDescription;
+typedef struct VMStateField VMStateField;
+
+int vmstate_save_state(SlirpOStream *f, const VMStateDescription *vmsd,
+                       void *opaque);
+int vmstate_load_state(SlirpIStream *f, const VMStateDescription *vmsd,
+                       void *opaque, int version_id);
+
+/* VMStateInfo allows customized migration of objects that don't fit in
+ * any category in VMStateFlags. Additional information is always passed
+ * into get and put in terms of field and vmdesc parameters. However
+ * these two parameters should only be used in cases when customized
+ * handling is needed, such as QTAILQ. For primitive data types such as
+ * integer, field and vmdesc parameters should be ignored inside get/put.
+ */
+struct VMStateInfo {
+    const char *name;
+    int (*get)(SlirpIStream *f, void *pv, size_t size, VMStateField *field);
+    int (*put)(SlirpOStream *f, void *pv, size_t size, VMStateField *field);
+};
+
+enum VMStateFlags {
+    /* Ignored */
+    VMS_SINGLE           = 0x001,
+
+    /* The struct member at opaque + VMStateField.offset is a pointer
+     * to the actual field (e.g. struct a { uint8_t *b;
+     * }). Dereference the pointer before using it as basis for
+     * further pointer arithmetic (see e.g. VMS_ARRAY). Does not
+     * affect the meaning of VMStateField.num_offset or
+     * VMStateField.size_offset; see VMS_VARRAY* and VMS_VBUFFER for
+     * those. */
+    VMS_POINTER          = 0x002,
+
+    /* The field is an array of fixed size. VMStateField.num contains
+     * the number of entries in the array. The size of each entry is
+     * given by VMStateField.size and / or opaque +
+     * VMStateField.size_offset; see VMS_VBUFFER and
+     * VMS_MULTIPLY. Each array entry will be processed individually
+     * (VMStateField.info.get()/put() if VMS_STRUCT is not set,
+     * recursion into VMStateField.vmsd if VMS_STRUCT is set). May not
+     * be combined with VMS_VARRAY*. */
+    VMS_ARRAY            = 0x004,
+
+    /* The field is itself a struct, containing one or more
+     * fields. Recurse into VMStateField.vmsd. Most useful in
+     * combination with VMS_ARRAY / VMS_VARRAY*, recursing into each
+     * array entry. */
+    VMS_STRUCT           = 0x008,
+
+    /* The field is an array of variable size. The int32_t at opaque +
+     * VMStateField.num_offset contains the number of entries in the
+     * array. See the VMS_ARRAY description regarding array handling
+     * in general. May not be combined with VMS_ARRAY or any other
+     * VMS_VARRAY*. */
+    VMS_VARRAY_INT32     = 0x010,
+
+    /* Ignored */
+    VMS_BUFFER           = 0x020,
+
+    /* The field is a (fixed-size or variable-size) array of pointers
+     * (e.g. struct a { uint8_t *b[]; }). Dereference each array entry
+     * before using it. Note: Does not imply any one of VMS_ARRAY /
+     * VMS_VARRAY*; these need to be set explicitly. */
+    VMS_ARRAY_OF_POINTER = 0x040,
+
+    /* The field is an array of variable size. The uint16_t at opaque
+     * + VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS)
+     * contains the number of entries in the array. See the VMS_ARRAY
+     * description regarding array handling in general. May not be
+     * combined with VMS_ARRAY or any other VMS_VARRAY*. */
+    VMS_VARRAY_UINT16    = 0x080,
+
+    /* The size of the individual entries (a single array entry if
+     * VMS_ARRAY or any of VMS_VARRAY* are set, or the field itself if
+     * neither is set) is variable (i.e. not known at compile-time),
+     * but the same for all entries. Use the int32_t at opaque +
+     * VMStateField.size_offset (subject to VMS_MULTIPLY) to determine
+     * the size of each (and every) entry. */
+    VMS_VBUFFER          = 0x100,
+
+    /* Multiply the entry size given by the int32_t at opaque +
+     * VMStateField.size_offset (see VMS_VBUFFER description) with
+     * VMStateField.size to determine the number of bytes to be
+     * allocated. Only valid in combination with VMS_VBUFFER. */
+    VMS_MULTIPLY         = 0x200,
+
+    /* The field is an array of variable size. The uint8_t at opaque +
+     * VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS)
+     * contains the number of entries in the array. See the VMS_ARRAY
+     * description regarding array handling in general. May not be
+     * combined with VMS_ARRAY or any other VMS_VARRAY*. */
+    VMS_VARRAY_UINT8     = 0x400,
+
+    /* The field is an array of variable size. The uint32_t at opaque
+     * + VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS)
+     * contains the number of entries in the array. See the VMS_ARRAY
+     * description regarding array handling in general. May not be
+     * combined with VMS_ARRAY or any other VMS_VARRAY*. */
+    VMS_VARRAY_UINT32    = 0x800,
+
+    /* Fail loading the serialised VM state if this field is missing
+     * from the input. */
+    VMS_MUST_EXIST       = 0x1000,
+
+    /* When loading serialised VM state, allocate memory for the
+     * (entire) field. Only valid in combination with
+     * VMS_POINTER. Note: Not all combinations with other flags are
+     * currently supported, e.g. VMS_ALLOC|VMS_ARRAY_OF_POINTER won't
+     * cause the individual entries to be allocated. */
+    VMS_ALLOC            = 0x2000,
+
+    /* Multiply the number of entries given by the integer at opaque +
+     * VMStateField.num_offset (see VMS_VARRAY*) with VMStateField.num
+     * to determine the number of entries in the array. Only valid in
+     * combination with one of VMS_VARRAY*. */
+    VMS_MULTIPLY_ELEMENTS = 0x4000,
+
+    /* A structure field that is like VMS_STRUCT, but uses
+     * VMStateField.struct_version_id to tell which version of the
+     * structure we are referencing to use. */
+    VMS_VSTRUCT           = 0x8000,
+};
+
+struct VMStateField {
+    const char *name;
+    size_t offset;
+    size_t size;
+    size_t start;
+    int num;
+    size_t num_offset;
+    size_t size_offset;
+    const VMStateInfo *info;
+    enum VMStateFlags flags;
+    const VMStateDescription *vmsd;
+    int version_id;
+    int struct_version_id;
+    bool (*field_exists)(void *opaque, int version_id);
+};
+
+struct VMStateDescription {
+    const char *name;
+    int version_id;
+    int (*pre_load)(void *opaque);
+    int (*post_load)(void *opaque, int version_id);
+    int (*pre_save)(void *opaque);
+    VMStateField *fields;
+};
+
+
+extern const VMStateInfo vmstate_info_int16;
+extern const VMStateInfo vmstate_info_int32;
+extern const VMStateInfo vmstate_info_uint8;
+extern const VMStateInfo vmstate_info_uint16;
+extern const VMStateInfo vmstate_info_uint32;
+
+/** Put this in the stream when migrating a null pointer.*/
+#define VMS_NULLPTR_MARKER (0x30U) /* '0' */
+extern const VMStateInfo vmstate_info_nullptr;
+
+extern const VMStateInfo vmstate_info_buffer;
+extern const VMStateInfo vmstate_info_tmp;
+
+#define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0)
+#define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0)
+#define typeof_field(type, field) typeof(((type *)0)->field)
+#define type_check(t1,t2) ((t1*)0 - (t2*)0)
+
+#define vmstate_offset_value(_state, _field, _type)                  \
+    (offsetof(_state, _field) +                                      \
+     type_check(_type, typeof_field(_state, _field)))
+
+#define vmstate_offset_pointer(_state, _field, _type)                \
+    (offsetof(_state, _field) +                                      \
+     type_check_pointer(_type, typeof_field(_state, _field)))
+
+#define vmstate_offset_array(_state, _field, _type, _num)            \
+    (offsetof(_state, _field) +                                      \
+     type_check_array(_type, typeof_field(_state, _field), _num))
+
+#define vmstate_offset_buffer(_state, _field)                        \
+    vmstate_offset_array(_state, _field, uint8_t,                    \
+                         sizeof(typeof_field(_state, _field)))
+
+/* In the macros below, if there is a _version, that means the macro's
+ * field will be processed only if the version being received is >=
+ * the _version specified.  In general, if you add a new field, you
+ * would increment the structure's version and put that version
+ * number into the new field so it would only be processed with the
+ * new version.
+ *
+ * In particular, for VMSTATE_STRUCT() and friends the _version does
+ * *NOT* pick the version of the sub-structure.  It works just as
+ * specified above.  The version of the top-level structure received
+ * is passed down to all sub-structures.  This means that the
+ * sub-structures must have version that are compatible with all the
+ * structures that use them.
+ *
+ * If you want to specify the version of the sub-structure, use
+ * VMSTATE_VSTRUCT(), which allows the specific sub-structure version
+ * to be directly specified.
+ */
+
+#define VMSTATE_SINGLE_TEST(_field, _state, _test, _version, _info, _type) { \
+    .name         = (stringify(_field)),                             \
+    .version_id   = (_version),                                      \
+    .field_exists = (_test),                                         \
+    .size         = sizeof(_type),                                   \
+    .info         = &(_info),                                        \
+    .flags        = VMS_SINGLE,                                      \
+    .offset       = vmstate_offset_value(_state, _field, _type),     \
+}
+
+#define VMSTATE_ARRAY(_field, _state, _num, _version, _info, _type) {\
+    .name       = (stringify(_field)),                               \
+    .version_id = (_version),                                        \
+    .num        = (_num),                                            \
+    .info       = &(_info),                                          \
+    .size       = sizeof(_type),                                     \
+    .flags      = VMS_ARRAY,                                         \
+    .offset     = vmstate_offset_array(_state, _field, _type, _num), \
+}
+
+#define VMSTATE_STRUCT_TEST(_field, _state, _test, _version, _vmsd, _type) { \
+    .name         = (stringify(_field)),                             \
+    .version_id   = (_version),                                      \
+    .field_exists = (_test),                                         \
+    .vmsd         = &(_vmsd),                                        \
+    .size         = sizeof(_type),                                   \
+    .flags        = VMS_STRUCT,                                      \
+    .offset       = vmstate_offset_value(_state, _field, _type),     \
+}
+
+#define VMSTATE_STRUCT_POINTER_V(_field, _state, _version, _vmsd, _type) { \
+    .name         = (stringify(_field)),                             \
+    .version_id   = (_version),                                        \
+    .vmsd         = &(_vmsd),                                        \
+    .size         = sizeof(_type *),                                 \
+    .flags        = VMS_STRUCT|VMS_POINTER,                          \
+    .offset       = vmstate_offset_pointer(_state, _field, _type),   \
+}
+
+#define VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, _test, _version, _vmsd, _type) { \
+    .name         = (stringify(_field)),                             \
+    .num          = (_num),                                          \
+    .field_exists = (_test),                                         \
+    .version_id   = (_version),                                      \
+    .vmsd         = &(_vmsd),                                        \
+    .size         = sizeof(_type),                                   \
+    .flags        = VMS_STRUCT|VMS_ARRAY,                            \
+    .offset       = vmstate_offset_array(_state, _field, _type, _num),\
+}
+
+#define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \
+    .name         = (stringify(_field)),                             \
+    .version_id   = (_version),                                      \
+    .field_exists = (_test),                                         \
+    .size         = (_size - _start),                                \
+    .info         = &vmstate_info_buffer,                            \
+    .flags        = VMS_BUFFER,                                      \
+    .offset       = vmstate_offset_buffer(_state, _field) + _start,  \
+}
+
+#define VMSTATE_VBUFFER_UINT32(_field, _state, _version, _test, _field_size) { \
+    .name         = (stringify(_field)),                             \
+    .version_id   = (_version),                                      \
+    .field_exists = (_test),                                         \
+    .size_offset  = vmstate_offset_value(_state, _field_size, uint32_t),\
+    .info         = &vmstate_info_buffer,                            \
+    .flags        = VMS_VBUFFER|VMS_POINTER,                         \
+    .offset       = offsetof(_state, _field),                        \
+}
+
+#define QEMU_BUILD_BUG_ON_STRUCT(x)             \
+    struct {                                    \
+        int:(x) ? -1 : 1;                       \
+    }
+
+#define QEMU_BUILD_BUG_ON_ZERO(x) (sizeof(QEMU_BUILD_BUG_ON_STRUCT(x)) - \
+                                   sizeof(QEMU_BUILD_BUG_ON_STRUCT(x)))
+
+/* Allocate a temporary of type 'tmp_type', set tmp->parent to _state
+ * and execute the vmsd on the temporary.  Note that we're working with
+ * the whole of _state here, not a field within it.
+ * We compile time check that:
+ *    That _tmp_type contains a 'parent' member that's a pointer to the
+ *        '_state' type
+ *    That the pointer is right at the start of _tmp_type.
+ */
+#define VMSTATE_WITH_TMP(_state, _tmp_type, _vmsd) {                 \
+    .name         = "tmp",                                           \
+    .size         = sizeof(_tmp_type) +                              \
+                    QEMU_BUILD_BUG_ON_ZERO(offsetof(_tmp_type, parent) != 0) + \
+                    type_check_pointer(_state,                       \
+                        typeof_field(_tmp_type, parent)),            \
+    .vmsd         = &(_vmsd),                                        \
+    .info         = &vmstate_info_tmp,                               \
+}
+
+#define VMSTATE_SINGLE(_field, _state, _version, _info, _type)          \
+    VMSTATE_SINGLE_TEST(_field, _state, NULL, _version, _info, _type)
+
+#define VMSTATE_STRUCT(_field, _state, _version, _vmsd, _type)        \
+    VMSTATE_STRUCT_TEST(_field, _state, NULL, _version, _vmsd, _type)
+
+#define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type)          \
+    VMSTATE_STRUCT_POINTER_V(_field, _state, 0, _vmsd, _type)
+
+#define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) \
+    VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version,   \
+            _vmsd, _type)
+
+#define VMSTATE_INT16_V(_f, _s, _v)                                   \
+    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int16, int16_t)
+#define VMSTATE_INT32_V(_f, _s, _v)                                   \
+    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int32, int32_t)
+
+#define VMSTATE_UINT8_V(_f, _s, _v)                                   \
+    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint8, uint8_t)
+#define VMSTATE_UINT16_V(_f, _s, _v)                                  \
+    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16, uint16_t)
+#define VMSTATE_UINT32_V(_f, _s, _v)                                  \
+    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint32, uint32_t)
+
+#define VMSTATE_INT16(_f, _s)                                         \
+    VMSTATE_INT16_V(_f, _s, 0)
+#define VMSTATE_INT32(_f, _s)                                         \
+    VMSTATE_INT32_V(_f, _s, 0)
+
+#define VMSTATE_UINT8(_f, _s)                                         \
+    VMSTATE_UINT8_V(_f, _s, 0)
+#define VMSTATE_UINT16(_f, _s)                                        \
+    VMSTATE_UINT16_V(_f, _s, 0)
+#define VMSTATE_UINT32(_f, _s)                                        \
+    VMSTATE_UINT32_V(_f, _s, 0)
+
+#define VMSTATE_UINT16_TEST(_f, _s, _t)                               \
+    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t)
+
+#define VMSTATE_UINT32_TEST(_f, _s, _t)                                  \
+    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint32, uint32_t)
+
+#define VMSTATE_INT16_ARRAY_V(_f, _s, _n, _v)                         \
+    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int16, int16_t)
+
+#define VMSTATE_INT16_ARRAY(_f, _s, _n)                               \
+    VMSTATE_INT16_ARRAY_V(_f, _s, _n, 0)
+
+#define VMSTATE_BUFFER_V(_f, _s, _v)                                    \
+    VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, 0, sizeof(typeof_field(_s, _f)))
+
+#define VMSTATE_BUFFER(_f, _s)                                        \
+    VMSTATE_BUFFER_V(_f, _s, 0)
+
+#define VMSTATE_END_OF_LIST()                                         \
+    {}
+
+#endif
-- 
2.21.0.rc0.1.g036caf7885

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH slirp 5/5] Add .gitlab-ci.yml
  2019-02-08 18:11 [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project marcandre.lureau
                   ` (3 preceding siblings ...)
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading marcandre.lureau
@ 2019-02-08 18:11 ` marcandre.lureau
  2019-02-09 11:33 ` [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project Samuel Thibault
  2019-02-10 21:35 ` Peter Maydell
  6 siblings, 0 replies; 17+ messages in thread
From: marcandre.lureau @ 2019-02-08 18:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: samuel.thibault, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 .gitlab-ci.yml | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 .gitlab-ci.yml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..71fda28
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,20 @@
+image: fedora:latest
+
+variables:
+  DEPS: meson ninja-build
+        gcc pkg-config glib2-devel
+        mingw64-gcc mingw64-pkg-config mingw64-glib2
+
+before_script:
+  - dnf install -y $DEPS
+
+build:
+  script:
+    - meson build || (cat build/meson-logs/meson-log.txt && exit 1)
+    - ninja -C build
+    - (cd build && meson test) || (cat build/meson-logs/testlog.txt && exit 1)
+
+build-mingw64:
+  script:
+    - (mkdir buildw && cd buildw && mingw64-meson) || (cat buildw/meson-logs/meson-log.txt && exit 1)
+    - ninja -C buildw
-- 
2.21.0.rc0.1.g036caf7885

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project
  2019-02-08 18:11 [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project marcandre.lureau
                   ` (4 preceding siblings ...)
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 5/5] Add .gitlab-ci.yml marcandre.lureau
@ 2019-02-09 11:33 ` Samuel Thibault
  2019-02-10 21:35 ` Peter Maydell
  6 siblings, 0 replies; 17+ messages in thread
From: Samuel Thibault @ 2019-02-09 11:33 UTC (permalink / raw)
  To: marcandre.lureau; +Cc: qemu-devel

Hello,

marcandre.lureau@redhat.com, le ven. 08 févr. 2019 19:11:17 +0100, a ecrit:
> Where should this new project be hosted? (I suggest some gitlab
> instance, because of the nice ui/CI/issues/milestone...)

I'd say freedesktop's gitlab would make a lot of sense yes, I'd go for
it https://www.freedesktop.org/wiki/NewProject/

Samuel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading
  2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading marcandre.lureau
@ 2019-02-09 11:40   ` Samuel Thibault
  2019-02-09 13:09     ` Marc-André Lureau
  0 siblings, 1 reply; 17+ messages in thread
From: Samuel Thibault @ 2019-02-09 11:40 UTC (permalink / raw)
  To: marcandre.lureau; +Cc: qemu-devel

marcandre.lureau@redhat.com, le ven. 08 févr. 2019 19:11:21 +0100, a ecrit:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Based on qemu vmstate serialization code. At this point it should
> produce the same result. However, with future state versions, slirp
> should be free to change its format, by bumping the reported state
> version.

Mmm, then qemu needs to be taught to call slirp_state_save/load/version?

Samuel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading
  2019-02-09 11:40   ` Samuel Thibault
@ 2019-02-09 13:09     ` Marc-André Lureau
  2019-02-09 13:12       ` Samuel Thibault
  0 siblings, 1 reply; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-09 13:09 UTC (permalink / raw)
  To: Samuel Thibault; +Cc: qemu-devel

Hi

On Sat, Feb 9, 2019 at 12:40 PM Samuel Thibault <samuel.thibault@gnu.org> wrote:
>
> marcandre.lureau@redhat.com, le ven. 08 févr. 2019 19:11:21 +0100, a ecrit:
> > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> >
> > Based on qemu vmstate serialization code. At this point it should
> > produce the same result. However, with future state versions, slirp
> > should be free to change its format, by bumping the reported state
> > version.
>
> Mmm, then qemu needs to be taught to call slirp_state_save/load/version?

Yes, see "[Qemu-devel] [PATCH 1/1] RFC: net/slirp: link with libslirp"

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading
  2019-02-09 13:09     ` Marc-André Lureau
@ 2019-02-09 13:12       ` Samuel Thibault
  2019-02-09 13:16         ` Marc-André Lureau
  0 siblings, 1 reply; 17+ messages in thread
From: Samuel Thibault @ 2019-02-09 13:12 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau, le sam. 09 févr. 2019 14:09:02 +0100, a ecrit:
> On Sat, Feb 9, 2019 at 12:40 PM Samuel Thibault <samuel.thibault@gnu.org> wrote:
> >
> > marcandre.lureau@redhat.com, le ven. 08 févr. 2019 19:11:21 +0100, a ecrit:
> > > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> > >
> > > Based on qemu vmstate serialization code. At this point it should
> > > produce the same result. However, with future state versions, slirp
> > > should be free to change its format, by bumping the reported state
> > > version.
> >
> > Mmm, then qemu needs to be taught to call slirp_state_save/load/version?
> 
> Yes, see "[Qemu-devel] [PATCH 1/1] RFC: net/slirp: link with libslirp"

Ah, I did have a look there but somehow missed it because burried within
file removals :)

Samuel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading
  2019-02-09 13:12       ` Samuel Thibault
@ 2019-02-09 13:16         ` Marc-André Lureau
  2019-02-09 13:19           ` Samuel Thibault
  0 siblings, 1 reply; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-09 13:16 UTC (permalink / raw)
  To: Samuel Thibault; +Cc: qemu-devel

Hi

On Sat, Feb 9, 2019 at 2:13 PM Samuel Thibault <samuel.thibault@gnu.org> wrote:
>
> Marc-André Lureau, le sam. 09 févr. 2019 14:09:02 +0100, a ecrit:
> > On Sat, Feb 9, 2019 at 12:40 PM Samuel Thibault <samuel.thibault@gnu.org> wrote:
> > >
> > > marcandre.lureau@redhat.com, le ven. 08 févr. 2019 19:11:21 +0100, a ecrit:
> > > > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> > > >
> > > > Based on qemu vmstate serialization code. At this point it should
> > > > produce the same result. However, with future state versions, slirp
> > > > should be free to change its format, by bumping the reported state
> > > > version.
> > >
> > > Mmm, then qemu needs to be taught to call slirp_state_save/load/version?
> >
> > Yes, see "[Qemu-devel] [PATCH 1/1] RFC: net/slirp: link with libslirp"
>
> Ah, I did have a look there but somehow missed it because burried within
> file removals :)
>

Indeed, the original patch series was splited in 2, but I thought as
an RFC it was easier to send a single patch. Bad choice I suppose.



-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading
  2019-02-09 13:16         ` Marc-André Lureau
@ 2019-02-09 13:19           ` Samuel Thibault
  0 siblings, 0 replies; 17+ messages in thread
From: Samuel Thibault @ 2019-02-09 13:19 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau, le sam. 09 févr. 2019 14:16:53 +0100, a ecrit:
> Hi
> 
> On Sat, Feb 9, 2019 at 2:13 PM Samuel Thibault <samuel.thibault@gnu.org> wrote:
> >
> > Marc-André Lureau, le sam. 09 févr. 2019 14:09:02 +0100, a ecrit:
> > > On Sat, Feb 9, 2019 at 12:40 PM Samuel Thibault <samuel.thibault@gnu.org> wrote:
> > > >
> > > > marcandre.lureau@redhat.com, le ven. 08 févr. 2019 19:11:21 +0100, a ecrit:
> > > > > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> > > > >
> > > > > Based on qemu vmstate serialization code. At this point it should
> > > > > produce the same result. However, with future state versions, slirp
> > > > > should be free to change its format, by bumping the reported state
> > > > > version.
> > > >
> > > > Mmm, then qemu needs to be taught to call slirp_state_save/load/version?
> > >
> > > Yes, see "[Qemu-devel] [PATCH 1/1] RFC: net/slirp: link with libslirp"
> >
> > Ah, I did have a look there but somehow missed it because burried within
> > file removals :)
> >
> 
> Indeed, the original patch series was splited in 2, but I thought as
> an RFC it was easier to send a single patch. Bad choice I suppose.

No, it's fine enough, it's just the file ordering in the patch which
posed problem :)

Samuel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project
  2019-02-08 18:11 [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project marcandre.lureau
                   ` (5 preceding siblings ...)
  2019-02-09 11:33 ` [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project Samuel Thibault
@ 2019-02-10 21:35 ` Peter Maydell
  2019-02-10 21:38   ` Samuel Thibault
  6 siblings, 1 reply; 17+ messages in thread
From: Peter Maydell @ 2019-02-10 21:35 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: QEMU Developers, Samuel Thibault

On Fri, 8 Feb 2019 at 20:58, <marcandre.lureau@redhat.com> wrote:
> As discussed earlier in "[PATCH for-3.2 00/41] RFC: slirp: make it
> again a standalone project" and other threads, it would be useful to
> make slirp a separate project (the submodule approach was discarded)
> for various projects to share.

> The following patches add meson build system (if necessary for older
> distros, autotools could be added - however I believe python & ninja
> are generally available on the QEMU supported platforms)

Do you really need to make QEMU add an extra build dependency
just to use a different build system? From my end that seems like
just unnecessary pain for us (we're going to need to ship libslirp
as a submodule for a while until it's been around long enough to
be in stable distros, so its build dependencies will get added
to QEMU's build deps).

Is the standalone project going to provide a shared library
or just a .a static library? (ie are you confident enough in
the long-term stability of your API and ABI to do the shared
library yet? the prudent approach might be to start with just
the .a...)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project
  2019-02-10 21:35 ` Peter Maydell
@ 2019-02-10 21:38   ` Samuel Thibault
  2019-02-10 21:42     ` Peter Maydell
  0 siblings, 1 reply; 17+ messages in thread
From: Samuel Thibault @ 2019-02-10 21:38 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Marc-André Lureau, QEMU Developers

Hello,

Peter Maydell, le dim. 10 févr. 2019 21:35:37 +0000, a ecrit:
> On Fri, 8 Feb 2019 at 20:58, <marcandre.lureau@redhat.com> wrote:
> > As discussed earlier in "[PATCH for-3.2 00/41] RFC: slirp: make it
> > again a standalone project" and other threads, it would be useful to
> > make slirp a separate project (the submodule approach was discarded)
> > for various projects to share.
> 
> > The following patches add meson build system (if necessary for older
> > distros, autotools could be added - however I believe python & ninja
> > are generally available on the QEMU supported platforms)
> 
> Do you really need to make QEMU add an extra build dependency
> just to use a different build system?

AIUI, this patches series is meant for the slirp repository, not the
QEMU repository. I.e. just to show how it'll look like, until a project
it settled somewhere and the discussion can happen there.

Samuel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project
  2019-02-10 21:38   ` Samuel Thibault
@ 2019-02-10 21:42     ` Peter Maydell
  2019-02-10 22:03       ` Marc-André Lureau
  0 siblings, 1 reply; 17+ messages in thread
From: Peter Maydell @ 2019-02-10 21:42 UTC (permalink / raw)
  To: Samuel Thibault; +Cc: Marc-André Lureau, QEMU Developers

On Sun, 10 Feb 2019 at 21:38, Samuel Thibault <samuel.thibault@gnu.org> wrote:
>
> Hello,
>
> Peter Maydell, le dim. 10 févr. 2019 21:35:37 +0000, a ecrit:
> > On Fri, 8 Feb 2019 at 20:58, <marcandre.lureau@redhat.com> wrote:
> > > As discussed earlier in "[PATCH for-3.2 00/41] RFC: slirp: make it
> > > again a standalone project" and other threads, it would be useful to
> > > make slirp a separate project (the submodule approach was discarded)
> > > for various projects to share.
> >
> > > The following patches add meson build system (if necessary for older
> > > distros, autotools could be added - however I believe python & ninja
> > > are generally available on the QEMU supported platforms)
> >
> > Do you really need to make QEMU add an extra build dependency
> > just to use a different build system?
>
> AIUI, this patches series is meant for the slirp repository, not the
> QEMU repository. I.e. just to show how it'll look like, until a project
> it settled somewhere and the discussion can happen there.

Yes, but we're going to be pulling it in as a submodule,
so a split out libslirp in its own repository with extra
build dependencies is harder to work with than one without.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project
  2019-02-10 21:42     ` Peter Maydell
@ 2019-02-10 22:03       ` Marc-André Lureau
  2019-02-10 22:07         ` Peter Maydell
  0 siblings, 1 reply; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-10 22:03 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Samuel Thibault, QEMU Developers, Daniel P. Berrange

Hi

On Sun, Feb 10, 2019 at 10:42 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Sun, 10 Feb 2019 at 21:38, Samuel Thibault <samuel.thibault@gnu.org> wrote:
> >
> > Hello,
> >
> > Peter Maydell, le dim. 10 févr. 2019 21:35:37 +0000, a ecrit:
> > > On Fri, 8 Feb 2019 at 20:58, <marcandre.lureau@redhat.com> wrote:
> > > > As discussed earlier in "[PATCH for-3.2 00/41] RFC: slirp: make it
> > > > again a standalone project" and other threads, it would be useful to
> > > > make slirp a separate project (the submodule approach was discarded)
> > > > for various projects to share.
> > >
> > > > The following patches add meson build system (if necessary for older
> > > > distros, autotools could be added - however I believe python & ninja
> > > > are generally available on the QEMU supported platforms)
> > >
> > > Do you really need to make QEMU add an extra build dependency
> > > just to use a different build system?
> >
> > AIUI, this patches series is meant for the slirp repository, not the
> > QEMU repository. I.e. just to show how it'll look like, until a project
> > it settled somewhere and the discussion can happen there.
>
> Yes, but we're going to be pulling it in as a submodule,
> so a split out libslirp in its own repository with extra
> build dependencies is harder to work with than one without.
>

Why do you think it should be a submodule? That's the approach I
proposed first, but Daniel suggested to make it immediately a shared
library if possible.

Regarding the build system, if meson/ninja is problematic for some
distro, we can come up with autotools or plain Make for a while.



-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project
  2019-02-10 22:03       ` Marc-André Lureau
@ 2019-02-10 22:07         ` Peter Maydell
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2019-02-10 22:07 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: Samuel Thibault, QEMU Developers, Daniel P. Berrange

On Sun, 10 Feb 2019 at 22:03, Marc-André Lureau
<marcandre.lureau@gmail.com> wrote:
> Why do you think it should be a submodule? That's the approach I
> proposed first, but Daniel suggested to make it immediately a shared
> library if possible.

It needs to be a submodule because you don't have a time
machine to arrange for it to be an available package in
all the stable versions of the distros we support. As
and when it is packaged in the oldest stable versions we
care about, we can drop the submodule, but submodule is where
we need to start. (This is the same as we did with third
party bits of code like pixman.)

I think immediately going for the shared library (as opposed
to static) is a bit of a bold decision also because it is a
hard commitment to API and ABI compatibility, which previously
has been something the slirp code didn't need to care about at all.

> Regarding the build system, if meson/ninja is problematic for some
> distro, we can come up with autotools or plain Make for a while.

I think plain make would be more convenient. Otherwise
everybody building QEMU needs to install a random extra
build tool.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2019-02-10 22:07 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-02-08 18:11 [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project marcandre.lureau
2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 1/5] Extract slirp/ from qemu repository marcandre.lureau
2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 2/5] build-sys: add a meson build marcandre.lureau
2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 3/5] build-sys: add version tooling marcandre.lureau
2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 4/5] slirp: add state saving/loading marcandre.lureau
2019-02-09 11:40   ` Samuel Thibault
2019-02-09 13:09     ` Marc-André Lureau
2019-02-09 13:12       ` Samuel Thibault
2019-02-09 13:16         ` Marc-André Lureau
2019-02-09 13:19           ` Samuel Thibault
2019-02-08 18:11 ` [Qemu-devel] [PATCH slirp 5/5] Add .gitlab-ci.yml marcandre.lureau
2019-02-09 11:33 ` [Qemu-devel] [PATCH slirp 0/5] Make it a standalone project Samuel Thibault
2019-02-10 21:35 ` Peter Maydell
2019-02-10 21:38   ` Samuel Thibault
2019-02-10 21:42     ` Peter Maydell
2019-02-10 22:03       ` Marc-André Lureau
2019-02-10 22:07         ` Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).