--- open-iscsi-2.0-707/usr/iscsi-dbconvert.c.orig	2007-03-05 15:44:00.698951427 +0100
+++ open-iscsi-2.0-707/usr/iscsi-dbconvert.c	2007-03-05 15:30:56.000000000 +0100
@@ -0,0 +1,130 @@
+/*
+ * iSCSI Database conversion Utility
+ *
+ * Copyright (C) 2007 Hannes Reinecke
+ * Copyright (C) 2007 SUSE Linux Products GmbH. All rights reserved.
+ *
+ * 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.
+ *
+ * See the file COPYING included with this distribution for more details.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "idbm.h"
+#include "log.h"
+#include "util.h"
+
+static char program_name[] = "iscsi-dbconvert";
+
+extern idbm_t* compat_idbm_init(char *configfile);
+extern int compat_idbm_convert_discovery(idbm_t *db, char *db_dir);
+extern int compat_idbm_convert_nodes(idbm_t *db, char *db_dir);
+
+static struct option const long_options[] =
+{
+	{"config", required_argument, NULL, 'c'},
+	{"debug", required_argument, NULL, 'c'},
+	{"dbdir", required_argument, NULL, 'i'},
+	{"etcdir", required_argument, NULL, 'o'},
+	{"help", no_argument, NULL, 'h'},
+	{NULL, 0, NULL, 0},
+};
+static char *short_options = "c:d:hi:o:";
+
+static void usage(int status)
+{
+	if (status != 0)
+		fprintf(stderr, "Try `%s --help' for more information.\n",
+			program_name);
+	else {
+		printf("\
+iscsiadm -m discovery [ -cdhV ] [ -t type -p ip:port [ -l ] ] | [ -p ip:port ] \
+[ -o operation ] [ -n name ] [ -v value ]\n\
+iscsiadm -m node [ -cdhV ] [ -L all,manual,automatic ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p ip:port | -P sysdir | -r recordid ] [ -l | -u ] ] \
+[ [ -o  operation  ] [ -n name ] [ -v value ] [ -p ip:port ] ]\n\
+iscsiadm -m session [ -dhV ] [ [ -r recordid:sessionid | -P sysdir ] [ -i | -R | -u | -s ] [ -o operation ] [ -n name ] [ -v value ] ]\n");
+	}
+	exit(status == 0 ? 0 : -1);
+}
+
+int
+main(int argc, char **argv)
+{
+	int rc;
+	char *config_file = CONFIG_FILE;
+	char *dbdir = "/var/db/open-iscsi";
+	char *etcdir = "/etc/iscsi";
+	int ch, longindex;
+	idbm_t *compat_db, *db;
+
+	/* enable stdout logging */
+	log_daemon = 0;
+	log_init(program_name, 1024);
+
+	optopt = 0;
+	while ((ch = getopt_long(argc, argv, short_options,
+				 long_options, &longindex)) >= 0) {
+		switch (ch) {
+		case 'c':
+			config_file = optarg;
+			break;
+		case 'd':
+			log_level = atoi(optarg);
+			break;
+		case 'i':
+			dbdir = optarg;
+			break;
+		case 'o':
+			etcdir = optarg;
+			break;
+		case 'h':
+			usage(0);
+			break;
+		}
+	}
+
+	if (optopt) {
+		log_error("unrecognized character '%c'", optopt);
+		return -1;
+	}
+
+	compat_db = compat_idbm_init(config_file);
+	if (!compat_db) {
+		log_warning("exiting due to idbm configuration error");
+		return -1;
+	}
+
+	
+	/* First get all db discovery records */
+	if (!compat_idbm_convert_discovery(compat_db, dbdir)) {
+		
+		log_debug(1, "no records found!");
+		rc = 0;
+	}
+
+	/* First get all db discovery records */
+	if (!compat_idbm_convert_nodes(compat_db, dbdir)) {
+		
+		log_debug(1, "no records found!");
+		rc = 0;
+	}
+
+	return 0;
+}
--- open-iscsi-2.0-707/usr/idbm-compat.c.orig	2007-03-05 15:44:08.745857754 +0100
+++ open-iscsi-2.0-707/usr/idbm-compat.c	2007-03-05 15:43:00.862083839 +0100
@@ -0,0 +1,297 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+
+#if defined(Linux)
+#define DB_DBM_HSEARCH 1
+#include <db.h>
+#elif defined(FreeBSD)
+#define DB_DBM_HSEARCH 1
+#include <ndbm.h>
+#endif
+
+#define TARGET_NAME_MAXLEN 255
+
+#include "idbm.h"
+#include "log.h"
+#include "util.h"
+#include "config-compat.h"
+
+
+#define IDBM_LOCK_EX	2    /* Exclusive lock.  */
+#define IDBM_LOCK_UN	8    /* Unlock.  */
+#define IDBM_HIDE	0    /* Hide parameter when print. */
+#define IDBM_SHOW	1    /* Show parameter when print. */
+#define IDBM_MASKED	2    /* Show "stars" instead of real value when print */
+
+idbm_t*
+compat_idbm_init(char *configfile)
+{
+	idbm_t *db;
+
+	db = malloc(sizeof(idbm_t));
+	if (!db) {
+		log_error("out of memory on idbm allocation");
+		return NULL;
+	}
+	memset(db, 0, sizeof(idbm_t));
+
+	db->configfile = strdup(configfile);
+
+	return db;
+}
+
+static void
+idbm_close(DBM *dbm)
+{
+	dbm_close(dbm);
+}
+
+static DBM*
+idbm_open(char *filename, int flags)
+{
+	DBM *dbm;
+
+	if (flags & O_CREAT) {
+		char *dirname, *ptr;
+
+		dirname = strdup(filename);
+		if (dirname && (ptr = strrchr(dirname, '/'))) {
+			*ptr = '\0';
+		} else if (!dirname)
+			return NULL;
+
+		if (access(dirname, F_OK) != 0) {
+			if (mkdir(dirname, 0755) != 0) {
+				free(dirname);
+				log_error("can't create file '%s'", filename);
+				return NULL;
+			}
+		}
+		free(dirname);
+	}
+
+	/* Now open the database */
+	dbm = dbm_open(filename, flags, 0666);
+	if (!dbm) {
+		log_error("discovery DB '%s' open failed", filename);
+		return NULL;
+	}
+
+	return dbm;
+}
+
+static int idbm_open_dbs(idbm_t *db, char *db_dir)
+{
+	char db_file[255];
+
+	sprintf(db_file,"%s/discovery", db_dir);
+
+	if (db->refs > 0) {
+		db->refs++;
+		return 0;
+	}
+
+	if ((db->discdb = idbm_open(db_file, access(db_file, F_OK) != 0 ?
+				    O_CREAT|O_RDWR : O_RDWR)) == NULL) {
+		return -1;
+	}
+	
+	sprintf(db_file,"%s/node", db_dir);
+
+	if ((db->nodedb = idbm_open(db_file, access(db_file, F_OK) != 0 ?
+				    O_CREAT|O_RDWR : O_RDWR)) == NULL) {
+		idbm_close(db->discdb);
+		return -1;
+	}
+
+	db->refs = 1;
+	
+	return 0;
+}
+
+static void idbm_close_dbs(idbm_t *db)
+{
+	if (db->refs > 1) {
+		db->refs--;
+		return;
+	}
+	
+	idbm_close(db->discdb);
+	idbm_close(db->nodedb);
+	db->refs = 0;
+}
+
+static void
+compat_sync_discovery(discovery_rec_t *d, compat_discovery_rec_t *c)
+{
+	memcpy(d, c, sizeof(compat_discovery_rec_t));
+	d->u.sendtargets.conn_timeo.login_timeout =
+		c->u.sendtargets.conn_timeo.login_timeout;
+	d->u.sendtargets.conn_timeo.logout_timeout =
+		c->u.sendtargets.conn_timeo.login_timeout;
+	d->u.sendtargets.conn_timeo.auth_timeout =
+		c->u.sendtargets.conn_timeo.auth_timeout;
+	d->u.sendtargets.conn_timeo.active_timeout =
+		c->u.sendtargets.conn_timeo.active_timeout;
+	d->u.sendtargets.conn_timeo.idle_timeout =
+		c->u.sendtargets.conn_timeo.idle_timeout;
+	d->u.sendtargets.conn_timeo.ping_timeout =
+		c->u.sendtargets.conn_timeo.ping_timeout;
+	d->u.sendtargets.conn_timeo.noop_out_interval =
+		c->u.sendtargets.conn_timeo.noop_out_interval;
+	d->u.sendtargets.conn_timeo.noop_out_timeout =
+		c->u.sendtargets.conn_timeo.noop_out_timeout;
+}
+
+int
+compat_idbm_convert_discovery(idbm_t *db, char *db_dir)
+{
+	int found = 0, ret;
+	datum key, data;
+	DBM *dbm;
+	compat_discovery_rec_t compat_drec;
+	discovery_rec_t drec;
+
+	ret = idbm_open_dbs(db, db_dir);
+	if (ret)
+		return -1;
+
+	dbm = db->discdb;
+
+	for (key=dbm_firstkey(dbm); key.dptr != NULL; key=dbm_nextkey(dbm)) {
+		data = dbm_fetch(dbm, key);
+		compat_node_rec_t *rec = (compat_node_rec_t*)data.dptr;
+		if (rec != NULL) {
+			memcpy(&compat_drec, rec,
+			       sizeof(compat_discovery_rec_t));
+			log_debug(3, "converting [%06x] %s:%d : ",
+				  compat_drec.id,
+				  compat_drec.u.sendtargets.address,
+				  compat_drec.u.sendtargets.port);
+			compat_sync_discovery(&drec, &compat_drec);
+
+			if (idbm_add_discovery(db, &drec)) {
+				log_debug(3, "failed.\n");
+			} else {
+				log_debug(3, "ok.\n");
+			}
+			found++;
+		}
+	}
+
+	idbm_close_dbs(db);
+
+	return found;
+}
+
+void
+compat_sync_nodes(node_rec_t *d, compat_node_rec_t *c)
+{
+	memcpy(d, c, sizeof(compat_node_rec_t));
+	
+	d->session.iscsi.protocol =
+		c->session.iscsi.protocol;
+	d->session.iscsi.InitialR2T =
+		c->session.iscsi.InitialR2T;
+	d->session.iscsi.ImmediateData =
+		c->session.iscsi.ImmediateData;
+	d->session.iscsi.FirstBurstLength =
+		c->session.iscsi.FirstBurstLength;
+	d->session.iscsi.MaxBurstLength =
+		c->session.iscsi.MaxBurstLength;
+	d->session.iscsi.DefaultTime2Wait =
+		c->session.iscsi.DefaultTime2Wait;
+	d->session.iscsi.DefaultTime2Retain =
+		c->session.iscsi.DefaultTime2Retain;
+	d->session.iscsi.MaxConnections =
+		c->session.iscsi.MaxConnections;
+	d->session.iscsi.MaxOutstandingR2T =
+		c->session.iscsi.MaxOutstandingR2T;
+	d->session.iscsi.ERL =
+		c->session.iscsi.ERL;
+
+	d->conn[0].startup =
+		c->conn[0].startup;
+	memcpy(d->conn[0].address,
+	       c->conn[0].address, NI_MAXHOST);
+	d->conn[0].port = c->conn[0].port;
+	d->conn[0].tcp.window_size =
+		c->conn[0].tcp.window_size;
+	d->conn[0].tcp.type_of_service =
+		c->conn[0].tcp.type_of_service;
+	d->conn[0].timeo.login_timeout =
+		c->conn[0].timeo.login_timeout;
+	d->conn[0].timeo.logout_timeout =
+		c->conn[0].timeo.login_timeout;
+	d->conn[0].timeo.auth_timeout =
+		c->conn[0].timeo.auth_timeout;
+	d->conn[0].timeo.active_timeout =
+		c->conn[0].timeo.active_timeout;
+	d->conn[0].timeo.idle_timeout =
+		c->conn[0].timeo.idle_timeout;
+	d->conn[0].timeo.ping_timeout =
+		c->conn[0].timeo.ping_timeout;
+	d->conn[0].timeo.noop_out_interval =
+		c->conn[0].timeo.noop_out_interval;
+	d->conn[0].timeo.noop_out_timeout =
+		c->conn[0].timeo.noop_out_timeout;
+	d->conn[0].iscsi.MaxRecvDataSegmentLength =
+		c->conn[0].iscsi.MaxRecvDataSegmentLength;
+	d->conn[0].iscsi.MaxXmitDataSegmentLength =
+		c->conn[0].iscsi.MaxRecvDataSegmentLength;
+	d->conn[0].iscsi.HeaderDigest =
+		c->conn[0].iscsi.HeaderDigest;
+	d->conn[0].iscsi.DataDigest =
+		c->conn[0].iscsi.DataDigest;
+	d->conn[0].iscsi.IFMarker =
+		c->conn[0].iscsi.IFMarker;
+	d->conn[0].iscsi.OFMarker =
+		c->conn[0].iscsi.OFMarker;
+}
+
+int
+compat_idbm_convert_nodes(idbm_t *db, char *db_dir)
+{
+	int found = 0, ret;
+	datum key, data;
+	DBM *dbm;
+	node_rec_t rec;
+
+	ret = idbm_open_dbs(db, db_dir);
+	if (ret)
+		return -1;
+
+	dbm = db->nodedb;
+
+	for (key=dbm_firstkey(dbm); key.dptr != NULL; key=dbm_nextkey(dbm)) {
+		data = dbm_fetch(dbm, key);
+		compat_node_rec_t *crec = (compat_node_rec_t*)data.dptr;
+		if (crec != NULL) {
+			log_debug(3, "converting [%06x] %s:%d,%d %s : ",
+				  crec->id,
+				  crec->conn[0].address,
+				  crec->conn[0].port,
+				  crec->tpgt, crec->name);
+			compat_sync_nodes(&rec, crec);
+
+			if (idbm_new_node(db, &rec)) {
+				log_debug(3, "failed.\n");
+			} else {
+				log_debug(3, "ok.\n");
+			}
+			found++;
+		}
+	}
+
+	idbm_close_dbs(db);
+
+	return found;
+}
+
--- open-iscsi-2.0-707/usr/config-compat.h.orig	2007-03-05 15:44:15.345960716 +0100
+++ open-iscsi-2.0-707/usr/config-compat.h	2007-03-05 14:44:25.000000000 +0100
@@ -0,0 +1,113 @@
+/*
+ * iSCSI Configuration
+ *
+ * Copyright (C) 2002 Cisco Systems, Inc.
+ * maintained by linux-iscsi-devel@lists.sourceforge.net
+ *
+ * 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.
+ *
+ * See the file COPYING included with this distribution for more details.
+ */
+
+#ifndef CONFIG_COMPAT_H
+#define CONFIG_COMPAT_H
+
+/* all per-connection timeouts go in this structure.
+ * this structure is per-portal, and can be configured
+ * both by TargetName and Subnet.
+ */
+struct iscsi_compat_connection_timeout_config {
+	int login_timeout;
+	int auth_timeout;
+	int active_timeout;
+	int idle_timeout;
+	int ping_timeout;
+	int noop_out_interval;
+	int noop_out_timeout;
+};
+
+struct iscsi_compat_conn_operational_config {
+	int MaxRecvDataSegmentLength;
+	int HeaderDigest;
+	int DataDigest;
+	int IFMarker;
+	int OFMarker;
+};
+
+/* all iSCSI operational params go in this structure.
+ * this structure is per-portal, and can be configured
+ * both by TargetName and Subnet.
+ */
+struct iscsi_compat_session_operational_config {
+	int protocol;
+	int InitialR2T;
+	int ImmediateData;
+	int FirstBurstLength;
+	int MaxBurstLength;
+	int DefaultTime2Wait;
+	int DefaultTime2Retain;
+	int MaxConnections;
+	int MaxOutstandingR2T;
+	int ERL;
+};
+
+struct iscsi_compat_sendtargets_config {
+	char address[NI_MAXHOST];
+	int port;
+	int continuous;
+	int send_async_text;
+	int reopen_max;
+	struct iscsi_auth_config auth;
+	struct iscsi_compat_connection_timeout_config conn_timeo;
+};
+
+typedef struct compat_conn_rec {
+	iscsi_startup_e				startup;
+	char					address[NI_MAXHOST];
+	int					port;
+	struct iscsi_tcp_config			tcp;
+	struct iscsi_compat_connection_timeout_config	timeo;
+	struct iscsi_compat_conn_operational_config	iscsi;
+} compat_conn_rec_t;
+
+typedef struct compat_session_rec {
+	int					initial_cmdsn;
+	int					reopen_max;
+	struct iscsi_auth_config		auth;
+	struct iscsi_session_timeout_config	timeo;
+	struct iscsi_error_timeout_config	err_timeo;
+	struct iscsi_compat_session_operational_config	iscsi;
+} compat_session_rec_t;
+
+typedef struct compat_node_rec {
+	int			id;
+	int			dbversion;
+	char			name[TARGET_NAME_MAXLEN];
+	char			transport_name[ISCSI_TRANSPORT_NAME_MAXLEN];
+	int			tpgt;
+	int			active_conn;
+	iscsi_startup_e		startup;
+	compat_session_rec_t		session;
+	compat_conn_rec_t		conn[ISCSI_CONN_MAX];
+} compat_node_rec_t;
+
+typedef struct compat_discovery_rec {
+	int					id;
+	int					dbversion;
+	iscsi_startup_e				startup;
+	discovery_type_e			type;
+	union {
+		struct iscsi_compat_sendtargets_config	sendtargets;
+		struct iscsi_slp_config		slp;
+	} u;
+} compat_discovery_rec_t;
+
+#endif /* CONFIG_H */
--- open-iscsi-2.0-707/usr/Makefile	2007/03/05 14:56:15	1.13
+++ open-iscsi-2.0-707/usr/Makefile	2007/03/05 14:58:11
@@ -31,7 +31,7 @@
 OPTFLAGS ?= -O2 -g
 WARNFLAGS ?= -Wall -Wstrict-prototypes
 CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -I../include -D$(OSNAME) $(IPC_CFLAGS)
-PROGRAMS = iscsid iscsiadm iscsistart iscsi-iname
+PROGRAMS = iscsid iscsiadm iscsistart iscsi-dbconvert iscsi-iname
 
 # sources shared between iscsid, iscsiadm and iscsistart
 ISCSI_LIB_SRCS = util.o io.o auth.o login.o log.o md5.o sha1.o iscsi_sysfs.o idbm.o
@@ -52,6 +52,9 @@
 		statics.o
 	$(CC) $(CFLAGS) -static $^ -o $@
 
+iscsi-dbconvert: $(ISCSI_LIB_SRCS) iscsi-dbconvert.o idbm-compat.o
+	$(CC) $(CFLAGS) $^ -o $@ -ldb -pthread
+
 iscsi-iname: md5.o iscsi-iname.o
 	$(CC) $^ -o $@
 
--- open-iscsi-2.0-707/usr/idbm.h	2007/03/05 14:56:10	1.11
+++ open-iscsi-2.0-707/usr/idbm.h	2007/03/05 15:04:17
@@ -23,7 +23,9 @@
 #define IDBM_H
 
 #include <sys/types.h>
+#ifndef DB_DBM_HSEARCH
 #include "initiator.h"
+#endif
 #include "config.h"
 
 #define HASH_MAXLEN	NI_MAXHOST + NI_MAXSERV
--- open-iscsi-2.0-707/usr/types.h	2007/03/05 14:55:59	1.7
+++ open-iscsi-2.0-707/usr/types.h	2007/03/05 15:05:26
@@ -10,7 +10,9 @@
 #include <netinet/in.h>
 #include <stdint.h>
 #include <sys/types.h>
+#ifndef DB_DBM_HSEARCH
 #include <search.h>
+#endif
 
 #define DATASEG_MAX	8192
 #define HDRSEG_MAX	48+4
