📄 iscsi_manage.c
字号:
/* common/iscsi_manage.c vi: set autoindent tabstop=4 shiftwidth=4 : This is the Management interface used to configure parameters on the iSCSI initiator and iSCSI target implementations Assumptions: requires the initiator and target modules to be loaded before the program is invoked. (Uses the proc interface provided by the modules).*//* Copyright (C) 2001-2003 InterOperability Lab (IOL) University of New Hampshier (UNH) Durham, NH 03824 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, 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The name of IOL and/or UNH may not be used to endorse or promote products derived from this software without specific prior written permission.*/#define _POSIX_C_SOURCE 199506L#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <ctype.h>#include <string.h>#include <errno.h>#include <netdb.h>#include <arpa/inet.h>#include <asm/param.h>#include <asm/types.h>#include "iscsi_common.h"#include "debug.h"/* strdup() not defined in POSIX */extern char *strdup(const char *);#define DEFAULT_HOST_NO 0#define DEFAULT_TARGET_NO 0char server_node[MAXHOSTNAMELEN];/* configures the initiator and target login parameters by writing the parameters to a /proc file */intdo_param(int who, int neg_info, char *keytext, int host_no, int target_no){ int fd, n, len = 0, result; static char file_name[128]; static char text_line[1024]; TRACE(TRACE_DEBUG, "Entering do_param\n"); if (who == INITIATOR) sprintf(file_name, "/proc/scsi/iscsi_initiator/%d", host_no); else if (who == TARGET) sprintf(file_name, "/proc/scsi_target/iscsi_target/%d", host_no); result = -1; if ((fd = open(file_name, O_RDWR)) < 0) { perror(file_name); } else { if (who == INITIATOR) len = sprintf(text_line, "iscsi_initiator manage %d %d %s", target_no, neg_info, keytext); else if (who == TARGET) len = sprintf(text_line, "iscsi_target manage %d %s", neg_info, keytext); if ((n = write(fd, text_line, len)) < 0) perror(file_name); else if (n != len && n != 0) printf("%s: wrote %d bytes, expected %d\n", file_name, n, len); else result = 0; close(fd); } TRACE(TRACE_DEBUG, "Leaving do_param\n"); return result;}/* number must follow offset in buffer */unsigned intcheck_number(char *buffer, int offset){ char *endptr; unsigned int result; errno = 0; result = strtoul(&buffer[offset], &endptr, 0); if (buffer[offset] == '\0' || errno != 0 || strspn(endptr, WHITE_SPACE) != strlen(endptr)) { printf("illegal number \"%s\"\n", buffer); exit(EXIT_FAILURE); } return result;}intmain(int argc, char *argv[]){ int neg_info, i, inittarget; unsigned int value; char *value_list = NULL; int host_no, target_no; char *endptr; if (argc < 4) { /* must have at least 4 parameters except when using "restore" */ if ((argc != 3) || strcmp(argv[2], "restore") != 0) { printf ("Usage: iscsi_manage init/target set/setr/unset/setp/restore" "/force <ParameterName>=[value=val1[,val2,..]] [host=number]\n"); exit(EXIT_FAILURE); } } if (strcmp(argv[1], "init") == 0) inittarget = INITIATOR; else if (strcmp(argv[1], "target") == 0) inittarget = TARGET; else { printf ("parameter 1 must be \"init\" or \"target\", not \"%s\"\n", argv[1]); exit(EXIT_FAILURE); } if (strcmp(argv[2], "set") == 0) { /* negotiate a new value and accept whatever other side wants */ neg_info = KEY_TO_BE_NEGOTIATED; } else if (strcmp(argv[2], "setr") == 0) { /* negotiate a new value that MUST be used or we terminate the login */ neg_info = KEY_TO_BE_NEGOTIATED | KEY_BREAK_CONN_OR_RJT; } else if (strcmp(argv[2], "unset") == 0) { /* do nothing (i.e., keep default value and do not try to negotiate) */ neg_info = 0; } else if (strcmp(argv[2], "restore") == 0) { /* restore default values for all keys */ neg_info = RESTORE; } else if (strcmp(argv[2], "setp") == 0) { /* change value in table, but do not negotiate it */ neg_info = 0; } else if (strcmp(argv[2], "force") == 0) { /* force security phase or operational phase during login */ neg_info = FORCE; } /* Code added for handling snack - SAI */ else if (strcmp(argv[2], "snack") == 0) { /* Configure snack parameters for Error Recovery */ neg_info = SNACK; } else { printf ("parameter 2 must be \"set\" or \"setr\" or \"unset\" or " "\"restore\" or \"force\", or \"snack\", not \"%s\"\n", argv[2]); exit(EXIT_FAILURE); } /* Initialise */ host_no = DEFAULT_HOST_NO; target_no = DEFAULT_TARGET_NO; value_list = NULL; /* this loop is to get the host number from the arguments */ for (i = 3; i < argc; i++) { if (strncmp(argv[i], "host=", 5) == 0) { /* number of host adaptor */ errno = 0; host_no = strtoul(&argv[i][5], &endptr, 0); if (errno != 0 || strspn(endptr, WHITE_SPACE) != strlen(endptr)) { printf("illegal host number \"%s\"\n", &argv[i][5]); exit(EXIT_FAILURE); } } if (strncmp(argv[i], "target=", 7) == 0) { /* number of target within the host adaptor */ errno = 0; target_no = strtoul(&argv[i][7], &endptr, 0); if (errno != 0 || strspn(endptr, WHITE_SPACE) != strlen(endptr)) { printf("illegal target number \"%s\"\n", &argv[i][7]); exit(EXIT_FAILURE); } } } /* This loop is for actually setting the Key=Param values for the */ /* initiator or target */ for (i = 3; i < argc; i++) { char *buffer; if (!(buffer = strdup(argv[i]))) { printf("unable to allocate memory\n"); return -1; } if (strncmp(buffer, "host=", 5) == 0 || strncmp(buffer, "target=", 7) == 0) { /* * number of host adaptor */ } else if (neg_info == FORCE) { /* special case for forcing login phases and other features */ if (strncmp(buffer, "n=", 2) == 0) { /* force sending of nops, number must follow */ check_number(buffer, 2); } else if (strncmp(buffer, "v=", 2) == 0) { /* force version number, number must follow */ value = check_number(buffer, 2); if (value < DRAFT_MULTIPLIER) value *= DRAFT_MULTIPLIER; if (value != DRAFT20) { printf("illegal draft version number \"%s\"\n", buffer); exit(EXIT_FAILURE); } printf("ignoring draft version number \"%s\"\n", buffer); /* in case value was multiplied by 100, set up new v= */ free(buffer); if (!(buffer = malloc(16))) { printf("unable to allocate memory\n"); return -1; } sprintf(buffer, "v=%u", value); } /* force r2t retransmit timer - SAI */ else if (strncmp(buffer, "r2tp=", 5) == 0) { check_number(buffer, 5); /* force the retransmit check interval and command retransmit period - SAI */ } else if (strncmp(buffer, "p=", 2) == 0) { check_number(buffer, 2); } else if (strncmp(buffer, "sch=", 4) == 0) { check_number(buffer, 4); } else if (strcmp(buffer, "s") != 0 && strcmp(buffer, "o") != 0 && strcmp(buffer, "f") != 0 && strcmp(buffer, "r") != 0 && strcmp(buffer, "xok") != 0 && strcmp(buffer, "tk1") != 0 /* chap and srp support - CHONG */ && strcmp(buffer, "t") != 0 && strcmp(buffer, "b") != 0 && strncmp(buffer, "cl=", 3) != 0 && strncmp(buffer, "px=", 3) != 0 && strncmp(buffer, "pn=", 3) != 0 && strncmp(buffer, "lx=", 3) != 0 && strncmp(buffer, "ln=", 3) != 0 && strncmp(buffer, "sg=", 3) != 0 && strncmp(buffer, "sx=", 3) != 0 && strncmp(buffer, "V=", 2) != 0 /* iscsi_trace */ && strncmp(buffer, "isidt=", 6) != 0 && strncmp(buffer, "isidn=", 6) != 0 && strncmp(buffer, "isidq=", 6) != 0 && strncmp(buffer, "sn=", 3) != 0) { printf("illegal force parameter, \"%s\" not allowed\n", buffer); exit(EXIT_FAILURE); } /* Configure the parameter */ do_param(inittarget, neg_info, buffer, host_no, target_no); /* SNACK DATA and STATUS options - SAI */ } else if (neg_info == SNACK) { if (strncmp(buffer, "a=", 2) == 0) { if ((strcmp(buffer + 2, "y") != 0) && (strcmp(buffer + 2, "Y") != 0) && (strcmp(buffer + 2, "n") != 0) && (strcmp(buffer + 2, "N") != 0)) { printf("Invalid value for datack snack - \"%s\"\n", buffer); exit(EXIT_FAILURE); } } else if (strncmp(buffer, "d=", 2) == 0) { if ((strcmp(buffer + 2, "y") != 0) && (strcmp(buffer + 2, "Y") != 0) && (strcmp(buffer + 2, "n") != 0) && (strcmp(buffer + 2, "N") != 0)) { printf("Invalid value for data snack - \"%s\"\n", buffer); exit(EXIT_FAILURE); } } else if (strncmp(buffer, "s=", 2) == 0) { if ((strcmp(buffer + 2, "y") != 0) && (strcmp(buffer + 2, "Y") != 0) && (strcmp(buffer + 2, "n") != 0) && (strcmp(buffer + 2, "N") != 0)) { printf("Invalid value for status snack - \"%s\"\n", buffer); exit(EXIT_FAILURE); } } else if (strncmp(buffer, "h=", 2) == 0) { check_number(buffer, 2); } else { printf("illegal snack parameter, \"%s\" not allowed\n", buffer); exit(EXIT_FAILURE); } /* Configure the parameter */ do_param(inittarget, neg_info, buffer, host_no, target_no); } else { /* Configure the parameter */ do_param(inittarget, neg_info, buffer, host_no, target_no); } free(buffer); } if (neg_info == RESTORE) { /* Configure the parameter */ do_param(inittarget, neg_info, "", host_no, target_no); } exit(EXIT_SUCCESS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -