|
Packit |
eace71 |
/*
|
|
Packit |
eace71 |
* Copyright (C) 2017-2018 Red Hat, Inc.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* This program is free software: you can redistribute it and/or modify
|
|
Packit |
eace71 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
eace71 |
* the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
eace71 |
* (at your option) any later version.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
eace71 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
eace71 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
eace71 |
* GNU General Public License for more details.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
eace71 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* Author: Gris Ge <fge@redhat.com>
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* The code below is modified from usr/idbm.c which licensed like below:
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* iSCSI Discovery Database Library
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* Copyright (C) 2004 Dmitry Yusupov, Alex Aizman
|
|
Packit |
eace71 |
* Copyright (C) 2006 Mike Christie
|
|
Packit |
eace71 |
* Copyright (C) 2006 Red Hat, Inc. All rights reserved.
|
|
Packit |
eace71 |
* maintained by open-iscsi@@googlegroups.com
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
eace71 |
* it under the terms of the GNU General Public License as published
|
|
Packit |
eace71 |
* by the Free Software Foundation; either version 2 of the License, or
|
|
Packit |
eace71 |
* (at your option) any later version.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
eace71 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
eace71 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
eace71 |
* General Public License for more details.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* See the file COPYING included with this distribution for more details.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#ifndef _GNU_SOURCE
|
|
Packit |
eace71 |
#define _GNU_SOURCE /* For strerror_r() */
|
|
Packit |
eace71 |
#endif
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include <sys/stat.h>
|
|
Packit |
eace71 |
#include <fcntl.h>
|
|
Packit |
eace71 |
#include <unistd.h>
|
|
Packit |
eace71 |
#include <string.h>
|
|
Packit |
eace71 |
#include <inttypes.h>
|
|
Packit |
eace71 |
#include <limits.h>
|
|
Packit |
eace71 |
#include <stdlib.h>
|
|
Packit |
eace71 |
#include <ctype.h>
|
|
Packit |
eace71 |
#include <stdbool.h>
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include "libopeniscsiusr/libopeniscsiusr_common.h"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include "context.h"
|
|
Packit |
eace71 |
#include "idbm.h"
|
|
Packit |
eace71 |
#include "misc.h"
|
|
Packit |
eace71 |
#include "idbm_fields.h"
|
|
Packit |
eace71 |
#include "iface.h"
|
|
Packit |
eace71 |
#include "version.h"
|
|
Packit |
eace71 |
#include "node.h"
|
|
Packit |
eace71 |
#include "default.h"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define TYPE_INT_O 1
|
|
Packit |
eace71 |
#define TYPE_STR 2
|
|
Packit |
eace71 |
#define TYPE_UINT8 3
|
|
Packit |
eace71 |
#define TYPE_UINT16 4
|
|
Packit |
eace71 |
#define TYPE_UINT32 5
|
|
Packit |
eace71 |
#define TYPE_INT32 6
|
|
Packit |
eace71 |
#define TYPE_INT64 7
|
|
Packit |
eace71 |
#define TYPE_BOOL 8
|
|
Packit |
eace71 |
#define MAX_KEYS 256 /* number of keys total(including CNX_MAX) */
|
|
Packit |
eace71 |
#define NAME_MAXVAL 128 /* the maximum length of key name */
|
|
Packit |
eace71 |
#define VALUE_MAXVAL 256 /* the maximum length of 223 bytes in the RFC. */
|
|
Packit |
eace71 |
/* ^ MAX_KEYS, NAME_MAXVAL and VALUE_MAXVAL are copied from usr/idbm.h
|
|
Packit |
eace71 |
* The RFC 3720 only said:
|
|
Packit |
eace71 |
* If not otherwise specified, the maximum length of a simple-value (not
|
|
Packit |
eace71 |
* its encoded representation) is 255 bytes, not including the delimiter
|
|
Packit |
eace71 |
* (comma or zero byte).
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define OPTS_MAXVAL 8
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define IDBM_HIDE 0 /* Hide parameter when print. */
|
|
Packit |
eace71 |
#define IDBM_SHOW 1 /* Show parameter when print. */
|
|
Packit |
eace71 |
#define IDBM_MASKED 2 /* Show "stars" instead of real value when print */
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define ISCSI_BEGIN_REC "# BEGIN RECORD "ISCSI_VERSION_STR
|
|
Packit |
eace71 |
#define ISCSI_END_REC "# END RECORD"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#ifndef LOCK_DIR
|
|
Packit |
eace71 |
#define LOCK_DIR "/run/lock/iscsi"
|
|
Packit |
eace71 |
#endif
|
|
Packit |
eace71 |
#define LOCK_FILE LOCK_DIR"/lock"
|
|
Packit |
eace71 |
#define LOCK_WRITE_FILE LOCK_DIR"/lock.write"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_str(_key, _recs, _org, _name, _show, _n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_recs[_n].type = TYPE_STR; \
|
|
Packit |
eace71 |
_strncpy(_recs[_n].name, _key, NAME_MAXVAL); \
|
|
Packit |
eace71 |
if (strlen((char*)_org->_name)) \
|
|
Packit |
eace71 |
_strncpy((char*)_recs[_n].value, (char*)_org->_name, \
|
|
Packit |
eace71 |
VALUE_MAXVAL); \
|
|
Packit |
eace71 |
_recs[_n].data = &_org->_name; \
|
|
Packit |
eace71 |
_recs[_n].data_len = sizeof(_org->_name); \
|
|
Packit |
eace71 |
_recs[_n].visible = _show; \
|
|
Packit |
eace71 |
_recs[_n].can_modify = _mod; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while(0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_uint8(_key, _recs, _org, _name, _show, _n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_recs[_n].type = TYPE_UINT8; \
|
|
Packit |
eace71 |
_strncpy(_recs[_n].name, _key, NAME_MAXVAL); \
|
|
Packit |
eace71 |
snprintf(_recs[_n].value, VALUE_MAXVAL, "%" PRIu8, _org->_name); \
|
|
Packit |
eace71 |
_recs[_n].data = &_org->_name; \
|
|
Packit |
eace71 |
_recs[_n].data_len = sizeof(_org->_name); \
|
|
Packit |
eace71 |
_recs[_n].visible = _show; \
|
|
Packit |
eace71 |
_recs[_n].can_modify = _mod; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while (0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_uint16(_key, _recs, _org, _name, _show, _n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_recs[_n].type = TYPE_UINT16; \
|
|
Packit |
eace71 |
_strncpy(_recs[_n].name, _key, NAME_MAXVAL); \
|
|
Packit |
eace71 |
snprintf(_recs[_n].value, VALUE_MAXVAL, "%" PRIu16, _org->_name); \
|
|
Packit |
eace71 |
_recs[_n].data = &_org->_name; \
|
|
Packit |
eace71 |
_recs[_n].data_len = sizeof(_org->_name); \
|
|
Packit |
eace71 |
_recs[_n].visible = _show; \
|
|
Packit |
eace71 |
_recs[_n].can_modify = _mod; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while (0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_uint32(_key, _recs, _org, _name, _show, _n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_recs[_n].type = TYPE_UINT32; \
|
|
Packit |
eace71 |
_strncpy(_recs[_n].name, _key, NAME_MAXVAL); \
|
|
Packit |
eace71 |
snprintf(_recs[_n].value, VALUE_MAXVAL, "%" PRIu32, _org->_name); \
|
|
Packit |
eace71 |
_recs[_n].data = &_org->_name; \
|
|
Packit |
eace71 |
_recs[_n].data_len = sizeof(_org->_name); \
|
|
Packit |
eace71 |
_recs[_n].visible = _show; \
|
|
Packit |
eace71 |
_recs[_n].can_modify = _mod; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while (0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_int32(_key, _recs, _org, _name, _show, _n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_recs[_n].type = TYPE_INT32; \
|
|
Packit |
eace71 |
_strncpy(_recs[_n].name, _key, NAME_MAXVAL); \
|
|
Packit |
eace71 |
snprintf(_recs[_n].value, VALUE_MAXVAL, "%" PRIi32, _org->_name); \
|
|
Packit |
eace71 |
_recs[_n].data = &_org->_name; \
|
|
Packit |
eace71 |
_recs[_n].data_len = sizeof(_org->_name); \
|
|
Packit |
eace71 |
_recs[_n].visible = _show; \
|
|
Packit |
eace71 |
_recs[_n].can_modify = _mod; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while (0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_int64(_key, _recs, _org, _name, _show, _n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_recs[_n].type = TYPE_INT64; \
|
|
Packit |
eace71 |
_strncpy(_recs[_n].name, _key, NAME_MAXVAL); \
|
|
Packit |
eace71 |
snprintf(_recs[_n].value, VALUE_MAXVAL, "%" PRIi64, _org->_name); \
|
|
Packit |
eace71 |
_recs[_n].data = &_org->_name; \
|
|
Packit |
eace71 |
_recs[_n].data_len = sizeof(_org->_name); \
|
|
Packit |
eace71 |
_recs[_n].visible = _show; \
|
|
Packit |
eace71 |
_recs[_n].can_modify = _mod; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while (0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_bool(_key, _recs, _org, _name, _show, _n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_recs[_n].type = TYPE_BOOL; \
|
|
Packit |
eace71 |
_strncpy(_recs[_n].name, _key, NAME_MAXVAL); \
|
|
Packit |
eace71 |
snprintf(_recs[_n].value, VALUE_MAXVAL, "%s", \
|
|
Packit |
eace71 |
_org->_name ? "Yes" : "No"); \
|
|
Packit |
eace71 |
_recs[_n].data = &_org->_name; \
|
|
Packit |
eace71 |
_recs[_n].data_len = sizeof(_org->_name); \
|
|
Packit |
eace71 |
_recs[_n].visible = _show; \
|
|
Packit |
eace71 |
_recs[_n].can_modify = _mod; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while(0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_int_o2(_key, _recs, _org, _name, _show, _op0, _op1, _n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_recs[_n].type = TYPE_INT_O; \
|
|
Packit |
eace71 |
_strncpy(_recs[_n].name, _key, NAME_MAXVAL); \
|
|
Packit |
eace71 |
if (_org->_name == 0) _strncpy(_recs[_n].value, _op0, VALUE_MAXVAL); \
|
|
Packit |
eace71 |
if (_org->_name == 1) _strncpy(_recs[_n].value, _op1, VALUE_MAXVAL); \
|
|
Packit |
eace71 |
_recs[_n].data = &_org->_name; \
|
|
Packit |
eace71 |
_recs[_n].data_len = sizeof(_org->_name); \
|
|
Packit |
eace71 |
_recs[_n].visible = _show; \
|
|
Packit |
eace71 |
_recs[_n].opts[0] = _op0; \
|
|
Packit |
eace71 |
_recs[_n].opts[1] = _op1; \
|
|
Packit |
eace71 |
_recs[_n].numopts = 2; \
|
|
Packit |
eace71 |
_recs[_n].can_modify = _mod; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while(0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_int_o3(_key, _recs, _org, _name, _show, _op0, _op1, _op2, _n, \
|
|
Packit |
eace71 |
_mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_rec_int_o2(_key, _recs, _org, _name, _show, _op0, _op1, _n, _mod); \
|
|
Packit |
eace71 |
_n--; \
|
|
Packit |
eace71 |
if (_org->_name == 2) _strncpy(_recs[_n].value, _op2, VALUE_MAXVAL);\
|
|
Packit |
eace71 |
_recs[_n].opts[2] = _op2; \
|
|
Packit |
eace71 |
_recs[_n].numopts = 3; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while(0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_int_o4(_key, _recs, _org, _name, _show, _op0, _op1, _op2, _op3, \
|
|
Packit |
eace71 |
_n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_rec_int_o3(_key, _recs, _org, _name, _show, _op0, _op1, _op2, _n, \
|
|
Packit |
eace71 |
_mod); \
|
|
Packit |
eace71 |
_n--; \
|
|
Packit |
eace71 |
if (_org->_name == 3) _strncpy(_recs[_n].value, _op3, VALUE_MAXVAL);\
|
|
Packit |
eace71 |
_recs[_n].opts[3] = _op3; \
|
|
Packit |
eace71 |
_recs[_n].numopts = 4; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while(0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_int_o5(_key, _recs, _org, _name, _show, _op0, _op1, _op2, _op3, \
|
|
Packit |
eace71 |
_op4, _n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_rec_int_o4(_key, _recs, _org, _name, _show, _op0, _op1, _op2, _op3, \
|
|
Packit |
eace71 |
_n, _mod); \
|
|
Packit |
eace71 |
_n--; \
|
|
Packit |
eace71 |
if (_org->_name == 4) _strncpy(_recs[_n].value, _op4, VALUE_MAXVAL);\
|
|
Packit |
eace71 |
_recs[_n].opts[4] = _op4; \
|
|
Packit |
eace71 |
_recs[_n].numopts = 5; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while(0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define _rec_int_o6(_key, _recs, _org, _name, _show, _op0, _op1, _op2, _op3, \
|
|
Packit |
eace71 |
_op4, _op5, _n, _mod) \
|
|
Packit |
eace71 |
do { \
|
|
Packit |
eace71 |
_rec_int_o5(_key, _recs, _org, _name, _show, _op0, _op1, _op2, _op3, \
|
|
Packit |
eace71 |
_op4, _n, _mod); \
|
|
Packit |
eace71 |
_n--; \
|
|
Packit |
eace71 |
if (_org->_name == 5) _strncpy(_recs[_n].value, _op5, VALUE_MAXVAL);\
|
|
Packit |
eace71 |
_recs[_n].opts[5] = _op5; \
|
|
Packit |
eace71 |
_recs[_n].numopts = 6; \
|
|
Packit |
eace71 |
_n++; \
|
|
Packit |
eace71 |
} while(0)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
enum modify_mode {
|
|
Packit |
eace71 |
_CANNOT_MODIFY,
|
|
Packit |
eace71 |
_CAN_MODIFY,
|
|
Packit |
eace71 |
};
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
struct idbm_rec {
|
|
Packit |
eace71 |
int type;
|
|
Packit |
eace71 |
char name[NAME_MAXVAL];
|
|
Packit |
eace71 |
char value[VALUE_MAXVAL];
|
|
Packit |
eace71 |
void *data;
|
|
Packit |
eace71 |
int data_len;
|
|
Packit |
eace71 |
int visible;
|
|
Packit |
eace71 |
char* opts[OPTS_MAXVAL];
|
|
Packit |
eace71 |
int numopts;
|
|
Packit |
eace71 |
/*
|
|
Packit |
eace71 |
* TODO: make it a enum that can indicate whether it also requires
|
|
Packit |
eace71 |
* a relogin to pick up if a session is running.
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
enum modify_mode can_modify;
|
|
Packit |
eace71 |
};
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static void _idbm_node_rec_link(struct iscsi_node *node, struct idbm_rec *recs);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int _idbm_lock(struct iscsi_context *ctx)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int fd, i, ret;
|
|
Packit |
eace71 |
struct idbm *db = NULL;
|
|
Packit |
eace71 |
char strerr_buff[_STRERR_BUFF_LEN];
|
|
Packit |
eace71 |
int errno_save = 0;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
assert(ctx != NULL);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
db = ctx->db;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (db->refs > 0) {
|
|
Packit |
eace71 |
db->refs++;
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (access(LOCK_DIR, F_OK) != 0) {
|
|
Packit |
eace71 |
if (mkdir(LOCK_DIR, 0660) != 0) {
|
|
Packit |
eace71 |
_error(ctx, "Could not open %s: %d %s", LOCK_DIR, errno,
|
|
Packit |
eace71 |
_strerror(errno, strerr_buff));
|
|
Packit |
eace71 |
return LIBISCSI_ERR_IDBM;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
fd = open(LOCK_FILE, O_RDWR | O_CREAT, 0666);
|
|
Packit |
eace71 |
if (fd >= 0)
|
|
Packit |
eace71 |
close(fd);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
for (i = 0; i < 3000; i++) {
|
|
Packit |
eace71 |
ret = link(LOCK_FILE, LOCK_WRITE_FILE);
|
|
Packit |
eace71 |
if (ret == 0)
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
errno_save = errno;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (errno != EEXIST) {
|
|
Packit |
eace71 |
_error(ctx, "Maybe you are not root? "
|
|
Packit |
eace71 |
"Could not lock discovery DB: %s: %d %s",
|
|
Packit |
eace71 |
LOCK_WRITE_FILE, errno_save,
|
|
Packit |
eace71 |
_strerror(errno_save, strerr_buff));
|
|
Packit |
eace71 |
return LIBISCSI_ERR_IDBM;
|
|
Packit |
eace71 |
} else if (i == 0)
|
|
Packit |
eace71 |
_debug(ctx, "Waiting for discovery DB lock on %s",
|
|
Packit |
eace71 |
LOCK_WRITE_FILE);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
usleep(10000);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (ret != 0) {
|
|
Packit |
eace71 |
_error(ctx, "Timeout on acquiring lock on DB: %s, errno: %d %s",
|
|
Packit |
eace71 |
LOCK_WRITE_FILE, errno_save,
|
|
Packit |
eace71 |
_strerror(errno_save, strerr_buff));
|
|
Packit |
eace71 |
return LIBISCSI_ERR_IDBM;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
db->refs = 1;
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
void _idbm_unlock(struct iscsi_context *ctx)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct idbm *db = NULL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
assert(ctx != NULL);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
db = ctx->db;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (db->refs > 1) {
|
|
Packit |
eace71 |
db->refs--;
|
|
Packit |
eace71 |
return;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
db->refs = 0;
|
|
Packit |
eace71 |
unlink(LOCK_WRITE_FILE);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static struct idbm_rec* _idbm_recs_alloc(void)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
return calloc(MAX_KEYS, sizeof(struct idbm_rec));
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static void _idbm_recs_free(struct idbm_rec* recs)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
free(recs);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static int _idbm_iface_rec_link(struct iscsi_iface *iface,
|
|
Packit |
eace71 |
struct idbm_rec *recs, int num)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int init_num = num;
|
|
Packit |
eace71 |
if (init_num == 0)
|
|
Packit |
eace71 |
_rec_str(IFACE_ISCSINAME, recs, iface, name, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CANNOT_MODIFY);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
_rec_str(IFACE_ISCSINAME, recs, iface, name, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_NETNAME, recs, iface, netdev, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_IPADDR, recs, iface, ipaddress, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint8(IFACE_PREFIX_LEN, recs, iface, prefix_len, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_HWADDR, recs, iface, hwaddress, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_TRANSPORTNAME, recs, iface, transport_name, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_INAME, recs, iface, iname, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_STATE, recs, iface, state, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint16(IFACE_VLAN_ID, recs, iface, vlan_id, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint8(IFACE_VLAN_PRIORITY, recs, iface, vlan_priority, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_VLAN_STATE, recs, iface, vlan_state, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(IFACE_NUM, recs, iface, iface_num, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint16(IFACE_MTU, recs, iface, mtu, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint16(IFACE_PORT, recs, iface, port, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (! iface->is_ipv6) {
|
|
Packit |
eace71 |
_rec_str(IFACE_BOOT_PROTO, recs, iface, bootproto, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_SUBNET_MASK, recs, iface, subnet_mask, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_GATEWAY, recs, iface, gateway, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DHCP_ALT_CID, recs, iface,
|
|
Packit |
eace71 |
dhcp_alt_client_id_state, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DHCP_ALT_CID_STR, recs, iface,
|
|
Packit |
eace71 |
dhcp_alt_client_id, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DHCP_DNS, recs, iface, dhcp_dns, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DHCP_LEARN_IQN, recs, iface, dhcp_learn_iqn,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DHCP_REQ_VID, recs, iface,
|
|
Packit |
eace71 |
dhcp_req_vendor_id_state, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DHCP_VID, recs, iface, dhcp_vendor_id_state,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DHCP_VID_STR, recs, iface, dhcp_vendor_id,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DHCP_SLP_DA, recs, iface, dhcp_slp_da, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_FRAGMENTATION, recs, iface, fragmentation,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_GRAT_ARP, recs, iface, gratuitous_arp, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_IN_FORWARD, recs, iface, incoming_forwarding,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_TOS_STATE, recs, iface, tos_state, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint8(IFACE_TOS, recs, iface, tos, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint8(IFACE_TTL, recs, iface, ttl, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
} else {
|
|
Packit |
eace71 |
_rec_str(IFACE_IPV6_AUTOCFG, recs, iface, ipv6_autocfg,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_LINKLOCAL_AUTOCFG, recs, iface,
|
|
Packit |
eace71 |
linklocal_autocfg, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_ROUTER_AUTOCFG, recs, iface, router_autocfg,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_LINKLOCAL, recs, iface, ipv6_linklocal,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_ROUTER, recs, iface, ipv6_router, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint8(IFACE_DUP_ADDR_DETECT_CNT, recs, iface,
|
|
Packit |
eace71 |
dup_addr_detect_cnt, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(IFACE_FLOW_LABEL, recs, iface, flow_label,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_GRAT_NEIGHBOR_ADV, recs, iface,
|
|
Packit |
eace71 |
gratuitous_neighbor_adv, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint8(IFACE_HOP_LIMIT, recs, iface, hop_limit, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_MLD, recs, iface, mld, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(IFACE_ND_REACHABLE_TMO, recs, iface,
|
|
Packit |
eace71 |
nd_reachable_tmo, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(IFACE_ND_REXMIT_TIME, recs, iface, nd_rexmit_time,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(IFACE_ND_STALE_TMO, recs, iface, nd_stale_tmo,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(IFACE_RTR_ADV_LINK_MTU, recs, iface,
|
|
Packit |
eace71 |
router_adv_link_mtu, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint8(IFACE_TRAFFIC_CLASS, recs, iface, traffic_class,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_rec_str(IFACE_DELAYED_ACK, recs, iface, delayed_ack, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_TCP_NAGLE, recs, iface, nagle, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_TCP_WSF_STATE, recs, iface, tcp_wsf_state, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint8(IFACE_TCP_WSF, recs, iface, tcp_wsf, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint8(IFACE_TCP_TIMER_SCALE, recs, iface, tcp_timer_scale,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_TCP_TIMESTAMP, recs, iface, tcp_timestamp, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_REDIRECT, recs, iface, redirect, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint16(IFACE_DEF_TMF_TMO, recs, iface, def_task_mgmt_tmo,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_HDRDGST, recs, iface, header_digest, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DATADGST, recs, iface, data_digest, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_IMM_DATA, recs, iface, immediate_data, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_INITIAL_R2T, recs, iface, initial_r2t, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DSEQ_INORDER, recs, iface, data_seq_inorder, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DPDU_INORDER, recs, iface, data_pdu_inorder, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint8(IFACE_ERL, recs, iface, erl, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(IFACE_MAX_RECV_DLEN, recs, iface, max_recv_dlength,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(IFACE_FIRST_BURST, recs, iface, first_burst_len, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint16(IFACE_MAX_R2T, recs, iface, max_out_r2t, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(IFACE_MAX_BURST, recs, iface, max_burst_len, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_CHAP_AUTH, recs, iface, chap_auth, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_BIDI_CHAP, recs, iface, bidi_chap, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_STRICT_LOGIN_COMP, recs, iface, strict_login_comp,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DISCOVERY_AUTH, recs, iface, discovery_auth, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(IFACE_DISCOVERY_LOGOUT, recs, iface, discovery_logout,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
return num;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static void _idbm_recs_print(struct idbm_rec *recs, FILE *f, int show)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int i;
|
|
Packit |
eace71 |
fprintf(f, "%s\n", ISCSI_BEGIN_REC);
|
|
Packit |
eace71 |
for (i = 0; i < MAX_KEYS; i++) {
|
|
Packit |
eace71 |
if (recs[i].visible == IDBM_HIDE)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
if (show == IDBM_MASKED && recs[i].visible == IDBM_MASKED) {
|
|
Packit |
eace71 |
if (*(char*)recs[i].data) {
|
|
Packit |
eace71 |
fprintf(f, "%s = ********\n", recs[i].name);
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
/* fall through */
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (strlen(recs[i].value))
|
|
Packit |
eace71 |
fprintf(f, "%s = %s\n", recs[i].name, recs[i].value);
|
|
Packit |
eace71 |
else if (f == stdout)
|
|
Packit |
eace71 |
fprintf(f, "%s = <empty>\n", recs[i].name);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
fprintf(f, "%s\n", ISCSI_END_REC);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
void _idbm_iface_print(struct iscsi_iface *iface, FILE *f)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct idbm_rec *recs = NULL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
recs = _idbm_recs_alloc();
|
|
Packit |
eace71 |
if (recs == NULL)
|
|
Packit |
eace71 |
return;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_idbm_iface_rec_link(iface, recs, 0);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_idbm_recs_print(recs, f, IDBM_SHOW);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_idbm_recs_free(recs);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
void _idbm_node_print(struct iscsi_node *node, FILE *f, bool show_secret)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct idbm_rec *recs = NULL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
recs = _idbm_recs_alloc();
|
|
Packit |
eace71 |
if (recs == NULL)
|
|
Packit |
eace71 |
return;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_idbm_node_rec_link(node, recs);
|
|
Packit |
eace71 |
_idbm_recs_print(recs, f, show_secret ? IDBM_SHOW : IDBM_MASKED);
|
|
Packit |
eace71 |
_idbm_recs_free(recs);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static int _idbm_rec_update_param(struct iscsi_context *ctx,
|
|
Packit |
eace71 |
struct idbm_rec *recs, char *name,
|
|
Packit |
eace71 |
char *value, int line_number)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int rc = LIBISCSI_OK;
|
|
Packit |
eace71 |
int i = 0;
|
|
Packit |
eace71 |
int j = 0;
|
|
Packit |
eace71 |
int passwd_done = 0;
|
|
Packit |
eace71 |
char passwd_len[8];
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
assert(ctx != NULL);
|
|
Packit |
eace71 |
assert(recs != NULL);
|
|
Packit |
eace71 |
assert(name != NULL);
|
|
Packit |
eace71 |
assert(value != NULL);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
setup_passwd_len:
|
|
Packit |
eace71 |
for (i = 0; i < MAX_KEYS; ++i) {
|
|
Packit |
eace71 |
if (!strcmp(name, recs[i].name)) {
|
|
Packit |
eace71 |
_debug(ctx, "updated '%s', '%s' => '%s'", name,
|
|
Packit |
eace71 |
recs[i].value, value);
|
|
Packit |
eace71 |
/* parse recinfo by type */
|
|
Packit |
eace71 |
switch (recs[i].type) {
|
|
Packit |
eace71 |
case TYPE_UINT8:
|
|
Packit |
eace71 |
if (!recs[i].data)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
*(uint8_t *)recs[i].data =
|
|
Packit |
eace71 |
strtoul(value, NULL, 10);
|
|
Packit |
eace71 |
goto updated;
|
|
Packit |
eace71 |
case TYPE_UINT16:
|
|
Packit |
eace71 |
if (!recs[i].data)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
*(uint16_t *)recs[i].data =
|
|
Packit |
eace71 |
strtoul(value, NULL, 10);
|
|
Packit |
eace71 |
goto updated;
|
|
Packit |
eace71 |
case TYPE_UINT32:
|
|
Packit |
eace71 |
if (!recs[i].data)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
*(uint32_t *)recs[i].data =
|
|
Packit |
eace71 |
strtoul(value, NULL, 10);
|
|
Packit |
eace71 |
goto updated;
|
|
Packit |
eace71 |
case TYPE_STR:
|
|
Packit |
eace71 |
if (!recs[i].data)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_strncpy((char*)recs[i].data,
|
|
Packit |
eace71 |
value, recs[i].data_len);
|
|
Packit |
eace71 |
goto updated;
|
|
Packit |
eace71 |
case TYPE_INT32:
|
|
Packit |
eace71 |
if (!recs[i].data)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
*(int32_t *)recs[i].data =
|
|
Packit |
eace71 |
strtoul(value, NULL, 10);
|
|
Packit |
eace71 |
goto updated;
|
|
Packit |
eace71 |
case TYPE_INT64:
|
|
Packit |
eace71 |
if (!recs[i].data)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
*(int64_t *)recs[i].data =
|
|
Packit |
eace71 |
strtoull(value, NULL, 10);
|
|
Packit |
eace71 |
goto updated;
|
|
Packit |
eace71 |
case TYPE_INT_O:
|
|
Packit |
eace71 |
for (j = 0; j < recs[i].numopts; ++j) {
|
|
Packit |
eace71 |
if (!strcmp(value, recs[i].opts[j])) {
|
|
Packit |
eace71 |
if (!recs[i].data)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
*(int*)recs[i].data = j;
|
|
Packit |
eace71 |
goto updated;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
goto unknown_value;
|
|
Packit |
eace71 |
case TYPE_BOOL:
|
|
Packit |
eace71 |
if (!recs[i].data)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
if (strcmp(value, "Yes") == 0)
|
|
Packit |
eace71 |
*(bool *)recs[i].data = true;
|
|
Packit |
eace71 |
else if (strcmp(value, "No") == 0)
|
|
Packit |
eace71 |
*(bool *)recs[i].data = false;
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
goto unknown_value;
|
|
Packit |
eace71 |
goto updated;
|
|
Packit |
eace71 |
default:
|
|
Packit |
eace71 |
unknown_value:
|
|
Packit |
eace71 |
_error(ctx, "Got unknown data type %d "
|
|
Packit |
eace71 |
"for name '%s', value '%s'",
|
|
Packit |
eace71 |
recs[i].data, recs[i].name,
|
|
Packit |
eace71 |
recs[i].value);
|
|
Packit |
eace71 |
rc = LIBISCSI_ERR_BUG;
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
if (line_number) {
|
|
Packit |
eace71 |
_warn(ctx, "config file line %d contains "
|
|
Packit |
eace71 |
"unknown value format '%s' for "
|
|
Packit |
eace71 |
"parameter name '%s'",
|
|
Packit |
eace71 |
line_number, value, name);
|
|
Packit |
eace71 |
} else {
|
|
Packit |
eace71 |
_error(ctx, "unknown value format '%s' for "
|
|
Packit |
eace71 |
"parameter name '%s'", value, name);
|
|
Packit |
eace71 |
rc = LIBISCSI_ERR_INVAL;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
_error(ctx, "Unknown parameter name %s", name);
|
|
Packit |
eace71 |
rc = LIBISCSI_ERR_INVAL;
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
updated:
|
|
Packit |
eace71 |
_strncpy((char*)recs[i].value, value, VALUE_MAXVAL);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define check_password_param(_param) \
|
|
Packit |
eace71 |
if (!passwd_done && !strcmp(#_param, name)) { \
|
|
Packit |
eace71 |
passwd_done = 1; \
|
|
Packit |
eace71 |
name = #_param "_length"; \
|
|
Packit |
eace71 |
snprintf(passwd_len, 8, "%.7d", (int)strlen(value) & 0xffff); \
|
|
Packit |
eace71 |
value = passwd_len; \
|
|
Packit |
eace71 |
goto setup_passwd_len; \
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
check_password_param(node.session.auth.password);
|
|
Packit |
eace71 |
check_password_param(node.session.auth.password_in);
|
|
Packit |
eace71 |
check_password_param(discovery.sendtargets.auth.password);
|
|
Packit |
eace71 |
check_password_param(discovery.sendtargets.auth.password_in);
|
|
Packit |
eace71 |
check_password_param(discovery.slp.auth.password);
|
|
Packit |
eace71 |
check_password_param(discovery.slp.auth.password_in);
|
|
Packit |
eace71 |
check_password_param(host.auth.password);
|
|
Packit |
eace71 |
check_password_param(host.auth.password_in);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
out:
|
|
Packit |
eace71 |
return rc;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/*
|
|
Packit |
eace71 |
* from linux kernel
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
static char *strstrip(char *s)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
size_t size;
|
|
Packit |
eace71 |
char *end;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
size = strlen(s);
|
|
Packit |
eace71 |
if (!size)
|
|
Packit |
eace71 |
return s;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
end = s + size - 1;
|
|
Packit |
eace71 |
while (end >= s && isspace(*end))
|
|
Packit |
eace71 |
end--;
|
|
Packit |
eace71 |
*(end + 1) = '\0';
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
while (*s && isspace(*s))
|
|
Packit |
eace71 |
s++;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
return s;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static int _idbm_recs_read(struct iscsi_context *ctx, struct idbm_rec *recs,
|
|
Packit |
eace71 |
const char *conf_path)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int rc = LIBISCSI_OK;
|
|
Packit |
eace71 |
char name[NAME_MAXVAL];
|
|
Packit |
eace71 |
char value[VALUE_MAXVAL];
|
|
Packit |
eace71 |
char *line = NULL;
|
|
Packit |
eace71 |
char *nl = NULL;
|
|
Packit |
eace71 |
char buffer[2048];
|
|
Packit |
eace71 |
int line_number = 0;
|
|
Packit |
eace71 |
int c = 0;
|
|
Packit |
eace71 |
int i = 0;
|
|
Packit |
eace71 |
FILE *f = NULL;
|
|
Packit |
eace71 |
int errno_save = 0;
|
|
Packit |
eace71 |
char strerr_buff[_STRERR_BUFF_LEN];
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
assert(ctx != NULL);
|
|
Packit |
eace71 |
assert(recs != NULL);
|
|
Packit |
eace71 |
assert(conf_path != NULL);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
f = fopen(conf_path, "r");
|
|
Packit |
eace71 |
errno_save = errno;
|
|
Packit |
eace71 |
if (!f) {
|
|
Packit |
eace71 |
_error(ctx, "Failed to open %s using read mode: %d %s",
|
|
Packit |
eace71 |
conf_path, errno_save,
|
|
Packit |
eace71 |
_strerror(errno_save, strerr_buff));
|
|
Packit |
eace71 |
rc = LIBISCSI_ERR_IDBM;
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_info(ctx, "Parsing iSCSI interface configuration %s", conf_path);
|
|
Packit |
eace71 |
/* process the config file */
|
|
Packit |
eace71 |
do {
|
|
Packit |
eace71 |
line = fgets(buffer, sizeof (buffer), f);
|
|
Packit |
eace71 |
line_number++;
|
|
Packit |
eace71 |
if (!line)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
if (strlen(line) == 0)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
nl = line + strlen(line) - 1;
|
|
Packit |
eace71 |
if (*nl != '\n') {
|
|
Packit |
eace71 |
_warn(ctx, "Config file %s line %d too long.",
|
|
Packit |
eace71 |
conf_path, line_number);
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
line = strstrip(line);
|
|
Packit |
eace71 |
/* process any non-empty, non-comment lines */
|
|
Packit |
eace71 |
if (!*line || *line == '\0' || *line == '\n' || *line == '#')
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* parse name */
|
|
Packit |
eace71 |
i=0; nl = line; *name = 0;
|
|
Packit |
eace71 |
while (*nl && !isspace(c = *nl) && *nl != '=') {
|
|
Packit |
eace71 |
*(name+i) = *nl; i++; nl++;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
if (!*nl) {
|
|
Packit |
eace71 |
_warn(ctx, "config file %s line %d do not has value",
|
|
Packit |
eace71 |
conf_path, line_number);
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
*(name+i)=0; nl++;
|
|
Packit |
eace71 |
/* skip after-name traling spaces */
|
|
Packit |
eace71 |
while (*nl && isspace(c = *nl)) nl++;
|
|
Packit |
eace71 |
if (*nl && *nl != '=') {
|
|
Packit |
eace71 |
_warn(ctx, "config file %s line %d has not '=' "
|
|
Packit |
eace71 |
"separator", conf_path, line_number);
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
/* skip '=' sepa */
|
|
Packit |
eace71 |
nl++;
|
|
Packit |
eace71 |
/* skip after-sepa traling spaces */
|
|
Packit |
eace71 |
while (*nl && isspace(c = *nl)) nl++;
|
|
Packit |
eace71 |
if (!*nl) {
|
|
Packit |
eace71 |
_warn(ctx, "config file %s line %d do not has value",
|
|
Packit |
eace71 |
conf_path, line_number);
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
/* parse value */
|
|
Packit |
eace71 |
i=0; *value = 0;
|
|
Packit |
eace71 |
while (*nl) {
|
|
Packit |
eace71 |
*(value+i) = *nl; i++; nl++;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
*(value+i) = 0;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
rc = _idbm_rec_update_param(ctx, recs, name, value,
|
|
Packit |
eace71 |
line_number);
|
|
Packit |
eace71 |
if (rc == LIBISCSI_ERR_INVAL) {
|
|
Packit |
eace71 |
_error(ctx, "config file %s invalid.", conf_path);
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
} else if (rc != LIBISCSI_OK)
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
} while (line);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
out:
|
|
Packit |
eace71 |
if (f != NULL)
|
|
Packit |
eace71 |
fclose(f);
|
|
Packit |
eace71 |
return rc;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int _idbm_iface_get(struct iscsi_context *ctx, const char *iface_name, struct
|
|
Packit |
eace71 |
iscsi_iface **iface)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int rc = LIBISCSI_OK;
|
|
Packit |
eace71 |
char *conf_path = NULL;
|
|
Packit |
eace71 |
struct idbm_rec *recs = NULL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
assert(iface != NULL);
|
|
Packit |
eace71 |
assert(ctx != NULL);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
*iface = NULL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (iface_name == NULL)
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (strcmp(iface_name, "iface.example") == 0)
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_good(_asprintf(&conf_path, "%s/%s", IFACE_CONFIG_DIR, iface_name),
|
|
Packit |
eace71 |
rc, out);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
*iface = calloc(1, sizeof(struct iscsi_iface));
|
|
Packit |
eace71 |
_alloc_null_check(ctx, *iface, rc, out);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
snprintf((*iface)->name, sizeof((*iface)->name)/sizeof(char),
|
|
Packit |
eace71 |
"%s", iface_name);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (strstr(iface_name, "ipv6"))
|
|
Packit |
eace71 |
(*iface)->is_ipv6 = true;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
recs = _idbm_recs_alloc();
|
|
Packit |
eace71 |
_alloc_null_check(ctx, recs, rc, out);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_idbm_iface_rec_link(*iface, recs, 0);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_good(_idbm_recs_read(ctx, recs, conf_path), rc, out);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (! _iface_is_valid(*iface)) {
|
|
Packit |
eace71 |
_warn(ctx, "'%s' is not a valid iSCSI interface configuration "
|
|
Packit |
eace71 |
"file", conf_path);
|
|
Packit |
eace71 |
iscsi_iface_free(*iface);
|
|
Packit |
eace71 |
*iface = NULL;
|
|
Packit |
eace71 |
/* We still treat this as pass(no error) */
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
out:
|
|
Packit |
eace71 |
if (rc != LIBISCSI_OK) {
|
|
Packit |
eace71 |
iscsi_iface_free(*iface);
|
|
Packit |
eace71 |
*iface = NULL;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
free(conf_path);
|
|
Packit |
eace71 |
_idbm_recs_free(recs);
|
|
Packit |
eace71 |
return rc;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
struct idbm *_idbm_new(void)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
return calloc(1, sizeof(struct idbm));
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
void _idbm_free(struct idbm *db)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
free(db);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static void _idbm_node_rec_link(struct iscsi_node *node, struct idbm_rec *recs)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int num = 0;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_rec_str(NODE_NAME, recs, node, target_name, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CANNOT_MODIFY);
|
|
Packit |
eace71 |
_rec_int32(NODE_TPGT, recs, node, tpgt, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CANNOT_MODIFY);
|
|
Packit |
eace71 |
_rec_int_o3(NODE_STARTUP, recs, node, startup, IDBM_SHOW, "manual",
|
|
Packit |
eace71 |
"automatic", "onboot", num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_bool(NODE_LEADING_LOGIN, recs, node, leading_login, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/*
|
|
Packit |
eace71 |
* Note: because we do not add the iface.iscsi_ifacename to
|
|
Packit |
eace71 |
* sysfs iscsiadm does some weird matching. We can change the iface
|
|
Packit |
eace71 |
* values if a session is not running, but node record ifaces values
|
|
Packit |
eace71 |
* have to be changed and so do the iface record ones.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* Users should normally not want to change the iface ones
|
|
Packit |
eace71 |
* in the node record directly and instead do it through
|
|
Packit |
eace71 |
* the iface mode which will do the right thing (although that
|
|
Packit |
eace71 |
* needs some locking).
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
num = _idbm_iface_rec_link(&((*node).iface), recs, num);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_rec_str(NODE_DISC_ADDR, recs, node, disc_address, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CANNOT_MODIFY);
|
|
Packit |
eace71 |
_rec_int32(NODE_DISC_PORT, recs, node, disc_port, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CANNOT_MODIFY);
|
|
Packit |
eace71 |
_rec_int_o6(NODE_DISC_TYPE, recs, node, disc_type, IDBM_SHOW,
|
|
Packit |
eace71 |
"send_targets", "isns", "offload_send_targets", "slp",
|
|
Packit |
eace71 |
"static", "fw", num, _CANNOT_MODIFY);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_rec_uint32(SESSION_INIT_CMDSN, recs, node, session.initial_cmdsn,
|
|
Packit |
eace71 |
IDBM_SHOW, num,_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_INIT_LOGIN_RETRY, recs, node,
|
|
Packit |
eace71 |
session.initial_login_retry_max, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_XMIT_THREAD_PRIORITY, recs, node,
|
|
Packit |
eace71 |
session.xmit_thread_priority, IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint16(SESSION_CMDS_MAX, recs, node, session.cmds_max, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint16(SESSION_QDEPTH, recs, node, session.queue_depth, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_NR_SESSIONS, recs, node, session.nr_sessions,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int_o2(SESSION_AUTH_METHOD, recs, node, session.auth.authmethod,
|
|
Packit |
eace71 |
IDBM_SHOW, "None", "CHAP", num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(SESSION_USERNAME, recs, node, session.auth.username, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(SESSION_PASSWORD, recs, node, session.auth.password,
|
|
Packit |
eace71 |
IDBM_MASKED, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(SESSION_PASSWORD_LEN, recs, node,
|
|
Packit |
eace71 |
session.auth.password_length, IDBM_HIDE, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(SESSION_USERNAME_IN, recs, node, session.auth.username_in,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_str(SESSION_PASSWORD_IN, recs, node, session.auth.password_in,
|
|
Packit |
eace71 |
IDBM_MASKED, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_uint32(SESSION_PASSWORD_IN_LEN, recs, node,
|
|
Packit |
eace71 |
session.auth.password_in_length, IDBM_HIDE, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_REPLACEMENT_TMO, recs, node,
|
|
Packit |
eace71 |
session.tmo.replacement_timeout, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_ABORT_TMO, recs, node, session.err_tmo.abort_timeout,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_LU_RESET_TMO, recs, node,
|
|
Packit |
eace71 |
session.err_tmo.lu_reset_timeout, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_TGT_RESET_TMO, recs, node,
|
|
Packit |
eace71 |
session.err_tmo.tgt_reset_timeout, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_HOST_RESET_TMO, recs, node,
|
|
Packit |
eace71 |
session.err_tmo.host_reset_timeout, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_bool(SESSION_FAST_ABORT, recs, node, session.op_cfg.FastAbort,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_bool(SESSION_INITIAL_R2T, recs, node, session.op_cfg.InitialR2T,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_bool(SESSION_IMM_DATA, recs, node, session.op_cfg.ImmediateData,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_FIRST_BURST, recs, node,
|
|
Packit |
eace71 |
session.op_cfg.FirstBurstLength, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_MAX_BURST, recs, node, session.op_cfg.MaxBurstLength,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_DEF_TIME2RETAIN, recs, node,
|
|
Packit |
eace71 |
session.op_cfg.DefaultTime2Retain, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_DEF_TIME2WAIT, recs, node,
|
|
Packit |
eace71 |
session.op_cfg.DefaultTime2Wait, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_MAX_CONNS, recs, node, session.op_cfg.MaxConnections,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_MAX_R2T, recs, node,
|
|
Packit |
eace71 |
session.op_cfg.MaxOutstandingR2T, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_ERL, recs, node, session.op_cfg.ERL, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int_o2(SESSION_SCAN, recs, node, session.scan, IDBM_SHOW, "manual",
|
|
Packit |
eace71 |
"auto", num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(SESSION_REOPEN_MAX, recs, node, session.reopen_max, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CAN_MODIFY);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_rec_str(CONN_ADDR, recs, node, conn.address, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CANNOT_MODIFY);
|
|
Packit |
eace71 |
_rec_int32(CONN_PORT, recs, node, conn.port, IDBM_SHOW, num,
|
|
Packit |
eace71 |
_CANNOT_MODIFY);
|
|
Packit |
eace71 |
_rec_int_o3(CONN_STARTUP, recs, node, conn.startup, IDBM_SHOW,
|
|
Packit |
eace71 |
"manual", "automatic", "onboot", num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(CONN_WINDOW_SIZE, recs, node, conn.tcp.window_size,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(CONN_SERVICE_TYPE, recs, node, conn.tcp.type_of_service,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(CONN_LOGOUT_TMO, recs, node, conn.tmo.logout_timeout,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(CONN_LOGIN_TMO, recs, node, conn.tmo.login_timeout,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(CONN_AUTH_TMO, recs, node, conn.tmo.auth_timeout,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(CONN_NOP_INT, recs, node, conn.tmo.noop_out_interval,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(CONN_NOP_TMO, recs, node, conn.tmo.noop_out_timeout,
|
|
Packit |
eace71 |
IDBM_SHOW, num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(CONN_MAX_XMIT_DLEN, recs, node,
|
|
Packit |
eace71 |
conn.op_cfg.MaxXmitDataSegmentLength, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int64(CONN_MAX_RECV_DLEN, recs, node,
|
|
Packit |
eace71 |
conn.op_cfg.MaxRecvDataSegmentLength, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int_o4(CONN_HDR_DIGEST, recs, node, conn.op_cfg.HeaderDigest,
|
|
Packit |
eace71 |
IDBM_SHOW, "None", "CRC32C", "CRC32C,None",
|
|
Packit |
eace71 |
"None,CRC32C", num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_int_o4(CONN_DATA_DIGEST, recs, node, conn.op_cfg.DataDigest,
|
|
Packit |
eace71 |
IDBM_SHOW, "None", "CRC32C", "CRC32C,None",
|
|
Packit |
eace71 |
"None,CRC32C", num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_bool(CONN_IFMARKER, recs, node, conn.op_cfg.IFMarker, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
_rec_bool(CONN_OFMARKER, recs, node, conn.op_cfg.OFMarker, IDBM_SHOW,
|
|
Packit |
eace71 |
num, _CAN_MODIFY);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int _idbm_node_get(struct iscsi_context *ctx, const char *target_name,
|
|
Packit |
eace71 |
const char *portal, const char *iface_name,
|
|
Packit |
eace71 |
struct iscsi_node **node)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int rc = LIBISCSI_OK;
|
|
Packit |
eace71 |
char *conf_path = NULL;
|
|
Packit |
eace71 |
struct idbm_rec *recs = NULL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
assert(node != NULL);
|
|
Packit |
eace71 |
assert(ctx != NULL);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
*node = NULL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if ((target_name == NULL) || (portal == NULL))
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (iface_name == NULL) // old style of config
|
|
Packit |
eace71 |
_good(_asprintf(&conf_path, "%s/%s/%s", NODE_CONFIG_DIR,
|
|
Packit |
eace71 |
target_name, portal), rc, out);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
_good(_asprintf(&conf_path, "%s/%s/%s/%s", NODE_CONFIG_DIR,
|
|
Packit |
eace71 |
target_name, portal, iface_name), rc, out);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
*node = calloc(1, sizeof(struct iscsi_node));
|
|
Packit |
eace71 |
_alloc_null_check(ctx, *node, rc, out);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_default_node(*node);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
recs = _idbm_recs_alloc();
|
|
Packit |
eace71 |
_alloc_null_check(ctx, recs, rc, out);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_idbm_node_rec_link(*node, recs);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
_good(_idbm_recs_read(ctx, recs, conf_path), rc, out);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (! _iface_is_valid(&((*node)->iface))) {
|
|
Packit |
eace71 |
_warn(ctx, "'%s' has invalid iSCSI interface configuration",
|
|
Packit |
eace71 |
conf_path);
|
|
Packit |
eace71 |
iscsi_node_free(*node);
|
|
Packit |
eace71 |
*node = NULL;
|
|
Packit |
eace71 |
/* We still treat this as pass(no error) */
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
// Add extra properties
|
|
Packit |
eace71 |
if (strchr((*node)->conn.address, '.')) {
|
|
Packit |
eace71 |
(*node)->conn.is_ipv6 = false;
|
|
Packit |
eace71 |
snprintf((*node)->portal, sizeof((*node)->portal)/sizeof(char),
|
|
Packit |
eace71 |
"%s:%" PRIi32, (*node)->conn.address,
|
|
Packit |
eace71 |
(*node)->conn.port);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
} else {
|
|
Packit |
eace71 |
(*node)->conn.is_ipv6 = true;
|
|
Packit |
eace71 |
snprintf((*node)->portal, sizeof((*node)->portal)/sizeof(char),
|
|
Packit |
eace71 |
"[%s]:%" PRIi32, (*node)->conn.address,
|
|
Packit |
eace71 |
(*node)->conn.port);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
out:
|
|
Packit |
eace71 |
if (rc != LIBISCSI_OK) {
|
|
Packit |
eace71 |
iscsi_node_free(*node);
|
|
Packit |
eace71 |
*node = NULL;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
free(conf_path);
|
|
Packit |
eace71 |
_idbm_recs_free(recs);
|
|
Packit |
eace71 |
return rc;
|
|
Packit |
eace71 |
}
|