{"id":207,"date":"2018-05-31T07:07:48","date_gmt":"2018-05-31T07:07:48","guid":{"rendered":"http:\/\/www.luo666.com\/?p=207"},"modified":"2019-02-16T12:50:03","modified_gmt":"2019-02-16T12:50:03","slug":"207","status":"publish","type":"post","link":"http:\/\/www.luo666.com\/?p=207","title":{"rendered":"libvirt \u5411qemu\u4f20\u6587\u4ef6\u63cf\u8ff0\u7b26"},"content":{"rendered":"<div>libvirt\u521b\u5efa\u7684qemu\u8fdb\u7a0b\u91cc\u9762\u6709\u4e00\u4e9bfd\u7684\u53c2\u6570\uff0c\u8fd9\u4e9b\u6587\u4ef6\u662flibvirt\u5e2eqemu\u6253\u5f00\u7684\u4e00\u4e9b\u8bbe\u5907\u6587\u4ef6\u53e5\u67c4\u7b49\uff0c\u6bd4\u5982\uff1a<\/div>\n<div>qemu &#8230; -netdev tap,fd=24,id=hostnet1,vhost=on,vhostfd=25<\/div>\n<div><\/div>\n<div>\u56e0\u4e3a\u9700\u8981libvirt\u5e2e\u5fd9\u5148\u914d\u7f6e\u597d\u540e\u7aef\u4ee5\u53ca\u5904\u4e8e\u5b89\u5168\u8003\u8651\uff1b\u4f46\u662fqemu\u8d77\u6765\u5c31\u662f\u53e6\u5916\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u7ed9\u4e2afd\u53f7\u5c31\u80fd\u76f4\u63a5\u7528\u4e86\u5417\uff0c\u663e\u7136\u4e0d\u662f\uff0c\u4e0b\u9762\u4ece\u4ee3\u7801\u89d2\u5ea6\u5206\u6790\u4e0b<\/div>\n<p><!--more--><\/p>\n<div>[libvirt]<\/div>\n<div>qemuOpenVhostNet<\/div>\n<div>-qemuMonitorPassDevfd<\/div>\n<div>&#8211;qemuMonitorSendFileHandle<\/div>\n<div>&#8212;qemuMonitorJSONSendFileHandle<\/div>\n<div>&#8212;-qemuMonitorJSONCommandWithFd<\/div>\n<div><\/div>\n<div>qemuConnectMonitor-&gt;qemuMonitorOpen<\/div>\n<div>qemuMonitorOpenInternal\u8c03\u7528virEventAddHandle\u628aqemuMonitorIO\u6ce8\u518c\u7ed9mon-&gt;watch\u4f5c\u4e3acallback\uff0c\u7b49monitor\u68c0\u6d4b\u5230qemu\u8fdb\u7a0b\u8d77\u6765\u4f1a\u8c03\u7528\u8fd9\u4e2a\u51fd\u6570\u628afd\u4f20\u8fc7\u53bb\uff0c<\/div>\n<div>\u800c\u4f20fd\u7528\u7684\u662fLinux\u7cfb\u7edf\u8c03\u7528sendmsg\u3002\u5bf9\uff0c\u5c31\u662f\u90a3\u4e2asocket\u901a\u4fe1\u4e2d\u5e38\u7528\u7684sendmsg\uff0c\u4ed6\u8fd8\u6709\u8fd9\u4e2a\u9644\u52a0\u5c5e\u6027~<\/div>\n<div>\n<pre class=\"lang:c decode:true\">int virEventPollAddHandle(int fd, int events,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0virEventHandleCallback cb,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0void *opaque,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0virFreeCallback ff) {\n\u00a0\u00a0\u00a0\u00a0int watch;\n\u00a0\u00a0\u00a0\u00a0virMutexLock(&amp;eventLoop.lock);\n\u00a0\u00a0\u00a0\u00a0if (eventLoop.handlesCount == eventLoop.handlesAlloc) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0EVENT_DEBUG(\"Used %zu handle slots, adding at least %d more\",\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0eventLoop.handlesAlloc, EVENT_ALLOC_EXTENT);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (VIR_RESIZE_N(eventLoop.handles, eventLoop.handlesAlloc,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0eventLoop.handlesCount, EVENT_ALLOC_EXTENT) &lt; 0) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0virMutexUnlock(&amp;eventLoop.lock);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return -1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0watch = nextWatch++;\n\n\u00a0\u00a0\u00a0\u00a0eventLoop.handles[eventLoop.handlesCount].watch = watch;\n\u00a0\u00a0\u00a0\u00a0eventLoop.handles[eventLoop.handlesCount].fd = fd;\n\u00a0\u00a0\u00a0\u00a0eventLoop.handles[eventLoop.handlesCount].events =\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0virEventPollToNativeEvents(events);\n\u00a0\u00a0\u00a0\u00a0eventLoop.handles[eventLoop.handlesCount].cb = cb;\n\u00a0\u00a0\u00a0\u00a0eventLoop.handles[eventLoop.handlesCount].ff = ff;\n\u00a0\u00a0\u00a0\u00a0eventLoop.handles[eventLoop.handlesCount].opaque = opaque;\n\u00a0\u00a0\u00a0\u00a0eventLoop.handles[eventLoop.handlesCount].deleted = 0;<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<div><\/div>\n<div>qemuMonitorIO:<\/div>\n<div>qemuMonitorIOWrite:<\/div>\n<div><\/div>\n<div>\n<pre class=\"lang:default decode:true \">\u00a0\u00a0\u00a0\u00a0if (mon-&gt;msg-&gt;txFD == -1)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0done = write(mon-&gt;fd,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mon-&gt;msg-&gt;txBuffer + mon-&gt;msg-&gt;txOffset,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mon-&gt;msg-&gt;txLength - mon-&gt;msg-&gt;txOffset);\n\u00a0\u00a0\u00a0\u00a0else\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0done = qemuMonitorIOWriteWithFD(mon,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mon-&gt;msg-&gt;txBuffer + mon-&gt;msg-&gt;txOffset,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mon-&gt;msg-&gt;txLength - mon-&gt;msg-&gt;txOffset,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mon-&gt;msg-&gt;txFD);\n\u00a0\u00a0 \u00a0qemuMonitorIOWriteWithFD\n\u00a0\u00a0\u00a0\u00a0cmsg = CMSG_FIRSTHDR(&amp;msg);\n\u00a0\u00a0\u00a0\u00a0\/* Some static analyzers, like clang 2.6-0.6.pre2, fail to see\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0that our use of CMSG_FIRSTHDR will not return NULL.\u00a0\u00a0*\/\n\u00a0\u00a0\u00a0\u00a0sa_assert(cmsg);\n\u00a0\u00a0\u00a0\u00a0cmsg-&gt;cmsg_len = CMSG_LEN(sizeof(int));\n\u00a0\u00a0\u00a0\u00a0cmsg-&gt;cmsg_level = SOL_SOCKET;\n\u00a0\u00a0\u00a0\u00a0cmsg-&gt;cmsg_type = SCM_RIGHTS;\n\u00a0\u00a0\u00a0\u00a0memcpy(CMSG_DATA(cmsg), &amp;fd, sizeof(int));\n\n\u00a0\u00a0\u00a0\u00a0do {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ret =sendmsg(mon-&gt;fd, &amp;msg, 0);\n\u00a0\u00a0\u00a0\u00a0} while (ret &lt; 0 &amp;&amp; errno == EINTR);<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<div><\/div>\n<div>virEventPollRunOnce-&gt;virEventPollDispatchHandles<\/div>\n<div>\u6700\u540e\u5728\u8fd9\u91ccvirEventPollDispatchHandles\u8c03\u7528\u4e86\u6ce8\u518c\u7684callback\uff1a\u00a0(cb)(watch, fds[n].fd, hEvents, opaque);<\/div>\n<div><\/div>\n<div><\/div>\n<div>[qemu]<\/div>\n<div>register_types<\/div>\n<div>\n<pre class=\"lang:default decode:true \">register_char_driver(\"socket\", CHARDEV_BACKEND_KIND_SOCKET,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0qemu_chr_parse_socket, qmp_chardev_open_socket);\n\nregister_char_driver(\"file\", CHARDEV_BACKEND_KIND_FILE,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0qemu_chr_parse_file_out, qmp_chardev_open_file);\nqmp_chardev_open_file-&gt;qemu_chr_open_fd\nchr-&gt;chr_update_read_handler = fd_chr_update_read_handler;\n\u00a0\u00a0\u00a0\u00a0remove_fd_in_watch(chr);\n\u00a0\u00a0\u00a0\u00a0if (s-&gt;ioc_in) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0chr-&gt;fd_in_tag = io_add_watch_poll(s-&gt;ioc_in,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0fd_chr_read_poll,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0fd_chr_read, chr);\n\u00a0\u00a0\u00a0\u00a0}<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<div>fd_chr_read-&gt;qio_channel_read-&gt;qio_channel_readv_full-&gt;<\/div>\n<div>\n<div>return klass-&gt;io_readv(ioc, iov, niov, fds, nfds, errp);<\/div>\n<\/div>\n<div>\n<div>ioc_klass-&gt;io_readv = qio_channel_socket_readv;<\/div>\n<\/div>\n<div>\n<div>ret =recvmsg(sioc-&gt;fd, &amp;msg, sflags);<\/div>\n<\/div>\n<div><\/div>\n<div><\/div>\n<div>qmp_getfd-&gt;qemu_chr_fe_get_msgfd-&gt;qemu_chr_fe_get_msgfds-&gt;<\/div>\n<div>\n<div>return s-&gt;get_msgfds ? s-&gt;get_msgfds(s, fds, len) : -1;<\/div>\n<\/div>\n<div><\/div>\n<div><\/div>\n<div>\n<hr \/>\n<\/div>\n<div>\u00a0\u53c2\u8003\u6587\u732e\uff1a<\/div>\n<div><\/div>\n<div><a href=\"http:\/\/blog.csdn.net\/win_lin\/article\/details\/7760951\">http:\/\/blog.csdn.net\/win_lin\/article\/details\/7760951<\/a><\/div>\n<div><a href=\"http:\/\/blog.csdn.net\/sparkliang\/article\/details\/5486069\">http:\/\/blog.csdn.net\/sparkliang\/article\/details\/5486069<\/a><\/div>\n<div><a href=\"http:\/\/blog.csdn.net\/sparkliang\/article\/details\/5490242\">http:\/\/blog.csdn.net\/sparkliang\/article\/details\/5490242<\/a><\/div>\n<div><\/div>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n","protected":false},"excerpt":{"rendered":"<p>libvirt\u521b\u5efa\u7684qemu\u8fdb\u7a0b\u91cc\u9762\u6709\u4e00\u4e9bfd\u7684\u53c2\u6570\uff0c\u8fd9\u4e9b\u6587\u4ef6\u662flibvirt\u5e2eqemu\u6253\u5f00\u7684\u4e00\u4e9b\u8bbe\u5907\u6587\u4ef6\u53e5\u67c4\u7b49\uff0c\u6bd4\u5982\uff1a qemu &#8230; -netdev tap,fd=24,id=hostnet1,vhost=on,vhostfd=25 \u56e0\u4e3a\u9700\u8981libvirt\u5e2e\u5fd9\u5148\u914d\u7f6e\u597d\u540e\u7aef\u4ee5\u53ca\u5904\u4e8e\u5b89\u5168\u8003\u8651\uff1b\u4f46\u662fqemu\u8d77\u6765\u5c31\u662f\u53e6\u5916\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u7ed9\u4e2afd\u53f7\u5c31\u80fd\u76f4\u63a5\u7528\u4e86\u5417\uff0c\u663e\u7136\u4e0d\u662f\uff0c\u4e0b\u9762\u4ece\u4ee3\u7801\u89d2\u5ea6\u5206\u6790\u4e0b<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false,"jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[3],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/s7Dhki-207","jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/www.luo666.com\/index.php?rest_route=\/wp\/v2\/posts\/207"}],"collection":[{"href":"http:\/\/www.luo666.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.luo666.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.luo666.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.luo666.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=207"}],"version-history":[{"count":13,"href":"http:\/\/www.luo666.com\/index.php?rest_route=\/wp\/v2\/posts\/207\/revisions"}],"predecessor-version":[{"id":312,"href":"http:\/\/www.luo666.com\/index.php?rest_route=\/wp\/v2\/posts\/207\/revisions\/312"}],"wp:attachment":[{"href":"http:\/\/www.luo666.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=207"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.luo666.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=207"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.luo666.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=207"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}