Commit 5d4a434d authored by Rusty Russell's avatar Rusty Russell

iscsi: ccanize a little more, add silly simple test case.

parent cb522f25
LIBS= LIBS=
CC=gcc CC=gcc
CFLAGS=-g -O0 -Wall -W -I../.. "-D_U_=__attribute__((unused))" CFLAGS=-g -O0 -Wall -W -I../..
LIBISCSI_OBJ = socket.o init.o login.o nop.o pdu.o discovery.o scsi-command.o scsi-lowlevel.o LIBISCSI_OBJ = socket.o init.o login.o nop.o pdu.o discovery.o scsi-command.o scsi-lowlevel.o
all: tools/iscsiclient all: tools/iscsiclient
......
...@@ -20,6 +20,7 @@ int main(int argc, char *argv[]) ...@@ -20,6 +20,7 @@ int main(int argc, char *argv[])
return 1; return 1;
if (strcmp(argv[1], "depends") == 0) { if (strcmp(argv[1], "depends") == 0) {
printf("ccan/compiler\n");
return 0; return 0;
} }
......
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
...@@ -90,7 +90,7 @@ static void iscsi_free_discovery_addresses(struct iscsi_discovery_address *addre ...@@ -90,7 +90,7 @@ static void iscsi_free_discovery_addresses(struct iscsi_discovery_address *addre
free(addresses); free(addresses);
addresses = next; addresses = next;
} }
} }
int iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size) int iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size)
{ {
...@@ -121,7 +121,7 @@ int iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, ...@@ -121,7 +121,7 @@ int iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
pdu->callback(iscsi, ISCSI_STATUS_ERROR, NULL, pdu->private_data); pdu->callback(iscsi, ISCSI_STATUS_ERROR, NULL, pdu->private_data);
iscsi_free_discovery_addresses(targets); iscsi_free_discovery_addresses(targets);
return -1; return -1;
} }
/* parse the strings */ /* parse the strings */
if (!strncmp((char *)hdr, "TargetName=", 11)) { if (!strncmp((char *)hdr, "TargetName=", 11)) {
......
/* /*
Unix SMB/CIFS implementation. Unix SMB/CIFS implementation.
some simple double linked list macros some simple double linked list macros
......
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
......
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
...@@ -14,13 +14,11 @@ ...@@ -14,13 +14,11 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef CCAN_ISCSI_PRIVATE_H
#define CCAN_ISCSI_PRIVATE_H
#include <stdint.h> #include <stdint.h>
#ifndef _U_
#define _U_
#endif
#ifndef discard_const #ifndef discard_const
#define discard_const(ptr) ((void *)((intptr_t)(ptr))) #define discard_const(ptr) ((void *)((intptr_t)(ptr)))
#endif #endif
...@@ -141,3 +139,5 @@ int iscsi_process_logout_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pd ...@@ -141,3 +139,5 @@ int iscsi_process_logout_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pd
int iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size); int iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size);
int iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size, int *is_finished); int iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size, int *is_finished);
int iscsi_process_nop_out_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size); int iscsi_process_nop_out_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size);
#endif /* CCAN_ISCSI_PRIVATE_H */
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef CCAN_ISCSI_H
#define CCAN_ISCSI_H
struct iscsi_context; struct iscsi_context;
struct sockaddr; struct sockaddr;
...@@ -103,7 +105,7 @@ enum icsi_status { ISCSI_STATUS_GOOD =0, ...@@ -103,7 +105,7 @@ enum icsi_status { ISCSI_STATUS_GOOD =0,
ISCSI_STATUS_ERROR =0x0f000001 }; ISCSI_STATUS_ERROR =0x0f000001 };
/* /*
* Generic callback for completion of iscsi_*_async(). * Generic callback for completion of iscsi_*_async().
* command_data depends on status. * command_data depends on status.
*/ */
...@@ -125,7 +127,7 @@ typedef void (*iscsi_command_cb)(struct iscsi_context *iscsi, int status, void * ...@@ -125,7 +127,7 @@ typedef void (*iscsi_command_cb)(struct iscsi_context *iscsi, int status, void *
* ISCSI_STATUS_GOOD : Connection was successful. Command_data is NULL. * ISCSI_STATUS_GOOD : Connection was successful. Command_data is NULL.
* In this case the callback will be invoked a second time once the connection * In this case the callback will be invoked a second time once the connection
* is torn down. * is torn down.
* *
* ISCSI_STATUS_ERROR : Either failed to establish the connection, or an already established connection * ISCSI_STATUS_ERROR : Either failed to establish the connection, or an already established connection
* has failed with an error. * has failed with an error.
* *
...@@ -226,7 +228,7 @@ int iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb, unsign ...@@ -226,7 +228,7 @@ int iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb, unsign
* *
* status : * status :
* ISCSI_STATUS_GOOD the scsi command completed successfullt on the target. * ISCSI_STATUS_GOOD the scsi command completed successfullt on the target.
* If this scsi command returns DATA-IN, that data is stored in an scsi_task structure * If this scsi command returns DATA-IN, that data is stored in an scsi_task structure
* returned in the command_data parameter. This buffer will be automatically freed once the callback * returned in the command_data parameter. This buffer will be automatically freed once the callback
* returns. * returns.
* *
...@@ -259,4 +261,4 @@ int iscsi_write10_async(struct iscsi_context *iscsi, int lun, iscsi_command_cb c ...@@ -259,4 +261,4 @@ int iscsi_write10_async(struct iscsi_context *iscsi, int lun, iscsi_command_cb c
int iscsi_modesense6_async(struct iscsi_context *iscsi, int lun, iscsi_command_cb cb, int dbd, int pc, int page_code, int sub_page_code, unsigned char alloc_len, void *private_data); int iscsi_modesense6_async(struct iscsi_context *iscsi, int lun, iscsi_command_cb cb, int dbd, int pc, int page_code, int sub_page_code, unsigned char alloc_len, void *private_data);
#endif /* CCAN_ISCSI_H */
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <ccan/compiler/compiler.h>
#include "iscsi.h" #include "iscsi.h"
#include "iscsi-private.h" #include "iscsi-private.h"
...@@ -212,7 +213,7 @@ int iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu ...@@ -212,7 +213,7 @@ int iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu
* some parameters. * some parameters.
* we should also do proper handshaking if the target is not yet prepared to transition * we should also do proper handshaking if the target is not yet prepared to transition
* to the next stage * to the next stage
*/ */
status = ntohs(*(uint16_t *)&hdr[36]); status = ntohs(*(uint16_t *)&hdr[36]);
if (status != 0) { if (status != 0) {
pdu->callback(iscsi, ISCSI_STATUS_ERROR, NULL, pdu->private_data); pdu->callback(iscsi, ISCSI_STATUS_ERROR, NULL, pdu->private_data);
...@@ -267,7 +268,7 @@ int iscsi_logout_async(struct iscsi_context *iscsi, iscsi_command_cb cb, void *p ...@@ -267,7 +268,7 @@ int iscsi_logout_async(struct iscsi_context *iscsi, iscsi_command_cb cb, void *p
return 0; return 0;
} }
int iscsi_process_logout_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size _U_) int iscsi_process_logout_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size UNNEEDED_ATTRIBUTE)
{ {
iscsi->is_loggedin = 0; iscsi->is_loggedin = 0;
pdu->callback(iscsi, ISCSI_STATUS_GOOD, NULL, pdu->private_data); pdu->callback(iscsi, ISCSI_STATUS_GOOD, NULL, pdu->private_data);
......
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
......
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
...@@ -104,7 +104,7 @@ int iscsi_add_data(struct iscsi_data *data, unsigned char *dptr, int dsize, int ...@@ -104,7 +104,7 @@ int iscsi_add_data(struct iscsi_data *data, unsigned char *dptr, int dsize, int
aligned = (aligned+3)&0xfffffffc; aligned = (aligned+3)&0xfffffffc;
} }
buf = malloc(aligned); buf = malloc(aligned);
if (buf == NULL) { if (buf == NULL) {
printf("failed to allocate buffer for %d bytes\n", len); printf("failed to allocate buffer for %d bytes\n", len);
return -2; return -2;
} }
...@@ -125,9 +125,6 @@ int iscsi_add_data(struct iscsi_data *data, unsigned char *dptr, int dsize, int ...@@ -125,9 +125,6 @@ int iscsi_add_data(struct iscsi_data *data, unsigned char *dptr, int dsize, int
int iscsi_pdu_add_data(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, unsigned char *dptr, int dsize) int iscsi_pdu_add_data(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, unsigned char *dptr, int dsize)
{ {
int len, aligned;
unsigned char *buf;
if (pdu == NULL) { if (pdu == NULL) {
printf("trying to add data to NULL pdu\n"); printf("trying to add data to NULL pdu\n");
return -1; return -1;
......
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
...@@ -50,16 +50,16 @@ static void iscsi_scsi_response_cb(struct iscsi_context *iscsi, int status, void ...@@ -50,16 +50,16 @@ static void iscsi_scsi_response_cb(struct iscsi_context *iscsi, int status, void
switch (status) { switch (status) {
case ISCSI_STATUS_CHECK_CONDITION: case ISCSI_STATUS_CHECK_CONDITION:
scsi_cbdata->callback(iscsi, ISCSI_STATUS_CHECK_CONDITION, task, scsi_cbdata->private_data); scsi_cbdata->callback(iscsi, ISCSI_STATUS_CHECK_CONDITION, task, scsi_cbdata->private_data);
return; return;
case ISCSI_STATUS_GOOD: case ISCSI_STATUS_GOOD:
scsi_cbdata->callback(iscsi, ISCSI_STATUS_GOOD, task, scsi_cbdata->private_data); scsi_cbdata->callback(iscsi, ISCSI_STATUS_GOOD, task, scsi_cbdata->private_data);
return; return;
default: default:
printf("Cant handle scsi status %d yet\n", status); printf("Cant handle scsi status %d yet\n", status);
scsi_cbdata->callback(iscsi, ISCSI_STATUS_ERROR, task, scsi_cbdata->private_data); scsi_cbdata->callback(iscsi, ISCSI_STATUS_ERROR, task, scsi_cbdata->private_data);
} }
} }
...@@ -228,12 +228,12 @@ int iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, ...@@ -228,12 +228,12 @@ int iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
task->sense.key = task->datain.data[4] & 0x0f; task->sense.key = task->datain.data[4] & 0x0f;
task->sense.ascq = ntohs(*(uint16_t *)&(task->datain.data[14])); task->sense.ascq = ntohs(*(uint16_t *)&(task->datain.data[14]));
pdu->callback(iscsi, ISCSI_STATUS_CHECK_CONDITION, task, pdu->private_data); pdu->callback(iscsi, ISCSI_STATUS_CHECK_CONDITION, task, pdu->private_data);
break; break;
default: default:
printf("Unknown status :%d\n", status); printf("Unknown status :%d\n", status);
pdu->callback(iscsi, ISCSI_STATUS_ERROR, task, pdu->private_data); pdu->callback(iscsi, ISCSI_STATUS_ERROR, task, pdu->private_data);
return -1; return -1;
} }
......
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
along with this program; if not, see <http://www.gnu.org/licenses/>. along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
/* /*
* would be nice if this could grow into a full blown library for scsi to * would be nice if this could grow into a full blown library for scsi to
* 1, build a CDB * 1, build a CDB
* 2, check how big a complete data-in structure needs to be * 2, check how big a complete data-in structure needs to be
* 3, unmarshall data-in into a real structure * 3, unmarshall data-in into a real structure
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <strings.h> #include <strings.h>
#include <stdint.h> #include <stdint.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <ccan/compiler/compiler.h>
#include "scsi-lowlevel.h" #include "scsi-lowlevel.h"
#include "dlinklist.h" #include "dlinklist.h"
...@@ -44,7 +45,7 @@ void scsi_free_scsi_task(struct scsi_task *task) ...@@ -44,7 +45,7 @@ void scsi_free_scsi_task(struct scsi_task *task)
free(task); free(task);
} }
void *scsi_malloc(struct scsi_task *task, size_t size) static void *scsi_malloc(struct scsi_task *task, size_t size)
{ {
struct scsi_allocated_memory *mem; struct scsi_allocated_memory *mem;
...@@ -161,7 +162,7 @@ static struct scsi_reportluns_list *scsi_reportluns_datain_unmarshall(struct scs ...@@ -161,7 +162,7 @@ static struct scsi_reportluns_list *scsi_reportluns_datain_unmarshall(struct scs
} }
return list; return list;
} }
/* /*
...@@ -199,7 +200,8 @@ struct scsi_task *scsi_cdb_readcapacity10(int lba, int pmi) ...@@ -199,7 +200,8 @@ struct scsi_task *scsi_cdb_readcapacity10(int lba, int pmi)
/* /*
* parse the data in blob and calcualte the size of a full readcapacity10 datain structure * parse the data in blob and calcualte the size of a full readcapacity10 datain structure
*/ */
static int scsi_readcapacity10_datain_getfullsize(struct scsi_task *task _U_) static int scsi_readcapacity10_datain_getfullsize(struct scsi_task *task
UNNEEDED_ATTRIBUTE)
{ {
return 8; return 8;
} }
...@@ -282,7 +284,7 @@ static int scsi_inquiry_datain_getfullsize(struct scsi_task *task) ...@@ -282,7 +284,7 @@ static int scsi_inquiry_datain_getfullsize(struct scsi_task *task)
/* /*
* unmarshall the data in blob for inquiry into a structure * unmarshall the data in blob for inquiry into a structure
*/ */
void *scsi_inquiry_datain_unmarshall(struct scsi_task *task) static void *scsi_inquiry_datain_unmarshall(struct scsi_task *task)
{ {
struct scsi_inquiry_standard *inq; struct scsi_inquiry_standard *inq;
......
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
...@@ -14,10 +14,8 @@ ...@@ -14,10 +14,8 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef CCAN_ISCSI_SCSI_LOWLEVEL_H
#ifndef _U_ #define CCAN_ISCSI_SCSI_LOWLEVEL_H
#define _U_
#endif
#define SCSI_CDB_MAX_SIZE 16 #define SCSI_CDB_MAX_SIZE 16
...@@ -165,7 +163,7 @@ struct scsi_inquiry_standard { ...@@ -165,7 +163,7 @@ struct scsi_inquiry_standard {
char vendor_identification[8+1]; char vendor_identification[8+1];
char product_identification[16+1]; char product_identification[16+1];
char product_revision_level[4+1]; char product_revision_level[4+1];
}; };
struct scsi_task *scsi_cdb_inquiry(int evpd, int page_code, int alloc_len); struct scsi_task *scsi_cdb_inquiry(int evpd, int page_code, int alloc_len);
...@@ -192,3 +190,4 @@ void *scsi_datain_unmarshall(struct scsi_task *task); ...@@ -192,3 +190,4 @@ void *scsi_datain_unmarshall(struct scsi_task *task);
struct scsi_task *scsi_cdb_read10(int lba, int xferlen, int blocksize); struct scsi_task *scsi_cdb_read10(int lba, int xferlen, int blocksize);
struct scsi_task *scsi_cdb_write10(int lba, int xferlen, int fua, int fuanv, int blocksize); struct scsi_task *scsi_cdb_write10(int lba, int xferlen, int fua, int fuanv, int blocksize);
#endif /* CCAN_ISCSI_SCSI_LOWLEVEL_H */
/* /*
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com> Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
...@@ -43,8 +43,11 @@ int iscsi_connect_async(struct iscsi_context *iscsi, const char *target, iscsi_c ...@@ -43,8 +43,11 @@ int iscsi_connect_async(struct iscsi_context *iscsi, const char *target, iscsi_c
int port = 3260; int port = 3260;
char *str; char *str;
char *addr; char *addr;
struct sockaddr_storage s; union {
struct sockaddr_in *sin = (struct sockaddr_in *)&s; struct sockaddr sa;
struct sockaddr_storage ss;
struct sockaddr_in sin;
} s;
int socksize; int socksize;
if (iscsi == NULL) { if (iscsi == NULL) {
...@@ -75,22 +78,22 @@ int iscsi_connect_async(struct iscsi_context *iscsi, const char *target, iscsi_c ...@@ -75,22 +78,22 @@ int iscsi_connect_async(struct iscsi_context *iscsi, const char *target, iscsi_c
str[0] = 0; str[0] = 0;
} }
sin->sin_family = AF_INET; s.sin.sin_family = AF_INET;
sin->sin_port = htons(port); s.sin.sin_port = htons(port);
if (inet_pton(AF_INET, addr, &sin->sin_addr) != 1) { if (inet_pton(AF_INET, addr, &s.sin.sin_addr) != 1) {
printf("failed to convert to ip address\n"); printf("failed to convert to ip address\n");
free(addr); free(addr);
return -4; return -4;
} }
free(addr); free(addr);
switch (s.ss_family) { switch (s.ss.ss_family) {
case AF_INET: case AF_INET:
iscsi->fd = socket(AF_INET, SOCK_STREAM, 0); iscsi->fd = socket(AF_INET, SOCK_STREAM, 0);
socksize = sizeof(struct sockaddr_in); socksize = sizeof(struct sockaddr_in);
break; break;
default: default:
printf("Unknown family :%d\n", s.ss_family); printf("Unknown family :%d\n", s.ss.ss_family);
return -5; return -5;
} }
...@@ -106,13 +109,13 @@ int iscsi_connect_async(struct iscsi_context *iscsi, const char *target, iscsi_c ...@@ -106,13 +109,13 @@ int iscsi_connect_async(struct iscsi_context *iscsi, const char *target, iscsi_c
set_nonblocking(iscsi->fd); set_nonblocking(iscsi->fd);
if (connect(iscsi->fd, (struct sockaddr *)&s, socksize) != 0 && errno != EINPROGRESS) { if (connect(iscsi->fd, &s.sa, socksize) != 0 && errno != EINPROGRESS) {
printf("Connect failed errno : %s (%d)\n", strerror(errno), errno); printf("Connect failed errno : %s (%d)\n", strerror(errno), errno);
return -7; return -7;
} }
return 0; return 0;
} }
int iscsi_disconnect(struct iscsi_context *iscsi) int iscsi_disconnect(struct iscsi_context *iscsi)
{ {
...@@ -153,7 +156,7 @@ int iscsi_which_events(struct iscsi_context *iscsi) ...@@ -153,7 +156,7 @@ int iscsi_which_events(struct iscsi_context *iscsi)
if (iscsi->is_connected == 0) { if (iscsi->is_connected == 0) {
events |= POLLOUT; events |= POLLOUT;
} }
if (iscsi->outqueue) { if (iscsi->outqueue) {
events |= POLLOUT; events |= POLLOUT;
......
#include <ccan/iscsi/iscsi.h>
#include <ccan/iscsi/discovery.c>
#include <ccan/iscsi/socket.c>
#include <ccan/iscsi/init.c>
#include <ccan/iscsi/pdu.c>
#include <ccan/iscsi/scsi-lowlevel.c>
#include <ccan/iscsi/nop.c>
#include <ccan/iscsi/login.c>
#include <ccan/iscsi/scsi-command.c>
#include <ccan/tap/tap.h>
int main(void)
{
struct iscsi_context *iscsi;
plan_tests(2);
iscsi = iscsi_create_context("some name");
ok1(iscsi);
ok1(iscsi_destroy_context(iscsi) == 0);
/* This exits depending on whether all tests passed */
return exit_status();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment