mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-17 02:31:27 +00:00
There is a regular need in the kernel to provide a way to declare
having a dynamically sized set of trailing elements in a structure.
Kernel code should always use “flexible array members”[1] for these
cases. The older style of one-element or zero-length arrays should
no longer be used[2].
This code was transformed with the help of Coccinelle:
($ spatch --jobs $(getconf _NPROCESSORS_ONLN) --sp-file script.cocci --include-headers --dir . > output.patch)
@@
identifier S, member, array;
type T1, T2;
@@
struct S {
...
T1 member;
T2 array[
- 0
];
};
[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arrays
Link: https://github.com/KSPP/linux/issues/78
405 lines
12 KiB
C
405 lines
12 KiB
C
/*
|
|
* Copyright (C) 2002 - 2003 Ardis Technologies <roman@ardistech.com>
|
|
* Copyright (C) 2007 - 2018 Vladislav Bolkhovitin
|
|
* Copyright (C) 2007 - 2018 Western Digital Corporation
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation, version 2
|
|
* of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#ifndef ISCSID_H
|
|
#define ISCSID_H
|
|
|
|
#include <search.h>
|
|
#include <sys/types.h>
|
|
#include <poll.h>
|
|
#include <assert.h>
|
|
#include <netdb.h>
|
|
#include <syslog.h>
|
|
|
|
#include "types.h"
|
|
#ifdef INSIDE_KERNEL_TREE
|
|
#include <scst/iscsi_scst.h>
|
|
#include <scst/isert_scst.h>
|
|
#else
|
|
#include "iscsi_scst.h"
|
|
#include "isert_scst.h"
|
|
#endif
|
|
#include "iscsi_hdr.h"
|
|
#include "param.h"
|
|
#include "misc.h"
|
|
|
|
#ifndef bool
|
|
typedef enum {false = 0, true} bool;
|
|
#endif
|
|
|
|
#define sBUG() assert(0)
|
|
#define sBUG_ON(p) assert(!(p))
|
|
|
|
struct iscsi_init_params {
|
|
int max_data_seg_len;
|
|
int max_queued_cmds;
|
|
};
|
|
|
|
struct buf_segment {
|
|
struct __qelem entry;
|
|
|
|
unsigned int len;
|
|
char data[];
|
|
};
|
|
|
|
struct PDU {
|
|
struct iscsi_hdr bhs;
|
|
void *ahs;
|
|
unsigned int ahssize;
|
|
void *data;
|
|
unsigned int datasize;
|
|
};
|
|
|
|
#define KEY_STATE_START 0
|
|
#define KEY_STATE_REQUEST 1
|
|
#define KEY_STATE_DONE_ADDED 2
|
|
#define KEY_STATE_DONE 3
|
|
|
|
struct session {
|
|
struct __qelem slist;
|
|
|
|
char *initiator;
|
|
struct target *target;
|
|
union iscsi_sid sid;
|
|
|
|
struct __qelem conn_list;
|
|
};
|
|
|
|
struct connection {
|
|
int state;
|
|
int iostate;
|
|
int fd;
|
|
|
|
unsigned int passed_to_kern:1;
|
|
unsigned int sessions_count_incremented:1;
|
|
|
|
struct target *target;
|
|
struct session *sess;
|
|
|
|
u32 tid;
|
|
|
|
/* Put here, because negotiations is done before session created */
|
|
struct iscsi_param session_params[session_key_last];
|
|
|
|
char *initiator;
|
|
char *target_portal;
|
|
char *user;
|
|
union iscsi_sid sid;
|
|
u16 cid;
|
|
|
|
int session_type;
|
|
int auth_method;
|
|
|
|
u32 stat_sn;
|
|
u32 exp_stat_sn;
|
|
|
|
u32 cmd_sn;
|
|
u32 exp_cmd_sn;
|
|
u32 ttt;
|
|
|
|
struct PDU req;
|
|
void *req_buffer;
|
|
struct PDU rsp;
|
|
struct __qelem rsp_buf_list;
|
|
unsigned char *buffer;
|
|
int rwsize;
|
|
|
|
int auth_state;
|
|
union {
|
|
struct {
|
|
int digest_alg;
|
|
int id;
|
|
int challenge_size;
|
|
unsigned char *challenge;
|
|
} chap;
|
|
} auth;
|
|
|
|
struct __qelem clist;
|
|
|
|
bool is_iser;
|
|
|
|
int (*cork_transmit)(int fd);
|
|
int (*uncork_transmit)(int fd);
|
|
int (*getsockname)(int fd, struct sockaddr *name, socklen_t *namelen);
|
|
int (*is_discovery)(int fd);
|
|
};
|
|
|
|
#define IOSTATE_FREE 0
|
|
#define IOSTATE_READ_BHS 1
|
|
#define IOSTATE_READ_AHS_DATA 2
|
|
#define IOSTATE_WRITE_BHS 3
|
|
#define IOSTATE_WRITE_AHS 4
|
|
#define IOSTATE_WRITE_DATA 5
|
|
|
|
#define STATE_FREE 0
|
|
#define STATE_SECURITY 1
|
|
#define STATE_SECURITY_AUTH 2
|
|
#define STATE_SECURITY_DONE 3
|
|
#define STATE_SECURITY_LOGIN 4
|
|
#define STATE_SECURITY_FULL 5
|
|
#define STATE_LOGIN 6
|
|
#define STATE_LOGIN_FULL 7
|
|
#define STATE_FULL 8
|
|
#define STATE_KERNEL 9
|
|
#define STATE_CLOSE 10
|
|
#define STATE_EXIT 11
|
|
#define STATE_DROP 12
|
|
|
|
#define AUTH_STATE_START 0
|
|
#define AUTH_STATE_CHALLENGE 1
|
|
|
|
#define SESSION_NORMAL 0
|
|
#define SESSION_DISCOVERY 1
|
|
#define AUTH_UNKNOWN -1
|
|
#define AUTH_NONE 0
|
|
#define AUTH_CHAP 1
|
|
#define DIGEST_UNKNOWN -1
|
|
|
|
#define BHS_SIZE 48
|
|
|
|
/*
|
|
* Must be 8192, since it used as MaxRecvDataSegmentLength during Login phase,
|
|
* because iSCSI RFC requires: "The default MaxRecvDataSegmentLength is used
|
|
* during Login".
|
|
*/
|
|
#define INCOMING_BUFSIZE 8192
|
|
|
|
#define ISCSI_USER_DIR_INCOMING 0
|
|
#define ISCSI_USER_DIR_OUTGOING 1
|
|
|
|
#define ISCSI_USER_NAME(attr) ((attr)->attr_key)
|
|
#define ISCSI_USER_PASS(attr) ((attr)->attr_value)
|
|
|
|
struct iscsi_attr {
|
|
struct __qelem ulist;
|
|
const char *attr_key;
|
|
const char *attr_value;
|
|
u32 sysfs_mode;
|
|
char sysfs_name[64];
|
|
};
|
|
|
|
struct target {
|
|
struct __qelem tlist;
|
|
|
|
struct __qelem sessions_list;
|
|
|
|
unsigned int tgt_enabled:1;
|
|
unsigned int per_portal_acl:1;
|
|
|
|
unsigned int target_params[target_key_last];
|
|
unsigned int session_params[session_key_last];
|
|
|
|
u32 tid;
|
|
char name[ISCSI_NAME_LEN];
|
|
char *alias;
|
|
unsigned int sessions_count;
|
|
|
|
struct redirect_addr {
|
|
char addr[NI_MAXHOST + 1];
|
|
int port;
|
|
u8 type; /* one of ISCSI_STATUS_TGT_MOVED_* constants */
|
|
} redirect;
|
|
|
|
struct __qelem target_in_accounts;
|
|
struct __qelem target_out_accounts;
|
|
|
|
struct __qelem allowed_portals;
|
|
|
|
struct __qelem isns_head;
|
|
};
|
|
|
|
extern int ctrl_fd;
|
|
extern int conn_blocked;
|
|
|
|
#define ADDR_MAX 32
|
|
#define LISTEN_MAX 32
|
|
#define INCOMING_MAX 256
|
|
|
|
enum {
|
|
POLL_LISTEN,
|
|
POLL_IPC = POLL_LISTEN + LISTEN_MAX,
|
|
POLL_ISER_LISTEN,
|
|
POLL_NL,
|
|
POLL_ISNS,
|
|
POLL_SCN_LISTEN,
|
|
POLL_SCN,
|
|
POLL_INCOMING,
|
|
POLL_MAX = POLL_INCOMING + INCOMING_MAX,
|
|
};
|
|
|
|
extern struct pollfd poll_array[POLL_MAX];
|
|
|
|
extern int nl_fd;
|
|
|
|
/* chap.c */
|
|
extern int cmnd_exec_auth_chap(struct connection *conn);
|
|
|
|
/* conn.c */
|
|
extern struct connection *conn_alloc(void);
|
|
extern void conn_free(struct connection *conn);
|
|
extern void conn_pass_to_kern(struct connection *conn, int fd);
|
|
extern void conn_read_pdu(struct connection *conn);
|
|
extern void conn_write_pdu(struct connection *conn);
|
|
extern void conn_free_pdu(struct connection *conn);
|
|
extern void conn_free_rsp_buf_list(struct connection *conn);
|
|
|
|
/* iscsi_scstd.c */
|
|
extern uint16_t server_port;
|
|
extern struct iscsi_init_params iscsi_init_params;
|
|
extern void isns_set_fd(int isns, int scn_listen, int scn);
|
|
extern const char *get_error_str(int error);
|
|
|
|
/* iscsid.c */
|
|
extern int iscsi_enabled;
|
|
|
|
extern int cmnd_execute(struct connection *conn);
|
|
extern void cmnd_finish(struct connection *conn);
|
|
extern char *text_key_find(struct connection *conn, const char *searchKey);
|
|
extern void text_key_add(struct connection *conn, const char *key,
|
|
const char *value);
|
|
|
|
/* log.c */
|
|
extern int log_daemon;
|
|
extern int log_level;
|
|
|
|
extern void log_init(void);
|
|
extern void __log(const char *func, int line, int prio, int level, const char *fmt, ...)
|
|
__attribute__ ((format (printf, 5, 6)));
|
|
extern void __log_pdu(const char *func, int line, int level, struct PDU *pdu);
|
|
|
|
#define log_info(args...) __log(__func__, __LINE__, LOG_INFO, 0, ## args)
|
|
#define log_warning(args...) __log(__func__, __LINE__, LOG_WARNING, 0, ## args)
|
|
#define log_error(args...) __log(__func__, __LINE__, LOG_ERR, 0, ## args)
|
|
#define log_debug(level, args...) __log(__func__, __LINE__, LOG_DEBUG, level, ## args)
|
|
#define log_pdu(level, args...) __log_pdu(__func__, __LINE__, level, ## args)
|
|
|
|
/* Conditional versions of log_* functions. Useful when log priority depends
|
|
* on some parameter, say recurrence of some event. In these cases the first
|
|
* occurrence could be logged as log_info while the latter ones may be logged
|
|
* with log_debug. So, if level != 0 then log_debug is called.
|
|
*/
|
|
#define log_info_cond(level, args...) \
|
|
__log(__func__, __LINE__, LOG_INFO, level, ## args)
|
|
#define log_warning_cond(level, args...) \
|
|
__log(__func__, __LINE__, LOG_WARNING, level, ## args)
|
|
#define log_error_cond(level, args...) \
|
|
__log(__func__, __LINE__, LOG_ERR, level, ## args)
|
|
|
|
/* session.c */
|
|
extern struct session *session_find_name(u32 tid, const char *iname, union iscsi_sid sid);
|
|
extern struct session *session_find_id(u32 tid, u64 sid);
|
|
extern int session_create(struct connection *conn);
|
|
extern void session_free(struct session *session);
|
|
extern struct connection *conn_find(struct session *session, u16 cid);
|
|
|
|
/* target.c */
|
|
extern struct __qelem targets_list;
|
|
extern int target_create(const char *name, struct target **out_target);
|
|
extern void target_free(struct target *target);
|
|
extern int target_add(struct target *target, u32 *tid, u32 cookie);
|
|
extern int target_del(u32 tid, u32 cookie);
|
|
extern u32 target_find_id_by_name(const char *name);
|
|
extern struct target *target_find_by_name(const char *name);
|
|
extern struct target *target_find_by_id(u32);
|
|
extern void target_list_build(struct connection *, char *);
|
|
extern int target_portal_allowed(struct target *target,
|
|
const char *target_portal, const char *initiator_name);
|
|
extern const char *iscsi_make_full_initiator_name(int per_portal_acl,
|
|
const char *initiator_name, const char *target_portal,
|
|
char *buf, int size);
|
|
extern bool target_redirected(struct target *target, struct connection *conn);
|
|
|
|
/* message.c */
|
|
extern int iscsi_adm_request_listen(void);
|
|
extern int iscsi_adm_request_handle(int accept_fd);
|
|
|
|
/* ctldev.c */
|
|
extern int kernel_open(void);
|
|
extern int kernel_params_get(u32 tid, u64 sid, int type, struct iscsi_param *params);
|
|
extern int kernel_params_set(u32 tid, u64 sid, int type, u32 partial,
|
|
const struct iscsi_param *params);
|
|
extern int kernel_target_create(struct target *target, u32 *tid, u32 cookie);
|
|
extern int kernel_target_destroy(u32 tid, u32 cookie);
|
|
extern int kernel_user_add(struct target *target, struct iscsi_attr *attr,
|
|
u32 cookie);
|
|
extern int kernel_user_del(struct target *target, struct iscsi_attr *attr,
|
|
u32 cookie);
|
|
extern int kernel_attr_add(struct target *target, const char *name,
|
|
u32 mode, u32 cookie);
|
|
extern int kernel_attr_del(struct target *target, const char *name, u32 cookie);
|
|
extern int kernel_initiator_allowed(u32 tid, const char *initiator_name);
|
|
extern int kernel_session_create(struct connection *conn);
|
|
extern int kernel_session_destroy(u32 tid, u64 sid);
|
|
extern int kernel_conn_create(u32 tid, u64 sid, u32 cid, u32 stat_sn, u32 exp_stat_sn,
|
|
int fd);
|
|
extern int kernel_conn_destroy(u32 tid, u64 sid, u32 cid);
|
|
|
|
/* event.c */
|
|
extern int handle_iscsi_events(int fd, bool wait);
|
|
extern int nl_open(void);
|
|
|
|
/* config.c */
|
|
extern char *config_sep_string(char **pp);
|
|
extern int config_parse_main(const char *data, u32 cookie);
|
|
extern int config_load(const char *config_name);
|
|
extern int config_target_create(u32 *tid, char *name);
|
|
extern int config_target_destroy(u32 tid);
|
|
extern int config_account_add(u32 tid, int dir, char *name, char *pass,
|
|
const char *sysfs_name, u32 cookie);
|
|
extern int __config_account_add(struct target *target, int dir, char *name,
|
|
char *pass, const char *sysfs_name, int send_to_kern, u32 cookie);
|
|
extern int config_account_query(u32 tid, int dir, const char *name, char *pass);
|
|
extern int config_account_list(u32 tid, int dir, u32 *cnt, u32 *overflow,
|
|
char *buf, size_t buf_sz);
|
|
extern int config_account_del(u32 tid, int dir, char *name, u32 cookie);
|
|
extern int config_params_get(u32 tid, u64 sid, int type, struct iscsi_param *params);
|
|
extern int config_params_set(u32 tid, u64 sid, int type, u32 partial,
|
|
struct iscsi_param *params);
|
|
extern int config_initiator_access_allowed(u32 tid, int fd);
|
|
extern int accounts_empty(u32 tid, int dir);
|
|
extern struct iscsi_attr *account_get_first(u32 tid, int dir);
|
|
extern struct iscsi_attr *account_lookup_by_sysfs_name(struct target *target,
|
|
int dir, const char *sysfs_name);
|
|
extern int account_replace(struct target *target, int direction,
|
|
const char *sysfs_name, char *value);
|
|
extern void accounts_free(struct __qelem *accounts_list);
|
|
extern struct iscsi_attr *iscsi_attr_lookup_by_sysfs_name(
|
|
struct __qelem *attrs_list, const char *sysfs_name);
|
|
extern struct iscsi_attr *iscsi_attr_lookup_by_key(
|
|
struct __qelem *attrs_list, const char *key);
|
|
extern void iscsi_attrs_free(struct __qelem *attrs_list);
|
|
extern int iscsi_attr_create(int attr_size, struct __qelem *attrs_list,
|
|
const char *sysfs_name_tmpl, const char *key, const char *val,
|
|
u32 mode, struct iscsi_attr **res_attr);
|
|
extern void iscsi_attr_destroy(struct iscsi_attr *attr);
|
|
extern int iscsi_attr_replace(struct __qelem *attrs_list, const char *sysfs_name,
|
|
char *raw_value);
|
|
|
|
/* isns.c */
|
|
extern char *isns_server;
|
|
extern int isns_access_control;
|
|
extern char isns_entity_target_name[ISCSI_NAME_LEN];
|
|
extern int isns_timeout;
|
|
extern int isns_init(void);
|
|
extern int isns_handle(int is_timeout);
|
|
extern int isns_scn_handle(int accept);
|
|
extern int isns_scn_access_allowed(u32 tid, char *name);
|
|
extern int isns_target_register(char *name);
|
|
extern int isns_target_deregister(char *name);
|
|
extern void isns_exit(void);
|
|
|
|
#endif /* ISCSID_H */
|