📄 iscsi_config.c
字号:
/* initiator/iscsi_config.c vi: set autoindent tabstop=4 shiftwidth=4 : This file contains the core functions to initiate session to the target. The file when compiled generates a user-level program which calls iscsi_initiator.c functions through /proc filesystem interface.*//* 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 <sys/param.h>#include <scsi/scsi.h>#include <sys/stat.h>#include "iscsi_common.h"#include "debug.h"extern int ioctl(int, int, ...);#define DEFAULT_HOST_NO 0#define DEFAULT_TARGET_NO 0#define DEFAULT_LUN_NO -1#define DEFAULT_CID_NO 0#define WHITE_SPACE " \t\v\f\n\r"#define UNH_ISCSI_DEV_DIR "/opt/unh/iscsi/dev"#define MAX_LUNS 8char server_node[MAXHOSTNAMELEN];char target_dir[MAXPATHLEN];char target_node[MAXPATHLEN];char cmd[MAXPATHLEN];intcreate_device_nodes(char *target_dir, int host_no, int target_no, int lun_no){ char disk_fmt[] = "/dev/sd%c"; char tape_fmt[] = "/dev/st%d"; char cd_fmt[] = "/dev/scd%d"; char disk_name[10], disk_part[10]; char tape_name[10], tape_subname[10]; char cd_name[10]; char tape_types[] = { 'a', 'l', 'm', 0 }; int fd, ret = 0, id_buf[2], found = 0; int host, chan, lun, id, i = 0, p = 0; /* First do the disks */ for (i = 'a'; i <= 'z'; i++) { sprintf(disk_name, disk_fmt, i); fd = open(disk_name, O_RDONLY); if (fd <= 0) continue; ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id_buf); close(fd); if (ret) { continue; } TRACE(TRACE_DEBUG, "create_device_nodes disk_name: %s, id_buf: 0x%08x\n", disk_name, id_buf[0]); host = (id_buf[0] >> 24) & 0xff; chan = (id_buf[0] >> 16) & 0xff; lun = (id_buf[0] >> 8) & 0xff; id = (id_buf[0] & 0xff); if (host != host_no || chan != 0 || id != target_no || lun != lun_no) { continue; } found++; TRACE(TRACE_DEBUG, "create_device_nodes found %d, target_dir: %s, " "lun_no %d\n", found, target_dir, lun_no); sprintf(target_node, "%s/l%d", target_dir, lun_no); ret = link(disk_name, target_node); if (ret) { printf("Unable to link %s to %s \n", target_node, disk_name); goto out; } TRACE(TRACE_DEBUG, "Able to link %s to %s \n", target_node, disk_name); for (p = 1; p <= 15; p++) { sprintf(target_node, "%s/l%dp%d", target_dir, lun_no, p); sprintf(disk_part, "%s%d", disk_name, p); ret = link(disk_part, target_node); if (ret) { printf("Unable to link %s to %s \n", target_node, disk_part); goto out; } } } if (found) goto out; /* Check for SCSI tapes */ for (i = 0; i <= 9; i++) { sprintf(tape_name, tape_fmt, i); fd = open(tape_name, O_RDONLY); if (fd <= 0) continue; ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id_buf); close(fd); if (ret) { continue; } TRACE(TRACE_DEBUG, "create_device_nodes tape_name: %s, id_buf: 0x%08x\n", tape_name, id_buf[0]); host = (id_buf[0] >> 24) & 0xff; chan = (id_buf[0] >> 16) & 0xff; lun = (id_buf[0] >> 8) & 0xff; id = (id_buf[0] & 0xff); if (host != host_no || chan != 0 || id != target_no || lun != lun_no) { continue; } found++; TRACE(TRACE_DEBUG, "create_device_nodes found %d, target_dir: %s, " "lun_no %d\n", found, target_dir, lun_no); sprintf(target_node, "%s/l%d", target_dir, lun_no); ret = link(tape_name, target_node); if (ret) { printf("Unable to link %s to %s \n", target_node, tape_name); goto out; } TRACE(TRACE_DEBUG, "Able to link %s to %s \n", target_node, tape_name); for (p = 0; tape_types[p]; p++) { TRACE(TRACE_DEBUG, "p: %d, tape_types[p]: %c\n", p, tape_types[p]); sprintf(tape_subname, "%s%c", tape_name, tape_types[p]); sprintf(target_node, "%s/l%d%c", target_dir, lun_no, tape_types[p]); ret = link(tape_subname, target_node); if (ret) { printf("Unable to link %s to %s \n", target_node, tape_subname); goto out; } TRACE(TRACE_DEBUG, "Able to link %s to %s \n", target_node, tape_subname); } } if (found) goto out; /* Check for SCSI CD-ROMs */ for (i = 0; i <= 9; i++) { sprintf(cd_name, cd_fmt, i); fd = open(cd_name, O_RDONLY); if (fd <= 0) continue; ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id_buf); close(fd); if (ret) { continue; } TRACE(TRACE_DEBUG, "create_device_nodes cd_name: %s, id_buf: 0x%08x\n", cd_name, id_buf[0]); host = (id_buf[0] >> 24) & 0xff; chan = (id_buf[0] >> 16) & 0xff; lun = (id_buf[0] >> 8) & 0xff; id = (id_buf[0] & 0xff); if (host != host_no || chan != 0 || id != target_no || lun != lun_no) { continue; } found++; TRACE(TRACE_DEBUG, "create_device_nodes found %d, target_dir: %s, " "lun_no %d\n", found, target_dir, lun_no); sprintf(target_node, "%s/l%d", target_dir, lun_no); ret = link(cd_name, target_node); if (ret) { printf("Unable to link %s to %s \n", target_node, cd_name); goto out; } } out: TRACE(TRACE_DEBUG, "create_device_nodes exiting\n"); return (ret);}/* creates the directory given by path, including all * directories in path * path must be an absolute path name * returns 0 on success, -1 on error */intmake_full_path_dir(char *path){ char *ptr, *partial_path = NULL; int len, mode; int retval = -1; /* assume this function fails */ if (path == NULL || (len = strlen(path)) <= 0) { /* path is bogus */ goto early_out; } if (*path != '/') { /* path is relative, not absolute */ goto early_out; } /* else path is absolute */ if ((ptr = partial_path = malloc(len + 1)) == NULL) goto early_out; /* we need a copy of path because we are going to mess it up */ strcpy(partial_path, path); mode = X_OK; /* only need x access to intermediate directories */ if (len == 1) { mode |= R_OK | W_OK; /* need rwx access to final directory */ } if (access("/", mode)) { /* we do not have proper access to root, leave with error */ goto out; } if (len == 1) { /* the entire path is just "/" and we have rwx access to it */ goto ok; } do { /* repair any previous damage to partial-path */ *ptr++ = '/'; if ((ptr = strchr(ptr, '/')) == NULL) { /* have last component in string, ptr is now NULL to exit loop */ /* need rwx access to final directory */ mode |= R_OK | W_OK; } else { /* still have subdirectories to follow, isolate this subdir */ *ptr = '\0'; } if (access(partial_path, mode)) { /* don't have desired access to this subdirectory */ if (mkdir(partial_path, 0744)) { /* can't create this subdirectory, return an error */ printf("Unable to create directory %s: %s\n", partial_path, strerror(errno)); goto out; } } } while (ptr); ok: retval = 0; out: free(partial_path); early_out: return retval;}/* write a magic line to the proc file system to cause the scsi * mid-level to redo the inquiry for our device */voiddo_inquiry(int add, int host_no, int target_no, int lun_no){ int fd, n, len, ret = 0; static char *file_name = "/proc/scsi/scsi"; char text_line[128]; TRACE(TRACE_DEBUG, "Entering do_inquiry\n"); if ((fd = open(file_name, O_RDWR)) < 0) { perror(file_name); return; } TRACE(TRACE_DEBUG, "do_inquiry file_name: %s\n", file_name); len = sprintf(text_line, "scsi %s-single-device %d 0 %d %d", add ? "add" : "remove", host_no, target_no, lun_no); len++; /* for writing the last null character */ TRACE(TRACE_DEBUG, "write to scsi: %s\n", text_line); if ((n = write(fd, text_line, len)) < 0) {#ifdef CONF_ISCSI_DEBUG perror(file_name);#endif /* CONF_ISCSI_DEBUG */ } else if (n != len && n != 0) printf("%s: wrote %d bytes, expected %d\n", file_name, n, len); /* FEATURE - ADD DEVICE ENTRY */ else { if (add) { if (access(UNH_ISCSI_DEV_DIR, R_OK | W_OK | X_OK)) { ret = make_full_path_dir(UNH_ISCSI_DEV_DIR); //ret = mkdir(UNH_ISCSI_DEV_DIR, 0744); if (ret) { goto out; } } sprintf(target_dir, "%s/%d", UNH_ISCSI_DEV_DIR, target_no); if (access(target_dir, R_OK | W_OK | X_OK)) { ret = make_full_path_dir(target_dir); //ret = mkdir(target_dir, 0744); if (ret) { goto out; } } /* Remove old device files */ sprintf(cmd, "/bin/rm -rf %s/%d/l%d*", UNH_ISCSI_DEV_DIR, target_no, lun_no); ret = system(cmd); if (ret) { printf("Unable to remove old device files.\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -