|
Packit Service |
37dbff |
/*
|
|
Packit Service |
37dbff |
* iSCSI Administration library
|
|
Packit Service |
37dbff |
*
|
|
Packit Service |
37dbff |
* Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
|
|
Packit Service |
37dbff |
* Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
|
|
Packit Service |
44d698 |
* Copyright (C) 2015 Peter Hatina <phatina@redhat.com>
|
|
Packit Service |
37dbff |
* maintained by open-iscsi@googlegroups.com
|
|
Packit Service |
37dbff |
*
|
|
Packit Service |
37dbff |
* This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
37dbff |
* it under the terms of the GNU General Public License as published
|
|
Packit Service |
37dbff |
* by the Free Software Foundation; either version 2 of the License, or
|
|
Packit Service |
37dbff |
* (at your option) any later version.
|
|
Packit Service |
37dbff |
*
|
|
Packit Service |
37dbff |
* This program is distributed in the hope that it will be useful, but
|
|
Packit Service |
37dbff |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
37dbff |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
37dbff |
* General Public License for more details.
|
|
Packit Service |
37dbff |
*
|
|
Packit Service |
37dbff |
* See the file COPYING included with this distribution for more details.
|
|
Packit Service |
37dbff |
*/
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
#include <stdio.h>
|
|
Packit Service |
37dbff |
#include <stdlib.h>
|
|
Packit Service |
37dbff |
#include <string.h>
|
|
Packit Service |
37dbff |
#include <errno.h>
|
|
Packit Service |
37dbff |
#include <unistd.h>
|
|
Packit Service |
37dbff |
#include <sys/syslog.h>
|
|
Packit Service |
37dbff |
#include "libiscsi.h"
|
|
Packit Service |
37dbff |
#include "idbm.h"
|
|
Packit Service |
37dbff |
#include "discovery.h"
|
|
Packit Service |
37dbff |
#include "log.h"
|
|
Packit Service |
37dbff |
#include "sysfs.h"
|
|
Packit Service |
37dbff |
#include "iscsi_sysfs.h"
|
|
Packit Service |
37dbff |
#include "session_info.h"
|
|
Packit Service |
37dbff |
#include "iscsi_util.h"
|
|
Packit Service |
37dbff |
#include "sysdeps.h"
|
|
Packit Service |
37dbff |
#include "iface.h"
|
|
Packit Service |
37dbff |
#include "iscsi_proto.h"
|
|
Packit Service |
37dbff |
#include "fw_context.h"
|
|
Packit Service |
37dbff |
#include "iscsid_req.h"
|
|
Packit Service |
37dbff |
#include "iscsi_err.h"
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
#define CHECK(a) { context->error_str[0] = 0; rc = a; if (rc) goto leave; }
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
/* UGLY, not thread safe :( */
|
|
Packit Service |
37dbff |
static int sysfs_initialized = 0;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
struct libiscsi_context {
|
|
Packit Service |
37dbff |
char error_str[256];
|
|
Packit Service |
37dbff |
/* For get_parameter_helper() */
|
|
Packit Service |
37dbff |
const char *parameter;
|
|
Packit Service |
37dbff |
char *value;
|
|
Packit Service |
37dbff |
};
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
static void libiscsi_log(int prio, void *priv, const char *fmt, va_list ap)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
struct libiscsi_context *context = priv;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (prio > LOG_ERR) /* We are only interested in errors (or worse) */
|
|
Packit Service |
37dbff |
return;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
vsnprintf(context->error_str, sizeof(context->error_str), fmt, ap);
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
struct libiscsi_context *libiscsi_init(void)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
struct libiscsi_context *context;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
context = calloc(1, sizeof *context);
|
|
Packit Service |
37dbff |
if (!context)
|
|
Packit Service |
37dbff |
return NULL;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
log_init("libiscsi", 1024, libiscsi_log, context);
|
|
Packit Service |
37dbff |
if (!sysfs_initialized) {
|
|
Packit Service |
37dbff |
sysfs_init();
|
|
Packit Service |
37dbff |
sysfs_initialized = 1;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
increase_max_files();
|
|
Packit Service |
37dbff |
if (idbm_init(NULL)) {
|
|
Packit Service |
37dbff |
sysfs_cleanup();
|
|
Packit Service |
37dbff |
free(context);
|
|
Packit Service |
37dbff |
return NULL;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
iface_setup_host_bindings();
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
return context;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
void libiscsi_cleanup(struct libiscsi_context *context)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
idbm_terminate();
|
|
Packit Service |
37dbff |
free_transports();
|
|
Packit Service |
37dbff |
sysfs_cleanup();
|
|
Packit Service |
37dbff |
free(context);
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
static void free_iface_list(struct list_head *ifaces)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
struct iface_rec *iface, *tmp_iface;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
list_for_each_entry_safe(iface, tmp_iface, ifaces, list) {
|
|
Packit Service |
37dbff |
list_del(&iface->list);
|
|
Packit Service |
37dbff |
free(iface);
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
static void free_rec_list(struct list_head *rec_list)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
struct node_rec *rec, *tmp;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
list_for_each_entry_safe(rec, tmp, rec_list, list) {
|
|
Packit Service |
37dbff |
list_del(&rec->list);
|
|
Packit Service |
37dbff |
free(rec);
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int libiscsi_discover_sendtargets(struct libiscsi_context *context,
|
|
Packit Service |
37dbff |
const char *address, int port,
|
|
Packit Service |
37dbff |
const struct libiscsi_auth_info *auth_info,
|
|
Packit Service |
37dbff |
int *nr_found, struct libiscsi_node **found_nodes)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
struct discovery_rec drec;
|
|
Packit Service |
37dbff |
LIST_HEAD(bound_rec_list);
|
|
Packit Service |
37dbff |
struct node_rec *rec;
|
|
Packit Service |
37dbff |
int rc = 0, found = 0;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
INIT_LIST_HEAD(&bound_rec_list);
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (nr_found)
|
|
Packit Service |
37dbff |
*nr_found = 0;
|
|
Packit Service |
37dbff |
if (found_nodes)
|
|
Packit Service |
37dbff |
*found_nodes = NULL;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
CHECK(libiscsi_verify_auth_info(context, auth_info))
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
/* Fill the drec struct with all needed info */
|
|
Packit Service |
37dbff |
memset(&drec, 0, sizeof drec);
|
|
Packit Service |
c705e8 |
drec.iscsid_req_tmo = -1;
|
|
Packit Service |
37dbff |
idbm_sendtargets_defaults(&drec.u.sendtargets);
|
|
Packit Service |
37dbff |
drec.type = DISCOVERY_TYPE_SENDTARGETS;
|
|
Packit Service |
37dbff |
strlcpy(drec.address, address, sizeof(drec.address));
|
|
Packit Service |
37dbff |
drec.port = port ? port : ISCSI_LISTEN_PORT;
|
|
Packit Service |
37dbff |
switch(auth_info ? auth_info->method : libiscsi_auth_none) {
|
|
Packit Service |
37dbff |
case libiscsi_auth_chap:
|
|
Packit Service |
37dbff |
drec.u.sendtargets.auth.authmethod = AUTH_METHOD_CHAP;
|
|
Packit Service |
37dbff |
strlcpy(drec.u.sendtargets.auth.username,
|
|
Packit Service |
37dbff |
auth_info->chap.username, AUTH_STR_MAX_LEN);
|
|
Packit Service |
37dbff |
strlcpy((char *)drec.u.sendtargets.auth.password,
|
|
Packit Service |
37dbff |
auth_info->chap.password, AUTH_STR_MAX_LEN);
|
|
Packit Service |
37dbff |
drec.u.sendtargets.auth.password_length =
|
|
Packit Service |
37dbff |
strlen((char *)drec.u.sendtargets.auth.password);
|
|
Packit Service |
37dbff |
strlcpy(drec.u.sendtargets.auth.username_in,
|
|
Packit Service |
37dbff |
auth_info->chap.reverse_username, AUTH_STR_MAX_LEN);
|
|
Packit Service |
37dbff |
strlcpy((char *)drec.u.sendtargets.auth.password_in,
|
|
Packit Service |
37dbff |
auth_info->chap.reverse_password, AUTH_STR_MAX_LEN);
|
|
Packit Service |
37dbff |
drec.u.sendtargets.auth.password_in_length =
|
|
Packit Service |
37dbff |
strlen((char *)drec.u.sendtargets.auth.password_in);
|
|
Packit Service |
37dbff |
break;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
CHECK(idbm_add_discovery(&drec))
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
CHECK(idbm_bind_ifaces_to_nodes(discovery_sendtargets,
|
|
Packit Service |
37dbff |
&drec, NULL, &bound_rec_list))
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
/* now add/update records */
|
|
Packit Service |
37dbff |
list_for_each_entry(rec, &bound_rec_list, list) {
|
|
Packit Service |
37dbff |
CHECK(idbm_add_node(rec, &drec, 1 /* overwrite */))
|
|
Packit Service |
37dbff |
found++;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (nr_found)
|
|
Packit Service |
37dbff |
*nr_found = found;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (found_nodes && found) {
|
|
Packit Service |
37dbff |
*found_nodes = calloc(found, sizeof **found_nodes);
|
|
Packit Service |
37dbff |
if (*found_nodes == NULL) {
|
|
Packit Service |
37dbff |
snprintf(context->error_str,
|
|
Packit Service |
bc4570 |
sizeof(context->error_str),
|
|
Packit Service |
bc4570 |
"%s", strerror(ENOMEM));
|
|
Packit Service |
37dbff |
rc = ENOMEM;
|
|
Packit Service |
37dbff |
goto leave;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
found = 0;
|
|
Packit Service |
37dbff |
list_for_each_entry(rec, &bound_rec_list, list) {
|
|
Packit Service |
37dbff |
strlcpy((*found_nodes)[found].name, rec->name,
|
|
Packit Service |
37dbff |
LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
(*found_nodes)[found].tpgt = rec->tpgt;
|
|
Packit Service |
37dbff |
strlcpy((*found_nodes)[found].address,
|
|
Packit Service |
37dbff |
rec->conn[0].address, NI_MAXHOST);
|
|
Packit Service |
37dbff |
(*found_nodes)[found].port = rec->conn[0].port;
|
|
Packit Service |
37dbff |
strlcpy((*found_nodes)[found].iface,
|
|
Packit Service |
37dbff |
rec->iface.name, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
found++;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
leave:
|
|
Packit Service |
37dbff |
free_rec_list(&bound_rec_list);
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int libiscsi_discover_firmware(struct libiscsi_context *context,
|
|
Packit Service |
37dbff |
int *nr_found, struct libiscsi_node **found_nodes)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
struct list_head targets, ifaces, rec_list;
|
|
Packit Service |
37dbff |
discovery_rec_t drec;
|
|
Packit Service |
37dbff |
int rc = 0;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
INIT_LIST_HEAD(&targets;;
|
|
Packit Service |
37dbff |
INIT_LIST_HEAD(&ifaces);
|
|
Packit Service |
37dbff |
INIT_LIST_HEAD(&rec_list);
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (nr_found) {
|
|
Packit Service |
37dbff |
*nr_found = 0;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (found_nodes) {
|
|
Packit Service |
37dbff |
*found_nodes = NULL;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
rc = fw_get_targets(&targets;;
|
|
Packit Service |
37dbff |
if (rc) {
|
|
Packit Service |
37dbff |
log_error("%s: Could not get list of targets from firmware "
|
|
Packit Service |
37dbff |
"(err %d).\n", __func__, rc);
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
CHECK(iface_create_ifaces_from_boot_contexts(&ifaces, &targets));
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
memset(&drec, 0, sizeof(drec));
|
|
Packit Service |
c705e8 |
drec.iscsid_req_tmo = -1;
|
|
Packit Service |
37dbff |
drec.type = DISCOVERY_TYPE_FW;
|
|
Packit Service |
37dbff |
rc = idbm_bind_ifaces_to_nodes(discovery_fw, &drec, &ifaces, &rec_list);
|
|
Packit Service |
37dbff |
if (rc) {
|
|
Packit Service |
37dbff |
log_error("%s: Could not determine target nodes from firmware "
|
|
Packit Service |
37dbff |
"(err %d).\n", __func__, rc);
|
|
Packit Service |
37dbff |
goto leave;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int node_count = 0;
|
|
Packit Service |
37dbff |
struct list_head *pos;
|
|
Packit Service |
37dbff |
list_for_each(pos, &rec_list) {
|
|
Packit Service |
37dbff |
++node_count;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
struct libiscsi_node* new_nodes;
|
|
Packit Service |
37dbff |
/* allocate enough space for all the nodes */
|
|
Packit Service |
37dbff |
new_nodes = calloc(node_count, sizeof *new_nodes);
|
|
Packit Service |
37dbff |
if (new_nodes == NULL) {
|
|
Packit Service |
37dbff |
rc = ENOMEM;
|
|
Packit Service |
37dbff |
log_error("%s: %s.\n", __func__, strerror(ENOMEM));
|
|
Packit Service |
37dbff |
goto leave;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
struct node_rec *rec;
|
|
Packit Service |
37dbff |
struct libiscsi_node *new_node = new_nodes;
|
|
Packit Service |
37dbff |
/* in one loop, add nodes to idbm and create libiscsi_node entries */
|
|
Packit Service |
37dbff |
list_for_each_entry(rec, &rec_list, list) {
|
|
Packit Service |
37dbff |
CHECK(idbm_add_node(rec, NULL, 1 /* overwrite */));
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
strlcpy(new_node->name, rec->name, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
new_node->tpgt = rec->tpgt;
|
|
Packit Service |
37dbff |
strlcpy(new_node->address, rec->conn[0].address, NI_MAXHOST);
|
|
Packit Service |
37dbff |
new_node->port = rec->conn[0].port;
|
|
Packit Service |
37dbff |
strlcpy(new_node->iface, rec->iface.name, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
++new_node;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
/* update output parameters */
|
|
Packit Service |
37dbff |
if (nr_found) {
|
|
Packit Service |
37dbff |
*nr_found = node_count;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
if (found_nodes) {
|
|
Packit Service |
37dbff |
*found_nodes = new_nodes;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
leave:
|
|
Packit Service |
37dbff |
fw_free_targets(&targets;;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
free_iface_list(&ifaces);
|
|
Packit Service |
37dbff |
free_rec_list(&rec_list);
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int libiscsi_verify_auth_info(struct libiscsi_context *context,
|
|
Packit Service |
37dbff |
const struct libiscsi_auth_info *auth_info)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
switch(auth_info ? auth_info->method : libiscsi_auth_none) {
|
|
Packit Service |
37dbff |
case libiscsi_auth_none:
|
|
Packit Service |
37dbff |
break;
|
|
Packit Service |
37dbff |
case libiscsi_auth_chap:
|
|
Packit Service |
37dbff |
if (!auth_info->chap.username[0]) {
|
|
Packit Service |
37dbff |
strcpy(context->error_str, "Empty username");
|
|
Packit Service |
37dbff |
return EINVAL;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
if (!auth_info->chap.password[0]) {
|
|
Packit Service |
37dbff |
strcpy(context->error_str, "Empty password");
|
|
Packit Service |
37dbff |
return EINVAL;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
if (auth_info->chap.reverse_username[0] &&
|
|
Packit Service |
37dbff |
!auth_info->chap.reverse_password[0]) {
|
|
Packit Service |
37dbff |
strcpy(context->error_str, "Empty reverse password");
|
|
Packit Service |
37dbff |
return EINVAL;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
break;
|
|
Packit Service |
37dbff |
default:
|
|
Packit Service |
37dbff |
sprintf(context->error_str,
|
|
Packit Service |
37dbff |
"Invalid authentication method: %d",
|
|
Packit Service |
37dbff |
(int)auth_info->method);
|
|
Packit Service |
37dbff |
return EINVAL;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
return 0;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int libiscsi_node_set_auth(struct libiscsi_context *context,
|
|
Packit Service |
37dbff |
const struct libiscsi_node *node,
|
|
Packit Service |
37dbff |
const struct libiscsi_auth_info *auth_info)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
int rc = 0;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
CHECK(libiscsi_verify_auth_info(context, auth_info))
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
switch(auth_info ? auth_info->method : libiscsi_auth_none) {
|
|
Packit Service |
37dbff |
case libiscsi_auth_none:
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_set_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.authmethod", "None"))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_set_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.username", ""))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_set_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.password", ""))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_set_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.username_in", ""))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_set_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.password_in", ""))
|
|
Packit Service |
37dbff |
break;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
case libiscsi_auth_chap:
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_set_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.authmethod", "CHAP"))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_set_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.username",
|
|
Packit Service |
37dbff |
auth_info->chap.username))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_set_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.password",
|
|
Packit Service |
37dbff |
auth_info->chap.password))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_set_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.username_in",
|
|
Packit Service |
37dbff |
auth_info->chap.reverse_username))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_set_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.password_in",
|
|
Packit Service |
37dbff |
auth_info->chap.reverse_password))
|
|
Packit Service |
37dbff |
break;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
leave:
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int libiscsi_node_get_auth(struct libiscsi_context *context,
|
|
Packit Service |
37dbff |
const struct libiscsi_node *node,
|
|
Packit Service |
37dbff |
struct libiscsi_auth_info *auth_info)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
int rc = 0;
|
|
Packit Service |
37dbff |
char value[LIBISCSI_VALUE_MAXLEN];
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
memset(auth_info, 0, sizeof *auth_info);
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_get_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.authmethod", value))
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (!strcmp(value, "None")) {
|
|
Packit Service |
37dbff |
auth_info->method = libiscsi_auth_none;
|
|
Packit Service |
37dbff |
} else if (!strcmp(value, "CHAP")) {
|
|
Packit Service |
37dbff |
auth_info->method = libiscsi_auth_chap;
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_get_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.username",
|
|
Packit Service |
37dbff |
auth_info->chap.username))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_get_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.password",
|
|
Packit Service |
37dbff |
auth_info->chap.password))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_get_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.username_in",
|
|
Packit Service |
37dbff |
auth_info->chap.reverse_username))
|
|
Packit Service |
37dbff |
CHECK(libiscsi_node_get_parameter(context, node,
|
|
Packit Service |
37dbff |
"node.session.auth.password_in",
|
|
Packit Service |
37dbff |
auth_info->chap.reverse_password))
|
|
Packit Service |
37dbff |
} else {
|
|
Packit Service |
37dbff |
snprintf(context->error_str, sizeof(context->error_str),
|
|
Packit Service |
37dbff |
"unknown authentication method: %s", value);
|
|
Packit Service |
37dbff |
rc = EINVAL;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
leave:
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
static void node_to_rec(const struct libiscsi_node *node,
|
|
Packit Service |
37dbff |
struct node_rec *rec)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
memset(rec, 0, sizeof *rec);
|
|
Packit Service |
37dbff |
idbm_node_setup_defaults(rec);
|
|
Packit Service |
37dbff |
strlcpy(rec->name, node->name, TARGET_NAME_MAXLEN);
|
|
Packit Service |
37dbff |
rec->tpgt = node->tpgt;
|
|
Packit Service |
37dbff |
strlcpy(rec->conn[0].address, node->address, NI_MAXHOST);
|
|
Packit Service |
37dbff |
rec->conn[0].port = node->port;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int login_helper(void *data, node_rec_t *rec)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
char *iface = (char*)data;
|
|
Packit Service |
37dbff |
if (strcmp(iface, rec->iface.name))
|
|
Packit Service |
37dbff |
/* different iface, skip it */
|
|
Packit Service |
37dbff |
return -1;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int rc = iscsid_req_by_rec(MGMT_IPC_SESSION_LOGIN, rec);
|
|
Packit Service |
37dbff |
if (rc) {
|
|
Packit Service |
37dbff |
iscsi_err_print_msg(rc);
|
|
Packit Service |
37dbff |
rc = ENOTCONN;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int libiscsi_node_login(struct libiscsi_context *context,
|
|
Packit Service |
37dbff |
const struct libiscsi_node *node)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
int nr_found = 0, rc;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
CHECK(idbm_for_each_iface(&nr_found, (void*)node->iface, login_helper,
|
|
Packit Service |
37dbff |
(char *)node->name, node->tpgt,
|
|
Packit Service |
6fbcfd |
(char *)node->address, node->port, false))
|
|
Packit Service |
37dbff |
if (nr_found == 0) {
|
|
Packit Service |
37dbff |
strcpy(context->error_str, "No such node");
|
|
Packit Service |
37dbff |
rc = ENODEV;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
leave:
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
static int logout_helper(void *data, struct session_info *info)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
int rc;
|
|
Packit Service |
37dbff |
struct node_rec *rec = data;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (!iscsi_match_session(rec, info))
|
|
Packit Service |
37dbff |
/* Tell iscsi_sysfs_for_each_session this session was not a
|
|
Packit Service |
37dbff |
match so that it will not increase nr_found. */
|
|
Packit Service |
37dbff |
return -1;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
rc = iscsid_req_by_sid(MGMT_IPC_SESSION_LOGOUT, info->sid);
|
|
Packit Service |
37dbff |
if (rc) {
|
|
Packit Service |
37dbff |
iscsi_err_print_msg(rc);
|
|
Packit Service |
37dbff |
rc = EIO;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int libiscsi_node_logout(struct libiscsi_context *context,
|
|
Packit Service |
37dbff |
const struct libiscsi_node *node)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
int nr_found = 0, rc;
|
|
Packit Service |
37dbff |
struct node_rec rec;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
node_to_rec(node, &rec);
|
|
Packit Service |
37dbff |
CHECK(iscsi_sysfs_for_each_session(&rec, &nr_found, logout_helper,0))
|
|
Packit Service |
37dbff |
if (nr_found == 0) {
|
|
Packit Service |
37dbff |
strcpy(context->error_str, "No matching session");
|
|
Packit Service |
37dbff |
rc = ENODEV;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
leave:
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
44d698 |
struct libiscsi_session_array {
|
|
Packit Service |
44d698 |
int cnt;
|
|
Packit Service |
44d698 |
int size;
|
|
Packit Service |
44d698 |
struct libiscsi_session_info *data;
|
|
Packit Service |
44d698 |
};
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
static void libiscsi_session_array_init(struct libiscsi_session_array *arr)
|
|
Packit Service |
44d698 |
{
|
|
Packit Service |
44d698 |
arr->cnt = 0;
|
|
Packit Service |
44d698 |
arr->size = 0;
|
|
Packit Service |
44d698 |
arr->data = NULL;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
static int libiscsi_session_array_grow(struct libiscsi_session_array *arr)
|
|
Packit Service |
44d698 |
{
|
|
Packit Service |
44d698 |
if (arr->size == 0)
|
|
Packit Service |
44d698 |
arr->size = 4;
|
|
Packit Service |
44d698 |
else
|
|
Packit Service |
44d698 |
arr->size *= 2;
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
arr->data = (struct libiscsi_session_info *) realloc(
|
|
Packit Service |
44d698 |
arr->data,
|
|
Packit Service |
44d698 |
arr->size * sizeof(struct libiscsi_session_info));
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
return arr->data ? 0 : 1;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
static int libiscsi_session_array_grow_ondemand(struct libiscsi_session_array *arr)
|
|
Packit Service |
44d698 |
{
|
|
Packit Service |
44d698 |
if (arr->size == arr->cnt)
|
|
Packit Service |
44d698 |
return libiscsi_session_array_grow(arr);
|
|
Packit Service |
44d698 |
return 0;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
static int libiscsi_session_array_resize_precize(struct libiscsi_session_array *arr)
|
|
Packit Service |
44d698 |
{
|
|
Packit Service |
44d698 |
arr->data = (struct libiscsi_session_info *) realloc(
|
|
Packit Service |
44d698 |
arr->data,
|
|
Packit Service |
44d698 |
arr->cnt * sizeof(struct libiscsi_session_info));
|
|
Packit Service |
44d698 |
arr->size = arr->cnt;
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
return arr->data ? 0 : 1;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
static void copy_session_info_to_libiscsi_session_info(
|
|
Packit Service |
44d698 |
struct libiscsi_session_info *info,
|
|
Packit Service |
44d698 |
struct session_info *s_info)
|
|
Packit Service |
44d698 |
{
|
|
Packit Service |
44d698 |
/* Copy session info to public struct. */
|
|
Packit Service |
44d698 |
info->sid = s_info->sid;
|
|
Packit Service |
44d698 |
/* Timeouts */
|
|
Packit Service |
44d698 |
memcpy(&info->tmo, &s_info->tmo, sizeof(struct libiscsi_session_timeout));
|
|
Packit Service |
44d698 |
/* CHAP authentication information */
|
|
Packit Service |
44d698 |
memcpy(&info->chap, &s_info->chap, sizeof(struct libiscsi_chap_auth_info));
|
|
Packit Service |
44d698 |
/* Target information */
|
|
Packit Service |
44d698 |
strncpy(info->targetname, s_info->targetname, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
44d698 |
strncpy(info->address, s_info->address, NI_MAXHOST);
|
|
Packit Service |
44d698 |
strncpy(info->persistent_address, s_info->persistent_address, NI_MAXHOST);
|
|
Packit Service |
44d698 |
info->tpgt = s_info->tpgt;
|
|
Packit Service |
44d698 |
info->persistent_port = s_info->persistent_port;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
static int get_sessions_helper(void *data, struct session_info *s_info)
|
|
Packit Service |
44d698 |
{
|
|
Packit Service |
44d698 |
struct libiscsi_session_array *arr = (struct libiscsi_session_array *) data;
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
if (libiscsi_session_array_grow_ondemand(arr) != 0)
|
|
Packit Service |
44d698 |
return 1;
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
copy_session_info_to_libiscsi_session_info(&arr->data[arr->cnt++], s_info);
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
return 0;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
int libiscsi_get_session_infos(struct libiscsi_context *context,
|
|
Packit Service |
44d698 |
struct libiscsi_session_info **infos,
|
|
Packit Service |
44d698 |
int *nr_sessions)
|
|
Packit Service |
44d698 |
{
|
|
Packit Service |
44d698 |
int rc = 0;
|
|
Packit Service |
44d698 |
int nr_found = 0;
|
|
Packit Service |
44d698 |
struct libiscsi_session_array arr;
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
if (!context || !infos || !nr_sessions)
|
|
Packit Service |
44d698 |
return 1;
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
libiscsi_session_array_init(&arr;;
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
rc = iscsi_sysfs_for_each_session((void *) &arr, &nr_found,
|
|
Packit Service |
44d698 |
get_sessions_helper, 0);
|
|
Packit Service |
44d698 |
if (rc != 0 || nr_found == 0) {
|
|
Packit Service |
44d698 |
strcpy(context->error_str, "No matching session");
|
|
Packit Service |
44d698 |
return ENODEV;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
if (libiscsi_session_array_resize_precize(&arr) != 0) {
|
|
Packit Service |
44d698 |
strcpy(context->error_str, "Can't allocate memory for session infos");
|
|
Packit Service |
44d698 |
return ENOMEM;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
*infos = arr.data;
|
|
Packit Service |
44d698 |
*nr_sessions = nr_found;
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
return 0;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
int libiscsi_get_session_info_by_id(struct libiscsi_context *context,
|
|
Packit Service |
44d698 |
struct libiscsi_session_info *info,
|
|
Packit Service |
44d698 |
const char *session)
|
|
Packit Service |
44d698 |
{
|
|
Packit Service |
44d698 |
struct session_info s_info;
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
if (!context || !info || !session)
|
|
Packit Service |
44d698 |
return 1;
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
if (iscsi_sysfs_get_sessioninfo_by_id(&s_info, (char*) session) != 0) {
|
|
Packit Service |
44d698 |
strcpy(context->error_str, "No matching session");
|
|
Packit Service |
44d698 |
return ENODEV;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
copy_session_info_to_libiscsi_session_info(info, &s_info);
|
|
Packit Service |
44d698 |
|
|
Packit Service |
44d698 |
return 0;
|
|
Packit Service |
44d698 |
}
|
|
Packit Service |
44d698 |
|
|
Packit Service |
37dbff |
int libiscsi_node_set_parameter(struct libiscsi_context *context,
|
|
Packit Service |
37dbff |
const struct libiscsi_node *node,
|
|
Packit Service |
37dbff |
const char *parameter, const char *value)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
int nr_found = 0, rc;
|
|
Packit Service |
37dbff |
struct user_param *param;
|
|
Packit Service |
37dbff |
struct list_head params;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
INIT_LIST_HEAD(¶ms);
|
|
Packit Service |
37dbff |
param = idbm_alloc_user_param(parameter, value);
|
|
Packit Service |
37dbff |
if (!param) {
|
|
Packit Service |
37dbff |
rc = ENOMEM;
|
|
Packit Service |
37dbff |
goto leave;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
list_add_tail(¶ms, ¶m->list);
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
CHECK(idbm_for_each_iface(&nr_found, ¶ms, idbm_node_set_param,
|
|
Packit Service |
37dbff |
(char *)node->name, node->tpgt,
|
|
Packit Service |
6fbcfd |
(char *)node->address, node->port, false))
|
|
Packit Service |
37dbff |
if (nr_found == 0) {
|
|
Packit Service |
37dbff |
strcpy(context->error_str, "No such node");
|
|
Packit Service |
37dbff |
rc = ENODEV;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
free(param->name);
|
|
Packit Service |
37dbff |
free(param);
|
|
Packit Service |
37dbff |
leave:
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
static int get_parameter_helper(void *data, node_rec_t *rec)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
struct libiscsi_context *context = data;
|
|
Packit Service |
37dbff |
recinfo_t *info;
|
|
Packit Service |
37dbff |
int i;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
info = idbm_recinfo_alloc(MAX_KEYS);
|
|
Packit Service |
37dbff |
if (!info) {
|
|
Packit Service |
37dbff |
snprintf(context->error_str, sizeof(context->error_str),
|
|
Packit Service |
bc4570 |
"%s", strerror(ENOMEM));
|
|
Packit Service |
37dbff |
return ENOMEM;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
idbm_recinfo_node(rec, info);
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
for (i = 0; i < MAX_KEYS; i++) {
|
|
Packit Service |
37dbff |
if (!info[i].visible)
|
|
Packit Service |
37dbff |
continue;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (strcmp(context->parameter, info[i].name))
|
|
Packit Service |
37dbff |
continue;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
strlcpy(context->value, info[i].value, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
break;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
free(info);
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (i == MAX_KEYS) {
|
|
Packit Service |
37dbff |
strcpy(context->error_str, "No such parameter");
|
|
Packit Service |
37dbff |
return EINVAL;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
return 0;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int libiscsi_node_get_parameter(struct libiscsi_context *context,
|
|
Packit Service |
37dbff |
const struct libiscsi_node *node, const char *parameter, char *value)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
int nr_found = 0, rc = 0;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
context->parameter = parameter;
|
|
Packit Service |
37dbff |
context->value = value;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
/* Note we assume there is only one interface, if not we will get
|
|
Packit Service |
37dbff |
the value from the last interface iterated over!
|
|
Packit Service |
37dbff |
This (multiple interfaces) can only happen if someone explicitly
|
|
Packit Service |
37dbff |
created ones using iscsiadm. Even then this should not be a problem
|
|
Packit Service |
37dbff |
as most settings should be the same independent of the iface. */
|
|
Packit Service |
37dbff |
CHECK(idbm_for_each_iface(&nr_found, context, get_parameter_helper,
|
|
Packit Service |
37dbff |
(char *)node->name, node->tpgt,
|
|
Packit Service |
6fbcfd |
(char *)node->address, node->port, false))
|
|
Packit Service |
37dbff |
if (nr_found == 0) {
|
|
Packit Service |
37dbff |
strcpy(context->error_str, "No such node");
|
|
Packit Service |
37dbff |
rc = ENODEV;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
leave:
|
|
Packit Service |
37dbff |
return rc;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
const char *libiscsi_get_error_string(struct libiscsi_context *context)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
/* Sometimes the core open-iscsi code does not give us an error
|
|
Packit Service |
37dbff |
message */
|
|
Packit Service |
37dbff |
if (!context->error_str[0])
|
|
Packit Service |
37dbff |
return "Unknown error";
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
return context->error_str;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
/************************** Utility functions *******************************/
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int libiscsi_get_firmware_network_config(
|
|
Packit Service |
37dbff |
struct libiscsi_network_config *config)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
struct boot_context fw_entry;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (!sysfs_initialized) {
|
|
Packit Service |
37dbff |
sysfs_init();
|
|
Packit Service |
37dbff |
sysfs_initialized = 1;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
memset(config, 0, sizeof *config);
|
|
Packit Service |
37dbff |
memset(&fw_entry, 0, sizeof fw_entry);
|
|
Packit Service |
37dbff |
if (fw_get_entry(&fw_entry))
|
|
Packit Service |
37dbff |
return ENODEV;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
config->dhcp = strlen(fw_entry.dhcp) ? 1 : 0;
|
|
Packit Service |
37dbff |
strlcpy(config->iface_name, fw_entry.iface, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
strlcpy(config->mac_address, fw_entry.mac, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
strlcpy(config->ip_address, fw_entry.ipaddr, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
strlcpy(config->netmask, fw_entry.mask, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
strlcpy(config->gateway, fw_entry.gateway, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
strlcpy(config->primary_dns, fw_entry.primary_dns, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
strlcpy(config->secondary_dns, fw_entry.secondary_dns, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
return 0;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
int libiscsi_get_firmware_initiator_name(char *initiatorname)
|
|
Packit Service |
37dbff |
{
|
|
Packit Service |
37dbff |
struct boot_context fw_entry;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
if (!sysfs_initialized) {
|
|
Packit Service |
37dbff |
sysfs_init();
|
|
Packit Service |
37dbff |
sysfs_initialized = 1;
|
|
Packit Service |
37dbff |
}
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
memset(initiatorname, 0, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
memset(&fw_entry, 0, sizeof fw_entry);
|
|
Packit Service |
37dbff |
if (fw_get_entry(&fw_entry))
|
|
Packit Service |
37dbff |
return ENODEV;
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
strlcpy(initiatorname, fw_entry.initiatorname, LIBISCSI_VALUE_MAXLEN);
|
|
Packit Service |
37dbff |
|
|
Packit Service |
37dbff |
return 0;
|
|
Packit Service |
37dbff |
}
|