📄 blktapctrl.c
字号:
buf = malloc(MSG_SIZE); ret = 0; FD_ZERO(&readfds); FD_SET(fd,&readfds); timeout.tv_sec = max_timeout; /*Wait for up to max_timeout seconds*/ timeout.tv_usec = 0; if (select(fd+1, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout) > 0) { ret = read(fd, buf, msglen); } if (ret > 0) { msg = (msg_hdr_t *)buf; switch (msg->type) { case CTLMSG_IMG: img = (image_t *)(buf + sizeof(msg_hdr_t)); image->size = img->size; image->secsize = img->secsize; image->info = img->info; DPRINTF("Received CTLMSG_IMG: %llu, %lu, %u\n", image->size, image->secsize, image->info); if(msgtype != CTLMSG_IMG) ret = 0; break; case CTLMSG_IMG_FAIL: DPRINTF("Received CTLMSG_IMG_FAIL, " "unable to open image\n"); ret = 0; break; case CTLMSG_NEWDEV_RSP: DPRINTF("Received CTLMSG_NEWDEV_RSP\n"); if(msgtype != CTLMSG_NEWDEV_RSP) ret = 0; break; case CTLMSG_NEWDEV_FAIL: DPRINTF("Received CTLMSG_NEWDEV_FAIL\n"); ret = 0; break; case CTLMSG_CLOSE_RSP: DPRINTF("Received CTLMSG_CLOSE_RSP\n"); if (msgtype != CTLMSG_CLOSE_RSP) ret = 0; break; case CTLMSG_PID_RSP: DPRINTF("Received CTLMSG_PID_RSP\n"); if (msgtype != CTLMSG_PID_RSP) ret = 0; else { msg_pid = (msg_pid_t *) (buf + sizeof(msg_hdr_t)); blkif->tappid = msg_pid->pid; DPRINTF("\tPID: [%d]\n",blkif->tappid); } break; default: DPRINTF("UNKNOWN MESSAGE TYPE RECEIVED\n"); ret = 0; break; } } free(buf); return ret;}int launch_tapdisk(char *wrctldev, char *rdctldev){ char *argv[] = { "tapdisk", wrctldev, rdctldev, NULL }; pid_t child; if ((child = fork()) < 0) return -1; if (!child) { int i; for (i = 0 ; i < sysconf(_SC_OPEN_MAX) ; i++) if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO) close(i); execvp("tapdisk", argv); _exit(1); } else { pid_t got; do { got = waitpid(child, NULL, 0); } while (got != child); } return 0;}int blktapctrl_new_blkif(blkif_t *blkif){ blkif_info_t *blk; int major, minor, fd_read, fd_write, type, new; char *rdctldev, *wrctldev, *ptr; image_t *image; blkif_t *exist = NULL; static uint16_t next_cookie = 0; DPRINTF("Received a poll for a new vbd\n"); if ( ((blk=blkif->info) != NULL) && (blk->params != NULL) ) { if (get_new_dev(&major, &minor, blkif)<0) return -1; if (test_path(blk->params, &ptr, &type, &exist) != 0) { DPRINTF("Error in blktap device string(%s).\n", blk->params); goto fail; } blkif->drivertype = type; blkif->cookie = next_cookie++; if (!exist) { DPRINTF("Process does not exist:\n"); if (asprintf(&rdctldev, "%s/tapctrlread%d", BLKTAP_CTRL_DIR, minor) == -1) goto fail; if (asprintf(&wrctldev, "%s/tapctrlwrite%d", BLKTAP_CTRL_DIR, minor) == -1) { free(rdctldev); goto fail; } blkif->fds[READ] = open_ctrl_socket(rdctldev); blkif->fds[WRITE] = open_ctrl_socket(wrctldev); if (blkif->fds[READ] == -1 || blkif->fds[WRITE] == -1) goto fail; /*launch the new process*/ DPRINTF("Launching process, CMDLINE [tapdisk %s %s]\n",wrctldev, rdctldev); if (launch_tapdisk(wrctldev, rdctldev) == -1) { DPRINTF("Unable to fork, cmdline: [tapdisk %s %s]\n",wrctldev, rdctldev); goto fail; } free(rdctldev); free(wrctldev); } else { DPRINTF("Process exists!\n"); blkif->fds[READ] = exist->fds[READ]; blkif->fds[WRITE] = exist->fds[WRITE]; } add_disktype(blkif, type); blkif->major = major; blkif->minor = minor; image = (image_t *)malloc(sizeof(image_t)); blkif->prv = (void *)image; blkif->ops = &tapdisk_ops; /*Retrieve the PID of the new process*/ if (get_tapdisk_pid(blkif) <= 0) { DPRINTF("Unable to contact disk process\n"); goto fail; } /* Both of the following read and write calls will block up to * max_timeout val*/ if (write_msg(blkif->fds[WRITE], CTLMSG_PARAMS, blkif, ptr) <= 0) { DPRINTF("Write_msg failed - CTLMSG_PARAMS\n"); goto fail; } if (read_msg(blkif->fds[READ], CTLMSG_IMG, blkif) <= 0) { DPRINTF("Read_msg failure - CTLMSG_IMG\n"); goto fail; } } else return -1; return 0;fail: ioctl(ctlfd, BLKTAP_IOCTL_FREEINTF, minor); return -EINVAL;}int map_new_blktapctrl(blkif_t *blkif){ DPRINTF("Received a poll for a new devmap\n"); if (write_msg(blkif->fds[WRITE], CTLMSG_NEWDEV, blkif, NULL) <= 0) { DPRINTF("Write_msg failed - CTLMSG_NEWDEV\n"); return -EINVAL; } if (read_msg(blkif->fds[READ], CTLMSG_NEWDEV_RSP, blkif) <= 0) { DPRINTF("Read_msg failed - CTLMSG_NEWDEV_RSP\n"); return -EINVAL; } DPRINTF("Exiting map_new_blktapctrl\n"); return blkif->minor - 1;}int unmap_blktapctrl(blkif_t *blkif){ DPRINTF("Unmapping vbd\n"); if (write_msg(blkif->fds[WRITE], CTLMSG_CLOSE, blkif, NULL) <= 0) { DPRINTF("Write_msg failed - CTLMSG_CLOSE\n"); return -EINVAL; } if (del_disktype(blkif)) { close(blkif->fds[WRITE]); close(blkif->fds[READ]); } return 0;}int open_ctrl_socket(char *devname){ int ret; int ipc_fd; fd_set socks; struct timeval timeout; if (mkdir(BLKTAP_CTRL_DIR, 0755) == 0) DPRINTF("Created %s directory\n", BLKTAP_CTRL_DIR); ret = mkfifo(devname,S_IRWXU|S_IRWXG|S_IRWXO); if ( (ret != 0) && (errno != EEXIST) ) { DPRINTF("ERROR: pipe failed (%d)\n", errno); exit(0); } ipc_fd = open(devname,O_RDWR|O_NONBLOCK); if (ipc_fd < 0) { DPRINTF("FD open failed\n"); return -1; } return ipc_fd;}static void print_drivers(void){ int i, size; size = sizeof(dtypes)/sizeof(disk_info_t *); DPRINTF("blktapctrl: v1.0.0\n"); for (i = 0; i < size; i++) DPRINTF("Found driver: [%s]\n",dtypes[i]->name);} static void write_pidfile(long pid){ char buf[100]; int len; int fd; int flags; fd = open(PIDFILE, O_RDWR | O_CREAT, 0600); if (fd == -1) { DPRINTF("Opening pid file failed (%d)\n", errno); exit(1); } /* We exit silently if daemon already running. */ if (lockf(fd, F_TLOCK, 0) == -1) exit(0); /* Set FD_CLOEXEC, so that tapdisk doesn't get this file descriptor. */ if ((flags = fcntl(fd, F_GETFD)) == -1) { DPRINTF("F_GETFD failed (%d)\n", errno); exit(1); } flags |= FD_CLOEXEC; if (fcntl(fd, F_SETFD, flags) == -1) { DPRINTF("F_SETFD failed (%d)\n", errno); exit(1); } len = snprintf(buf, sizeof(buf), "%ld\n", pid); if (write(fd, buf, len) != len) { DPRINTF("Writing pid file failed (%d)\n", errno); exit(1); }}int main(int argc, char *argv[]){ char *devname; tapdev_info_t *ctlinfo; int tap_pfd, store_pfd, xs_fd, ret, timeout, pfd_count, count=0; struct xs_handle *h; struct pollfd pfd[NUM_POLL_FDS]; pid_t process; char buf[128]; __init_blkif(); snprintf(buf, sizeof(buf), "BLKTAPCTRL[%d]", getpid()); openlog(buf, LOG_CONS|LOG_ODELAY, LOG_DAEMON); if (daemon(0,0)) { DPRINTF("daemon failed (%d)\n", errno); goto open_failed; } print_drivers(); init_driver_list(); init_rng(); register_new_blkif_hook(blktapctrl_new_blkif); register_new_devmap_hook(map_new_blktapctrl); register_new_unmap_hook(unmap_blktapctrl); /* Attach to blktap0 */ if (asprintf(&devname,"%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME) == -1) goto open_failed; if ((ret = xc_find_device_number("blktap0")) < 0) { DPRINTF("couldn't find device number for 'blktap0'\n"); goto open_failed; } blktap_major = major(ret); make_blktap_dev(devname,blktap_major,0); ctlfd = open(devname, O_RDWR); if (ctlfd == -1) { DPRINTF("blktap0 open failed\n"); goto open_failed; } retry: /* Set up store connection and watch. */ h = xs_daemon_open(); if (h == NULL) { DPRINTF("xs_daemon_open failed -- " "is xenstore running?\n"); if (count < MAX_ATTEMPTS) { count++; sleep(2); goto retry; } else goto open_failed; } ret = setup_probe_watch(h); if (ret != 0) { DPRINTF("Failed adding device probewatch\n"); xs_daemon_close(h); goto open_failed; } ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE ); process = getpid(); write_pidfile(process); ret = ioctl(ctlfd, BLKTAP_IOCTL_SENDPID, process ); /*Static pollhooks*/ pfd_count = 0; tap_pfd = pfd_count++; pfd[tap_pfd].fd = ctlfd; pfd[tap_pfd].events = POLLIN; store_pfd = pfd_count++; pfd[store_pfd].fd = xs_fileno(h); pfd[store_pfd].events = POLLIN; while (run) { timeout = 1000; /*Milliseconds*/ ret = poll(pfd, pfd_count, timeout); if (ret > 0) { if (pfd[store_pfd].revents) { ret = xs_fire_next_watch(h); } } } xs_daemon_close(h); ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_PASSTHROUGH ); close(ctlfd); closelog(); return 0; open_failed: DPRINTF("Unable to start blktapctrl\n"); closelog(); return -1;}/* * Local variables: * c-file-style: "linux" * indent-tabs-mode: t * c-indent-level: 8 * c-basic-offset: 8 * tab-width: 8 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -