Commit 062e55272e21d45bd8056fb5d8745ec8f22961ff

Authored by aliguori
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 +}
... ...