From patchwork Fri Dec 3 11:09:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ronnie sahlberg X-Patchwork-Id: 74127 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 520701007D7 for ; Fri, 3 Dec 2010 22:59:53 +1100 (EST) Received: from localhost ([127.0.0.1]:43060 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1POTnR-0006iz-Cg for incoming@patchwork.ozlabs.org; Fri, 03 Dec 2010 06:27:25 -0500 Received: from [140.186.70.92] (port=59234 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1POTYK-0001oM-So for qemu-devel@nongnu.org; Fri, 03 Dec 2010 06:11:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1POTYJ-0002n6-Cj for qemu-devel@nongnu.org; Fri, 03 Dec 2010 06:11:48 -0500 Received: from mail-iw0-f173.google.com ([209.85.214.173]:39180) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1POTYJ-0002lQ-9Q for qemu-devel@nongnu.org; Fri, 03 Dec 2010 06:11:47 -0500 Received: by mail-iw0-f173.google.com with SMTP id 38so3529036iwn.4 for ; Fri, 03 Dec 2010 03:11:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:received:from:to:cc:subject :date:message-id:x-mailer:in-reply-to:references; bh=XautUeN5tddo8YRRKzQA19N9v1CDxskYkjyGreAtW7Y=; b=Luh2pJLQI8fO0JJBVALseybHo5uekPfZMnRAZdHj8VTeo9K7CJLvqqDviFYGX/ktmD tw8sNdnV5PH7AKZRxQhmjR2KHTqofXkFBepuBO3ROQyuWWA8fKCnySqsjuV0GbFcnl4h WazolLKqyFcnNxxaSuN43Ct7POmDQbxycAa6c= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=fo2Gf53ZLFxTqdNJRkQX14eR9IHh/UOgHOLgAW4Zz+rIs6Jt6Ja2gj8LTpWciJd6ys XIHD4u7GHJK5MKVySA05vRpZwe/P0kRwhm34Z749ODTQApw6A5MH3EHebjKFADjelwr9 4iBCefWTZ72+2JFxtZGE6g+i5POeAAayiz8D0= Received: by 10.231.79.15 with SMTP id n15mr1658135ibk.37.1291374707067; Fri, 03 Dec 2010 03:11:47 -0800 (PST) Received: from ronniesahlberg@gmail.com (CPE-121-216-183-74.lnse2.ken.bigpond.net.au [121.216.183.74]) by mx.google.com with ESMTPS id 34sm1485197ibi.8.2010.12.03.03.11.43 (version=TLSv1/SSLv3 cipher=RC4-MD5); Fri, 03 Dec 2010 03:11:46 -0800 (PST) Received: by ronniesahlberg@gmail.com (sSMTP sendmail emulation); Fri, 03 Dec 2010 22:11:18 +1100 From: ronniesahlberg@gmail.com To: qemu-devel@nongnu.org Date: Fri, 3 Dec 2010 22:09:49 +1100 Message-Id: <1291374593-17448-11-git-send-email-ronniesahlberg@gmail.com> X-Mailer: git-send-email 1.7.3.1 In-Reply-To: <1291374593-17448-1-git-send-email-ronniesahlberg@gmail.com> References: <1291374593-17448-1-git-send-email-ronniesahlberg@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: Ronnie Sahlberg Subject: [Qemu-devel] [PATCH 10/14] ./block/iscsi/sync.c X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Ronnie Sahlberg iscsi client library : sync.c This file contains functions for implementing a synchronous api layers ontop of the asynchronous library. These functions are all synchronous and thus blocking making them' useful mainly for simple applications where ease of use if more important than a fully performing async interface. ... ./block/iscsi/ contains a copy of a general purpose iscsi client library which is aimed at providing a clientside api for iscsi for both qemu/kvm as well as otther scsi related utilities. As such, there is need to make merging across various consumers, qemu/kvm being one of many here, as easy as possible when features are added to the library. As such, no consumer/qemu specific code is used in this library as well as coding guidelined might not be adhered to 100% It is the intention that this library will be useful for many and that iscsi use spawned from this will flourish. Signed-off-by: Ronnie Sahlberg --- block/iscsi/sync.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 282 insertions(+), 0 deletions(-) create mode 100644 block/iscsi/sync.c diff --git a/block/iscsi/sync.c b/block/iscsi/sync.c new file mode 100644 index 0000000..ca3cd56 --- /dev/null +++ b/block/iscsi/sync.c @@ -0,0 +1,282 @@ +/* + Copyright (C) 2010 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include +#include +#include "iscsi.h" +#include "iscsi-private.h" +#include "scsi-lowlevel.h" + +struct scsi_sync_state { + int finished; + struct scsi_task *task; +}; + +struct iscsi_sync_state { + int finished; + int status; +}; + +static void +event_loop(struct iscsi_context *iscsi, struct scsi_sync_state *state) +{ + struct pollfd pfd; + + while (state->finished == 0) { + pfd.fd = iscsi_get_fd(iscsi); + pfd.events = iscsi_which_events(iscsi); + + if (poll(&pfd, 1, -1) < 0) { + iscsi_set_error(iscsi, "Poll failed"); + return; + } + if (iscsi_service(iscsi, pfd.revents) < 0) { + iscsi_set_error(iscsi, + "iscsi_service failed with : %s\n", + iscsi_get_error(iscsi)); + return; + } + } +} + +/* + * Synchronous iSCSI commands + */ +static void +iscsi_sync_cb(struct iscsi_context *iscsi, int status, + void *command_data, void *private_data) +{ + struct iscsi_sync_state *state = private_data; + + state->status = status; + state->finished = 1; +} + +int +iscsi_connect_sync(struct iscsi_context *iscsi, const char *portal) +{ + struct iscsi_sync_state state; + + bzero(&state, sizeof(state)); + + if (iscsi_connect_async(iscsi, portal, + iscsi_sync_cb, &state) != 0) { + iscsi_set_error(iscsi, + "Failed to start connect() %s", + iscsi_get_error(iscsi)); + return -1; + } + + event_loop(iscsi, (struct scsi_sync_state *)&state); + + return state.status; +} + +int +iscsi_full_connect_sync(struct iscsi_context *iscsi, + const char *portal, int lun) +{ + struct iscsi_sync_state state; + + bzero(&state, sizeof(state)); + + if (iscsi_full_connect_async(iscsi, portal, lun, + iscsi_sync_cb, &state) != 0) { + iscsi_set_error(iscsi, + "Failed to start full connect %s", + iscsi_get_error(iscsi)); + return -1; + } + + event_loop(iscsi, (struct scsi_sync_state *)&state); + + return state.status; +} + +int iscsi_login_sync(struct iscsi_context *iscsi) +{ + struct iscsi_sync_state state; + + bzero(&state, sizeof(state)); + + if (iscsi_login_async(iscsi, iscsi_sync_cb, &state) != 0) { + iscsi_set_error(iscsi, "Failed to login. %s", + iscsi_get_error(iscsi)); + return -1; + } + + event_loop(iscsi, (struct scsi_sync_state *)&state); + + return state.status; +} + +int iscsi_logout_sync(struct iscsi_context *iscsi) +{ + struct iscsi_sync_state state; + + bzero(&state, sizeof(state)); + + if (iscsi_logout_async(iscsi, iscsi_sync_cb, &state) != 0) { + iscsi_set_error(iscsi, "Failed to start logout() %s", + iscsi_get_error(iscsi)); + return -1; + } + + event_loop(iscsi, (struct scsi_sync_state *)&state); + + return state.status; +} + + + +/* + * Synchronous SCSI commands + */ +static void +scsi_sync_cb(struct iscsi_context *iscsi, int status, void *command_data, + void *private_data) +{ + struct scsi_task *task = command_data; + struct scsi_sync_state *state = private_data; + + task->status = status; + state->finished = 1; + state->task = task; + iscsi_cbdata_steal_scsi_task(task); +} + +struct scsi_task * +iscsi_reportluns_sync(struct iscsi_context *iscsi, int report_type, + int alloc_len) +{ + struct scsi_sync_state state; + + bzero(&state, sizeof(state)); + + if (iscsi_reportluns_async(iscsi, report_type, alloc_len, + scsi_sync_cb, &state) != 0) { + iscsi_set_error(iscsi, "Failed to send ReportLuns command"); + return NULL; + } + + event_loop(iscsi, &state); + + return state.task; +} + + +struct scsi_task * +iscsi_testunitready_sync(struct iscsi_context *iscsi, int lun) +{ + struct scsi_sync_state state; + + bzero(&state, sizeof(state)); + + if (iscsi_testunitready_async(iscsi, lun, + scsi_sync_cb, &state) != 0) { + iscsi_set_error(iscsi, + "Failed to send TestUnitReady command"); + return NULL; + } + + event_loop(iscsi, &state); + + return state.task; +} + +struct scsi_task * +iscsi_inquiry_sync(struct iscsi_context *iscsi, int lun, int evpd, + int page_code, int maxsize) +{ + struct scsi_sync_state state; + + bzero(&state, sizeof(state)); + + if (iscsi_inquiry_async(iscsi, lun, evpd, page_code, maxsize, + scsi_sync_cb, &state) != 0) { + iscsi_set_error(iscsi, "Failed to send Inquiry command"); + return NULL; + } + + event_loop(iscsi, &state); + + return state.task; +} + +struct scsi_task * +iscsi_readcapacity10_sync(struct iscsi_context *iscsi, int lun, int lba, + int pmi) +{ + struct scsi_sync_state state; + + bzero(&state, sizeof(state)); + + if (iscsi_readcapacity10_async(iscsi, lun, lba, pmi, + scsi_sync_cb, &state) != 0) { + iscsi_set_error(iscsi, + "Failed to send ReadCapacity10 command"); + return NULL; + } + + event_loop(iscsi, &state); + + return state.task; +} + +struct scsi_task * +iscsi_synchronizecache10_sync(struct iscsi_context *iscsi, int lun, int lba, + int num_blocks, int syncnv, int immed) +{ + struct scsi_sync_state state; + + bzero(&state, sizeof(state)); + + if (iscsi_synchronizecache10_async(iscsi, lun, lba, num_blocks, + syncnv, immed, + scsi_sync_cb, &state) != 0) { + iscsi_set_error(iscsi, + "Failed to send SynchronizeCache10 command"); + return NULL; + } + + event_loop(iscsi, &state); + + return state.task; +} + +struct scsi_task * +iscsi_scsi_command_sync(struct iscsi_context *iscsi, int lun, + struct scsi_task *task, struct iscsi_data *data) +{ + struct scsi_sync_state state; + + bzero(&state, sizeof(state)); + + if (iscsi_scsi_command_async(iscsi, lun, task, + scsi_sync_cb, data, &state) != 0) { + iscsi_set_error(iscsi, "Failed to send SCSI command"); + return NULL; + } + + event_loop(iscsi, &state); + + return state.task; +} + +