int tap_ctl_send_and_receive_with_logpath(int sfd, tapdisk_message_t *message, const char *logpath, struct timeval *timeout) { int err, ret; err = tap_ctl_write_message(sfd, message, timeout); if (err) { EPRINTF("failed to send '%s' message\n", tapdisk_message_name(message->type)); return err; } char buf[TAPDISK_MESSAGE_MAX_PATH_LENGTH]; snprintf(buf, TAPDISK_MESSAGE_MAX_PATH_LENGTH - 1, "%s", logpath); ret = write(sfd, &buf, sizeof(buf)); if (ret == -1) { EPRINTF("Failed to send logpath with '%s' message\n", tapdisk_message_name(message->type)); } err = tap_ctl_read_message(sfd, message, timeout); if (err) { EPRINTF("failed to receive '%s' message\n", tapdisk_message_name(message->type)); return err; } return 0; }
int tap_ctl_detach(const int id, const int minor) { int err; tapdisk_message_t message; memset(&message, 0, sizeof(message)); message.type = TAPDISK_MESSAGE_DETACH; message.cookie = minor; err = tap_ctl_connect_send_and_receive(id, &message, NULL); if (err) return err; if (message.type == TAPDISK_MESSAGE_DETACH_RSP) { err = message.u.response.error; if (err < 0) printf("detach failed: %d\n", err); } else { printf("got unexpected result '%s' from %d\n", tapdisk_message_name(message.type), id); err = EINVAL; } return err; }
int tap_ctl_close(const int id, const int minor, const int force, struct timeval *timeout) { int err; tapdisk_message_t message; memset(&message, 0, sizeof(message)); message.type = TAPDISK_MESSAGE_CLOSE; if (force) message.type = TAPDISK_MESSAGE_FORCE_SHUTDOWN; message.cookie = minor; err = tap_ctl_connect_send_and_receive(id, &message, timeout); if (err) return err; if (message.type == TAPDISK_MESSAGE_CLOSE_RSP) { err = message.u.response.error; if (err) EPRINTF("close failed: %d\n", err); } else { EPRINTF("got unexpected result '%s' from %d\n", tapdisk_message_name(message.type), id); err = EINVAL; } return err; }
int tap_ctl_unpause(const int id, const int minor, const char *params) { int err; tapdisk_message_t message; memset(&message, 0, sizeof(message)); message.type = TAPDISK_MESSAGE_RESUME; message.cookie = minor; if (params) strncpy(message.u.params.path, params, sizeof(message.u.params.path) - 1); err = tap_ctl_connect_send_and_receive(id, &message, NULL); if (err) return err; if (message.type == TAPDISK_MESSAGE_RESUME_RSP) err = message.u.response.error; else { err = EINVAL; EPRINTF("got unexpected result '%s' from %d\n", tapdisk_message_name(message.type), id); } return err; }
int tap_ctl_send_and_receive(int sfd, tapdisk_message_t * message, struct timeval *timeout) { int err; err = tap_ctl_write_message(sfd, message, timeout); if (err) { EPRINTF("failed to send '%s' message\n", tapdisk_message_name(message->type)); return err; } err = tap_ctl_read_message(sfd, message, timeout); if (err) { EPRINTF("failed to receive '%s' message\n", tapdisk_message_name(message->type)); return err; } return 0; }
int tap_ctl_open(const int id, const int minor, const char *params, int flags, const int prt_minor, const char *secondary, int timeout) { int err; tapdisk_message_t message; memset(&message, 0, sizeof(message)); message.type = TAPDISK_MESSAGE_OPEN; message.cookie = minor; message.u.params.devnum = minor; message.u.params.prt_devnum = prt_minor; message.u.params.req_timeout = timeout; message.u.params.flags = flags; err = snprintf(message.u.params.path, sizeof(message.u.params.path) - 1, "%s", params); if (err >= sizeof(message.u.params.path)) { EPRINTF("name too long\n"); return ENAMETOOLONG; } if (secondary) { err = snprintf(message.u.params.secondary, sizeof(message.u.params.secondary) - 1, "%s", secondary); if (err >= sizeof(message.u.params.secondary)) { EPRINTF("secondary image name too long\n"); return ENAMETOOLONG; } } err = tap_ctl_connect_send_and_receive(id, &message, NULL); if (err) return err; switch (message.type) { case TAPDISK_MESSAGE_OPEN_RSP: break; case TAPDISK_MESSAGE_ERROR: err = -message.u.response.error; EPRINTF("open failed, err %d\n", err); break; default: EPRINTF("got unexpected result '%s' from %d\n", tapdisk_message_name(message.type), id); err = EINVAL; } return err; }
int tap_ctl_read_message(int fd, tapdisk_message_t * message, struct timeval *timeout) { size_t size = sizeof(tapdisk_message_t); int err; err = tap_ctl_read_raw(fd, message, size, timeout); if (err) return err; DBG("received '%s' message (uuid = %u)\n", tapdisk_message_name(message->type), message->cookie); return 0; }
int tap_ctl_unpause(const int id, const int minor, const char *params, int flags, char *secondary) { int err; tapdisk_message_t message; memset(&message, 0, sizeof(message)); message.type = TAPDISK_MESSAGE_RESUME; message.cookie = minor; message.u.params.flags = flags; if (params) strncpy(message.u.params.path, params, sizeof(message.u.params.path) - 1); if (secondary) { err = snprintf(message.u.params.secondary, sizeof(message.u.params.secondary) - 1, "%s", secondary); if (err >= sizeof(message.u.params.secondary)) { EPRINTF("secondary image name too long\n"); return -ENAMETOOLONG; } } err = tap_ctl_connect_send_and_receive(id, &message, NULL); if (err) return err; if (message.type == TAPDISK_MESSAGE_RESUME_RSP || message.type == TAPDISK_MESSAGE_ERROR) err = -message.u.response.error; else { EPRINTF("got unexpected result '%s' from %d\n", tapdisk_message_name(message.type), id); err = -EINVAL; } if (err) EPRINTF("unpause failed: %s\n", strerror(-err)); return err; }
int tap_ctl_write_message(int fd, tapdisk_message_t * message, struct timeval *timeout) { fd_set writefds; int ret, len, offset; offset = 0; len = sizeof(tapdisk_message_t); DBG("sending '%s' message (uuid = %u)\n", tapdisk_message_name(message->type), message->cookie); while (offset < len) { FD_ZERO(&writefds); FD_SET(fd, &writefds); /* we don't bother reinitializing tv. at worst, it will wait a * bit more time than expected. */ ret = select(fd + 1, NULL, &writefds, NULL, timeout); if (ret == -1) break; else if (FD_ISSET(fd, &writefds)) { ret = write(fd, message + offset, len - offset); if (ret <= 0) break; offset += ret; } else break; } if (offset != len) { EPRINTF("failure writing message\n"); return -EIO; } return 0; }
int tap_ctl_disconnect_xenblkif(const pid_t pid, const domid_t domid, const int devid, struct timeval *timeout) { int err; tapdisk_message_t message; memset(&message, 0, sizeof(message)); message.type = TAPDISK_MESSAGE_XENBLKIF_DISCONNECT; message.u.blkif.domid = domid; message.u.blkif.devid = devid; err = tap_ctl_connect_send_and_receive(pid, &message, timeout); if (err) goto out; if (message.type == TAPDISK_MESSAGE_XENBLKIF_DISCONNECT_RSP || message.type == TAPDISK_MESSAGE_ERROR) err = -message.u.response.error; else { EPRINTF("got unexpected result '%s' from tapdisk[%d]\n", tapdisk_message_name(message.type), pid); err = -EINVAL; } out: if (err) { if (likely(err == -ENOENT)) DPRINTF("failed to disconnect tapdisk[%d] from the ring: %s\n", pid, strerror(-err)); else EPRINTF("failed to disconnect tapdisk[%d] from the ring: %s\n", pid, strerror(-err)); } return err; }
int tap_ctl_pause(const int id, const int minor, struct timeval *timeout) { int err; tapdisk_message_t message; memset(&message, 0, sizeof(message)); message.type = TAPDISK_MESSAGE_PAUSE; message.cookie = minor; err = tap_ctl_connect_send_and_receive(id, &message, timeout); if (err) return err; if (message.type == TAPDISK_MESSAGE_PAUSE_RSP) err = message.u.response.error; else { err = EINVAL; EPRINTF("got unexpected result '%s' from %d\n", tapdisk_message_name(message.type), id); } return err; }
int tap_ctl_open(const int id, const int minor, const char *params, int flags, const int prt_minor, const char *secondary, int timeout, const char* logpath, uint8_t key_size, uint8_t *encryption_key) { int err; tapdisk_message_t message; memset(&message, 0, sizeof(message)); message.type = TAPDISK_MESSAGE_OPEN; message.cookie = minor; message.u.params.devnum = minor; message.u.params.prt_devnum = prt_minor; message.u.params.req_timeout = timeout; message.u.params.flags = flags; err = snprintf(message.u.params.path, sizeof(message.u.params.path) - 1, "%s", params); if (err >= sizeof(message.u.params.path)) { EPRINTF("name too long\n"); return ENAMETOOLONG; } if (secondary) { err = snprintf(message.u.params.secondary, sizeof(message.u.params.secondary) - 1, "%s", secondary); if (err >= sizeof(message.u.params.secondary)) { EPRINTF("secondary image name too long\n"); return ENAMETOOLONG; } } if (flags & (TAPDISK_MESSAGE_FLAG_ADD_LOG | TAPDISK_MESSAGE_FLAG_OPEN_ENCRYPTED)) { err = tap_ctl_connect_send_receive_ex( id, &message, logpath, key_size, encryption_key, NULL); } else { err = tap_ctl_connect_send_and_receive(id, &message, NULL); } if (encryption_key) free(encryption_key); if (err) return err; switch (message.type) { case TAPDISK_MESSAGE_OPEN_RSP: break; case TAPDISK_MESSAGE_ERROR: err = -message.u.response.error; EPRINTF("open failed: %s\n", strerror(-err)); break; default: EPRINTF("got unexpected result '%s' from %d\n", tapdisk_message_name(message.type), id); err = EINVAL; } return err; }