QEMU是一套开源的模拟处理器,在GNU/Linux平台上使用广泛,本文我们将通过网络连接QEMU的监控器monitor.
1.QEMU monitor支持远程telnet访问:
[root@kvm-host ~]# qemu-system-x86_64 -enable-kvm -smp 2 -m 1024 vm2.img -monitor telnet:10.1.77.82:4444,server,nowait
关于这里-monitor的选项,做如下说明:
- tcp–rawtcpsockets#下面第2点,我的举例是RAWTCPsocket
- telnet–thetelnetprotocolisusedinsteadofrawtcpsockets.ThisisthepreferredoptionovertcpasyoucanbreakoutofthemonitorusingCtrl-]thentypingquit.Youcan’tbreakoutofthemonitorlikethisafterconnectingwiththerawsocketoption
- 10.1.77.82–Listenonthishost/IPonly.Youcanuse127.0.0.1ifyouwanttoonlyallowconnectionslocally.Ifyouwanttolistenonanyipaddressontheserver,justleavethisblanksoyouendupwithtwoconsecutivecolonsie“::”.
- 4444–portnumbertolistenon.
- server–listeninginservermode
- nowait–qemuwillwaitforaclientsocketapplicationtoconnecttotheportbeforecontinuingunlessthisoptionisused.Inmostcasesyou’llwanttousethenowaitoption.
通过telnet连接到远程的QEMU monitor上,代码如下:
- jay@jay-linux:~$telnet10.1.77.824444
- Trying10.1.77.82...
- Connectedto10.1.77.82.
- Escapecharacteris'^]'.
- QEMU1.7.50monitor-type'help'formoreinformation
- (qemu)infokvm
- kvmsupport:enabled
- (qemu)infostatus
- VMstatus:running
- (qemu)helpmigrate
- migrate[-d][-b][-i]uri--migratetoURI(using-dtonotwaitforcompletion)
- -bformigrationwithoutsharedstoragewithfullcopyofdisk--phpfensi.com
- -iformigrationwithoutsharedstoragewithincrementalcopyofdisk(baseimagesharedbetweensrcanddestination)
- (qemu)ctrl+](断掉telnet连接)
- telnet>quit(退出telnet)
- Connectionclosed.
2.QEMU monitor支持RAW socket的远程访问,代码如下:
[root@kvm-host ~]# qemu-system-x86_64 -enable-kvm -smp 2 -m 1024 vm2.img -monitor tcp:10.1.77.82:4444,server,nowait
可以使用netcat去连接这个socket,代码如下:
- jay@jay-linux:~$nc10.1.77.824444
- QEMU1.7.50monitor-type'help'formoreinformation
- (qemu)infokvm
- infokvm
- kvmsupport:enabled
- (qemu)^C
自己写了个socket程序示例如连接monitor,效果如下:
- jay@jay-linux:~/workspace/c-cpp.git/c2013$./monitor_client
- sendingcommand'infokvm
- 'toremoteqemumonitor
- outputfromqemumonitor:QEMU1.7.50monitor-type'help'formoreinformation
- ??,?
- outputfromqemumonitor:(qemu)infokvm
- kvmsupport:enabled
- (qemu)
上面那个连接monitor的socket程序示例为:
https://github.com/smilejay/c-cpp/blob/master/c2013/socket_qemu_monitor_client.c
代码如下:
- /*socket_qemu_monitor_clinet.c
- *ConnecttoremoteQEMUmonitorsocketandsendingacommandtothemonitor.
- *author:Jay<smile665@gmail.com>
- */
- #include<sys/types.h>
- #include<sys/socket.h>
- #include<stdio.h>
- #include<netinet/in.h>
- #include<arpa/inet.h>
- #include<unistd.h>
- #include<stdlib.h>
- #include<string.h>
- intmain(intargc,char*argv[])
- {
- intsockfd;
- intlen;
- structsockaddr_inaddress;
- intresult;
- char*cmd="infokvmn";
- charoutput[200];
- /*Createasocketfortheclient.*/
- sockfd=socket(AF_INET,SOCK_STREAM,0);
- /*Namethesocket,asagreedwiththeserver.*/
- address.sin_family=AF_INET;
- address.sin_addr.s_addr=inet_addr("10.1.77.82");
- address.sin_port=htons(4444);
- len=sizeof(address);
- /*Nowconnectoursockettotheserver'ssocket.*/
- result=connect(sockfd,(structsockaddr*)&address,len);
- if(result==-1){
- perror("oops:socketconnetionfailed.");
- exit(1);//phpfensi.com
- }
- /*Wecannowread/writeviasockfd.*/
- printf("sendingcommand'%s'toremoteqemumonitorn",cmd);
- write(sockfd,cmd,strlen(cmd));
- read(sockfd,output,sizeof(output));
- printf("outputfromqemumonitor:%sn",output);
- read(sockfd,output,sizeof(output));
- printf("outputfromqemumonitor:%sn",output);
- close(sockfd);
- exit(0);
- }