static int nbd_open(BlockDriverState *bs, const char* filename, int flags) { BDRVNBDState *s = bs->opaque; const char *host; const char *unixpath; int sock; off_t size; size_t blocksize; int ret; if ((flags & BDRV_O_CREAT)) return -EINVAL; if (!strstart(filename, "nbd:", &host)) return -EINVAL; if (strstart(host, "unix:", &unixpath)) { if (unixpath[0] != '/') return -EINVAL; sock = unix_socket_outgoing(unixpath); } else { uint16_t port; char *p, *r; char hostname[128]; pstrcpy(hostname, 128, host); p = strchr(hostname, ':'); if (p == NULL) return -EINVAL; *p = '\0'; p++; port = strtol(p, &r, 0); if (r == p) return -EINVAL; sock = tcp_socket_outgoing(hostname, port); } if (sock == -1) return -errno; ret = nbd_receive_negotiate(sock, &size, &blocksize); if (ret == -1) return -errno; s->sock = sock; s->size = size; s->blocksize = blocksize; return 0; }
static int nbd_open(BlockDriverState *bs, const char* filename, int flags) { BDRVNBDState *s = bs->opaque; uint32_t nbdflags; char *file; char *name; const char *host; const char *unixpath; int sock; off_t size; size_t blocksize; int ret; int err = -EINVAL; file = qemu_strdup(filename); name = strstr(file, EN_OPTSTR); if (name) { if (name[strlen(EN_OPTSTR)] == 0) { goto out; } name[0] = 0; name += strlen(EN_OPTSTR); } if (!strstart(file, "nbd:", &host)) { goto out; } if (strstart(host, "unix:", &unixpath)) { if (unixpath[0] != '/') { goto out; } sock = unix_socket_outgoing(unixpath); } else { uint16_t port = NBD_DEFAULT_PORT; char *p, *r; char hostname[128]; pstrcpy(hostname, 128, host); p = strchr(hostname, ':'); if (p != NULL) { *p = '\0'; p++; port = strtol(p, &r, 0); if (r == p) { goto out; } } else if (name == NULL) { goto out; } sock = tcp_socket_outgoing(hostname, port); } if (sock == -1) { err = -errno; goto out; } ret = nbd_receive_negotiate(sock, name, &nbdflags, &size, &blocksize); if (ret == -1) { err = -errno; goto out; } s->sock = sock; s->size = size; s->blocksize = blocksize; err = 0; out: qemu_free(file); return err; }