Esempio n. 1
0
int setup_inet_connection(gchar *hostname, int port, gchar* name, CONNECTION_TYPE ctype, int* serverflags) {
	int sock;
	struct hostent *host;
	struct sockaddr_in addr;

	sock=0;
	if(ctype<CONNECTION_TYPE_CONNECT)
		goto end;
	if((sock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))<0) {
		strncpy(errstr, strerror(errno), errstr_len);
		goto err;
	}
	setmysockopt(sock);
	if(!(host=gethostbyname(hostname))) {
		strncpy(errstr, hstrerror(h_errno), errstr_len);
		goto err_open;
	}
	addr.sin_family=AF_INET;
	addr.sin_port=htons(port);
	addr.sin_addr.s_addr=*((int *) host->h_addr);
	if((connect(sock, (struct sockaddr *)&addr, sizeof(addr))<0)) {
		strncpy(errstr, strerror(errno), errstr_len);
		goto err_open;
	}
	sock=setup_connection_common(sock, name, ctype, serverflags);
	goto end;
err_open:
	close(sock);
err:
	sock=-1;
end:
	return sock;
}
Esempio n. 2
0
int setup_unix_connection(gchar* unixsock, gchar* name, CONNECTION_TYPE ctype, int* serverflags) {
	struct sockaddr_un addr;
	int sock;

	sock = 0;
	if(ctype<CONNECTION_TYPE_CONNECT) {
		goto end;
	}
	if((sock=socket(AF_UNIX, SOCK_STREAM, 0))<0) {
		strncpy(errstr, strerror(errno), errstr_len);
		goto err;
	}

	setmysockopt(sock);
	memset(&addr, 0, sizeof(struct sockaddr_un));
	addr.sun_family = AF_UNIX;
	strncpy(addr.sun_path, unixsock, 107);
	if(connect(sock, (struct sockaddr*)&addr, sizeof(addr))<0) {
		strncpy(errstr, strerror(errno), errstr_len);
		goto err_open;
	}
	sock = setup_connection_common(sock, name, ctype, serverflags);
	goto end;
err_open:
	close(sock);
err:
	sock=-1;
end:
	return sock;
}
Esempio n. 3
0
int throughput_test(char *name, int sock, char close_sock, int testflags)
{
	long long int i;
	char writebuf[1024];
	struct nbd_request req;
	int requests = 0;
	fd_set set;
	struct timeval tv;
	struct timeval start;
	struct timeval stop;
	double timespan;
	double speed;
	char speedchar[2] = { '\0', '\0' };
	int retval = 0;
	int serverflags = 0;
	signed int do_write = TRUE;
	pid_t mypid = getpid();
	char *print = getenv("NBD_TEST_SILENT");

	if (!(testflags & TEST_WRITE))
		testflags &= ~TEST_FLUSH;

	memset(writebuf, 'X', 1024);
	size = 0;
	if ((sock =
		 setup_connection_common(sock, name,
				  CONNECTION_TYPE_FULL,
				  &serverflags, testflags)) < 0) {
		g_warning("Could not open socket: %s", errstr);
		if(testflags & TEST_EXPECT_ERROR) {
			g_message("Test failed, as expected");
			retval = 0;
		} else {
			retval = -1;
		}
		goto err;
	}
	if ((testflags & TEST_FLUSH)
	    && ((serverflags & (NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA))
		!= (NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA))) {
		snprintf(errstr, errstr_len,
			 "Server did not supply flush capability flags");
		retval = -1;
		goto err_open;
	}
	req.magic = htonl(NBD_REQUEST_MAGIC);
	req.len = htonl(1024);
	if (gettimeofday(&start, NULL) < 0) {
		retval = -1;
		snprintf(errstr, errstr_len, "Could not measure start time: %s",
			 strerror(errno));
		goto err_open;
	}
	for (i = 0; i + 1024 <= size; i += 1024) {
		if (do_write) {
			int sendfua = (testflags & TEST_FLUSH)
			    && (((i >> 10) & 15) == 3);
			int sendflush = (testflags & TEST_FLUSH)
			    && (((i >> 10) & 15) == 11);
			req.type =
			    htonl((testflags & TEST_WRITE) ? NBD_CMD_WRITE :
				  NBD_CMD_READ);
			if (sendfua)
				req.type =
				    htonl(NBD_CMD_WRITE | NBD_CMD_FLAG_FUA);
			memcpy(&(req.handle), &i, sizeof(i));
			req.from = htonll(i);
			if (write_all(sock, &req, sizeof(req)) < 0) {
				retval = -1;
				goto err_open;
			}
			if (testflags & TEST_WRITE) {
				if (write_all(sock, writebuf, 1024) < 0) {
					retval = -1;
					goto err_open;
				}
			}
			++requests;
			if (sendflush) {
				long long int j = i ^ (1LL << 63);
				req.type = htonl(NBD_CMD_FLUSH);
				memcpy(&(req.handle), &j, sizeof(j));
				req.from = 0;
				req.len = 0;
				if (write_all(sock, &req, sizeof(req)) < 0) {
					retval = -1;
					goto err_open;
				}
				req.len = htonl(1024);
				++requests;
			}
		}
		do {
			FD_ZERO(&set);
			FD_SET(sock, &set);
			tv.tv_sec = 0;
			tv.tv_usec = 0;
			select(sock + 1, &set, NULL, NULL, &tv);
			if (FD_ISSET(sock, &set)) {
				/* Okay, there's something ready for
				 * reading here */
				int rv;
				if ((rv =
				     read_packet_check_header(sock,
							      (testflags &
							       TEST_WRITE) ? 0 :
							      1024, i)) < 0) {
					if (!(testflags & TEST_EXPECT_ERROR)
					    || rv != -2) {
						retval = -1;
					} else {
						printf("\n");
					}
					goto err_open;
				} else {
					if (testflags & TEST_EXPECT_ERROR) {
						retval = -1;
						goto err_open;
					}
				}
				--requests;
			}
		} while (FD_ISSET(sock, &set));
		/* Now wait until we can write again or until a second have
		 * passed, whichever comes first*/
		FD_ZERO(&set);
		FD_SET(sock, &set);
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		do_write = select(sock + 1, NULL, &set, NULL, &tv);
		if (!do_write)
			printf("Select finished\n");
		if (do_write < 0) {
			snprintf(errstr, errstr_len, "select: %s",
				 strerror(errno));
			retval = -1;
			goto err_open;
		}
		if(print == NULL) {
			printf("%d: Requests: %d  \r", (int)mypid, requests);
		}
	}
	/* Now empty the read buffer */
	do {
		FD_ZERO(&set);
		FD_SET(sock, &set);
		tv.tv_sec = 0;
		tv.tv_usec = 0;
		select(sock + 1, &set, NULL, NULL, &tv);
		if (FD_ISSET(sock, &set)) {
			/* Okay, there's something ready for
			 * reading here */
			read_packet_check_header(sock,
						 (testflags & TEST_WRITE) ? 0 :
						 1024, i);
			--requests;
		}
		if(print == NULL) {
			printf("%d: Requests: %d  \r", (int)mypid, requests);
		}
	} while (requests);
	printf("%d: Requests: %d  \n", (int)mypid, requests);
	if (gettimeofday(&stop, NULL) < 0) {
		retval = -1;
		snprintf(errstr, errstr_len, "Could not measure end time: %s",
			 strerror(errno));
		goto err_open;
	}
	timespan = timeval_diff_to_double(&stop, &start);
	speed = size / timespan;
	if (speed > 1024) {
		speed = speed / 1024.0;
		speedchar[0] = 'K';
	}
	if (speed > 1024) {
		speed = speed / 1024.0;
		speedchar[0] = 'M';
	}
	if (speed > 1024) {
		speed = speed / 1024.0;
		speedchar[0] = 'G';
	}
	g_message
	    ("%d: Throughput %s test (%s flushes) complete. Took %.3f seconds to complete, %.3f%sib/s",
	     (int)getpid(), (testflags & TEST_WRITE) ? "write" : "read",
	     (testflags & TEST_FLUSH) ? "with" : "without", timespan, speed,
	     speedchar);

err_open:
	if (close_sock) {
		close_connection(sock, CONNECTION_CLOSE_PROPERLY);
	}
err:
	return retval;
}
Esempio n. 4
0
int handshake_test(char *name, int sock, char close_sock, int testflags)
{
	int retval = -1;
	int serverflags = 0;
	u64 tmp64;
	uint32_t tmp32 = 0;

	/* This should work */
	if ((sock =
		 setup_connection_common(sock, name,
				  CONNECTION_TYPE_FULL,
				  &serverflags, testflags)) < 0) {
		g_warning("Could not open socket: %s", errstr);
		goto err;
	}

	/* Intentionally throw an unknown option at the server */
	tmp64 = htonll(opts_magic);
	WRITE_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
			 "Could not write magic: %s", strerror(errno));
	tmp32 = htonl(0x7654321);
	WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
			 "Could not write option: %s", strerror(errno));
	tmp32 = htonl((uint32_t) sizeof(tmp32));
	WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
			 "Could not write option length: %s", strerror(errno));
	WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
			 "Could not write option payload: %s", strerror(errno));
	/* Expect proper error from server */
	READ_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
			"Could not read magic: %s", strerror(errno));
	tmp64 = ntohll(tmp64);
	if (tmp64 != 0x3e889045565a9LL) {
		strncpy(errstr, "magic does not match", errstr_len);
		goto err;
	}
	READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
			"Could not read option: %s", strerror(errno));
	tmp32 = ntohl(tmp32);
	if (tmp32 != 0x7654321) {
		strncpy(errstr, "option does not match", errstr_len);
		goto err;
	}
	READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
			"Could not read status: %s", strerror(errno));
	tmp32 = ntohl(tmp32);
	if (tmp32 != NBD_REP_ERR_UNSUP) {
		strncpy(errstr, "status does not match", errstr_len);
		goto err;
	}
	READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
			"Could not read length: %s", strerror(errno));
	tmp32 = ntohl(tmp32);
	while (tmp32) {
		char buf[1024];
		size_t len = tmp32 < sizeof(buf) ? tmp32 : sizeof(buf);
		READ_ALL_ERRCHK(sock, buf, len, err,
				"Could not read payload: %s", strerror(errno));
		tmp32 -= len;
	}


	/* Send NBD_OPT_ABORT to close the connection */
	tmp64 = htonll(opts_magic);
	WRITE_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
			 "Could not write magic: %s", strerror(errno));
	tmp32 = htonl(NBD_OPT_ABORT);
	WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
			 "Could not write option: %s", strerror(errno));
	tmp32 = htonl((uint32_t) 0);
	WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
			 "Could not write option length: %s", strerror(errno));

	retval = 0;

	g_message("Handshake test completed. No errors encountered.");
err:
	return retval;
}
Esempio n. 5
0
int oversize_test(char *name, int sock, char close_sock, int testflags)
{
	int retval = 0;
	struct nbd_request req;
	struct nbd_reply rep;
	int i = 0;
	int serverflags = 0;
	pid_t G_GNUC_UNUSED mypid = getpid();
	char buf[((1024 * 1024) + sizeof(struct nbd_request) / 2) << 1];
	bool got_err;

	/* This should work */
	if ((sock =
		 setup_connection_common(sock, name,
				  CONNECTION_TYPE_FULL,
				  &serverflags, testflags)) < 0) {
		g_warning("Could not open socket: %s", errstr);
		retval = -1;
		goto err;
	}
	req.magic = htonl(NBD_REQUEST_MAGIC);
	req.type = htonl(NBD_CMD_READ);
	req.len = htonl(1024 * 1024);
	memcpy(&(req.handle), &i, sizeof(i));
	req.from = htonll(i);
	WRITE_ALL_ERR_RT(sock, &req, sizeof(req), err, -1,
			 "Could not write request: %s", strerror(errno));
	printf("%d: testing oversized request: %d: ", getpid(), ntohl(req.len));
	READ_ALL_ERR_RT(sock, &rep, sizeof(struct nbd_reply), err, -1,
			"Could not read reply header: %s", strerror(errno));
	READ_ALL_ERR_RT(sock, &buf, ntohl(req.len), err, -1,
			"Could not read data: %s", strerror(errno));
	if (rep.error) {
		snprintf(errstr, errstr_len, "Received unexpected error: %d",
			 rep.error);
		retval = -1;
		goto err;
	} else {
		printf("OK\n");
	}
	/* This probably should not work */
	i++;
	req.from = htonll(i);
	req.len = htonl(ntohl(req.len) + sizeof(struct nbd_request) / 2);
	WRITE_ALL_ERR_RT(sock, &req, sizeof(req), err, -1,
			 "Could not write request: %s", strerror(errno));
	printf("%d: testing oversized request: %d: ", getpid(), ntohl(req.len));
	READ_ALL_ERR_RT(sock, &rep, sizeof(struct nbd_reply), err, -1,
			"Could not read reply header: %s", strerror(errno));
	READ_ALL_ERR_RT(sock, &buf, ntohl(req.len), err, -1,
			"Could not read data: %s", strerror(errno));
	if (rep.error) {
		printf("Received expected error\n");
		got_err = true;
	} else {
		printf("OK\n");
		got_err = false;
	}
	/* ... unless this works, too */
	i++;
	req.from = htonll(i);
	req.len = htonl(ntohl(req.len) << 1);
	WRITE_ALL_ERR_RT(sock, &req, sizeof(req), err, -1,
			 "Could not write request: %s", strerror(errno));
	printf("%d: testing oversized request: %d: ", getpid(), ntohl(req.len));
	READ_ALL_ERR_RT(sock, &rep, sizeof(struct nbd_reply), err, -1,
			"Could not read reply header: %s", strerror(errno));
	READ_ALL_ERR_RT(sock, &buf, ntohl(req.len), err, -1,
			"Could not read data: %s", strerror(errno));
	if (rep.error) {
		printf("error\n");
	} else {
		printf("OK\n");
	}
	if ((rep.error && !got_err) || (!rep.error && got_err)) {
		printf("Received unexpected error\n");
		retval = -1;
	}
err:
	return retval;
}