Advertisement
Guest User

qemu vfsd daemon

a guest
Aug 4th, 2020
452
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.61 KB | None | 0 0
  1. commit fad5c5b8fb3e6865ad6076b305b142e7248a8c16
  2. Author: Your Name <you@example.com>
  3. Date: Thu Jul 23 07:34:50 2020 +0900
  4.  
  5. Forked
  6.  
  7. diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
  8. index 3b6d16a041..44c007b55c 100644
  9. --- a/tools/virtiofsd/fuse_virtio.c
  10. +++ b/tools/virtiofsd/fuse_virtio.c
  11. @@ -846,126 +846,10 @@ int virtio_loop(struct fuse_session *se)
  12. return 0;
  13. }
  14.  
  15. -static void strreplace(char *s, char old, char new)
  16. -{
  17. - for (; *s; ++s) {
  18. - if (*s == old) {
  19. - *s = new;
  20. - }
  21. - }
  22. -}
  23. -
  24. -static bool fv_socket_lock(struct fuse_session *se)
  25. -{
  26. - g_autofree gchar *sk_name = NULL;
  27. - g_autofree gchar *pidfile = NULL;
  28. - g_autofree gchar *dir = NULL;
  29. - Error *local_err = NULL;
  30. -
  31. - dir = qemu_get_local_state_pathname("run/virtiofsd");
  32. -
  33. - if (g_mkdir_with_parents(dir, S_IRWXU) < 0) {
  34. - fuse_log(FUSE_LOG_ERR, "%s: Failed to create directory %s: %s",
  35. - __func__, dir, strerror(errno));
  36. - return false;
  37. - }
  38. -
  39. - sk_name = g_strdup(se->vu_socket_path);
  40. - strreplace(sk_name, '/', '.');
  41. - pidfile = g_strdup_printf("%s/%s.pid", dir, sk_name);
  42. -
  43. - if (!qemu_write_pidfile(pidfile, &local_err)) {
  44. - error_report_err(local_err);
  45. - return false;
  46. - }
  47. -
  48. - return true;
  49. -}
  50. -
  51. -static int fv_create_listen_socket(struct fuse_session *se)
  52. -{
  53. - struct sockaddr_un un;
  54. - mode_t old_umask;
  55. -
  56. - /* Nothing to do if fd is already initialized */
  57. - if (se->vu_listen_fd >= 0) {
  58. - return 0;
  59. - }
  60. -
  61. - if (strlen(se->vu_socket_path) >= sizeof(un.sun_path)) {
  62. - fuse_log(FUSE_LOG_ERR, "Socket path too long\n");
  63. - return -1;
  64. - }
  65. -
  66. - if (!strlen(se->vu_socket_path)) {
  67. - fuse_log(FUSE_LOG_ERR, "Socket path is empty\n");
  68. - return -1;
  69. - }
  70. -
  71. - /* Check the vu_socket_path is already used */
  72. - if (!fv_socket_lock(se)) {
  73. - return -1;
  74. - }
  75. -
  76. - /*
  77. - * Create the Unix socket to communicate with qemu
  78. - * based on QEMU's vhost-user-bridge
  79. - */
  80. - unlink(se->vu_socket_path);
  81. - strcpy(un.sun_path, se->vu_socket_path);
  82. - size_t addr_len = sizeof(un);
  83. -
  84. - int listen_sock = socket(AF_UNIX, SOCK_STREAM, 0);
  85. - if (listen_sock == -1) {
  86. - fuse_log(FUSE_LOG_ERR, "vhost socket creation: %m\n");
  87. - return -1;
  88. - }
  89. - un.sun_family = AF_UNIX;
  90. -
  91. - /*
  92. - * Unfortunately bind doesn't let you set the mask on the socket,
  93. - * so set umask to 077 and restore it later.
  94. - */
  95. - old_umask = umask(0077);
  96. - if (bind(listen_sock, (struct sockaddr *)&un, addr_len) == -1) {
  97. - fuse_log(FUSE_LOG_ERR, "vhost socket bind: %m\n");
  98. - close(listen_sock);
  99. - umask(old_umask);
  100. - return -1;
  101. - }
  102. - umask(old_umask);
  103. -
  104. - if (listen(listen_sock, 1) == -1) {
  105. - fuse_log(FUSE_LOG_ERR, "vhost socket listen: %m\n");
  106. - close(listen_sock);
  107. - return -1;
  108. - }
  109. -
  110. - se->vu_listen_fd = listen_sock;
  111. - return 0;
  112. -}
  113.  
  114. int virtio_session_mount(struct fuse_session *se)
  115. {
  116. - int ret;
  117.  
  118. - ret = fv_create_listen_socket(se);
  119. - if (ret < 0) {
  120. - return ret;
  121. - }
  122. -
  123. - se->fd = -1;
  124. -
  125. - fuse_log(FUSE_LOG_INFO, "%s: Waiting for vhost-user socket connection...\n",
  126. - __func__);
  127. - int data_sock = accept(se->vu_listen_fd, NULL, NULL);
  128. - if (data_sock == -1) {
  129. - fuse_log(FUSE_LOG_ERR, "vhost socket accept: %m\n");
  130. - close(se->vu_listen_fd);
  131. - return -1;
  132. - }
  133. - close(se->vu_listen_fd);
  134. - se->vu_listen_fd = -1;
  135. fuse_log(FUSE_LOG_INFO, "%s: Received vhost-user socket connection\n",
  136. __func__);
  137.  
  138. @@ -973,11 +857,10 @@ int virtio_session_mount(struct fuse_session *se)
  139. se->virtio_dev = calloc(sizeof(struct fv_VuDev), 1);
  140. if (!se->virtio_dev) {
  141. fuse_log(FUSE_LOG_ERR, "%s: virtio_dev calloc failed\n", __func__);
  142. - close(data_sock);
  143. + close(se->vu_socketfd);
  144. return -1;
  145. }
  146.  
  147. - se->vu_socketfd = data_sock;
  148. se->virtio_dev->se = se;
  149. pthread_rwlock_init(&se->virtio_dev->vu_dispatch_rwlock, NULL);
  150. vu_init(&se->virtio_dev->dev, 2, se->vu_socketfd, fv_panic, fv_set_watch,
  151. --- a/tools/virtiofsd/passthrough_ll.c
  152. +++ b/tools/virtiofsd/passthrough_ll.c
  153. @@ -2754,6 +2754,145 @@ static void fuse_lo_data_cleanup(struct lo_data *lo)
  154. free(lo->source);
  155. }
  156.  
  157. +
  158. +static void strreplace(char *s, char old, char new)
  159. +{
  160. + for (; *s; ++s) {
  161. + if (*s == old) {
  162. + *s = new;
  163. + }
  164. + }
  165. +}
  166. +
  167. +
  168. +static bool fv_socket_lock(struct fuse_session *se)
  169. +{
  170. + g_autofree gchar *sk_name = NULL;
  171. + g_autofree gchar *pidfile = NULL;
  172. + //g_autofree gchar *dir = NULL;
  173. + char *dir;
  174. + Error *local_err = NULL;
  175. +
  176. + dir = "/run/virtiofsd";
  177. +
  178. + if (g_mkdir_with_parents(dir, S_IRWXU) < 0) {
  179. + fuse_log(FUSE_LOG_ERR, "%s: Failed to create directory %s: %s",
  180. + __func__, dir, strerror(errno));
  181. + return false;
  182. + }
  183. +
  184. + sk_name = g_strdup(se->vu_socket_path);
  185. + strreplace(sk_name, '/', '.');
  186. + pidfile = g_strdup_printf("%s/%s.pid", dir, sk_name);
  187. +
  188. + if (!qemu_write_pidfile(pidfile, &local_err)) {
  189. + error_report_err(local_err);
  190. + return false;
  191. + }
  192. +
  193. + return true;
  194. +}
  195. +
  196. +static int fv_create_listen_socket(struct fuse_session *se)
  197. +{
  198. + struct sockaddr_un un;
  199. + mode_t old_umask;
  200. +
  201. + /* Nothing to do if fd is already initialized */
  202. + if (se->vu_listen_fd >= 0) {
  203. + return se->vu_listen_fd;
  204. + }
  205. +
  206. + if (strlen(se->vu_socket_path) >= sizeof(un.sun_path)) {
  207. + fuse_log(FUSE_LOG_ERR, "Socket path too long\n");
  208. + return -1;
  209. + }
  210. +
  211. + if (!strlen(se->vu_socket_path)) {
  212. + fuse_log(FUSE_LOG_ERR, "Socket path is empty\n");
  213. + return -1;
  214. + }
  215. +
  216. + /* Check the vu_socket_path is already used */
  217. + if (!fv_socket_lock(se)) {
  218. + return -1;
  219. + }
  220. +
  221. + /*
  222. + * Create the Unix socket to communicate with qemu
  223. + * based on QEMU's vhost-user-bridge
  224. + */
  225. + unlink(se->vu_socket_path);
  226. + strcpy(un.sun_path, se->vu_socket_path);
  227. + size_t addr_len = sizeof(un);
  228. +
  229. + int listen_sock = socket(AF_UNIX, SOCK_STREAM, 0);
  230. + if (listen_sock == -1) {
  231. + fuse_log(FUSE_LOG_ERR, "vhost socket creation: %m\n");
  232. + return -1;
  233. + }
  234. + un.sun_family = AF_UNIX;
  235. +
  236. + /*
  237. + * Unfortunately bind doesn't let you set the mask on the socket,
  238. + * so set umask to 077 and restore it later.
  239. + */
  240. + old_umask = umask(0007);
  241. + if (bind(listen_sock, (struct sockaddr *)&un, addr_len) == -1) {
  242. + fuse_log(FUSE_LOG_ERR, "vhost socket bind: %m\n");
  243. + close(listen_sock);
  244. + umask(old_umask);
  245. + return -1;
  246. + }
  247. + umask(old_umask);
  248. +
  249. + if (listen(listen_sock, 1) == -1) {
  250. + fuse_log(FUSE_LOG_ERR, "vhost socket listen: %m\n");
  251. + close(listen_sock);
  252. + return -1;
  253. + }
  254. +
  255. + se->vu_listen_fd = listen_sock;
  256. + return listen_sock;
  257. +}
  258. +
  259. +static int wait_for_connection(struct fuse_session *se)
  260. +{
  261. + int ret;
  262. + int fd = se->vu_listen_fd;
  263. + ret = fv_create_listen_socket(se);
  264. + if (ret < 0) {
  265. + return ret;
  266. + }
  267. +
  268. + fd = se->vu_listen_fd;
  269. + for(;;) {
  270. + int kid = -1;
  271. + fuse_log(FUSE_LOG_INFO, "%s: Waiting for vhost-user socket connection...\n",
  272. + __func__);
  273. + int data_sock = accept(fd, NULL, NULL);
  274. + if (data_sock == -1) {
  275. + fuse_log(FUSE_LOG_ERR, "vhost socket accept: %m\n");
  276. + close(se->vu_listen_fd);
  277. + return -1;
  278. + }
  279. + kid = fork();
  280. + if(kid == 0) {
  281. + fuse_log(FUSE_LOG_INFO, "%s: Accepted connection...\n",
  282. + __func__);
  283. + se->vu_socketfd = data_sock;
  284. + break;
  285. + } else if(kid < 0) {
  286. + fuse_log(FUSE_LOG_INFO, "%s: forked..\n",
  287. + __func__);
  288. + }
  289. + }
  290. + close(se->vu_listen_fd);
  291. + se->vu_listen_fd = -1;
  292. + virtio_session_mount(se);
  293. + return ret;
  294. +}
  295. +
  296. int main(int argc, char *argv[])
  297. {
  298. struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
  299. @@ -2777,18 +2916,7 @@ int main(int argc, char *argv[])
  300. lo.root.fuse_ino = FUSE_ROOT_ID;
  301. lo.cache = CACHE_AUTO;
  302.  
  303. - /*
  304. - * Set up the ino map like this:
  305. - * [0] Reserved (will not be used)
  306. - * [1] Root inode
  307. - */
  308. - lo_map_init(&lo.ino_map);
  309. - lo_map_reserve(&lo.ino_map, 0)->in_use = false;
  310. - root_elem = lo_map_reserve(&lo.ino_map, lo.root.fuse_ino);
  311. - root_elem->inode = &lo.root;
  312.  
  313. - lo_map_init(&lo.dirp_map);
  314. - lo_map_init(&lo.fd_map);
  315.  
  316. if (fuse_parse_cmdline(&args, &opts) != 0) {
  317. goto err_out1;
  318. @@ -2866,6 +2994,18 @@ int main(int argc, char *argv[])
  319. fuse_log(FUSE_LOG_ERR, "timeout is negative (%lf)\n", lo.timeout);
  320. exit(1);
  321. }
  322. + /*
  323. + * Set up the ino map like this:
  324. + * [0] Reserved (will not be used)
  325. + * [1] Root inode
  326. + */
  327. + lo_map_init(&lo.ino_map);
  328. + lo_map_reserve(&lo.ino_map, 0)->in_use = false;
  329. + root_elem = lo_map_reserve(&lo.ino_map, lo.root.fuse_ino);
  330. + root_elem->inode = &lo.root;
  331. +
  332. + lo_map_init(&lo.dirp_map);
  333. + lo_map_init(&lo.fd_map);
  334.  
  335. se = fuse_session_new(&args, &lo_oper, sizeof(lo_oper), &lo);
  336. if (se == NULL) {
  337. @@ -3107,6 +3107,8 @@
  338.  
  339. fuse_daemonize(opts.foreground);
  340.  
  341. + wait_for_connection(se);
  342. +
  343. setup_nofile_rlimit();
  344.  
  345. /* Must be before sandbox since it wants /proc */
  346.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement