📄 iscsi-linux.c
字号:
debugmsg(2, "authentication outgoing username %s password %s " "for target %s", ioctld->username, ioctld->password, config->target->TargetName); if (config->target->auth_options.username_in[0] && config->target->auth_options.password_length_in) { /* also copy the target authentication information */ ioctld->password_length_in = config->target->auth_options.password_length_in; strncpy(ioctld->username_in, config->target->auth_options.username_in, sizeof (ioctld->username_in)); ioctld->username_in[sizeof (ioctld->username_in) - 1] = '\0'; memcpy(ioctld->password_in, config->target->auth_options.password_in, MIN(config->target->auth_options. password_length_in, sizeof (ioctld->password_in))); ioctld->password_in[sizeof (ioctld->password_in) - 1] = '\0'; debugmsg(2, "authentication incoming username %s " "password %s for target %s", ioctld->username_in, ioctld->password_in, config->target->TargetName); } } else { ioctld->password_length = 0; ioctld->password_length_in = 0; debugmsg(2, "authentication not configured for target %s", config->target->TargetName); } memcpy(ioctld->initiator_name, daemon_config.initiator_name, strlen(daemon_config.initiator_name)); memcpy(ioctld->initiator_alias, daemon_config.initiator_alias, strlen(daemon_config.initiator_alias)); memcpy(ioctld->target_name, config->target->TargetName, strlen(config->target->TargetName)); memcpy(ioctld->isid, config->isid, sizeof (ioctld->isid)); /* * Tell the kernel to establish a session. */ do { rc = ioctl(control_fd, ISCSI_ESTABLISH_SESSION, (char *) ioctld); if (rc < 0) { if (errno == EBUSY) { debugmsg(2, "iSCSI session ioctl got EBUSY, " "retrying"); usleep(20 * 1000); } else if (errno == EINVAL) { ret = ISCSI_SESSION_FAILED_NO_RETRY; /* most likely a version mismatch * with the kernel module */ break; } else { errormsg ("iSCSI session ioctl failed for %s, %s", config->target->TargetName, strerror(errno)); sleep(1); } } else debugmsg(2, "session ioctl for %s returned from " "kernel with rc %d", config->target->TargetName, rc); if (stop_requested) break; } while (rc < 0); /* don't want to leave passwords in memory */ memset(&ioctld, 0, sizeof (ioctld)); free(ioctld); return ret;}/* handle any max target number limits in this function */intiscsi_session_process(struct iscsi_session_process *process, struct iscsi_session_config *config){ struct sigaction action; int ret; memset(&action, 0, sizeof (struct sigaction)); action.sa_sigaction = NULL; action.sa_flags = 0; action.sa_handler = SIG_DFL; sigaction(SIGTERM, &action, NULL); sigaction(SIGINT, &action, NULL); action.sa_handler = SIG_IGN; sigaction(SIGCHLD, &action, NULL); ret = ioctl_establish_session(config, 1, process->config_number, 0); /* don't want to leave passwords in memory */ memset(&config->target->auth_options, 0, sizeof (config->target->auth_options)); exit(ret);}voidioctl_terminate_session(struct iscsi_session_config *config){ debugmsg(1, "terminate session not implemented\n", __FILE__, __LINE__);}voidiscsi_kill_session(struct iscsi_session_process *process){ pid_t pid = process->pid; if (pid) { debugmsg(2, "sending SIGTERM to session process %p pid %d", process, pid); /* if the proces is still running, kill it */ kill(SIGTERM, pid); } /* if the daemon is dying, leave the session running. * the sysfs shutdown will take care of it. */ if (stop_requested) return;}voidiscsi_lun_inventory_changed(struct iscsi_session_process *process){ struct iscsi_session_config *config = process->config; pid_t pid = 0; if (config == NULL) { logmsg(AS_ERROR, "can't reprobe LUNs for process %p, no config", process); return; } fork_again: pid = fork(); if (pid == 0) { /* FIXME: ignore SIGHUP? */ exit(0); } else if (pid < 0) { errormsg("cannot fork child"); usleep(100 * 1000); goto fork_again; } else { logmsg(AS_NOTICE, "reprobing LUNs for bus %d target %d", config->iscsi_bus, config->target_id); }}voidiscsi_config_changed(struct iscsi_session_process *process, struct iscsi_session_config *new_config, struct iscsi_session_config *current_config){ int probe_luns = 0; pid_t pid; if (process == NULL) { logmsg(AS_ERROR, "config changed for NULL process, new_config %p, " "current_config %p\n", new_config, current_config); return; } if (new_config == NULL) { /* This can happen only if target is deleted */ offline_warn("Target Offline", current_config); ioctl_terminate_session(current_config); return; } logmsg(AS_NOTICE, "updating bus %d target %d to configuration #%lu", new_config->iscsi_bus, new_config->target_id, process->config_number); if ((new_config->target) && (new_config->target->auth_options.password_length)) { debugmsg(2, "new config has username %s password %s length %d", new_config->target->auth_options.username, new_config->target->auth_options.password, new_config->target->auth_options.password_length); } /* if a LUN probe is needed, we might as well do it now */ if (process->lun_inventory_changed) { /* no point doing a separate ioctl */ process->lun_inventory_changed = 0; probe_luns = 1; debugmsg(2, "bus %d target %d LUN inventory may have changed, " "reprobing LUNs while updating config", new_config->iscsi_bus, new_config->target_id); } if ((new_config->iscsi_bus != current_config->iscsi_bus) || (new_config->target_id != current_config->target_id)) { logmsg(AS_NOTICE, "bus %d target %d rebound to bus %d target %d", current_config->iscsi_bus, current_config->target_id, new_config->iscsi_bus, new_config->target_id); } fork_again: pid = fork(); if (pid == 0) { /* FIXME: ignore SIGHUP? */ ioctl_establish_session(new_config, probe_luns, process->config_number, 1); if (new_config && new_config->target) memset(&new_config->target->auth_options, 0, sizeof (new_config->target->auth_options)); if (current_config && current_config->target) memset(¤t_config->target->auth_options, 0, sizeof (current_config->target->auth_options)); debugmsg(2, "updated configuration for bus %d target %d", new_config->iscsi_bus, new_config->target_id); exit(0); } else if (pid < 0) { errormsg("cannot fork child to update config"); usleep(100 * 1000); goto fork_again; } else { /* give it a chance to get going */ usleep(10 * 1000); }}voidiscsi_session_count_changed(int num_sessions, int discovery_in_progress, int discovery_not_in_progress){ /* we don't care, since sessions can take care of themselves */}intiscsi_lock_file(int fd){ struct flock lock; int result = 0; memset(&lock, 0, sizeof (lock)); lock.l_type = F_WRLCK; /* entire file */ lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = 0; /* try to acquire the lock, returning if we can't */ result = fcntl(fd, F_SETLK, &lock); return result;}intiscsi_unlock_file(int fd){ struct flock lock; int result = 0; memset(&lock, 0, sizeof (lock)); lock.l_type = F_UNLCK; /* entire file */ lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = 0; /* try to release the lock */ result = fcntl(fd, F_SETLKW, &lock); return result;}/* lock a pid file, to ensure that only one instance of the * daemon can run at a time */intlock_pid_file(void){ int fd = open(daemon_config.pid_file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); char buffer[64]; int val; if (fd < 0) { errormsg("open of lock_file %s failed", daemon_config.pid_file); exit(0); } debugmsg(7, "pid file fd %d", fd); if (iscsi_lock_file(fd) < 0) { if (errno == EACCES || ((errno == EAGAIN) && !iscsi_process_should_exit())) { /* daemon already running */ fprintf(stderr, "pid file %s already locked", daemon_config.pid_file); close(fd); exit(0); } else { /* lock error */ errormsg("iscsi_lock_file %s failed", daemon_config.pid_file); close(fd); exit(0); } } else { debugmsg(7, "locked pid file %s", daemon_config.pid_file); } /* truncate the file, and write our pid */ ftruncate(fd, 0); sprintf(buffer, "%d\n", getpid()); if (write(fd, buffer, strlen(buffer)) != strlen(buffer)) { errormsg("error writing pid file %s", daemon_config.pid_file); close(fd); exit(0); } /* sync the file to disk */ fsync(fd); /* mark the pid file close-on-exec */ if ((val = fcntl(fd, F_GETFD, 0)) < 0) { errormsg("failed to get pid file %s flags", daemon_config.pid_file); close(fd); exit(0); } val |= FD_CLOEXEC; if (fcntl(fd, F_SETFD, val) < 0) { errormsg("error setting flags on pid file %s descriptor %d", daemon_config.pid_file, fd); close(fd); exit(0); } return 1;}voidlogmsg(int priority, const char *fmt, ...){ va_list args; char buf[1024]; int rc; va_start(args, fmt); rc = vsnprintf(buf, sizeof (buf), fmt, args); if ((rc > 0) && (rc < sizeof (buf))) { /* don't end with a double newline */ if (buf[rc - 1] == '\n') buf[rc - 1] = '\0'; } if (daemon_config.debug_level) { struct timeval time; gettimeofday(&time, NULL); fprintf(stderr, "%ld.%ld >> %s[%d]: %s\n", time.tv_sec, time.tv_usec, progname, getpid(), buf); fflush(stderr); } syslog(priority, "%s\n", buf); va_end(args);}voiderrormsg(const char *fmt, ...){ va_list args; char buf[1024]; int en = errno; int rc; va_start(args, fmt); rc = vsnprintf(buf, sizeof (buf), fmt, args); if ((rc > 0) && (rc < sizeof (buf))) { /* don't end with a double newline */ if (buf[rc - 1] == '\n') buf[rc - 1] = '\0'; } if (daemon_config.debug_level) { struct timeval time; gettimeofday(&time, NULL); fprintf(stderr, "%ld.%ld >> %s[%d]: %s: %s\n", time.tv_sec, time.tv_usec, progname, getpid(), buf, strerror(en)); fflush(stderr); } syslog(LOG_ERR, "%s: %s\n", buf, strerror(en)); va_end(args);}voiddebugmsg(int level, const char *fmt, ...){ va_list args; char buf[1024]; struct timeval time; int rc; if (daemon_config.debug_level < level) return; va_start(args, fmt); rc = vsnprintf(buf, sizeof (buf), fmt, args); if ((rc > 0) && (rc < sizeof (buf))) { /* don't end with a double newline */ if (buf[rc - 1] == '\n') buf[rc - 1] = '\0'; } gettimeofday(&time, NULL); fprintf(stderr, "%ld.%ld >> %s[%d]: %s\n", time.tv_sec, time.tv_usec, progname, getpid(), buf); fflush(stderr); /* syslog can block, and prevent the daemon from getting a new * socket passed to the kernel in time, so we no longer syslog * debug messages. For other messages, we need to be careful to * avoid having syslog block in the critical path. */ va_end(args);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -