#ifndef ISCSID_H_
#define ISCSID_H_

/*
 * iSCSI driver for Linux
 * Copyright (C) 2002 Cisco Systems, Inc.
 * maintained by linux-iscsi@cisco.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * See the file COPYING included with this distribution for more details.
 *
 * $Id: iscsid.h,v 1.18 2003/01/20 23:23:33 smferris Exp $
 *
 * iscsid.h
 *
 *    Main include for iSCSI daemon
 * 
 */

#ifndef MIN
# define MIN(x,y) ((x) < (y) ? (x) : (y))
#endif

#ifndef MAX
# define MAX(x,y) ((x) >= (y) ? (x) : (y))
#endif

/* header plus alignment plus max login pdu size + pad */
#define ISCSI_LOGIN_BUFFER_SIZE    ((2 * sizeof(struct IscsiHdr)) + 4096 + 4) 

#include "iscsi-config.h"

/* structures representing processes that the main daemon has started */
typedef struct iscsi_session_process {
    struct iscsi_session_process *volatile next;
    struct iscsi_session_process *volatile prev;
    struct iscsi_session_config  *volatile config;
    unsigned long config_number;
    pid_t pid;
    volatile int remove;  /* kill and remove this from the list at the next opportunity */
    volatile int restart; /* restart if the pid is 0 */
    volatile int failed;  /* process failed, don't restart unless the user reloads the config */
    volatile int lun_inventory_changed; /* the session's LUNs may have changed */
} iscsi_session_process_t;

typedef struct iscsi_discovery_process {
    struct iscsi_discovery_process *volatile prev;
    struct iscsi_discovery_process *volatile next;
    iscsi_config_entry_t *entry;
    pid_t pid;
    int order;
    int pipe_fd;
    int in_progress;
    volatile int remove; /* kill and remove this from the list at the next opportunity */
    volatile int restart; /* restart if the pid is 0 */
} iscsi_discovery_process_t;

typedef struct iscsi_discovery_process_list {
    iscsi_discovery_process_t *volatile head;
    iscsi_discovery_process_t *volatile tail;
    volatile int changed;
    int count;
} iscsi_discovery_process_list_t;

typedef struct iscsi_session_process_list {
    iscsi_session_process_t *volatile head;
    iscsi_session_process_t *volatile tail;
    volatile int changed;
    volatile int lun_inventory_changed; 
    int count;
} iscsi_session_process_list_t;

struct iscsi_target_config;

typedef struct iscsi_target {
    struct iscsi_target *next;

    char *TargetName;

    struct iscsi_target_config *new_config;
    struct iscsi_target_config *current_config;

    iscsi_portal_descriptor_t  *new_portals; /* one or more portals referenced by the new_config */
    iscsi_portal_descriptor_t  *current_portals; /* one or more portals referenced by the current_config */

    /* used for tracking which process gets to propagate auth credentials to this target, to avoid flapping */
    iscsi_discovery_process_t *discovery; 
    int discovered;

} iscsi_target_t;

typedef struct iscsi_target_list {
    iscsi_target_t *volatile head;
    iscsi_target_t *volatile tail;
    volatile int lun_inventory_changed;
    volatile int check_configs; 
} iscsi_target_list_t;

/* daemon config */
typedef struct iscsi_daemon_config {
    char *config_file;
    char *pid_file;
    char *bindings_file;
    char *initiator_name_file;
    char *slp_program;

    char *initiator_name;
    char *initiator_alias;

    int  debug_level; /* for use by debugmsg */
    int  foreground;  /* if non-zero, the main process will remain in the foreground,
                       * instead of daemonizing itself.
                       */
} iscsi_daemon_config_t;

/* let everything access the daemon config */
extern iscsi_daemon_config_t daemon_config;

/* handling session processes */
extern void add_session_process(iscsi_session_process_list_t *list, iscsi_session_process_t *process);
extern void remove_session_process(iscsi_session_process_list_t *list, iscsi_session_process_t *process);
extern void free_session_process(iscsi_session_process_t *process);


/* exit code for session processes that failed, but shouldn't be retried */
#define ISCSI_SESSION_FAILED_NO_RETRY 100

#endif



