mirror of
https://github.com/cristicalin/synology-csi.git
synced 2026-03-26 19:03:12 +00:00
163 lines
3.3 KiB
Go
163 lines
3.3 KiB
Go
// Copyright 2021 Synology Inc.
|
|
|
|
package driver
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
utilexec "k8s.io/utils/exec"
|
|
)
|
|
|
|
type initiatorDriver struct {
|
|
chapUser string
|
|
chapPassword string
|
|
}
|
|
|
|
const (
|
|
ISCSIPort = 3260
|
|
)
|
|
|
|
func iscsiadm(cmdArgs ...string) utilexec.Cmd {
|
|
executor := utilexec.New()
|
|
|
|
return executor.Command("iscsiadm", cmdArgs...)
|
|
}
|
|
|
|
func iscsiadm_session() string {
|
|
cmd := iscsiadm("-m", "session")
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
exitErr, ok := err.(utilexec.ExitError)
|
|
if ok && exitErr.ExitStatus() == 21 { // iscsiadm: No active sessions
|
|
log.Info("No active iscsi session found.")
|
|
} else {
|
|
log.Errorf("Failed to run iscsiadm session: %v", err)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
return string(out)
|
|
}
|
|
|
|
func iscsiadm_discovery(ip string) error {
|
|
cmd := iscsiadm(
|
|
"-m", "discoverydb",
|
|
"--type", "sendtargets",
|
|
"--portal", ip,
|
|
"--discover")
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
return fmt.Errorf("%s (%v)", string(out), err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func iscsiadm_login(iqn, portal string) error {
|
|
cmd := iscsiadm(
|
|
"-m", "node",
|
|
"--targetname", iqn,
|
|
"--portal", portal,
|
|
"--login")
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
return fmt.Errorf("%s (%v)", string(out), err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func iscsiadm_logout(iqn string) error {
|
|
cmd := iscsiadm(
|
|
"-m", "node",
|
|
"--targetname", iqn,
|
|
"--logout")
|
|
if _, err := cmd.CombinedOutput(); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func iscsiadm_rescan(iqn string) error {
|
|
cmd := iscsiadm(
|
|
"-m", "node",
|
|
"--targetname", iqn,
|
|
"-R")
|
|
if _, err := cmd.CombinedOutput(); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func hasSession(targetIqn string) bool{
|
|
sessions := iscsiadm_session();
|
|
|
|
for _, line := range strings.Split(sessions, "\n") {
|
|
if strings.Contains(line, targetIqn) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func (d *initiatorDriver) login(targetIqn string, ip string) error{
|
|
portal := fmt.Sprintf("%s:%d", ip, ISCSIPort)
|
|
|
|
if (hasSession(targetIqn)) {
|
|
log.Infof("Session[%s] already exists.", targetIqn)
|
|
return nil
|
|
}
|
|
|
|
if err := iscsiadm_discovery(ip); err != nil {
|
|
log.Errorf("Failed in discovery of the target: %v", err)
|
|
return err
|
|
}
|
|
|
|
if err := iscsiadm_login(targetIqn, portal); err != nil {
|
|
log.Errorf("Failed in login of the target: %v", err)
|
|
return err
|
|
}
|
|
|
|
log.Infof("Login target portal [%s], iqn [%s].", portal, targetIqn)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *initiatorDriver) logout(targetIqn string, ip string) error{
|
|
if (!hasSession(targetIqn)) {
|
|
log.Infof("Session[%s] doesn't exist.", targetIqn)
|
|
return nil
|
|
}
|
|
|
|
portal := fmt.Sprintf("%s:%d", ip, ISCSIPort)
|
|
if err := iscsiadm_logout(targetIqn); err != nil {
|
|
log.Errorf("Failed in logout of the target.\nTarget [%s], Portal [%s], Err[%v]",
|
|
targetIqn, portal, err)
|
|
return err
|
|
}
|
|
|
|
log.Infof("Logout target portal [%s], iqn [%s].", portal, targetIqn)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *initiatorDriver) rescan(targetIqn string) error{
|
|
if (!hasSession(targetIqn)) {
|
|
msg := fmt.Sprintf("Session[%s] doesn't exist.", targetIqn)
|
|
log.Error(msg)
|
|
return errors.New(msg)
|
|
}
|
|
|
|
if err := iscsiadm_rescan(targetIqn); err != nil {
|
|
log.Errorf("Failed in rescan of the target.\nTarget [%s], Err[%v]",
|
|
targetIqn, err)
|
|
return err
|
|
}
|
|
|
|
log.Infof("Rescan target iqn [%s].", targetIqn)
|
|
|
|
return nil
|
|
}
|