Commit 062e55272e21d45bd8056fb5d8745ec8f22961ff
1 parent
49ec9b40
Add support for vmchannel socket migration (Gleb Natapov)
Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6243 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
227 additions
and
0 deletions
slirp/slirp.c
... | ... | @@ -23,6 +23,7 @@ |
23 | 23 | */ |
24 | 24 | #include "qemu-common.h" |
25 | 25 | #include "slirp.h" |
26 | +#include "hw/hw.h" | |
26 | 27 | |
27 | 28 | /* host address */ |
28 | 29 | struct in_addr our_addr; |
... | ... | @@ -166,6 +167,9 @@ static void slirp_cleanup(void) |
166 | 167 | } |
167 | 168 | #endif |
168 | 169 | |
170 | +static void slirp_state_save(QEMUFile *f, void *opaque); | |
171 | +static int slirp_state_load(QEMUFile *f, void *opaque, int version_id); | |
172 | + | |
169 | 173 | void slirp_init(int restrict, char *special_ip) |
170 | 174 | { |
171 | 175 | // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); |
... | ... | @@ -201,6 +205,7 @@ void slirp_init(int restrict, char *special_ip) |
201 | 205 | inet_aton(slirp_special_ip, &special_addr); |
202 | 206 | alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); |
203 | 207 | getouraddr(); |
208 | + register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL); | |
204 | 209 | } |
205 | 210 | |
206 | 211 | #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) |
... | ... | @@ -809,3 +814,225 @@ void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf, |
809 | 814 | if (ret > 0) |
810 | 815 | tcp_output(sototcpcb(so)); |
811 | 816 | } |
817 | + | |
818 | +static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp) | |
819 | +{ | |
820 | + int i; | |
821 | + | |
822 | + qemu_put_sbe16(f, tp->t_state); | |
823 | + for (i = 0; i < TCPT_NTIMERS; i++) | |
824 | + qemu_put_sbe16(f, tp->t_timer[i]); | |
825 | + qemu_put_sbe16(f, tp->t_rxtshift); | |
826 | + qemu_put_sbe16(f, tp->t_rxtcur); | |
827 | + qemu_put_sbe16(f, tp->t_dupacks); | |
828 | + qemu_put_be16(f, tp->t_maxseg); | |
829 | + qemu_put_sbyte(f, tp->t_force); | |
830 | + qemu_put_be16(f, tp->t_flags); | |
831 | + qemu_put_be32(f, tp->snd_una); | |
832 | + qemu_put_be32(f, tp->snd_nxt); | |
833 | + qemu_put_be32(f, tp->snd_up); | |
834 | + qemu_put_be32(f, tp->snd_wl1); | |
835 | + qemu_put_be32(f, tp->snd_wl2); | |
836 | + qemu_put_be32(f, tp->iss); | |
837 | + qemu_put_be32(f, tp->snd_wnd); | |
838 | + qemu_put_be32(f, tp->rcv_wnd); | |
839 | + qemu_put_be32(f, tp->rcv_nxt); | |
840 | + qemu_put_be32(f, tp->rcv_up); | |
841 | + qemu_put_be32(f, tp->irs); | |
842 | + qemu_put_be32(f, tp->rcv_adv); | |
843 | + qemu_put_be32(f, tp->snd_max); | |
844 | + qemu_put_be32(f, tp->snd_cwnd); | |
845 | + qemu_put_be32(f, tp->snd_ssthresh); | |
846 | + qemu_put_sbe16(f, tp->t_idle); | |
847 | + qemu_put_sbe16(f, tp->t_rtt); | |
848 | + qemu_put_be32(f, tp->t_rtseq); | |
849 | + qemu_put_sbe16(f, tp->t_srtt); | |
850 | + qemu_put_sbe16(f, tp->t_rttvar); | |
851 | + qemu_put_be16(f, tp->t_rttmin); | |
852 | + qemu_put_be32(f, tp->max_sndwnd); | |
853 | + qemu_put_byte(f, tp->t_oobflags); | |
854 | + qemu_put_byte(f, tp->t_iobc); | |
855 | + qemu_put_sbe16(f, tp->t_softerror); | |
856 | + qemu_put_byte(f, tp->snd_scale); | |
857 | + qemu_put_byte(f, tp->rcv_scale); | |
858 | + qemu_put_byte(f, tp->request_r_scale); | |
859 | + qemu_put_byte(f, tp->requested_s_scale); | |
860 | + qemu_put_be32(f, tp->ts_recent); | |
861 | + qemu_put_be32(f, tp->ts_recent_age); | |
862 | + qemu_put_be32(f, tp->last_ack_sent); | |
863 | +} | |
864 | + | |
865 | +static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf) | |
866 | +{ | |
867 | + uint32_t off; | |
868 | + | |
869 | + qemu_put_be32(f, sbuf->sb_cc); | |
870 | + qemu_put_be32(f, sbuf->sb_datalen); | |
871 | + off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data); | |
872 | + qemu_put_sbe32(f, off); | |
873 | + off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data); | |
874 | + qemu_put_sbe32(f, off); | |
875 | + qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen); | |
876 | +} | |
877 | + | |
878 | +static void slirp_socket_save(QEMUFile *f, struct socket *so) | |
879 | +{ | |
880 | + qemu_put_be32(f, so->so_urgc); | |
881 | + qemu_put_be32(f, so->so_faddr.s_addr); | |
882 | + qemu_put_be32(f, so->so_laddr.s_addr); | |
883 | + qemu_put_be16(f, so->so_fport); | |
884 | + qemu_put_be16(f, so->so_lport); | |
885 | + qemu_put_byte(f, so->so_iptos); | |
886 | + qemu_put_byte(f, so->so_emu); | |
887 | + qemu_put_byte(f, so->so_type); | |
888 | + qemu_put_be32(f, so->so_state); | |
889 | + slirp_sbuf_save(f, &so->so_rcv); | |
890 | + slirp_sbuf_save(f, &so->so_snd); | |
891 | + slirp_tcp_save(f, so->so_tcpcb); | |
892 | +} | |
893 | + | |
894 | +static void slirp_state_save(QEMUFile *f, void *opaque) | |
895 | +{ | |
896 | + struct ex_list *ex_ptr; | |
897 | + | |
898 | + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) | |
899 | + if (ex_ptr->ex_pty == 3) { | |
900 | + struct socket *so; | |
901 | + so = slirp_find_ctl_socket(ex_ptr->ex_addr, ntohs(ex_ptr->ex_fport)); | |
902 | + if (!so) | |
903 | + continue; | |
904 | + | |
905 | + qemu_put_byte(f, 42); | |
906 | + slirp_socket_save(f, so); | |
907 | + } | |
908 | + qemu_put_byte(f, 0); | |
909 | +} | |
910 | + | |
911 | +static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp) | |
912 | +{ | |
913 | + int i; | |
914 | + | |
915 | + tp->t_state = qemu_get_sbe16(f); | |
916 | + for (i = 0; i < TCPT_NTIMERS; i++) | |
917 | + tp->t_timer[i] = qemu_get_sbe16(f); | |
918 | + tp->t_rxtshift = qemu_get_sbe16(f); | |
919 | + tp->t_rxtcur = qemu_get_sbe16(f); | |
920 | + tp->t_dupacks = qemu_get_sbe16(f); | |
921 | + tp->t_maxseg = qemu_get_be16(f); | |
922 | + tp->t_force = qemu_get_sbyte(f); | |
923 | + tp->t_flags = qemu_get_be16(f); | |
924 | + tp->snd_una = qemu_get_be32(f); | |
925 | + tp->snd_nxt = qemu_get_be32(f); | |
926 | + tp->snd_up = qemu_get_be32(f); | |
927 | + tp->snd_wl1 = qemu_get_be32(f); | |
928 | + tp->snd_wl2 = qemu_get_be32(f); | |
929 | + tp->iss = qemu_get_be32(f); | |
930 | + tp->snd_wnd = qemu_get_be32(f); | |
931 | + tp->rcv_wnd = qemu_get_be32(f); | |
932 | + tp->rcv_nxt = qemu_get_be32(f); | |
933 | + tp->rcv_up = qemu_get_be32(f); | |
934 | + tp->irs = qemu_get_be32(f); | |
935 | + tp->rcv_adv = qemu_get_be32(f); | |
936 | + tp->snd_max = qemu_get_be32(f); | |
937 | + tp->snd_cwnd = qemu_get_be32(f); | |
938 | + tp->snd_ssthresh = qemu_get_be32(f); | |
939 | + tp->t_idle = qemu_get_sbe16(f); | |
940 | + tp->t_rtt = qemu_get_sbe16(f); | |
941 | + tp->t_rtseq = qemu_get_be32(f); | |
942 | + tp->t_srtt = qemu_get_sbe16(f); | |
943 | + tp->t_rttvar = qemu_get_sbe16(f); | |
944 | + tp->t_rttmin = qemu_get_be16(f); | |
945 | + tp->max_sndwnd = qemu_get_be32(f); | |
946 | + tp->t_oobflags = qemu_get_byte(f); | |
947 | + tp->t_iobc = qemu_get_byte(f); | |
948 | + tp->t_softerror = qemu_get_sbe16(f); | |
949 | + tp->snd_scale = qemu_get_byte(f); | |
950 | + tp->rcv_scale = qemu_get_byte(f); | |
951 | + tp->request_r_scale = qemu_get_byte(f); | |
952 | + tp->requested_s_scale = qemu_get_byte(f); | |
953 | + tp->ts_recent = qemu_get_be32(f); | |
954 | + tp->ts_recent_age = qemu_get_be32(f); | |
955 | + tp->last_ack_sent = qemu_get_be32(f); | |
956 | + tcp_template(tp); | |
957 | +} | |
958 | + | |
959 | +static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf) | |
960 | +{ | |
961 | + uint32_t off, sb_cc, sb_datalen; | |
962 | + | |
963 | + sb_cc = qemu_get_be32(f); | |
964 | + sb_datalen = qemu_get_be32(f); | |
965 | + | |
966 | + sbreserve(sbuf, sb_datalen); | |
967 | + | |
968 | + if (sbuf->sb_datalen != sb_datalen) | |
969 | + return -ENOMEM; | |
970 | + | |
971 | + sbuf->sb_cc = sb_cc; | |
972 | + | |
973 | + off = qemu_get_sbe32(f); | |
974 | + sbuf->sb_wptr = sbuf->sb_data + off; | |
975 | + off = qemu_get_sbe32(f); | |
976 | + sbuf->sb_rptr = sbuf->sb_data + off; | |
977 | + qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen); | |
978 | + | |
979 | + return 0; | |
980 | +} | |
981 | + | |
982 | +static int slirp_socket_load(QEMUFile *f, struct socket *so) | |
983 | +{ | |
984 | + if (tcp_attach(so) < 0) | |
985 | + return -ENOMEM; | |
986 | + | |
987 | + so->so_urgc = qemu_get_be32(f); | |
988 | + so->so_faddr.s_addr = qemu_get_be32(f); | |
989 | + so->so_laddr.s_addr = qemu_get_be32(f); | |
990 | + so->so_fport = qemu_get_be16(f); | |
991 | + so->so_lport = qemu_get_be16(f); | |
992 | + so->so_iptos = qemu_get_byte(f); | |
993 | + so->so_emu = qemu_get_byte(f); | |
994 | + so->so_type = qemu_get_byte(f); | |
995 | + so->so_state = qemu_get_be32(f); | |
996 | + if (slirp_sbuf_load(f, &so->so_rcv) < 0) | |
997 | + return -ENOMEM; | |
998 | + if (slirp_sbuf_load(f, &so->so_snd) < 0) | |
999 | + return -ENOMEM; | |
1000 | + slirp_tcp_load(f, so->so_tcpcb); | |
1001 | + | |
1002 | + return 0; | |
1003 | +} | |
1004 | + | |
1005 | +static int slirp_state_load(QEMUFile *f, void *opaque, int version_id) | |
1006 | +{ | |
1007 | + struct ex_list *ex_ptr; | |
1008 | + int r; | |
1009 | + | |
1010 | + while ((r = qemu_get_byte(f))) { | |
1011 | + int ret; | |
1012 | + struct socket *so = socreate(); | |
1013 | + | |
1014 | + if (!so) | |
1015 | + return -ENOMEM; | |
1016 | + | |
1017 | + ret = slirp_socket_load(f, so); | |
1018 | + | |
1019 | + if (ret < 0) | |
1020 | + return ret; | |
1021 | + | |
1022 | + if ((so->so_faddr.s_addr & htonl(0xffffff00)) != special_addr.s_addr) | |
1023 | + return -EINVAL; | |
1024 | + | |
1025 | + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) | |
1026 | + if (ex_ptr->ex_pty == 3 && | |
1027 | + (ntohl(so->so_faddr.s_addr) & 0xff) == ex_ptr->ex_addr && | |
1028 | + so->so_fport == ex_ptr->ex_fport) | |
1029 | + break; | |
1030 | + | |
1031 | + if (!ex_ptr) | |
1032 | + return -EINVAL; | |
1033 | + | |
1034 | + so->extra = ex_ptr->ex_exec; | |
1035 | + } | |
1036 | + | |
1037 | + return 0; | |
1038 | +} | ... | ... |