lio-utils-3.1+git2.fd0b34fd/0000755000175000017500000000000011753136721013636 5ustar rrsrrslio-utils-3.1+git2.fd0b34fd/Makefile0000644000175000017500000000315711753136721015304 0ustar rrsrrsinclude MCONFIG_ALL CWD=$(shell pwd) default:: all all: cd tcm-py ; python setup.py build cd lio-py ; python setup.py build -if test -d tools; then make -C tools; fi; ifeq ($(SNMP_FEATURE), 1) -if test -d mib-modules; then make -C mib-modules; fi; endif user_rpms: -if test -d tools; then make -C tools; fi; ./autoconfig make_target_user_rpm ifeq ($(SNMP_FEATURE), 1) -if test -d mib-modules; then make -C mib-modules; fi; ./autoconfig make_mibs_rpm endif conf_install: if [ ! -d $(DESTDIR)/etc/target ]; then \ mkdir -p $(DESTDIR)/etc/target; \ fi if [ ! -f $(DESTDIR)/etc/target/tcm_start.sh ]; then \ install -m 0755 conf/tcm_start.default $(DESTDIR)/etc/target/tcm_start.sh; \ fi if [ ! -f $(DESTDIR)/etc/target/lio_start.sh ]; then \ install -m 0755 conf/lio_start.default $(DESTDIR)/etc/target/lio_start.sh; \ fi \ initd_install: if [ ! -d $(DESTDIR)/etc/init.d ]; then \ mkdir -p $(DESTDIR)/etc/init.d; \ fi install -m 0755 scripts/rc.target $(DESTDIR)/etc/init.d/target install: all initd_install conf_install cd tcm-py ; python setup.py install ; sh install.sh cd lio-py ; python setup.py install ; sh install.sh -if test -d tools; then make -C tools install; fi ifeq ($(SNMP_FEATURE), 1) -if test -d mib-modules; then make -C mib-modules install; fi endif deinstall: cd tcm-py ; sh uninstall.sh cd lio-py ; sh uninstall.sh clean: cd tcm-py ; python setup.py clean ; rm -rf build cd lio-py ; python setup.py clean ; rm -rf build rm -rf build -if test -d tools; then make -C tools clean; fi; ifeq ($(SNMP_FEATURE), 1) -if test -d mib-modules; then make -C mib-modules clean; fi; endif lio-utils-3.1+git2.fd0b34fd/.gitignore0000644000175000017500000000000611753136721015622 0ustar rrsrrs*.pyc lio-utils-3.1+git2.fd0b34fd/tcm-py/0000755000175000017500000000000011753136721015047 5ustar rrsrrslio-utils-3.1+git2.fd0b34fd/tcm-py/tcm_iblock.py0000755000175000017500000000425711753136721017542 0ustar rrsrrs#!/usr/bin/python import os, tempfile import subprocess as sub import string, re from optparse import OptionParser tcm_root = "/sys/kernel/config/target/core" def createvirtdev(path, params): # print "Calling iblock createvirtdev: path " + path cfs_path = tcm_root + "/" + path + "/" # print "Calling iblock createvirtdev: params " + str(params) path = params[0] if not re.search('/dev/', path): print "IBLOCK: Please reference a valid /dev/ block_device" return -1 udev_path = path.rstrip() # Resolve symbolic links to get major/minor udev_op = "/bin/ls -laL " + udev_path p = sub.Popen(udev_op, shell=True, stdout=sub.PIPE).stdout line = p.readline() out = line.split(' '); major = out[4] minor = out[5] p.close() if major == "11,": print "Unable to export Linux/SCSI TYPE_CDROM from IBLOCK, please use pSCSI export" return -1 if major == "22,": print "Unable to export IDE CDROM from IBLOCK" return -1 set_udev_path_op = "echo -n " + udev_path + " > " + cfs_path + "udev_path" ret = os.system(set_udev_path_op) if ret: print "IBLOCK: Unable to set udev_path in " + cfs_path + " for: " + udev_path return -1 control_opt = "echo -n udev_path=" + udev_path + " > " + cfs_path + "control" ret = os.system(control_opt) if ret: print "IBLOCK: createvirtdev failed for control_opt with " + control_opt return -1 enable_opt = "echo 1 > " + cfs_path + "enable" ret = os.system(enable_opt) if ret: print "IBLOCK: createvirtdev failed for enable_opt with " + enable_opt return -1 def iblock_freevirtdev(): pass def iblock_get_params(path): # Reference by udev_path if available udev_path_file = path + "/udev_path" p = os.open(udev_path_file, 0) value = os.read(p, 1024) if re.search('/dev/', value): os.close(p) return value.rstrip() os.close(p) info_file = path + "/info" p = open(info_file, 'rU') try: value = p.read(1024) except IOError, msg: p.close() return p.close() of = value.index('Major: ') off += 7 major_tmp = value[off:] major = major_tmp.split(' ') off = value.index('Minor: ') off += 7 minor_tmp = value[off:] minor = minor_tmp.split(' ') params = "major=" + major[0] + ",minor=" + minor[0] os.close(p) return params lio-utils-3.1+git2.fd0b34fd/tcm-py/tcm_dump.py0000755000175000017500000002530311753136721017237 0ustar rrsrrs#!/usr/bin/python import os, sys, shutil import subprocess as sub from subprocess import Popen, PIPE import string import re import datetime, time from optparse import OptionParser import tcm_node import tcm_pscsi import tcm_iblock import tcm_ramdisk import tcm_fileio import lio_dump import tcm_fabric tcm_root = "/sys/kernel/config/target/core" def tcm_dump_hba_devices(): pass def tcm_dump_configfs(option, opt_str, value, parser): if not os.path.isdir(tcm_root): print "Unable to access tcm_root: " + tcm_root sys.exit(1) print "modprobe target_core_mod" # Loop through ALUA Logical Unit Groups # Note that the 'default_lu_gp' is automatically created when # target_core_mod is loaded. print "#### ALUA Logical Unit Groups" for lu_gp in os.listdir(tcm_root + "/alua/lu_gps"): if lu_gp == "default_lu_gp": continue print "mkdir -p " + tcm_root + "/alua/lu_gps/" + lu_gp lu_gp_id_file = tcm_root + "/alua/lu_gps/" + lu_gp + "/lu_gp_id" p = os.open(lu_gp_id_file, 0) value = os.read(p, 8) os.close(p) if not value: continue print "echo " + value.rstrip() + " > " + lu_gp_id_file # Loop through HBA list for f in os.listdir(tcm_root): if f == "alua": continue; # print "mkdir -p " + tcm_root + "/" + f dev_root = tcm_root + "/" + f + "/" for g in os.listdir(dev_root): if g == "hba_info" or g == "hba_mode": continue; # Dump device aka storage object print "#### Parameters for TCM subsystem plugin storage object reference" # Generate subsystem dependent configfs ops for association to # an target_core_mod storage object. result = re.search('pscsi_', f) if result: dev = dev_root + g params = tcm_pscsi.pscsi_get_params(dev) if not params: continue print "tcm_node --establishdev " + f + "/" + g + " " + str(params) result = re.search('iblock_', f) if result: dev = dev_root + g params = tcm_iblock.iblock_get_params(dev) if not params: continue print "tcm_node --establishdev " + f + "/" + g + " " + str(params) result = re.search('rd_dr_', f) if result: dev = dev_root + g params = tcm_ramdisk.rd_get_params(dev) if not params: continue print "tcm_node --establishdev " + f + "/" + g + " " + str(params) result = re.search('rd_mcp_', f) if result: dev = dev_root + g params = tcm_ramdisk.rd_get_params(dev) if not params: continue print "tcm_node --establishdev " + f + "/" + g + " " + str(params) result = re.search('fileio_', f) if result: dev = dev_root + g params = tcm_fileio.fd_get_params(dev) if not params: continue print "tcm_node --establishdev " + f + "/" + g + " " + str(params) # Dump T10 VP Unit Serial for all non Target_Core_Mod/pSCSI objects result = re.search('pscsi_', f) if not result: unit_serial_file = dev_root + g + "/wwn/vpd_unit_serial" p = os.open(unit_serial_file, 0) value = os.read(p, 512) off = value.index('Number: ') off += 8 # Skip over "Number: " unit_serial = value[off:] # Note that this will handle read, parse and set any PR APTPL metadata print "tcm_node --setunitserialwithmd " + f + "/" + g + " " + unit_serial.rstrip() os.close(p) # Dump device object alias alias_file = dev_root + g + "/alias" p = open(alias_file, 'r') value = p.read(512) value = value.rstrip() p.close() if value: print "echo -n \"" + value + "\" > " + dev_root + g + "/alias" # Dump ALUA Logical Unit Group lu_gp_file = dev_root + g + "/alua_lu_gp" p = os.open(lu_gp_file, 0) value = os.read(p, 512) os.close(p) if value: lu_gp_tmp = value.split('\n') lu_gp_out = lu_gp_tmp[0] off = lu_gp_out.index('Alias: ') off += 7 # Skip over "Alias: " lu_gp_name = lu_gp_out[off:] # Only need to dump if storage object is NOT part of # the 'default_lu_gp' if not re.search(lu_gp_name, 'default_lu_gp'): print "echo " + lu_gp_name + " > " + lu_gp_file # Loop through ALUA Target Port Groups if os.path.isdir(dev_root + g + "/alua/") == True: print "#### ALUA Target Port Groups" for tg_pt_gp in os.listdir(dev_root + g + "/alua/"): tg_pt_gp_id_file = dev_root + g + "/alua/" + tg_pt_gp + "/tg_pt_gp_id" p = os.open(tg_pt_gp_id_file, 0) value = os.read(p, 8) os.close(p) if not value: continue print "tcm_node --addaluatpgwithmd " + f + "/" + g + " " + tg_pt_gp + " " + value.rstrip() # Dump the ALUA types tg_pt_gp_type_file = dev_root + g + "/alua/" + tg_pt_gp + "/alua_access_type" p = os.open(tg_pt_gp_type_file, 0) value = os.read(p, 32) os.close(p) if value: value = value.rstrip() alua_type = 0 if re.search('Implict and Explict', value): alua_type = 3 elif re.search('Explict', value): alua_type = 2 elif re.search('Implict', value): alua_type = 1 print "echo " + str(alua_type) + " > " + tg_pt_gp_type_file # Dump the preferred bit tg_pt_gp_pref_file = dev_root + g + "/alua/" + tg_pt_gp + "/preferred" p = os.open(tg_pt_gp_pref_file, 0) value = os.read(p, 8) os.close(p) if value: print "echo " + value.rstrip() + " > " + tg_pt_gp_pref_file # Dump the Active/NonOptimized Delay tg_pt_gp_nonop_delay_file = dev_root + g + "/alua/" + tg_pt_gp + "/nonop_delay_msecs" p = os.open(tg_pt_gp_nonop_delay_file, 0) value = os.read(p, 8) os.close(p) if value: print "echo " + value.rstrip() + " > " + tg_pt_gp_nonop_delay_file # Dump the Transition Delay tg_pt_gp_trans_delay_file = dev_root + g + "/alua/" + tg_pt_gp + "/trans_delay_msecs" p = os.open(tg_pt_gp_trans_delay_file, 0) value = os.read(p, 8) os.close(p) if value: print "echo " + value.rstrip() + " > " + tg_pt_gp_trans_delay_file # Dump device attributes print "#### Attributes for " + dev_root + g dev_attrib_root = dev_root + g + "/attrib/" for h in os.listdir(dev_attrib_root): # The hw_* prefixed attributes are RO if h == "hw_queue_depth": continue if h == "hw_max_sectors": continue if h == "hw_block_size": continue # Do not change block-size for target_core_mod/pSCSI if h == "block_size": result = re.search('pscsi_', f) if result: continue attrib_file = dev_attrib_root + h p = os.open(attrib_file, 0) value = os.read(p, 8) print "echo " + value.rstrip() + " > " + attrib_file os.close(p) # Dump snapshot attributes snap_attrib_root = dev_root + g + "/snap/" if (os.path.isdir(snap_attrib_root) == False): continue snap_enabled = 0 enabled_attr_file = snap_attrib_root + "enabled" p = open(enabled_attr_file, 'rU') if not p: continue value = p.read() enabled = value.rstrip() p.close() if enabled != "1": continue snap_enabled = 1 print "#### Snapshot Attributes for " + dev_root + g for s in os.listdir(snap_attrib_root): if s == "pid": continue if s == "usage": continue if s == "enabled": continue attrib_file = snap_attrib_root + s p = open(attrib_file, 'rU') value = p.read() p.close() attr_val = value.rstrip() print "echo " + attr_val + " > " + attrib_file if snap_enabled == 1: print "tcm_node --lvsnapstart " + f + "/" + g def tcm_backup_to_file(option, opt_str, value, parser): datetime = str(value) if not os.path.isdir(tcm_root): print "Unable to access tcm_root: " + tcm_root sys.exit(1) backup_dir = "/etc/target/backup" if not os.path.isdir(backup_dir): op = "mkdir " + backup_dir ret = os.system(op) if ret: print "Unable to open backup_dir" sys.exit(1) op = "tcm_dump --stdout" p = sub.Popen(op, shell=True, stdout=sub.PIPE).stdout if not p: print "Unable to dump Target_Core_Mod/ConfigFS running state" sys.exit(0) print "Making backup of Target_Core_Mod/ConfigFS with timestamp: " + datetime backup_file = backup_dir + "/tcm_backup-" + datetime + ".sh" if os.path.isfile(backup_file): print "Target_Core_Mod backup_file: " + backup_file + "already exists, exiting" p.close() sys.exit(1) back = open(backup_file, 'w') line = p.readline() while line: print >>back, line.rstrip() line = p.readline() p.close() back.close() return backup_file def tcm_full_backup(option, opt_str, value, parser): overwrite = str(value) now = datetime.datetime.now() tmp = str(now) tmp2 = tmp.split(' ') timestamp = tmp2[0] + "_" + tmp2[1] tcm_file = "/etc/target/tcm_start.sh" lio_file = "/etc/target/lio_start.sh" lio_active = 0 ret = tcm_fabric.fabric_backup_to_file_all(timestamp) if ret: print "Unable to backup tcm_fabric.modules" if os.path.isdir("/sys/kernel/config/target/iscsi"): lio_file_new = lio_dump.lio_backup_to_file(None, None, timestamp, None) if not lio_file_new: sys.exit(1) lio_active = 1 print "Generated LIO-Target config: " + lio_file_new tcm_file_new = tcm_backup_to_file(None, None, timestamp, None) if not tcm_file_new: sys.exit(1) print "Generated Target_Core_Mod config: " + tcm_file_new if overwrite != "1": print "Not updating default config" return if lio_active: ret = shutil.copyfile(lio_file_new, lio_file) if ret: print "Unable to copy " + lio_file_new sys.exit(1) print "Successfully updated default config " + lio_file ret = shutil.copyfile(tcm_file_new, tcm_file) if ret: print "Unable to copy " + tcm_file_new sys.exit(1) print "Successfully updated default config " + tcm_file def tcm_overwrite_default(option, opt_str, value, parser): input = raw_input("Are you sure you want to overwrite the default configuration? Type 'yes': ") if input != "yes": sys.exit(0) val = "1" tcm_full_backup(None, None, val, None) def main(): parser = OptionParser() parser.add_option("--b","--backup", action="callback", callback=tcm_full_backup, nargs=1, type="string", dest="OVERWRITE", help="Do backup of TCM and storage fabric modules, and optionally overwrite default config data") parser.add_option("--o","--overwrite", action="callback", callback=tcm_overwrite_default, nargs=0, help="Overwrite default config data of TCM and storage fabric modules") parser.add_option("--s","--stdout", action="callback", callback=tcm_dump_configfs, nargs=0, help="Dump running Target_Core_Mod/ConfigFS syntax to STDOUT") parser.add_option("--t", "--tofile", action="callback", callback=tcm_backup_to_file, nargs=1, type="string", dest="DATE_TIME", help="Backup running Target_Core_Mod/ConfigFS syntax to /etc/target/backup/tcm_backup-.sh") (options, args) = parser.parse_args() if len(sys.argv) == 1: parser.print_help() sys.exit(0) elif not re.search('--', sys.argv[1]): print "Unknown CLI option: " + sys.argv[1] sys.exit(1) if __name__ == "__main__": main() lio-utils-3.1+git2.fd0b34fd/tcm-py/tcm_node.py0000755000175000017500000006127111753136721017223 0ustar rrsrrs#!/usr/bin/python from __future__ import with_statement import os, sys, signal import subprocess as sub import string import re import errno import uuid import shutil from optparse import OptionParser import tcm_pscsi import tcm_iblock import tcm_ramdisk import tcm_fileio tcm_root = "/sys/kernel/config/target/core" def tcm_err(msg): print >> sys.stderr, msg sys.exit(1) def tcm_read(filename): try: with open(filename) as f: return f.read() except IOError, (errno, strerror): if errno == 2: tcm_err("%s %s\n%s" % (filename, strerror, "Is kernel module loaded?") ) def tcm_write(filename, value, newline=True): try: with open(filename, "w") as f: f.write(value) if newline: f.write("\n") except IOError, (errno, strerror): if errno == 2: tcm_err("%s %s\n%s" % (filename, strerror, "Is kernel module loaded?") ) def tcm_full_path(arg): return tcm_root + "/" + arg def tcm_check_dev_exists(dev_path): full_path = tcm_full_path(dev_path) if not os.path.isdir(full_path): tcm_err("TCM/ConfigFS storage object does not exist: " + full_path) def tcm_add_alua_lugp(gp_name): os.makedirs(tcm_root + "/alua/lu_gps/" + gp_name) try: tcm_write(tcm_root + "/alua/lu_gps/%s/lu_gp_id" % lu_gp_name, lu_gp_name) except: os.rmdir(tcm_root + "/alua/lu_gps/" + lu_gp_name) raise def tcm_add_alua_tgptgp(dev_path, gp_name): tcm_check_dev_exists(dev_path) alua_cfs_path = tcm_full_path(dev_path) + "alua/" + gp_name + "/" os.makedirs(alua_cfs_path) try: tcm_write(alua_cfs_path + "tg_pt_gp_id", "0") except: os.rmdir(alua_cfs_path) raise def tcm_alua_check_metadata_dir(dev_path): alua_path = "/var/target/alua/tpgs_" + tcm_get_unit_serial(dev_path) + "/" if os.path.isdir(alua_path): return # Create the ALUA metadata directory for the passed storage object # if it does not already exist. os.makedirs(alua_path) def tcm_alua_delete_metadata_dir(unit_serial): try: os.rmdir("/var/target/alua/tpgs_" + unit_serial + "/") except OSError: pass def tcm_alua_process_metadata(dev_path, gp_name, gp_id): alua_gp_path = tcm_full_path(dev_path) + "/alua/" + gp_name alua_md_path = "/var/target/alua/tpgs_" + tcm_get_unit_serial(dev_path) \ + "/" + gp_name if not os.path.isfile(alua_md_path): # If not pre-existing ALUA metadata exists, go ahead and # allow new ALUA state changes to create and update the # struct file metadata tcm_write(alua_gp_path + "/alua_write_metadata", "1") return with open(alua_md_path, 'rU') as p: d = dict() for line in p.readlines(): name, value = line.split("=") d[name.strip()] = value.strip() if "tg_pt_gp_id" in d and int(d["tg_pt_gp_id"]) != int(gp_id): raise IOError("Passed tg_pt_gp_id: %s does not match extracted: %s" % \ (gp_id, d["tg_pt_gp_id"])) if "alua_access_state" in d: tcm_write(alua_gp_path + "/alua_access_state", d["alua_access_state"]) if "alua_access_status" in d: tcm_write(alua_gp_path + "/alua_access_status", d["alua_access_status"]) # Now allow changes to ALUA target port group update the struct file metadata # in /var/target/alua/tpgs_$T10_UNIT_SERIAL/$TG_PT_GP_NAME tcm_write(alua_gp_path + "/alua_write_metadata", "1") def tcm_add_alua_tgptgp_with_md(dev_path, gp_name, gp_id): alua_gp_path = tcm_full_path(dev_path) + "/alua/" + gp_name tcm_check_dev_exists(dev_path) # If the default_tg_pt_gp is passed, we skip the creation (as it already exists) # and just process ALUA metadata if gp_name == 'default_tg_pt_gp' and gp_id == '0': tcm_alua_process_metadata(dev_path, gp_name, gp_id) return os.makedirs(alua_gp_path) try: tcm_write(alua_gp_path + "/tg_pt_gp_id", gp_id) except: os.rmdir(alua_gp_path) raise # Now process the ALUA metadata for this group tcm_alua_process_metadata(dev_path, gp_name, gp_id) def tcm_delhba(hba_name): hba_path = tcm_full_path(hba_name) for g in os.listdir(hba_path): if g == "hba_info" or g == "hba_mode": continue __tcm_freevirtdev(hba_name + "/" + g) os.rmdir(hba_path) def tcm_del_alua_lugp(lu_gp_name): if not os.path.isdir(tcm_root + "/alua/lu_gps/" + lu_gp_name): tcm_err("ALUA Logical Unit Group: " + lu_gp_name + " does not exist!") os.rmdir(tcm_root + "/alua/lu_gps/" + lu_gp_name) def __tcm_del_alua_tgptgp(dev_path, gp_name): tcm_check_dev_exists(dev_path) full_path = tcm_full_path(dev_path) if not os.path.isdir(full_path + "/alua/" + gp_name): tcm_err("ALUA Target Port Group: " + gp_name + " does not exist!") os.rmdir(full_path + "/alua/" + gp_name) # deletes configfs entry for alua *and* metadata dir. def tcm_del_alua_tgptgp(dev_path, gp_name): tcm_check_dev_exists(dev_path) alua_md_path = "/var/target/alua/tpgs_" + tcm_get_unit_serial(dev_path) \ + "/" + gp_name __tcm_del_alua_tgptgp(dev_path, gp_name) if not os.path.isfile(alua_md_path): return shutil.rmtree(alua_md_path) def tcm_generate_uuid_for_unit_serial(dev_path): # Generate random uuid tcm_set_wwn_unit_serial(dev_path, str(uuid.uuid4())) tcm_types = ( \ dict(name="pscsi", module=tcm_pscsi, gen_uuid=False), dict(name="stgt", module=None, gen_uuid=True), dict(name="iblock", module=tcm_iblock, gen_uuid=True), dict(name="rd_dr", module=tcm_ramdisk, gen_uuid=True), dict(name="rd_mcp", module=tcm_ramdisk, gen_uuid=True), dict(name="fileio", module=tcm_fileio, gen_uuid=True), ) def tcm_createvirtdev(dev_path, plugin_params, establishdev=False): hba_path = dev_path.split('/')[0] # create hba if it doesn't exist hba_full_path = tcm_full_path(hba_path) if not os.path.isdir(hba_full_path): os.mkdir(hba_full_path) # create dev if it doesn't exist full_path = tcm_full_path(dev_path) if os.path.isdir(full_path): tcm_err("TCM/ConfigFS storage object already exists: " + full_path) else: os.mkdir(full_path) # Determine if --establishdev is being called and we want to skip # the T10 Unit Serial Number generation gen_uuid = True if establishdev: gen_uuid = False # Calls into submodules depending on target_core_mod subsystem plugin for tcm in tcm_types: if hba_path.startswith(tcm["name"] + "_"): try: if tcm["module"]: # modules expect plugin_params to be a list, for now. tcm["module"].createvirtdev(dev_path, [plugin_params]) else: tcm_err("no module for %s" % tcm["name"]) except: os.rmdir(full_path) print "Unable to register TCM/ConfigFS storage object: " \ + full_path raise print tcm_read(full_path + "/info") if tcm["gen_uuid"] and gen_uuid: tcm_generate_uuid_for_unit_serial(dev_path) tcm_alua_check_metadata_dir(dev_path) break def tcm_get_unit_serial(dev_path): string = tcm_read(tcm_full_path(dev_path) + "/wwn/vpd_unit_serial") return string.split(":")[1].strip() def tcm_show_aptpl_metadata(dev_path): tcm_check_dev_exists(dev_path) aptpl_file = "/var/target/pr/aptpl_" + tcm_get_unit_serial(dev_path) if not os.path.isfile(aptpl_file): tcm_err("Unable to dump PR APTPL metadata file: " + aptpl_file) print tcm_read(aptpl_file) def tcm_delete_aptpl_metadata(unit_serial): aptpl_file = "/var/target/pr/aptpl_" + unit_serial if not os.path.isfile(aptpl_file): return shutil.rmtree(aptpl_file) def tcm_process_aptpl_metadata(dev_path): tcm_check_dev_exists(dev_path) full_path = tcm_full_path(dev_path) aptpl_file = "/var/target/pr/aptpl_" + tcm_get_unit_serial(dev_path) if not os.path.isfile(aptpl_file): return # read PR info from file lines = tcm_read(aptpl_file).split() if not lines[0].startswith("PR_REG_START:"): return reservations = [] for line in lines: if line.startswith("PR_REG_START:"): res_list = [] elif line.startswith("PR_REG_END:"): reservations.append(res_list) else: res_list.append(line.strip()) # write info into configfs for res in reservations: tcm_write(full_path + "/pr/res_aptpl_metadata", ",".join(res)) def tcm_establishvirtdev(dev_path, plugin_params): tcm_createvirtdev(dev_path, plugin_params, True) def tcm_create_pscsi(dev_path, ctl): # convert passed 3-tuple to format pscsi expects # "1:3:5" -> "scsi_channel_id=1,scsi_target_id=3..." # param_names = ("scsi_channel_id", "scsi_target_id", "scsi_lun_id") pscsi_params = zip(param_names, ctl.split(":")) pscsi_params_str = ",".join([x + "=" + y for x, y in pscsi_params]) tcm_createvirtdev(dev_path, pscsi_params_str) def tcm_create_pscsibyudev(dev_path, udev_path): tcm_createvirtdev(cfs_dev, udev_path) def tcm_create_iblock(dev_path, udev_path): tcm_createvirtdev(dev_path, udev_path) def tcm_create_fileio(dev_path, filename, size): fileio_params = "fd_dev_name=" + filename + ",fd_dev_size=" + size tcm_createvirtdev(dev_path, fileio_params) def tcm_create_ramdisk(dev_path, pages): tcm_createvirtdev(dev_path, pages) def __tcm_freevirtdev(dev_path): tcm_check_dev_exists(dev_path) full_path = tcm_full_path(dev_path) for tg_pt_gp in os.listdir(full_path + "/alua/"): if tg_pt_gp == "default_tg_pt_gp": continue __tcm_del_alua_tgptgp(dev_path, tg_pt_gp) os.rmdir(full_path) def tcm_freevirtdev(dev_path): tcm_check_dev_exists(dev_path) unit_serial = tcm_get_unit_serial(dev_path) __tcm_freevirtdev(dev_path) # For explict tcm_node --freedev, delete any remaining # PR APTPL and ALUA metadata tcm_delete_aptpl_metadata(unit_serial) tcm_alua_delete_metadata_dir(unit_serial) def tcm_list_dev_attribs(dev_path): tcm_check_dev_exists(dev_path) full_path = tcm_full_path(dev_path) print "TCM Storage Object Attributes for " + full_path for attrib in os.listdir(full_path + "/attrib/"): print " %s: %s" % \ (attrib, tcm_read(full_path + "/attrib/" + attrib).strip()) def tcm_list_hbas(): for hba in os.listdir(tcm_root): if hba == "alua": continue print "\------> " + hba dev_root = tcm_root + "/" + hba print "\t" + tcm_read(dev_root+"/hba_info").strip() for dev in os.listdir(dev_root): if dev in ("hba_info", "hba_mode"): continue try: value = tcm_read(dev_root + "/" + dev + "/info") except IOError, msg: print " \-------> " + dev print " No TCM object association active, skipping" continue udev_path = tcm_read(dev_root + "/" + dev + "/udev_path") if udev_path: udev_str = "udev_path: " + udev_path.rstrip() else: udev_str = "udev_path: N/A" print " \-------> " + dev print " " + value.rstrip() print " " + udev_str def tcm_list_alua_lugps(): for lu_gp in os.listdir(tcm_root + "/alua/lu_gps"): group_path = tcm_root + "/alua/lu_gps/" + lu_gp lu_gp_id = tcm_read(group_path + "/lu_gp_id").strip() print "\------> " + lu_gp + " LUN Group ID: " + lu_gp_id lu_gp_members = tcm_read(group_path + "/members").strip().split() if not lu_gp_members: print " No Logical Unit Group Members" continue for member in lu_gp_members: print " " + member def tcm_dump_alua_state(alua_state_no): if alua_state_no == "0": return "Active/Optimized" elif alua_state_no == "1": return "Active/NonOptimized" elif alua_state_no == "2": return "Standby" elif alua_state_no == "3": return "Unavailable" elif alua_state_no == "15": return "Transition" else: return "Unknown" def tcm_list_alua_tgptgp(dev_path, gp_name): tcm_check_dev_exists(dev_path) gp_path = tcm_full_path(dev_path) + "/alua/" + gp_name gp_id = tcm_read(gp_path + "/tg_pt_gp_id").strip() print "\------> " + tg_pt_gp + " Target Port Group ID: " + tg_pt_gp_id alua_type = tcm_read(gp_path + "/alua_access_type").strip() print " Active ALUA Access Type(s): " + alua_type alua_state = tcm_read(gp_path + "/alua_access_state").strip() print " Primary Access State: " + tcm_dump_alua_state(alua_state) try: access_status = tcm_read(gp_path + "/alua_access_status").strip() print " Primary Access Status: " + access_status except IOError: pass preferred = tcm_read(gp_path + "/preferred").strip() print " Preferred Bit: " + preferred nonop_delay = tcm_read(gp_path + "/nonop_delay_msecs").strip() print " Active/NonOptimized Delay in milliseconds: " + nonop_delay trans_delay = tcm_read(gp_path + "/trans_delay_msecs").strip() print " Transition Delay in milliseconds: " + trans_delay gp_members = tcm_read(gp_path + "/members").strip().split() print " \------> TG Port Group Members" if not gp_members: print " No Target Port Group Members" else: for member in gp_members: print " " + member def tcm_list_alua_tgptgps(dev_path): tcm_check_dev_exists(dev_path) for tg_pt_gp in os.listdir(tcm_full_path(dev_path) + "/alua/"): tcm_list_alua_tgptgp(dev_path, tg_pt_gp) def tcm_show_persistent_reserve_info(dev_path): tcm_check_dev_exists(dev_path) full_path = tcm_full_path(dev_path) for f in os.listdir(full_path + "/pr/"): info = tcm_read(full_path + "/pr/" + f).strip() if info: print info def tcm_set_alua_state(dev_path, gp_name, access_state): tcm_check_dev_exists(dev_path) new_alua_state_str = str(access_state).lower() if new_alua_state_str == "o": alua_state = 0 # Active/Optimized elif new_alua_state_str == "a": alua_state = 1 # Active/NonOptimized elif new_alua_state_str == "s": alua_state = 2 # Standby elif new_alua_state_str == "u": alua_state = 3 # Unavailable else: tcm_err("Unknown ALUA access state: " + new_alua_state_str) alua_path = tcm_full_path(dev_path) + "/alua/" + gp_name + "/alua_access_state" tcm_write(alua_path, str(alua_state)) def tcm_set_alua_type(dev_path, gp_name, access_type): tcm_check_dev_exists(dev_path) new_alua_type_str = str(access_type).lower() if new_alua_type_str == "both": alua_type = 3 elif new_alua_type_str == "explict": alua_type = 2 elif new_alua_type_str == "implict": alua_type = 1 elif new_alua_type_str == "none": alua_type = 0 else: tcm_err("Unknown ALUA access type: " + new_alua_type_str) alua_path = tcm_full_path(dev_path) + "/alua/" + gp_name + "/alua_access_type" tcm_write(alua_path, str(alua_type)) def tcm_set_alua_nonop_delay(dev_path, gp_name, msec_delay): tcm_check_dev_exists(dev_path) if not os.path.isdir(tcm_full_path(dev_path) + "/alua/" + gp_name): tcm_err("Unable to locate TG Pt Group: " + gp_name) alua_path = tcm_full_path(dev_path) + "/alua/" + gp_name + "/nonop_delay_msecs" tcm_write(alua_path, str(msec_delay)) def tcm_set_alua_trans_delay(dev_path, gp_name, msec_delay): tcm_check_dev_exists(dev_path) if not os.path.isdir(tcm_full_path(dev_path) + "/alua/" + gp_name): tcm_err("Unable to locate TG Pt Group: " + gp_name) alua_path = tcm_full_path(dev_path) + "/alua/" + gp_name + "/trans_delay_msecs" tcm_write(alua_path, str(msec_delay)) def tcm_clear_alua_tgpt_pref(dev_path, gp_name): tcm_check_dev_exists(dev_path) if not os.path.isdir(tcm_full_path(dev_path) + "/alua/" + gp_name): tcm_err("Unable to locate TG Pt Group: " + gp_name) alua_path = tcm_full_path(dev_path) + "/alua/" + gp_name + "/preferred" tcm_write(alua_path, "0") def tcm_set_alua_tgpt_pref(dev_path, gp_name): tcm_check_dev_exists(dev_path) if not os.path.isdir(tcm_full_path(dev_path) + "/alua/" + gp_name): tcm_err("Unable to locate TG Pt Group: " + gp_name) alua_path = tcm_full_path(dev_path) + "/alua/" + gp_name + "/preferred" tcm_write(alua_path, "1") def tcm_set_alua_lugp(dev_path, gp_name): tcm_check_dev_exists(dev_path) if not os.path.isdir(tcm_full_path(dev_path) + "/alua/lu_gps/" + gp_name): tcm_err("Unable to locate ALUA Logical Unit Group: " + gp_name) alua_path = tcm_full_path(dev_path) + "/alua/lu_gps/" + gp_name + "/alua_lu_gp" tcm_write(alua_path, gp_name) def tcm_set_dev_attrib(dev_path, attrib, value): tcm_check_dev_exists(dev_path) tcm_write(tcm_full_path(dev_path) + "/attrib/" + attrib, value) def tcm_set_udev_path(dev_path, udev_path): tcm_check_dev_exists(dev_path) tcm_write(tcm_full_path(dev_path) + "/udev_path", udev_path, newline=False) def tcm_set_wwn_unit_serial(dev_path, unit_serial): tcm_check_dev_exists(dev_path) tcm_write(tcm_full_path(dev_path) + "/wwn/vpd_unit_serial", unit_serial) def tcm_set_wwn_unit_serial_with_md(dev_path, unit_serial): tcm_check_dev_exists(dev_path) tcm_set_wwn_unit_serial(dev_path, unit_serial) # Process PR APTPL metadata tcm_process_aptpl_metadata(dev_path) # Make sure the ALUA metadata directory exists for this storage object tcm_alua_check_metadata_dir(dev_path) def tcm_show_udev_path(dev_path): tcm_check_dev_exists(dev_path) print tcm_read(tcm_full_path(dev_path) + "/udev_path") def tcm_show_wwn_info(dev_path): tcm_check_dev_exists(dev_path) full_path = tcm_full_path(dev_path) + "/wwn/" for f in os.listdir(full_path): info = tcm_read(full_path + f).strip() if info: print info def tcm_unload(): if not os.path.isdir(tcm_root): tcm_err("Unable to access tcm_root: " + tcm_root) hba_root = os.listdir(tcm_root) for f in hba_root: if f == "alua": continue tcm_delhba(f) for lu_gp in os.listdir(tcm_root + "/alua/lu_gps"): if lu_gp == "default_lu_gp": continue tcm_del_alua_lugp(lu_gp) # Unload TCM subsystem plugin modules for module in ("iblock", "file", "pscsi", "stgt"): os.system("rmmod target_core_%s" % module) # Unload TCM Core rmmod_op = "rmmod target_core_mod" ret = os.system(rmmod_op) if ret: tcm_err("Unable to rmmod target_core_mod") def tcm_version(): return tcm_read("/sys/kernel/config/target/version").strip() cmdline_options = ( \ dict(opt_str="--addlungp", callback=tcm_add_alua_lugp, nargs=1, dest="lu_gp_name", help="Add ALUA Logical Unit Group"), dict(opt_str=("--addtgptgp","--addaluatpg"), callback=tcm_add_alua_tgptgp, nargs=2, dest="HBA/DEV ", help="Add ALUA Target Port Group to Storage Object"), dict(opt_str=("--addtgptgpwithmd","--addaluatpgwithmd"), action="callback", callback=tcm_add_alua_tgptgp_with_md, nargs=3, dest="HBA/DEV ", help="Add ALUA Target Port Group to Storage Object with ID and process ALUA metadata"), dict(opt_str=("--block","--iblock"), callback=tcm_create_iblock, nargs=2, dest="HBA/DEV ", help="Associate TCM/IBLOCK object with Linux/BLOCK device"), dict(opt_str="--clearaluapref", callback=tcm_clear_alua_tgpt_pref, nargs=2, dest="HBA/DEV ", help="Clear ALUA Target Port Group Preferred Bit"), dict(opt_str="--delhba", callback=tcm_delhba, nargs=1, dest="HBA", help="Delete TCM Host Bus Adapter (HBA)"), dict(opt_str="--dellungp", callback=tcm_del_alua_lugp, nargs=1, dest="lu_gp_name", help="Delete ALUA Logical Unit Group"), dict(opt_str=("--deltgptgp","--delaluatpg"), callback=tcm_del_alua_tgptgp, nargs=2, dest="HBA/DEV TG_PT_GP_NAME", help="Delete ALUA Target Port Group from Storage Object"), dict(opt_str="--createdev", callback=tcm_createvirtdev, nargs=2, dest="HBA/DEV ", help="Create TCM Storage Object using subsystem dependent parameters," " and generate new T10 Unit Serial for IBLOCK,FILEIO,RAMDISK"), dict(opt_str="--establishdev", callback=tcm_establishvirtdev, nargs=2, dest="HBA/DEV ", help="Create TCM Storage Object using subsystem dependent parameters, do" "not generate new T10 Unit Serial"), dict(opt_str="--fileio", callback=tcm_create_fileio, nargs=3, dest="HBA/DEV ", help="Associate TCM/FILEIO object with Linux/VFS file or underlying" " device for buffered FILEIO"), dict(opt_str="--freedev", callback=tcm_freevirtdev, nargs=1, dest="HBA/DEV", help="Free TCM Storage Object"), dict(opt_str="--listdevattr", callback=tcm_list_dev_attribs, nargs=1, dest="HBA/DEV", help="List TCM storage object device attributes"), dict(opt_str="--listhbas", callback=tcm_list_hbas, nargs=0, help="List TCM Host Bus Adapters (HBAs)"), dict(opt_str="--listlugps", callback=tcm_list_alua_lugps, nargs=0, help="List ALUA Logical Unit Groups"), dict(opt_str=("--listtgptgp","--listaluatpg"), callback=tcm_list_alua_tgptgp, nargs=2, dest="HBA/DEV ", help="List specific ALUA Target Port Group for Storage Object"), dict(opt_str=("--listtgptgps","--listaluatpgs"), callback=tcm_list_alua_tgptgps, nargs=1, dest="HBA/DEV", help="List all ALUA Target Port Groups for Storage Object"), dict(opt_str="--pr", callback=tcm_show_persistent_reserve_info, nargs=1, dest="HBA/DEV", help="Show Persistent Reservation info"), dict(opt_str="--praptpl", callback=tcm_process_aptpl_metadata, nargs=1, dest="HBA/DEV", help="Process PR APTPL metadata from file"), dict(opt_str="--prshowmd", callback=tcm_show_aptpl_metadata, nargs=1, dest="HBA/DEV", help="Show APTPL metadata file"), dict(opt_str="--ramdisk", callback=tcm_create_ramdisk, nargs=2, dest="HBA/DEV ", help="Create and associate TCM/RAMDISK object"), dict(opt_str=("--scsi","--pscsi"), callback=tcm_create_pscsi, nargs=2, dest="HBA/DEV ", help="Associate TCM/pSCSI object with Linux/SCSI device by bus location"), dict(opt_str=("--scsibyudev", "--pscsibyudev"), callback=tcm_create_pscsibyudev, nargs=2, dest="HBA/DEV ", help="Associate TCM/pSCSI object with Linux/SCSI device by UDEV Path"), dict(opt_str="--setaluadelay", callback=tcm_set_alua_nonop_delay, nargs=3, dest="HBA/DEV ", help="Set ALUA Target Port Group delay for Active/NonOptimized in milliseconds"), dict(opt_str="--setaluapref", callback=tcm_set_alua_tgpt_pref, nargs=2, dest="HBA/DEV ", help="Set ALUA Target Port Group Preferred Bit"), dict(opt_str="--setaluastate", callback=tcm_set_alua_state, nargs=3, dest="HBA/DEV ", help="Set ALUA access state for TG_PT_GP_NAME on Storage Object. The value access" " states are \"o\" = active/optimized, \"a\" = active/nonoptimized, \"s\" = standby," " \"u\" = unavailable"), dict(opt_str="--setaluatransdelay", callback=tcm_set_alua_trans_delay, nargs=3, dest="HBA/DEV ", help="Set ALUA Target Port Group Transition delay"), dict(opt_str="--setaluatype", callback=tcm_set_alua_type, nargs=3, dest="HBA/DEV ", help="Set ALUA access type for TG_PT_GP_NAME on Storage Object. The value type" " states are \"both\" = implict/explict, \"explict\", \"implict\", or \"none\""), dict(opt_str="--setdevattr", callback=tcm_set_dev_attrib, nargs=3, dest="HBA/DEV ", help="Set new value for TCM storage object device attribute"), dict(opt_str="--setlugp", callback=tcm_set_alua_lugp, nargs=2, dest="HBA/DEV LU_GP_NAME", help="Set ALUA Logical Unit Group"), dict(opt_str="--setudevpath", callback=tcm_set_udev_path, nargs=2, dest="HBA/DEV ", help="Set UDEV Path Information, only used when --createdev did not contain" " as parameter"), dict(opt_str="--setunitserial", callback=tcm_set_wwn_unit_serial, nargs=2, dest="HBA/DEV ", help="Set T10 EVPD Unit Serial Information"), dict(opt_str="--setunitserialwithmd", callback=tcm_set_wwn_unit_serial_with_md, nargs=2, dest="HBA/DEV ", help="Set T10 EVPD Unit Serial Information and process PR APTPL metadata"), dict(opt_str="--udevpath", callback=tcm_show_udev_path, nargs=1, dest="HBA/DEV", help="Show UDEV Path Information for TCM storage object"), dict(opt_str="--unload", callback=tcm_unload, nargs=0, help="Unload target_core_mod"), dict(opt_str="--wwn", callback=tcm_show_wwn_info, nargs=1, dest="HBA/DEV", help="Show WWN info"), ) def dispatcher(option, opt_str, value, parser, orig_callback): if option.nargs == 1: value = (value,) value = [str(x).strip() for x in value] orig_callback(*value) def main(): parser = OptionParser(version=tcm_version()) for opt in cmdline_options: # cmd_aliases can be string or tuple of strings. # we're unpacking below, so convert strings to 1 item tuples cmd_aliases = opt["opt_str"] if isinstance(cmd_aliases, basestring): cmd_aliases = (cmd_aliases,) del opt["opt_str"] # common params for all options opt["action"] = "callback" opt["type"] = "string" opt["callback_kwargs"] = dict(orig_callback=opt["callback"]) opt["callback"] = dispatcher parser.add_option(*cmd_aliases, **opt) (options, args) = parser.parse_args() if len(sys.argv) == 1: parser.print_help() sys.exit(0) elif not re.search('--', sys.argv[1]): tcm_err("Unknown CLI option: " + sys.argv[1]) if __name__ == "__main__": main() lio-utils-3.1+git2.fd0b34fd/tcm-py/uninstall.sh0000755000175000017500000000054211753136721017420 0ustar rrsrrs#!/bin/sh SITE_PACKAGES=`python ../get-py-modules-path.py` if [ -f /usr/sbin/tcm_node ]; then rm /usr/sbin/tcm_node fi if [ -f /usr/sbin/tcm_dump ]; then rm /usr/sbin/tcm_dump fi if [ -f /usr/sbin/tcm_loop ]; then rm /usr/sbin/tcm_loop fi if [ -f /usr/sbin/tcm_fabric ]; then rm /usr/sbin/tcm_fabric fi rm -rf $SITE_PACKAGES/tcm_* lio-utils-3.1+git2.fd0b34fd/tcm-py/tcm_fabric.py0000755000175000017500000004271211753136721017523 0ustar rrsrrs#!/usr/bin/python import os, sys, shutil import subprocess as sub import string import re import datetime, time import optparse target_root = "/sys/kernel/config/target/" spec_root = "/var/target/fabric/" def fabric_err(msg): print >> sys.stderr, msg sys.exit(1) def fabric_configfs_dump(fabric_name, fabric_root, module_name): if not os.path.isdir(fabric_root): print "Unable to access fabric_root: " + fabric_root sys.exit(1) iqn_root = os.listdir(fabric_root) # This will load up the fabric module print "modprobe " + module_name print "mkdir " + fabric_root # print "#### " + fabric_name + " Discovery authentication information" auth_dir = fabric_root + "/discovery_auth" if os.path.isdir(auth_dir) == True: for auth in os.listdir(auth_dir): if auth == "authenticate_target": continue auth_file = auth_dir + "/" + auth p = os.open(auth_file, 0) value = os.read(p, 256) ret = value.isspace() if ret: os.close(p) continue print "echo -n " + value.rstrip() + " > " + auth_file os.close(p) iqn_root = os.listdir(fabric_root) # Loop through LIO-Target IQN list for iqn in iqn_root: if not os.path.isdir(fabric_root + "/" + iqn): continue if iqn == "lio_version": continue if iqn == "discovery_auth": continue # Loop through LIO-Target IQN+TPGT list tpg_root = os.listdir(fabric_root + "/" + iqn); for tpgt_tmp in tpg_root: if tpgt_tmp == "fabric_statistics": continue tpgt_tmp2 = tpgt_tmp.split('_') tpgt = tpgt_tmp2[1] # print "#### Network portals for iSCSI Target Portal Group" # np_root = os.listdir(fabric_root + "/" + iqn + "/tpgt_" + tpgt + "/np") # for np in np_root: # print "mkdir -p " + fabric_root + "/" + iqn + "/tpgt_" + tpgt + "/np/" + np # Dump Nexus attribute (when available) nexus_file = fabric_root + "/" + iqn + "/tpgt_" + tpgt + "/nexus" if os.path.isfile(nexus_file): print "mkdir -p " + fabric_root + "/" + iqn + "/tpgt_" + tpgt p = os.open(nexus_file, 0) value = os.read(p, 256) print "echo " + value.rstrip() + " > " + nexus_file os.close(p) print "#### " + fabric_name + " Target Ports" lun_root = os.listdir(fabric_root + "/" + iqn + "/tpgt_" + tpgt + "/lun") for lun_tmp in lun_root: lun_tmp2 = lun_tmp.split('_') lun = lun_tmp2[1] lun_dir = fabric_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun print "mkdir -p " + lun_dir port_root = os.listdir(lun_dir) for port in port_root: if port == "alua_tg_pt_gp": continue if port == "alua_tg_pt_offline": continue if port == "alua_tg_pt_status": continue if port == "alua_tg_pt_write_md": continue if not os.path.islink(lun_dir + "/" + port): continue port_link = fabric_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun + "/" + port sourcelink = os.readlink(port_link) sourcelink2 = os.path.join(os.path.dirname(port_link), sourcelink) print "ln -s " + sourcelink2 + " " + port_link # Dump ALUA Target Port Group tg_pt_gp_file = lun_dir + "/alua_tg_pt_gp" p = os.open(tg_pt_gp_file, 0) try: value = os.read(p, 512) except: os.close(p) continue os.close(p) if value: tg_pt_gp_tmp = value.split('\n') tg_pt_gp_out = tg_pt_gp_tmp[0] off = tg_pt_gp_out.index('Alias: ') off += 7 # Skip over "Alias: " tg_pt_gp_name = tg_pt_gp_out[off:] # Only need to dump if LIO-Target Port is NOT partof # the 'default_tg_pt_gp' if not re.search(tg_pt_gp_name, 'default_tg_pt_gp'): print "#### ALUA Target Port Group" print "echo " + tg_pt_gp_name + " > " + tg_pt_gp_file #FIXME: --aluasecmd support # print "lio_node --aluasecmd " + iqn + " " + tpgt + " " + lun # Dump values of iscsi/iqn/tpgt/attrib/ print "#### Attributes for " + fabric_name + " Target Portal Group" attrib_dir = fabric_root + "/" + iqn + "/tpgt_" + tpgt + "/attrib/" attrib_root = os.listdir(attrib_dir) for attrib in attrib_root: attrib_file = attrib_dir + attrib p = os.open(attrib_file, 0) value = os.read(p, 16) print "echo " + value.rstrip() + " > " + attrib_file os.close(p) # Dump values for iscsi/iqn/tpgt/param print "#### Parameters for " + fabric_name + " Target Portal Group" param_dir = fabric_root + "/" + iqn + "/tpgt_" + tpgt + "/param/" param_root = os.listdir(param_dir) for param in param_root: param_file = param_dir + param p = os.open(param_file, 0) value = os.read(p, 256) print "echo \"" + value.rstrip() + "\" > " + param_file os.close(p) if os.path.isfile(nexus_file): continue # Dump fabric Initiator Node ACLs from fabric_root/$WWN/tpgt_$TPGT/acls/ print "#### " + fabric_name + " Initiator ACLs for " + fabric_name + " Target Portal Group" nacl_dir = fabric_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" nacl_root = os.listdir(nacl_dir) for nacl in nacl_root: print "mkdir -p " + nacl_dir + nacl # Dump fabric Initiator ACL authentication info from fabric_root/$WWN/tpgt_$TPGT/acls//$INITIATOR/auth print "#### " + fabric_name + " Initiator ACL authentication information" auth_dir = nacl_dir + nacl + "/auth" for auth in os.listdir(auth_dir): if auth == "authenticate_target": continue auth_file = auth_dir + "/" + auth p = os.open(auth_file, 0) value = os.read(p, 256) ret = value.isspace() if ret: os.close(p) continue print "echo -n " + value.rstrip() + " > " + auth_file os.close(p) # Dump fabric Initiator ACL TPG attributes from fabric_root/$WWN/tpgt_$TPGT/acls/$INITIATOR/attrib print "#### " + fabric_name + " Initiator ACL TPG attributes" nacl_attrib_dir = nacl_dir + nacl + "/attrib" for nacl_attrib in os.listdir(nacl_attrib_dir): nacl_attrib_file = nacl_attrib_dir + "/" + nacl_attrib p = os.open(nacl_attrib_file, 0) value = os.read(p, 8) print "echo " + value.rstrip() + " > " + nacl_attrib_file os.close(p) # Dump fabric Initiator LUN ACLs from fabric_root/$WWN/tpgt_$TPGT//acls/$INITIATOR/lun print "#### " + fabric_name + " Initiator LUN ACLs for iSCSI Target Portal Group" lun_acl_dir = nacl_dir + nacl for lun_acl in os.listdir(lun_acl_dir): ret = re.search('lun_', lun_acl) if not ret: continue lun_link_dir = nacl_dir + nacl + "/" + lun_acl print "mkdir -p " + lun_link_dir for lun_acl_link in os.listdir(lun_link_dir): if lun_acl_link == "write_protect": p = os.open(lun_link_dir + "/write_protect", 0) value = os.read(p, 4) print "echo " + value.rstrip() + " > " + lun_link_dir + "/write_protect" os.close(p) continue if not os.path.islink(lun_link_dir + "/" + lun_acl_link): continue sourcelink = os.readlink(lun_link_dir + "/" + lun_acl_link) sourcelink2 = os.path.join(os.path.dirname(lun_link_dir + "/" + lun_acl_link), sourcelink) print "ln -s " + sourcelink2 + " " + lun_link_dir + "/" + lun_acl_link # Dump value of fabric_root/$WWN/tpgt_$TPGT//enable print "#### Trigger to enable " + fabric_name + " Target Portal Group" enable_file = fabric_root + "/" + iqn + "/tpgt_" + tpgt + "/enable" if os.path.isfile(enable_file): p = os.open(enable_file, 0) value = os.read(p, 1) print "echo " + value.rstrip() + " > " + enable_file os.close(p) return def fabric_configfs_dump_all(): for fabric_name in os.listdir(target_root): if fabric_name == "version": continue if fabric_name == "core": continue # FIXME: currently using lio_dump --stdout if fabric_name == "iscsi": continue fabric_root = target_root + fabric_name # print "Using fabric_configfs_dump_all: " + fabric_name + ", " + fabric_root module_name = fabric_get_module_name(fabric_name) # print "module_name: "+ module_name fabric_configfs_dump(fabric_name, fabric_root, module_name); return def fabric_backup_to_file(date_time, fabric_name, fabric_root, module_name): now = date_time if not os.path.isdir(fabric_root): print "Unable to access fabric_root: " + fabric_root sys.exit(1) current_dir = "/etc/target" backup_dir = "/etc/target/backup" if not os.path.isdir(backup_dir): op = "mkdir " + backup_dir ret = os.system(op) if ret: print "Unable to open backup_dir" sys.exit(1) op = "tcm_fabric --stdout --fabric-name=" + fabric_name + " --fabric-root=" + fabric_root + " --module-name=" + module_name # print "Using op: " + op p = sub.Popen(op, shell=True, stdout=sub.PIPE).stdout if not p: print "Unable to dump " + fabric_name + "/ConfigFS running state" sys.exit(1) orig_file = current_dir + "/" + fabric_name + "_start.sh" print "Making backup of " + fabric_name + "/ConfigFS with timestamp: " + now backup_file = backup_dir + "/" + fabric_name + "_backup-" + now + ".sh" if os.path.isfile(backup_file): print "" + fabric_name + " backup_file: " + backup_file + "already exists, exiting" p.close() sys.exit(1) back = open(backup_file, 'w') line = p.readline() while line: print >>back, line.rstrip() line = p.readline() p.close() back.close() ret = shutil.copyfile(backup_file, orig_file) if ret: print "Unable to copy " + back_file sys.exit(1) print "Successfully updated default config " + orig_file return backup_file def fabric_backup_to_file_all(date_time): if not os.path.isdir(target_root): print "Unable to open target_root: " + target_root sys.exit(1) for fabric_name in os.listdir(target_root): if fabric_name == "version": continue if fabric_name == "core": continue # FIXME: currently using lio_dump if fabric_name == "iscsi": continue fabric_root = target_root + fabric_name # print "Using fabric_backup_to_file: " + date_time + ", " + fabric_name + ", " + fabric_root module_name = fabric_get_module_name(fabric_name) # print "Using module_name: "+ module_name fabric_backup_to_file(date_time, fabric_name, fabric_root, module_name) return def fabric_unload(fabric_name, fabric_root, module_name): if not os.path.isdir(fabric_root): print "Unable to access fabric_root: " + fabric_root sys.exit(1) wwn_root = os.listdir(fabric_root) for wwn in wwn_root: if not os.path.isdir(fabric_root + "/" + wwn): continue if wwn == "discovery_auth": continue tpg_root = fabric_root + "/" + wwn for tpgt_tmp in os.listdir(tpg_root): if tpgt_tmp == "fabric_statistics": continue tpgt_tmp2 = tpgt_tmp.split('_') tpgt = tpgt_tmp2[1] if os.path.isfile(fabric_root + "/" + wwn + "/tpgt_" + tpgt + "/enable"): disable_op = "echo 0 > " + fabric_root + "/" + wwn + "/tpgt_" + tpgt + "/enable" ret = os.system(disable_op) if ret: print "Unable to disable TPG: " + wwn + " TPGT: " + tpgt nacl_root = fabric_root + "/" + wwn + "/tpgt_" + tpgt + "/acls" for nacl in os.listdir(nacl_root): lun_acl_root = nacl_root + "/" + nacl + "/" for lun_acl in os.listdir(lun_acl_root): ret = re.search('lun_', lun_acl) if not ret: continue mapped_lun = lun_acl[4:] lun_link_dir = lun_acl_root + "/" + lun_acl + "/" for lun_acl_link in os.listdir(lun_link_dir): if lun_acl_link == "write_protect": continue if os.path.islink(lun_link_dir + "/" + lun_acl_link): unlink_op = lun_link_dir + "/" + lun_acl_link ret = os.unlink(unlink_op) if ret: print "Unable to unlink MappedLUN: " + lun_link_dir + "/" + lun_acl_link dellunacl_op = "rmdir " + lun_link_dir ret = os.system(dellunacl_op) if ret: print "Unable to rmdir fabric mapped_lun" delnodeacl_op = "rmdir " + nacl_root + "/" + nacl + "/" ret = os.system(delnodeacl_op) if ret: print "Unable to remove NodeACL: " + nacl_root + "/" + nacl + "/" lun_root = fabric_root + "/" + wwn + "/tpgt_" + tpgt + "/lun" for lun_tmp in os.listdir(lun_root): lun_tmp2 = lun_tmp.split('_') lun = lun_tmp2[1] lun_dir = lun_root + "/lun_" + lun for port in os.listdir(lun_dir): if not os.path.islink(lun_dir + "/" + port): continue unlink_op = lun_dir + "/" + port ret = os.unlink(unlink_op) if ret: print "Unable to unlink fabric port/lun" rmdir_op= "rmdir " + lun_dir ret = os.system(rmdir_op); if ret: print "Unable to rmdir fabric port/lun: " + lun_dir rmdir_op = "rmdir " + fabric_root + "/" + wwn + "/tpgt_" + tpgt + "/" ret = os.system(rmdir_op) if ret: print "Unable to rmdir fabric tpg: " + fabric_root + "/" + wwn + "/tpgt_" + tpgt + "/" rmdir_op = "rmdir " + fabric_root + "/" + wwn + "/" ret = os.system(rmdir_op) if ret: print "Unable to rmdir fabric wwn: " + fabric_root + "/" + wwn + "/" rmdir_op = "rmdir " + fabric_root ret = os.system(rmdir_op) if ret: print "Unable to release fabric_root: " + fabric_root rmmod_op = "rmmod " + module_name ret = os.system(rmmod_op) if ret: print "Unable to unload " + module_name print "Successfully released fabric: " + fabric_root return def fabric_get_module_name(fabric_name): kernel_module = "" for specs in os.listdir(spec_root): if specs == "README": continue # print "specs: " + specs + ", fabric_name: " + fabric_name if not re.search(fabric_name + ".spec", specs) and not re.search("tcm_" + fabric_name + ".spec", specs) and not re.search(fabric_name, specs): continue op = "cat " + spec_root + specs p = sub.Popen(op, shell=True, stdout=sub.PIPE).stdout if not p: print "Unable to dump " + fabric_name + "/ConfigFS running state" sys.exit(1) line = p.readline() while line: tmp = line.rstrip() # Check for 'kernel_module' line in $FABRIC.spec if re.search('kernel_module', tmp): tmp_list = tmp.split('= ') p.close() return tmp_list[1] line = p.readline() p.close() return kernel_module def fabric_unloadall(): module_name = "" try: for fabric_name in os.listdir(target_root): if fabric_name == "version": continue if fabric_name == "core": continue # FIXME: currently using lio_node --unload if fabric_name == "iscsi": continue fabric_root = target_root + fabric_name module_name = fabric_get_module_name(fabric_name) #print "fabric_get_module_name() using: " + module_name if module_name == "": continue fabric_unload(fabric_name, fabric_root, module_name) except OSError, (errno, strerror): if errno == 2: fabric_err("%s %s\n%s" % (target_root, strerror, "Is kernel module loaded?") ) def do_work(stdout_enable, stdout_enable_all, date_time, unload, unloadall, fabric_name, fabric_root, module_name): if not stdout_enable == "None": fabric_configfs_dump(fabric_name, fabric_root, module_name) elif not stdout_enable_all == "None": fabric_configfs_dump_all() elif not date_time == "None": fabric_backup_to_file(date_time, fabric_name, fabric_root, module_name) elif not unload == "None": fabric_unload(fabric_name, fabric_root, module_name) elif not unloadall == "None": fabric_unloadall() return 0 def main(): parser_fabric = optparse.OptionParser() parser_fabric.add_option("--s","--stdout", dest='stdout_enable', action='store', nargs=0, help="Dump running Fabric/ConfigFS syntax to STDOUT", type='string') parser_fabric.add_option("--z","--stdoutall", dest='stdout_enable_all', action='store', nargs=0, help="Dump all running Fabric/ConfigFS syntax to STDOUT", type='string') parser_fabric.add_option("--t", "--tofile", dest="date_time", action='store', nargs=1, help="Backup running Fabric/ConfigFS syntax to /etc/target/backup/fabricname_backup-.sh", type='string') parser_fabric.add_option("--u", "--unload", dest="unload", action='store', nargs=0, help="Unload running Fabric/ConfigFS", type='string') parser_fabric.add_option("--a", "--unloadall", dest="unloadall", action='store', nargs=0, help="Unload all running Fabric/ConfigFS", type='string') parser_fabric.add_option("--f", "--fabric-name", dest='fabric_name', action='store', nargs=1, help="Target fabric name", type='string') parser_fabric.add_option("--r", "--fabric-root", dest='fabric_root', action='store', nargs=1, help="Target fabric configfs root", type='string') parser_fabric.add_option("--m", "--module-name", dest='module_name', action='store', nargs=1, help="Target fabric module name ", type='string') (opts_fabric, args_fabric) = parser_fabric.parse_args() mandatories = ['fabric_name', 'fabric_root', 'module_name'] for m in mandatories: if not opts_fabric.__dict__[m]: unloadall = str(opts_fabric.__dict__['unloadall']) stdout_enable = str(opts_fabric.__dict__['stdout_enable']) stdout_enable_all = str(opts_fabric.__dict__['stdout_enable_all']) date_time = str(opts_fabric.__dict__['date_time']) if unloadall == "None" and stdout_enable == "None" and stdout_enable_all == "None" and date_time == "None": print "mandatory option is missing\n" parser_fabric.print_help() exit(-1) do_work(str(opts_fabric.stdout_enable), str(opts_fabric.stdout_enable_all), str(opts_fabric.date_time), str(opts_fabric.unload), str(opts_fabric.unloadall), str(opts_fabric.fabric_name), str(opts_fabric.fabric_root), str(opts_fabric.module_name)) if __name__ == "__main__": main() lio-utils-3.1+git2.fd0b34fd/tcm-py/setup.py0000755000175000017500000000103311753136721016561 0ustar rrsrrs#!/usr/bin/python from distutils.core import setup long_desc="""Python CLI for controlling the generic target_core_mod/ConfigFS engine """ setup (name='tcm', version='4.1', description='CLI for controlling target_core_mod/ConfigFS', long_description=long_desc, author='Nicholas A. Bellinger', author_email='nab@linux-iscsi.org', url='http://linux-iscsi.org', license='GPL', py_modules=['tcm_dump', 'tcm_fileio','tcm_iblock','tcm_node','tcm_pscsi','tcm_ramdisk','tcm_loop','tcm_fabric'] ) lio-utils-3.1+git2.fd0b34fd/tcm-py/tcm_loop.py0000755000175000017500000001777411753136721017260 0ustar rrsrrs#!/usr/bin/python import os, sys import subprocess as sub import string import re from optparse import OptionParser tcm_loop_root = "/sys/kernel/config/target/loopback/" tcm_root = "/sys/kernel/config/target/core" def tcm_generate_naa_sas_address(): # Use NAA IEEE Registered Designator prefix, and append WWN UUID below sas_address = "naa.6001405" uuidgen_op = 'uuidgen' p = sub.Popen(uuidgen_op, shell=True, stdout=sub.PIPE).stdout uuid = p.readline() p.close() if not uuid: print "Unable to generate UUID using uuidgen, continuing anyway" sys.exit(1) val = uuid.rstrip(); sas_address += val[:10] sas_address = sas_address.replace('-','') return sas_address def tcm_loop_add_target_www(option, opt_str, value, parser): sas_target_address = tcm_generate_naa_sas_address(); sas_target_tpgt = str(value) def tcm_loop_del_target_wwn(option, opt_str, value, parser): sas_target_address = str(value[0]) sas_target_tpgt = str(value[1]) tpgt_dir = tcm_loop_root + sas_target_address + "/tpgt_" + sas_target_tpgt delete_op = "rmdir " + tpgt_dir ret = os.system(delete_op) if ret: print "Unable to remove configfs group: " + tpgt_dir naa_dir = tcm_loop_root + sas_target_address delete_op = "rmdir " + naa_dir ret = os.system(delete_op) if ret: print "Unable to remove configfs group: " + naa_dir else: print "Successfully removed NAA based SAS Target Address: " + naa_dir + "/" + tpgt_dir def tcm_loop_create_nexus(option, opt_str, value, parser): sas_target_address = tcm_generate_naa_sas_address(); sas_target_tpgt = str(value) sas_initiator_address = tcm_generate_naa_sas_address(); tpgt_dir = tcm_loop_root + sas_target_address + "/tpgt_" + sas_target_tpgt create_op = "mkdir -p " + tpgt_dir ret = os.system(create_op) if ret: print "Unable to create virtual Target Port: " + create_op sys.exit(1) # In TCM_Loop 4.x code, there is an nexus configfs attribute instead of # nexus configfs group nexus_dir = tpgt_dir + "/nexus" if os.path.isfile(nexus_dir): create_op = "echo " + sas_initiator_address + " > " + nexus_dir else: create_op = "mkdir -p " + nexus_dir + "/" + sas_initiator_address ret = os.system(create_op) if ret: print "Unable to create virtual SAS I_T Nexus: " + create_op sys.exit(1) else: print "Successfully created virtual SCSI I_T Nexus between TCM and Linux/SCSI HBA" print " SAS Target Address: " + sas_target_address print " SAS Initiator Address " + sas_initiator_address def tcm_loop_delete_nexus(option, opt_str, value, parser): sas_target_address = str(value[0]) sas_target_tpgt = str(value[1]) sas_initiator_address = ""; nexus_dir = tcm_loop_root + sas_target_address + "/tpgt_" + sas_target_tpgt + "/nexus" if os.path.isfile(nexus_dir): delete_op = "echo NULL > " + nexus_dir ret = os.system(delete_op) if ret: print "Unable to delete virtual SCSI I_T Nexus between TCM and Linux/SCSI HBA" sys.exit(1) print "Successfully deleted virtual SCSI I_T Nexus between TCM and Linux/SCSI HBA" return for nexus in os.listdir(nexus_dir): delete_op = "rmdir " + nexus_dir + "/" + nexus ret = os.system(delete_op) if ret: print "Unable to delete virtual SCSI I_T Nexus between TCM and Linux/SCSI HBA" sys.exit(1) print "Successfully deleted virtual SCSI I_T Nexus between TCM and Linux/SCSI HBA" return def tcm_loop_addlun(option, opt_str, value, parser): sas_target_address = str(value[0]) sas_target_tpgt = str(value[1]) sas_target_lun = str(value[2]) mkdir_op = "mkdir -p " + tcm_loop_root + sas_target_address + "/tpgt_" + sas_target_tpgt + "/lun/lun_" + sas_target_lun ret = os.system(mkdir_op) if ret: print "Unable to create SAS Target Port LUN configfs group: " + mkdir_op sys.exit(1) tcm_obj = str(value[3]); port_src = tcm_root + "/" + tcm_obj port_dst = tcm_loop_root + sas_target_address + "/tpgt_" + sas_target_tpgt + "/lun/lun_" + sas_target_lun + "/virtual_scsi_port" link_op = "ln -s " + port_src + " " + port_dst ret = os.system(link_op) if not ret: print "Successfully created SAS Target Port to local virtual SCSI Logical Unit" # FIXME Add tcm_loop_alua_check_secondary_md() # FIXME Add tcm_loop_alua_set_secondary_write_md() else: print "Unable to create SAS Target Port to local virtual SCSI Logical Unit" sys.exit(1) def tcm_loop_dellun(option, opt_str, value, parser): sas_target_address = str(value[0]) sas_target_tpgt = str(value[1]) sas_target_lun = str(value[2]) port_link = "" lun_dir = tcm_loop_root + sas_target_address + "/tpgt_" + sas_target_tpgt + "/lun/lun_" + sas_target_lun if not os.path.isdir(lun_dir): print "TCM_Loop lun_dir: " + lun_dir + " does not exist" sys.exit(1) # Locate the port symlink, skipping over the per TCM port alua_* attributes for port in os.listdir(lun_dir): port_link_tmp = lun_dir + "/" + port if not os.path.islink(port_link_tmp): continue port_link = port_link_tmp break if port_link == "": print "Active TCM_Loop port link does not exist!" sys.exit(1) ret = os.unlink(port_link) if ret: print "Unable to unlink port for virtual SCSI Logical Unit: " + port sys.exit(1) rmdir_op = "rmdir " + tcm_loop_root + sas_target_address + "/tpgt_" + sas_target_tpgt + "/lun/lun_" + sas_target_lun ret = os.system(rmdir_op) if ret: print "Unable to rmdir configfs group for virtual SCSI Logical Unit: " + port sys.exit(1) else: print "Succesfully deleted local virtual SCSI Logical Unit from SAS Target Port" def tcm_loop_unload(option, opt_str, value, parser): for sas_target_naa in os.listdir(tcm_loop_root): print "sas_target_naa: " + sas_target_naa if os.path.isfile(tcm_loop_root + sas_target_naa) == True: continue tpgt_dir = tcm_loop_root + sas_target_naa + "/" for sas_target_tpgt in os.listdir(tpgt_dir): if sas_target_tpgt == "fabric_statistics": continue print "sas_target_tpgt: " + sas_target_tpgt lun_dir = tpgt_dir + "/" + sas_target_tpgt + "/lun/" for sas_target_lun in os.listdir(lun_dir): print "sas_target_lun: " + sas_target_lun tpgt = sas_target_tpgt[5:] lun = sas_target_lun[4:] vals = [sas_target_naa, tpgt, lun] tcm_loop_dellun(None, None, vals, None) tpgt = sas_target_tpgt[5:] vals = [sas_target_naa, tpgt] tcm_loop_delete_nexus(None, None, vals, None) tcm_loop_del_target_wwn(None, None, vals, None) rmdir_op = "rmdir " + tcm_loop_root ret = os.system(rmdir_op) if ret: print "Unable to remove tcm_loop_root configfs group: " + tcm_loop_root sys.exit(1) rmmod_op = "rmmod tcm_loop" ret = os.system(rmmod_op) if ret: print "Unable to remove tcm_loop kernel module" sys.exit(1) print "Successfully removed tcm_loop kernel module" def main(): parser = OptionParser() parser.add_option("--delwwn", action="callback", callback=tcm_loop_del_target_wwn, nargs=2, type="string", dest="NAA_TARGET_WWN TPGT", help="Delete a SAS Virtual HBA by WWN+TPGT") parser.add_option("--createnexus", action="callback", callback=tcm_loop_create_nexus, nargs=1, type="string", dest="TPGT", help="Create a virtual SAS I_T Nexus using generated NAA WWN for SAS Address. This will create a new Linux/SCSI Host Bus Adapter for the I_T Nexus"); parser.add_option("--delnexus", action="callback", callback=tcm_loop_delete_nexus, nargs=2, type="string", dest="NAA_TARGET_WWN TPGT", help="Delete a virtual SAS I_T Nexus"); parser.add_option("--addlun", action="callback", callback=tcm_loop_addlun, nargs=4, type="string", dest="NAA_TARGET_WWN TPGT LUN HBA/DEV", help="Add virtual SCSI Linux to NAA Target/Initiator Sas Addresses") parser.add_option("--dellun", action="callback", callback=tcm_loop_dellun, nargs=3, type="string", dest="NAA_TARGET_WWN TPGT LUN", help="Delete Target SAS Port to virtual SCSI Logical unit mapping") parser.add_option("--unload", action="callback", callback=tcm_loop_unload, nargs=0, help="Shutdown all virtual SCSI LUNs and unload tcm_loop") (options, args) = parser.parse_args() if len(sys.argv) == 1: parser.print_help() sys.exit(0) elif not re.search('--', sys.argv[1]): lio_err("Unknown CLI option: " + sys.argv[1]) if __name__ == "__main__": main() lio-utils-3.1+git2.fd0b34fd/tcm-py/install.sh0000755000175000017500000000114511753136721017055 0ustar rrsrrs#!/bin/sh SITE_PACKAGES=`python ../get-py-modules-path.py` chmod a+x $SITE_PACKAGES/tcm_node.py chmod a+x $SITE_PACKAGES/tcm_dump.py chmod a+x $SITE_PACKAGES/tcm_loop.py chmod a+x $SITE_PACKAGES/tcm_fabric.py if [ ! -f /usr/sbin/tcm_node ]; then ln -s $SITE_PACKAGES/tcm_node.py /usr/sbin/tcm_node fi if [ ! -f /usr/sbin/tcm_dump ]; then ln -s $SITE_PACKAGES/tcm_dump.py /usr/sbin/tcm_dump fi if [ ! -f /usr/sbin/tcm_loop ]; then ln -s $SITE_PACKAGES/tcm_loop.py /usr/sbin/tcm_loop fi if [ ! -f /usr/sbin/tcm_fabric ]; then ln -s $SITE_PACKAGES/tcm_fabric.py /usr/sbin/tcm_fabric fi lio-utils-3.1+git2.fd0b34fd/tcm-py/tcm_fileio.py0000755000175000017500000000450611753136721017543 0ustar rrsrrs#!/usr/bin/python import os import subprocess as sub import string, re from optparse import OptionParser tcm_root = "/sys/kernel/config/target/core" def createvirtdev(path, params): # print "Calling fileio createvirtdev: path " + path cfs_path = tcm_root + "/" + path + "/" # print "Calling fileio createvirtdev: params " + str(params) fd_params = str(params) # Extract the udev_dev path from fd_dev_name= try: off = fd_params.index('fd_dev_name=') off += 12 file_tmp = fd_params[off:] file = file_tmp.split(',') except IOError, msg: print "Unable to locate fd_dev_name= parameter key" return -1 # Set UDEV path if struct file is pointing to an underlying struct block_device if re.search('/dev/', file[0]): udev_path = file[0] set_udev_path_op = "echo -n " + udev_path + " > " + cfs_path + "udev_path" ret = os.system(set_udev_path_op) if ret: print "pSCSI: Unable to set udev_path in " + cfs_path + " for: " + udev_path return -1 control_opt = "echo -n " + params[0] + " > " + cfs_path + "control" # print "control_opt: " + control_opt ret = os.system(control_opt) if ret: print "FILEIO: createvirtdev failed for control_opt with " + params[0] return -1 enable_opt = "echo 1 > " + cfs_path + "enable" # print "Calling enable_opt " + enable_opt ret = os.system(enable_opt) if ret: print "FILEIO: createvirtdev failed for enable_opt with " + params[0] return -1 def fd_freevirtdev(): pass def fd_get_params(path): # Reference by udev_path if available udev_path_file = path + "/udev_path" p = os.open(udev_path_file, 0) value = os.read(p, 1024) if re.search('/dev/', value): os.close(p) # Append a FILEIO size of ' 0', as struct block_device sector count is autodetected by TCM return "fd_dev_name=" + value.rstrip() + ",fd_dev_size=0" os.close(p) info_file = path + "/info" p = open(info_file, 'rU') try: value = p.read(1024) except IOError, msg: p.close() return p.close() off = value.index('File: ') off += 6 fd_dev_name_tmp = value[off:] fd_dev_name = fd_dev_name_tmp.split(' ') off = value.index(' Size: ') off += 7 fd_dev_size_tmp = value[off:] fd_dev_size = fd_dev_size_tmp.split(' ') params = "fd_dev_name=" + fd_dev_name[0] + ",fd_dev_size=" + fd_dev_size[0] # fd_dev_name= and fd_dev_size= parameters for tcm_node --createdev return params lio-utils-3.1+git2.fd0b34fd/tcm-py/tcm_pscsi.py0000755000175000017500000001213411753136721017411 0ustar rrsrrs#!/usr/bin/python import os import subprocess as sub import string, re from optparse import OptionParser tcm_root = "/sys/kernel/config/target/core" def print_lsscsi(option, opt_str, value, parser): command = "lsscsi" p = sub.Popen(command,shell=True, stdout=sub.PIPE).stdout while 1: line = p.readline() if not line: break print line, def pscsi_get_hba_prefix(arg): path = "/sys/kernel/config/target/core/pscsi_" + arg return path def pscsi_scan_lsscsi(option, opt_str, value, parser): command = "lsscsi -H" p = sub.Popen(command,shell=True, stdout=sub.PIPE).stdout while 1: line = p.readline() if not line: break line.split() host_id = line[1] print "SCSI Host ID: " + host_id cfs_path = pscsi_get_hba_prefix(host_id) if (os.path.isdir(cfs_path)): print "pSCSI HBA already registered, skipping" continue print cfs_path ret = os.mkdir(cfs_path) print "os.path.mkdir ret: " + str(ret) if not ret: print "Successfully added ConfigFS path " + cfs_path def createvirtdev(path, params): # print "Calling pscsi createvirtdev: path " + path cfs_path = tcm_root + "/" + path + "/" # print "Calling pscsi createvirtdev: params " + str(params) pscsi_params = params[0] # print pscsi_params # Exract HCTL from sysfs and set udev_path if re.search('/dev/', pscsi_params): udev_path = pscsi_params.rstrip() if re.search('/dev/disk/', udev_path): udev_op = "/bin/ls -l " + udev_path p = sub.Popen(udev_op, shell=True, stdout=sub.PIPE).stdout if not p: print "pSCSI: Unable to locate scsi_device from udev_path: " + udev_path return -1 line = p.readline() out = line.split(' ../../'); p.close() if not out: print "pSCSI: Unable to locate scsi_device from udev_path: " + udev_path return -1 scsi_dev = out[1].rstrip() elif re.search('/dev/s', udev_path): out = udev_path.split('/dev/') scsi_dev = out[1] else: print "pSCSI: Unable to locate scsi_device from udev_path: " + udev_path return -1 # Convert scdX to sr0 for TYPE_ROM in /sys/block/ if re.search('scd', scsi_dev): scsi_dev = scsi_dev.replace('scd', 'sr'); if not os.path.isdir("/sys/block/" + scsi_dev + "/device/"): print "pSCSI: Unable to locate scsi_device from udev_path: " + udev_path return -1 scsi_dev_sysfs = "/sys/block/" + scsi_dev + "/device" udev_op = "/bin/ls -l " + scsi_dev_sysfs p = sub.Popen(udev_op, shell=True, stdout=sub.PIPE).stdout if not p: print "pSCSI: Unable to locate scsi_device from udev_path: " + udev_path return -1 line = p.readline() out = line.split('/') p.close() scsi_hctl_tmp = out[len(out)-1] scsi_hctl = scsi_hctl_tmp.split(':') scsi_host_id = scsi_hctl[0] scsi_channel_id = scsi_hctl[1] scsi_target_id = scsi_hctl[2] scsi_lun_id = scsi_hctl[3] print "pSCSI: Referencing HCTL " + out[1].rstrip() + " for udev_path: " + udev_path set_udev_path_op = "echo -n " + udev_path + " > " + cfs_path + "udev_path" ret = os.system(set_udev_path_op) if ret: print "pSCSI: Unable to set udev_path in " + cfs_path + " for: " + udev_path return -1 pscsi_params = "scsi_host_id=" + scsi_host_id + ",scsi_channel_id=" + scsi_channel_id + ",scsi_target_id=" + scsi_target_id + ",scsi_lun_id=" + scsi_lun_id.rstrip() control_opt = "echo -n " + pscsi_params + " > " + cfs_path + "control" # print "Calling control_opt " + control_opt ret = os.system(control_opt) if ret: print "pSCSI: createvirtdev failed for control_opt with " + pscsi_params return -1 enable_opt = "echo 1 > " + cfs_path + "enable" # print "Calling enable_opt " + enable_opt ret = os.system(enable_opt) if ret: print "pSCSI: createvirtdev failed for enable_opt with " + pscsi_params return -1 def pscsi_freevirtdev(): pass def pscsi_get_params(path): # Reference by udev_path if available udev_path_file = path + "/udev_path" p = os.open(udev_path_file, 0) value = os.read(p, 1024) if re.search('/dev/', value): os.close(p) return value.rstrip() os.close(p) info_file = path + "/info" p = open(info_file, 'rU') try: value = p.read(1024) except IOError, msg: p.close() return p.close() off = value.index('Channel ID: ') off += 12 channel_id_tmp = value[off:] channel_id = channel_id_tmp.split(' ') off = value.index('Target ID: ') off += 11 target_id_tmp = value[off:] target_id = target_id_tmp.split(' ') off = value.index('LUN: ') off += 5 lun_id_tmp = value[off:] lun_id = lun_id_tmp.split(' ') params = "" try: off = value.index('Host ID: ') except ValueError: params = "" else: off += 9 host_id_tmp = value[off:] host_id = host_id_tmp.split(' ') host_id = host_id[0].rstrip() if host_id != "PHBA": params += "scsi_host_id=" + host_id[0] + "," params += "scsi_channel_id=" + channel_id[0] + ",scsi_target_id=" + target_id[0] + ",scsi_lun_id=" + lun_id[0].rstrip() # scsi_channel_id=, scsi_target_id= and scsi_lun_id= reference for tcm_node --createdev return params #parser = OptionParser() #parser.add_option("-s", "--scan", action="callback", callback=pscsi_scan_lsscsi, # default=False, help="Scan and register pSCSI HBAs with TCM/ConfigFS") #parser.parse_args() # lio-utils-3.1+git2.fd0b34fd/tcm-py/tcm_ramdisk.py0000755000175000017500000000246411753136721017727 0ustar rrsrrs#!/usr/bin/python import os import subprocess as sub import string, re from optparse import OptionParser tcm_root = "/sys/kernel/config/target/core" def createvirtdev(path, params): # print "Calling ramdisk createvirtdev: path " + path cfs_path = tcm_root + "/" + path + "/" # print "Calling ramdisk createvirtdev: params " + str(params) rd_pages = params[0] rd_params = "rd_pages=" + rd_pages # print "rd_params: " + rd_params control_opt = "echo -n " + rd_params.rstrip() + " > " + cfs_path + "/control" # print "control_opt: " + control_opt ret = os.system(control_opt) if ret: print "RAMDISK: createvirtdev failed for control_opt with " + rd_params return -1 enable_opt = "echo 1 > " + cfs_path + "enable" # print "Calling enable_opt " + enable_opt ret = os.system(enable_opt) if ret: print "RAMDISK: createvirtdev failed for enable_opt with " + rd_params return -1 def rd_freevirtdev(): pass def rd_get_params(path): info_file = path + "/info" p = open(info_file, 'rU') try: value = p.read(1024) except IOError, msg: p.close() return p.close() off = value.index('PAGE_SIZE: ') off += 11 # Skip over "PAGE_SIZE: " rd_pages_tmp = value[off:] rd_pages = rd_pages_tmp.split('*') params = "rd_pages=" + rd_pages[0] # rd_pages= parameter for tcm_node --createdev return rd_pages[0] lio-utils-3.1+git2.fd0b34fd/ostype.pm0000644000175000017500000001625711753136721015532 0ustar rrsrrssub ostype { my $root = shift @_; my $keyfile = "$root/etc/issue"; my $txt=`cat $keyfile`; my $rval; $rval->{ARCH}="$ENV{'ARCH'}"; $rval->{RELEASE}="$ENV{'RELEASE'}"; if (($root ne "") && ($root ne "/")) { my $atxt = $txt; $atxt =~ s/\n/ /g; $rval->{ARCH} = $1 if (($rval->{ARCH} eq "") && (lc ($atxt) =~ /arch (\w+)/)); $rval->{RELEASE} = $1 if (($rval->{RELEASE} eq "") && (lc ($atxt) =~ /release ([\w.]+)/)); } if ($rval->{RELEASE} eq "") { $rval->{RELEASE} = `uname -r`; $rval->{RELEASE} =~ s/\n+//g; } foreach my $key (glob("$root/lib/modules/*/kernel/arch/*")) { $key =~ s/^$root\/lib\/modules\///; my($release,$kernel,$archword,$arch) = split (/\//, $key); push @{$rval->{RELEASES}}, $release; } if ($rval->{ARCH} eq "") { my $kname = `uname -m`; my $uname = `file $root/bin/ls`; $uname =~ s/\n+//g; $rval->{ARCH}="x86_64" if ($uname =~ /64.*(AMD|Intel|x86-64)/); $rval->{ARCH}="i386" if ($uname =~ /32.*(AMD|Intel)/); $rval->{ARCH}="ppc" if ($uname =~ /32.*(PowerPC)/ && !$kname =~ /ppc64/); $rval->{ARCH}="powerpc" if ($uname =~ /64.*(PowerPC)/ || $kname =~ /ppc64/); $rval->{ARCH}="alpha" if ($uname =~ /64.*(Alpha)/); } if ($rval->{ARCH} eq "") { die "Unknown architecture: could not continue --- $uname"; } $rval->{LIBL}="ia32" if ($rval->{ARCH} eq "i386"); $rval->{LIBL}="x86_64" if ($rval->{ARCH} eq "x86_64"); $rval->{KERNEL} = "24" if ($rval->{RELEASE} =~ /2\.4/); $rval->{KERNEL} = "26" if ($rval->{RELEASE} =~ /2\.6/); if (lc($txt) =~/red.*hat.*release\s+(\w+)\s+\(\w+\s+update\s+(\w+)/ || lc($txt) =~/red.*hat.*release\s+(\w+)/) { $rval->{DISTRO}="REDHAT"; $rval->{SYSTEM}="RedHat-R$1"; $rval->{KERNEL_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="$rval->{KERNEL_DIR}"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_DIR}/include"; $rval->{OSTYPE}="LINUX"; if ("$2" eq "") { $rval->{SYSTEM}.="-Gold"; } else { $rval->{SYSTEM}.="-Update-\u$2"; } $rval->{RPM_DIR}="/usr/src/redhat"; } elsif (lc($txt) =~/suse.*enterprise.*server\s+(\w+) / || lc($txt) =~/suse/) { my $release = $1; my ($kernel) = glob("$root/lib/modules/*-{default,smp,desktop}"); $kernel = basename($kernel); $kernel =~ s/-(default|smp|desktop)$//; unless ($ENV{'KERNEL'} eq "") { $kernel = $ENV{'KERNEL'}; } if (lc($txt) =~/opensuse/) { $rval->{SYSTEM}="OPENSUSE$release-$kernel"; } else { $rval->{SYSTEM}="SLES$release-$kernel"; } $rval->{RPM_DIR}="/usr/src/packages"; $rval->{DISTRO}="SUSE"; $rval->{OSTYPE}="LINUX"; $rval->{KERNEL_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_SOURCE_DIR}/include"; } elsif (lc($txt) =~/centos.*release\s+(\d+)\.(\d+)\s+\((\w+)/) { $rval->{SYSTEM}="CentOS-R$1.$2-\u$3"; $rval->{RPM_DIR}="/usr/src/redhat"; $rval->{DISTRO}="CENTOS"; $rval->{OSTYPE}="LINUX"; $rval->{KERNEL_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="/lib/modules/$rval->{RELEASE}/source"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_SOURCE_DIR}/include"; } elsif (lc($txt) =~/centos.*release\s+(\d+)\s+\((\w+)/) { $rval->{SYSTEM}="CentOS-R$1-$2"; $rval->{RPM_DIR}="/usr/src/redhat"; $rval->{DISTRO}="CENTOS"; $rval->{OSTYPE}="LINUX"; $rval->{KERNEL_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="/lib/modules/$rval->{RELEASE}/source"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_SOURCE_DIR}/include"; } elsif (lc($txt) =~/scientific.*linux.*release\s+(\d+)\.(\d+)\s+\((\w+)/) { $rval->{SYSTEM}="SL-R$1.$2-\u$3"; $rval->{RPM_DIR}="/root/rpmbuild"; $rval->{DISTRO}="SL"; $rval->{OSTYPE}="LINUX"; $rval->{KERNEL_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="/lib/modules/$rval->{RELEASE}/source"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_SOURCE_DIR}/include"; } elsif (lc($txt) =~/fedora.*(?:core)?.*release\s+(\w+)\s+\((\w+)/) { $rval->{SYSTEM}="FedoraCore-R$1-\u$2"; $rval->{RPM_DIR}="/usr/src/redhat"; $rval->{DISTRO}="FEDORA"; $rval->{OSTYPE}="LINUX"; $rval->{KERNEL_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="/lib/modules/$rval->{RELEASE}/source"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_SOURCE_DIR}/include"; } elsif ( -e "$root/etc/make.profile") { $rval->{DISTRO}="GENTOO"; $rval->{RPM_DIR}="/usr/src/redhat"; $rval->{OSTYPE}="LINUX"; my $link = readlink("$root/etc/make.profile"); if ($link =~ /.*?([\w\.]+)$/) { $rval->{SYSTEM} = "Gentoo-$1"; } $rval->{KERNEL_DIR}="$root/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="$rval->{KERNEL_DIR}"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_DIR}/include"; } elsif (lc($txt) =~/debian/) { $rval->{DISTRO}="DEBIAN"; $rval->{RPM_DIR}="/usr/src/redhat"; $rval->{OSTYPE}="LINUX"; $rval->{KERNEL_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_SOURCE_DIR}/include"; } elsif (lc($txt) =~ /ubuntu/) { $rval->{DISTRO}="UBUNTU"; $rval->{RPM_DIR}="/usr/src/redhat"; $rval->{OSTYPE}="LINUX"; $rval->{KERNEL_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_SOURCE_DIR}/include"; } elsif (lc($txt) =~ /mandrake|pelco/) { $rval->{SYSTEM}="Mandrake-R10.0"; $rval->{RPM_DIR}="/usr/src/RPM"; $rval->{DISTRO}="MANDRAKE"; $rval->{OSTYPE}="LINUX"; $rval->{KERNEL_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="/lib/modules/$rval->{RELEASE}/source"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_SOURCE_DIR}/include"; } elsif (lc($txt) =~/elinos release (.*)/) { $rval->{SYSTEM}="ELinos-V$1"; $rval->{DISTRO}="ELINOS"; $rval->{RPM_DIR}="/usr/src/redhat"; $rval->{OSTYPE}="LINUX"; $rval->{KERNEL_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_SOURCE_DIR}="/lib/modules/$rval->{RELEASE}/build"; $rval->{KERNEL_INCLUDE_DIR}="$rval->{KERNEL_SOURCE_DIR}/include"; $rval->{NO_RPM}=1; } else { die "No distribution found in $txt\n"; } $rval->{KERNEL_VERSION_INFO}=$rval->{OSTYPE} . "_KERNEL_" . $rval->{KERNEL}; $rval->{BASENAME}="$rval->{SYSTEM}.$rval->{ARCH}"; return $rval; } sub report_time { my $prompt = shift @_; my $start_time = shift @_; my $duration = int(time()) - int($start_time); my $seconds = $duration % 60; $duration /= 60; my $minutes = $duration % 60; $duration /= 60; my $hours = $duration % 24; $duration /= 24; my $days = $duration; print $prompt; print_time ($days, "day") if (int($days) > 0); print_time ($hours, "hour") if (int($hours) > 0); print_time ($minutes, "minute") if (int($minutes) > 0); print_time ($seconds, "second"); print "\n"; } sub print_time { my ($amt, $msg) = @_; if ($amt == 1) { print "$amt $msg "; } else { print "$amt $msg" ."s "; } } 1; lio-utils-3.1+git2.fd0b34fd/conf/0000755000175000017500000000000011753136721014563 5ustar rrsrrslio-utils-3.1+git2.fd0b34fd/conf/tcm_start.default0000644000175000017500000000003111753136721020123 0ustar rrsrrsmodprobe target_core_mod lio-utils-3.1+git2.fd0b34fd/conf/lio_start.default0000644000175000017500000000003711753136721020131 0ustar rrsrrs# placeholder for lio_start.sh lio-utils-3.1+git2.fd0b34fd/mib-modules/0000755000175000017500000000000011753136721016053 5ustar rrsrrslio-utils-3.1+git2.fd0b34fd/mib-modules/README0000644000175000017500000001121611753136721016734 0ustar rrsrrsiSCSI Target MIB Support: Net-SNMP is an SNMP Agent and a collection of SNMP applications available with all Linux distributions. MIB support for the v3.0 Target_Core_Mod SCSI target and v3.0 Linux-iSCSI.org Target fabric module is provided using dynamic load module (dlmod) functionality of the Net-SNMP Agent. See www.net-snmp.org and man pages for info on Net-SNMP. Net-SNMP Support: The Linux OS distributions supported by the TCM-SCSI and LIO-iSCSI target stack come with various versions of Net-SNMP ranging from 5.0.9 to 5.1.3.1. The iscsiTargetMib module is built for the native version of Net-SNMP of each Linux distribution. However, the iscsiTargetMib module built for net-snmp-5.1 and higher are upward compatible with newer versions of Net-SNMP. The iscsiTargetMib module built for net-snmp-5.0.9 is not upward compatible. SNMP Versions supported: v1, v2c and v3 MIB Support: The following standard MIBs are supported: MIB Files IETF Drafts Level of Support ------------------------------------------------------------------------ LIO-ISCSI-MIB.txt draft-ietf-ips-iscsi-mib-11.txt Full support LIO-IPS-AUTH-MIB.txt draft-ietf-ips-auth-mib-08.txt Partial support LIO-SCSI-MIB.txt RFC 4455 Partial support a) LIO-ISCSI-MIB: Tables Supported: iscsiInstanceAttributesTable iscsiInstanceSsnErrorStatsTable iscsiPortalAttributesTable iscsiTgtPortalAttributesTable iscsiNodeAttributesTable iscsiTargetAttributesTable iscsiTargetLoginStatsTable iscsiTargetLogoutStatsTable iscsiTgtAuthAttributesTable iscsiSessionAttributesTable iscsiSessionStatsTable iscsiSessionCxnErrorStatsTable iscsiConnectionAttributesTable Traps/Notifications supported: iscsiTgtLoginFailure iscsiInstSessionFailure b) LIO-SCSI-MIB: Tables Supported: scsiInstanceTable scsiDeviceTable scsiPortTable scsiTransportTable scsiTgtDevTable scsiTgtPortTable scsiAuthorizedIntrTable scsiAttIntrPortTable scsiLuTable Traps/Notifications supported: scsiTgtDeviceStatusChanged Note: This trap is generated based on the software status maintained by the iSCSI stack and mapped to scsiTgtDeviceStatus as follows: available: Device is assigned to target portal group abnormal: Device is deactivated, shutdown or offline unknown: Software status could not be mapped c) LIO-IPS-AUTH-MIB: Tables Supported: ipsAuthInstanceAttributesTable ipsAuthIdentAttributesTable ipsAuthIdentNameAttributesTable ipsAuthCredentialAttributesTable ipsAuthCredChapAttributesTable Notes: 1. Initiator MIBs are not supported. 2. Writes(SETs) are not supported. They are not required for standard compliance. 3. All MIBs are placed under LIO's private branch instead of mib-2 branch because the top level OIDs for ISCSI MIB and IPS AUTH MIB have not been assigned by IANA yet. FIXME --nab Installation of Target MIB module and MIB files: The Target MIB module and the MIB files are included in the lio-mibs rpm and installed in the following location as part of the Target installation: Target MIB module (iscsiTargetMib.so): /usr/lib/snmp/dlmod Target MIB files (LIO-IPS-AUTH-MIB.txt, LIO-ISCSI-MIB.txt, LIO-SCSI-MIB.txt): /usr/share/snmp/mibs/ Config changes required for loading the target MIB module are also made to the Net-SNMP config file as part of the installation. Location of the config files: RedHat, CentOS, FC: /etc/snmpd/snmpd.conf SUSE: /etc/snmpd.conf Starting the Net-SNMP agent: > /etc/init.d/snmpd start Check /var/log/snmpd.log to see whether loading of the target mib module was successful. You should see the following messages: NET-SNMP version 5.1.2 Linux-iSCSI.org Target Mib Module version 0.0.2 If you don't see the following messages, check the Net-SNMP agent configure file to ensure that the following line has been added by the installation process: dlmod iscsiTargetMib /usr/local/lib/snmp/dlmod/iscsiTargetMib.so Testing: The Net-SNMP includes several applications which may be used for testing the target mib support. A couple of them are listed below. See the man pages for snmpcmd, snmpget, snmpgetnext, snmpwalk, snmptrapd, etc. for more information. Note: Add the following shell variables to your environment for the Net-SNMP applications to decode the MIB OIDs. MIBDIRS=/usr/share/snmp/mibs MIBS=ALL Alternatively, add these variables to the snmp.conf file. See the man page for snmp.conf. List all iSCSI related MIB objects: > snmpwalk -v1 -c public localhost lio Receive Traps and display them: > snmptrapd -f Use the Net-SNMP applications and/or an SNMP manager to retrieve each object supported by the Target and ensure that the values returned by the agent are correct. lio-utils-3.1+git2.fd0b34fd/mib-modules/Makefile0000644000175000017500000000174511753136721017522 0ustar rrsrrs#CWD=$(shell pwd) #AUTOCONFIG=$(CWD)/../autoconfig --write-to-file --current-directory=$(CWD) #include $(shell $(AUTOCONFIG)) # # Makefile for dynamically loadable module for the Target Mib # TOPDIR = /usr MIBDIR = $(TOPDIR)/share/snmp/mibs DLMODDIR = $(TOPDIR)/lib/snmp/dlmod INCLDIR = $(TOPDIR)/include/net-snmp MIBS = LIO-IPS-AUTH-MIB.txt LIO-ISCSI-MIB.txt LIO-SCSI-MIB.txt TARG = iscsiTargetMib.so OBJS = iscsiTargetMib.o iscsiMib.o scsiMib.o ipsAuthMib.o \ iscsiAuthData.o CC = gcc CFLAGS = -I$(INCLDIR) -I$(INCLDIR)/agent -I$(INCLDIR)/agent/mibgroup -shared -fPIC CFLAGS += -I../include -Wall -Werror #CFLAGS +=$(AUTO_CFLAGS) LD = gcc -shared INSTALL = install all: $(TARG) %.o: %.c *.h $(CC) $(CFLAGS) -o $@ -c $< $(TARG): $(OBJS) $(LD) -o $@ $(OBJS) clean: rm -f $(OBJS) $(TARG) install: all mkdir -p $(DESTDIR)/$(DLMODDIR) $(INSTALL) $(TARG) $(DESTDIR)/$(DLMODDIR) mkdir -p $(DESTDIR)/$(MIBDIR) (cd mibs ; $(INSTALL) -m 644 $(MIBS) $(DESTDIR)/$(MIBDIR)) lio-utils-3.1+git2.fd0b34fd/mib-modules/snmpd.conf.test0000644000175000017500000000045211753136721021022 0ustar rrsrrs# A trivial net-snmp agent configuration for testing only syslocation Server Room syscontact Sysadmin (root@localhost) rocommunity public trapcommunity public #rwcommunity secret trapsink localhost # Combined MIB Module for iSCSI Target dlmod iscsiTargetMib /usr/lib/snmp/dlmod/iscsiTargetMib.so lio-utils-3.1+git2.fd0b34fd/mib-modules/common.h0000644000175000017500000000145611753136721017522 0ustar rrsrrs/* * Copyright (c) 2006 SBE, Inc. * Copyright (c) 2009 Linux-iSCSI.org * * 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. */ #ifndef COMMON_H #define COMMON_H #ifdef NETSNMP_CACHE_HANDLER_H #define HAVE_CACHE_HANDLER 1 #endif #ifdef CACHE_H /* v5.1 */ #define HAVE_CACHE_HANDLER 1 #endif #if !HAVE_CACHE_HANDLER typedef void * netsnmp_cache; #endif #define OID_LIO 1,3,6,1,4,1,1055 #define OID_LIO_ISCSI_PRODUCT OID_LIO,10 #define OID_LIO_ISCSI_MIB OID_LIO_ISCSI_PRODUCT,1 #define OID_LIO_IPS_AUTH_MIB OID_LIO_ISCSI_PRODUCT,2 #define OID_LIO_SCSI_MIB OID_LIO_ISCSI_PRODUCT,3 #endif /* COMMON_H */ lio-utils-3.1+git2.fd0b34fd/mib-modules/scsiMib.h0000644000175000017500000002630611753136721017624 0ustar rrsrrs/* * Copyright (c) 2006 SBE, Inc. * Copyright (c) 2009-2011 Linux-iSCSI.org * * 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. */ #ifndef SCSIMIB_H #define SCSIMIB_H #define SCSI_MAX_NAME_LEN 262 #define SCSI_ROLE_TARGET (1 << 7) #define SCSI_ROLE_INITIATOR (1 << 6) #define SCSI_TRANSPORT_INDEX 1 /* Device status */ #define SCSI_DEV_STATUS_UNKNOWN 1 #define SCSI_DEV_STATUS_AVAILABLE 2 #define SCSI_DEV_STATUS_BROKEN 3 #define SCSI_DEV_STATUS_READYING 4 #define SCSI_DEV_STATUS_ABNORMAL 5 #define SCSI_DEV_STATUS_NONADDRFAILURE 6 #define SCSI_DEV_STATUS_NONADDRFAILREADYING 7 #define SCSI_DEV_STATUS_NONADDRFAILABNORMAL 8 /* LU status */ #define SCSI_LU_STATUS_UNKNOWN 1 #define SCSI_LU_STATUS_AVAILABLE 2 #define SCSI_LU_STATUS_NOTAVAILABLE 3 #define SCSI_LU_STATUS_BROKEN 4 #define SCSI_LU_STATUS_READYING 5 #define SCSI_LU_STATUS_ABNORMAL 6 /* LU state bit */ #define SCSI_LU_STATE_DATALOST 0 #define SCSI_LU_STATE_DYNAMICREGONFIG 1 #define SCSI_LU_STATE_EXPOSED 2 #define SCSI_LU_STATE_FRACTIONALLYEXPOSED 3 #define SCSI_LU_STATE_PARTIALLYEXPOSED 4 #define SCSI_LU_STATE_PROTECTEDREBUILD 5 #define SCSI_LU_STATE_PROTECTIONDISABLED 6 #define SCSI_LU_STATE_REBUILD 7 #define SCSI_LU_STATE_RECALCULATE 8 #define SCSI_LU_STATE_SPARCEINUSE 9 #define SCSI_LU_STATE_VERIFYINPROGRESS 10 /* * Instance Table */ void initialize_table_scsiInstanceTable(void); Netsnmp_Node_Handler scsiInstanceTable_handler; Netsnmp_First_Data_Point scsiInstanceTable_get_first_data_point; Netsnmp_Next_Data_Point scsiInstanceTable_get_next_data_point; int scsiInstanceTable_load(netsnmp_cache *cache, void *vmagic); void scsiInstanceTable_free(netsnmp_cache *cache, void *vmagic); /* column number definitions for table scsiInstanceTable */ #define COLUMN_SCSIINSTINDEX 1 #define COLUMN_SCSIINSTALIAS 2 #define COLUMN_SCSIINSTSOFTWAREINDEX 3 #define COLUMN_SCSIINSTVENDORVERSION 4 #define COLUMN_SCSIINSTSCSINOTIFICATIONSENABLE 5 #define COLUMN_SCSIINSTSTORAGETYPE 6 /* Data structure for row entry */ struct scsiInstanceTable_entry { u_long scsiInstIndex; char scsiInstAlias[80]; char old_scsiInstAlias[80]; long scsiInstSoftwareIndex; char scsiInstVendorVersion[80]; long scsiInstScsiNotificationsEnable; long scsiInstStorageType; struct scsiInstanceTable_entry *next; }; /* * Device Table */ void initialize_table_scsiDeviceTable(void); Netsnmp_Node_Handler scsiDeviceTable_handler; Netsnmp_First_Data_Point scsiDeviceTable_get_first_data_point; Netsnmp_Next_Data_Point scsiDeviceTable_get_next_data_point; int scsiDeviceTable_load(netsnmp_cache *cache, void *vmagic); void scsiDeviceTable_free(netsnmp_cache *cache, void *vmagic); /* column number definitions for table scsiDeviceTable */ #define COLUMN_SCSIDEVICEINDEX 1 #define COLUMN_SCSIDEVICEALIAS 2 #define COLUMN_SCSIDEVICEROLE 3 #define COLUMN_SCSIDEVICEPORTNUMBER 4 /* Data structure for row entry */ struct scsiDeviceTable_entry { u_long scsiInstIndex; u_long scsiDeviceIndex; char scsiDeviceAlias[80]; char scsiDeviceRole; u_long scsiDevicePortNumber; struct scsiDeviceTable_entry *next; }; /* * Port Table */ void initialize_table_scsiPortTable(void); Netsnmp_Node_Handler scsiPortTable_handler; Netsnmp_First_Data_Point scsiPortTable_get_first_data_point; Netsnmp_Next_Data_Point scsiPortTable_get_next_data_point; int scsiPortTable_load(netsnmp_cache *cache, void *vmagic); void scsiPortTable_free(netsnmp_cache *cache, void *vmagic); /* column number definitions for table scsiPortTable */ #define COLUMN_SCSIPORTINDEX 1 #define COLUMN_SCSIPORTROLE 2 #define COLUMN_SCSIPORTTRANSPORTPTR 3 #define COLUMN_SCSIPORTBUSYSTATUSES 4 /* Data structure for row entry */ struct scsiPortTable_entry { u_long scsiInstIndex; u_long scsiDeviceIndex; u_long scsiPortIndex; u_char scsiPortRole; oid scsiPortTransportPtr[MAX_OID_LEN]; int scsiPortTransportPtr_len; u_long scsiPortBusyStatuses; struct scsiPortTable_entry *next; }; /* * Transport Table */ void initialize_table_scsiTransportTable(void); Netsnmp_Node_Handler scsiTransportTable_handler; Netsnmp_First_Data_Point scsiTransportTable_get_first_data_point; Netsnmp_Next_Data_Point scsiTransportTable_get_next_data_point; int scsiTransportTable_load(netsnmp_cache *cache, void *vmagic); void scsiTransportTable_free(netsnmp_cache *cache, void *vmagic); /* column number definitions for table scsiTransportTable */ #define COLUMN_SCSITRANSPORTINDEX 1 #define COLUMN_SCSITRANSPORTTYPE 2 #define COLUMN_SCSITRANSPORTPOINTER 3 #define COLUMN_SCSITRANSPORTDEVNAME 4 /* Data structure for row entry */ struct scsiTransportTable_entry { u_long scsiInstIndex; u_long scsiDeviceIndex; u_long scsiTransportIndex; oid scsiTransportType[MAX_OID_LEN]; int scsiTransportType_len; oid scsiTransportPointer[MAX_OID_LEN]; int scsiTransportPointer_len; char scsiTransportDevName[SCSI_MAX_NAME_LEN]; struct scsiTransportTable_entry *next; }; /* * Target Device Table */ void initialize_scsiTgtDevTable(void); void initialize_table_scsiTgtDevTable(void); Netsnmp_Node_Handler scsiTgtDevTable_handler; Netsnmp_First_Data_Point scsiTgtDevTable_get_first_data_point; Netsnmp_Next_Data_Point scsiTgtDevTable_get_next_data_point; void scsiTgtDevTable_load(unsigned int clientreg, void *clientarg); /* column number definitions for table scsiTgtDevTable */ #define COLUMN_SCSITGTDEVNUMBEROFLUS 1 #define COLUMN_SCSITGTDEVICESTATUS 2 #define COLUMN_SCSITGTDEVNONACCESSIBLELUS 3 #define COLUMN_SCSITGTDEVRESETS 4 /* Data structure for row entry */ struct scsiTgtDevTable_entry { u_long scsiInstIndex; u_long scsiDeviceIndex; u_long scsiTgtDevNumberOfLUs; long scsiTgtDeviceStatus; u_long scsiTgtDevNonAccessibleLUs; u_long scsiTgtDevResets; struct scsiTgtDevTable_entry *next; }; /* * Target Port Table */ void initialize_table_scsiTgtPortTable(void); Netsnmp_Node_Handler scsiTgtPortTable_handler; Netsnmp_First_Data_Point scsiTgtPortTable_get_first_data_point; Netsnmp_Next_Data_Point scsiTgtPortTable_get_next_data_point; int scsiTgtPortTable_load(netsnmp_cache *cache, void *vmagic); void scsiTgtPortTable_free(netsnmp_cache *cache, void *vmagic); /* column number definitions for table scsiTgtPortTable */ #define COLUMN_SCSITGTPORTNAME 1 #define COLUMN_SCSITGTPORTIDENTIFIER 2 #define COLUMN_SCSITGTPORTINCOMMANDS 3 #define COLUMN_SCSITGTPORTWRITTENMEGABYTES 4 #define COLUMN_SCSITGTPORTREADMEGABYTES 5 #define COLUMN_SCSITGTPORTHSINCOMMANDS 6 /* Data structure for row entry */ struct scsiTgtPortTable_entry { u_long scsiInstIndex; u_long scsiDeviceIndex; u_long scsiPortIndex; char scsiTgtPortName[SCSI_MAX_NAME_LEN]; char scsiTgtPortIdentifier[SCSI_MAX_NAME_LEN]; u_long scsiTgtPortInCommands; u_long scsiTgtPortWrittenMegaBytes; u_long scsiTgtPortReadMegaBytes; U64 scsiTgtPortHSInCommands; struct scsiTgtPortTable_entry *next; }; /* * Authorized Initiator Table */ void initialize_table_scsiAuthorizedIntrTable(void); Netsnmp_Node_Handler scsiAuthorizedIntrTable_handler; Netsnmp_First_Data_Point scsiAuthorizedIntrTable_get_first_data_point; Netsnmp_Next_Data_Point scsiAuthorizedIntrTable_get_next_data_point; int scsiAuthorizedIntrTable_load(netsnmp_cache *cache, void *vmagic); void scsiAuthorizedIntrTable_free(netsnmp_cache *cache, void *vmagic); /* column number definitions for table scsiAuthorizedIntrTable */ #define COLUMN_SCSIAUTHINTRTGTPORTINDEX 1 #define COLUMN_SCSIAUTHINTRINDEX 2 #define COLUMN_SCSIAUTHINTRDEVORPORT 3 #define COLUMN_SCSIAUTHINTRNAME 4 #define COLUMN_SCSIAUTHINTRLUNMAPINDEX 5 #define COLUMN_SCSIAUTHINTRATTACHEDTIMES 6 #define COLUMN_SCSIAUTHINTROUTCOMMANDS 7 #define COLUMN_SCSIAUTHINTRREADMEGABYTES 8 #define COLUMN_SCSIAUTHINTRWRITTENMEGABYTES 9 #define COLUMN_SCSIAUTHINTRHSOUTCOMMANDS 10 #define COLUMN_SCSIAUTHINTRLASTCREATION 11 #define COLUMN_SCSIAUTHINTRROWSTATUS 12 /* Data structure for row entry */ struct scsiAuthorizedIntrTable_entry { u_long scsiInstIndex; u_long scsiDeviceIndex; u_long scsiAuthIntrTgtPortIndex; u_long scsiAuthIntrIndex; long scsiAuthIntrDevOrPort; char scsiAuthIntrName[SCSI_MAX_NAME_LEN]; u_long scsiAuthIntrLunMapIndex; u_long scsiAuthIntrAttachedTimes; u_long scsiAuthIntrOutCommands; u_long scsiAuthIntrReadMegaBytes; u_long scsiAuthIntrWrittenMegaBytes; U64 scsiAuthIntrHSOutCommands; u_long scsiAuthIntrLastCreation; long scsiAuthIntrRowStatus; struct scsiAuthorizedIntrTable_entry *next; }; /* * Attached Initiator Port Table */ void initialize_table_scsiAttIntrPortTable(void); Netsnmp_Node_Handler scsiAttIntrPortTable_handler; Netsnmp_First_Data_Point scsiAttIntrPortTable_get_first_data_point; Netsnmp_Next_Data_Point scsiAttIntrPortTable_get_next_data_point; int scsiAttIntrPortTable_load(netsnmp_cache *cache, void *vmagic); void scsiAttIntrPortTable_free(netsnmp_cache *cache, void *vmagic); /* column number definitions for table scsiAttIntrPortTable */ #define COLUMN_SCSIATTINTRPORTINDEX 1 #define COLUMN_SCSIATTINTRPORTAUTHINTRIDX 2 #define COLUMN_SCSIATTINTRPORTNAME 3 #define COLUMN_SCSIATTINTRPORTIDENTIFIER 4 /* Data structure for row entry */ struct scsiAttIntrPortTable_entry { u_long scsiInstIndex; u_long scsiDeviceIndex; u_long scsiPortIndex; u_long scsiAttIntrPortIndex; u_long scsiAttIntrPortAuthIntrIdx; char scsiAttIntrPortName[SCSI_MAX_NAME_LEN]; char scsiAttIntrPortIdentifier[SCSI_MAX_NAME_LEN]; struct scsiAttIntrPortTable_entry *next; }; /* * Logical Unit Table */ void initialize_table_scsiLuTable(void); Netsnmp_Node_Handler scsiLuTable_handler; Netsnmp_First_Data_Point scsiLuTable_get_first_data_point; Netsnmp_Next_Data_Point scsiLuTable_get_next_data_point; int scsiLuTable_load(netsnmp_cache *cache, void *vmagic); void scsiLuTable_free(netsnmp_cache *cache, void *vmagic); /* column number definitions for table scsiLuTable */ #define COLUMN_SCSILUINDEX 1 #define COLUMN_SCSILUDEFAULTLUN 2 #define COLUMN_SCSILUWWNNAME 3 #define COLUMN_SCSILUVENDORID 4 #define COLUMN_SCSILUPRODUCTID 5 #define COLUMN_SCSILUREVISIONID 6 #define COLUMN_SCSILUPERIPHERALTYPE 7 #define COLUMN_SCSILUSTATUS 8 #define COLUMN_SCSILUSTATE 9 #define COLUMN_SCSILUINCOMMANDS 10 #define COLUMN_SCSILUREADMEGABYTES 11 #define COLUMN_SCSILUWRITTENMEGABYTES 12 #define COLUMN_SCSILUINRESETS 13 #define COLUMN_SCSILUOUTTASKSETFULLSTATUS 14 #define COLUMN_SCSILUHSINCOMMANDS 15 #define COLUMN_SCSILULASTCREATION 16 /* Data structure for row entry */ struct scsiLuTable_entry { u_long scsiInstIndex; u_long scsiDeviceIndex; u_long scsiLuIndex; u_char scsiLuDefaultLun[8]; char scsiLuWwnName[12]; char scsiLuVendorId[32]; char scsiLuProductId[32]; char scsiLuRevisionId[16]; u_long scsiLuPeripheralType; long scsiLuStatus; char scsiLuState[2]; u_long scsiLuInCommands; u_long scsiLuReadMegaBytes; u_long scsiLuWrittenMegaBytes; u_long scsiLuInResets; u_long scsiLuOutTaskSetFullStatus; U64 scsiLuHSInCommands; u_long scsiLuLastCreation; struct scsiLuTable_entry *next; }; #endif /* SCSIMIB_H */ lio-utils-3.1+git2.fd0b34fd/mib-modules/scsiMib.c0000644000175000017500000024703011753136721017616 0ustar rrsrrs/* * Copyright (c) 2006 SBE, Inc. * Copyright (c) 2009-2011 Linux-iSCSI.org * * Nicholas A. Bellinger * * 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. */ #include #include #include #include "common.h" #include "scsiMib.h" /* Initializes the scsiMib module */ void init_scsiMib(void) { /* Initialize all tables */ initialize_table_scsiInstanceTable(); initialize_table_scsiDeviceTable(); initialize_table_scsiPortTable(); initialize_table_scsiTransportTable(); initialize_table_scsiTgtPortTable(); initialize_table_scsiAuthorizedIntrTable(); initialize_table_scsiAttIntrPortTable(); initialize_table_scsiLuTable(); initialize_scsiTgtDevTable(); } /* * Instance Table */ #define SCSI_INST_CACHE_TIMEOUT 10 /* * Initialize the scsiInstanceTable table */ void initialize_table_scsiInstanceTable(void) { static oid scsiInstanceTable_oid[] = {OID_LIO_SCSI_MIB,2,1,1}; size_t scsiInstanceTable_oid_len = OID_LENGTH(scsiInstanceTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("scsiInstanceTable", scsiInstanceTable_handler, scsiInstanceTable_oid, scsiInstanceTable_oid_len, HANDLER_CAN_RWRITE); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* scsiInstIndex */ 0); table_info->min_column = 1; table_info->max_column = 6; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = scsiInstanceTable_get_first_data_point; iinfo->get_next_data_point = scsiInstanceTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(SCSI_INST_CACHE_TIMEOUT, scsiInstanceTable_load, scsiInstanceTable_free, scsiInstanceTable_oid, scsiInstanceTable_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void scsiInstanceTable_cache_update(void) { static marker_t scsiInstanceTable_cache_marker = NULL; if (scsiInstanceTable_cache_marker && (!atime_ready(scsiInstanceTable_cache_marker, SCSI_INST_CACHE_TIMEOUT * 1000))) return; if (scsiInstanceTable_cache_marker) atime_setMarker(scsiInstanceTable_cache_marker); else scsiInstanceTable_cache_marker = atime_newMarker(); scsiInstanceTable_load(NULL, NULL); } #endif struct scsiInstanceTable_entry *scsiInstanceTable_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * scsiInstanceTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER scsiInstanceTable_cache_update(); #endif *my_loop_context = scsiInstanceTable_head; return scsiInstanceTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * scsiInstanceTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct scsiInstanceTable_entry *entry = (struct scsiInstanceTable_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->scsiInstIndex, sizeof(entry->scsiInstIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the scsiInstanceTable table */ int scsiInstanceTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct scsiInstanceTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct scsiInstanceTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_SCSIINSTINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiInstIndex, sizeof(table_entry->scsiInstIndex)); break; case COLUMN_SCSIINSTALIAS: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)&table_entry->scsiInstAlias, strlen(table_entry->scsiInstAlias)); break; case COLUMN_SCSIINSTSOFTWAREINDEX: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->scsiInstSoftwareIndex, sizeof(table_entry->scsiInstSoftwareIndex)); break; case COLUMN_SCSIINSTVENDORVERSION: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)&table_entry->scsiInstVendorVersion, strlen(table_entry->scsiInstVendorVersion)); break; case COLUMN_SCSIINSTSCSINOTIFICATIONSENABLE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->scsiInstScsiNotificationsEnable, sizeof(table_entry->scsiInstScsiNotificationsEnable)); break; case COLUMN_SCSIINSTSTORAGETYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->scsiInstStorageType, sizeof(table_entry->scsiInstStorageType)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SCSI_INST "/proc/scsi_target/mib/scsi_inst" #define SCSI_INST_LINE "%lu %lu" int scsiInstanceTable_load(netsnmp_cache *cache, void *vmagic) { FILE *fp, *alias_fp; char line[256]; struct scsiInstanceTable_entry tmp, *entry; if (scsiInstanceTable_head) scsiInstanceTable_free(NULL, NULL); if (!(fp = fopen(PROC_SCSI_INST, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SCSI_INST); return -1; } alias_fp = fopen("/etc/iscsi.alias", "r"); while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, SCSI_INST_LINE, &tmp.scsiInstIndex, &tmp.scsiInstSoftwareIndex) != 2) continue; /* Change this if write is supported */ tmp.scsiInstScsiNotificationsEnable = TV_TRUE; if (line != fgets(line, sizeof(line), fp)) break; if (sscanf(line, "version: %s", tmp.scsiInstVendorVersion) == 1) { *(line + strlen(line) - 1) = 0; strcpy(tmp.scsiInstVendorVersion, line + strlen("version: ")); } else break; tmp.scsiInstStorageType = ST_READONLY; if (alias_fp && (line == fgets(line, sizeof(line), alias_fp))) sscanf(line, "%s", tmp.scsiInstAlias); entry = SNMP_MALLOC_TYPEDEF(struct scsiInstanceTable_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = scsiInstanceTable_head; scsiInstanceTable_head = entry; } fclose(fp); if (alias_fp) fclose(alias_fp); return 0; } void scsiInstanceTable_free(netsnmp_cache *cache, void *vmagic) { struct scsiInstanceTable_entry *entry; while (scsiInstanceTable_head) { entry = scsiInstanceTable_head; scsiInstanceTable_head = scsiInstanceTable_head->next; SNMP_FREE(entry); } } /* * Device Table */ #define SCSI_DEV_CACHE_TIMEOUT 10 /* * Initialize the scsiDeviceTable table */ void initialize_table_scsiDeviceTable(void) { static oid scsiDeviceTable_oid[] = {OID_LIO_SCSI_MIB,2,1,2}; size_t scsiDeviceTable_oid_len = OID_LENGTH(scsiDeviceTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("scsiDeviceTable", scsiDeviceTable_handler, scsiDeviceTable_oid, scsiDeviceTable_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* scsiInstIndex */ ASN_UNSIGNED, /* scsiDeviceIndex */ 0); table_info->min_column = 1; table_info->max_column = 6; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = scsiDeviceTable_get_first_data_point; iinfo->get_next_data_point = scsiDeviceTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(SCSI_DEV_CACHE_TIMEOUT, scsiDeviceTable_load, scsiDeviceTable_free, scsiDeviceTable_oid, scsiDeviceTable_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void scsiDeviceTable_cache_update(void) { static marker_t scsiDeviceTable_cache_marker = NULL; if (scsiDeviceTable_cache_marker && (!atime_ready(scsiDeviceTable_cache_marker, SCSI_DEV_CACHE_TIMEOUT * 1000))) return; if (scsiDeviceTable_cache_marker) atime_setMarker(scsiDeviceTable_cache_marker); else scsiDeviceTable_cache_marker = atime_newMarker(); scsiDeviceTable_load(NULL, NULL); } #endif struct scsiDeviceTable_entry *scsiDeviceTable_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * scsiDeviceTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER scsiDeviceTable_cache_update(); #endif *my_loop_context = scsiDeviceTable_head; return scsiDeviceTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * scsiDeviceTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct scsiDeviceTable_entry *entry = (struct scsiDeviceTable_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->scsiInstIndex, sizeof(entry->scsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiDeviceIndex, sizeof(entry->scsiDeviceIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the scsiDeviceTable table */ int scsiDeviceTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct scsiDeviceTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct scsiDeviceTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_SCSIDEVICEINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiDeviceIndex, sizeof(table_entry->scsiDeviceIndex)); break; case COLUMN_SCSIDEVICEALIAS: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiDeviceAlias, strlen(table_entry->scsiDeviceAlias)); break; case COLUMN_SCSIDEVICEROLE: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)&table_entry->scsiDeviceRole, sizeof(table_entry->scsiDeviceRole)); break; case COLUMN_SCSIDEVICEPORTNUMBER: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiDevicePortNumber, sizeof(table_entry->scsiDevicePortNumber)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SCSI_DEV "/proc/scsi_target/mib/scsi_dev" #define SCSI_DEV_LINE "%lu %lu %s %lu" int scsiDeviceTable_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[128]; struct scsiDeviceTable_entry tmp, *entry; char role[12]; if (scsiDeviceTable_head) scsiDeviceTable_free(NULL, NULL); if (!(fp = fopen(PROC_SCSI_DEV, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SCSI_DEV); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, SCSI_DEV_LINE, &tmp.scsiInstIndex, &tmp.scsiDeviceIndex, role, &tmp.scsiDevicePortNumber) != 4) continue; tmp.scsiDeviceRole = SCSI_ROLE_TARGET; if (line != fgets(line, sizeof(line), fp)) break; if (sscanf(line, "dev_alias: %s", tmp.scsiDeviceAlias) == 1) { *(line + strlen(line) - 1) = 0; strcpy(tmp.scsiDeviceAlias, line + strlen("dev_alias: ")); } else break; entry = SNMP_MALLOC_TYPEDEF(struct scsiDeviceTable_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = scsiDeviceTable_head; scsiDeviceTable_head = entry; } fclose(fp); return 0; } void scsiDeviceTable_free(netsnmp_cache *cache, void *vmagic) { struct scsiDeviceTable_entry *entry; while (scsiDeviceTable_head) { entry = scsiDeviceTable_head; scsiDeviceTable_head = scsiDeviceTable_head->next; SNMP_FREE(entry); } } /* * Port Table */ #define SCSI_PORT_CACHE_TIMEOUT 10 /* * Initialize the scsiPortTable table */ void initialize_table_scsiPortTable(void) { static oid scsiPortTable_oid[] = {OID_LIO_SCSI_MIB,2,1,3}; size_t scsiPortTable_oid_len = OID_LENGTH(scsiPortTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("scsiPortTable", scsiPortTable_handler, scsiPortTable_oid, scsiPortTable_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* scsiInstIndex */ ASN_UNSIGNED, /* scsiDeviceIndex */ ASN_UNSIGNED, /* scsiPortIndex */ 0); table_info->min_column = 1; table_info->max_column = 6; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = scsiPortTable_get_first_data_point; iinfo->get_next_data_point = scsiPortTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(SCSI_PORT_CACHE_TIMEOUT, scsiPortTable_load, scsiPortTable_free, scsiPortTable_oid, scsiPortTable_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void scsiPortTable_cache_update(void) { static marker_t scsiPortTable_cache_marker = NULL; if (scsiPortTable_cache_marker && (!atime_ready(scsiPortTable_cache_marker, SCSI_PORT_CACHE_TIMEOUT * 1000))) return; if (scsiPortTable_cache_marker) atime_setMarker(scsiPortTable_cache_marker); else scsiPortTable_cache_marker = atime_newMarker(); scsiPortTable_load(NULL, NULL); } #endif struct scsiPortTable_entry *scsiPortTable_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * scsiPortTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER scsiPortTable_cache_update(); #endif *my_loop_context = scsiPortTable_head; return scsiPortTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * scsiPortTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct scsiPortTable_entry *entry = (struct scsiPortTable_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->scsiInstIndex, sizeof(entry->scsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiDeviceIndex, sizeof(entry->scsiDeviceIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiPortIndex, sizeof(entry->scsiPortIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the scsiPortTable table */ int scsiPortTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct scsiPortTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct scsiPortTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_SCSIPORTINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiPortIndex, sizeof(table_entry->scsiPortIndex)); break; case COLUMN_SCSIPORTROLE: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, &table_entry->scsiPortRole, sizeof(table_entry->scsiPortRole)); break; case COLUMN_SCSIPORTTRANSPORTPTR: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *)&table_entry->scsiPortTransportPtr, table_entry->scsiPortTransportPtr_len * sizeof(oid)); break; case COLUMN_SCSIPORTBUSYSTATUSES: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiPortBusyStatuses, sizeof(table_entry->scsiPortBusyStatuses)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SCSI_PORT "/proc/scsi_target/mib/scsi_port" #define SCSI_PORT_LINE "%lu %lu %lu %s %lu" /* * scsiTransportTable.scsiTransportEntry.scsiTransportType */ static oid scsiTransportEntry_oid[] = {OID_LIO_SCSI_MIB,2,1,5,1,2}; int scsiPortTable_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[128]; struct scsiPortTable_entry tmp, *entry; char role[12]; if (scsiPortTable_head) scsiPortTable_free(NULL, NULL); if (!(fp = fopen(PROC_SCSI_PORT, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SCSI_PORT); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, SCSI_PORT_LINE, &tmp.scsiInstIndex, &tmp.scsiDeviceIndex, &tmp.scsiPortIndex, role, &tmp.scsiPortBusyStatuses) != 5) continue; tmp.scsiPortRole = SCSI_ROLE_TARGET; memcpy(tmp.scsiPortTransportPtr, scsiTransportEntry_oid, sizeof(scsiTransportEntry_oid)); tmp.scsiPortTransportPtr_len = OID_LENGTH(scsiTransportEntry_oid) + 3; tmp.scsiPortTransportPtr[tmp.scsiPortTransportPtr_len - 3] = tmp.scsiInstIndex; tmp.scsiPortTransportPtr[tmp.scsiPortTransportPtr_len - 2] = tmp.scsiDeviceIndex; tmp.scsiPortTransportPtr[tmp.scsiPortTransportPtr_len - 1] = SCSI_TRANSPORT_INDEX; entry = SNMP_MALLOC_TYPEDEF(struct scsiPortTable_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = scsiPortTable_head; scsiPortTable_head = entry; } fclose(fp); return 0; } void scsiPortTable_free(netsnmp_cache *cache, void *vmagic) { struct scsiPortTable_entry *entry; while (scsiPortTable_head) { entry = scsiPortTable_head; scsiPortTable_head = scsiPortTable_head->next; SNMP_FREE(entry); } } /* * Transport Table */ #define SCSI_TRANSPORT_CACHE_TIMEOUT 10 /* * Initialize the scsiTransportTable table */ void initialize_table_scsiTransportTable(void) { static oid scsiTransportTable_oid[] = {OID_LIO_SCSI_MIB,2,1,5}; size_t scsiTransportTable_oid_len = OID_LENGTH(scsiTransportTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("scsiTransportTable", scsiTransportTable_handler, scsiTransportTable_oid, scsiTransportTable_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* scsiInstIndex */ ASN_UNSIGNED, /* scsiDeviceIndex */ ASN_UNSIGNED, /* scsiTransportIndex */ 0); table_info->min_column = 1; table_info->max_column = 6; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = scsiTransportTable_get_first_data_point; iinfo->get_next_data_point = scsiTransportTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(SCSI_TRANSPORT_CACHE_TIMEOUT, scsiTransportTable_load, scsiTransportTable_free, scsiTransportTable_oid, scsiTransportTable_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void scsiTransportTable_cache_update(void) { static marker_t scsiTransportTable_cache_marker = NULL; if (scsiTransportTable_cache_marker && (!atime_ready(scsiTransportTable_cache_marker, SCSI_TRANSPORT_CACHE_TIMEOUT * 1000))) return; if (scsiTransportTable_cache_marker) atime_setMarker(scsiTransportTable_cache_marker); else scsiTransportTable_cache_marker = atime_newMarker(); scsiTransportTable_load(NULL, NULL); } #endif struct scsiTransportTable_entry *scsiTransportTable_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * scsiTransportTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER scsiTransportTable_cache_update(); #endif *my_loop_context = scsiTransportTable_head; return scsiTransportTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * scsiTransportTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct scsiTransportTable_entry *entry = (struct scsiTransportTable_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->scsiInstIndex, sizeof(entry->scsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiDeviceIndex, sizeof(entry->scsiDeviceIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiTransportIndex, sizeof(entry->scsiTransportIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the scsiTransportTable table */ int scsiTransportTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct scsiTransportTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct scsiTransportTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_SCSITRANSPORTINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiTransportIndex, sizeof(table_entry->scsiTransportIndex)); case COLUMN_SCSITRANSPORTTYPE: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *)&table_entry->scsiTransportType, table_entry->scsiTransportType_len * sizeof(oid)); break; case COLUMN_SCSITRANSPORTPOINTER: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *)&table_entry->scsiTransportPointer, table_entry->scsiTransportPointer_len * sizeof(oid)); break; case COLUMN_SCSITRANSPORTDEVNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiTransportDevName, strlen(table_entry->scsiTransportDevName)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SCSI_TRANSPORT "/proc/scsi_target/mib/scsi_transport" #define SCSI_TRANSPORT_LINE "%lu %lu %lu %s" static oid scsiTransportISCSI_oid[] = {OID_LIO_SCSI_MIB,1,1,5}; static oid iscsiInstAttributes_oid[] = {OID_LIO_ISCSI_MIB,1,1,1,1,2}; int scsiTransportTable_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[512]; struct scsiTransportTable_entry tmp, *entry; if (scsiTransportTable_head) scsiTransportTable_free(NULL, NULL); if (!(fp = fopen(PROC_SCSI_TRANSPORT, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SCSI_TRANSPORT); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, SCSI_TRANSPORT_LINE, &tmp.scsiInstIndex, &tmp.scsiDeviceIndex, &tmp.scsiTransportIndex, tmp.scsiTransportDevName) != 4) continue; /* Transport type is always iSCSI */ memcpy(tmp.scsiTransportType, scsiTransportISCSI_oid, sizeof(scsiTransportISCSI_oid)); tmp.scsiTransportType_len = OID_LENGTH(scsiTransportISCSI_oid); /* Point to the iSCSI Instance (index 1) */ memcpy(tmp.scsiTransportPointer, iscsiInstAttributes_oid, sizeof(iscsiInstAttributes_oid)); tmp.scsiTransportPointer_len = OID_LENGTH(iscsiInstAttributes_oid) + 1; tmp.scsiTransportPointer[tmp.scsiTransportPointer_len - 1] = 1; entry = SNMP_MALLOC_TYPEDEF(struct scsiTransportTable_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = scsiTransportTable_head; scsiTransportTable_head = entry; } fclose(fp); return 0; } void scsiTransportTable_free(netsnmp_cache *cache, void *vmagic) { struct scsiTransportTable_entry *entry; while (scsiTransportTable_head) { entry = scsiTransportTable_head; scsiTransportTable_head = scsiTransportTable_head->next; SNMP_FREE(entry); } } /* * Target Device Table support and Device status change Trap generator */ /* Use 3 sec poll recommended by the draft */ #define SCSI_TGT_DEV_STATUS_POLL_INTERVAL 3 /* * Initializes the iscsiTargetAttributes */ void initialize_scsiTgtDevTable(void) { /* Initialize the table */ initialize_table_scsiTgtDevTable(); /* Setup callback for polling */ snmp_alarm_register(SCSI_TGT_DEV_STATUS_POLL_INTERVAL, SA_REPEAT, scsiTgtDevTable_load, NULL); /* Initial load */ scsiTgtDevTable_load(0, NULL); } /* * Initialize the scsiTgtDevTable table */ void initialize_table_scsiTgtDevTable(void) { static oid scsiTgtDevTable_oid[] = {OID_LIO_SCSI_MIB,2,3,1}; size_t scsiTgtDevTable_oid_len = OID_LENGTH(scsiTgtDevTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("scsiTgtDevTable", scsiTgtDevTable_handler, scsiTgtDevTable_oid, scsiTgtDevTable_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* scsiInstIndex */ ASN_UNSIGNED, /* scsiDeviceIndex */ 0); table_info->min_column = 1; table_info->max_column = 6; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = scsiTgtDevTable_get_first_data_point; iinfo->get_next_data_point = scsiTgtDevTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); } struct scsiTgtDevTable_entry *scsiTgtDevTable_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * scsiTgtDevTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { *my_loop_context = scsiTgtDevTable_head; return scsiTgtDevTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * scsiTgtDevTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct scsiTgtDevTable_entry *entry = (struct scsiTgtDevTable_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->scsiInstIndex, sizeof(entry->scsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiDeviceIndex, sizeof(entry->scsiDeviceIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the scsiTgtDevTable table */ int scsiTgtDevTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct scsiTgtDevTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct scsiTgtDevTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_SCSITGTDEVNUMBEROFLUS: snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *)&table_entry->scsiTgtDevNumberOfLUs, sizeof(table_entry->scsiTgtDevNumberOfLUs)); break; case COLUMN_SCSITGTDEVICESTATUS: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->scsiTgtDeviceStatus, sizeof(table_entry->scsiTgtDeviceStatus)); break; case COLUMN_SCSITGTDEVNONACCESSIBLELUS: snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *)&table_entry->scsiTgtDevNonAccessibleLUs, sizeof(table_entry->scsiTgtDevNonAccessibleLUs)); break; case COLUMN_SCSITGTDEVRESETS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiTgtDevResets, sizeof(table_entry->scsiTgtDevResets)); break; } } break; } return SNMP_ERR_NOERROR; } /* * Notification code */ static oid snmptrap_oid[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0}; int send_scsiTgtDeviceStatusChanged_trap(struct scsiTgtDevTable_entry *entry) { netsnmp_variable_list *var_list = NULL; oid scsiTgtDeviceStatusChanged_oid[] = {OID_LIO_SCSI_MIB,0,0,1}; oid scsiTgtDeviceStatus_oid[] = {OID_LIO_SCSI_MIB,2,3,1,1,2, entry->scsiInstIndex, entry->scsiDeviceIndex}; /* * Set the snmpTrapOid.0 value */ snmp_varlist_add_variable(&var_list, snmptrap_oid, OID_LENGTH(snmptrap_oid), ASN_OBJECT_ID, (u_char *)scsiTgtDeviceStatusChanged_oid, sizeof(scsiTgtDeviceStatusChanged_oid)); /* * Add objects from the trap definition */ snmp_varlist_add_variable(&var_list, scsiTgtDeviceStatus_oid, OID_LENGTH(scsiTgtDeviceStatus_oid), ASN_INTEGER, (u_char *)&entry->scsiTgtDeviceStatus, sizeof(entry->scsiTgtDeviceStatus)); /* * Send the trap to the list of configured destinations and clean up */ send_v2trap(var_list); snmp_free_varbind(var_list); return SNMP_ERR_NOERROR; } void scsiTgtDevTable_free(struct scsiTgtDevTable_entry **table_head_ptr) { struct scsiTgtDevTable_entry *entry; while (*table_head_ptr) { entry = *table_head_ptr; *table_head_ptr = (*table_head_ptr)->next; SNMP_FREE(entry); } } #define PROC_SCSI_TGT_DEV "/proc/scsi_target/mib/scsi_tgt_dev" #define SCSI_TGT_DEV_LINE "%lu %lu %lu %s %lu %lu" void scsiTgtDevTable_load(unsigned int clientreg, void *clientarg) { FILE *fp; char line[128]; struct scsiTgtDevTable_entry tmp, *entry; struct scsiTgtDevTable_entry *old_table, *old_entry; char status[16]; if (!(fp = fopen(PROC_SCSI_TGT_DEV, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SCSI_TGT_DEV); if (scsiTgtDevTable_head) scsiTgtDevTable_free(&scsiTgtDevTable_head); return; } old_table = scsiTgtDevTable_head; scsiTgtDevTable_head = NULL; while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, SCSI_TGT_DEV_LINE, &tmp.scsiInstIndex, &tmp.scsiDeviceIndex, &tmp.scsiTgtDevNumberOfLUs, status, &tmp.scsiTgtDevNonAccessibleLUs, &tmp.scsiTgtDevResets) != 6) continue; if (!strcmp(status, "activated")) tmp.scsiTgtDeviceStatus = SCSI_DEV_STATUS_AVAILABLE; else if (!strncmp(status, "unknown", 7)) tmp.scsiTgtDeviceStatus = SCSI_DEV_STATUS_UNKNOWN; else tmp.scsiTgtDeviceStatus = SCSI_DEV_STATUS_ABNORMAL; #if 0 /* Test code. Simulate status changes */ static int count = 0; if (!(++count % 20)) tmp.scsiTgtDeviceStatus = SCSI_DEV_STATUS_ABNORMAL; #endif /* Get the previous status */ for (old_entry = old_table; old_entry; old_entry = old_entry->next) { if ((old_entry->scsiInstIndex == tmp.scsiInstIndex) && (old_entry->scsiDeviceIndex == tmp.scsiDeviceIndex)) { if (old_entry->scsiTgtDeviceStatus != tmp.scsiTgtDeviceStatus) { /* Status changed. Send a trap */ send_scsiTgtDeviceStatusChanged_trap(&tmp); } break; } } entry = SNMP_MALLOC_TYPEDEF(struct scsiTgtDevTable_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = scsiTgtDevTable_head; scsiTgtDevTable_head = entry; } fclose(fp); if (old_table) scsiTgtDevTable_free(&old_table); return; } /* * Target Port Table */ #define SCSI_TGT_PORT_CACHE_TIMEOUT 5 /* * Initialize the scsiTgtPortTable table */ void initialize_table_scsiTgtPortTable(void) { static oid scsiTgtPortTable_oid[] = {OID_LIO_SCSI_MIB,2,3,2}; size_t scsiTgtPortTable_oid_len = OID_LENGTH(scsiTgtPortTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("scsiTgtPortTable", scsiTgtPortTable_handler, scsiTgtPortTable_oid, scsiTgtPortTable_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* scsiInstIndex */ ASN_UNSIGNED, /* scsiDeviceIndex */ ASN_UNSIGNED, /* scsiPortIndex */ 0); table_info->min_column = 1; table_info->max_column = 9; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = scsiTgtPortTable_get_first_data_point; iinfo->get_next_data_point = scsiTgtPortTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(SCSI_TGT_PORT_CACHE_TIMEOUT, scsiTgtPortTable_load, scsiTgtPortTable_free, scsiTgtPortTable_oid, scsiTgtPortTable_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void scsiTgtPortTable_cache_update(void) { static marker_t scsiTgtPortTable_cache_marker = NULL; if (scsiTgtPortTable_cache_marker && (!atime_ready(scsiTgtPortTable_cache_marker, SCSI_TGT_PORT_CACHE_TIMEOUT * 1000))) return; if (scsiTgtPortTable_cache_marker) atime_setMarker(scsiTgtPortTable_cache_marker); else scsiTgtPortTable_cache_marker = atime_newMarker(); scsiTgtPortTable_load(NULL, NULL); } #endif struct scsiTgtPortTable_entry *scsiTgtPortTable_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * scsiTgtPortTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER scsiTgtPortTable_cache_update(); #endif *my_loop_context = scsiTgtPortTable_head; return scsiTgtPortTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * scsiTgtPortTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct scsiTgtPortTable_entry *entry = (struct scsiTgtPortTable_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->scsiInstIndex, sizeof(entry->scsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiDeviceIndex, sizeof(entry->scsiDeviceIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiPortIndex, sizeof(entry->scsiPortIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the scsiTgtPortTable table */ int scsiTgtPortTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct scsiTgtPortTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct scsiTgtPortTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_SCSITGTPORTNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiTgtPortName, strlen(table_entry->scsiTgtPortName)); break; case COLUMN_SCSITGTPORTIDENTIFIER: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiTgtPortIdentifier, strlen(table_entry->scsiTgtPortIdentifier)); break; case COLUMN_SCSITGTPORTINCOMMANDS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiTgtPortInCommands, sizeof(table_entry->scsiTgtPortInCommands)); break; case COLUMN_SCSITGTPORTWRITTENMEGABYTES: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiTgtPortWrittenMegaBytes, sizeof(table_entry->scsiTgtPortWrittenMegaBytes)); break; case COLUMN_SCSITGTPORTREADMEGABYTES: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiTgtPortReadMegaBytes, sizeof(table_entry->scsiTgtPortReadMegaBytes)); break; case COLUMN_SCSITGTPORTHSINCOMMANDS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64, (u_char *)&table_entry->scsiTgtPortHSInCommands, sizeof(table_entry->scsiTgtPortHSInCommands)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SCSI_TGT_PORT "/proc/scsi_target/mib/scsi_tgt_port" #define SCSI_TGT_PORT_LINE_32 "%lu %lu %lu %s %s %llu %lu %lu" #define SCSI_TGT_PORT_LINE_64 "%lu %lu %lu %s %s %lu %lu %lu" int scsiTgtPortTable_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[512]; struct scsiTgtPortTable_entry tmp, *entry; u_int64_t inCommands; if (scsiTgtPortTable_head) scsiTgtPortTable_free(NULL, NULL); if (!(fp = fopen(PROC_SCSI_TGT_PORT, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SCSI_TGT_PORT); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, (sizeof(long) == 8)? SCSI_TGT_PORT_LINE_64 : SCSI_TGT_PORT_LINE_32, &tmp.scsiInstIndex, &tmp.scsiDeviceIndex, &tmp.scsiPortIndex, tmp.scsiTgtPortName, tmp.scsiTgtPortIdentifier, &inCommands, &tmp.scsiTgtPortWrittenMegaBytes, &tmp.scsiTgtPortReadMegaBytes) != 8) continue; tmp.scsiTgtPortHSInCommands.high = (inCommands >> 32) & 0xffffffff; tmp.scsiTgtPortHSInCommands.low = inCommands & 0xffffffff; tmp.scsiTgtPortInCommands = tmp.scsiTgtPortHSInCommands.low; entry = SNMP_MALLOC_TYPEDEF(struct scsiTgtPortTable_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = scsiTgtPortTable_head; scsiTgtPortTable_head = entry; } fclose(fp); return 0; } void scsiTgtPortTable_free(netsnmp_cache *cache, void *vmagic) { struct scsiTgtPortTable_entry *entry; while (scsiTgtPortTable_head) { entry = scsiTgtPortTable_head; scsiTgtPortTable_head = scsiTgtPortTable_head->next; SNMP_FREE(entry); } } /* * Authorized Initiator Table */ #define SCSI_AUTH_INTR_CACHE_TIMEOUT 5 /* * Initialize the scsiAuthorizedIntrTable table */ void initialize_table_scsiAuthorizedIntrTable(void) { static oid scsiAuthorizedIntrTable_oid[] = {OID_LIO_SCSI_MIB,2,3,3,1}; size_t scsiAuthorizedIntrTable_oid_len = OID_LENGTH(scsiAuthorizedIntrTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("scsiAuthorizedIntrTable", scsiAuthorizedIntrTable_handler, scsiAuthorizedIntrTable_oid, scsiAuthorizedIntrTable_oid_len, HANDLER_CAN_RWRITE); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* scsiInstIndex */ ASN_UNSIGNED, /* scsiDeviceIndex */ ASN_UNSIGNED, /* scsiAuthIntrTgtPortIndex*/ ASN_UNSIGNED, /* scsiAuthIntrIndex */ 0); table_info->min_column = 1; table_info->max_column = 14; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = scsiAuthorizedIntrTable_get_first_data_point; iinfo->get_next_data_point = scsiAuthorizedIntrTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(SCSI_AUTH_INTR_CACHE_TIMEOUT, scsiAuthorizedIntrTable_load, scsiAuthorizedIntrTable_free, scsiAuthorizedIntrTable_oid, scsiAuthorizedIntrTable_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void scsiAuthorizedIntrTable_cache_update(void) { static marker_t scsiAuthorizedIntrTable_cache_marker = NULL; if (scsiAuthorizedIntrTable_cache_marker && (!atime_ready(scsiAuthorizedIntrTable_cache_marker, SCSI_AUTH_INTR_CACHE_TIMEOUT * 1000))) return; if (scsiAuthorizedIntrTable_cache_marker) atime_setMarker(scsiAuthorizedIntrTable_cache_marker); else scsiAuthorizedIntrTable_cache_marker = atime_newMarker(); scsiAuthorizedIntrTable_load(NULL, NULL); } #endif struct scsiAuthorizedIntrTable_entry *scsiAuthorizedIntrTable_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * scsiAuthorizedIntrTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER scsiAuthorizedIntrTable_cache_update(); #endif *my_loop_context = scsiAuthorizedIntrTable_head; return scsiAuthorizedIntrTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * scsiAuthorizedIntrTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct scsiAuthorizedIntrTable_entry *entry = (struct scsiAuthorizedIntrTable_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->scsiInstIndex, sizeof(entry->scsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiDeviceIndex, sizeof(entry->scsiDeviceIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiAuthIntrTgtPortIndex, sizeof(entry->scsiAuthIntrTgtPortIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiAuthIntrIndex, sizeof(entry->scsiAuthIntrIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the scsiAuthorizedIntrTable table */ int scsiAuthorizedIntrTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct scsiAuthorizedIntrTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct scsiAuthorizedIntrTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_SCSIAUTHINTRTGTPORTINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiAuthIntrTgtPortIndex, sizeof(table_entry->scsiAuthIntrTgtPortIndex)); break; case COLUMN_SCSIAUTHINTRINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiAuthIntrIndex, sizeof(table_entry->scsiAuthIntrIndex)); break; case COLUMN_SCSIAUTHINTRDEVORPORT: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->scsiAuthIntrDevOrPort, sizeof(table_entry->scsiAuthIntrDevOrPort)); break; case COLUMN_SCSIAUTHINTRNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiAuthIntrName, strlen(table_entry->scsiAuthIntrName)); break; case COLUMN_SCSIAUTHINTRLUNMAPINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiAuthIntrLunMapIndex, sizeof(table_entry->scsiAuthIntrLunMapIndex)); break; case COLUMN_SCSIAUTHINTRATTACHEDTIMES: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiAuthIntrAttachedTimes, sizeof(table_entry->scsiAuthIntrAttachedTimes)); break; case COLUMN_SCSIAUTHINTROUTCOMMANDS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiAuthIntrOutCommands, sizeof(table_entry->scsiAuthIntrOutCommands)); break; case COLUMN_SCSIAUTHINTRREADMEGABYTES: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiAuthIntrReadMegaBytes, sizeof(table_entry->scsiAuthIntrReadMegaBytes)); break; case COLUMN_SCSIAUTHINTRWRITTENMEGABYTES: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiAuthIntrWrittenMegaBytes, sizeof(table_entry->scsiAuthIntrWrittenMegaBytes)); break; case COLUMN_SCSIAUTHINTRHSOUTCOMMANDS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64, (u_char *)&table_entry->scsiAuthIntrHSOutCommands, sizeof(table_entry->scsiAuthIntrHSOutCommands)); break; case COLUMN_SCSIAUTHINTRLASTCREATION: snmp_set_var_typed_value(request->requestvb, ASN_TIMETICKS, (u_char *)&table_entry->scsiAuthIntrLastCreation, sizeof(table_entry->scsiAuthIntrLastCreation)); break; case COLUMN_SCSIAUTHINTRROWSTATUS: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->scsiAuthIntrRowStatus, sizeof(table_entry->scsiAuthIntrRowStatus)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SCSI_AUTH_INTR "/proc/scsi_target/mib/scsi_auth_intr" #define SCSI_AUTH_INTR_LINE "%lu %lu %lu %lu %lu %s %lu %lu %lu %lu %lu %lu" int scsiAuthorizedIntrTable_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[512]; struct scsiAuthorizedIntrTable_entry tmp, *entry; if (scsiAuthorizedIntrTable_head) scsiAuthorizedIntrTable_free(NULL, NULL); if (!(fp = fopen(PROC_SCSI_AUTH_INTR, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SCSI_AUTH_INTR); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, SCSI_AUTH_INTR_LINE, &tmp.scsiInstIndex, &tmp.scsiDeviceIndex, &tmp.scsiAuthIntrTgtPortIndex, &tmp.scsiAuthIntrIndex, &tmp.scsiAuthIntrDevOrPort, tmp.scsiAuthIntrName, &tmp.scsiAuthIntrLunMapIndex, &tmp.scsiAuthIntrAttachedTimes, &tmp.scsiAuthIntrOutCommands, &tmp.scsiAuthIntrReadMegaBytes, &tmp.scsiAuthIntrWrittenMegaBytes, &tmp.scsiAuthIntrLastCreation) != 12) continue; tmp.scsiAuthIntrHSOutCommands.low = tmp.scsiAuthIntrOutCommands; tmp.scsiAuthIntrRowStatus = RS_ACTIVE; entry = SNMP_MALLOC_TYPEDEF(struct scsiAuthorizedIntrTable_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = scsiAuthorizedIntrTable_head; scsiAuthorizedIntrTable_head = entry; } fclose(fp); return 0; } void scsiAuthorizedIntrTable_free(netsnmp_cache *cache, void *vmagic) { struct scsiAuthorizedIntrTable_entry *entry; while (scsiAuthorizedIntrTable_head) { entry = scsiAuthorizedIntrTable_head; scsiAuthorizedIntrTable_head = scsiAuthorizedIntrTable_head->next; SNMP_FREE(entry); } } /* * Attached Initiator Port Table */ #define SCSI_ATT_INTR_PORT_CACHE_TIMEOUT 10 /* * Initialize the scsiAttIntrPortTable table */ void initialize_table_scsiAttIntrPortTable(void) { static oid scsiAttIntrPortTable_oid[] = {OID_LIO_SCSI_MIB,2,3,3,2}; size_t scsiAttIntrPortTable_oid_len = OID_LENGTH(scsiAttIntrPortTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("scsiAttIntrPortTable", scsiAttIntrPortTable_handler, scsiAttIntrPortTable_oid, scsiAttIntrPortTable_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* scsiInstIndex */ ASN_UNSIGNED, /* scsiDeviceIndex */ ASN_UNSIGNED, /* scsiPortIndex */ ASN_UNSIGNED, /* scsiAttIntrPortIndex */ 0); table_info->min_column = 1; table_info->max_column = 7; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = scsiAttIntrPortTable_get_first_data_point; iinfo->get_next_data_point = scsiAttIntrPortTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(SCSI_ATT_INTR_PORT_CACHE_TIMEOUT, scsiAttIntrPortTable_load, scsiAttIntrPortTable_free, scsiAttIntrPortTable_oid, scsiAttIntrPortTable_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void scsiAttIntrPortTable_cache_update(void) { static marker_t scsiAttIntrPortTable_cache_marker = NULL; if (scsiAttIntrPortTable_cache_marker && (!atime_ready(scsiAttIntrPortTable_cache_marker, SCSI_ATT_INTR_PORT_CACHE_TIMEOUT * 1000))) return; if (scsiAttIntrPortTable_cache_marker) atime_setMarker(scsiAttIntrPortTable_cache_marker); else scsiAttIntrPortTable_cache_marker = atime_newMarker(); scsiAttIntrPortTable_load(NULL, NULL); } #endif struct scsiAttIntrPortTable_entry *scsiAttIntrPortTable_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * scsiAttIntrPortTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER scsiAttIntrPortTable_cache_update(); #endif *my_loop_context = scsiAttIntrPortTable_head; return scsiAttIntrPortTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * scsiAttIntrPortTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct scsiAttIntrPortTable_entry *entry = (struct scsiAttIntrPortTable_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->scsiInstIndex, sizeof(entry->scsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiDeviceIndex, sizeof(entry->scsiDeviceIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiPortIndex, sizeof(entry->scsiPortIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiAttIntrPortIndex, sizeof(entry->scsiAttIntrPortIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the scsiAttIntrPortTable table */ int scsiAttIntrPortTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct scsiAttIntrPortTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct scsiAttIntrPortTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_SCSIATTINTRPORTINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiAttIntrPortIndex, sizeof(table_entry->scsiAttIntrPortIndex)); break; case COLUMN_SCSIATTINTRPORTAUTHINTRIDX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiAttIntrPortAuthIntrIdx, sizeof(table_entry->scsiAttIntrPortAuthIntrIdx)); break; case COLUMN_SCSIATTINTRPORTNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiAttIntrPortName, strlen(table_entry->scsiAttIntrPortName)); break; case COLUMN_SCSIATTINTRPORTIDENTIFIER: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiAttIntrPortIdentifier, strlen(table_entry->scsiAttIntrPortIdentifier)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SCSI_ATT_INTR_PORT "/proc/scsi_target/mib/scsi_att_intr_port" #define SCSI_ATT_INTR_PORT_LINE "%lu %lu %lu %lu %lu %s" int scsiAttIntrPortTable_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[512]; struct scsiAttIntrPortTable_entry tmp, *entry; if (scsiAttIntrPortTable_head) scsiAttIntrPortTable_free(NULL, NULL); if (!(fp = fopen(PROC_SCSI_ATT_INTR_PORT, "r"))) { //snmp_log(LOG_DEBUG,"snmpd: cannot open %s\n",PROC_SCSI_ATT_INTR_PORT); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, SCSI_ATT_INTR_PORT_LINE, &tmp.scsiInstIndex, &tmp.scsiDeviceIndex, &tmp.scsiPortIndex, &tmp.scsiAttIntrPortIndex, &tmp.scsiAttIntrPortAuthIntrIdx, tmp.scsiAttIntrPortName) != 6) continue; strcpy(tmp.scsiAttIntrPortIdentifier, tmp.scsiAttIntrPortName); entry = SNMP_MALLOC_TYPEDEF(struct scsiAttIntrPortTable_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = scsiAttIntrPortTable_head; scsiAttIntrPortTable_head = entry; } fclose(fp); return 0; } void scsiAttIntrPortTable_free(netsnmp_cache *cache, void *vmagic) { struct scsiAttIntrPortTable_entry *entry; while (scsiAttIntrPortTable_head) { entry = scsiAttIntrPortTable_head; scsiAttIntrPortTable_head = scsiAttIntrPortTable_head->next; SNMP_FREE(entry); } } /* * Logical Unit Table */ #define SCSI_LU_CACHE_TIMEOUT 5 /* * Initialize the scsiLuTable table */ void initialize_table_scsiLuTable(void) { static oid scsiLuTable_oid[] = {OID_LIO_SCSI_MIB,2,4,1}; size_t scsiLuTable_oid_len = OID_LENGTH(scsiLuTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("scsiLuTable", scsiLuTable_handler, scsiLuTable_oid, scsiLuTable_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* scsiInstIndex */ ASN_UNSIGNED, /* scsiDeviceIndex */ ASN_UNSIGNED, /* scsiLuIndex */ 0); table_info->min_column = 1; table_info->max_column = 18; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = scsiLuTable_get_first_data_point; iinfo->get_next_data_point = scsiLuTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(SCSI_LU_CACHE_TIMEOUT, scsiLuTable_load, scsiLuTable_free, scsiLuTable_oid, scsiLuTable_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void scsiLuTable_cache_update(void) { static marker_t scsiLuTable_cache_marker = NULL; if (scsiLuTable_cache_marker && (!atime_ready(scsiLuTable_cache_marker, SCSI_LU_CACHE_TIMEOUT * 1000))) return; if (scsiLuTable_cache_marker) atime_setMarker(scsiLuTable_cache_marker); else scsiLuTable_cache_marker = atime_newMarker(); scsiLuTable_load(NULL, NULL); } #endif struct scsiLuTable_entry *scsiLuTable_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * scsiLuTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER scsiLuTable_cache_update(); #endif *my_loop_context = scsiLuTable_head; return scsiLuTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * scsiLuTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct scsiLuTable_entry *entry = (struct scsiLuTable_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->scsiInstIndex, sizeof(entry->scsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiDeviceIndex, sizeof(entry->scsiDeviceIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->scsiLuIndex, sizeof(entry->scsiLuIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the scsiLuTable table */ int scsiLuTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct scsiLuTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct scsiLuTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_SCSILUINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiLuIndex, sizeof(table_entry->scsiLuIndex)); break; case COLUMN_SCSILUDEFAULTLUN: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, table_entry->scsiLuDefaultLun, sizeof(table_entry->scsiLuDefaultLun)); break; case COLUMN_SCSILUWWNNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiLuWwnName, strlen(table_entry->scsiLuWwnName)); break; case COLUMN_SCSILUVENDORID: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiLuVendorId, strlen(table_entry->scsiLuVendorId)); break; case COLUMN_SCSILUPRODUCTID: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiLuProductId, strlen(table_entry->scsiLuProductId)); break; case COLUMN_SCSILUREVISIONID: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiLuRevisionId, strlen(table_entry->scsiLuRevisionId)); break; case COLUMN_SCSILUPERIPHERALTYPE: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->scsiLuPeripheralType, sizeof(table_entry->scsiLuPeripheralType)); break; case COLUMN_SCSILUSTATUS: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->scsiLuStatus, sizeof(table_entry->scsiLuStatus)); break; case COLUMN_SCSILUSTATE: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->scsiLuState, sizeof(table_entry->scsiLuState)); break; case COLUMN_SCSILUINCOMMANDS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiLuInCommands, sizeof(table_entry->scsiLuInCommands)); break; case COLUMN_SCSILUREADMEGABYTES: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiLuReadMegaBytes, sizeof(table_entry->scsiLuReadMegaBytes)); break; case COLUMN_SCSILUWRITTENMEGABYTES: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiLuWrittenMegaBytes, sizeof(table_entry->scsiLuWrittenMegaBytes)); break; case COLUMN_SCSILUINRESETS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiLuInResets, sizeof(table_entry->scsiLuInResets)); break; case COLUMN_SCSILUOUTTASKSETFULLSTATUS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->scsiLuOutTaskSetFullStatus, sizeof(table_entry->scsiLuOutTaskSetFullStatus)); break; case COLUMN_SCSILUHSINCOMMANDS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64, (u_char *)&table_entry->scsiLuHSInCommands, sizeof(table_entry->scsiLuHSInCommands)); break; case COLUMN_SCSILULASTCREATION: snmp_set_var_typed_value(request->requestvb, ASN_TIMETICKS, (u_char *)&table_entry->scsiLuLastCreation, sizeof(table_entry->scsiLuLastCreation)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SCSI_LU "/proc/scsi_target/mib/scsi_lu" #define SCSI_LU_LINE_32 "%lu %lu %lu %llu %s %lu %s %s %llu %lu %lu %lu" #define SCSI_LU_LINE_64 "%lu %lu %lu %lu %s %lu %s %s %lu %lu %lu %lu" int scsiLuTable_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[512]; struct scsiLuTable_entry tmp, *entry; char status[16]; char state[36]; char luName[12]; u_int64_t inCommands; if (scsiLuTable_head) scsiLuTable_free(NULL, NULL); if (!(fp = fopen(PROC_SCSI_LU, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SCSI_LU); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, (sizeof(long) == 8)? SCSI_LU_LINE_64 : SCSI_LU_LINE_32, &tmp.scsiInstIndex, &tmp.scsiDeviceIndex, &tmp.scsiLuIndex, (u_int64_t *)tmp.scsiLuDefaultLun, luName, &tmp.scsiLuPeripheralType, status, state, &inCommands, &tmp.scsiLuReadMegaBytes, &tmp.scsiLuWrittenMegaBytes, &tmp.scsiLuLastCreation) != 12) continue; if (strcmp(luName, "None")) strcpy(tmp.scsiLuWwnName, luName); if (!strcmp(status, "available")) tmp.scsiLuStatus = SCSI_LU_STATUS_AVAILABLE; else if (!strcmp(status, "notavailable")) tmp.scsiLuStatus = SCSI_LU_STATUS_NOTAVAILABLE; else tmp.scsiLuStatus = SCSI_LU_STATUS_UNKNOWN; tmp.scsiLuHSInCommands.high = (inCommands >> 32) & 0xffffffff; tmp.scsiLuHSInCommands.low = inCommands & 0xffffffff; //TODO: Check this and tmp.scsiLuDefaultLun tmp.scsiLuInCommands = tmp.scsiLuHSInCommands.low; /* Use state "exposed (bit 2)" for now */ tmp.scsiLuState[0] = (1 << 5); if (line != fgets(line, sizeof(line), fp)) break; if (sscanf(line, "vendor: %s", tmp.scsiLuVendorId) == 1) { *(line + strlen(line) - 1) = 0; strcpy(tmp.scsiLuVendorId, line + strlen("vendor: ")); } else break; if (line != fgets(line, sizeof(line), fp)) break; if (sscanf(line, "model: %s", tmp.scsiLuProductId) == 1) { *(line + strlen(line) - 1) = 0; strcpy(tmp.scsiLuProductId, line + strlen("model: ")); } else break; if (line != fgets(line, sizeof(line), fp)) break; if (sscanf(line, "revision: %s", tmp.scsiLuRevisionId) == 1) { *(line + strlen(line) - 1) = 0; strcpy(tmp.scsiLuRevisionId, line + strlen("revision: ")); } else break; entry = SNMP_MALLOC_TYPEDEF(struct scsiLuTable_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = scsiLuTable_head; scsiLuTable_head = entry; } fclose(fp); return 0; } void scsiLuTable_free(netsnmp_cache *cache, void *vmagic) { struct scsiLuTable_entry *entry; while (scsiLuTable_head) { entry = scsiLuTable_head; scsiLuTable_head = scsiLuTable_head->next; SNMP_FREE(entry); } } lio-utils-3.1+git2.fd0b34fd/mib-modules/mibs/0000755000175000017500000000000011753136721017005 5ustar rrsrrslio-utils-3.1+git2.fd0b34fd/mib-modules/mibs/LIO-ISCSI-MIB.txt0000644000175000017500000032262211753136721021455 0ustar rrsrrsLIO-ISCSI-MIB DEFINITIONS ::= BEGIN IMPORTS MODULE-IDENTITY, OBJECT-TYPE, OBJECT-IDENTITY, NOTIFICATION-TYPE, Unsigned32, Counter32, Counter64, Gauge32, mib-2, enterprises FROM SNMPv2-SMI TEXTUAL-CONVENTION, TruthValue, RowPointer, TimeStamp, RowStatus, AutonomousType, StorageType FROM SNMPv2-TC MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP FROM SNMPv2-CONF SnmpAdminString FROM SNMP-FRAMEWORK-MIB -- RFC 3411 InetAddressType, InetAddress, InetPortNumber, InetAddressIPv4 FROM INET-ADDRESS-MIB -- RFC 4001 ; lio OBJECT IDENTIFIER ::= { enterprises 1055 } iscsiProduct OBJECT IDENTIFIER ::= { lio 10 } iscsiMibModule MODULE-IDENTITY LAST-UPDATED "200510100000Z" -- October 10, 2005 ORGANIZATION "IETF IPS Working Group" CONTACT-INFO " Mark Bakke Postal: Cisco Systems, Inc 7900 International Drive, Suite 400 Bloomington, MN USA 55425 E-mail: mbakke@cisco.com Marjorie Krueger Postal: Hewlett-Packard Networked Storage Architecture Networked Storage Solutions Org. 8000 Foothills Blvd. Roseville, CA 95747 E-mail: marjorie_krueger@hp.com Tom McSweeney Postal: IBM Corporation 600 Park Offices Drive Research Triangle Park, NC USA 27709 E-mail: tommcs@us.ibm.com James Muchow Postal: Qlogic Corp. 6321 Bury Dr. Eden Prairie, MN USA 55346 E-Mail: james.muchow@qlogic.com" DESCRIPTION "The iSCSI Protocol MIB module. Copyright (C) The Internet Society (2005). This version of this MIB module is part of RFC yyyy; see the RFC itself for full legal notices." -- RFC Ed.: replace yyyy with actual RFC number & remove this note REVISION "200510100000Z" -- October 10, 2005 DESCRIPTION "Initial version of the iSCSI Protocol MIB module" ::= { iscsiProduct 1 } -- LIO Changes: -- Changed DISPLAY-HINT for IscsiName from "223t" to "223a" to improve -- display. -- Since IPv6 is not supported by the stack, changed SYNTAX of IP address -- objects from InetAddress to InetAddressIPv4 for dot-quad format display. iscsiNotifications OBJECT IDENTIFIER ::= { iscsiMibModule 0 } iscsiObjects OBJECT IDENTIFIER ::= { iscsiMibModule 1 } iscsiConformance OBJECT IDENTIFIER ::= { iscsiMibModule 2 } iscsiAdmin OBJECT IDENTIFIER ::= { iscsiMibModule 3 } -- Textual Conventions IscsiTransportProtocol ::= TEXTUAL-CONVENTION DISPLAY-HINT "d" STATUS current DESCRIPTION "This data type is used to define the transport protocols that will carry iSCSI PDUs." REFERENCE "RFC791, RFC1700 The presently known, officially delegated numbers can be found at: http://www.iana.org/assignments/protocol-numbers" SYNTAX Unsigned32 (0..255) IscsiDigestMethod ::= TEXTUAL-CONVENTION STATUS current DESCRIPTION "This data type represents the methods possible for digest negotiation. none - a placeholder for a secondary digest method that means only the primary method can be used. other - a digest method other than those defined below; noDigest - does not support digests (will operate without a digest (NOTE: implementations must support digests to be compliant with the RFC3720); CRC32c - require a CRC32C digest." REFERENCE "RFC 3720, Section 12.1, HeaderDigest and DataDigest" SYNTAX INTEGER { none(1), other(2), noDigest(3), crc32c(4) } IscsiName ::= TEXTUAL-CONVENTION -- DISPLAY-HINT "223t" DISPLAY-HINT "223a" STATUS current DESCRIPTION "This data type is used for objects whose value is an iSCSI Name with the properties described in RFC 3720 section 3.2.6.1, and encoded as specified in RFC 3720 section 3.2.6.2. A zero-length string indicates the absense of an iSCSI name." REFERENCE "RFC 3720, Section 3.2.6, iSCSI Names." SYNTAX OCTET STRING (SIZE(0 | 16..223)) --********************************************************************** iscsiDescriptors OBJECT IDENTIFIER ::= { iscsiAdmin 1 } iscsiHeaderIntegrityTypes OBJECT IDENTIFIER ::= { iscsiDescriptors 1 } iscsiHdrIntegrityNone OBJECT-IDENTITY STATUS current DESCRIPTION "The authoritative identifier when no integrity scheme (for either the header or data) is being used." REFERENCE "RFC 3720, Section 12.1, HeaderDigest and DataDigest" ::= { iscsiHeaderIntegrityTypes 1 } iscsiHdrIntegrityCrc32c OBJECT-IDENTITY STATUS current DESCRIPTION "The authoritative identifier when the integrity scheme (for either the header or data) is CRC-32c." REFERENCE "RFC 3720, Section 12.1, HeaderDigest and DataDigest" ::= { iscsiHeaderIntegrityTypes 2 } iscsiDataIntegrityTypes OBJECT IDENTIFIER ::= { iscsiDescriptors 2 } iscsiDataIntegrityNone OBJECT-IDENTITY STATUS current DESCRIPTION "The authoritative identifier when no integrity scheme (for either the header or data) is being used." REFERENCE "RFC 3720, Section 12.1, HeaderDigest and DataDigest" ::= { iscsiDataIntegrityTypes 1 } iscsiDataIntegrityCrc32c OBJECT-IDENTITY STATUS current DESCRIPTION "The authoritative identifier when the integrity scheme (for either the header or data) is CRC-32c." REFERENCE "RFC 3720, Section 12.1, HeaderDigest and DataDigest" ::= { iscsiDataIntegrityTypes 2 } --********************************************************************** iscsiInstance OBJECT IDENTIFIER ::= { iscsiObjects 1 } -- Instance Attributes Table iscsiInstanceAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiInstanceAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of iSCSI instances present on the system." ::= { iscsiInstance 1 } iscsiInstanceAttributesEntry OBJECT-TYPE SYNTAX IscsiInstanceAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular iSCSI instance." INDEX { iscsiInstIndex } ::= { iscsiInstanceAttributesTable 1 } IscsiInstanceAttributesEntry ::= SEQUENCE { iscsiInstIndex Unsigned32, iscsiInstDescr SnmpAdminString, iscsiInstVersionMin Unsigned32, iscsiInstVersionMax Unsigned32, iscsiInstVendorID SnmpAdminString, iscsiInstVendorVersion SnmpAdminString, iscsiInstPortalNumber Unsigned32, iscsiInstNodeNumber Unsigned32, iscsiInstSessionNumber Unsigned32, iscsiInstSsnFailures Counter32, iscsiInstLastSsnFailureType AutonomousType, iscsiInstLastSsnRmtNodeName IscsiName, iscsiInstDiscontinuityTime TimeStamp } iscsiInstIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular ISCSI instance. This index value must not be modified or reused by an agent unless a reboot has occurred. An agent should attempt to keep this value persistent across reboots." ::= { iscsiInstanceAttributesEntry 1 } iscsiInstDescr OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-only STATUS current DESCRIPTION "A UTF-8 string, determined by the implementation to describe the iSCSI instance. When only a single instance is present, this object may be set to the zero-length string; with multiple iSCSI instances, it may be used in an implementation-dependent manner to describe the purpose of the respective instance." ::= { iscsiInstanceAttributesEntry 2 } iscsiInstVersionMin OBJECT-TYPE SYNTAX Unsigned32 (0..255) MAX-ACCESS read-only STATUS current DESCRIPTION "The minimum version number of the iSCSI specification such that this iSCSI instance supports this minimum value, the maximum value indicated by the corresponding instance in iscsiInstVersionMax, and all versions in between." REFERENCE "RFC 3720, Section 10.12, Login Request" ::= { iscsiInstanceAttributesEntry 3 } iscsiInstVersionMax OBJECT-TYPE SYNTAX Unsigned32 (0..255) MAX-ACCESS read-only STATUS current DESCRIPTION "The maximum version number of the iSCSI specification such that this iSCSI instance supports this maximum value, the minimum value indicated by the corresponding instance in iscsiInstVersionMin, and all versions in between." REFERENCE "RFC 3720, Section 10.12, Login Request" ::= { iscsiInstanceAttributesEntry 4 } iscsiInstVendorID OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-only STATUS current DESCRIPTION "A UTF-8 string describing the manufacturer of the implementation of this instance." ::= { iscsiInstanceAttributesEntry 5 } iscsiInstVendorVersion OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-only STATUS current DESCRIPTION "A UTF-8 string set by the manufacturer describing the version of the implementation of this instance. The format of this string is determined solely by the manufacturer, and is for informational purposes only. It is unrelated to the iSCSI specification version numbers." ::= { iscsiInstanceAttributesEntry 6 } iscsiInstPortalNumber OBJECT-TYPE SYNTAX Unsigned32 UNITS "transport endpoints" MAX-ACCESS read-only STATUS current DESCRIPTION "The number of rows in the iscsiPortalAttributesTable which are currently associated with this iSCSI instance." ::= { iscsiInstanceAttributesEntry 7 } iscsiInstNodeNumber OBJECT-TYPE SYNTAX Unsigned32 UNITS "iSCSI nodes" MAX-ACCESS read-only STATUS current DESCRIPTION "The number of rows in the iscsiNodeAttributesTable which are currently associated with this iSCSI instance." ::= { iscsiInstanceAttributesEntry 8 } iscsiInstSessionNumber OBJECT-TYPE SYNTAX Unsigned32 UNITS "sessions" MAX-ACCESS read-only STATUS current DESCRIPTION "The number of rows in the iscsiSessionAttributesTable which are currently associated with this iSCSI instance." ::= { iscsiInstanceAttributesEntry 9 } iscsiInstSsnFailures OBJECT-TYPE SYNTAX Counter32 UNITS "sessions" MAX-ACCESS read-only STATUS current DESCRIPTION "This object counts the number of times a session belonging to this instance has been failed. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiInstDiscontinuityTime." REFERENCE "RFC 3720, Section 12.1, HeaderDigest and DataDigest" ::= { iscsiInstanceAttributesEntry 10 } iscsiInstLastSsnFailureType OBJECT-TYPE SYNTAX AutonomousType MAX-ACCESS read-only STATUS current DESCRIPTION "The counter object in the iscsiInstSsnErrorStatsTable that was incremented when the last session failure occurred. If the reason for failure is not found in the iscsiInstSsnErrorStatsTable, the value { 0.0 } is used instead." ::= { iscsiInstanceAttributesEntry 11 } iscsiInstLastSsnRmtNodeName OBJECT-TYPE SYNTAX IscsiName MAX-ACCESS read-only STATUS current DESCRIPTION "The iSCSI Name of the remote node from the failed session." ::= { iscsiInstanceAttributesEntry 12 } iscsiInstDiscontinuityTime OBJECT-TYPE SYNTAX TimeStamp MAX-ACCESS read-only STATUS current DESCRIPTION "The value of SysUpTime on the most recent occasion at which any one or more of this instance's counters suffered a discontinuity. If no such discontinuities have occurred since the last re-initialization of the local management subsystem then this object contains a zero value." ::= { iscsiInstanceAttributesEntry 13 } -- Instance Session Failure Stats Table iscsiInstanceSsnErrorStatsTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiInstanceSsnErrorStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "Statistics regarding the occurrences of error types that result in a session failure." ::= { iscsiInstance 2 } iscsiInstanceSsnErrorStatsEntry OBJECT-TYPE SYNTAX IscsiInstanceSsnErrorStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular iSCSI instance." AUGMENTS { iscsiInstanceAttributesEntry } ::= { iscsiInstanceSsnErrorStatsTable 1 } IscsiInstanceSsnErrorStatsEntry ::= SEQUENCE { iscsiInstSsnDigestErrors Counter32, iscsiInstSsnCxnTimeoutErrors Counter32, iscsiInstSsnFormatErrors Counter32 } iscsiInstSsnDigestErrors OBJECT-TYPE SYNTAX Counter32 UNITS "sessions" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of sessions which were failed due to receipt of a PDU containing header or data digest errors. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiInstDiscontinuityTime." REFERENCE "RFC 3720, Section 6.7, Digest Errors" ::= { iscsiInstanceSsnErrorStatsEntry 1 } iscsiInstSsnCxnTimeoutErrors OBJECT-TYPE SYNTAX Counter32 UNITS "sessions" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of sessions which were failed due to a sequence exceeding a time limit. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiInstDiscontinuityTime." REFERENCE "RFC 3720, Section 6.4, Connection Timeout Management" ::= { iscsiInstanceSsnErrorStatsEntry 2 } iscsiInstSsnFormatErrors OBJECT-TYPE SYNTAX Counter32 UNITS "sessions" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of sessions which were failed due to receipt of a PDU which contained a format error. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiInstDiscontinuityTime." REFERENCE "RFC 3720, Section 6.6, Format Errors" ::= { iscsiInstanceSsnErrorStatsEntry 3 } --********************************************************************** iscsiPortal OBJECT IDENTIFIER ::= { iscsiObjects 2 } -- Portal Attributes Table iscsiPortalAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiPortalAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of transport endpoints (using TCP or another transport protocol) used by this iSCSI instance. An iSCSI instance may use a portal to listen for incoming connections to its targets, to initiate connections to other targets, or both." ::= { iscsiPortal 1 } iscsiPortalAttributesEntry OBJECT-TYPE SYNTAX IscsiPortalAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular portal instance." INDEX { iscsiInstIndex, iscsiPortalIndex } ::= { iscsiPortalAttributesTable 1 } IscsiPortalAttributesEntry ::= SEQUENCE { iscsiPortalIndex Unsigned32, iscsiPortalRowStatus RowStatus, iscsiPortalRoles BITS, iscsiPortalAddrType InetAddressType, iscsiPortalAddr InetAddressIPv4, iscsiPortalProtocol IscsiTransportProtocol, iscsiPortalMaxRecvDataSegLength Unsigned32, iscsiPortalPrimaryHdrDigest IscsiDigestMethod, iscsiPortalPrimaryDataDigest IscsiDigestMethod, iscsiPortalSecondaryHdrDigest IscsiDigestMethod, iscsiPortalSecondaryDataDigest IscsiDigestMethod, iscsiPortalRecvMarker TruthValue, iscsiPortalStorageType StorageType } iscsiPortalIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular transport endpoint within this iSCSI instance. This index value must not be modified or reused by an agent unless a reboot has occurred. An agent should attempt to keep this value persistent across reboots." ::= { iscsiPortalAttributesEntry 1 } iscsiPortalRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This field allows entries to be dynamically added and removed from this table via SNMP. When adding a row to this table, all non-Index/RowStatus objects must be set. When the value of this object is 'active', the values of the other objects in this table cannot be changed. Rows may be discarded using RowStatus. Note that creating a row in this table will typically cause the agent to create one or more rows in iscsiTgtPortalAttributesTable and/or iscsiIntrPortalAttributesTable." ::= { iscsiPortalAttributesEntry 2 } iscsiPortalRoles OBJECT-TYPE SYNTAX BITS { targetTypePortal(0), initiatorTypePortal(1) } MAX-ACCESS read-create STATUS current DESCRIPTION "A portal can operate in one or both of two roles: as a target portal and/or an initiator portal. If the portal will operate in both roles, both bits must be set. This object will define a corresponding row that will exist or must be created in the iscsiTgtPortalAttributesTable, the iscsiIntrPortalAttributesTable or both. If the targetTypePortal bit is set, one or more corresponding iscsiTgtPortalAttributesEntry rows will be found or created. If the initiatorTypePortal bit is set, one or more corresponding iscsiIntrPortalAttributesEntry rows will be found or created. If both bits are set, one or more corresponding rows will be found or created in of the above tables." ::= { iscsiPortalAttributesEntry 3 } iscsiPortalAddrType OBJECT-TYPE SYNTAX InetAddressType MAX-ACCESS read-create STATUS current DESCRIPTION "The type of Internet Network Address contained in the corresponding instance of the iscsiPortalAddr." DEFVAL { ipv4 } ::= { iscsiPortalAttributesEntry 4 } iscsiPortalAddr OBJECT-TYPE SYNTAX InetAddressIPv4 MAX-ACCESS read-create STATUS current DESCRIPTION "The portal's Internet Network Address, of the type specified by the object iscsiPortalAddrType. If iscsiPortalAddrType has the value 'dns', this address gets resolved to an IP address whenever a new iSCSI connection is established using this portal." ::= { iscsiPortalAttributesEntry 5 } iscsiPortalProtocol OBJECT-TYPE SYNTAX IscsiTransportProtocol MAX-ACCESS read-create STATUS current DESCRIPTION "The portal's transport protocol." DEFVAL { 6 } -- TCP ::= { iscsiPortalAttributesEntry 6 } iscsiPortalMaxRecvDataSegLength OBJECT-TYPE SYNTAX Unsigned32 (512..16777215) UNITS "bytes" MAX-ACCESS read-create STATUS current DESCRIPTION "The maximum PDU length this portal can receive. This may be constrained by hardware characteristics and individual implementations may choose not to allow this object to be changed." REFERENCE "RFC 3720, Section 12.12, MaxRecvDataSegmentLength" DEFVAL { 8192 } ::= { iscsiPortalAttributesEntry 7 } iscsiPortalPrimaryHdrDigest OBJECT-TYPE SYNTAX IscsiDigestMethod MAX-ACCESS read-create STATUS current DESCRIPTION "The preferred header digest for this portal." DEFVAL { crc32c } ::= { iscsiPortalAttributesEntry 8 } iscsiPortalPrimaryDataDigest OBJECT-TYPE SYNTAX IscsiDigestMethod MAX-ACCESS read-create STATUS current DESCRIPTION "The preferred data digest method for this portal." DEFVAL { crc32c } ::= { iscsiPortalAttributesEntry 9 } iscsiPortalSecondaryHdrDigest OBJECT-TYPE SYNTAX IscsiDigestMethod MAX-ACCESS read-create STATUS current DESCRIPTION "An alternate header digest preference for this portal." DEFVAL { noDigest } ::= { iscsiPortalAttributesEntry 10 } iscsiPortalSecondaryDataDigest OBJECT-TYPE SYNTAX IscsiDigestMethod MAX-ACCESS read-create STATUS current DESCRIPTION "An alternate data digest preference for this portal." DEFVAL { noDigest } ::= { iscsiPortalAttributesEntry 11 } iscsiPortalRecvMarker OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-create STATUS current DESCRIPTION "This object indicates whether or not this portal will request markers in it's incoming data stream." REFERENCE "RFC 3720, Appendix A." DEFVAL { false } ::= { iscsiPortalAttributesEntry 12 } iscsiPortalStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-create STATUS current DESCRIPTION "The storage type for this row. Rows in this table that were created through an external process may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row." DEFVAL { nonVolatile } ::= { iscsiPortalAttributesEntry 13 } --********************************************************************** iscsiTargetPortal OBJECT IDENTIFIER ::= { iscsiObjects 3 } -- Target Portal Attributes Table iscsiTgtPortalAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiTgtPortalAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of transport endpoints (using TCP or another transport protocol) on which this iSCSI instance listens for incoming connections to its targets." ::= { iscsiTargetPortal 1 } iscsiTgtPortalAttributesEntry OBJECT-TYPE SYNTAX IscsiTgtPortalAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular portal instance that is used to listen for incoming connections to local targets. One or more rows in this table is populated by the agent for each iscsiPortalAttributesEntry row that has the bit targetTypePortal set in its iscsiPortalRoles column." INDEX { iscsiInstIndex, iscsiPortalIndex, iscsiTgtPortalNodeIndexOrZero } ::= { iscsiTgtPortalAttributesTable 1 } IscsiTgtPortalAttributesEntry ::= SEQUENCE { iscsiTgtPortalNodeIndexOrZero Unsigned32, iscsiTgtPortalPort InetPortNumber, iscsiTgtPortalTag Unsigned32 } iscsiTgtPortalNodeIndexOrZero OBJECT-TYPE SYNTAX Unsigned32 (0..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular node within an iSCSI instance present on the local system. For implementations where each {portal, node} tuple can have a different portal tag, this value will map to the iscsiNodeIndex. For implementations where the portal tag is the same for a given portal regardless of which node is using the portal, the value 0 (zero) is used." ::= { iscsiTgtPortalAttributesEntry 1 } iscsiTgtPortalPort OBJECT-TYPE SYNTAX InetPortNumber (1..65535) MAX-ACCESS read-write STATUS current DESCRIPTION "The portal's transport protocol port number on which the portal listens for incoming iSCSI connections when the portal is used as a target portal. This object's storage type is specified in iscsiPortalStorageType." ::= { iscsiTgtPortalAttributesEntry 2 } iscsiTgtPortalTag OBJECT-TYPE SYNTAX Unsigned32 (1..65535) MAX-ACCESS read-write STATUS current DESCRIPTION "The portal's aggregation tag when portal is used as a target portal. Multiple-connection sessions may be aggregated over portals sharing an identical aggregation tag. This object's storage type is specified in iscsiPortalStorageType." REFERENCE "RFC 3720, Section 3.4.1, iSCSI Architectural Modell" ::= { iscsiTgtPortalAttributesEntry 3 } --********************************************************************** iscsiInitiatorPortal OBJECT IDENTIFIER ::= { iscsiObjects 4 } -- Initiator Portal Attributes Table iscsiIntrPortalAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiIntrPortalAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of Internet Network Addresses (using TCP or another transport protocol) from which this iSCSI instance may initiate connections to other targets." ::= { iscsiInitiatorPortal 1 } iscsiIntrPortalAttributesEntry OBJECT-TYPE SYNTAX IscsiIntrPortalAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular portal instance that is used to initiate connections to iSCSI targets. One or more rows in this table is populated by the agent for each iscsiPortalAttributesEntry row that has the bit initiatorTypePortal set in its iscsiPortalRoles column." INDEX { iscsiInstIndex, iscsiPortalIndex, iscsiIntrPortalNodeIndexOrZero } ::= { iscsiIntrPortalAttributesTable 1 } IscsiIntrPortalAttributesEntry ::= SEQUENCE { iscsiIntrPortalNodeIndexOrZero Unsigned32, iscsiIntrPortalTag Unsigned32 } iscsiIntrPortalNodeIndexOrZero OBJECT-TYPE SYNTAX Unsigned32 (0..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular node within an iSCSI instance present on the local system. For implementations where each {portal, node} tuple can have a different portal tag, this value will map to the iscsiNodeIndex. For implementations where the portal tag is the same for a given portal regardless of which node is using the portal, the value 0 (zero) is used." ::= { iscsiIntrPortalAttributesEntry 1 } iscsiIntrPortalTag OBJECT-TYPE SYNTAX Unsigned32 (1..65535) MAX-ACCESS read-write STATUS current DESCRIPTION "The portal's aggregation tag when the portal is used as an initiator portal. Multiple-connection sessions may be aggregated over portals sharing an identical aggregation tag. This object's storage type is specified in iscsiPortalStorageType." REFERENCE "RFC 3720, Section 3.4.1, iSCSI Architectural Model" ::= { iscsiIntrPortalAttributesEntry 2 } --********************************************************************** iscsiNode OBJECT IDENTIFIER ::= { iscsiObjects 5 } -- Node Attributes Table iscsiNodeAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiNodeAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of iSCSI nodes belonging to each iSCSI instance present on the local system. An iSCSI node can act as an initiator, a target, or both." ::= { iscsiNode 1 } iscsiNodeAttributesEntry OBJECT-TYPE SYNTAX IscsiNodeAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular iSCSI node." INDEX { iscsiInstIndex, iscsiNodeIndex } ::= { iscsiNodeAttributesTable 1 } IscsiNodeAttributesEntry ::= SEQUENCE { iscsiNodeIndex Unsigned32, iscsiNodeName IscsiName, iscsiNodeAlias SnmpAdminString, iscsiNodeRoles BITS, iscsiNodeTransportType RowPointer, iscsiNodeInitialR2T TruthValue, iscsiNodeImmediateData TruthValue, iscsiNodeMaxOutstandingR2T Unsigned32, iscsiNodeFirstBurstLength Unsigned32, iscsiNodeMaxBurstLength Unsigned32, iscsiNodeMaxConnections Unsigned32, iscsiNodeDataSequenceInOrder TruthValue, iscsiNodeDataPDUInOrder TruthValue, iscsiNodeDefaultTime2Wait Unsigned32, iscsiNodeDefaultTime2Retain Unsigned32, iscsiNodeErrorRecoveryLevel Unsigned32, iscsiNodeDiscontinuityTime TimeStamp, iscsiNodeStorageType StorageType } iscsiNodeIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular node within an iSCSI instance. This index value must not be modified or reused by an agent unless a reboot has occurred. An agent should attempt to keep this value persistent across reboots." ::= { iscsiNodeAttributesEntry 1 } iscsiNodeName OBJECT-TYPE SYNTAX IscsiName MAX-ACCESS read-only STATUS current DESCRIPTION "This node's iSCSI Name, which is independent of the location of the node, and can be resolved into a set of addresses through various discovery services." ::= { iscsiNodeAttributesEntry 2 } iscsiNodeAlias OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-only STATUS current DESCRIPTION "A character string that is a human-readable name or description of the iSCSI node. If configured, this alias may be communicated to the initiator or target node at the remote end of the connection during a Login Request or Response message. This string is not used as an identifier, but can be displayed by the system's user interface in a list of initiators and/or targets to which it is connected. If no alias exists, the value is a zero-length string." REFERENCE "RFC 3720, Section 12.6, TargetAlias, 12.7, InitiatorAlias" ::= { iscsiNodeAttributesEntry 3 } iscsiNodeRoles OBJECT-TYPE SYNTAX BITS { targetTypeNode(0), initiatorTypeNode(1) } MAX-ACCESS read-only STATUS current DESCRIPTION "A node can operate in one or both of two roles: a target role and/or an initiator role. If the node will operate in both roles, both bits must be set. This object will also define the corresponding rows that will exist in the iscsiTargetAttributesTable, the iscsiInitiatorAttributesTable or both. If the targetTypeNode bit is set, there will be a corresponding iscsiTargetAttributesEntry. If the initiatorTypeNode bit is set, there will be a corresponding iscsiInitiatorAttributesEntry. If both bits are set, there will be a corresponding iscsiTgtPortalAttributesEntry and iscsiPortalAttributesEntry." ::= { iscsiNodeAttributesEntry 4 } iscsiNodeTransportType OBJECT-TYPE SYNTAX RowPointer MAX-ACCESS read-only STATUS current DESCRIPTION "A pointer to the corresponding row in the appropriate table for this SCSI transport, thereby allowing management stations to locate the SCSI-level device that is represented by this iscsiNode. For example, it will usually point to the corresponding scsiTrnspt object in the SCSI MIB module. If no corresponding row exists, the value 0.0 must be used to indicate this." REFERENCE "SCSI-MIB" ::= { iscsiNodeAttributesEntry 5 } iscsiNodeInitialR2T OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-only STATUS current DESCRIPTION "This object indicates the InitialR2T preference for this node: true = YES, false = will try to negotiate NO, will accept YES " REFERENCE "RFC 3720, Section 12.10, InitialR2T" ::= { iscsiNodeAttributesEntry 6 } iscsiNodeImmediateData OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-write STATUS current DESCRIPTION "This object indicates ImmediateData preference for this node true = YES (but will accept NO), false = NO " REFERENCE "RFC 3720, Section 12.11, ImmediateData" DEFVAL { true } ::= { iscsiNodeAttributesEntry 7 } iscsiNodeMaxOutstandingR2T OBJECT-TYPE SYNTAX Unsigned32 (1..65535) UNITS "R2Ts" MAX-ACCESS read-write STATUS current DESCRIPTION "Maximum number of outstanding R2Ts allowed per ISCSI task." REFERENCE "RFC 3720, Section 12.17, MaxOutstandingR2T" DEFVAL { 1 } ::= { iscsiNodeAttributesEntry 8 } iscsiNodeFirstBurstLength OBJECT-TYPE SYNTAX Unsigned32 (512..16777215) UNITS "bytes" MAX-ACCESS read-write STATUS current DESCRIPTION "The maximum length (bytes) supported for unsolicited data to/from this node." REFERENCE "RFC 3720, Section 12.14, FirstBurstLength" DEFVAL { 65536 } ::= { iscsiNodeAttributesEntry 9 } iscsiNodeMaxBurstLength OBJECT-TYPE SYNTAX Unsigned32 (512..16777215) UNITS "bytes" MAX-ACCESS read-write STATUS current DESCRIPTION "The maximum number of bytes which can be sent within a single sequence of Data-In or Data-Out PDUs." REFERENCE "RFC 3720, Section 12.13, MaxBurstLength" DEFVAL { 262144 } ::= { iscsiNodeAttributesEntry 10 } iscsiNodeMaxConnections OBJECT-TYPE SYNTAX Unsigned32 (1..65535) UNITS "connections" MAX-ACCESS read-write STATUS current DESCRIPTION "The maximum number of connections allowed in each session to and/or from this node." REFERENCE "RFC 3720, Section 12.2, MaxConnections" DEFVAL { 1 } ::= { iscsiNodeAttributesEntry 11 } iscsiNodeDataSequenceInOrder OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-write STATUS current DESCRIPTION "The DataSequenceInOrder preference of this node. False (=No) indicates that iSCSI data PDU sequences may be transferred in any order. True (=Yes) indicates that data PDU sequences must be transferred using continuously increasing offsets, except during error recovery." REFERENCE "RFC 3720, Section 12.19, DataSequenceInOrder" DEFVAL { true } ::= { iscsiNodeAttributesEntry 12 } iscsiNodeDataPDUInOrder OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-write STATUS current DESCRIPTION "The DataPDUInOrder preference of this node. False (=No) indicates that iSCSI data PDUs within sequences may be in any order. True (=Yes) indicates that data PDUs within sequences must be at continuously increasing addresses, with no gaps or overlay between PDUs." REFERENCE "RFC 3720, Section 12.18, DataPDUInOrder" DEFVAL { true } ::= { iscsiNodeAttributesEntry 13 } iscsiNodeDefaultTime2Wait OBJECT-TYPE SYNTAX Unsigned32 (0..3600) UNITS "seconds" MAX-ACCESS read-write STATUS current DESCRIPTION "The DefaultTime2Wait preference of this node. This is the minimum time, in seconds, to wait before attempting an explicit/implicit logout or active iSCSI task reassignment after an unexpected connection termination or a connection reset." REFERENCE "RFC 3720, Section 12.15, DefaultTime2Wait" DEFVAL { 2 } ::= { iscsiNodeAttributesEntry 14 } iscsiNodeDefaultTime2Retain OBJECT-TYPE SYNTAX Unsigned32 (0..3600) UNITS "seconds" MAX-ACCESS read-write STATUS current DESCRIPTION "The DefaultTime2Retain preference of this node. This is the maximum time, in seconds after an initial wait (Time2Wait), before which an active iSCSI task reassignment is still possible after an unexpected connection termination or a connection reset." REFERENCE "RFC 3720, Section 12.16, DefaultTime2Retain" DEFVAL { 20 } ::= { iscsiNodeAttributesEntry 15 } iscsiNodeErrorRecoveryLevel OBJECT-TYPE SYNTAX Unsigned32 (0..255) MAX-ACCESS read-write STATUS current DESCRIPTION "The ErrorRecoveryLevel preference of this node. Currently, only 0-2 are valid. This object is designed to accommodate future error recover levels. Higher error recovery levels imply support in addition to support for the lower error level functions. In other words, error level 2 implies support for levels 0-1, since those functions are subsets of error level 2." REFERENCE "RFC 3720, Section 12.20, ErrorRecoveryLevel" DEFVAL { 0 } ::= { iscsiNodeAttributesEntry 16 } iscsiNodeDiscontinuityTime OBJECT-TYPE SYNTAX TimeStamp MAX-ACCESS read-only STATUS current DESCRIPTION "The value of SysUpTime on the most recent occasion at which any one or more of this node's counters suffered a discontinuity. If no such discontinuities have occurred since the last re-initialization of the local management subsystem then this object contains a zero value." ::= { iscsiNodeAttributesEntry 17 } iscsiNodeStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-write STATUS current DESCRIPTION "The storage type for all read-write objects within this row. Rows in this table are always created via an external process, and may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row. If this object has the value 'volatile', modifications to read-write objects in this row are not persistent across reboots. If this object has the value 'nonVolatile', modifications to objects in this row are persistent. An implementation may choose to allow this object to be set to either 'nonVolatile' or 'volatile', allowing the management application to choose this behavior." DEFVAL { volatile } ::= { iscsiNodeAttributesEntry 18 } --********************************************************************** iscsiTarget OBJECT IDENTIFIER ::= { iscsiObjects 6 } -- Target Attributes Table iscsiTargetAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiTargetAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of iSCSI nodes that can take on a target role, belonging to each iSCSI instance present on the local system." ::= { iscsiTarget 1 } iscsiTargetAttributesEntry OBJECT-TYPE SYNTAX IscsiTargetAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular node that can take on a target role." INDEX { iscsiInstIndex, iscsiNodeIndex } ::= { iscsiTargetAttributesTable 1 } IscsiTargetAttributesEntry ::= SEQUENCE { iscsiTgtLoginFailures Counter32, iscsiTgtLastFailureTime TimeStamp, iscsiTgtLastFailureType AutonomousType, iscsiTgtLastIntrFailureName IscsiName, iscsiTgtLastIntrFailureAddrType InetAddressType, iscsiTgtLastIntrFailureAddr InetAddressIPv4 } iscsiTgtLoginFailures OBJECT-TYPE SYNTAX Counter32 UNITS "failed login attempts" MAX-ACCESS read-only STATUS current DESCRIPTION "This object counts the number of times a login attempt to this local target has failed. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiTargetAttributesEntry 1 } iscsiTgtLastFailureTime OBJECT-TYPE SYNTAX TimeStamp MAX-ACCESS read-only STATUS current DESCRIPTION "The timestamp of the most recent failure of a login attempt to this target. A value of zero indicates that no such failures have occurred since the last system boot." ::= { iscsiTargetAttributesEntry 2 } iscsiTgtLastFailureType OBJECT-TYPE SYNTAX AutonomousType MAX-ACCESS read-only STATUS current DESCRIPTION "The type of the most recent failure of a login attempt to this target, represented as the OID of the counter object in iscsiTargetLoginStatsTable for which the relevant instance was incremented. A value of 0.0 indicates a type which is not represented by any of the counters in iscsiTargetLoginStatsTable." ::= { iscsiTargetAttributesEntry 3 } iscsiTgtLastIntrFailureName OBJECT-TYPE SYNTAX IscsiName MAX-ACCESS read-only STATUS current DESCRIPTION "The iSCSI Name of the initiator that failed the last login attempt." ::= { iscsiTargetAttributesEntry 4 } iscsiTgtLastIntrFailureAddrType OBJECT-TYPE SYNTAX InetAddressType MAX-ACCESS read-only STATUS current DESCRIPTION "The type of Internet Network Address contained in the corresponding instance of the iscsiTgtLastIntrFailureAddr. The value 'dns' is not allowed." ::= { iscsiTargetAttributesEntry 5 } iscsiTgtLastIntrFailureAddr OBJECT-TYPE SYNTAX InetAddressIPv4 MAX-ACCESS read-only STATUS current DESCRIPTION "An Internet Network Address, of the type specified by the object iscsiTgtLastIntrFailureAddrType, giving the host address of the initiator that failed the last login attempt." ::= { iscsiTargetAttributesEntry 6 } -- Target Login Stats Table iscsiTargetLoginStatsTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiTargetLoginStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A table of counters which keep a record of the results of initiators' login attempts to this target." ::= { iscsiTarget 2 } iscsiTargetLoginStatsEntry OBJECT-TYPE SYNTAX IscsiTargetLoginStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing counters for each result of a login attempt to this target." AUGMENTS { iscsiTargetAttributesEntry } ::= { iscsiTargetLoginStatsTable 1 } IscsiTargetLoginStatsEntry ::= SEQUENCE { iscsiTgtLoginAccepts Counter32, iscsiTgtLoginOtherFails Counter32, iscsiTgtLoginRedirects Counter32, iscsiTgtLoginAuthorizeFails Counter32, iscsiTgtLoginAuthenticateFails Counter32, iscsiTgtLoginNegotiateFails Counter32 } iscsiTgtLoginAccepts OBJECT-TYPE SYNTAX Counter32 UNITS "successful logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Login Response PDUs with status 0x0000, Accept Login, transmitted by this target. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiTargetLoginStatsEntry 1 } iscsiTgtLoginOtherFails OBJECT-TYPE SYNTAX Counter32 UNITS "failed logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The number of Login Response PDUs which were transmitted by this target, and which were not counted by any other object in the row. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiTargetLoginStatsEntry 2 } iscsiTgtLoginRedirects OBJECT-TYPE SYNTAX Counter32 UNITS "redirected logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Login Response PDUs with status class 0x01, Redirection, transmitted by this target. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiTargetLoginStatsEntry 3 } iscsiTgtLoginAuthorizeFails OBJECT-TYPE SYNTAX Counter32 UNITS "failed logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Login Response PDUs with status 0x0202, Forbidden Target, transmitted by this target. If this counter is incremented, an iscsiTgtLoginFailure notification should be generated. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiTargetLoginStatsEntry 4 } iscsiTgtLoginAuthenticateFails OBJECT-TYPE SYNTAX Counter32 UNITS "failed logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Login Response PDUs with status 0x0201, Authentication Failed, transmitted by this target If this counter is incremented, an iscsiTgtLoginFailure notification should be generated. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiTargetLoginStatsEntry 5 } iscsiTgtLoginNegotiateFails OBJECT-TYPE SYNTAX Counter32 UNITS "failed logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The number of times a target has effectively refused a login because the parameter negotiation failed. If this counter is incremented, an iscsiTgtLoginFailure notification should be generated. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." ::= { iscsiTargetLoginStatsEntry 6 } -- Target Logout Stats Table iscsiTargetLogoutStatsTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiTargetLogoutStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "When a target receives a Logout command, it responds with a Logout Response that carries a status code. This table contains counters for both normal and abnormal logout requests received by this target." ::= { iscsiTarget 3 } iscsiTargetLogoutStatsEntry OBJECT-TYPE SYNTAX IscsiTargetLogoutStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing counters of Logout Response PDUs that were received by this target." AUGMENTS { iscsiTargetAttributesEntry } ::= { iscsiTargetLogoutStatsTable 1 } IscsiTargetLogoutStatsEntry ::= SEQUENCE { iscsiTgtLogoutNormals Counter32, iscsiTgtLogoutOthers Counter32 } iscsiTgtLogoutNormals OBJECT-TYPE SYNTAX Counter32 UNITS "normal logouts" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Logout Command PDUs received by this target, with reason code 0 (closes the session). If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.14.1, Reason Code" ::= { iscsiTargetLogoutStatsEntry 1 } iscsiTgtLogoutOthers OBJECT-TYPE SYNTAX Counter32 UNITS "abnormal logouts" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Logout Command PDUs received by this target, with any reason code other than 0. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.14.1, Reason Code" ::= { iscsiTargetLogoutStatsEntry 2 } --********************************************************************** iscsiTgtAuthorization OBJECT IDENTIFIER ::= { iscsiObjects 7 } -- Target Authorization Attributes Table iscsiTgtAuthAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiTgtAuthAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of initiator identities that are authorized to access each target node within each iSCSI instance present on the local system." ::= { iscsiTgtAuthorization 1 } iscsiTgtAuthAttributesEntry OBJECT-TYPE SYNTAX IscsiTgtAuthAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular target node's authorized initiator identity." INDEX { iscsiInstIndex, iscsiNodeIndex, iscsiTgtAuthIndex } ::= { iscsiTgtAuthAttributesTable 1 } IscsiTgtAuthAttributesEntry ::= SEQUENCE { iscsiTgtAuthIndex Unsigned32, iscsiTgtAuthRowStatus RowStatus, iscsiTgtAuthIdentity RowPointer, iscsiTgtAuthStorageType StorageType } iscsiTgtAuthIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular target's authorized initiator identity within an iSCSI instance present on the local system. This index value must not be modified or reused by an agent unless a reboot has occurred. An agent should attempt to keep this value persistent across reboots." ::= { iscsiTgtAuthAttributesEntry 1 } iscsiTgtAuthRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This field allows entries to be dynamically added and removed from this table via SNMP. When adding a row to this table, all non-Index/RowStatus objects must be set. When the value of this object is 'active', the values of the other objects in this table cannot be changed. Rows may be discarded using RowStatus." ::= { iscsiTgtAuthAttributesEntry 2 } iscsiTgtAuthIdentity OBJECT-TYPE SYNTAX RowPointer MAX-ACCESS read-create STATUS current DESCRIPTION "A pointer to the corresponding user entry in the IPS-AUTH MIB module that will be allowed to access this iSCSI target." REFERENCE "IPS-AUTH MIB" ::= { iscsiTgtAuthAttributesEntry 3 } iscsiTgtAuthStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-create STATUS current DESCRIPTION "The storage type for this row. Rows in this table that were created through an external process may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row." DEFVAL { nonVolatile } ::= { iscsiTgtAuthAttributesEntry 4 } --********************************************************************** iscsiInitiator OBJECT IDENTIFIER ::= { iscsiObjects 8 } -- Initiator Attributes Table iscsiInitiatorAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiInitiatorAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of iSCSI nodes that can take on an initiator role, belonging to each iSCSI instance present on the local system." ::= { iscsiInitiator 1 } iscsiInitiatorAttributesEntry OBJECT-TYPE SYNTAX IscsiInitiatorAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular iSCSI node that has initiator capabilities." INDEX { iscsiInstIndex, iscsiNodeIndex } ::= { iscsiInitiatorAttributesTable 1 } IscsiInitiatorAttributesEntry ::= SEQUENCE { iscsiIntrLoginFailures Counter32, iscsiIntrLastFailureTime TimeStamp, iscsiIntrLastFailureType AutonomousType, iscsiIntrLastTgtFailureName IscsiName, iscsiIntrLastTgtFailureAddrType InetAddressType, iscsiIntrLastTgtFailureAddr InetAddress } iscsiIntrLoginFailures OBJECT-TYPE SYNTAX Counter32 UNITS "failed logins" MAX-ACCESS read-only STATUS current DESCRIPTION "This object counts the number of times a login attempt from this local initiator has failed. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiInitiatorAttributesEntry 1 } iscsiIntrLastFailureTime OBJECT-TYPE SYNTAX TimeStamp MAX-ACCESS read-only STATUS current DESCRIPTION "The timestamp of the most recent failure of a login attempt from this initiator. A value of zero indicates that no such failures have occurred since the last system boot." ::= { iscsiInitiatorAttributesEntry 2 } iscsiIntrLastFailureType OBJECT-TYPE SYNTAX AutonomousType MAX-ACCESS read-only STATUS current DESCRIPTION "The type of the most recent failure of a login attempt from this initiator, represented as the OID of the counter object in iscsiInitiatorLoginStatsTable for which the relevant instance was incremented. A value of 0.0 indicates a type which is not represented by any of the counters in iscsiInitiatorLoginStatsTable." ::= { iscsiInitiatorAttributesEntry 3 } iscsiIntrLastTgtFailureName OBJECT-TYPE SYNTAX IscsiName MAX-ACCESS read-only STATUS current DESCRIPTION "A UTF-8 string giving the name of the target that failed the last login attempt." ::= { iscsiInitiatorAttributesEntry 4 } iscsiIntrLastTgtFailureAddrType OBJECT-TYPE SYNTAX InetAddressType MAX-ACCESS read-only STATUS current DESCRIPTION "The type of Internet Network Address contained in the corresponding instance of the iscsiIntrLastTgtFailureAddr. The value 'dns' is not allowed." ::= { iscsiInitiatorAttributesEntry 5 } iscsiIntrLastTgtFailureAddr OBJECT-TYPE SYNTAX InetAddress MAX-ACCESS read-only STATUS current DESCRIPTION "An Internet Network Address, of the type specified by the object iscsiIntrLastTgtFailureAddrType, giving the host address of the target that failed the last login attempt." ::= { iscsiInitiatorAttributesEntry 6 } -- Initiator Login Stats Table iscsiInitiatorLoginStatsTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiInitiatorLoginStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A table of counters which keep track of the results of this initiator's login attempts." ::= { iscsiInitiator 2 } iscsiInitiatorLoginStatsEntry OBJECT-TYPE SYNTAX IscsiInitiatorLoginStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing counters of each result of this initiator's login attempts." AUGMENTS { iscsiInitiatorAttributesEntry } ::= { iscsiInitiatorLoginStatsTable 1 } IscsiInitiatorLoginStatsEntry ::= SEQUENCE { iscsiIntrLoginAcceptRsps Counter32, iscsiIntrLoginOtherFailRsps Counter32, iscsiIntrLoginRedirectRsps Counter32, iscsiIntrLoginAuthFailRsps Counter32, iscsiIntrLoginAuthenticateFails Counter32, iscsiIntrLoginNegotiateFails Counter32 } iscsiIntrLoginAcceptRsps OBJECT-TYPE SYNTAX Counter32 UNITS "successful logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Login Response PDUs with status 0x0000, Accept Login, received by this initiator. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiInitiatorLoginStatsEntry 1 } iscsiIntrLoginOtherFailRsps OBJECT-TYPE SYNTAX Counter32 UNITS "failed logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Login Response PDUs received by this initiator with any status code not counted in the objects below. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiInitiatorLoginStatsEntry 2 } iscsiIntrLoginRedirectRsps OBJECT-TYPE SYNTAX Counter32 UNITS "failed logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Login Response PDUs with status class 0x01, Redirection, received by this initiator. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiInitiatorLoginStatsEntry 3 } iscsiIntrLoginAuthFailRsps OBJECT-TYPE SYNTAX Counter32 UNITS "failed logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Login Response PDUs with status class 0x201, Authentication Failed, received by this initiator. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiInitiatorLoginStatsEntry 4 } iscsiIntrLoginAuthenticateFails OBJECT-TYPE SYNTAX Counter32 UNITS "failed logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The number of times the initiator has aborted a login because the target could not be authenticated. No response is generated. If this counter is incremented, an iscsiIntrLoginFailure notification should be generated. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.13.5, Status-Class and Status-Detail" ::= { iscsiInitiatorLoginStatsEntry 5 } iscsiIntrLoginNegotiateFails OBJECT-TYPE SYNTAX Counter32 UNITS "failed logins" MAX-ACCESS read-only STATUS current DESCRIPTION "The number of times the initiator has aborted a login because parameter negotiation with the target failed. No response is generated. If this counter is incremented, an iscsiIntrLoginFailure notification should be generated. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 6.10, Negotiation Failures" ::= { iscsiInitiatorLoginStatsEntry 6 } -- Initiator Logout Stats Table iscsiInitiatorLogoutStatsTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiInitiatorLogoutStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "When an initiator attempts send a Logout command, the target responds with a Logout Response that carries a status code. This table contains a list of counters of Logout Response PDUs of each status code, that were received by each initiator belonging to this iSCSI instance present on this system." ::= { iscsiInitiator 3 } iscsiInitiatorLogoutStatsEntry OBJECT-TYPE SYNTAX IscsiInitiatorLogoutStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing counters of Logout Response PDUs of each status code, that were generated by this initiator." AUGMENTS { iscsiInitiatorAttributesEntry } ::= { iscsiInitiatorLogoutStatsTable 1 } IscsiInitiatorLogoutStatsEntry ::= SEQUENCE { iscsiIntrLogoutNormals Counter32, iscsiIntrLogoutOthers Counter32 } iscsiIntrLogoutNormals OBJECT-TYPE SYNTAX Counter32 UNITS "normal logouts" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Logout Command PDUs generated by this initiator with reason code 0 (closes the session). If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.14.1, Reason Code" ::= { iscsiInitiatorLogoutStatsEntry 1 } iscsiIntrLogoutOthers OBJECT-TYPE SYNTAX Counter32 UNITS "abnormal logouts" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Logout Command PDUs generated by this initiator with any status code other than 0. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiNodeDiscontinuityTime." REFERENCE "RFC 3720, Section 10.14.1, Reason Code" ::= { iscsiInitiatorLogoutStatsEntry 2 } --********************************************************************** iscsiIntrAuthorization OBJECT IDENTIFIER ::= { iscsiObjects 9 } -- Initiator Authorization Attributes Table iscsiIntrAuthAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiIntrAuthAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of target identities which each initiator on the local system may access." ::= { iscsiIntrAuthorization 1 } iscsiIntrAuthAttributesEntry OBJECT-TYPE SYNTAX IscsiIntrAuthAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular initiator node's authorized target identity." INDEX { iscsiInstIndex, iscsiNodeIndex, iscsiIntrAuthIndex } ::= { iscsiIntrAuthAttributesTable 1 } IscsiIntrAuthAttributesEntry ::= SEQUENCE { iscsiIntrAuthIndex Unsigned32, iscsiIntrAuthRowStatus RowStatus, iscsiIntrAuthIdentity RowPointer, iscsiIntrAuthStorageType StorageType } iscsiIntrAuthIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular initiator node's authorized target identity within an iSCSI instance present on the local system. This index value must not be modified or reused by an agent unless a reboot has occurred. An agent should attempt to keep this value persistent across reboots." ::= { iscsiIntrAuthAttributesEntry 1 } iscsiIntrAuthRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This field allows entries to be dynamically added and removed from this table via SNMP. When adding a row to this table, all non-Index/RowStatus objects must be set. When the value of this object is 'active', the values of the other objects in this table cannot be changed. Rows may be discarded using RowStatus." ::= { iscsiIntrAuthAttributesEntry 2 } iscsiIntrAuthIdentity OBJECT-TYPE SYNTAX RowPointer MAX-ACCESS read-create STATUS current DESCRIPTION "A pointer to the corresponding user entry in the IPS-AUTH MIB module to which this initiator node should attempt to establish an iSCSI session." REFERENCE "IPS-AUTH MIB" ::= { iscsiIntrAuthAttributesEntry 3 } iscsiIntrAuthStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-create STATUS current DESCRIPTION "The storage type for this row. Rows in this table that were created through an external process may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row." DEFVAL { nonVolatile } ::= { iscsiIntrAuthAttributesEntry 4 } --********************************************************************** iscsiSession OBJECT IDENTIFIER ::= { iscsiObjects 10 } -- Session Attributes Table iscsiSessionAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiSessionAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of sessions belonging to each iSCSI instance present on the system." ::= { iscsiSession 1 } iscsiSessionAttributesEntry OBJECT-TYPE SYNTAX IscsiSessionAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular session. If this session is a discovery session which is not attached to any particular node, the iscsiSsnNodeIndex will be zero. Otherwise, the iscsiSsnNodeIndex will have the same value as iscsiNodeIndex." INDEX { iscsiInstIndex, iscsiSsnNodeIndex, iscsiSsnIndex } ::= { iscsiSessionAttributesTable 1 } IscsiSessionAttributesEntry ::= SEQUENCE { iscsiSsnNodeIndex Unsigned32, iscsiSsnIndex Unsigned32, iscsiSsnDirection INTEGER, iscsiSsnInitiatorName IscsiName, iscsiSsnTargetName IscsiName, iscsiSsnTSIH Unsigned32, iscsiSsnISID OCTET STRING, iscsiSsnInitiatorAlias SnmpAdminString, iscsiSsnTargetAlias SnmpAdminString, iscsiSsnInitialR2T TruthValue, iscsiSsnImmediateData TruthValue, iscsiSsnType INTEGER, iscsiSsnMaxOutstandingR2T Unsigned32, iscsiSsnFirstBurstLength Unsigned32, iscsiSsnMaxBurstLength Unsigned32, iscsiSsnConnectionNumber Gauge32, iscsiSsnAuthIdentity RowPointer, iscsiSsnDataSequenceInOrder TruthValue, iscsiSsnDataPDUInOrder TruthValue, iscsiSsnErrorRecoveryLevel Unsigned32, iscsiSsnDiscontinuityTime TimeStamp } iscsiSsnNodeIndex OBJECT-TYPE SYNTAX Unsigned32 (0..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular node within an iSCSI instance present on the local system. For normal, non-discovery sessions, this value will map to the iscsiNodeIndex. For discovery sessions which do not have a node associated, the value 0 (zero) is used." ::= { iscsiSessionAttributesEntry 1 } iscsiSsnIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular session within an iSCSI instance present on the local system. An agent should attempt to not reuse index values unless a reboot has occurred. iSCSI sessions are destroyed during a reboot; rows in this table are not persistent across reboots." ::= { iscsiSessionAttributesEntry 2 } iscsiSsnDirection OBJECT-TYPE SYNTAX INTEGER { inboundSession(1), outboundSession(2) } MAX-ACCESS read-only STATUS current DESCRIPTION "Direction of iSCSI session: InboundSession - session is established from an external initiator to a target within this iSCSI instance. OutboundSession - session is established from an initiator within this iSCSI instance to an external target." ::= { iscsiSessionAttributesEntry 3 } iscsiSsnInitiatorName OBJECT-TYPE SYNTAX IscsiName MAX-ACCESS read-only STATUS current DESCRIPTION "If iscsiSsnDirection is Inbound, this object is a UTF-8 string that will contain the name of the remote initiator. If this session is a discovery session that does not specify a particular initiator, this object will contain a zero-length string. If iscsiSsnDirection is Outbound, this object will contain a zero-length string." ::= { iscsiSessionAttributesEntry 4 } iscsiSsnTargetName OBJECT-TYPE SYNTAX IscsiName MAX-ACCESS read-only STATUS current DESCRIPTION "If iscsiSsnDirection is Outbound, this object is a UTF-8 string that will contain the name of the remote target. If this session is a discovery session that does not specify a particular target, this object will contain a zero-length string. If iscsiSsnDirection is Inbound, this object will contain a zero-length string." ::= { iscsiSessionAttributesEntry 5 } iscsiSsnTSIH OBJECT-TYPE SYNTAX Unsigned32 (1..65535) MAX-ACCESS read-only STATUS current DESCRIPTION "The target-defined identification handle for this session." REFERENCE "RFC 3720, Section 10.12.6, TSIH" ::= { iscsiSessionAttributesEntry 6 } iscsiSsnISID OBJECT-TYPE SYNTAX OCTET STRING (SIZE(6)) MAX-ACCESS read-only STATUS current DESCRIPTION "The initiator-defined portion of the iSCSI Session ID." REFERENCE "RFC 3720, Section 10.12.5, ISID" ::= { iscsiSessionAttributesEntry 7 } iscsiSsnInitiatorAlias OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-only STATUS current DESCRIPTION "A UTF-8 string that gives the alias communicated by the initiator end of the session during the login phase. If no alias exists, the value is a zero-length string." REFERENCE "RFC 3720, Section 12.7, InitiatorAlias" ::= { iscsiSessionAttributesEntry 8 } iscsiSsnTargetAlias OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-only STATUS current DESCRIPTION "A UTF-8 string that gives the alias communicated by the target end of the session during the login phase. If no alias exists, the value is a zero-length string." REFERENCE "RFC 3720, Section 12.6, TargetAlias" ::= { iscsiSessionAttributesEntry 9 } iscsiSsnInitialR2T OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-only STATUS current DESCRIPTION "If set to true, indicates that the initiator must wait for an R2T before sending to the target. If set to false, the initiator may send data immediately, within limits set by iscsiSsnFirstBurstLength and the expected data transfer length of the request." REFERENCE "RFC 3720, Section 12.10, InitialR2T" ::= { iscsiSessionAttributesEntry 10 } iscsiSsnImmediateData OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-only STATUS current DESCRIPTION "Indicates whether the initiator and target have agreed to support immediate data on this session." REFERENCE "RFC 3720, Section 12.11, ImmediateData" ::= { iscsiSessionAttributesEntry 11 } iscsiSsnType OBJECT-TYPE SYNTAX INTEGER { normalSession(1), discoverySession(2) } MAX-ACCESS read-only STATUS current DESCRIPTION "Type of iSCSI session: normalSession - session is a normal iSCSI session discoverySession - session is being used only for discovery." REFERENCE "RFC 3720, Section 12.21, SessionType" ::= { iscsiSessionAttributesEntry 12 } iscsiSsnMaxOutstandingR2T OBJECT-TYPE SYNTAX Unsigned32 (1..65535) UNITS "R2Ts" MAX-ACCESS read-only STATUS current DESCRIPTION "The maximum number of outstanding request-to-transmit (R2T)s per iSCSI task within this session." REFERENCE "RFC 3720, Section 12.17, MaxOutstandingR2T" ::= { iscsiSessionAttributesEntry 13 } iscsiSsnFirstBurstLength OBJECT-TYPE SYNTAX Unsigned32 (512..16777215) UNITS "bytes" MAX-ACCESS read-only STATUS current DESCRIPTION "The maximum length supported for unsolicited data sent within this session." REFERENCE "RFC 3720, Section 12.14, FirstBurstLength" ::= { iscsiSessionAttributesEntry 14 } iscsiSsnMaxBurstLength OBJECT-TYPE SYNTAX Unsigned32 (512..16777215) UNITS "bytes" MAX-ACCESS read-only STATUS current DESCRIPTION "The maximum number of bytes which can be sent within a single sequence of Data-In or Data-Out PDUs." REFERENCE "RFC 3720, Section 12.13, MaxBurstLength" ::= { iscsiSessionAttributesEntry 15 } iscsiSsnConnectionNumber OBJECT-TYPE SYNTAX Gauge32 (1..65535) UNITS "connections" MAX-ACCESS read-only STATUS current DESCRIPTION "The number of transport protocol connections that currently belong to this session." ::= { iscsiSessionAttributesEntry 16 } iscsiSsnAuthIdentity OBJECT-TYPE SYNTAX RowPointer MAX-ACCESS read-only STATUS current DESCRIPTION "This object contains a pointer to a row in the IPS-AUTH MIB module which identifies the authentication method being used on this session, as communicated during the login phase." REFERENCE "IPS-AUTH MIB" ::= { iscsiSessionAttributesEntry 17 } iscsiSsnDataSequenceInOrder OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-only STATUS current DESCRIPTION "False indicates that iSCSI data PDU sequences may be transferred in any order. True indicates that data PDU sequences must be transferred using continuously increasing offsets, except during error recovery." REFERENCE "RFC 3720, Section 12.19, DataSequenceInOrder" ::= { iscsiSessionAttributesEntry 18 } iscsiSsnDataPDUInOrder OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-only STATUS current DESCRIPTION "False indicates that iSCSI data PDUs within sequences may be in any order. True indicates that data PDUs within sequences must be at continuously increasing addresses, with no gaps or overlay between PDUs. Default is true." REFERENCE "RFC 3720, Section 12.18, DataPDUInOrder" ::= { iscsiSessionAttributesEntry 19 } iscsiSsnErrorRecoveryLevel OBJECT-TYPE SYNTAX Unsigned32 (0..255) MAX-ACCESS read-only STATUS current DESCRIPTION "The level of error recovery negotiated between the initiator and the target. Higher numbers represent more detailed recovery schemes." REFERENCE "RFC 3720, Section 12.20, ErrorRecoveryLevel" ::= { iscsiSessionAttributesEntry 20 } iscsiSsnDiscontinuityTime OBJECT-TYPE SYNTAX TimeStamp MAX-ACCESS read-only STATUS current DESCRIPTION "The value of SysUpTime on the most recent occasion at which any one or more of this session's counters suffered a discontinuity. When a session is established, and this object is created, it is initialized to the current value of SysUpTime." ::= { iscsiSessionAttributesEntry 21 } -- Session Stats Table iscsiSessionStatsTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiSessionStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of general iSCSI traffic counters for each of the sessions present on the system." ::= { iscsiSession 2 } iscsiSessionStatsEntry OBJECT-TYPE SYNTAX IscsiSessionStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing general iSCSI traffic counters for a particular session." AUGMENTS { iscsiSessionAttributesEntry } ::= { iscsiSessionStatsTable 1 } IscsiSessionStatsEntry ::= SEQUENCE { iscsiSsnCmdPDUs Counter32, iscsiSsnRspPDUs Counter32, iscsiSsnTxDataOctets Counter64, iscsiSsnRxDataOctets Counter64, iscsiSsnLCTxDataOctets Counter32, iscsiSsnLCRxDataOctets Counter32 } iscsiSsnCmdPDUs OBJECT-TYPE SYNTAX Counter32 UNITS "PDUs" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Command PDUs transferred on this session. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiSsnDiscontinuityTime." ::= { iscsiSessionStatsEntry 1 } iscsiSsnRspPDUs OBJECT-TYPE SYNTAX Counter32 UNITS "PDUs" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of Response PDUs transferred on this session. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiSsnDiscontinuityTime." ::= { iscsiSessionStatsEntry 2 } iscsiSsnTxDataOctets OBJECT-TYPE SYNTAX Counter64 UNITS "octets" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of data octets that were transmitted by the local iSCSI node on this session. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiSsnDiscontinuityTime." ::= { iscsiSessionStatsEntry 3 } iscsiSsnRxDataOctets OBJECT-TYPE SYNTAX Counter64 UNITS "octets" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of data octets that were received by the local iSCSI node on this session. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiSsnDiscontinuityTime." ::= { iscsiSessionStatsEntry 4 } iscsiSsnLCTxDataOctets OBJECT-TYPE SYNTAX Counter32 UNITS "octets" MAX-ACCESS read-only STATUS current DESCRIPTION "A Low Capacity shadow object of iscsiSsnTxDataOctets for those systems that don't support Counter64. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiSsnDiscontinuityTime." ::= { iscsiSessionStatsEntry 5 } iscsiSsnLCRxDataOctets OBJECT-TYPE SYNTAX Counter32 UNITS "octets" MAX-ACCESS read-only STATUS current DESCRIPTION "A Low Capacity shadow object of iscsiSsnRxDataOctets for those systems that don't support Counter64. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiSsnDiscontinuityTime." ::= { iscsiSessionStatsEntry 6 } -- Session Connection Error Stats Table iscsiSessionCxnErrorStatsTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiSessionCxnErrorStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of error counters for each of the sessions present on this system." ::= { iscsiSession 3 } iscsiSessionCxnErrorStatsEntry OBJECT-TYPE SYNTAX IscsiSessionCxnErrorStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing error counters for a particular session." AUGMENTS { iscsiSessionAttributesEntry } ::= { iscsiSessionCxnErrorStatsTable 1 } IscsiSessionCxnErrorStatsEntry ::= SEQUENCE { iscsiSsnCxnDigestErrors Counter32, iscsiSsnCxnTimeoutErrors Counter32 } iscsiSsnCxnDigestErrors OBJECT-TYPE SYNTAX Counter32 UNITS "PDUs" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of PDUs which were received on the session and contained header or data digest errors. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiSsnDiscontinuityTime." REFERENCE "RFC 3720, Section 6.7, Digest Errors" ::= { iscsiSessionCxnErrorStatsEntry 1 } iscsiSsnCxnTimeoutErrors OBJECT-TYPE SYNTAX Counter32 UNITS "connections" MAX-ACCESS read-only STATUS current DESCRIPTION "The count of connections within this session which have been terminated due to timeout. If this counter has suffered a discontinuity, the time of the last discontinuity is indicated in iscsiSsnDiscontinuityTime." REFERENCE "RFC 3720, Section 6.4, Connection Timeout Management" ::= { iscsiSessionCxnErrorStatsEntry 2 } --********************************************************************** iscsiConnection OBJECT IDENTIFIER ::= { iscsiObjects 11 } -- Connection Attributes Table iscsiConnectionAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IscsiConnectionAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of connections belonging to each iSCSI instance present on the system." ::= { iscsiConnection 1 } iscsiConnectionAttributesEntry OBJECT-TYPE SYNTAX IscsiConnectionAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular connection." INDEX { iscsiInstIndex, iscsiSsnNodeIndex, iscsiSsnIndex, iscsiCxnIndex } ::= { iscsiConnectionAttributesTable 1 } IscsiConnectionAttributesEntry ::= SEQUENCE { iscsiCxnIndex Unsigned32, iscsiCxnCid Unsigned32, iscsiCxnState INTEGER, iscsiCxnAddrType InetAddressType, iscsiCxnLocalAddr InetAddressIPv4, iscsiCxnProtocol IscsiTransportProtocol, iscsiCxnLocalPort InetPortNumber, iscsiCxnRemoteAddr InetAddressIPv4, iscsiCxnRemotePort InetPortNumber, iscsiCxnMaxRecvDataSegLength Unsigned32, iscsiCxnMaxXmitDataSegLength Unsigned32, iscsiCxnHeaderIntegrity IscsiDigestMethod, iscsiCxnDataIntegrity IscsiDigestMethod, iscsiCxnRecvMarker TruthValue, iscsiCxnSendMarker TruthValue, iscsiCxnVersionActive Unsigned32 } iscsiCxnIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular connection of a particular session within an iSCSI instance present on the local system. An agent should attempt to not reuse index values unless a reboot has occurred. iSCSI connections are destroyed during a reboot; rows in this table are not persistent across reboots." ::= { iscsiConnectionAttributesEntry 1 } iscsiCxnCid OBJECT-TYPE SYNTAX Unsigned32 (1..65535) MAX-ACCESS read-only STATUS current DESCRIPTION "The iSCSI Connection ID for this connection." ::= { iscsiConnectionAttributesEntry 2 } iscsiCxnState OBJECT-TYPE SYNTAX INTEGER { login(1), full(2), logout(3) } MAX-ACCESS read-only STATUS current DESCRIPTION "The current state of this connection, from an iSCSI negotiation point of view. Here are the states: login - The transport protocol connection has been established, but a valid iSCSI login response with the final bit set has not been sent or received. full - A valid iSCSI login response with the final bit set has been sent or received. logout - A valid iSCSI logout command has been sent or received, but the transport protocol connection has not yet been closed." ::= { iscsiConnectionAttributesEntry 3 } iscsiCxnAddrType OBJECT-TYPE SYNTAX InetAddressType MAX-ACCESS read-only STATUS current DESCRIPTION "The type of Internet Network Addresses contained in the corresponding instances of iscsiCxnLocalAddr and iscsiCxnRemoteAddr. The value 'dns' is not allowed." ::= { iscsiConnectionAttributesEntry 4 } iscsiCxnLocalAddr OBJECT-TYPE SYNTAX InetAddressIPv4 MAX-ACCESS read-only STATUS current DESCRIPTION "The local Internet Network Address, of the type specified by iscsiCxnAddrType, used by this connection." ::= { iscsiConnectionAttributesEntry 5 } iscsiCxnProtocol OBJECT-TYPE SYNTAX IscsiTransportProtocol MAX-ACCESS read-only STATUS current DESCRIPTION "The transport protocol over which this connection is running." ::= { iscsiConnectionAttributesEntry 6 } iscsiCxnLocalPort OBJECT-TYPE SYNTAX InetPortNumber MAX-ACCESS read-only STATUS current DESCRIPTION "The local transport protocol port used by this connection. This object cannot have the value zero, since it represents an established connection." ::= { iscsiConnectionAttributesEntry 7 } iscsiCxnRemoteAddr OBJECT-TYPE SYNTAX InetAddressIPv4 MAX-ACCESS read-only STATUS current DESCRIPTION "The remote Internet Network Address, of the type specified by iscsiCxnAddrType, used by this connection." ::= { iscsiConnectionAttributesEntry 8 } iscsiCxnRemotePort OBJECT-TYPE SYNTAX InetPortNumber MAX-ACCESS read-only STATUS current DESCRIPTION "The remote transport protocol port used by this connection. This object cannot have the value zero, since it represents an established connection." ::= { iscsiConnectionAttributesEntry 9 } iscsiCxnMaxRecvDataSegLength OBJECT-TYPE SYNTAX Unsigned32 (512..16777215) UNITS "bytes" MAX-ACCESS read-only STATUS current DESCRIPTION "The maximum data payload size supported for command or data PDUs able to be received on this connection." REFERENCE "RFC 3720, Section 12.12, MaxRecvDataSegmentLength" ::= { iscsiConnectionAttributesEntry 10 } iscsiCxnMaxXmitDataSegLength OBJECT-TYPE SYNTAX Unsigned32 (512..16777215) UNITS "bytes" MAX-ACCESS read-only STATUS current DESCRIPTION "The maximum data payload size supported for command or data PDUs to be sent on this connection." REFERENCE "RFC 3720, Section 12.12, MaxRecvDataSegmentLength" ::= { iscsiConnectionAttributesEntry 11 } iscsiCxnHeaderIntegrity OBJECT-TYPE SYNTAX IscsiDigestMethod MAX-ACCESS read-only STATUS current DESCRIPTION "This object identifies the iSCSI header digest scheme in use within this connection." ::= { iscsiConnectionAttributesEntry 12 } iscsiCxnDataIntegrity OBJECT-TYPE SYNTAX IscsiDigestMethod MAX-ACCESS read-only STATUS current DESCRIPTION "This object identifies the iSCSI data digest scheme in use within this connection." ::= { iscsiConnectionAttributesEntry 13 } iscsiCxnRecvMarker OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-only STATUS current DESCRIPTION "This object indicates whether or not this connection is receiving markers in in its incoming data stream." REFERENCE "RFC 3720, Appendix A." ::= { iscsiConnectionAttributesEntry 14 } iscsiCxnSendMarker OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-only STATUS current DESCRIPTION "This object indicates whether or not this connection is inserting markers in in its outgoing data stream." REFERENCE "RFC 3720, Appendix A." ::= { iscsiConnectionAttributesEntry 15 } iscsiCxnVersionActive OBJECT-TYPE SYNTAX Unsigned32 (0..255) MAX-ACCESS read-only STATUS current DESCRIPTION "Active version number of the iSCSI specification negotiated on this connection." REFERENCE "RFC 3720, Section 10.12, Login Request" ::= { iscsiConnectionAttributesEntry 16 } --********************************************************************** -- Notifications iscsiTgtLoginFailure NOTIFICATION-TYPE OBJECTS { iscsiTgtLoginFailures, iscsiTgtLastFailureType, iscsiTgtLastIntrFailureName, iscsiTgtLastIntrFailureAddrType, iscsiTgtLastIntrFailureAddr } STATUS current DESCRIPTION "Sent when a login is failed by a target. To avoid sending an excessive number of notifications due to multiple errors counted, an SNMP agent implementing this notification SHOULD NOT send more than 3 notifications of this type in any 10 second time period." ::= { iscsiNotifications 1 } iscsiIntrLoginFailure NOTIFICATION-TYPE OBJECTS { iscsiIntrLoginFailures, iscsiIntrLastFailureType, iscsiIntrLastTgtFailureName, iscsiIntrLastTgtFailureAddrType, iscsiIntrLastTgtFailureAddr } STATUS current DESCRIPTION "Sent when a login is failed by a initiator. To avoid sending an excessive number of notifications due to multiple errors counted, an SNMP agent implementing this notification SHOULD NOT send more than 3 notifications of this type in any 10 second time period." ::= { iscsiNotifications 2 } iscsiInstSessionFailure NOTIFICATION-TYPE OBJECTS { iscsiInstSsnFailures, iscsiInstLastSsnFailureType, iscsiInstLastSsnRmtNodeName } STATUS current DESCRIPTION "Sent when an active session is failed by either the initiator or the target. To avoid sending an excessive number of notifications due to multiple errors counted, an SNMP agent implementing this notification SHOULD NOT send more than 3 notifications of this type in any 10 second time period." ::= { iscsiNotifications 3 } --********************************************************************** -- Conformance Statements iscsiCompliances OBJECT IDENTIFIER ::= { iscsiConformance 1 } iscsiGroups OBJECT IDENTIFIER ::= { iscsiConformance 2 } iscsiInstanceAttributesGroup OBJECT-GROUP OBJECTS { iscsiInstDescr, iscsiInstVersionMin, iscsiInstVersionMax, iscsiInstVendorID, iscsiInstVendorVersion, iscsiInstPortalNumber, iscsiInstNodeNumber, iscsiInstSessionNumber, iscsiInstSsnFailures, iscsiInstLastSsnFailureType, iscsiInstLastSsnRmtNodeName, iscsiInstDiscontinuityTime } STATUS current DESCRIPTION "A collection of objects providing information about iSCSI instances." ::= { iscsiGroups 1 } iscsiInstanceSsnErrorStatsGroup OBJECT-GROUP OBJECTS { iscsiInstSsnDigestErrors, iscsiInstSsnCxnTimeoutErrors, iscsiInstSsnFormatErrors } STATUS current DESCRIPTION "A collection of objects providing information about errors that have caused a session failure for an iSCSI instance." ::= { iscsiGroups 2 } iscsiPortalAttributesGroup OBJECT-GROUP OBJECTS { iscsiPortalRowStatus, iscsiPortalStorageType, iscsiPortalRoles, iscsiPortalAddrType, iscsiPortalAddr, iscsiPortalProtocol, iscsiPortalMaxRecvDataSegLength, iscsiPortalPrimaryHdrDigest, iscsiPortalPrimaryDataDigest, iscsiPortalSecondaryHdrDigest, iscsiPortalSecondaryDataDigest, iscsiPortalRecvMarker } STATUS current DESCRIPTION "A collection of objects providing information about the transport protocol endpoints of the local targets." ::= { iscsiGroups 3 } iscsiTgtPortalAttributesGroup OBJECT-GROUP OBJECTS { iscsiTgtPortalPort, iscsiTgtPortalTag } STATUS current DESCRIPTION "A collection of objects providing information about the transport protocol endpoints of the local targets." ::= { iscsiGroups 4 } iscsiIntrPortalAttributesGroup OBJECT-GROUP OBJECTS { iscsiIntrPortalTag } STATUS current DESCRIPTION "An object providing information about the portal tags used by the local initiators." ::= { iscsiGroups 5 } iscsiNodeAttributesGroup OBJECT-GROUP OBJECTS { iscsiNodeName, iscsiNodeAlias, iscsiNodeRoles, iscsiNodeTransportType, iscsiNodeInitialR2T, iscsiNodeImmediateData, iscsiNodeMaxOutstandingR2T, iscsiNodeFirstBurstLength, iscsiNodeMaxBurstLength, iscsiNodeMaxConnections, iscsiNodeDataSequenceInOrder, iscsiNodeDataPDUInOrder, iscsiNodeDefaultTime2Wait, iscsiNodeDefaultTime2Retain, iscsiNodeErrorRecoveryLevel, iscsiNodeDiscontinuityTime, iscsiNodeStorageType } STATUS current DESCRIPTION "A collection of objects providing information about all local targets." ::= { iscsiGroups 6 } iscsiTargetAttributesGroup OBJECT-GROUP OBJECTS { iscsiTgtLoginFailures, iscsiTgtLastFailureTime, iscsiTgtLastFailureType, iscsiTgtLastIntrFailureName, iscsiTgtLastIntrFailureAddrType, iscsiTgtLastIntrFailureAddr } STATUS current DESCRIPTION "A collection of objects providing information about all local targets." ::= { iscsiGroups 7 } iscsiTargetLoginStatsGroup OBJECT-GROUP OBJECTS { iscsiTgtLoginAccepts, iscsiTgtLoginOtherFails, iscsiTgtLoginRedirects, iscsiTgtLoginAuthorizeFails, iscsiTgtLoginAuthenticateFails, iscsiTgtLoginNegotiateFails } STATUS current DESCRIPTION "A collection of objects providing information about all login attempts by remote initiators to local targets." ::= { iscsiGroups 8 } iscsiTargetLogoutStatsGroup OBJECT-GROUP OBJECTS { iscsiTgtLogoutNormals, iscsiTgtLogoutOthers } STATUS current DESCRIPTION "A collection of objects providing information about all logout events between remote initiators to local targets." ::= { iscsiGroups 9 } iscsiTargetAuthGroup OBJECT-GROUP OBJECTS { iscsiTgtAuthRowStatus, iscsiTgtAuthStorageType, iscsiTgtAuthIdentity } STATUS current DESCRIPTION "A collection of objects providing information about all remote initiators that are authorized to connect to local targets." ::= { iscsiGroups 10 } iscsiInitiatorAttributesGroup OBJECT-GROUP OBJECTS { iscsiIntrLoginFailures, iscsiIntrLastFailureTime, iscsiIntrLastFailureType, iscsiIntrLastTgtFailureName, iscsiIntrLastTgtFailureAddrType, iscsiIntrLastTgtFailureAddr } STATUS current DESCRIPTION "A collection of objects providing information about all local initiators." ::= { iscsiGroups 11 } iscsiInitiatorLoginStatsGroup OBJECT-GROUP OBJECTS { iscsiIntrLoginAcceptRsps, iscsiIntrLoginOtherFailRsps, iscsiIntrLoginRedirectRsps, iscsiIntrLoginAuthFailRsps, iscsiIntrLoginAuthenticateFails, iscsiIntrLoginNegotiateFails } STATUS current DESCRIPTION "A collection of objects providing information about all login attempts by local initiators to remote targets." ::= { iscsiGroups 12 } iscsiInitiatorLogoutStatsGroup OBJECT-GROUP OBJECTS { iscsiIntrLogoutNormals, iscsiIntrLogoutOthers } STATUS current DESCRIPTION "A collection of objects providing information about all logout events between local initiators to remote targets." ::= { iscsiGroups 13 } iscsiInitiatorAuthGroup OBJECT-GROUP OBJECTS { iscsiIntrAuthRowStatus, iscsiIntrAuthStorageType, iscsiIntrAuthIdentity } STATUS current DESCRIPTION "A collection of objects providing information about all remote targets that are initiators of the local system are authorized to access." ::= { iscsiGroups 14 } iscsiSessionAttributesGroup OBJECT-GROUP OBJECTS { iscsiSsnDirection, iscsiSsnInitiatorName, iscsiSsnTargetName, iscsiSsnTSIH, iscsiSsnISID, iscsiSsnInitiatorAlias, iscsiSsnTargetAlias, iscsiSsnInitialR2T, iscsiSsnImmediateData, iscsiSsnType, iscsiSsnMaxOutstandingR2T, iscsiSsnFirstBurstLength, iscsiSsnMaxBurstLength, iscsiSsnConnectionNumber, iscsiSsnAuthIdentity, iscsiSsnDataSequenceInOrder, iscsiSsnDataPDUInOrder, iscsiSsnErrorRecoveryLevel, iscsiSsnDiscontinuityTime } STATUS current DESCRIPTION "A collection of objects providing information applicable to all sessions." ::= { iscsiGroups 15 } iscsiSessionPDUStatsGroup OBJECT-GROUP OBJECTS { iscsiSsnCmdPDUs, iscsiSsnRspPDUs } STATUS current DESCRIPTION "A collection of objects providing information about PDU traffic for each session." ::= { iscsiGroups 16 } iscsiSessionOctetStatsGroup OBJECT-GROUP OBJECTS { iscsiSsnTxDataOctets, iscsiSsnRxDataOctets } STATUS current DESCRIPTION "A collection of objects providing information about octet traffic for each session using a Counter64 data type." ::= { iscsiGroups 17 } iscsiSessionLCOctetStatsGroup OBJECT-GROUP OBJECTS { iscsiSsnLCTxDataOctets, iscsiSsnLCRxDataOctets } STATUS current DESCRIPTION "A collection of objects providing information about octet traffic for each session using a Counter32 data type." ::= { iscsiGroups 18 } iscsiSessionCxnErrorStatsGroup OBJECT-GROUP OBJECTS { iscsiSsnCxnDigestErrors, iscsiSsnCxnTimeoutErrors } STATUS current DESCRIPTION "A collection of objects providing information about connection errors for all sessions." ::= { iscsiGroups 19 } iscsiConnectionAttributesGroup OBJECT-GROUP OBJECTS { iscsiCxnCid, iscsiCxnState, iscsiCxnProtocol, iscsiCxnAddrType, iscsiCxnLocalAddr, iscsiCxnLocalPort, iscsiCxnRemoteAddr, iscsiCxnRemotePort, iscsiCxnMaxRecvDataSegLength, iscsiCxnMaxXmitDataSegLength, iscsiCxnHeaderIntegrity, iscsiCxnDataIntegrity, iscsiCxnRecvMarker, iscsiCxnSendMarker, iscsiCxnVersionActive } STATUS current DESCRIPTION "A collection of objects providing information about all connections used by all sessions." ::= { iscsiGroups 20 } iscsiTgtLgnNotificationsGroup NOTIFICATION-GROUP NOTIFICATIONS { iscsiTgtLoginFailure } STATUS current DESCRIPTION "A collection of notifications which indicate a login failure from a remote initiator to a local target." ::= { iscsiGroups 21 } iscsiIntrLgnNotificationsGroup NOTIFICATION-GROUP NOTIFICATIONS { iscsiIntrLoginFailure } STATUS current DESCRIPTION "A collection of notifications which indicate a login failure from a local initiator to a remote target." ::= { iscsiGroups 22 } iscsiSsnFlrNotificationsGroup NOTIFICATION-GROUP NOTIFICATIONS { iscsiInstSessionFailure } STATUS current DESCRIPTION "A collection of notifications which indicate session failures occurring after login." ::= { iscsiGroups 23 } --********************************************************************** iscsiComplianceV1 MODULE-COMPLIANCE STATUS current DESCRIPTION "Initial version of compliance statement based on initial version of this MIB module. If an implementation can be both a target and an initiator, all groups are mandatory." MODULE -- this module MANDATORY-GROUPS { iscsiInstanceAttributesGroup, iscsiInstanceSsnErrorStatsGroup, iscsiPortalAttributesGroup, iscsiNodeAttributesGroup, iscsiSessionAttributesGroup, iscsiSessionPDUStatsGroup, iscsiSessionCxnErrorStatsGroup, iscsiConnectionAttributesGroup, iscsiSsnFlrNotificationsGroup } -- Conditionally mandatory groups depending on the ability -- to support Counter64 data types and/or to provide counter -- information to SNMPv1 applications. GROUP iscsiSessionOctetStatsGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that can support Counter64 data types." GROUP iscsiSessionLCOctetStatsGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that provide information to SNMPv1-only applications; this includes agents that cannot support Counter64 data types." -- Conditionally mandatory groups to be included with -- the mandatory groups when the implementation has -- iSCSI target facilities. GROUP iscsiTgtPortalAttributesGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI target facilities." OBJECT iscsiPortalMaxRecvDataSegLength MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT iscsiNodeStorageType MIN-ACCESS read-only DESCRIPTION "Write access is not required; an implementation may choose to allow this object to be set to 'volatile' or 'nonVolatile'." GROUP iscsiTargetAttributesGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI target facilities." GROUP iscsiTargetLoginStatsGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI target facilities." GROUP iscsiTargetLogoutStatsGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI target facilities." GROUP iscsiTgtLgnNotificationsGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI target facilities." GROUP iscsiTargetAuthGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI target facilities." -- Conditionally mandatory groups to be included with -- the mandatory groups when the implementation has -- iSCSI initiator facilities. GROUP iscsiIntrPortalAttributesGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI initiator facilities." GROUP iscsiInitiatorAttributesGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI initiator facilities." GROUP iscsiInitiatorLoginStatsGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI initiator facilities." GROUP iscsiInitiatorLogoutStatsGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI initiator facilities." GROUP iscsiIntrLgnNotificationsGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI initiator facilities." GROUP iscsiInitiatorAuthGroup DESCRIPTION "This group is mandatory for all iSCSI implementations that have iSCSI initiator facilities." OBJECT iscsiNodeErrorRecoveryLevel SYNTAX Unsigned32 (0..2) DESCRIPTION "Only values 0-2 are defined at present." ::= { iscsiCompliances 1 } END lio-utils-3.1+git2.fd0b34fd/mib-modules/mibs/LIO-SCSI-MIB.txt0000644000175000017500000031413611753136721021345 0ustar rrsrrs LIO-SCSI-MIB DEFINITIONS ::= BEGIN IMPORTS MODULE-IDENTITY, OBJECT-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, Integer32, Unsigned32, Counter32, Counter64, Gauge32, mib-2, enterprises FROM SNMPv2-SMI TEXTUAL-CONVENTION, TimeStamp, TruthValue, RowStatus, RowPointer, AutonomousType, StorageType FROM SNMPv2-TC MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP FROM SNMPv2-CONF SnmpAdminString FROM SNMP-FRAMEWORK-MIB; lio OBJECT IDENTIFIER ::= { enterprises 1055 } iscsiProduct OBJECT IDENTIFIER ::= { lio 10 } scsiMIB MODULE-IDENTITY LAST-UPDATED "200603300000Z" -- 30th March 2006 ORGANIZATION "IETF" CONTACT-INFO " Michele Hallak-Stamler Sanrad Intelligent Network 27 Habarzel Street Tel Aviv, Israel Phone: +972 3 7674809 E-mail: michele@sanrad.com Yaron Lederman Siliquent Technologies Ltd. 21 Etzel Street Ramat Gan, Israel Phone: +972 54 5308833 E-mail: yaronled@bezeqint.net Mark Bakke Postal: Cisco Systems, Inc 7900 International Drive, Suite 400 Bloomington, MN USA 55425 E-mail: mbakke@cisco.com Marjorie Krueger Postal: Hewlett-Packard 8000 Foothills Blvd. Roseville, CA 95747 E-mail: marjorie_krueger@hp.com Keith McCloghrie Cisco Systems, Inc. Postal: 170 West Tasman Drive San Jose, CA USA 95134 Phone: +1 408 526-5260 E-mail: kzm@cisco.com " DESCRIPTION "The SCSI MIB Module. Copyright (C) The Internet Society (2006). This version of this MIB module is part of RFC 4455; see the RFC itself for full legal notices." -- Revision History REVISION "200603300000Z" DESCRIPTION " Initial version published as RFC 4455." ::= { iscsiProduct 3 } -- LIO Changes: -- Added DISPLAY-HINT for ScsiName and ScsiIdentifier --****************** Textual Conventions ************************** ScsiLUN ::= TEXTUAL-CONVENTION STATUS current DESCRIPTION "This textual convention represents a SCSI Logical Unit Number (LUN). The format of a LUN is documented in Tables A.2 and A.3 of SAM-2 [SAM2]." REFERENCE "SCSI Architecture Model-2 (SAM-2), ANSI INCITS 366-2003, T10 Project 1157-D, 12 September 2002 - Annex A [SAM2]" SYNTAX OCTET STRING (SIZE ( 2 | 8)) ScsiIndexValue ::= TEXTUAL-CONVENTION DISPLAY-HINT "d" STATUS current DESCRIPTION "An arbitrary integer value, greater than zero, for use as a unique index value." SYNTAX Unsigned32 (1..4294967295) ScsiPortIndexValueOrZero ::= TEXTUAL-CONVENTION DISPLAY-HINT "d" STATUS current DESCRIPTION "This textual convention is an extension of the ScsiIndexValue convention. The latter defines a greater than zero value used to identify an index. This extension permits the additional value of zero and is applicable only to indices of SCSI port. Usage of the zero is object-specific and must therefore be defined as part of the description of any object that uses this syntax. Examples of the usage of zero might include situations where the index was unknown, or when none or all indices need to be referenced." SYNTAX Unsigned32 (0..4294967295) ScsiIndexValueOrZero ::= TEXTUAL-CONVENTION DISPLAY-HINT "d" STATUS current DESCRIPTION "This textual convention is an extension of the ScsiIndexValue convention. The latter defines a greater than zero value used to identify an index. This extension permits the additional value of zero. Usage of the zero is object-specific and must therefore be defined as part of the description of any object that uses this syntax. Examples of the usage of zero might include situations where index was unknown, or when none or all indices need to be referenced." SYNTAX Unsigned32 (0..4294967295) ScsiIdentifier ::= TEXTUAL-CONVENTION DISPLAY-HINT "262a" STATUS current DESCRIPTION "This textual convention represents a generic SCSI port identifier. The format depends on the transport used and is documented in Tables A.2 and A.3 of SAM-2 [SAM2]." REFERENCE "SCSI Architecture Model-2 (SAM-2), ANSI INCITS 366-2003, T10 Project 1157-D, 12 September 2002 - Annex A [SAM2]" SYNTAX OCTET STRING (SIZE (0..262)) ScsiName ::= TEXTUAL-CONVENTION DISPLAY-HINT "262a" STATUS current DESCRIPTION "This textual convention represents the name of a SCSI initiator device, a SCSI target device, a SCSI initiator port or a SCSI target port. The format depends on the transport used and is documented in Tables A.4 and A.5 of SAM-2 [SAM2]. Every object defined using this syntax must define whether it is a) always used for a port, b) always used for a device, or c) the circumstances under which it is used for a port or device." REFERENCE "SCSI Architecture Model-2 (SAM-2), ANSI INCITS 366-2003, T10 Project 1157-D, 12 September 2002 - Annex A [SAM2]" SYNTAX OCTET STRING (SIZE (0..262)) ScsiLuNameOrZero ::= TEXTUAL-CONVENTION STATUS current DESCRIPTION "This textual convention represents either the name of a SCSI logical unit or a zero-length string. Objects defined with this syntax must specify the meaning of the zero-length string. The format of the name of a LU is defined as: - a zero-length octet string or - a string of eight bytes." REFERENCE "SCSI Architecture Model-2 (SAM-2), ANSI INCITS 366-2003, T10 Project 1157-D, 12 September 2002 - Annex A [SAM2]" SYNTAX OCTET STRING (SIZE (0 | 8)) ScsiDeviceOrPort ::= TEXTUAL-CONVENTION STATUS current DESCRIPTION "This type specifies whether a particular configuration is applicable to a port or to a device." SYNTAX INTEGER { device(1), port(2), other(3) } ScsiIdCodeSet ::= TEXTUAL-CONVENTION DISPLAY-HINT "d" STATUS current DESCRIPTION "This textual convention specifies the code set for the identifier contained in an Identification Descriptor returned in a logical unit's Device Identification Page, and is formatted as defined in T10 SPC-2 (see REFERENCE) Table 172 - Code Set" REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001 Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" SYNTAX Unsigned32 (0..15) ScsiIdAssociation ::= TEXTUAL-CONVENTION DISPLAY-HINT "d" STATUS current DESCRIPTION "This textual convention specifies what the identifier is associated with (e.g., with the addressed physical/logical device or with a particular port) for the identifier contained in an Identification Descriptor returned in a logical unit's Device Identification Page, and is formatted as defined in T10 SPC-2 (see REFERENCE) Table 173 - Association." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001 Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" SYNTAX Unsigned32 (0..3) ScsiIdType ::= TEXTUAL-CONVENTION DISPLAY-HINT "d" STATUS current DESCRIPTION "This textual convention specifies the type for the identifier contained in an Identification Descriptor returned in a logical unit's Device Identification Page, and is formatted as defined in T10 SPC-2 (see REFERENCE) table 174 - Identifier Type." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001 Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" SYNTAX Unsigned32 (0..15) ScsiIdValue ::= TEXTUAL-CONVENTION STATUS current DESCRIPTION "This textual convention represents an identifier. The objects of type ScsiIdCodeSet, ScsiIdAssociation, ScsiIdType define together the format. The format is the same as contained in an Identification Descriptor returned in a logical unit's Device Identification Page, and is formatted as defined in T10 SPC-2 (see REFERENCE)." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001 Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" SYNTAX OCTET STRING (SIZE (0..255)) ScsiHrSWInstalledIndexOrZero ::= TEXTUAL-CONVENTION DISPLAY-HINT "d" STATUS current DESCRIPTION "The index value for a software module's row in the Host Resources MIBs hrSWInstalledTable. A zero value indicates that no row in the hrSWInstalledTable is applicable." REFERENCE "hrSWInstalledTable is defined in the Host Resources MIB, [RFC2790]." SYNTAX Integer32 (0..2147483647) --****************** Structure of the MIB ************************** scsiNotifications OBJECT IDENTIFIER ::= { scsiMIB 0 } scsiAdmin OBJECT IDENTIFIER ::= { scsiMIB 1 } scsiObjects OBJECT IDENTIFIER ::= { scsiMIB 2 } scsiConformance OBJECT IDENTIFIER ::= { scsiMIB 3 } scsiTransportTypes OBJECT IDENTIFIER ::= { scsiAdmin 1 } scsiGeneral OBJECT IDENTIFIER ::= { scsiObjects 1 } scsiInitiatorDevice OBJECT IDENTIFIER ::= { scsiObjects 2 } scsiTargetDevice OBJECT IDENTIFIER ::= { scsiObjects 3 } scsiLogicalUnit OBJECT IDENTIFIER ::= { scsiObjects 4 } --****************** Transport Types ******************************* -- The following object identifiers allow determining the different -- transports (service delivery subsystems) in use under the SCSI -- layer. scsiTransportOther OBJECT-IDENTITY STATUS current DESCRIPTION "This identity identifies a transport that has no identity; it might happen because the transport is unknown or might not have been defined when this MIB module was created." ::= { scsiTransportTypes 1 } scsiTransportSPI OBJECT-IDENTITY STATUS current DESCRIPTION "This identity identifies a parallel SCSI transport." REFERENCE "T10 - SCSI Parallel Interface - 4 (SPI-4) - ANSI INCITS 362-2002 [SPI4]" ::= { scsiTransportTypes 2 } scsiTransportFCP OBJECT-IDENTITY STATUS current DESCRIPTION "This identity identifies a Fibre Channel Protocol for SCSI, Second Version." REFERENCE "T10 - SCSI Fibre Channel Protocol - 2 (FCP-2) - ANSI INCITS 350-2003 [FCP2]" ::= { scsiTransportTypes 3 } scsiTransportSRP OBJECT-IDENTITY STATUS current DESCRIPTION "This identity identifies a protocol for transporting SCSI over Remote Direct Memory Access (RDMA) interfaces, e.g., InfiniBand (tm)." REFERENCE "T10 - SCSI RDMA Protocol (SRP) - ANSI INCITS 365-2002 [SRP]." ::= { scsiTransportTypes 4 } scsiTransportISCSI OBJECT-IDENTITY STATUS current DESCRIPTION "This identity identifies an iSCSI transport." REFERENCE "IETF IPS WG - Internet Small Computer Systems Interface (iSCSI) [RFC3720] " ::= { scsiTransportTypes 5 } scsiTransportSBP OBJECT-IDENTITY STATUS current DESCRIPTION "This identity identifies the Serial Bus Protocol 3." REFERENCE "T10 - Serial Bus Protocol 3 (SBP-3) - ANSI INCITS 375-2004 [SBP3]." ::= { scsiTransportTypes 6 } scsiTransportSAS OBJECT-IDENTITY STATUS current DESCRIPTION "This identity identifies the Serial Attach SCSI Protocol." REFERENCE "T10 - Serial Attached SCSI - 1.1 (SAS - 1.1) - #1601-D Rev-10 [SAS-1.1]." ::= { scsiTransportTypes 7 } --****************** Instance Table ***************************** scsiInstanceTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiInstanceEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of SCSI instances present on the system. The SCSI instance is the top-level entity, to which everything else belongs. An SNMP agent could represent more than one instance if it represents either a stack of devices, or virtual partitions of a larger device, or a host running multiple SCSI implementations from different vendors." ::= { scsiGeneral 1 } scsiInstanceEntry OBJECT-TYPE SYNTAX ScsiInstanceEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular SCSI instance." INDEX { scsiInstIndex } ::= { scsiInstanceTable 1 } ScsiInstanceEntry ::= SEQUENCE { scsiInstIndex ScsiIndexValue, scsiInstAlias SnmpAdminString, scsiInstSoftwareIndex ScsiHrSWInstalledIndexOrZero, scsiInstVendorVersion SnmpAdminString, scsiInstScsiNotificationsEnable TruthValue, scsiInstStorageType StorageType } scsiInstIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object represents an arbitrary integer used to uniquely identify a particular SCSI instance." ::= { scsiInstanceEntry 1 } scsiInstAlias OBJECT-TYPE SYNTAX SnmpAdminString (SIZE(0..79)) MAX-ACCESS read-write STATUS current DESCRIPTION "This object represents an administrative string, configured by the administrator. It can be a zero-length string." ::= { scsiInstanceEntry 2 } scsiInstSoftwareIndex OBJECT-TYPE SYNTAX ScsiHrSWInstalledIndexOrZero MAX-ACCESS read-only STATUS current DESCRIPTION "If this management instance corresponds to an installed software module, then this object's value is the value of the hrSWInstalledIndex of that module. If there is no correspondence to an installed software module (or no module that has an hrSWInstalledIndex value), then the value of this object is zero." REFERENCE "hrSWInstalledIndex is defined in the Host Resources MIB, [RFC2790]." ::= { scsiInstanceEntry 3 } scsiInstVendorVersion OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents a text string set by the manufacturer describing the version of this instance. The format of this string is determined solely by the manufacturer and is for informational purposes only. It is unrelated to the SCSI specification version numbers." ::= { scsiInstanceEntry 4 } scsiInstScsiNotificationsEnable OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-write STATUS current DESCRIPTION "This object indicates whether notifications defined in this MIB module will be generated." DEFVAL { true } ::= { scsiInstanceEntry 5 } scsiInstStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-write STATUS current DESCRIPTION "This object specifies the memory realization for this SCSI entity. Specifically, each row in the following tables: scsiIntrDevTable scsiDscTgtTable scsiAuthorizedIntrTable scsiLunMapTable has a StorageType as specified by the instance of this object that is INDEXed by the same value of scsiInstIndex. This value of this object is also used to indicate the persistence across reboots of writable values in its row of the scsiInstanceTable. Conceptual rows having the value 'permanent' need not allow write-access to any columnar objects in the row, nor to any object belonging to a table whose entry is INDEXed by the same value of scsiInstIndex." DEFVAL { nonVolatile } ::= { scsiInstanceEntry 6 } --******************** Device Table ******************************** scsiDeviceTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiDeviceEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of SCSI devices contained in each of the SCSI manageable instances that this agent is reporting." ::= { scsiGeneral 2 } scsiDeviceEntry OBJECT-TYPE SYNTAX ScsiDeviceEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular SCSI device included in this SCSI manageable instance identifiable by the value of scsiInstIndex." INDEX {scsiInstIndex, scsiDeviceIndex} ::= { scsiDeviceTable 1 } ScsiDeviceEntry ::= SEQUENCE { scsiDeviceIndex ScsiIndexValue, scsiDeviceAlias SnmpAdminString, scsiDeviceRole BITS, scsiDevicePortNumber Unsigned32 } scsiDeviceIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object is an arbitrary integer used to uniquely identify a particular device within a particular SCSI instance." ::= { scsiDeviceEntry 1 } scsiDeviceAlias OBJECT-TYPE SYNTAX SnmpAdminString (SIZE(0..79)) MAX-ACCESS read-write STATUS current DESCRIPTION "This object contains an administrative name for this device. If no name is assigned, the value of this object is the zero-length string. The StorageType of this object is specified by the instance of scsiInstStorageType that is INDEXed by the same value of scsiInstIndex." ::= { scsiDeviceEntry 2 } scsiDeviceRole OBJECT-TYPE SYNTAX BITS { target(0), initiator(1) } MAX-ACCESS read-only STATUS current DESCRIPTION "This object determines whether this device is acting as a SCSI initiator device, or as a SCSI target device, or as both." ::= { scsiDeviceEntry 3 } scsiDevicePortNumber OBJECT-TYPE SYNTAX Unsigned32 MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of ports contained in this device." ::= { scsiDeviceEntry 4 } --****************** Port Table ************************************ scsiPortTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiPortEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of SCSI ports for each SCSI device in each instance." ::= { scsiGeneral 3 } scsiPortEntry OBJECT-TYPE SYNTAX ScsiPortEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular SCSI port of a particular SCSI device in a particular SCSI instance." INDEX { scsiInstIndex, scsiDeviceIndex, scsiPortIndex } ::= { scsiPortTable 1 } ScsiPortEntry ::= SEQUENCE { scsiPortIndex ScsiIndexValue, scsiPortRole BITS, scsiPortTransportPtr RowPointer, scsiPortBusyStatuses Counter32 } scsiPortIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular port of a given device within a particular SCSI instance." ::= { scsiPortEntry 1 } scsiPortRole OBJECT-TYPE SYNTAX BITS { target(0), initiator(1) } MAX-ACCESS read-only STATUS current DESCRIPTION "This object indicates whether this port is acting as a SCSI initiator port, or as a SCSI target port or as both." ::= { scsiPortEntry 2 } scsiPortTransportPtr OBJECT-TYPE SYNTAX RowPointer MAX-ACCESS read-only STATUS current DESCRIPTION "This object is a pointer to the corresponding row in the scsiTransportTable. This row contains information on the transport such as transport type and port name." ::= { scsiPortEntry 3 } scsiPortBusyStatuses OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of port busy statuses sent or received by this port. Note: Initiator ports only receive busy status and SCSI target ports only send busy status. Discontinuities in the value of this counter can occur at re- initialization of the management system." ::= { scsiPortEntry 4 } --******************** Table of supported transports *************** scsiTransportTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiTransportEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table contains the device transport-specific information for each transport connected to each device in scsiDeviceTable." ::= { scsiGeneral 5 } scsiTransportEntry OBJECT-TYPE SYNTAX ScsiTransportEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing parameters applicable to a transport used by a particular device of a particular SCSI manageable instance." INDEX { scsiInstIndex, scsiDeviceIndex, scsiTransportIndex} ::= { scsiTransportTable 1 } ScsiTransportEntry ::= SEQUENCE { scsiTransportIndex ScsiIndexValue, scsiTransportType AutonomousType, scsiTransportPointer RowPointer, scsiTransportDevName ScsiName } scsiTransportIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular transport within a given device within a particular SCSI instance." ::= { scsiTransportEntry 1 } scsiTransportType OBJECT-TYPE SYNTAX AutonomousType MAX-ACCESS read-only STATUS current DESCRIPTION "This object identifies the transport type of this row of the transport table. For example, if this object has the value scsiTransportFCP, then the identified transport is FCP." ::= { scsiTransportEntry 2 } scsiTransportPointer OBJECT-TYPE SYNTAX RowPointer MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents a pointer to a conceptual row in a 'transport' MIB module allowing a manager to get useful information for the transport described by this entry. For example, if the transport of this device is iSCSI, this object will point to the iSCSI Instance of the iSCSI MIB module. If there is no MIB for this transport, this object has the value 0.0." ::= { scsiTransportEntry 3 } scsiTransportDevName OBJECT-TYPE SYNTAX ScsiName MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the name of this device in one of the format(s) appropriate for this type of transport." ::= { scsiTransportEntry 4 } --******************** SCSI Initiator Device Table *************** scsiIntrDevTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiIntrDevEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table contains information for each local SCSI initiator device in each instance." ::= { scsiInitiatorDevice 1} scsiIntrDevEntry OBJECT-TYPE SYNTAX ScsiIntrDevEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing information applicable to a SCSI initiator device within a particular SCSI instance." INDEX { scsiInstIndex, scsiDeviceIndex } ::= { scsiIntrDevTable 1 } ScsiIntrDevEntry ::= SEQUENCE { scsiIntrDevTgtAccessMode INTEGER, scsiIntrDevOutResets Counter32 } scsiIntrDevTgtAccessMode OBJECT-TYPE SYNTAX INTEGER { unknown(1), autoEnable(2), manualEnable(3) } MAX-ACCESS read-write STATUS current DESCRIPTION "This object controls whether or not a discovered SCSI target device is immediately authorized: - autoEnable (2) means that when a SCSI initiator device discovers a SCSI target device, it can use it immediately. - manualEnable (3) means that the SCSI initiator device must wait for an operator to set scsiIntrDscTgtConfigured = true before it is authorized. The StorageType of this object is specified by the instance of scsiInstStorageType that is INDEXed by the same value of scsiInstIndex." ::= { scsiIntrDevEntry 1 } scsiIntrDevOutResets OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the total number of times that this SCSI initiator device has issued - a LOGICAL UNIT RESET or TARGET RESET task management request, or - any other SCSI transport protocol-specific action or event that causes a Logical Unit Reset or a Hard Reset at one or more SCSI target ports ([SAM2] chapters 5.9.6, 5.9.7). Discontinuities in the value of this counter can occur at re- initialization of the management system." REFERENCE "SCSI Architecture Model-2 (SAM-2), ANSI INCITS 366-2003, T10 Project 1157-D, 12 September 2002 Chapters 5.9.6 & 5.9.7 [SAM2]" ::= { scsiIntrDevEntry 2 } -- The following section describes managed objects related to -- SCSI initiator ports. scsiIntrPortTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiIntrPortEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table contains all the SCSI initiator ports for each local SCSI initiator or target/initiator devices in each SCSI instance." ::= { scsiInitiatorDevice 2 } scsiIntrPortEntry OBJECT-TYPE SYNTAX ScsiIntrPortEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing information applicable to a particular SCSI initiator port of a particular SCSI device within a SCSI instance." INDEX { scsiInstIndex, scsiDeviceIndex, scsiPortIndex } ::= { scsiIntrPortTable 1 } ScsiIntrPortEntry ::= SEQUENCE { scsiIntrPortName ScsiName, scsiIntrPortIdentifier ScsiIdentifier, scsiIntrPortOutCommands Counter32, scsiIntrPortWrittenMegaBytes Counter32, scsiIntrPortReadMegaBytes Counter32, scsiIntrPortHSOutCommands Counter64 } scsiIntrPortName OBJECT-TYPE SYNTAX ScsiName MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the name of the port assigned for use by the SCSI protocol. The format will depend on the type of transport this port is using." ::= { scsiIntrPortEntry 1 } scsiIntrPortIdentifier OBJECT-TYPE SYNTAX ScsiIdentifier MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the identifier of the port in one of the format(s) appropriate for the type of transport in use." ::= { scsiIntrPortEntry 2 } scsiIntrPortOutCommands OBJECT-TYPE SYNTAX Counter32 UNITS "commands" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of commands sent by this SCSI initiator port. Discontinuities in the value of this counter can occur at re- initialization of the management system." ::= { scsiIntrPortEntry 3 } scsiIntrPortWrittenMegaBytes OBJECT-TYPE SYNTAX Counter32 UNITS "Megabytes" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the amount of data in megabytes sent by this SCSI initiator port. Discontinuities in the value of this counter can occur at re- initialization of the management system." ::= { scsiIntrPortEntry 4 } scsiIntrPortReadMegaBytes OBJECT-TYPE SYNTAX Counter32 UNITS "Megabytes" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the amount of data in megabytes received by this SCSI initiator port. Discontinuities in the value of this counter can occur at re- initialization of the management system." ::= { scsiIntrPortEntry 5 } scsiIntrPortHSOutCommands OBJECT-TYPE SYNTAX Counter64 UNITS "commands" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of commands sent by this SCSI initiator port. This object provides support for systems that can quickly generate a large number of commands because they run at high speed. Discontinuities in the value of this counter can occur at re- initialization of the management system." ::= { scsiIntrPortEntry 6 } --******************** Discovered SCSI Target Device group ******** scsiRemoteTgtDev OBJECT IDENTIFIER ::= { scsiInitiatorDevice 3 } -- SCSI target device discovered or authorized to attach each of the -- SCSI initiator ports of each SCSI initiator device of each -- instance. scsiDscTgtTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiDscTgtEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table includes all the remote (not in the local system) SCSI target ports that are authorized to attach to each local SCSI initiator port of this SCSI instance." ::= { scsiRemoteTgtDev 1 } scsiDscTgtEntry OBJECT-TYPE SYNTAX ScsiDscTgtEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "Each entry (row) contains information about the SCSI target device or port to which this SCSI initiator port (or all SCSI initiator ports in the SCSI initiator entry indexed by scsiInstIndex, scsiDeviceIndex) will attempt to attach. The entry is either for all local ports (if scsiDscTgtIntrPortIndex is zero) or only for the specific SCSI initiator port identified by scsiDscTgtIntrPortIndex. Note that if an entry in this table is deleted, any corresponding entries in the scsiDscLunsTable must be deleted as well. The StorageType of a row in this table is specified by the instance of scsiInstStorageType that is INDEXed by the same value of scsiInstIndex." INDEX { scsiInstIndex, scsiDeviceIndex, scsiDscTgtIntrPortIndex, scsiDscTgtIndex } ::= { scsiDscTgtTable 1 } ScsiDscTgtEntry ::= SEQUENCE { scsiDscTgtIntrPortIndex ScsiPortIndexValueOrZero, scsiDscTgtIndex ScsiIndexValue, scsiDscTgtDevOrPort ScsiDeviceOrPort, scsiDscTgtName ScsiName, scsiDscTgtConfigured TruthValue, scsiDscTgtDiscovered TruthValue, scsiDscTgtInCommands Counter32, scsiDscTgtWrittenMegaBytes Counter32, scsiDscTgtReadMegaBytes Counter32, scsiDscTgtHSInCommands Counter64, scsiDscTgtLastCreation TimeStamp, scsiDscTgtRowStatus RowStatus } scsiDscTgtIntrPortIndex OBJECT-TYPE SYNTAX ScsiPortIndexValueOrZero MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object relates to a particular local device within a particular SCSI instance and specifies - the index of the local SCSI initiator port, - or zero, if this entry refers to the local device and therefore refers to all the local SCSI initiator ports." ::= { scsiDscTgtEntry 1 } scsiDscTgtIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object is an arbitrary integer used to uniquely identify a particular SCSI target device either discovered by, or configured for use with, one or more ports scsiDscTgtName of a particular device within a particular SCSI instance." ::= { scsiDscTgtEntry 2 } scsiDscTgtDevOrPort OBJECT-TYPE SYNTAX ScsiDeviceOrPort MAX-ACCESS read-create STATUS current DESCRIPTION "This object indicates whether this entry describes a configured SCSI target device name (and applies to all ports on the identified SCSI target device) or an individual SCSI target port." ::= { scsiDscTgtEntry 3 } scsiDscTgtName OBJECT-TYPE SYNTAX ScsiName MAX-ACCESS read-create STATUS current DESCRIPTION "This object represents the name of this configured or discovered SCSI target device or port depending on the value of scsiDscTgtDevOrPort." ::= { scsiDscTgtEntry 4 } scsiDscTgtConfigured OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-create STATUS current DESCRIPTION "This object means -true(1): this entry has been configured by an administrator. -false(2): this entry has been added from a discovery mechanism (e.g., SendTargets, SLP, iSNS). An administrator can modify this value from false to true." DEFVAL { true } ::= { scsiDscTgtEntry 5 } scsiDscTgtDiscovered OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-only STATUS current DESCRIPTION "This object means -true(1): this entry has been discovered by the SCSI instance as result of an automatic discovery process. -false(2):this entry has been added by manual configuration. This entry is read-only because an administrator cannot change it. Note that it is an implementation decision to determine how long to retain a row with configured=false, such as when the SCSI target device is no longer visible/accessible to the local SCSI initiator device." ::= { scsiDscTgtEntry 6 } scsiDscTgtInCommands OBJECT-TYPE SYNTAX Counter32 UNITS "commands" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of commands received from this SCSI target port or device. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiDscTgtLastCreation." ::= { scsiDscTgtEntry 7 } scsiDscTgtWrittenMegaBytes OBJECT-TYPE SYNTAX Counter32 UNITS "Megabytes" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the amount of megabytes of data sent as the result of WRITE commands to this SCSI target port or device. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiDscTgtLastCreation." ::= { scsiDscTgtEntry 8 } scsiDscTgtReadMegaBytes OBJECT-TYPE SYNTAX Counter32 UNITS "Megabytes" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the amount of megabytes received as the result of READ commands to this SCSI target port or device. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiDscTgtLastCreation." ::= { scsiDscTgtEntry 9 } scsiDscTgtHSInCommands OBJECT-TYPE SYNTAX Counter64 UNITS "commands" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of commands received by this SCSI target port or device. This object provides support for system that can quickly generate a large number of commands because they run at high speed. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiDscTgtLastCreation." ::= { scsiDscTgtEntry 10 } scsiDscTgtLastCreation OBJECT-TYPE SYNTAX TimeStamp MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the value of sysUpTime when this row was created." ::= { scsiDscTgtEntry 11 } scsiDscTgtRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This object allows an administrator to configure dynamically a new entry in this table via SNMP or eventually delete it. An administrator is not allowed to delete an entry for which the value of the object scsiIntrDscTgtDiscovered is equal to true. Note that when an entry in this table is deleted, then any corresponding entries in the scsiDscLunsTable must also be automatically deleted. A newly created row cannot be made active until a value has been set for scsiDscTgtName. In this case, the value of the corresponding instance of the scsiDscTgtRowStatus column will stay 'notReady'. The RowStatus TC [RFC2579] requires that this DESCRIPTION clause states under which circumstances other objects in this row can be modified: The value of this object has no effect on whether other objects in this conceptual row can be modified." ::= { scsiDscTgtEntry 12 } --********************** LUNs discovered *************************** scsiDscLunTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiDscLunEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table includes all the remote (not in the local system) logical unit numbers (LUNs) discovered via each local SCSI initiator port of each local device within a particular SCSI instance." ::= { scsiRemoteTgtDev 2 } scsiDscLunEntry OBJECT-TYPE SYNTAX ScsiDscLunEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) represents a discovered LUN at a particular SCSI target device (scsiDscTgtIndex), where the LUN was discovered by a particular local SCSI initiator device within a particular SCSI instance, possibly via a particular local SCSI initiator port. Note that when an entry in the scsiDscTgtTable is deleted, all corresponding entries in this table should automatically be deleted." INDEX { scsiInstIndex, scsiDeviceIndex, scsiDscTgtIntrPortIndex, scsiDscTgtIndex, scsiDscLunIndex } ::= { scsiDscLunTable 1 } ScsiDscLunEntry ::= SEQUENCE { scsiDscLunIndex ScsiIndexValue, scsiDscLunLun ScsiLUN } scsiDscLunIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object is an arbitrary integer used to uniquely identify a particular LUN discovered by a particular SCSI initiator port or a particular SCSI initiator device within a particular SCSI instance. Entries in the scsiDscLunIdTable are associated with a LUN by having the value of this object in their INDEX." ::= { scsiDscLunEntry 1 } scsiDscLunLun OBJECT-TYPE SYNTAX ScsiLUN MAX-ACCESS read-only STATUS current DESCRIPTION "This object contains the Logical Unit Number (LUN) of the discovered logical unit." ::= { scsiDscLunEntry 2 } --******************** LU Identifiers discovered ******************* scsiDscLunIdTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiDscLunIdEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table includes all the known LU identifiers of the remote (not in the local system) logical units discovered via each local SCSI initiator port or device of this SCSI instance." ::= { scsiRemoteTgtDev 3 } scsiDscLunIdEntry OBJECT-TYPE SYNTAX ScsiDscLunIdEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) represents the LU identifier of a discovered LUN at a particular SCSI target device (scsiDscTgtIndex), where the LUN was discovered by a particular local SCSI initiator device within a particular SCSI instance, possibly via a particular local SCSI initiator port." INDEX { scsiInstIndex, scsiDeviceIndex, scsiDscTgtIntrPortIndex, scsiDscTgtIndex, scsiDscLunIndex, scsiDscLunIdIndex } ::= { scsiDscLunIdTable 1 } ScsiDscLunIdEntry ::= SEQUENCE { scsiDscLunIdIndex ScsiIndexValue, scsiDscLunIdCodeSet ScsiIdCodeSet, scsiDscLunIdAssociation ScsiIdAssociation, scsiDscLunIdType ScsiIdType, scsiDscLunIdValue ScsiIdValue } scsiDscLunIdIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object is an arbitrary integer used to uniquely identify a particular LUN identifier discovered by each SCSI initiator device or particular SCSI initiator port within a particular SCSI instance." ::= { scsiDscLunIdEntry 1 } scsiDscLunIdCodeSet OBJECT-TYPE SYNTAX ScsiIdCodeSet MAX-ACCESS read-only STATUS current DESCRIPTION "This object specifies the code set in use with this identifier. The value is represented in the same format as is contained in the identifier's Identification Descriptor within the logical unit's Device Identification Page." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001 Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" ::= { scsiDscLunIdEntry 2 } scsiDscLunIdAssociation OBJECT-TYPE SYNTAX ScsiIdAssociation MAX-ACCESS read-only STATUS current DESCRIPTION "This object specifies what the identifier is associated with (e.g., with the addressed physical/logical device or with a particular port). The value is represented in the same format as is contained in the identifier's Identification Descriptor within the logical unit's Device Identification Page." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001 Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" ::= { scsiDscLunIdEntry 3 } scsiDscLunIdType OBJECT-TYPE SYNTAX ScsiIdType MAX-ACCESS read-only STATUS current DESCRIPTION "This object specifies the type of the identifier. The value is represented in the same format as is contained in the identifier's Identification Descriptor within the logical unit's Device Identification Page." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001 Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" ::= { scsiDscLunIdEntry 4 } scsiDscLunIdValue OBJECT-TYPE SYNTAX ScsiIdValue MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the actual value of this identifier. The format is defined by the objects scsiDscLunIdCodeSet, scsiDscLunIdAssociation, scsiDscLunIdType. The value is represented in the same format as is contained in the identifier's Identification Descriptor within the logical unit's Device Identification Page." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001 Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" ::= { scsiDscLunIdEntry 5 } --***** Table of SCSI Target Device Attached to local SCSI --***** Initiator Ports scsiAttTgtPortTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiAttTgtPortEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table includes all the remote (not in the local system) SCSI target ports that are currently attached to each local SCSI initiator port of this SCSI instance." ::= { scsiRemoteTgtDev 4 } scsiAttTgtPortEntry OBJECT-TYPE SYNTAX ScsiAttTgtPortEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) represents a remote SCSI target port (scsiAttTgtPortIndex) currently attached to a particular SCSI initiator port (scsiPortIndex) of a particular SCSI initiator device within a particular SCSI instance." INDEX { scsiInstIndex, scsiDeviceIndex, scsiPortIndex, scsiAttTgtPortIndex } ::= { scsiAttTgtPortTable 1 } ScsiAttTgtPortEntry ::= SEQUENCE { scsiAttTgtPortIndex ScsiIndexValue, scsiAttTgtPortDscTgtIdx ScsiIndexValueOrZero, scsiAttTgtPortName ScsiName, scsiAttTgtPortIdentifier ScsiIdentifier } scsiAttTgtPortIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular SCSI target currently attached to a particular SCSI initiator port of a particular SCSI initiator device within a particular SCSI instance." ::= { scsiAttTgtPortEntry 1 } scsiAttTgtPortDscTgtIdx OBJECT-TYPE SYNTAX ScsiIndexValueOrZero MAX-ACCESS read-only STATUS current DESCRIPTION "This object contains the value of the scsiDscTgtIntrPortIndex index variable for the row in the scsiDscTgtTable representing this currently attached SCSI target port. If the currently attached SCSI target port is not represented in the scsiDscTgtTable, then the value of this object is zero." ::= { scsiAttTgtPortEntry 2 } scsiAttTgtPortName OBJECT-TYPE SYNTAX ScsiName MAX-ACCESS read-only STATUS current DESCRIPTION "This object contains the name of the attached SCSI target port." ::= { scsiAttTgtPortEntry 3 } scsiAttTgtPortIdentifier OBJECT-TYPE SYNTAX ScsiIdentifier MAX-ACCESS read-only STATUS current DESCRIPTION "This object contains the identifier of the attached SCSI target port." ::= { scsiAttTgtPortEntry 4 } -- ***************************************************************** -- ***** Table of SCSI Target devices -- scsiTgtDevTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiTgtDevEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table contains information about each local SCSI target device." ::= { scsiTargetDevice 1 } scsiTgtDevEntry OBJECT-TYPE SYNTAX ScsiTgtDevEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing information applicable to a particular local SCSI target device within a particular SCSI instance." INDEX { scsiInstIndex, scsiDeviceIndex } ::= { scsiTgtDevTable 1 } ScsiTgtDevEntry ::= SEQUENCE { scsiTgtDevNumberOfLUs Gauge32, scsiTgtDeviceStatus INTEGER, scsiTgtDevNonAccessibleLUs Gauge32, scsiTgtDevResets Counter32 } scsiTgtDevNumberOfLUs OBJECT-TYPE SYNTAX Gauge32 MAX-ACCESS read-only STATUS current DESCRIPTION "This object is the number of logical units accessible via this local SCSI target device." ::= { scsiTgtDevEntry 1 } scsiTgtDeviceStatus OBJECT-TYPE SYNTAX INTEGER { unknown(1), available(2), broken(3), readying(4), abnormal(5), nonAddrFailure(6), nonAddrFailReadying(7), nonAddrFailAbnormal(8) } MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the status of this SCSI device, summarizing the state of both the addressable devices (i.e., the logical units) and the non-addressable devices within this SCSI device: - unknown(1): This value is used when the status cannot be determined - available(2): All addressable and non-addressable devices within the SCSI device are fully operational (i.e., no logical units have an abnormal status). - broken(3): The SCSI device is not operational and cannot be made operational without external intervention. - readying(4): One or more logical units within the SCSI device are being initialized and access to the SCSI device is temporarily limited (i.e., one or more of the logical units have a readying status). - abnormal(5): One or more addressable devices within the SCSI device are indicating a status other than available; nevertheless, the SCSI device is operational (i.e., one or more of the logical units have an abnormal status). - nonAddrFailure(6): One or more non-addressable devices within the SCSI device have failed; nevertheless, the SCSI device is operational (i.e., no logical units have an abnormal or readying status). - nonAddrFailReadying(7): One or more non-addressable devices within the SCSI device have failed; nevertheless, one or more logical units within the SCSI device are being initialized and access to the SCSI device is temporarily limited. - nonAddrFailAbnormal(8): One or more non-addressable devices within the SCSI device have failed and one or more addressable devices within the SCSI device are indicating a status other than available; however, the SCSI device is operational. " REFERENCE "SCSI Controller Commands-2 (SCC-2) ANSI INCITS 318-1998 6.3.1.8 REPORT STATES service action [SCC2]" ::= { scsiTgtDevEntry 2} scsiTgtDevNonAccessibleLUs OBJECT-TYPE SYNTAX Gauge32 MAX-ACCESS read-only STATUS current DESCRIPTION "This object is the number of logical units existing but not currently accessible via this local SCSI target device." ::= { scsiTgtDevEntry 3 } scsiTgtDevResets OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "This object counts the number of hard resets encountered by this SCSI target device. Discontinuities in the value of this counter can occur at re- initialization of the management system." REFERENCE "SCSI Architecture Model-2 (SAM-2), ANSI INCITS 366-2003, T10 Project 1157-D, 12 September 2002 - Chapter 5.9.7 [SAM2]" ::= { scsiTgtDevEntry 4 } --******************** SCSI Target Port Table ********************* scsiTgtPortTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiTgtPortEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table includes all the local SCSI target ports of all the local SCSI target devices." ::= { scsiTargetDevice 2 } scsiTgtPortEntry OBJECT-TYPE SYNTAX ScsiTgtPortEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing information applicable to a particular local SCSI target port of a particular local SCSI target device within a particular SCSI instance." INDEX { scsiInstIndex, scsiDeviceIndex, scsiPortIndex} ::= { scsiTgtPortTable 1 } ScsiTgtPortEntry ::= SEQUENCE { scsiTgtPortName ScsiName, scsiTgtPortIdentifier ScsiIdentifier, scsiTgtPortInCommands Counter32, scsiTgtPortWrittenMegaBytes Counter32, scsiTgtPortReadMegaBytes Counter32, scsiTgtPortHSInCommands Counter64 } scsiTgtPortName OBJECT-TYPE SYNTAX ScsiName MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the name of the port assigned for use in the SCSI protocol." ::= { scsiTgtPortEntry 1 } scsiTgtPortIdentifier OBJECT-TYPE SYNTAX ScsiIdentifier MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the identifier of the port in one of the format(s) appropriate for the type of transport." ::= { scsiTgtPortEntry 2 } scsiTgtPortInCommands OBJECT-TYPE SYNTAX Counter32 UNITS "commands" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of commands received by this SCSI target port. Discontinuities in the value of this counter can occur at re- initialization of the management system." ::= { scsiTgtPortEntry 3 } scsiTgtPortWrittenMegaBytes OBJECT-TYPE SYNTAX Counter32 UNITS "Megabytes" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the amount of data written in megabytes by this SCSI target port. Discontinuities in the value of this counter can occur at re- initialization of the management system." ::= { scsiTgtPortEntry 4 } scsiTgtPortReadMegaBytes OBJECT-TYPE SYNTAX Counter32 UNITS "Megabytes" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the amount of data read in megabytes by this SCSI target port. Discontinuities in the value of this counter can occur at re- initialization of the management system." ::= { scsiTgtPortEntry 5 } scsiTgtPortHSInCommands OBJECT-TYPE SYNTAX Counter64 UNITS "commands" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of commands received. This object provides support for systems that can quickly generate a large number of commands because they run at high speed. Discontinuities in the value of this counter can occur at re- initialization of the management system." ::= { scsiTgtPortEntry 6 } scsiRemoteIntrDev OBJECT IDENTIFIER ::= { scsiTargetDevice 3 } -- The scsiAuthorizedIntrTable contains the list of remote initiator -- ports that are authorized to be attached to specific SCSI target -- ports and on which an administrator would like to keep permanent -- information and long term statistics even when not currently -- attached. scsiAuthorizedIntrTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiAuthorizedIntrEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table includes all the authorized SCSI initiator devices or ports that may attach a SCSI target device (ScsiAuthIntrTgtPortIndex = 0) or port (ScsiAuthIntrTgtPortIndex different than 0) of the local SCSI instance. Statistics are kept for each such authorization; thus, the authorizations should be configured in the manner that will cause the desired set of statistics to be collected and that will determine the correct LUN map." ::= { scsiRemoteIntrDev 1 } scsiAuthorizedIntrEntry OBJECT-TYPE SYNTAX ScsiAuthorizedIntrEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) represents a remote SCSI initiator port or remote SCSI initiator device that may attach to the local SCSI target port or device within a particular SCSI instance. The StorageType of a row in this table is specified by the instance of scsiInstStorageType that is INDEXed by the same value of scsiInstIndex." INDEX { scsiInstIndex, scsiDeviceIndex, scsiAuthIntrTgtPortIndex, scsiAuthIntrIndex } ::= { scsiAuthorizedIntrTable 1 } ScsiAuthorizedIntrEntry ::= SEQUENCE { scsiAuthIntrTgtPortIndex ScsiPortIndexValueOrZero, scsiAuthIntrIndex ScsiIndexValue, scsiAuthIntrDevOrPort ScsiDeviceOrPort, scsiAuthIntrName ScsiName, scsiAuthIntrLunMapIndex ScsiIndexValueOrZero, scsiAuthIntrAttachedTimes Counter32, scsiAuthIntrOutCommands Counter32, scsiAuthIntrReadMegaBytes Counter32, scsiAuthIntrWrittenMegaBytes Counter32, scsiAuthIntrHSOutCommands Counter64, scsiAuthIntrLastCreation TimeStamp, scsiAuthIntrRowStatus RowStatus } scsiAuthIntrTgtPortIndex OBJECT-TYPE SYNTAX ScsiPortIndexValueOrZero MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object contains either the index of the port or zero, to indicate any port, on the particular local SCSI target device." ::= { scsiAuthorizedIntrEntry 1 } scsiAuthIntrIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object is an arbitrary integer used to uniquely identify a SCSI initiator device or port that is authorized to attach to a particular local SCSI target device or port of a particular SCSI instance." ::= { scsiAuthorizedIntrEntry 2 } scsiAuthIntrDevOrPort OBJECT-TYPE SYNTAX ScsiDeviceOrPort MAX-ACCESS read-create STATUS current DESCRIPTION "This object specifies whether this entry refers to a remote SCSI initiator port or to a SCSI initiator device. A value of device(1) means that the authorized remote initiator is a SCSI initiator device and includes all of its ports. A value of port(2) means that the authorized remote initiator is a SCSI initiator port." ::= { scsiAuthorizedIntrEntry 3 } scsiAuthIntrName OBJECT-TYPE SYNTAX ScsiName MAX-ACCESS read-create STATUS current DESCRIPTION "This object represents the name of the remote SCSI initiator device or port authorized by this row." ::= { scsiAuthorizedIntrEntry 4 } scsiAuthIntrLunMapIndex OBJECT-TYPE SYNTAX ScsiIndexValueOrZero MAX-ACCESS read-create STATUS current DESCRIPTION "This object identifies the set of entries in the scsiLunMapTable for which scsiLunMapIndex has the same value as the value of this object. The identified set of entries constitutes the LUN map to be used for accessing logical units when the remote SCSI initiator port or device corresponding to this entry is attached to any local SCSI target port or device corresponding to this entry. Note that this object has a value of zero if this entry should use the default LUN map." ::= { scsiAuthorizedIntrEntry 5 } scsiAuthIntrAttachedTimes OBJECT-TYPE SYNTAX Counter32 UNITS "Times" MAX-ACCESS read-only STATUS current DESCRIPTION "This object indicates the number of times that this remote SCSI initiator device or port has transitioned from unattached to attached to this local SCSI target device or port. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiAuthIntrLastCreation." ::= { scsiAuthorizedIntrEntry 6 } scsiAuthIntrOutCommands OBJECT-TYPE SYNTAX Counter32 UNITS "commands" MAX-ACCESS read-only STATUS current DESCRIPTION "This object indicates the number of commands that the remote SCSI initiator device or port corresponding to this entry has sent to the local SCSI target device or port corresponding to this entry. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiAuthIntrLastCreation." ::= { scsiAuthorizedIntrEntry 7 } scsiAuthIntrReadMegaBytes OBJECT-TYPE SYNTAX Counter32 UNITS "Megabytes" MAX-ACCESS read-only STATUS current DESCRIPTION "This object indicates the amount of data in megabytes that the remote SCSI initiator device or port corresponding to this entry has read from the local SCSI target device or port corresponding to this entry. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiAuthIntrLastCreation." ::= { scsiAuthorizedIntrEntry 8 } scsiAuthIntrWrittenMegaBytes OBJECT-TYPE SYNTAX Counter32 UNITS "Megabytes" MAX-ACCESS read-only STATUS current DESCRIPTION "This object indicates the amount of data in megabytes that the remote SCSI initiator device or port corresponding to this entry has written to the local SCSI target device or port corresponding to this entry. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiAuthIntrLastCreation." ::= { scsiAuthorizedIntrEntry 9} scsiAuthIntrHSOutCommands OBJECT-TYPE SYNTAX Counter64 UNITS "commands" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of commands sent by the remote SCSI initiator device or port corresponding to this entry to the local SCSI target device or port corresponding to this entry. This object provides support for systems that can quickly generate a large number of commands because they run at high speed. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiAuthIntrLastCreation." ::= { scsiAuthorizedIntrEntry 10 } scsiAuthIntrLastCreation OBJECT-TYPE SYNTAX TimeStamp MAX-ACCESS read-only STATUS current DESCRIPTION "This object indicates the value of sysUpTime when this row was last created." ::= { scsiAuthorizedIntrEntry 11 } scsiAuthIntrRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This object allows an administrator to create or delete this entry. A newly created row cannot be made active until a value has been set for scsiAuthIntrName. In this case, the value of the corresponding instance of the scsiAuthIntrRowStatus column will stay 'notReady'. The RowStatus TC [RFC2579] requires that this DESCRIPTION clause states under which circumstances other objects in this row can be modified: The value of this object has no effect on whether other objects in this conceptual row can be modified." ::= { scsiAuthorizedIntrEntry 12 } -- Table of SCSI initiator devices or ports attached to local -- SCSI target ports -- scsiAttIntrPortTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiAttIntrPortEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table includes all the remote SCSI initiator ports that are currently attached to a local SCSI target port of all local devices within all SCSI instances." ::= { scsiRemoteIntrDev 2 } scsiAttIntrPortEntry OBJECT-TYPE SYNTAX ScsiAttIntrPortEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) represents a remote SCSI initiator port currently attached to a particular local SCSI target port of a particular SCSI target device of a particular SCSI instance." INDEX { scsiInstIndex, scsiDeviceIndex, scsiPortIndex, scsiAttIntrPortIndex } ::= { scsiAttIntrPortTable 1 } ScsiAttIntrPortEntry ::= SEQUENCE { scsiAttIntrPortIndex ScsiIndexValue, scsiAttIntrPortAuthIntrIdx ScsiIndexValueOrZero, scsiAttIntrPortName ScsiName, scsiAttIntrPortIdentifier ScsiIdentifier } scsiAttIntrPortIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object represents an arbitrary integer used to uniquely identify a particular attached remote initiator port to a particular SCSI target port within a particular SCSI target device within a particular SCSI instance." ::= { scsiAttIntrPortEntry 1 } scsiAttIntrPortAuthIntrIdx OBJECT-TYPE SYNTAX ScsiIndexValueOrZero MAX-ACCESS read-only STATUS current DESCRIPTION "This object is the corresponding index in the scsiAuthorizedIntrTable for this current attached remote SCSI initiator device or zero if this remote attached SCSI initiator device is not configured in that table." ::= { scsiAttIntrPortEntry 2 } scsiAttIntrPortName OBJECT-TYPE SYNTAX ScsiName MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the name of the remote SCSI initiator device attached to this local SCSI target port." ::= { scsiAttIntrPortEntry 3 } scsiAttIntrPortIdentifier OBJECT-TYPE SYNTAX ScsiIdentifier MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the identifier of the remote SCSI initiator device attached to this local SCSI target port." ::= { scsiAttIntrPortEntry 4 } --****************** Managed Objects regarding logical units ******* scsiLuTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiLuEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table contains the logical units exposed by local SCSI target devices. It includes attributes for the World Wide Name (WWN), scsiLuVendorId, scsiLuProductId, and scsiLuRevisionId, which may also appear in the scsiLuIdTable. If an implementation exposes a WWN as a LuIdTable entry, it must match the scsiLuWwnName in this table. If an implementation exposes a (vendor, product, revision) identifier as an LuIdTable entry, each of these fields must match the scsiLuVendorId, scsiLuProductId, and scsiLuRevisionId attributes in this table." ::= { scsiLogicalUnit 1 } scsiLuEntry OBJECT-TYPE SYNTAX ScsiLuEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) contains information applicable to a particular logical unit of a particular local SCSI target device within a particular SCSI instance." INDEX { scsiInstIndex, scsiDeviceIndex, scsiLuIndex} ::= { scsiLuTable 1 } ScsiLuEntry ::= SEQUENCE { scsiLuIndex ScsiIndexValue, scsiLuDefaultLun ScsiLUN, scsiLuWwnName ScsiLuNameOrZero, scsiLuVendorId SnmpAdminString, scsiLuProductId SnmpAdminString, scsiLuRevisionId SnmpAdminString, scsiLuPeripheralType Unsigned32, scsiLuStatus INTEGER, scsiLuState BITS, scsiLuInCommands Counter32, scsiLuReadMegaBytes Counter32, scsiLuWrittenMegaBytes Counter32, scsiLuInResets Counter32, scsiLuOutTaskSetFullStatus Counter32, scsiLuHSInCommands Counter64, scsiLuLastCreation TimeStamp } scsiLuIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object represents an arbitrary integer used to uniquely identify a particular logical unit within a particular SCSI target device within a particular SCSI instance." ::= { scsiLuEntry 1 } scsiLuDefaultLun OBJECT-TYPE SYNTAX ScsiLUN MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the default Logical Unit Number (LUN) for this logical unit; if a SCSI initiator device has not been configured to view this logical unit via an entry in the ScsiLunMapTable, the LU will be visible as scsiLuDefaultLun. If this logical unit does not have a default LUN, it will only be visible if specified via the ScsiLunMapTable, and this object will contain a zero-length string." ::= { scsiLuEntry 2 } scsiLuWwnName OBJECT-TYPE SYNTAX ScsiLuNameOrZero MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the World Wide Name of this LU that is the device identifier of the Vital Product Data (VPD) page name; if there is no WWN for this LU, this object will contain a zero-length string. If there is more than one identifier, they will be listed in the scsiLuIdTable and this object will contain a zero-length string." ::= { scsiLuEntry 3 } scsiLuVendorId OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents a string identifying the vendor of this LU as reported in the Standard INQUIRY data." ::= { scsiLuEntry 4 } scsiLuProductId OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents a string identifying the product for this LU as reported in the Standard INQUIRY data." ::= { scsiLuEntry 5 } scsiLuRevisionId OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents a string defining the product revision of this LU as reported in the Standard INQUIRY data." ::= { scsiLuEntry 6 } scsiLuPeripheralType OBJECT-TYPE SYNTAX Unsigned32 MAX-ACCESS read-only STATUS current DESCRIPTION "This object is the value returned by SCSI Standard INQUIRY data. It can be: direct-access device, sequential-access device, printer, communication device and so on. The values that can be returned here are defined in SCSI Primary Commands -2." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001,11 July 2001 [SPC2]- Table 48." ::= { scsiLuEntry 7 } scsiLuStatus OBJECT-TYPE SYNTAX INTEGER { unknown(1), available(2), notAvailable(3), broken(4), readying(5), abnormal(6) } MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the status of this logical unit: - unknown(1): The status of this logical unit cannot be determined. - available(2): The logical unit is fully operational (i.e., accepts media access SCSI commands and has no state information to report). - notAvailable(3): The logical unit is capable of being supported but is not available (i.e., no logical unit is currently present or the logical unit is present but not configured for use). - broken(4): The logical unit has failed and cannot respond to SCSI commands. - readying(5): The logical unit is being initialized and access is temporarily limited. - abnormal(6): The logical unit has state information available that indicates it is operating with limits. The scsiLuState indicates what those limits are. " REFERENCE "SCSI Controller Commands-2 (SCC-2) ANSI INCITS 318-1998 6.3.1.8 REPORT STATES service action [SCC2]" ::= { scsiLuEntry 8 } scsiLuState OBJECT-TYPE SYNTAX BITS { dataLost(0), dynamicReconfigurationInProgress(1), exposed(2), fractionallyExposed(3), partiallyExposed(4), protectedRebuild(5), protectionDisabled(6), rebuild(7), recalculate(8), spareInUse(9), verifyInProgress(10) } MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the state of a logical unit and its meaning according to the bit position: 0 Data lost: Within the logical unit data has been lost. 1 Dynamic reconfiguration in progress: The logical unit is being reconfigured. In this state all data is still protected. 2 Exposed: Within the logical unit data is not protected. In this state all data is still valid; however, loss of data or data availability is unavoidable in the event of a failure. 3 Fractionally exposed: Within the logical unit part of the data is not protected. In this state all data is still valid; however, a failure may cause a loss of data or a loss of data availability. 4 Partially exposed: Within the logical unit one or more underlying storage devices have failed. In this state all data is still protected. 5 Protected rebuild: The logical unit is in the process of a rebuild operation. In this state all data is protected. 6 Protection disabled: Within the logical unit the data protection method has been disabled. In this state all data is still valid; however, loss of data or data availability is unavoidable in the event of a failure. 7 Rebuild: The data protection method is in the process of rebuilding data. In this state data is not protected. 8 Recalculate: The logical unit is in the process of a recalculate operation. 9 Spare in use: Within the logical unit a storage device in full or part is being used to store data. In this state all data is still protected. 10 Verify in progress: Within the logical unit data is being verified." REFERENCE "SCSI Controller Commands-2 (SCC-2) ANSI INCITS 318-1998 6.3.1.8 REPORT STATES service action [SCC2]" ::= { scsiLuEntry 9 } scsiLuInCommands OBJECT-TYPE SYNTAX Counter32 UNITS "commands" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of commands received by this logical unit. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiLuLastCreation." ::= { scsiLuEntry 10 } scsiLuReadMegaBytes OBJECT-TYPE SYNTAX Counter32 UNITS "Megabytes" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the amount of data in megabytes read from this logical unit. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiLuLastCreation." ::= { scsiLuEntry 11 } scsiLuWrittenMegaBytes OBJECT-TYPE SYNTAX Counter32 UNITS "Megabytes" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the amount of data in megabytes written to this logical unit. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiLuLastCreation." ::= { scsiLuEntry 12 } scsiLuInResets OBJECT-TYPE SYNTAX Counter32 UNITS "resets" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of times that this logical unit received - a LOGICAL UNIT RESET or TARGET RESET task management request, or - any other SCSI transport protocol-specific action or event that causes a Logical Unit Reset or a Hard Reset at a SCSI target port of the containing device ([SAM2] Chapters 5.9.6, 5.9.7). Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiLuLastCreation." REFERENCE "SCSI Architecture Model-2 (SAM-2), ANSI INCITS 366-2003, T10 Project 1157-D, 12 September 2002 - Chapter 5.9.7 [SAM2]" ::= { scsiLuEntry 13 } scsiLuOutTaskSetFullStatus OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of Task Set full statuses issued for this logical unit. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiLuLastCreation." ::= { scsiLuEntry 14 } scsiLuHSInCommands OBJECT-TYPE SYNTAX Counter64 UNITS "commands" MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the number of commands received by this logical unit. This object provides support for systems that can quickly generate a large number of commands because they run at high speed. Discontinuities in the value of this counter can occur at re- initialization of the management system, and at other times as indicated by the value of scsiLuLastCreation." ::= { scsiLuEntry 15 } scsiLuLastCreation OBJECT-TYPE SYNTAX TimeStamp MAX-ACCESS read-only STATUS current DESCRIPTION "This object indicates the value of sysUpTime when this row was last created." ::= { scsiLuEntry 16 } --****************** Logical Unit Identifier Table ***************** scsiLuIdTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiLuIdEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A table of identifiers for all logical units exposed by the local SCSI target device." ::= { scsiLogicalUnit 2 } scsiLuIdEntry OBJECT-TYPE SYNTAX ScsiLuIdEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing information applicable to a particular identifier for a particular logical unit of a particular SCSI target device within a particular SCSI instance." INDEX {scsiInstIndex, scsiDeviceIndex, scsiLuIndex, scsiLuIdIndex} ::= { scsiLuIdTable 1 } ScsiLuIdEntry ::= SEQUENCE { scsiLuIdIndex ScsiIndexValue, scsiLuIdCodeSet ScsiIdCodeSet, scsiLuIdAssociation ScsiIdAssociation, scsiLuIdType ScsiIdType, scsiLuIdValue ScsiIdValue } scsiLuIdIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object represents an arbitrary integer used to uniquely identify a particular LU identifier within a particular logical unit within a particular SCSI target device within a particular SCSI instance." ::= { scsiLuIdEntry 1 } scsiLuIdCodeSet OBJECT-TYPE SYNTAX ScsiIdCodeSet MAX-ACCESS read-only STATUS current DESCRIPTION "This object specifies the code set in use with this identifier. The value is represented in the same format as is contained in the identifier's Identification Descriptor within the logical unit's Device Identification Page." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001 Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" ::= { scsiLuIdEntry 2 } scsiLuIdAssociation OBJECT-TYPE SYNTAX ScsiIdAssociation MAX-ACCESS read-only STATUS current DESCRIPTION "This object specifies what the identifier is associated with (e.g., with the addressed physical/logical device or with a particular port). The value is represented in the same format as is contained in the identifier's Identification Descriptor within the logical unit's Device Identification Page." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001, Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" ::= { scsiLuIdEntry 3 } scsiLuIdType OBJECT-TYPE SYNTAX ScsiIdType MAX-ACCESS read-only STATUS current DESCRIPTION "This object specifies the type of the identifier. The value is represented in the same format as is contained in the identifier's Identification Descriptor within the logical unit's Device Identification Page." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001, Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" ::= { scsiLuIdEntry 4 } scsiLuIdValue OBJECT-TYPE SYNTAX ScsiIdValue MAX-ACCESS read-only STATUS current DESCRIPTION "This object represents the actual value of this identifier. The format is defined by the objects scsiLuIdCodeSet, scsiLuIdAssociation, scsiLuIdType. The value is represented in the same format as is contained in the identifier's Identification Descriptor within the logical unit's Device Identification Page." REFERENCE "ANSI - SCSI Primary Commands - 2 (SPC-2), ANSI INCITS 351-2001, 11 July 2001, Chapter 8: section 8.4.4, Vital Product Data Parameters [SPC2]" ::= { scsiLuIdEntry 5 } --******************* The LUN Map Table **************************** scsiLunMapTable OBJECT-TYPE SYNTAX SEQUENCE OF ScsiLunMapEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This table provides the ability to present a logical unit using different Logical Unit Numbers for different SCSI initiator devices. This table provides a mapping between a logical unit and a Logical Unit Number, and can be referenced by a ScsiAuthorizedIntrEntry to specify the LUN map for that initiator." ::= { scsiLogicalUnit 3 } scsiLunMapEntry OBJECT-TYPE SYNTAX ScsiLunMapEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry containing information about the mapping of a particular logical unit to a particular LUN. The set of entries that all have the same values of scsiInstIndex, scsiDeviceIndex and scsiLunMapIndex constitutes a LUN map within a particular SCSI instance. The StorageType of a row in this table is specified by the instance of scsiInstStorageType that is INDEX-ed by the same value of scsiInstIndex." INDEX { scsiInstIndex, scsiDeviceIndex, scsiLunMapIndex, scsiLunMapLun} ::= { scsiLunMapTable 1 } ScsiLunMapEntry ::= SEQUENCE { scsiLunMapIndex ScsiIndexValue, scsiLunMapLun ScsiLUN, scsiLunMapLuIndex ScsiIndexValue, scsiLunMapRowStatus RowStatus } scsiLunMapIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object represents an arbitrary integer used to uniquely identify a particular LunMap within a particular SCSI target device within a particular SCSI instance." ::= { scsiLunMapEntry 1 } scsiLunMapLun OBJECT-TYPE SYNTAX ScsiLUN MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object specifies the Logical Unit Number, to which a logical unit is mapped by this row." ::= { scsiLunMapEntry 2 } scsiLunMapLuIndex OBJECT-TYPE SYNTAX ScsiIndexValue MAX-ACCESS read-create STATUS current DESCRIPTION "This object identifies the logical unit for which the value of scsiLuIndex is the same as the value of this object. The identified logical unit is the one mapped to a LUN by this row." ::= { scsiLunMapEntry 3 } scsiLunMapRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This object allows an administrator to create and delete this entry." ::= { scsiLunMapEntry 4 } --********************** Notifications ****************************** -- scsiNotifications OBJECT IDENTIFIER ::= { scsiMIB 2 } scsiNotificationsPrefix OBJECT IDENTIFIER ::= { scsiNotifications 0 } scsiTgtDeviceStatusChanged NOTIFICATION-TYPE OBJECTS { scsiTgtDeviceStatus } STATUS current DESCRIPTION "This notification will be generated for each occurrence of the abnormal status (e.g., if the SCSI target device's current status is abnormal) providing that the SCSI instance's value of scsiInstScsiNotificationsEnable is enabled. An SNMP agent implementing the SCSI MIB module should not send more than three SCSI identical notifications in any 10-second period." ::= { scsiNotificationsPrefix 1 } scsiLuStatusChanged NOTIFICATION-TYPE OBJECTS { scsiLuStatus } STATUS current DESCRIPTION "This notification will be generated each time that scsiLuStatus changes providing that the SCSI instance's value of scsiInstScsiNotificationsEnable is enabled. An SNMP agent implementing the SCSI MIB module should not send more than three SCSI identical notifications in any 10-second period." ::= { scsiNotificationsPrefix 2 } --****************************************************************** -- The next part defines the conformance groups in use -- for SCSI MIB module. scsiCompliances OBJECT IDENTIFIER ::= { scsiConformance 1 } scsiCompliance MODULE-COMPLIANCE STATUS current DESCRIPTION "Describes the requirements for compliance to this SCSI MIB module. If an implementation can be both a SCSI target device and a SCSI initiator device, all groups are mandatory." MODULE -- this module MANDATORY-GROUPS { scsiDeviceGroup } OBJECT scsiInstAlias MIN-ACCESS read-only DESCRIPTION "Write access is not mandatory." OBJECT scsiInstScsiNotificationsEnable MIN-ACCESS read-only DESCRIPTION "Write access is not mandatory." OBJECT scsiDeviceAlias MIN-ACCESS read-only DESCRIPTION "Write access is not mandatory." OBJECT scsiInstStorageType MIN-ACCESS read-only DESCRIPTION "Write access is not required." -- Conditionally mandatory groups to be included with -- the mandatory groups when the implementation has -- SCSI target device. GROUP scsiTargetDeviceGroup DESCRIPTION "This group is mandatory for all SCSI implementations that have SCSI target devices." GROUP scsiLunMapGroup DESCRIPTION "This group is mandatory for systems having the capabilities of mapping local SCSI target devices and logical units according to remote SCSI initiator devices." OBJECT scsiAuthIntrDevOrPort MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT scsiAuthIntrName MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT scsiAuthIntrLunMapIndex MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT scsiAuthIntrRowStatus SYNTAX RowStatus { active(1) } MIN-ACCESS read-only DESCRIPTION "Write access is not required, and only one of the six enumerated values for the RowStatus textual convention need be supported, specifically: active(1)." GROUP scsiTgtDevLuNotificationsGroup DESCRIPTION "This group is mandatory for all SCSI implementations that have SCSI target devices and are able to report status changes." -- Conditionally mandatory groups to be included with -- the mandatory groups when the implementation has -- SCSI initiator device. GROUP scsiInitiatorDeviceGroup DESCRIPTION "This group is mandatory for all SCSI implementations that have SCSI initiator devices." OBJECT scsiIntrDevTgtAccessMode MIN-ACCESS read-only DESCRIPTION "Write access is not mandatory." GROUP scsiDiscoveryGroup DESCRIPTION "This group is mandatory for systems having the capabilities of discovering remote SCSI target devices via local SCSI initiator devices." OBJECT scsiLunMapLuIndex MIN-ACCESS read-only DESCRIPTION "Write access is not mandatory." OBJECT scsiLunMapRowStatus SYNTAX RowStatus { active(1) } MIN-ACCESS read-only DESCRIPTION "Write access is not required, and only one of the six enumerated values for the RowStatus textual convention need be supported, specifically: active(1)." OBJECT scsiDscTgtDevOrPort MIN-ACCESS read-only DESCRIPTION "Write access is not mandatory." OBJECT scsiDscTgtName MIN-ACCESS read-only DESCRIPTION "Write access is not mandatory." OBJECT scsiDscTgtConfigured SYNTAX TruthValue { false(2) } MIN-ACCESS read-only DESCRIPTION "The value of true(1) is not mandatory neither is the write access." OBJECT scsiDscTgtRowStatus SYNTAX RowStatus { active(1) } MIN-ACCESS read-only DESCRIPTION "Write access is not required, and only one of the six enumerated values for the RowStatus textual convention need be supported, specifically: active(1)." -- Conditionally mandatory groups to be included with the mandatory -- groups when the implementation can gather statistics. GROUP scsiDeviceStatGroup DESCRIPTION "This group is mandatory for all SCSI implementations that can gather statistics." -- Conditionally mandatory groups to be included with the mandatory -- groups when the implementation can gather statistics at the SCSI -- initiator device side. GROUP scsiInitiatorDevStatsGroup DESCRIPTION "This group is mandatory for all SCSI implementations that can gather statistics at SCSI initiator device side." GROUP scsiDiscoveryStatsGroup DESCRIPTION "This group is mandatory for system having the capabilities of gathering statistics regarding remote SCSI target devices via local SCSI initiator devices." -- Conditionally mandatory groups to be included with the mandatory -- groups when the implementation can gather statistics at the SCSI -- target side. GROUP scsiTargetDevStatsGroup DESCRIPTION "This group is mandatory for all SCSI implementations that can gather statistics at SCSI target devices." GROUP scsiLunMapStatsGroup DESCRIPTION "This group is mandatory for SCSI implementations able to map local SCSI target devices and logical units according to remote SCSI initiator devices." -- Conditionally mandatory groups to be included with the mandatory -- groups when the implementation is running at high speed and can -- gather statistics at the SCSI initiator device side. GROUP scsiInitiatorDevHSStatsGroup DESCRIPTION "This group is mandatory for all SCSI implementations that can gather statistics at the SCSI initiator device side and are running at high speed, meaning speed of 4 Gbit/second or higher." GROUP scsiDiscoveryHSStatsGroup DESCRIPTION "This group is mandatory for systems having the capabilities of gathering statistics regarding remote SCSI target devices via local SCSI initiator devices and are running at high speed, meaning speed of 4 Gbit/second or higher." -- Conditionally mandatory groups to be included with the mandatory -- groups when the implementation is running at high speed and can -- gather statistics at the SCSI target side. GROUP scsiTargetDevHSStatsGroup DESCRIPTION "This group is mandatory for all SCSI implementations that can gather statistics at SCSI target devices in high speed systems, meaning speed of 4 Gbit/second or higher." GROUP scsiLunMapHSStatsGroup DESCRIPTION "This group is mandatory for SCSI implementations able to map local SCSI target devices and logical units according to remote SCSI initiator devices in a high speed system, meaning speed of 4 Gbit/second or higher." ::= { scsiCompliances 1 } scsiGroups OBJECT IDENTIFIER ::= { scsiConformance 2 } scsiDeviceGroup OBJECT-GROUP OBJECTS { scsiInstAlias, scsiInstSoftwareIndex, scsiInstVendorVersion, scsiInstScsiNotificationsEnable, scsiInstStorageType, scsiDeviceAlias, scsiDeviceRole, scsiDevicePortNumber, scsiPortRole, scsiPortTransportPtr, scsiTransportType, scsiTransportPointer, scsiTransportDevName } STATUS current DESCRIPTION "A collection of objects providing information about SCSI instances, devices, and ports." ::= { scsiGroups 1 } scsiInitiatorDeviceGroup OBJECT-GROUP OBJECTS { scsiIntrDevTgtAccessMode, scsiIntrPortName, scsiIntrPortIdentifier, scsiAttTgtPortDscTgtIdx, scsiAttTgtPortName, scsiAttTgtPortIdentifier } STATUS current DESCRIPTION "This group is relevant for s SCSI initiator device and port." ::= { scsiGroups 2 } scsiDiscoveryGroup OBJECT-GROUP OBJECTS { scsiDscTgtDevOrPort, scsiDscTgtName, scsiDscTgtConfigured, scsiDscTgtDiscovered, scsiDscTgtRowStatus, scsiDscTgtLastCreation, scsiDscLunLun, scsiDscLunIdCodeSet, scsiDscLunIdAssociation, scsiDscLunIdType, scsiDscLunIdValue } STATUS current DESCRIPTION "This group is relevant for the discovered SCSI target devices by a SCSI initiator port." ::= { scsiGroups 3 } scsiTargetDeviceGroup OBJECT-GROUP OBJECTS { scsiTgtDevNumberOfLUs, scsiTgtDeviceStatus, scsiTgtDevNonAccessibleLUs, scsiTgtPortName, scsiTgtPortIdentifier, scsiAttIntrPortAuthIntrIdx, scsiAttIntrPortName, scsiAttIntrPortIdentifier, scsiLuDefaultLun, scsiLuWwnName, scsiLuVendorId, scsiLuProductId, scsiLuRevisionId, scsiLuPeripheralType, scsiLuStatus, scsiLuState, scsiLuLastCreation, scsiLuIdCodeSet, scsiLuIdAssociation, scsiLuIdType, scsiLuIdValue } STATUS current DESCRIPTION "This group is relevant for a SCSI target device and port." ::= { scsiGroups 4 } scsiLunMapGroup OBJECT-GROUP OBJECTS { scsiLunMapLuIndex, scsiLunMapRowStatus, scsiAuthIntrDevOrPort, scsiAuthIntrName, scsiAuthIntrLunMapIndex, scsiAuthIntrLastCreation, scsiAuthIntrRowStatus } STATUS current DESCRIPTION "This group is a collection of attributes regarding the mapping between Logical Unit Number, logical unit, and target device." ::= { scsiGroups 5} scsiTargetDevStatsGroup OBJECT-GROUP OBJECTS { scsiTgtDevResets, scsiTgtPortInCommands, scsiTgtPortWrittenMegaBytes, scsiTgtPortReadMegaBytes, scsiLuInCommands, scsiLuReadMegaBytes, scsiLuWrittenMegaBytes, scsiLuInResets, scsiLuOutTaskSetFullStatus } STATUS current DESCRIPTION "This group is a collection of statistics for all implementations of the SCSI MIB module that contain SCSI target devices." ::= { scsiGroups 6} scsiTargetDevHSStatsGroup OBJECT-GROUP OBJECTS { scsiTgtPortHSInCommands, scsiLuHSInCommands } STATUS current DESCRIPTION "This group is a collection of high speed statistics for all implementations of the SCSI MIB module that contain SCSI target devices." ::= { scsiGroups 7} scsiLunMapStatsGroup OBJECT-GROUP OBJECTS { scsiAuthIntrAttachedTimes, scsiAuthIntrOutCommands, scsiAuthIntrReadMegaBytes, scsiAuthIntrWrittenMegaBytes } STATUS current DESCRIPTION "This group is a collection of statistics regarding SCSI initiator devices authorized to attach local logical unit and SCSI target device." ::= { scsiGroups 8} scsiLunMapHSStatsGroup OBJECT-GROUP OBJECTS { scsiAuthIntrHSOutCommands } STATUS current DESCRIPTION "This group is a collection of high speed statistics regarding SCSI initiator devices authorized to attach local logical unit and SCSI target device." ::= { scsiGroups 9} scsiInitiatorDevStatsGroup OBJECT-GROUP OBJECTS { scsiIntrDevOutResets, scsiIntrPortOutCommands, scsiIntrPortWrittenMegaBytes, scsiIntrPortReadMegaBytes } STATUS current DESCRIPTION "This group is a collection of statistics for all implementations of the SCSI MIB module that contain SCSI initiator devices." ::= { scsiGroups 10} scsiInitiatorDevHSStatsGroup OBJECT-GROUP OBJECTS { scsiIntrPortHSOutCommands } STATUS current DESCRIPTION "This group is a collection of high speed statistics for all implementations of the SCSI MIB module that contain SCSI initiator devices." ::= { scsiGroups 11} scsiDiscoveryStatsGroup OBJECT-GROUP OBJECTS { scsiDscTgtInCommands, scsiDscTgtReadMegaBytes, scsiDscTgtWrittenMegaBytes } STATUS current DESCRIPTION "This group is a collection of statistics for all implementations of the SCSI MIB module that contain discovered SCSI initiator devices." ::= { scsiGroups 12} scsiDiscoveryHSStatsGroup OBJECT-GROUP OBJECTS { scsiDscTgtHSInCommands } STATUS current DESCRIPTION "This group is a collection of high speed statistics for all implementations of the SCSI MIB module that contain discovered SCSI initiator devices." ::= { scsiGroups 13} scsiDeviceStatGroup OBJECT-GROUP OBJECTS { scsiPortBusyStatuses } STATUS current DESCRIPTION "A collection of statistics regarding SCSI devices and ports." ::= { scsiGroups 14 } scsiTgtDevLuNotificationsGroup NOTIFICATION-GROUP NOTIFICATIONS { scsiTgtDeviceStatusChanged, scsiLuStatusChanged } STATUS current DESCRIPTION "A collection of notifications regarding status change of SCSI target devices and logical units." ::= { scsiGroups 15 } END lio-utils-3.1+git2.fd0b34fd/mib-modules/mibs/LIO-IPS-AUTH-MIB.txt0000644000175000017500000012007211753136721021770 0ustar rrsrrsLIO-IPS-AUTH-MIB DEFINITIONS ::= BEGIN IMPORTS MODULE-IDENTITY, OBJECT-TYPE, OBJECT-IDENTITY, Unsigned32, mib-2, enterprises FROM SNMPv2-SMI TEXTUAL-CONVENTION, RowStatus, AutonomousType, StorageType FROM SNMPv2-TC MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF SnmpAdminString FROM SNMP-FRAMEWORK-MIB -- RFC 3411 AddressFamilyNumbers FROM IANA-ADDRESS-FAMILY-NUMBERS-MIB ; lio OBJECT IDENTIFIER ::= { enterprises 1055 } iscsiProduct OBJECT IDENTIFIER ::= { lio 10 } ipsAuthMibModule MODULE-IDENTITY LAST-UPDATED "200602240000Z" -- February 24, 2006 ORGANIZATION "IETF IPS Working Group" CONTACT-INFO " Mark Bakke Postal: Cisco Systems, Inc 7900 International Drive, Suite 400 Bloomington, MN USA 55425 E-mail: mbakke@cisco.com James Muchow Postal: Qlogic Corp. 6321 Bury Dr. Eden Prairie, MN USA 55346 E-Mail: james.muchow@qlogic.com" DESCRIPTION "The IP Storage Authorization MIB module. Copyright (C) The Internet Society (2006). This version of this MIB module is part of RFC yyyy; see the RFC itself for full legal notices." -- RFC Ed.: replace yyyy with actual RFC number & remove this note REVISION "200602240000Z" -- February 24, 2006 DESCRIPTION "Initial version of the IP Storage Authentication MIB module, published as RFC yyyy" -- RFC Ed.: fill in yyyy ::= { iscsiProduct 2 } ipsAuthNotifications OBJECT IDENTIFIER ::= { ipsAuthMibModule 0 } ipsAuthObjects OBJECT IDENTIFIER ::= { ipsAuthMibModule 1 } ipsAuthConformance OBJECT IDENTIFIER ::= { ipsAuthMibModule 2 } -- Textual Conventions IpsAuthAddress ::= TEXTUAL-CONVENTION STATUS current DESCRIPTION "IP Storage requires the use of address information that uses not only the InetAddress type defined in the INET-ADDRESS-MIB, but also Fibre Channel type defined in the Fibre Channel Management MIB. Although these address types are recognized in the IANA Address Family Numbers MIB, the addressing mechanisms have not been merged into a well-known, common type. This data type, the IpsAuthAddress, performs the merging for this MIB module. The formats of objects of this type are determined by a corresponding object with syntax AddressFamilyNumbers and thus, every object defined using this TC must identify the object with syntax AddressFamilyNumbers which specifies its type. The syntax and semantics of this object depends on the identified AddressFamilyNumbers object as follows: AddressFamilyNumbers this object ==================== =========== ipV4(1) restricted to the same syntax and semantics as the InetAddressIPv4 TC. ipV6(2) restricted to the same syntax and semantics as the InetAddressIPv6 TC. fibreChannelWWPN (22) & fibreChannelWWNN(23) restricted to the same syntax and semantics as the FcNameIdOrZero TC. Using types other than the above should not be used unless the corresponding format of the IpsAuthAddress object is further specified (e.g., in a future revision of this TC)." REFERENCE "IANA-ADDRESS-FAMILY-NUMBERS-MIB; INET-ADDRESS-MIB (RFC 4001); FC-MGMT-MIB (RFC 4044)." SYNTAX OCTET STRING (SIZE(0..255)) --****************************************************************** ipsAuthDescriptors OBJECT IDENTIFIER ::= { ipsAuthObjects 1 } ipsAuthMethodTypes OBJECT-IDENTITY STATUS current DESCRIPTION "Registration point for Authentication Method Types." REFERENCE "RFC 3720, iSCSI Protocol Specification." ::= { ipsAuthDescriptors 1 } ipsAuthMethodNone OBJECT-IDENTITY STATUS current DESCRIPTION "The authoritative identifier when no authentication method is used." REFERENCE "RFC 3720, iSCSI Protocol Specification." ::= { ipsAuthMethodTypes 1 } ipsAuthMethodSrp OBJECT-IDENTITY STATUS current DESCRIPTION "The authoritative identifier when the authentication method is SRP." REFERENCE "RFC 3720, iSCSI Protocol Specification." ::= { ipsAuthMethodTypes 2 } ipsAuthMethodChap OBJECT-IDENTITY STATUS current DESCRIPTION "The authoritative identifier when the authentication method is CHAP." REFERENCE "RFC 3720, iSCSI Protocol Specification." ::= { ipsAuthMethodTypes 3 } ipsAuthMethodKerberos OBJECT-IDENTITY STATUS current DESCRIPTION "The authoritative identifier when the authentication method is Kerberos." REFERENCE "RFC 3720, iSCSI Protocol Specification." ::= { ipsAuthMethodTypes 4 } --****************************************************************** ipsAuthInstance OBJECT IDENTIFIER ::= { ipsAuthObjects 2 } -- Instance Attributes Table ipsAuthInstanceAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IpsAuthInstanceAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of Authorization instances present on the system." ::= { ipsAuthInstance 2 } ipsAuthInstanceAttributesEntry OBJECT-TYPE SYNTAX IpsAuthInstanceAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a particular Authorization instance." INDEX { ipsAuthInstIndex } ::= { ipsAuthInstanceAttributesTable 1 } IpsAuthInstanceAttributesEntry ::= SEQUENCE { ipsAuthInstIndex Unsigned32, ipsAuthInstDescr SnmpAdminString, ipsAuthInstStorageType StorageType } ipsAuthInstIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular authorization instance. This index value must not be modified or reused by an agent unless a reboot has occurred. An agent should attempt to keep this value persistent across reboots." ::= { ipsAuthInstanceAttributesEntry 1 } ipsAuthInstDescr OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-write STATUS current DESCRIPTION "A character string, determined by the implementation to describe the authorization instance. When only a single instance is present, this object may be set to the zero-length string; with multiple authorization instances, it must be set to a unique value in an implementation-dependent manner to describe the purpose of the respective instance. If this is deployed in a master agent with more than one subagent implementing this MIB module, the master agent is responsible for ensuring that this object is unique across all subagents." ::= { ipsAuthInstanceAttributesEntry 2 } ipsAuthInstStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-write STATUS current DESCRIPTION "The storage type for all read-write objects within this row. Rows in this table are always created via an external process, and may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row. If this object has the value 'volatile', modifications to read-write objects in this row are not persistent across reboots. If this object has the value 'nonVolatile', modifications to objects in this row are persistent. An implementation may choose to allow this object to be set to either 'nonVolatile' or 'volatile', allowing the management application to choose this behavior." DEFVAL { volatile } ::= { ipsAuthInstanceAttributesEntry 3 } ipsAuthIdentity OBJECT IDENTIFIER ::= { ipsAuthObjects 3 } -- User Identity Attributes Table ipsAuthIdentAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IpsAuthIdentAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of user identities, each belonging to a particular ipsAuthInstance." ::= { ipsAuthIdentity 1 } ipsAuthIdentAttributesEntry OBJECT-TYPE SYNTAX IpsAuthIdentAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information describing a user identity within an authorization instance on this node." INDEX { ipsAuthInstIndex, ipsAuthIdentIndex } ::= { ipsAuthIdentAttributesTable 1 } IpsAuthIdentAttributesEntry ::= SEQUENCE { ipsAuthIdentIndex Unsigned32, ipsAuthIdentDescription SnmpAdminString, ipsAuthIdentRowStatus RowStatus, ipsAuthIdentStorageType StorageType } ipsAuthIdentIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular identity instance within an authorization instance present on the node. This index value must not be modified or reused by an agent unless a reboot has occurred. An agent should attempt to keep this value persistent across reboots." ::= { ipsAuthIdentAttributesEntry 1 } ipsAuthIdentDescription OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-create STATUS current DESCRIPTION "A character string describing this particular identity." ::= { ipsAuthIdentAttributesEntry 2 } ipsAuthIdentRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This field allows entries to be dynamically added and removed from this table via SNMP. When adding a row to this table, all non-Index/RowStatus objects must be set. Rows may be discarded using RowStatus. The value of ipsAuthIdentDescription may be set while ipsAuthIdentRowStatus is 'active'." ::= { ipsAuthIdentAttributesEntry 3 } ipsAuthIdentStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-create STATUS current DESCRIPTION "The storage type for all read-create objects in this row. Rows in this table that were created through an external process may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row." DEFVAL { nonVolatile } ::= { ipsAuthIdentAttributesEntry 4 } ipsAuthIdentityName OBJECT IDENTIFIER ::= { ipsAuthObjects 4 } -- User Initiator Name Attributes Table ipsAuthIdentNameAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IpsAuthIdentNameAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of unique names that can be used to positively identify a particular user identity." ::= { ipsAuthIdentityName 1 } ipsAuthIdentNameAttributesEntry OBJECT-TYPE SYNTAX IpsAuthIdentNameAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a unique identity name which can be used to identify a user identity within a particular authorization instance." INDEX { ipsAuthInstIndex, ipsAuthIdentIndex, ipsAuthIdentNameIndex } ::= { ipsAuthIdentNameAttributesTable 1 } IpsAuthIdentNameAttributesEntry ::= SEQUENCE { ipsAuthIdentNameIndex Unsigned32, ipsAuthIdentName SnmpAdminString, ipsAuthIdentNameRowStatus RowStatus, ipsAuthIdentNameStorageType StorageType } ipsAuthIdentNameIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular identity name instance within an ipsAuthIdentity within an authorization instance. This index value must not be modified or reused by an agent unless a reboot has occurred. An agent should attempt to keep this value persistent across reboots." ::= { ipsAuthIdentNameAttributesEntry 1 } ipsAuthIdentName OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-create STATUS current DESCRIPTION "A character string which is the unique name of an identity that may be used to identify this ipsAuthIdent entry." ::= { ipsAuthIdentNameAttributesEntry 2 } ipsAuthIdentNameRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This field allows entries to be dynamically added and removed from this table via SNMP. When adding a row to this table, all non-Index/RowStatus objects must be set. Rows may be discarded using RowStatus. The value of ipsAuthIdentName may be set when this value is 'active'." ::= { ipsAuthIdentNameAttributesEntry 3 } ipsAuthIdentNameStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-create STATUS current DESCRIPTION "The storage type for all read-create objects in this row. Rows in this table that were created through an external process may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row." DEFVAL { nonVolatile } ::= { ipsAuthIdentNameAttributesEntry 4 } ipsAuthIdentityAddress OBJECT IDENTIFIER ::= { ipsAuthObjects 5 } -- User Initiator Address Attributes Table ipsAuthIdentAddrAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IpsAuthIdentAddrAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of address ranges that are allowed to serve as the endpoint addresses of a particular identity. An address range includes a starting and ending address and an optional netmask, and an address type indicator, which can specify whether the address is IPv4, IPv6, FC-WWPN, or FC-WWNN." ::= { ipsAuthIdentityAddress 1 } ipsAuthIdentAddrAttributesEntry OBJECT-TYPE SYNTAX IpsAuthIdentAddrAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to an address range which is used as part of the authorization of an identity within an authorization instance on this node." INDEX { ipsAuthInstIndex, ipsAuthIdentIndex, ipsAuthIdentAddrIndex } ::= { ipsAuthIdentAddrAttributesTable 1 } IpsAuthIdentAddrAttributesEntry ::= SEQUENCE { ipsAuthIdentAddrIndex Unsigned32, ipsAuthIdentAddrType AddressFamilyNumbers, ipsAuthIdentAddrStart IpsAuthAddress, ipsAuthIdentAddrEnd IpsAuthAddress, ipsAuthIdentAddrRowStatus RowStatus, ipsAuthIdentAddrStorageType StorageType } ipsAuthIdentAddrIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular ipsAuthIdentAddress instance within an ipsAuthIdentity within an authorization instance present on the node. This index value must not be modified or reused by an agent unless a reboot has occurred. An agent should attempt to keep this value persistent across reboots." ::= { ipsAuthIdentAddrAttributesEntry 1 } ipsAuthIdentAddrType OBJECT-TYPE SYNTAX AddressFamilyNumbers MAX-ACCESS read-create STATUS current DESCRIPTION "The address types used in the ipsAuthIdentAddrStart and ipsAuthAddrEnd objects. This type is taken from the IANA address family types." ::= { ipsAuthIdentAddrAttributesEntry 2 } ipsAuthIdentAddrStart OBJECT-TYPE SYNTAX IpsAuthAddress MAX-ACCESS read-create STATUS current DESCRIPTION "The starting address of the allowed address range. The format of this object is determined by ipsAuthIdentAddrType." ::= { ipsAuthIdentAddrAttributesEntry 3 } ipsAuthIdentAddrEnd OBJECT-TYPE SYNTAX IpsAuthAddress MAX-ACCESS read-create STATUS current DESCRIPTION "The ending address of the allowed address range. If the ipsAuthIdentAddrEntry specifies a single address, this shall match the ipsAuthIdentAddrStart. The format of this object is determined by ipsAuthIdentAddrType." ::= { ipsAuthIdentAddrAttributesEntry 4 } ipsAuthIdentAddrRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This field allows entries to be dynamically added and removed from this table via SNMP. When adding a row to this table, all non-Index/RowStatus objects must be set. Rows may be discarded using RowStatus. The values of ipsAuthIdentAddrStart, ipsAuthIdentAddrEnd may be set when this value is 'active'. The value of ipsAuthIdentAddrType may not be set when this value is 'active'." ::= { ipsAuthIdentAddrAttributesEntry 5 } ipsAuthIdentAddrStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-create STATUS current DESCRIPTION "The storage type for all read-create objects in this row. Rows in this table that were created through an external process may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row." DEFVAL { nonVolatile } ::= { ipsAuthIdentAddrAttributesEntry 6 } ipsAuthCredential OBJECT IDENTIFIER ::= { ipsAuthObjects 6 } -- Credential Attributes Table ipsAuthCredentialAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IpsAuthCredentialAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of credentials related to user identities that are allowed as valid authenticators of the particular identity." ::= { ipsAuthCredential 1 } ipsAuthCredentialAttributesEntry OBJECT-TYPE SYNTAX IpsAuthCredentialAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a credential which verifies a user identity within an authorization instance. To provide complete information in this MIB for a credential, the management station must not only create the row in this table but must also create a row in another table, where the other table is determined by the value of ipsAuthCredAuthMethod, e.g, if ipsAuthCredAuthMethod has the value ipsAuthMethodChap, a row must be created in the ipsAuthCredChapAttributesTable." INDEX { ipsAuthInstIndex, ipsAuthIdentIndex, ipsAuthCredIndex } ::= { ipsAuthCredentialAttributesTable 1 } IpsAuthCredentialAttributesEntry ::= SEQUENCE { ipsAuthCredIndex Unsigned32, ipsAuthCredAuthMethod AutonomousType, ipsAuthCredRowStatus RowStatus, ipsAuthCredStorageType StorageType } ipsAuthCredIndex OBJECT-TYPE SYNTAX Unsigned32 (1..4294967295) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An arbitrary integer used to uniquely identify a particular Credential instance within an instance present on the node. This index value must not be modified or reused by an agent unless a reboot has occurred. An agent should attempt to keep this value persistent across reboots." ::= { ipsAuthCredentialAttributesEntry 1 } ipsAuthCredAuthMethod OBJECT-TYPE SYNTAX AutonomousType MAX-ACCESS read-create STATUS current DESCRIPTION "This object contains an OBJECT IDENTIFIER which identifies the authentication method used with this credential. When a row is created in this table, a corresponding row must be created by the management station in a corresponding table specified by this value. When a row is deleted from this table, the corresponding row must be automatically deleted by the agent in the corresponding table specified by this value. If the value of this object is ipsAuthMethodNone, no corresponding rows are created or deleted from other tables. Some standardized values for this object are defined within the ipsAuthMethodTypes subtree." ::= { ipsAuthCredentialAttributesEntry 2 } ipsAuthCredRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This field allows entries to be dynamically added and removed from this table via SNMP. When adding a row to this table, all non-Index/RowStatus objects must be set. Rows may be discarded using RowStatus. The value of ipsAuthCredAuthMethod must not be changed while this row is 'active'." ::= { ipsAuthCredentialAttributesEntry 3 } ipsAuthCredStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-create STATUS current DESCRIPTION "The storage type for all read-create objects in this row. Rows in this table that were created through an external process may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row." DEFVAL { nonVolatile } ::= { ipsAuthCredentialAttributesEntry 4 } ipsAuthCredChap OBJECT IDENTIFIER ::= { ipsAuthObjects 7 } -- Credential Chap-Specific Attributes Table ipsAuthCredChapAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IpsAuthCredChapAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of CHAP attributes for credentials that use ipsAuthMethodChap as its ipsAuthCredAuthMethod. A row in this table can only exist when an instance of the ipsAuthCredAuthMethod object exists (or is created simultaneously) having the same instance identifiers and a value of 'ipsAuthMethodChap'." ::= { ipsAuthCredChap 1 } ipsAuthCredChapAttributesEntry OBJECT-TYPE SYNTAX IpsAuthCredChapAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a credential which uses ipsAuthMethodChap as its ipsAuthCredAuthMethod. When a row is created in ipsAuthCredentialAttributesTable with ipsAuthCredAuthMethod = ipsAuthCredChap, the management station must create a corresponding row in this table. When a row is deleted from ipsAuthCredentialAttributesTable with ipsAuthCredAuthMethod = ipsAuthCredChap, the agent must delete the corresponding row (if any) in this table." INDEX { ipsAuthInstIndex, ipsAuthIdentIndex, ipsAuthCredIndex } ::= { ipsAuthCredChapAttributesTable 1 } IpsAuthCredChapAttributesEntry ::= SEQUENCE { ipsAuthCredChapUserName SnmpAdminString, ipsAuthCredChapRowStatus RowStatus, ipsAuthCredChapStorageType StorageType } ipsAuthCredChapUserName OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-create STATUS current DESCRIPTION "A character string containing the CHAP user name for this credential." REFERENCE "W. Simpson, RFC 1994: PPP Challenge Handshake Authentication Protocol (CHAP), August 1996" ::= { ipsAuthCredChapAttributesEntry 1 } ipsAuthCredChapRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This field allows entries to be dynamically added and removed from this table via SNMP. When adding a row to this table, all non-Index/RowStatus objects must be set. Rows may be discarded using RowStatus. The value of ipsAuthCredChapUserName may be changed while this row is 'active'." ::= { ipsAuthCredChapAttributesEntry 2 } ipsAuthCredChapStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-create STATUS current DESCRIPTION "The storage type for all read-create objects in this row. Rows in this table that were created through an external process may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row." DEFVAL { nonVolatile } ::= { ipsAuthCredChapAttributesEntry 3 } ipsAuthCredSrp OBJECT IDENTIFIER ::= { ipsAuthObjects 8 } -- Credential Srp-Specific Attributes Table ipsAuthCredSrpAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IpsAuthCredSrpAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of SRP attributes for credentials that use ipsAuthMethodSrp as its ipsAuthCredAuthMethod. A row in this table can only exist when an instance of the ipsAuthCredAuthMethod object exists (or is created simultaneously) having the same instance identifiers and a value of 'ipsAuthMethodSrp'." ::= { ipsAuthCredSrp 1 } ipsAuthCredSrpAttributesEntry OBJECT-TYPE SYNTAX IpsAuthCredSrpAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a credential which uses ipsAuthMethodSrp as its ipsAuthCredAuthMethod. When a row is created in ipsAuthCredentialAttributesTable with ipsAuthCredAuthMethod = ipsAuthCredSrp, the management station must create a corresponding row in this table. When a row is deleted from ipsAuthCredentialAttributesTable with ipsAuthCredAuthMethod = ipsAuthCredSrp, the agent must delete the corresponding row (if any) in this table." INDEX { ipsAuthInstIndex, ipsAuthIdentIndex, ipsAuthCredIndex } ::= { ipsAuthCredSrpAttributesTable 1 } IpsAuthCredSrpAttributesEntry ::= SEQUENCE { ipsAuthCredSrpUserName SnmpAdminString, ipsAuthCredSrpRowStatus RowStatus, ipsAuthCredSrpStorageType StorageType } ipsAuthCredSrpUserName OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-create STATUS current DESCRIPTION "A character string containing the SRP user name for this credential." REFERENCE "T. Wu, RFC 2945: The SRP Authentication and Key Exchange System, September 2000" ::= { ipsAuthCredSrpAttributesEntry 1 } ipsAuthCredSrpRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This field allows entries to be dynamically added and removed from this table via SNMP. When adding a row to this table, all non-Index/RowStatus objects must be set. Rows may be discarded using RowStatus. The value of ipsAuthCredSrpUserName may be changed while the status of this row is 'active'." ::= { ipsAuthCredSrpAttributesEntry 2 } ipsAuthCredSrpStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-create STATUS current DESCRIPTION "The storage type for all read-create objects in this row. Rows in this table that were created through an external process may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row." DEFVAL { nonVolatile } ::= { ipsAuthCredSrpAttributesEntry 3 } ipsAuthCredKerberos OBJECT IDENTIFIER ::= { ipsAuthObjects 9 } -- Credential Kerberos-Specific Attributes Table ipsAuthCredKerbAttributesTable OBJECT-TYPE SYNTAX SEQUENCE OF IpsAuthCredKerbAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A list of Kerberos attributes for credentials that use ipsAuthMethodKerberos as its ipsAuthCredAuthMethod. A row in this table can only exist when an instance of the ipsAuthCredAuthMethod object exists (or is created simultaneously) having the same instance identifiers and a value of 'ipsAuthMethodKerb'." ::= { ipsAuthCredKerberos 1 } ipsAuthCredKerbAttributesEntry OBJECT-TYPE SYNTAX IpsAuthCredKerbAttributesEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry (row) containing management information applicable to a credential which uses ipsAuthMethodKerberos as its ipsAuthCredAuthMethod. When a row is created in ipsAuthCredentialAttributesTable with ipsAuthCredAuthMethod = ipsAuthCredKerberos, the management station must create a corresponding row in this table. When a row is deleted from ipsAuthCredentialAttributesTable with ipsAuthCredAuthMethod = ipsAuthCredKerberos, the agent must delete the corresponding row (if any) in this table." INDEX { ipsAuthInstIndex, ipsAuthIdentIndex, ipsAuthCredIndex } ::= { ipsAuthCredKerbAttributesTable 1 } IpsAuthCredKerbAttributesEntry ::= SEQUENCE { ipsAuthCredKerbPrincipal SnmpAdminString, ipsAuthCredKerbRowStatus RowStatus, ipsAuthCredKerbStorageType StorageType } ipsAuthCredKerbPrincipal OBJECT-TYPE SYNTAX SnmpAdminString MAX-ACCESS read-create STATUS current DESCRIPTION "A character string containing a Kerberos principal for this credential." REFERENCE "J. Kohl, C. Neuman, RFC 1510: The Kerberos Network Authentication Service (V5), September 1993" ::= { ipsAuthCredKerbAttributesEntry 1 } ipsAuthCredKerbRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "This field allows entries to be dynamically added and removed from this table via SNMP. When adding a row to this table, all non-Index/RowStatus objects must be set. Rows may be discarded using RowStatus. The value of ipsAuthCredKerbPrincipal may be changed while this row is 'active'." ::= { ipsAuthCredKerbAttributesEntry 2 } ipsAuthCredKerbStorageType OBJECT-TYPE SYNTAX StorageType MAX-ACCESS read-create STATUS current DESCRIPTION "The storage type for all read-create objects in this row. Rows in this table that were created through an external process may have a storage type of readOnly or permanent. Conceptual rows having the value 'permanent' need not allow write access to any columnar objects in the row." DEFVAL { nonVolatile } ::= { ipsAuthCredKerbAttributesEntry 3 } --****************************************************************** -- Notifications -- There are no notifications necessary in this MIB module. --****************************************************************** -- Conformance Statements ipsAuthCompliances OBJECT IDENTIFIER ::= { ipsAuthConformance 1 } ipsAuthGroups OBJECT IDENTIFIER ::= { ipsAuthConformance 2 } ipsAuthInstanceAttributesGroup OBJECT-GROUP OBJECTS { ipsAuthInstDescr, ipsAuthInstStorageType } STATUS current DESCRIPTION "A collection of objects providing information about authorization instances." ::= { ipsAuthGroups 1 } ipsAuthIdentAttributesGroup OBJECT-GROUP OBJECTS { ipsAuthIdentDescription, ipsAuthIdentRowStatus, ipsAuthIdentStorageType } STATUS current DESCRIPTION "A collection of objects providing information about user identities within an authorization instance." ::= { ipsAuthGroups 2 } ipsAuthIdentNameAttributesGroup OBJECT-GROUP OBJECTS { ipsAuthIdentName, ipsAuthIdentNameRowStatus, ipsAuthIdentNameStorageType } STATUS current DESCRIPTION "A collection of objects providing information about user names within user identities within an authorization instance." ::= { ipsAuthGroups 3 } ipsAuthIdentAddrAttributesGroup OBJECT-GROUP OBJECTS { ipsAuthIdentAddrType, ipsAuthIdentAddrStart, ipsAuthIdentAddrEnd, ipsAuthIdentAddrRowStatus, ipsAuthIdentAddrStorageType } STATUS current DESCRIPTION "A collection of objects providing information about address ranges within user identities within an authorization instance." ::= { ipsAuthGroups 4 } ipsAuthIdentCredAttributesGroup OBJECT-GROUP OBJECTS { ipsAuthCredAuthMethod, ipsAuthCredRowStatus, ipsAuthCredStorageType } STATUS current DESCRIPTION "A collection of objects providing information about credentials within user identities within an authorization instance." ::= { ipsAuthGroups 5 } ipsAuthIdentChapAttrGroup OBJECT-GROUP OBJECTS { ipsAuthCredChapUserName, ipsAuthCredChapRowStatus, ipsAuthCredChapStorageType } STATUS current DESCRIPTION "A collection of objects providing information about CHAP credentials within user identities within an authorization instance." ::= { ipsAuthGroups 6 } ipsAuthIdentSrpAttrGroup OBJECT-GROUP OBJECTS { ipsAuthCredSrpUserName, ipsAuthCredSrpRowStatus, ipsAuthCredSrpStorageType } STATUS current DESCRIPTION "A collection of objects providing information about SRP credentials within user identities within an authorization instance." ::= { ipsAuthGroups 7 } ipsAuthIdentKerberosAttrGroup OBJECT-GROUP OBJECTS { ipsAuthCredKerbPrincipal, ipsAuthCredKerbRowStatus, ipsAuthCredKerbStorageType } STATUS current DESCRIPTION "A collection of objects providing information about Kerberos credentials within user identities within an authorization instance." ::= { ipsAuthGroups 8 } --****************************************************************** ipsAuthComplianceV1 MODULE-COMPLIANCE STATUS current DESCRIPTION "Initial version of compliance statement based on initial version of this MIB module. The Instance and Identity groups are mandatory; at least one of the other groups (Name, Address, Credential, Certificate) is also mandatory for any given implementation." MODULE -- this module MANDATORY-GROUPS { ipsAuthInstanceAttributesGroup, ipsAuthIdentAttributesGroup } -- Conditionally mandatory groups to be included with -- the mandatory groups when necessary. GROUP ipsAuthIdentNameAttributesGroup DESCRIPTION "This group is mandatory for all implementations that make use of unique identity names." GROUP ipsAuthIdentAddrAttributesGroup DESCRIPTION "This group is mandatory for all implementations that use addresses to help verify identities." GROUP ipsAuthIdentCredAttributesGroup DESCRIPTION "This group is mandatory for all implementations that use credentials to help verify identities." GROUP ipsAuthIdentChapAttrGroup DESCRIPTION "This group is mandatory for all implementations that use CHAP to help verify identities. The ipsAuthIdentCredAttributesGroup must be implemented if this group is implemented." GROUP ipsAuthIdentSrpAttrGroup DESCRIPTION "This group is mandatory for all implementations that use SRP to help verify identities. The ipsAuthIdentCredAttributesGroup must be implemented if this group is implemented." GROUP ipsAuthIdentKerberosAttrGroup DESCRIPTION "This group is mandatory for all implementations that use Kerberos to help verify identities. The ipsAuthIdentCredAttributesGroup must be implemented if this group is implemented." OBJECT ipsAuthInstDescr MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthInstStorageType MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthIdentDescription MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthIdentRowStatus SYNTAX INTEGER { active(1) } -- subset of RowStatus MIN-ACCESS read-only DESCRIPTION "Write access is not required, and only one of the six enumerated values for the RowStatus textual convention need be supported, specifically: active(1)." OBJECT ipsAuthIdentName MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthIdentNameRowStatus SYNTAX INTEGER { active(1) } -- subset of RowStatus MIN-ACCESS read-only DESCRIPTION "Write access is not required, and only one of the six enumerated values for the RowStatus textual convention need be supported, specifically: active(1)." OBJECT ipsAuthIdentAddrType MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthIdentAddrStart MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthIdentAddrEnd MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthIdentAddrRowStatus SYNTAX INTEGER { active(1) } -- subset of RowStatus MIN-ACCESS read-only DESCRIPTION "Write access is not required, and only one of the six enumerated values for the RowStatus textual convention need be supported, specifically: active(1)." OBJECT ipsAuthCredAuthMethod MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthCredRowStatus SYNTAX INTEGER { active(1) } -- subset of RowStatus MIN-ACCESS read-only DESCRIPTION "Write access is not required, and only one of the six enumerated values for the RowStatus textual convention need be supported, specifically: active(1)." OBJECT ipsAuthCredChapUserName MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthCredChapRowStatus SYNTAX INTEGER { active(1) } -- subset of RowStatus MIN-ACCESS read-only DESCRIPTION "Write access is not required, and only one of the six enumerated values for the RowStatus textual convention need be supported, specifically: active(1)." OBJECT ipsAuthCredSrpUserName MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthCredSrpRowStatus SYNTAX INTEGER { active(1) } -- subset of RowStatus MIN-ACCESS read-only DESCRIPTION "Write access is not required, and only one of the six enumerated values for the RowStatus textual convention need be supported, specifically: active(1)." OBJECT ipsAuthCredKerbPrincipal MIN-ACCESS read-only DESCRIPTION "Write access is not required." OBJECT ipsAuthCredKerbRowStatus SYNTAX INTEGER { active(1) } -- subset of RowStatus MIN-ACCESS read-only DESCRIPTION "Write access is not required, and only one of the six enumerated values for the RowStatus textual convention need be supported, specifically: active(1)." ::= { ipsAuthCompliances 1 } END lio-utils-3.1+git2.fd0b34fd/mib-modules/iscsiTargetMib.c0000644000175000017500000000136411753136721021134 0ustar rrsrrs/* * Copyright (c) 2006 SBE, Inc. */ #include #include #include #include "common.h" #define LIO_ISCSI_VERSION "3.0" extern void init_iscsiMib(void); extern void init_scsiMib(void); extern void init_ipsAuthMib(void); void target_mib_version(unsigned int clientreg, void *clientarg) { snmp_log(LOG_INFO, "Linux-iSCSI.org Target Mib Module version %s\n", LIO_ISCSI_VERSION); } /* Initializes the iscsiTargetMib module */ void init_iscsiTargetMib(void) { init_iscsiMib(); init_scsiMib(); init_ipsAuthMib(); /* Setup callback for mib module version logging */ snmp_alarm_register(1, 0, target_mib_version, NULL); } lio-utils-3.1+git2.fd0b34fd/mib-modules/ipsAuthMib.c0000644000175000017500000011472211753136721020273 0ustar rrsrrs/* * Copyright (c) 2006 SBE, Inc. * Copyright (c) 2009-2011 Linux-iSCSI.org * * Nicholas A. Bellinger * * 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. */ #include #include #include #include #include "common.h" #include "iscsiAuthData.h" #include "ipsAuthMib.h" #define IPS_AUTH_MIB_CACHE_TIMEOUT 10 /* * Initializes the ipsAuthMib module */ void init_ipsAuthMib(void) { /* Initialize all tables */ initialize_table_ipsAuthInstAttr(); initialize_table_ipsAuthIdentAttr(); initialize_table_ipsAuthIdentNameAttr(); initialize_table_ipsAuthCredAttr(); initialize_table_ipsAuthCredChapAttr(); } /* * Instance Attributes Table */ /* * Initialize the ipsAuthInstAttr table */ void initialize_table_ipsAuthInstAttr(void) { static oid ipsAuthInstAttr_oid[] = {OID_LIO_IPS_AUTH_MIB,1,2,2}; size_t ipsAuthInstAttr_oid_len = OID_LENGTH(ipsAuthInstAttr_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("ipsAuthInstAttr", ipsAuthInstAttr_handler, ipsAuthInstAttr_oid, ipsAuthInstAttr_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* ipsAuthInstIndex */ 0); table_info->min_column = 1; table_info->max_column = 3; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = ipsAuthInstAttr_get_first_data_point; iinfo->get_next_data_point = ipsAuthInstAttr_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(IPS_AUTH_MIB_CACHE_TIMEOUT, ipsAuthInstAttr_load, ipsDummy_free, ipsAuthInstAttr_oid, ipsAuthInstAttr_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void ipsAuthInstAttr_cache_update(void) { static marker_t ipsAuthInstAttr_cache_marker = NULL; if (ipsAuthInstAttr_cache_marker && (!atime_ready(ipsAuthInstAttr_cache_marker, IPS_AUTH_MIB_CACHE_TIMEOUT * 1000))) return; if (ipsAuthInstAttr_cache_marker) atime_setMarker(ipsAuthInstAttr_cache_marker); else ipsAuthInstAttr_cache_marker = atime_newMarker(); ipsAuthInstAttr_load(NULL, NULL); } #endif struct ipsAuthInstAttr_entry *ipsAuthInstAttr_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * ipsAuthInstAttr_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER ipsAuthInstAttr_cache_update(); #endif *my_loop_context = ipsAuthInstAttr_head; return ipsAuthInstAttr_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * ipsAuthInstAttr_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct ipsAuthInstAttr_entry *entry = (struct ipsAuthInstAttr_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->ipsAuthInstIndex, sizeof(entry->ipsAuthInstIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the ipsAuthInstAttr table */ int ipsAuthInstAttr_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct ipsAuthInstAttr_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct ipsAuthInstAttr_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_IPSAUTHINSTINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->ipsAuthInstIndex, sizeof(table_entry->ipsAuthInstIndex)); break; case COLUMN_IPSAUTHINSTDESCR: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->ipsAuthInstDescr, strlen(table_entry->ipsAuthInstDescr)); break; case COLUMN_IPSAUTHINSTSTORAGETYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->ipsAuthInstStorageType, sizeof(table_entry->ipsAuthInstStorageType)); break; } } break; } return SNMP_ERR_NOERROR; } int ipsAuthInstAttr_load(netsnmp_cache *cache, void *vmagic) { struct ipsAuthInstAttr_entry *entry; if (ipsAuthInstAttr_head) return 0; entry = SNMP_MALLOC_TYPEDEF(struct ipsAuthInstAttr_entry); if (!entry) return -1; entry->ipsAuthInstIndex = AUTH_INST_INDEX; strcpy(entry->ipsAuthInstDescr, "iSCSI Target"); entry->ipsAuthInstStorageType = ST_READONLY; ipsAuthInstAttr_head = entry; return 0; } /* * User Identity Attributes Table */ /* * Initialize the ipsAuthIdentAttr table */ void initialize_table_ipsAuthIdentAttr(void) { static oid ipsAuthIdentAttr_oid[] = {OID_LIO_IPS_AUTH_MIB,1,3,1}; size_t ipsAuthIdentAttr_oid_len = OID_LENGTH(ipsAuthIdentAttr_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("ipsAuthIdentAttr", ipsAuthIdentAttr_handler, ipsAuthIdentAttr_oid, ipsAuthIdentAttr_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* ipsAuthInstIndex */ ASN_UNSIGNED, /* ipsAuthIdentIndex */ 0); table_info->min_column = 1; table_info->max_column = 5; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = ipsAuthIdentAttr_get_first_data_point; iinfo->get_next_data_point = ipsAuthIdentAttr_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(IPS_AUTH_MIB_CACHE_TIMEOUT, ipsAuthIdentAttr_load, ipsDummy_free, ipsAuthIdentAttr_oid, ipsAuthIdentAttr_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void ipsAuthIdentAttr_cache_update(void) { static marker_t ipsAuthIdentAttr_cache_marker = NULL; if (ipsAuthIdentAttr_cache_marker && (!atime_ready(ipsAuthIdentAttr_cache_marker, IPS_AUTH_MIB_CACHE_TIMEOUT * 1000))) return; if (ipsAuthIdentAttr_cache_marker) atime_setMarker(ipsAuthIdentAttr_cache_marker); else ipsAuthIdentAttr_cache_marker = atime_newMarker(); ipsAuthIdentAttr_load(NULL, NULL); } #endif struct ipsAuthIdentAttr_entry *ipsAuthIdentAttr_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * ipsAuthIdentAttr_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER ipsAuthIdentAttr_cache_update(); #endif *my_loop_context = ipsAuthIdentAttr_head; return ipsAuthIdentAttr_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * ipsAuthIdentAttr_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct ipsAuthIdentAttr_entry *entry = (struct ipsAuthIdentAttr_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->ipsAuthInstIndex, sizeof(entry->ipsAuthInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->ipsAuthIdentIndex, sizeof(entry->ipsAuthIdentIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the ipsAuthIdentAttr table */ int ipsAuthIdentAttr_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct ipsAuthIdentAttr_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct ipsAuthIdentAttr_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_IPSAUTHIDENTINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->ipsAuthIdentIndex, sizeof(table_entry->ipsAuthIdentIndex)); break; case COLUMN_IPSAUTHIDENTDESCRIPTION: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->ipsAuthIdentDescription, strlen(table_entry->ipsAuthIdentDescription)); break; case COLUMN_IPSAUTHIDENTROWSTATUS: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->ipsAuthIdentRowStatus, sizeof(table_entry->ipsAuthIdentRowStatus)); break; case COLUMN_IPSAUTHIDENTSTORAGETYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->ipsAuthIdentStorageType, sizeof(table_entry->ipsAuthIdentStorageType)); break; } } break; } return SNMP_ERR_NOERROR; } void ipsAuthIdentAttr_free(void) { struct ipsAuthIdentAttr_entry *entry; while (ipsAuthIdentAttr_head) { entry = ipsAuthIdentAttr_head; ipsAuthIdentAttr_head = ipsAuthIdentAttr_head->next; SNMP_FREE(entry); } } int ipsAuthIdentAttr_load(netsnmp_cache *cache, void *vmagic) { struct ipsAuthIdentAttr_entry *entry; static authId_entry_t *prev_authId_head = NULL; authId_entry_t *authId_head, *authId_entry; load_auth_data(&authId_head); if (authId_head == prev_authId_head) { /* No change to the cache */ return 0; } if (ipsAuthIdentAttr_head) ipsAuthIdentAttr_free(); prev_authId_head = authId_head; if (authId_head == NULL) { return 0; } for (authId_entry = authId_head; authId_entry; authId_entry = authId_entry->next) { entry = SNMP_MALLOC_TYPEDEF(struct ipsAuthIdentAttr_entry); if (!entry) break; entry->ipsAuthInstIndex = AUTH_INST_INDEX; entry->ipsAuthIdentIndex = authId_entry->authIdIndex; strcpy(entry->ipsAuthIdentDescription, authId_entry->authIdName); entry->ipsAuthIdentRowStatus = RS_ACTIVE; entry->ipsAuthIdentStorageType = ST_READONLY; entry->next = ipsAuthIdentAttr_head; ipsAuthIdentAttr_head = entry; } return 0; } /* * User Identity Attributes Table */ /* * Initialize the ipsAuthIdentNameAttr table */ void initialize_table_ipsAuthIdentNameAttr(void) { static oid ipsAuthIdentNameAttr_oid[] = {OID_LIO_IPS_AUTH_MIB,1,4,1}; size_t ipsAuthIdentNameAttr_oid_len = OID_LENGTH(ipsAuthIdentNameAttr_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("ipsAuthIdentNameAttr", ipsAuthIdentNameAttr_handler, ipsAuthIdentNameAttr_oid, ipsAuthIdentNameAttr_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* ipsAuthInstIndex */ ASN_UNSIGNED, /* ipsAuthIdentIndex */ ASN_UNSIGNED, /* ipsAuthIdentNameIndex */ 0); table_info->min_column = 1; table_info->max_column = 6; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = ipsAuthIdentNameAttr_get_first_data_point; iinfo->get_next_data_point = ipsAuthIdentNameAttr_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(IPS_AUTH_MIB_CACHE_TIMEOUT, ipsAuthIdentNameAttr_load, ipsDummy_free, ipsAuthIdentNameAttr_oid, ipsAuthIdentNameAttr_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void ipsAuthIdentNameAttr_cache_update(void) { static marker_t ipsAuthIdentNameAttr_cache_marker = NULL; if (ipsAuthIdentNameAttr_cache_marker && (!atime_ready(ipsAuthIdentNameAttr_cache_marker, IPS_AUTH_MIB_CACHE_TIMEOUT * 1000))) return; if (ipsAuthIdentNameAttr_cache_marker) atime_setMarker(ipsAuthIdentNameAttr_cache_marker); else ipsAuthIdentNameAttr_cache_marker = atime_newMarker(); ipsAuthIdentNameAttr_load(NULL, NULL); } #endif struct ipsAuthIdentNameAttr_entry *ipsAuthIdentNameAttr_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * ipsAuthIdentNameAttr_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER ipsAuthIdentNameAttr_cache_update(); #endif *my_loop_context = ipsAuthIdentNameAttr_head; return ipsAuthIdentNameAttr_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * ipsAuthIdentNameAttr_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct ipsAuthIdentNameAttr_entry *entry = (struct ipsAuthIdentNameAttr_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->ipsAuthInstIndex, sizeof(entry->ipsAuthInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->ipsAuthIdentIndex, sizeof(entry->ipsAuthIdentIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->ipsAuthIdentNameIndex, sizeof(entry->ipsAuthIdentNameIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the ipsAuthIdentNameAttr table */ int ipsAuthIdentNameAttr_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct ipsAuthIdentNameAttr_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct ipsAuthIdentNameAttr_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_IPSAUTHIDENTNAMEINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->ipsAuthIdentNameIndex, sizeof(table_entry->ipsAuthIdentNameIndex)); break; case COLUMN_IPSAUTHIDENTNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->ipsAuthIdentName, strlen(table_entry->ipsAuthIdentName)); break; case COLUMN_IPSAUTHIDENTNAMEROWSTATUS: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->ipsAuthIdentNameRowStatus, sizeof(table_entry->ipsAuthIdentNameRowStatus)); break; case COLUMN_IPSAUTHIDENTNAMESTORAGETYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->ipsAuthIdentNameStorageType, sizeof(table_entry->ipsAuthIdentNameStorageType)); break; } } break; } return SNMP_ERR_NOERROR; } void ipsAuthIdentNameAttr_free(void) { struct ipsAuthIdentNameAttr_entry *entry; while (ipsAuthIdentNameAttr_head) { entry = ipsAuthIdentNameAttr_head; ipsAuthIdentNameAttr_head = ipsAuthIdentNameAttr_head->next; SNMP_FREE(entry); } } int ipsAuthIdentNameAttr_load(netsnmp_cache *cache, void *vmagic) { struct ipsAuthIdentNameAttr_entry *entry; static authId_entry_t *prev_authId_head = NULL; authId_entry_t *authId_head, *authId_entry; load_auth_data(&authId_head); if (authId_head == prev_authId_head) { /* No change to the cache */ return 0; } if (ipsAuthIdentNameAttr_head) ipsAuthIdentNameAttr_free(); prev_authId_head = authId_head; if (authId_head == NULL) { return 0; } for (authId_entry = authId_head; authId_entry; authId_entry = authId_entry->next) { entry = SNMP_MALLOC_TYPEDEF(struct ipsAuthIdentNameAttr_entry); if (!entry) break; entry->ipsAuthInstIndex = AUTH_INST_INDEX; entry->ipsAuthIdentIndex = authId_entry->authIdIndex; entry->ipsAuthIdentNameIndex = AUTH_ID_NAME_INDEX; strcpy(entry->ipsAuthIdentName, authId_entry->authIdName); entry->ipsAuthIdentNameRowStatus = RS_ACTIVE; entry->ipsAuthIdentNameStorageType = ST_READONLY; entry->next = ipsAuthIdentNameAttr_head; ipsAuthIdentNameAttr_head = entry; } return 0; } /* * Credential Attributes Table */ /* * Initialize the ipsAuthCredAttr table */ void initialize_table_ipsAuthCredAttr(void) { static oid ipsAuthCredAttr_oid[] = {OID_LIO_IPS_AUTH_MIB,1,6,1}; size_t ipsAuthCredAttr_oid_len = OID_LENGTH(ipsAuthCredAttr_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("ipsAuthCredAttr", ipsAuthCredAttr_handler, ipsAuthCredAttr_oid, ipsAuthCredAttr_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* ipsAuthInstIndex */ ASN_UNSIGNED, /* ipsAuthIdentIndex */ ASN_UNSIGNED, /* ipsAuthCredIndex */ 0); table_info->min_column = 1; table_info->max_column = 6; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = ipsAuthCredAttr_get_first_data_point; iinfo->get_next_data_point = ipsAuthCredAttr_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(IPS_AUTH_MIB_CACHE_TIMEOUT, ipsAuthCredAttr_load, ipsAuthCredAttr_free, ipsAuthCredAttr_oid, ipsAuthCredAttr_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void ipsAuthCredAttr_cache_update(void) { static marker_t ipsAuthCredAttr_cache_marker = NULL; if (ipsAuthCredAttr_cache_marker && (!atime_ready(ipsAuthCredAttr_cache_marker, IPS_AUTH_MIB_CACHE_TIMEOUT * 1000))) return; if (ipsAuthCredAttr_cache_marker) atime_setMarker(ipsAuthCredAttr_cache_marker); else ipsAuthCredAttr_cache_marker = atime_newMarker(); ipsAuthCredAttr_load(NULL, NULL); } #endif struct ipsAuthCredAttr_entry *ipsAuthCredAttr_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * ipsAuthCredAttr_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER ipsAuthCredAttr_cache_update(); #endif *my_loop_context = ipsAuthCredAttr_head; return ipsAuthCredAttr_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * ipsAuthCredAttr_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct ipsAuthCredAttr_entry *entry = (struct ipsAuthCredAttr_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->ipsAuthInstIndex, sizeof(entry->ipsAuthInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->ipsAuthIdentIndex, sizeof(entry->ipsAuthIdentIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->ipsAuthCredIndex, sizeof(entry->ipsAuthCredIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the ipsAuthCredAttr table */ int ipsAuthCredAttr_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct ipsAuthCredAttr_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct ipsAuthCredAttr_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_IPSAUTHCREDINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->ipsAuthCredIndex, sizeof(table_entry->ipsAuthCredIndex)); break; case COLUMN_IPSAUTHCREDAUTHMETHOD: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *)&table_entry->ipsAuthCredAuthMethod, table_entry->ipsAuthCredAuthMethod_len * sizeof(oid)); break; case COLUMN_IPSAUTHCREDROWSTATUS: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->ipsAuthCredRowStatus, sizeof(table_entry->ipsAuthCredRowStatus)); break; case COLUMN_IPSAUTHCREDSTORAGETYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->ipsAuthCredStorageType, sizeof(table_entry->ipsAuthCredStorageType)); break; } } break; } return SNMP_ERR_NOERROR; } void ipsAuthCredAttr_free(netsnmp_cache *cache, void *vmagic) { struct ipsAuthCredAttr_entry *entry; while (ipsAuthCredAttr_head) { entry = ipsAuthCredAttr_head; ipsAuthCredAttr_head = ipsAuthCredAttr_head->next; SNMP_FREE(entry); } } static oid ipsAuthMethodNone_oid[] = {OID_LIO_IPS_AUTH_MIB,1,1,1,1}; static oid ipsAuthMethodChap_oid[] = {OID_LIO_IPS_AUTH_MIB,1,1,1,3}; int ipsAuthCredAttr_load(netsnmp_cache *cache, void *vmagic) { struct ipsAuthCredAttr_entry *entry; authId_entry_t *authId_head, *authId_entry; authCred_entry_t *authCred_entry; if (ipsAuthCredAttr_head) ipsAuthCredAttr_free(NULL, NULL); load_auth_data(&authId_head); if (authId_head == NULL) { return 0; } for (authId_entry = authId_head; authId_entry; authId_entry = authId_entry->next) { for (authCred_entry = authId_entry->authCred_list; authCred_entry; authCred_entry = authCred_entry->next) { entry = SNMP_MALLOC_TYPEDEF(struct ipsAuthCredAttr_entry); if (!entry) break; entry->ipsAuthInstIndex = AUTH_INST_INDEX; entry->ipsAuthIdentIndex = authId_entry->authIdIndex; entry->ipsAuthCredIndex = authCred_entry->tpgt + 1; if (authCred_entry->enforceAuth) memcpy(entry->ipsAuthCredAuthMethod, ipsAuthMethodChap_oid, sizeof(ipsAuthMethodChap_oid)); else memcpy(entry->ipsAuthCredAuthMethod, ipsAuthMethodNone_oid, sizeof(ipsAuthMethodNone_oid)); entry->ipsAuthCredAuthMethod_len = OID_LENGTH(ipsAuthMethodNone_oid); entry->ipsAuthCredRowStatus = RS_ACTIVE; entry->ipsAuthCredStorageType = ST_READONLY; entry->next = ipsAuthCredAttr_head; ipsAuthCredAttr_head = entry; } } return 0; } /* * Credential Chap-Specific Attributes Table */ /* * Initialize the ipsAuthCredChapAttr table */ void initialize_table_ipsAuthCredChapAttr(void) { static oid ipsAuthCredChapAttr_oid[] = {OID_LIO_IPS_AUTH_MIB,1,7,1}; size_t ipsAuthCredChapAttr_oid_len = OID_LENGTH(ipsAuthCredChapAttr_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("ipsAuthCredChapAttr", ipsAuthCredChapAttr_handler, ipsAuthCredChapAttr_oid, ipsAuthCredChapAttr_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* ipsAuthInstIndex */ ASN_UNSIGNED, /* ipsAuthIdentIndex */ ASN_UNSIGNED, /* ipsAuthCredIndex */ 0); table_info->min_column = 1; table_info->max_column = 6; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = ipsAuthCredChapAttr_get_first_data_point; iinfo->get_next_data_point = ipsAuthCredChapAttr_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(IPS_AUTH_MIB_CACHE_TIMEOUT, ipsAuthCredChapAttr_load, ipsAuthCredChapAttr_free, ipsAuthCredChapAttr_oid, ipsAuthCredChapAttr_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void ipsAuthCredChapAttr_cache_update(void) { static marker_t ipsAuthCredChapAttr_cache_marker = NULL; if (ipsAuthCredChapAttr_cache_marker && (!atime_ready(ipsAuthCredChapAttr_cache_marker, IPS_AUTH_MIB_CACHE_TIMEOUT * 1000))) return; if (ipsAuthCredChapAttr_cache_marker) atime_setMarker(ipsAuthCredChapAttr_cache_marker); else ipsAuthCredChapAttr_cache_marker = atime_newMarker(); ipsAuthCredChapAttr_load(NULL, NULL); } #endif struct ipsAuthCredChapAttr_entry *ipsAuthCredChapAttr_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * ipsAuthCredChapAttr_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER ipsAuthCredChapAttr_cache_update(); #endif *my_loop_context = ipsAuthCredChapAttr_head; return ipsAuthCredChapAttr_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * ipsAuthCredChapAttr_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct ipsAuthCredChapAttr_entry *entry = (struct ipsAuthCredChapAttr_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->ipsAuthInstIndex, sizeof(entry->ipsAuthInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->ipsAuthIdentIndex, sizeof(entry->ipsAuthIdentIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->ipsAuthCredIndex, sizeof(entry->ipsAuthCredIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the ipsAuthCredChapAttr table */ int ipsAuthCredChapAttr_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct ipsAuthCredChapAttr_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct ipsAuthCredChapAttr_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_IPSAUTHCREDCHAPUSERNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->ipsAuthCredChapUserName, strlen(table_entry->ipsAuthCredChapUserName)); break; case COLUMN_IPSAUTHCREDCHAPROWSTATUS: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->ipsAuthCredChapRowStatus, sizeof(table_entry->ipsAuthCredChapRowStatus)); break; case COLUMN_IPSAUTHCREDCHAPSTORAGETYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->ipsAuthCredChapStorageType, sizeof(table_entry->ipsAuthCredChapStorageType)); break; } } break; } return SNMP_ERR_NOERROR; } void ipsAuthCredChapAttr_free(netsnmp_cache *cache, void *vmagic) { struct ipsAuthCredChapAttr_entry *entry; while (ipsAuthCredChapAttr_head) { entry = ipsAuthCredChapAttr_head; ipsAuthCredChapAttr_head = ipsAuthCredChapAttr_head->next; SNMP_FREE(entry); } } int ipsAuthCredChapAttr_load(netsnmp_cache *cache, void *vmagic) { struct ipsAuthCredChapAttr_entry *entry; authId_entry_t *authId_head, *authId_entry; authCred_entry_t *authCred_entry; if (ipsAuthCredChapAttr_head) ipsAuthCredChapAttr_free(NULL, NULL); load_auth_data(&authId_head); if (authId_head == NULL) { return 0; } for (authId_entry = authId_head; authId_entry; authId_entry = authId_entry->next) { for (authCred_entry = authId_entry->authCred_list; authCred_entry; authCred_entry = authCred_entry->next) { if (!authCred_entry->enforceAuth) continue; entry = SNMP_MALLOC_TYPEDEF(struct ipsAuthCredChapAttr_entry); if (!entry) break; entry->ipsAuthInstIndex = AUTH_INST_INDEX; entry->ipsAuthIdentIndex = authId_entry->authIdIndex; entry->ipsAuthCredIndex = authCred_entry->tpgt + 1; strcpy(entry->ipsAuthCredChapUserName, authCred_entry->chapUserName); entry->ipsAuthCredChapRowStatus = RS_ACTIVE; entry->ipsAuthCredChapStorageType = ST_READONLY; entry->next = ipsAuthCredChapAttr_head; ipsAuthCredChapAttr_head = entry; } } return 0; } /* Prevent older versions of net-snmp from crashing */ void ipsDummy_free(netsnmp_cache *cache, void *vmagic) { } lio-utils-3.1+git2.fd0b34fd/mib-modules/setup_snmpd0000755000175000017500000000230511753136721020342 0ustar rrsrrs#!/usr/bin/perl sub install { my $config_file; if (-e ($config_file = "/etc/snmp/snmpd.conf") || -e ($config_file = "/etc/snmpd.conf")) { my $tag = "dlmod iscsiTargetMib /usr/lib/snmp/dlmod/iscsiTargetMib.so\n"; my $body = `cat $config_file`; $body =~ s/dlmod.*iscsiTargetMib.so\n//g; $body .= $tag; $body =~ s/view.*.*.enterprises.1055\n//g; $body =~ s/^(view\s+systemview\s+included)/view systemview included enterprises.1055\n$1/m; $body =~ s/rocommunity\s+public\s+127.0.0.1/rocommunity public/g; open(FILE,">$config_file") || die "Could not recreate $config_file"; print FILE $body; close FILE; } } sub uninstall { my $config_file; if (-e ($config_file = "/etc/snmp/snmpd.conf") || -e ($config_file = "/etc/snmpd.conf")) { my $body = `cat $config_file`; $body =~ s/view.*.*.enterprises.1055\n//g; $body =~ s/dlmod.*iscsiTargetMib.so\n//g; open(FILE,">$config_file") || die "Could not recreate $config_file"; print FILE $body; close FILE; } } $action = shift @ARGV; if ($action eq "install") { install(@ARGV); } elsif ($action eq "uninstall") { uninstall(@ARGV); } else { die "Error"; } lio-utils-3.1+git2.fd0b34fd/mib-modules/iscsiMib.c0000644000175000017500000043703711753136721017777 0ustar rrsrrs/* * Copyright (c) 2006 SBE, Inc. * Copyright (c) 2009-2011 Linux-iSCSI.org * * Nicholas A. Bellinger * * 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. */ #include #include #include #include "common.h" #include "iscsiMib.h" #include "iscsiAuthData.h" static oid snmptrap_oid[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0}; static oid iscsiInstSsnErrStats_oid[] = {OID_LIO_ISCSI_MIB,1,1,2,1}; /* * Initializes the iscsiMib module */ void init_iscsiMib(void) { /* Initialize all tables */ initialize_table_iscsiInstAttributes(); initialize_table_iscsiInstSsnErrStats(); initialize_table_iscsiPortalAttributes(); initialize_table_iscsiTgtPortalAttributes(); initialize_table_iscsiNodeAttributes(); initialize_table_iscsiTgtLoginStats(); initialize_table_iscsiTgtLogoutStats(); initialize_table_iscsiTgtAuthAttributes(); initialize_table_iscsiSessionAttributes(); initialize_table_iscsiSessionStats(); initialize_table_iscsiSsnCxnErrStats(); initialize_table_iscsiCxnAttributes(); initialize_iscsiTargetAttributes(); initialize_iscsiInstSessionFailure(); } /* * Instance Attributes Table */ #define ISCSI_INST_ATTR_CACHE_TIMEOUT 5 /* * Initialize the iscsiInstAttributes table */ void initialize_table_iscsiInstAttributes(void) { static oid iscsiInstAttributes_oid[] = {OID_LIO_ISCSI_MIB,1,1,1}; size_t iscsiInstAttributes_oid_len = OID_LENGTH(iscsiInstAttributes_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiInstAttributes", iscsiInstAttributes_handler, iscsiInstAttributes_oid, iscsiInstAttributes_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* index: iscsiInstIndex */ 0); table_info->min_column = 1; table_info->max_column = 13; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiInstAttributes_get_first_data_point; iinfo->get_next_data_point = iscsiInstAttributes_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_INST_ATTR_CACHE_TIMEOUT, iscsiInstAttributes_load, iscsiInstAttributes_free, iscsiInstAttributes_oid, iscsiInstAttributes_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiInstAttributes_cache_update(void) { static marker_t iscsiInstAttributes_cache_marker = NULL; if (iscsiInstAttributes_cache_marker && (!atime_ready(iscsiInstAttributes_cache_marker, ISCSI_INST_ATTR_CACHE_TIMEOUT * 1000))) return; if (iscsiInstAttributes_cache_marker) atime_setMarker(iscsiInstAttributes_cache_marker); else iscsiInstAttributes_cache_marker = atime_newMarker(); iscsiInstAttributes_load(NULL, NULL); } #endif struct iscsiInstAttributes_entry *iscsiInstAttributes_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiInstAttributes_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiInstAttributes_cache_update(); #endif *my_loop_context = iscsiInstAttributes_head; return iscsiInstAttributes_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiInstAttributes_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiInstAttributes_entry *entry = (struct iscsiInstAttributes_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiInstAttributes table */ int iscsiInstAttributes_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiInstAttributes_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiInstAttributes_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSIINSTINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiInstIndex, sizeof(table_entry->iscsiInstIndex)); break; case COLUMN_ISCSIINSTDESCR: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiInstDescr, strlen(table_entry->iscsiInstDescr)); break; case COLUMN_ISCSIINSTVERSIONMIN: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiInstVersionMin, sizeof(table_entry->iscsiInstVersionMin)); break; case COLUMN_ISCSIINSTVERSIONMAX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiInstVersionMax, sizeof(table_entry->iscsiInstVersionMax)); break; case COLUMN_ISCSIINSTVENDORID: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiInstVendorID, strlen(table_entry->iscsiInstVendorID)); break; case COLUMN_ISCSIINSTVENDORVERSION: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiInstVendorVersion, strlen(table_entry->iscsiInstVendorVersion)); break; case COLUMN_ISCSIINSTPORTALNUMBER: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiInstPortalNumber, sizeof(table_entry->iscsiInstPortalNumber)); break; case COLUMN_ISCSIINSTNODENUMBER: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiInstNodeNumber, sizeof(table_entry->iscsiInstNodeNumber)); break; case COLUMN_ISCSIINSTSESSIONNUMBER: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiInstSessionNumber, sizeof(table_entry->iscsiInstSessionNumber)); break; case COLUMN_ISCSIINSTSSNFAILURES: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiInstSsnFailures, sizeof(table_entry->iscsiInstSsnFailures)); break; case COLUMN_ISCSIINSTLASTSSNFAILURETYPE: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *)&table_entry->iscsiInstLastSsnFailureType, table_entry->iscsiInstLastSsnFailureType_len * sizeof(oid)); break; case COLUMN_ISCSIINSTLASTSSNRMTNODENAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiInstLastSsnRmtNodeName, strlen(table_entry->iscsiInstLastSsnRmtNodeName)); break; case COLUMN_ISCSIINSTDISCONTINUITYTIME: snmp_set_var_typed_value(request->requestvb, ASN_TIMETICKS, (u_char *)&table_entry->iscsiInstDiscontinuityTime, sizeof(table_entry->iscsiInstDiscontinuityTime)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_INST_ATTR "/proc/iscsi_target/mib/inst_attr" #define ISCSI_INST_ATTR_LINE "%lu %lu %lu %lu %lu %lu %lu %u %s %lu" int iscsiInstAttributes_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[512]; struct iscsiInstAttributes_entry tmp, *entry; u_int failType; if (iscsiInstAttributes_head) iscsiInstAttributes_free(NULL, NULL); if (!(fp = fopen(PROC_INST_ATTR, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_INST_ATTR); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_INST_ATTR_LINE, &tmp.iscsiInstIndex, &tmp.iscsiInstVersionMin, &tmp.iscsiInstVersionMax, &tmp.iscsiInstPortalNumber, &tmp.iscsiInstNodeNumber, &tmp.iscsiInstSessionNumber, &tmp.iscsiInstSsnFailures, &failType, tmp.iscsiInstLastSsnRmtNodeName, &tmp.iscsiInstDiscontinuityTime) != 10) continue; if (failType) { int oidLen = OID_LENGTH(iscsiInstSsnErrStats_oid); memcpy(tmp.iscsiInstLastSsnFailureType, iscsiInstSsnErrStats_oid, sizeof(iscsiInstSsnErrStats_oid)); tmp.iscsiInstLastSsnFailureType[oidLen] = failType; tmp.iscsiInstLastSsnFailureType_len = oidLen + 1; } else { /* return {0.0} */ tmp.iscsiInstLastSsnFailureType_len = 2; } if (line != fgets(line, sizeof(line), fp)) break; if (sscanf(line, "description: %s", tmp.iscsiInstDescr) == 1) { *(line + strlen(line) - 1) = 0; strcpy(tmp.iscsiInstDescr, line + strlen("description: ")); } else break; if (line != fgets(line, sizeof(line), fp)) break; if (sscanf(line, "vendor: %s", tmp.iscsiInstVendorID) == 1) { *(line + strlen(line) - 1) = 0; strcpy(tmp.iscsiInstVendorID, line + strlen("vendor: ")); } else break; if (line != fgets(line, sizeof(line), fp)) break; if (sscanf(line, "version: %s", tmp.iscsiInstVendorVersion) == 1) { *(line + strlen(line) - 1) = 0; strcpy(tmp.iscsiInstVendorVersion, line + strlen("version: ")); } else break; entry = SNMP_MALLOC_TYPEDEF(struct iscsiInstAttributes_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiInstAttributes_head; iscsiInstAttributes_head = entry; } fclose(fp); return 0; } void iscsiInstAttributes_free(netsnmp_cache *cache, void *vmagic) { struct iscsiInstAttributes_entry *entry; while (iscsiInstAttributes_head) { entry = iscsiInstAttributes_head; iscsiInstAttributes_head = iscsiInstAttributes_head->next; SNMP_FREE(entry); } } /* * Instance Session Failure Stats Table */ #define ISCSI_INST_SSN_ERR_CACHE_TIMEOUT 5 /* * Initialize the iscsiInstSsnErrStats table */ void initialize_table_iscsiInstSsnErrStats(void) { static oid iscsiInstSsnErrStats_oid[] = {OID_LIO_ISCSI_MIB,1,1,2}; size_t iscsiInstSsnErrStats_oid_len = OID_LENGTH(iscsiInstSsnErrStats_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiInstSsnErrStats", iscsiInstSsnErrStats_handler, iscsiInstSsnErrStats_oid, iscsiInstSsnErrStats_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info ); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* index: iscsiInstIndex */ 0); table_info->min_column = 1; table_info->max_column = 4; iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info ); iinfo->get_first_data_point= iscsiInstSsnErrStats_get_first_data_point; iinfo->get_next_data_point = iscsiInstSsnErrStats_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator( reg, iinfo ); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_INST_SSN_ERR_CACHE_TIMEOUT, iscsiInstSsnErrStats_load, iscsiInstSsnErrStats_free, iscsiInstSsnErrStats_oid, iscsiInstSsnErrStats_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiInstSsnErrStats_cache_update(void) { static marker_t iscsiInstSsnErrStats_cache_marker = NULL; if (iscsiInstSsnErrStats_cache_marker && (!atime_ready(iscsiInstSsnErrStats_cache_marker, ISCSI_INST_SSN_ERR_CACHE_TIMEOUT * 1000))) return; if (iscsiInstSsnErrStats_cache_marker) atime_setMarker(iscsiInstSsnErrStats_cache_marker); else iscsiInstSsnErrStats_cache_marker = atime_newMarker(); iscsiInstSsnErrStats_load(NULL, NULL); } #endif struct iscsiInstSsnErrStats_entry *iscsiInstSsnErrStats_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiInstSsnErrStats_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiInstSsnErrStats_cache_update(); #endif *my_loop_context = iscsiInstSsnErrStats_head; return iscsiInstSsnErrStats_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiInstSsnErrStats_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiInstSsnErrStats_entry *entry = (struct iscsiInstSsnErrStats_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiInstSsnErrStats table */ int iscsiInstSsnErrStats_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiInstSsnErrStats_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiInstSsnErrStats_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSIINSTSSNDIGESTERRORS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiInstSsnDigestErrors, sizeof(table_entry->iscsiInstSsnDigestErrors)); break; case COLUMN_ISCSIINSTSSNCXNTIMEOUTERRORS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiInstSsnCxnTimeoutErrors, sizeof(table_entry->iscsiInstSsnCxnTimeoutErrors)); break; case COLUMN_ISCSIINSTSSNFORMATERRORS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiInstSsnFormatErrors, sizeof(table_entry->iscsiInstSsnFormatErrors)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SESS_ERR_STATS "/proc/iscsi_target/mib/sess_err_stats" #define ISCSI_SESS_ERR_STATS_LINE "%lu %lu %lu %lu" int iscsiInstSsnErrStats_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[64]; struct iscsiInstSsnErrStats_entry tmp, *entry; if (iscsiInstSsnErrStats_head) iscsiInstSsnErrStats_free(NULL, NULL); if (!(fp = fopen(PROC_SESS_ERR_STATS, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SESS_ERR_STATS); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_SESS_ERR_STATS_LINE, &tmp.iscsiInstIndex, &tmp.iscsiInstSsnDigestErrors, &tmp.iscsiInstSsnCxnTimeoutErrors, &tmp.iscsiInstSsnFormatErrors) != 4) continue; entry = SNMP_MALLOC_TYPEDEF(struct iscsiInstSsnErrStats_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiInstSsnErrStats_head; iscsiInstSsnErrStats_head = entry; } fclose(fp); return 0; } void iscsiInstSsnErrStats_free(netsnmp_cache *cache, void *vmagic) { struct iscsiInstSsnErrStats_entry *entry; while (iscsiInstSsnErrStats_head) { entry = iscsiInstSsnErrStats_head; iscsiInstSsnErrStats_head = iscsiInstSsnErrStats_head->next; SNMP_FREE(entry); } } /* * Portal Attributes Table */ #define ISCSI_PORTAL_ATTR_CACHE_TIMEOUT 10 /* * Initialize the iscsiPortalAttributes table */ void initialize_table_iscsiPortalAttributes(void) { static oid iscsiPortalAttributes_oid[] = {OID_LIO_ISCSI_MIB,1,2,1}; size_t iscsiPortalAttributes_oid_len = OID_LENGTH(iscsiPortalAttributes_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiPortalAttributes", iscsiPortalAttributes_handler, iscsiPortalAttributes_oid, iscsiPortalAttributes_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* index: iscsiInstIndex */ ASN_UNSIGNED, /* index: iscsiPortalIndex*/ 0); table_info->min_column = 1; table_info->max_column = 14; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiPortalAttributes_get_first_data_point; iinfo->get_next_data_point = iscsiPortalAttributes_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_PORTAL_ATTR_CACHE_TIMEOUT, iscsiPortalAttributes_load, iscsiPortalAttributes_free, iscsiPortalAttributes_oid, iscsiPortalAttributes_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiPortalAttributes_cache_update(void) { static marker_t iscsiPortalAttributes_cache_marker = NULL; if (iscsiPortalAttributes_cache_marker && (!atime_ready(iscsiPortalAttributes_cache_marker, ISCSI_PORTAL_ATTR_CACHE_TIMEOUT * 1000))) return; if (iscsiPortalAttributes_cache_marker) atime_setMarker(iscsiPortalAttributes_cache_marker); else iscsiPortalAttributes_cache_marker = atime_newMarker(); iscsiPortalAttributes_load(NULL, NULL); } #endif struct iscsiPortalAttributes_entry *iscsiPortalAttributes_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiPortalAttributes_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiPortalAttributes_cache_update(); #endif *my_loop_context = iscsiPortalAttributes_head; return iscsiPortalAttributes_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiPortalAttributes_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiPortalAttributes_entry *entry = (struct iscsiPortalAttributes_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiPortalIndex, sizeof(entry->iscsiPortalIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiPortalAttributes table */ int iscsiPortalAttributes_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiPortalAttributes_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiPortalAttributes_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSIPORTALINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiPortalIndex, sizeof(table_entry->iscsiPortalIndex)); break; case COLUMN_ISCSIPORTALROWSTATUS: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiPortalRowStatus, sizeof(table_entry->iscsiPortalRowStatus)); break; case COLUMN_ISCSIPORTALROLES: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)&table_entry->iscsiPortalRoles, sizeof(table_entry->iscsiPortalRoles)); break; case COLUMN_ISCSIPORTALADDRTYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiPortalAddrType, sizeof(table_entry->iscsiPortalAddrType)); break; case COLUMN_ISCSIPORTALADDR: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiPortalAddr, (table_entry->iscsiPortalAddrType == INET_ADDR_TYPE_IPV4)? INET_ADDR_TYPE_IPV4_LEN: sizeof(table_entry->iscsiPortalAddr)); break; case COLUMN_ISCSIPORTALPROTOCOL: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiPortalProtocol, sizeof(table_entry->iscsiPortalProtocol)); break; case COLUMN_ISCSIPORTALMAXRECVDATASEGLENGTH: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiPortalMaxRecvDataSegLength, sizeof(table_entry->iscsiPortalMaxRecvDataSegLength)); break; case COLUMN_ISCSIPORTALPRIMARYHDRDIGEST: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiPortalPrimaryHdrDigest, sizeof(table_entry->iscsiPortalPrimaryHdrDigest)); break; case COLUMN_ISCSIPORTALPRIMARYDATADIGEST: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiPortalPrimaryDataDigest, sizeof(table_entry->iscsiPortalPrimaryDataDigest)); break; case COLUMN_ISCSIPORTALSECONDARYHDRDIGEST: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiPortalSecondaryHdrDigest, sizeof(table_entry->iscsiPortalSecondaryHdrDigest)); break; case COLUMN_ISCSIPORTALSECONDARYDATADIGEST: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiPortalSecondaryDataDigest, sizeof(table_entry->iscsiPortalSecondaryDataDigest)); break; case COLUMN_ISCSIPORTALRECVMARKER: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiPortalRecvMarker, sizeof(table_entry->iscsiPortalRecvMarker)); break; case COLUMN_ISCSIPORTALSTORAGETYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiPortalStorageType, sizeof(table_entry->iscsiPortalStorageType)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_PORTAL_ATTR "/proc/iscsi_target/mib/portal_attr" #define ISCSI_PORTAL_ATTR_LINE "%lu %lu %s %s %08X %s %lu %s %s %s" int iscsiPortalAttributes_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[128]; struct iscsiPortalAttributes_entry tmp, *entry; char roles[16]; char addrType[8]; char proto[8]; char hdrDigest[16]; char dataDigest[16]; char rcvMarker[4]; char *secDigest; uint32_t addr; if (iscsiPortalAttributes_head) iscsiPortalAttributes_free(NULL, NULL); if (!(fp = fopen(PROC_PORTAL_ATTR, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_PORTAL_ATTR); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_PORTAL_ATTR_LINE, &tmp.iscsiInstIndex, &tmp.iscsiPortalIndex, roles, addrType, (u_int *)tmp.iscsiPortalAddr, proto, &tmp.iscsiPortalMaxRecvDataSegLength, hdrDigest, dataDigest, rcvMarker) != 10) continue; tmp.iscsiPortalRowStatus = RS_ACTIVE; tmp.iscsiPortalRoles = NODE_ROLE_TARGET; if (!strcmp(addrType, "ipv4")) { tmp.iscsiPortalAddrType = INET_ADDR_TYPE_IPV4; addr = htonl(*(uint32_t *)&tmp.iscsiPortalAddr); *(uint32_t *)tmp.iscsiPortalAddr = addr; } if (!strcmp(proto, "TCP")) tmp.iscsiPortalProtocol = TRANSPORT_PROTO_TCP; else if (!strcmp(proto, "SCTP")) tmp.iscsiPortalProtocol = TRANSPORT_PROTO_SCTP; if (!strncmp(hdrDigest, "CRC32C", 6)) tmp.iscsiPortalPrimaryHdrDigest = ISCSI_DIGEST_CRC32C; else if (!strncmp(hdrDigest, "None", 4)) tmp.iscsiPortalPrimaryHdrDigest = ISCSI_DIGEST_NODIGEST; else tmp.iscsiPortalPrimaryHdrDigest = ISCSI_DIGEST_OTHER; if (!strncmp(dataDigest, "CRC32C", 6)) tmp.iscsiPortalPrimaryDataDigest = ISCSI_DIGEST_CRC32C; else if (!strncmp(dataDigest, "None", 4)) tmp.iscsiPortalPrimaryDataDigest = ISCSI_DIGEST_NODIGEST; else tmp.iscsiPortalPrimaryDataDigest = ISCSI_DIGEST_OTHER; if ((secDigest = strchr(hdrDigest, ','))) { secDigest++; if (!strcmp(secDigest, "CRC32C")) tmp.iscsiPortalSecondaryHdrDigest = ISCSI_DIGEST_CRC32C; else if (!strcmp(secDigest, "None")) tmp.iscsiPortalSecondaryHdrDigest = ISCSI_DIGEST_NODIGEST; else tmp.iscsiPortalSecondaryHdrDigest = ISCSI_DIGEST_OTHER; } else { tmp.iscsiPortalSecondaryHdrDigest = ISCSI_DIGEST_OTHER; snmp_log(LOG_DEBUG, "portal_attr: SecHdrDigest not found\n"); } if ((secDigest = strchr(hdrDigest, ','))) { secDigest++; if (!strcmp(secDigest, "CRC32C")) tmp.iscsiPortalSecondaryDataDigest = ISCSI_DIGEST_CRC32C; else if (!strcmp(secDigest, "None")) tmp.iscsiPortalSecondaryDataDigest = ISCSI_DIGEST_NODIGEST; else tmp.iscsiPortalSecondaryDataDigest = ISCSI_DIGEST_OTHER; } else { tmp.iscsiPortalSecondaryDataDigest = ISCSI_DIGEST_OTHER; snmp_log(LOG_DEBUG, "portal_attr: SecDataDigest not found\n"); } if (!strcmp(rcvMarker, "Yes")) tmp.iscsiPortalRecvMarker = TV_TRUE; else tmp.iscsiPortalRecvMarker = TV_FALSE; tmp.iscsiPortalStorageType = ST_READONLY; entry = SNMP_MALLOC_TYPEDEF(struct iscsiPortalAttributes_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiPortalAttributes_head; iscsiPortalAttributes_head = entry; } fclose(fp); return 0; } void iscsiPortalAttributes_free(netsnmp_cache *cache, void *vmagic) { struct iscsiPortalAttributes_entry *entry; while (iscsiPortalAttributes_head) { entry = iscsiPortalAttributes_head; iscsiPortalAttributes_head = iscsiPortalAttributes_head->next; SNMP_FREE(entry); } } /* * Target Portal Attributes Table */ #define ISCSI_TGT_PORTAL_ATTR_CACHE_TIMEOUT 10 /* * Initialize the iscsiTgtPortalAttributes table */ void initialize_table_iscsiTgtPortalAttributes(void) { static oid iscsiTgtPortalAttributes_oid[] = {OID_LIO_ISCSI_MIB,1,3,1}; size_t iscsiTgtPortalAttributes_oid_len = OID_LENGTH(iscsiTgtPortalAttributes_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiTgtPortalAttributes", iscsiTgtPortalAttributes_handler, iscsiTgtPortalAttributes_oid, iscsiTgtPortalAttributes_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* iscsiInstIndex */ ASN_UNSIGNED, /* iscsiPortalIndex */ ASN_UNSIGNED, /* iscsiTgtPortalNodeIndex*/ 0); table_info->min_column = 1; table_info->max_column = 5; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiTgtPortalAttributes_get_first_data_point; iinfo->get_next_data_point = iscsiTgtPortalAttributes_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_TGT_PORTAL_ATTR_CACHE_TIMEOUT, iscsiTgtPortalAttributes_load, iscsiTgtPortalAttributes_free, iscsiTgtPortalAttributes_oid, iscsiTgtPortalAttributes_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiTgtPortalAttributes_cache_update(void) { static marker_t iscsiTgtPortalAttributes_cache_marker = NULL; if (iscsiTgtPortalAttributes_cache_marker && (!atime_ready(iscsiTgtPortalAttributes_cache_marker, ISCSI_TGT_PORTAL_ATTR_CACHE_TIMEOUT * 1000))) return; if (iscsiTgtPortalAttributes_cache_marker) atime_setMarker(iscsiTgtPortalAttributes_cache_marker); else iscsiTgtPortalAttributes_cache_marker = atime_newMarker(); iscsiTgtPortalAttributes_load(NULL, NULL); } #endif struct iscsiTgtPortalAttributes_entry *iscsiTgtPortalAttributes_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiTgtPortalAttributes_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiTgtPortalAttributes_cache_update(); #endif *my_loop_context = iscsiTgtPortalAttributes_head; return iscsiTgtPortalAttributes_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiTgtPortalAttributes_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiTgtPortalAttributes_entry *entry = (struct iscsiTgtPortalAttributes_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiPortalIndex, sizeof(entry->iscsiPortalIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiTgtPortalNodeIndexOrZero, sizeof(entry->iscsiTgtPortalNodeIndexOrZero)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiTgtPortalAttributes table */ int iscsiTgtPortalAttributes_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiTgtPortalAttributes_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiTgtPortalAttributes_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSITGTPORTALNODEINDEXORZERO: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiTgtPortalNodeIndexOrZero, sizeof(table_entry->iscsiTgtPortalNodeIndexOrZero)); break; case COLUMN_ISCSITGTPORTALPORT: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiTgtPortalPort, sizeof(table_entry->iscsiTgtPortalPort)); break; case COLUMN_ISCSITGTPORTALTAG: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiTgtPortalTag, sizeof(table_entry->iscsiTgtPortalTag)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_TGT_PORTAL_ATTR "/proc/iscsi_target/mib/tgt_portal_attr" #define ISCSI_TGT_PORTAL_ATTR_LINE "%lu %lu %lu %lu %lu" int iscsiTgtPortalAttributes_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[64]; struct iscsiTgtPortalAttributes_entry tmp, *entry; if (iscsiTgtPortalAttributes_head) iscsiTgtPortalAttributes_free(NULL, NULL); if (!(fp = fopen(PROC_TGT_PORTAL_ATTR, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_TGT_PORTAL_ATTR); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_TGT_PORTAL_ATTR_LINE, &tmp.iscsiInstIndex, &tmp.iscsiPortalIndex, &tmp.iscsiTgtPortalNodeIndexOrZero, &tmp.iscsiTgtPortalPort, &tmp.iscsiTgtPortalTag) != 5) continue; entry = SNMP_MALLOC_TYPEDEF(struct iscsiTgtPortalAttributes_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiTgtPortalAttributes_head; iscsiTgtPortalAttributes_head = entry; } fclose(fp); return 0; } void iscsiTgtPortalAttributes_free(netsnmp_cache *cache, void *vmagic) { struct iscsiTgtPortalAttributes_entry *entry; while (iscsiTgtPortalAttributes_head) { entry = iscsiTgtPortalAttributes_head; iscsiTgtPortalAttributes_head = iscsiTgtPortalAttributes_head->next; SNMP_FREE(entry); } } /* * Node Attributes Table */ #define ISCSI_NODE_ATTR_CACHE_TIMEOUT 10 /* * Initialize the iscsiNodeAttributes table */ void initialize_table_iscsiNodeAttributes(void) { static oid iscsiNodeAttributes_oid[] = {OID_LIO_ISCSI_MIB,1,5,1}; size_t iscsiNodeAttributes_oid_len = OID_LENGTH(iscsiNodeAttributes_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiNodeAttributes", iscsiNodeAttributes_handler, iscsiNodeAttributes_oid, iscsiNodeAttributes_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* iscsiInstIndex */ ASN_UNSIGNED, /* iscsiNodeIndex */ 0); table_info->min_column = 1; table_info->max_column = 19; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiNodeAttributes_get_first_data_point; iinfo->get_next_data_point = iscsiNodeAttributes_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_NODE_ATTR_CACHE_TIMEOUT, iscsiNodeAttributes_load, iscsiNodeAttributes_free, iscsiNodeAttributes_oid, iscsiNodeAttributes_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiNodeAttributes_cache_update(void) { static marker_t iscsiNodeAttributes_cache_marker = NULL; if (iscsiNodeAttributes_cache_marker && (!atime_ready(iscsiNodeAttributes_cache_marker, ISCSI_NODE_ATTR_CACHE_TIMEOUT * 1000))) return; if (iscsiNodeAttributes_cache_marker) atime_setMarker(iscsiNodeAttributes_cache_marker); else iscsiNodeAttributes_cache_marker = atime_newMarker(); iscsiNodeAttributes_load(NULL, NULL); } #endif struct iscsiNodeAttributes_entry *iscsiNodeAttributes_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiNodeAttributes_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiNodeAttributes_cache_update(); #endif *my_loop_context = iscsiNodeAttributes_head; return iscsiNodeAttributes_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiNodeAttributes_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiNodeAttributes_entry *entry = (struct iscsiNodeAttributes_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiNodeIndex, sizeof(entry->iscsiNodeIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiNodeAttributes table */ int iscsiNodeAttributes_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiNodeAttributes_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiNodeAttributes_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSINODEINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiNodeIndex, sizeof(table_entry->iscsiNodeIndex)); break; case COLUMN_ISCSINODENAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiNodeName, strlen(table_entry->iscsiNodeName)); break; case COLUMN_ISCSINODEALIAS: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiNodeAlias, strlen(table_entry->iscsiNodeAlias)); break; case COLUMN_ISCSINODEROLES: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)&table_entry->iscsiNodeRoles, sizeof(table_entry->iscsiNodeRoles)); break; case COLUMN_ISCSINODETRANSPORTTYPE: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *)&table_entry->iscsiNodeTransportType, table_entry->iscsiNodeTransportType_len * sizeof(oid)); break; case COLUMN_ISCSINODEINITIALR2T: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiNodeInitialR2T, sizeof(table_entry->iscsiNodeInitialR2T)); break; case COLUMN_ISCSINODEIMMEDIATEDATA: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiNodeImmediateData, sizeof(table_entry->iscsiNodeImmediateData)); break; case COLUMN_ISCSINODEMAXOUTSTANDINGR2T: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiNodeMaxOutstandingR2T, sizeof(table_entry->iscsiNodeMaxOutstandingR2T)); break; case COLUMN_ISCSINODEFIRSTBURSTLENGTH: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiNodeFirstBurstLength, sizeof(table_entry->iscsiNodeFirstBurstLength)); break; case COLUMN_ISCSINODEMAXBURSTLENGTH: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiNodeMaxBurstLength, sizeof(table_entry->iscsiNodeMaxBurstLength)); break; case COLUMN_ISCSINODEMAXCONNECTIONS: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiNodeMaxConnections, sizeof(table_entry->iscsiNodeMaxConnections)); break; case COLUMN_ISCSINODEDATASEQUENCEINORDER: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiNodeDataSequenceInOrder, sizeof(table_entry->iscsiNodeDataSequenceInOrder)); break; case COLUMN_ISCSINODEDATAPDUINORDER: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiNodeDataPDUInOrder, sizeof(table_entry->iscsiNodeDataPDUInOrder)); break; case COLUMN_ISCSINODEDEFAULTTIME2WAIT: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiNodeDefaultTime2Wait, sizeof(table_entry->iscsiNodeDefaultTime2Wait)); break; case COLUMN_ISCSINODEDEFAULTTIME2RETAIN: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiNodeDefaultTime2Retain, sizeof(table_entry->iscsiNodeDefaultTime2Retain)); break; case COLUMN_ISCSINODEERRORRECOVERYLEVEL: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiNodeErrorRecoveryLevel, sizeof(table_entry->iscsiNodeErrorRecoveryLevel)); break; case COLUMN_ISCSINODEDISCONTINUITYTIME: snmp_set_var_typed_value(request->requestvb, ASN_TIMETICKS, (u_char *)&table_entry->iscsiNodeDiscontinuityTime, sizeof(table_entry->iscsiNodeDiscontinuityTime)); break; case COLUMN_ISCSINODESTORAGETYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiNodeStorageType, sizeof(table_entry->iscsiNodeStorageType)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_NODE_ATTR "/proc/iscsi_target/mib/node_attr" #define ISCSI_NODE_ATTR_LINE "%lu %lu %s %s %s %s %lu %lu %lu %lu %s %s %lu %lu %lu %lu" static oid scsiInstanceAlias_oid[] = {OID_LIO_SCSI_MIB,2,1,1,1,2,1}; int iscsiNodeAttributes_load(netsnmp_cache *cache, void *vmagic) { FILE *fp, *alias_fp; char line[512]; char roles[16]; char r2t[4]; char immData[4]; char seqOrder[4]; char pduOrder[4]; struct iscsiNodeAttributes_entry tmp, *entry; if (iscsiNodeAttributes_head) iscsiNodeAttributes_free(NULL, NULL); if (!(fp = fopen(PROC_NODE_ATTR, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_NODE_ATTR); return -1; } alias_fp = fopen("/etc/iscsi.alias", "r"); while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_NODE_ATTR_LINE, &tmp.iscsiInstIndex, &tmp.iscsiNodeIndex, tmp.iscsiNodeName, roles, r2t, immData, &tmp.iscsiNodeMaxOutstandingR2T, &tmp.iscsiNodeFirstBurstLength, &tmp.iscsiNodeMaxBurstLength, &tmp.iscsiNodeMaxConnections, seqOrder, pduOrder, &tmp.iscsiNodeDefaultTime2Wait, &tmp.iscsiNodeDefaultTime2Retain, &tmp.iscsiNodeErrorRecoveryLevel, &tmp.iscsiNodeDiscontinuityTime) != 16) continue; tmp.iscsiNodeRoles = NODE_ROLE_TARGET; /* As PyX stack supports multiple devices within a node, set the row pointer to the scsi instance instead of scsi transport */ tmp.iscsiNodeTransportType_len = OID_LENGTH(scsiInstanceAlias_oid); memcpy(tmp.iscsiNodeTransportType, scsiInstanceAlias_oid, sizeof(scsiInstanceAlias_oid)); if (!strcmp(r2t, "Yes")) tmp.iscsiNodeInitialR2T = TV_TRUE; else tmp.iscsiNodeInitialR2T = TV_FALSE; if (!strcmp(immData, "Yes")) tmp.iscsiNodeImmediateData = TV_TRUE; else tmp.iscsiNodeImmediateData = TV_FALSE; if (!strcmp(seqOrder, "Yes")) tmp.iscsiNodeDataSequenceInOrder = TV_TRUE; else tmp.iscsiNodeDataSequenceInOrder = TV_FALSE; if (!strcmp(pduOrder, "Yes")) tmp.iscsiNodeDataPDUInOrder = TV_TRUE; else tmp.iscsiNodeDataPDUInOrder = TV_FALSE; tmp.iscsiNodeStorageType = ST_READONLY; if (alias_fp && (line == fgets(line, sizeof(line), alias_fp))) sscanf(line, "%s", tmp.iscsiNodeAlias); entry = SNMP_MALLOC_TYPEDEF(struct iscsiNodeAttributes_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiNodeAttributes_head; iscsiNodeAttributes_head = entry; } fclose(fp); if (alias_fp) fclose(alias_fp); return 0; } void iscsiNodeAttributes_free(netsnmp_cache *cache, void *vmagic) { struct iscsiNodeAttributes_entry *entry; while (iscsiNodeAttributes_head) { entry = iscsiNodeAttributes_head; iscsiNodeAttributes_head = iscsiNodeAttributes_head->next; SNMP_FREE(entry); } } /* * Target Attributes Table and Target Login Failure Notification */ /* Use 3 sec poll recommended by the draft */ #define ISCSI_TGT_LOGIN_FAIL_POLL_INTERVAL 3 /* Initializes the iscsiTargetAttributes */ void initialize_iscsiTargetAttributes(void) { /* Initialize the table */ initialize_table_iscsiTargetAttributes(); /* Setup callback for polling for login failure */ snmp_alarm_register(ISCSI_TGT_LOGIN_FAIL_POLL_INTERVAL, SA_REPEAT, iscsiTargetAttributes_load, NULL); /* Initial load */ iscsiTargetAttributes_load(0, NULL); } /* * Initialize the iscsiTargetAttributes table */ void initialize_table_iscsiTargetAttributes(void) { static oid iscsiTargetAttributes_oid[] = {OID_LIO_ISCSI_MIB,1,6,1}; size_t iscsiTargetAttributes_oid_len = OID_LENGTH(iscsiTargetAttributes_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiTargetAttributes", iscsiTargetAttributes_handler, iscsiTargetAttributes_oid, iscsiTargetAttributes_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* iscsiInstIndex */ ASN_UNSIGNED, /* iscsiNodeIndex */ 0); table_info->min_column = 1; table_info->max_column = 8; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiTargetAttributes_get_first_data_point; iinfo->get_next_data_point = iscsiTargetAttributes_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); } struct iscsiTargetAttributes_entry *iscsiTargetAttributes_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiTargetAttributes_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { *my_loop_context = iscsiTargetAttributes_head; return iscsiTargetAttributes_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiTargetAttributes_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiTargetAttributes_entry *entry = (struct iscsiTargetAttributes_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiNodeIndex, sizeof(entry->iscsiNodeIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiTargetAttributes table */ int iscsiTargetAttributes_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiTargetAttributes_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiTargetAttributes_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSITGTLOGINFAILURES: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiTgtLoginFailures, sizeof(table_entry->iscsiTgtLoginFailures)); break; case COLUMN_ISCSITGTLASTFAILURETIME: snmp_set_var_typed_value(request->requestvb, ASN_TIMETICKS, (u_char *)&table_entry->iscsiTgtLastFailureTime, sizeof(table_entry->iscsiTgtLastFailureTime)); break; case COLUMN_ISCSITGTLASTFAILURETYPE: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *)table_entry->iscsiTgtLastFailureType, table_entry->iscsiTgtLastFailureType_len * sizeof(oid)); break; case COLUMN_ISCSITGTLASTINTRFAILURENAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiTgtLastIntrFailureName, strlen(table_entry->iscsiTgtLastIntrFailureName)); break; case COLUMN_ISCSITGTLASTINTRFAILUREADDRTYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiTgtLastIntrFailureAddrType, sizeof(table_entry->iscsiTgtLastIntrFailureAddrType)); break; case COLUMN_ISCSITGTLASTINTRFAILUREADDR: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiTgtLastIntrFailureAddr, (table_entry->iscsiTgtLastIntrFailureAddrType == INET_ADDR_TYPE_IPV4)? INET_ADDR_TYPE_IPV4_LEN: sizeof(table_entry->iscsiTgtLastIntrFailureAddr)); break; } } break; } return SNMP_ERR_NOERROR; } /* * Notification code */ struct iscsiTargetAttributes_entry lastTrap; int send_iscsiTgtLoginFailure_trap(struct iscsiTargetAttributes_entry *entry) { netsnmp_variable_list *var_list = NULL; oid iscsiTgtLoginFailure_oid[] = {OID_LIO_ISCSI_MIB,0,1}; oid iscsiTgtLoginFailures_oid[] = {OID_LIO_ISCSI_MIB,1,6,1,1,1, entry->iscsiInstIndex, entry->iscsiNodeIndex}; oid iscsiTgtLastFailureType_oid[] = {OID_LIO_ISCSI_MIB,1,6,1,1,3, entry->iscsiInstIndex, entry->iscsiNodeIndex}; oid iscsiTgtLastIntrFailureName_oid[] = {OID_LIO_ISCSI_MIB,1,6,1,1,4, entry->iscsiInstIndex, entry->iscsiNodeIndex}; oid iscsiTgtLastIntrFailureAddrType_oid[] = {OID_LIO_ISCSI_MIB,1,6,1,1,5, entry->iscsiInstIndex, entry->iscsiNodeIndex}; oid iscsiTgtLastIntrFailureAddr_oid[] = {OID_LIO_ISCSI_MIB,1,6,1,1,6, entry->iscsiInstIndex, entry->iscsiNodeIndex}; int fail_type_idx = entry->iscsiTgtLastFailureType_len - 1; /* * Prevent generating multiple traps within a short interval if an * initiator retries login over and over. */ if (!strcmp(entry->iscsiTgtLastIntrFailureName, lastTrap.iscsiTgtLastIntrFailureName) && (entry->iscsiTgtLastFailureType[fail_type_idx] == lastTrap.iscsiTgtLastFailureType[fail_type_idx]) && ((entry->iscsiTgtLastFailureTime - lastTrap.iscsiTgtLastFailureTime) < (120 * 100))) { return SNMP_ERR_NOERROR; } else { /* Save the failure info */ memcpy(&lastTrap, entry, sizeof(lastTrap)); } /* * Set the snmpTrapOid.0 value */ snmp_varlist_add_variable(&var_list, snmptrap_oid, OID_LENGTH(snmptrap_oid), ASN_OBJECT_ID, (u_char *)iscsiTgtLoginFailure_oid, sizeof(iscsiTgtLoginFailure_oid)); /* * Add objects from the trap definition */ snmp_varlist_add_variable(&var_list, iscsiTgtLoginFailures_oid, OID_LENGTH(iscsiTgtLoginFailures_oid),ASN_COUNTER, (u_char *)&entry->iscsiTgtLoginFailures, sizeof(entry->iscsiTgtLoginFailures)); snmp_varlist_add_variable(&var_list, iscsiTgtLastFailureType_oid, OID_LENGTH(iscsiTgtLastFailureType_oid), ASN_OBJECT_ID, (u_char *)entry->iscsiTgtLastFailureType, entry->iscsiTgtLastFailureType_len * sizeof(oid)); snmp_varlist_add_variable(&var_list, iscsiTgtLastIntrFailureName_oid, OID_LENGTH(iscsiTgtLastIntrFailureName_oid), ASN_OCTET_STR, (u_char *)entry->iscsiTgtLastIntrFailureName, strlen(entry->iscsiTgtLastIntrFailureName)); snmp_varlist_add_variable(&var_list, iscsiTgtLastIntrFailureAddrType_oid, OID_LENGTH(iscsiTgtLastIntrFailureAddrType_oid), ASN_INTEGER, (u_char *)&entry->iscsiTgtLastIntrFailureAddrType, sizeof(entry->iscsiTgtLastIntrFailureAddrType)); snmp_varlist_add_variable(&var_list, iscsiTgtLastIntrFailureAddr_oid, OID_LENGTH(iscsiTgtLastIntrFailureAddr_oid), ASN_OCTET_STR, (u_char *)entry->iscsiTgtLastIntrFailureAddr, (entry->iscsiTgtLastIntrFailureAddrType == INET_ADDR_TYPE_IPV4)? INET_ADDR_TYPE_IPV4_LEN: sizeof(entry->iscsiTgtLastIntrFailureAddr)); /* * Send the trap to the list of configured destinations and clean up */ send_v2trap(var_list); snmp_free_varbind(var_list); return SNMP_ERR_NOERROR; } #define PROC_TARGET_ATTR "/proc/iscsi_target/mib/tgt_attr" #define ISCSI_TARGET_ATTR_LINE "%lu %lu %lu %lu %u %s %s %08X" static uint32_t numFailures[ISCSI_NUM_INSTANCES + 1][ISCSI_NUM_NODES + 1]; static oid iscsiTgtLoginStats_oid[] = {OID_LIO_ISCSI_MIB,1,6,2,1}; void iscsiTargetAttributes_load(unsigned int clientreg, void *clientarg) { FILE *fp; char line[300]; struct iscsiTargetAttributes_entry tmp, *entry; char addrType[8]; uint32_t addr; uint32_t failType; if (iscsiTargetAttributes_head) iscsiTargetAttributes_free(); if (!(fp = fopen(PROC_TARGET_ATTR, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_TARGET_ATTR); return; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_TARGET_ATTR_LINE, &tmp.iscsiInstIndex, &tmp.iscsiNodeIndex, &tmp.iscsiTgtLoginFailures, &tmp.iscsiTgtLastFailureTime, &failType, tmp.iscsiTgtLastIntrFailureName, addrType, (u_int *)tmp.iscsiTgtLastIntrFailureAddr) != 8) continue; memcpy(tmp.iscsiTgtLastFailureType, iscsiTgtLoginStats_oid, sizeof(iscsiTgtLoginStats_oid)); tmp.iscsiTgtLastFailureType[OID_LENGTH(iscsiTgtLoginStats_oid)] = failType; tmp.iscsiTgtLastFailureType_len = OID_LENGTH(iscsiTgtLoginStats_oid)+1; if (!strcmp(addrType, "ipv4")) { tmp.iscsiTgtLastIntrFailureAddrType = INET_ADDR_TYPE_IPV4; addr = htonl(*(uint32_t *)tmp.iscsiTgtLastIntrFailureAddr); *(uint32_t *)tmp.iscsiTgtLastIntrFailureAddr = addr; } /* Send a trap on failures */ if ((tmp.iscsiInstIndex <= ISCSI_NUM_INSTANCES) && (tmp.iscsiNodeIndex <= ISCSI_NUM_NODES) && (tmp.iscsiTgtLoginFailures > numFailures[tmp.iscsiInstIndex][tmp.iscsiNodeIndex])) { if ((clientreg) && ((failType == ISCSI_LOGIN_FAIL_AUTHORIZE) || (failType == ISCSI_LOGIN_FAIL_AUTHENTICATE) || (failType == ISCSI_LOGIN_FAIL_NEGOTIATE))) send_iscsiTgtLoginFailure_trap(&tmp); } /* Update the counter to the current value from the stack */ if (numFailures[tmp.iscsiInstIndex][tmp.iscsiNodeIndex] != tmp.iscsiTgtLoginFailures) numFailures[tmp.iscsiInstIndex][tmp.iscsiNodeIndex] = tmp.iscsiTgtLoginFailures; entry = SNMP_MALLOC_TYPEDEF(struct iscsiTargetAttributes_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiTargetAttributes_head; iscsiTargetAttributes_head = entry; } fclose(fp); } void iscsiTargetAttributes_free(void) { struct iscsiTargetAttributes_entry *entry; while (iscsiTargetAttributes_head) { entry = iscsiTargetAttributes_head; iscsiTargetAttributes_head = iscsiTargetAttributes_head->next; SNMP_FREE(entry); } } /* * Target Login Stats Table */ #define ISCSI_TGT_LOGIN_STATS_CACHE_TIMEOUT 5 /* * Initialize the iscsiTgtLoginStats table */ void initialize_table_iscsiTgtLoginStats(void) { static oid iscsiTgtLoginStats_oid[] = {OID_LIO_ISCSI_MIB,1,6,2}; size_t iscsiTgtLoginStats_oid_len = OID_LENGTH(iscsiTgtLoginStats_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiTgtLoginStats", iscsiTgtLoginStats_handler, iscsiTgtLoginStats_oid, iscsiTgtLoginStats_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* iscsiInstIndex */ ASN_UNSIGNED, /* iscsiNodeIndex */ 0); table_info->min_column = 1; table_info->max_column = 8; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiTgtLoginStats_get_first_data_point; iinfo->get_next_data_point = iscsiTgtLoginStats_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_TGT_LOGIN_STATS_CACHE_TIMEOUT, iscsiTgtLoginStats_load, iscsiTgtLoginStats_free, iscsiTgtLoginStats_oid, iscsiTgtLoginStats_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiTgtLoginStats_cache_update(void) { static marker_t iscsiTgtLoginStats_cache_marker = NULL; if (iscsiTgtLoginStats_cache_marker && (!atime_ready(iscsiTgtLoginStats_cache_marker, ISCSI_TGT_LOGIN_STATS_CACHE_TIMEOUT * 1000))) return; if (iscsiTgtLoginStats_cache_marker) atime_setMarker(iscsiTgtLoginStats_cache_marker); else iscsiTgtLoginStats_cache_marker = atime_newMarker(); iscsiTgtLoginStats_load(NULL, NULL); } #endif struct iscsiTgtLoginStats_entry *iscsiTgtLoginStats_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiTgtLoginStats_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiTgtLoginStats_cache_update(); #endif *my_loop_context = iscsiTgtLoginStats_head; return iscsiTgtLoginStats_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiTgtLoginStats_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiTgtLoginStats_entry *entry = (struct iscsiTgtLoginStats_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiNodeIndex, sizeof(entry->iscsiNodeIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiTgtLoginStats table */ int iscsiTgtLoginStats_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiTgtLoginStats_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiTgtLoginStats_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSITGTLOGINACCEPTS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiTgtLoginAccepts, sizeof(table_entry->iscsiTgtLoginAccepts)); break; case COLUMN_ISCSITGTLOGINOTHERFAILS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiTgtLoginOtherFails, sizeof(table_entry->iscsiTgtLoginOtherFails)); break; case COLUMN_ISCSITGTLOGINREDIRECTS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiTgtLoginRedirects, sizeof(table_entry->iscsiTgtLoginRedirects)); break; case COLUMN_ISCSITGTLOGINAUTHORIZEFAILS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiTgtLoginAuthorizeFails, sizeof(table_entry->iscsiTgtLoginAuthorizeFails)); break; case COLUMN_ISCSITGTLOGINAUTHENTICATEFAILS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiTgtLoginAuthenticateFails, sizeof(table_entry->iscsiTgtLoginAuthenticateFails)); break; case COLUMN_ISCSITGTLOGINNEGOTIATEFAILS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiTgtLoginNegotiateFails, sizeof(table_entry->iscsiTgtLoginNegotiateFails)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_TGT_LOGIN_STATS "/proc/iscsi_target/mib/login_stats" #define ISCSI_TGT_LOGIN_STATS_LINE "%lu %lu %lu %lu %lu %lu %lu %lu" int iscsiTgtLoginStats_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[128]; struct iscsiTgtLoginStats_entry tmp, *entry; if (iscsiTgtLoginStats_head) iscsiTgtLoginStats_free(NULL, NULL); if (!(fp = fopen(PROC_TGT_LOGIN_STATS, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_TGT_LOGIN_STATS); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_TGT_LOGIN_STATS_LINE, &tmp.iscsiInstIndex, &tmp.iscsiNodeIndex, &tmp.iscsiTgtLoginAccepts, &tmp.iscsiTgtLoginOtherFails, &tmp.iscsiTgtLoginRedirects, &tmp.iscsiTgtLoginAuthorizeFails, &tmp.iscsiTgtLoginAuthenticateFails, &tmp.iscsiTgtLoginNegotiateFails) != 8) continue; entry = SNMP_MALLOC_TYPEDEF(struct iscsiTgtLoginStats_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiTgtLoginStats_head; iscsiTgtLoginStats_head = entry; } fclose(fp); return 0; } void iscsiTgtLoginStats_free(netsnmp_cache *cache, void *vmagic) { struct iscsiTgtLoginStats_entry *entry; while (iscsiTgtLoginStats_head) { entry = iscsiTgtLoginStats_head; iscsiTgtLoginStats_head = iscsiTgtLoginStats_head->next; SNMP_FREE(entry); } } /* * Target Logout Stats Table */ #define ISCSI_TGT_LOGOUT_STATS_CACHE_TIMEOUT 5 /* * Initialize the iscsiTgtLogoutStats table */ void initialize_table_iscsiTgtLogoutStats(void) { static oid iscsiTgtLogoutStats_oid[] = {OID_LIO_ISCSI_MIB,1,6,3}; size_t iscsiTgtLogoutStats_oid_len = OID_LENGTH(iscsiTgtLogoutStats_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiTgtLogoutStats", iscsiTgtLogoutStats_handler, iscsiTgtLogoutStats_oid, iscsiTgtLogoutStats_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* iscsiInstIndex */ ASN_UNSIGNED, /* iscsiNodeIndex */ 0); table_info->min_column = 1; table_info->max_column = 4; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiTgtLogoutStats_get_first_data_point; iinfo->get_next_data_point = iscsiTgtLogoutStats_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_TGT_LOGOUT_STATS_CACHE_TIMEOUT, iscsiTgtLogoutStats_load, iscsiTgtLogoutStats_free, iscsiTgtLogoutStats_oid, iscsiTgtLogoutStats_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiTgtLogoutStats_cache_update(void) { static marker_t iscsiTgtLogoutStats_cache_marker = NULL; if (iscsiTgtLogoutStats_cache_marker && (!atime_ready(iscsiTgtLogoutStats_cache_marker, ISCSI_TGT_LOGOUT_STATS_CACHE_TIMEOUT * 1000))) return; if (iscsiTgtLogoutStats_cache_marker) atime_setMarker(iscsiTgtLogoutStats_cache_marker); else iscsiTgtLogoutStats_cache_marker = atime_newMarker(); iscsiTgtLogoutStats_load(NULL, NULL); } #endif struct iscsiTgtLogoutStats_entry *iscsiTgtLogoutStats_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiTgtLogoutStats_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiTgtLogoutStats_cache_update(); #endif *my_loop_context = iscsiTgtLogoutStats_head; return iscsiTgtLogoutStats_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiTgtLogoutStats_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiTgtLogoutStats_entry *entry = (struct iscsiTgtLogoutStats_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiNodeIndex, sizeof(entry->iscsiNodeIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiTgtLogoutStats table */ int iscsiTgtLogoutStats_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiTgtLogoutStats_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiTgtLogoutStats_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSITGTLOGOUTNORMALS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiTgtLogoutNormals, sizeof(table_entry->iscsiTgtLogoutNormals)); break; case COLUMN_ISCSITGTLOGOUTOTHERS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiTgtLogoutOthers, sizeof(table_entry->iscsiTgtLogoutOthers)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_TGT_LOGOUT_STATS "/proc/iscsi_target/mib/logout_stats" #define ISCSI_TGT_LOGOUT_STATS_LINE "%lu %lu %lu %lu" int iscsiTgtLogoutStats_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[64]; struct iscsiTgtLogoutStats_entry tmp, *entry; if (iscsiTgtLogoutStats_head) iscsiTgtLogoutStats_free(NULL, NULL); if (!(fp = fopen(PROC_TGT_LOGOUT_STATS, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_TGT_LOGOUT_STATS); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_TGT_LOGOUT_STATS_LINE, &tmp.iscsiInstIndex, &tmp.iscsiNodeIndex, &tmp.iscsiTgtLogoutNormals, &tmp.iscsiTgtLogoutOthers) != 4) continue; entry = SNMP_MALLOC_TYPEDEF(struct iscsiTgtLogoutStats_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiTgtLogoutStats_head; iscsiTgtLogoutStats_head = entry; } fclose(fp); return 0; } void iscsiTgtLogoutStats_free(netsnmp_cache *cache, void *vmagic) { struct iscsiTgtLogoutStats_entry *entry; while (iscsiTgtLogoutStats_head) { entry = iscsiTgtLogoutStats_head; iscsiTgtLogoutStats_head = iscsiTgtLogoutStats_head->next; SNMP_FREE(entry); } } /* * Target Authorization Attributes Table */ #define ISCSI_TGT_AUTH_CACHE_TIMEOUT 10 /* * Initialize the iscsiTgtAuthAttributes table */ void initialize_table_iscsiTgtAuthAttributes(void) { static oid iscsiTgtAuthAttributes_oid[] = {OID_LIO_ISCSI_MIB,1,7,1}; size_t iscsiTgtAuthAttributes_oid_len = OID_LENGTH(iscsiTgtAuthAttributes_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiTgtAuthAttributes", iscsiTgtAuthAttributes_handler, iscsiTgtAuthAttributes_oid, iscsiTgtAuthAttributes_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* iscsiInstIndex */ ASN_UNSIGNED, /* iscsiNodeIndex */ ASN_UNSIGNED, /* iscsiTgtAuthIndex */ 0); table_info->min_column = 1; table_info->max_column = 6; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiTgtAuthAttributes_get_first_data_point; iinfo->get_next_data_point = iscsiTgtAuthAttributes_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_TGT_AUTH_CACHE_TIMEOUT, iscsiTgtAuthAttributes_load, iscsiTgtAuthAttributes_free, iscsiTgtAuthAttributes_oid, iscsiTgtAuthAttributes_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiTgtAuthAttributes_cache_update(void) { static marker_t iscsiTgtAuthAttributes_cache_marker = NULL; if (iscsiTgtAuthAttributes_cache_marker && (!atime_ready(iscsiTgtAuthAttributes_cache_marker, ISCSI_TGT_AUTH_CACHE_TIMEOUT * 1000))) return; if (iscsiTgtAuthAttributes_cache_marker) atime_setMarker(iscsiTgtAuthAttributes_cache_marker); else iscsiTgtAuthAttributes_cache_marker = atime_newMarker(); iscsiTgtAuthAttributes_load(NULL, NULL); } #endif struct iscsiTgtAuthAttributes_entry *iscsiTgtAuthAttributes_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiTgtAuthAttributes_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiTgtAuthAttributes_cache_update(); #endif *my_loop_context = iscsiTgtAuthAttributes_head; return iscsiTgtAuthAttributes_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiTgtAuthAttributes_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiTgtAuthAttributes_entry *entry = (struct iscsiTgtAuthAttributes_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiNodeIndex, sizeof(entry->iscsiNodeIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiTgtAuthIndex, sizeof(entry->iscsiTgtAuthIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiTgtAuthAttributes table */ int iscsiTgtAuthAttributes_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiTgtAuthAttributes_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiTgtAuthAttributes_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSITGTAUTHINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiTgtAuthIndex, sizeof(table_entry->iscsiTgtAuthIndex)); break; case COLUMN_ISCSITGTAUTHROWSTATUS: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiTgtAuthRowStatus, sizeof(table_entry->iscsiTgtAuthRowStatus)); break; case COLUMN_ISCSITGTAUTHIDENTITY: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *)&table_entry->iscsiTgtAuthIdentity, table_entry->iscsiTgtAuthIdentity_len * sizeof(oid)); break; case COLUMN_ISCSITGTAUTHSTORAGETYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiTgtAuthStorageType, sizeof(table_entry->iscsiTgtAuthStorageType)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_ISCSI_TGT_AUTH "/proc/iscsi_target/mib/tgt_auth" #define ISCSI_TGT_AUTH_LINE "%lu %lu %lu %s" static oid ipsAuthIdentDesc_oid[] = {OID_LIO_IPS_AUTH_MIB,1,3,1,1,2}; int iscsiTgtAuthAttributes_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[512]; char intrName[ISCSI_MAX_NAME_LEN]; struct iscsiTgtAuthAttributes_entry tmp, *entry; if (iscsiTgtAuthAttributes_head) iscsiTgtAuthAttributes_free(NULL, NULL); if (!(fp = fopen(PROC_ISCSI_TGT_AUTH, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_ISCSI_TGT_AUTH); return -1; } while (line == fgets(line, sizeof(line), fp)) { uint32_t idenIndex = 0; memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_TGT_AUTH_LINE, &tmp.iscsiInstIndex, &tmp.iscsiNodeIndex, &tmp.iscsiTgtAuthIndex, intrName) != 4) continue; if (intrName[0]) { idenIndex = find_authId_index(intrName); } if (idenIndex) { int oidLen = OID_LENGTH(ipsAuthIdentDesc_oid); memcpy(tmp.iscsiTgtAuthIdentity, ipsAuthIdentDesc_oid, sizeof(ipsAuthIdentDesc_oid)); tmp.iscsiTgtAuthIdentity[oidLen] = idenIndex; tmp.iscsiTgtAuthIdentity_len = oidLen + 1; } else { /* return {0.0} */ tmp.iscsiTgtAuthIdentity_len = 2; } tmp.iscsiTgtAuthRowStatus = RS_ACTIVE; tmp.iscsiTgtAuthStorageType = ST_READONLY; entry = SNMP_MALLOC_TYPEDEF(struct iscsiTgtAuthAttributes_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiTgtAuthAttributes_head; iscsiTgtAuthAttributes_head = entry; } fclose(fp); return 0; } void iscsiTgtAuthAttributes_free(netsnmp_cache *cache, void *vmagic) { struct iscsiTgtAuthAttributes_entry *entry; while (iscsiTgtAuthAttributes_head) { entry = iscsiTgtAuthAttributes_head; iscsiTgtAuthAttributes_head = iscsiTgtAuthAttributes_head->next; SNMP_FREE(entry); } } /* * Session Attributes Table */ #define ISCSI_SESSION_ATTR_CACHE_TIMEOUT 10 /* * Initialize the iscsiSessionAttributes table */ void initialize_table_iscsiSessionAttributes(void) { static oid iscsiSessionAttributes_oid[] = {OID_LIO_ISCSI_MIB,1,10,1}; size_t iscsiSessionAttributes_oid_len = OID_LENGTH(iscsiSessionAttributes_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiSessionAttributes", iscsiSessionAttributes_handler, iscsiSessionAttributes_oid, iscsiSessionAttributes_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* iscsiInstIndex */ ASN_UNSIGNED, /* iscsiSsnNodeIndex */ ASN_UNSIGNED, /* iscsiSsnIndex */ 0); table_info->min_column = 1; table_info->max_column = 22; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiSessionAttributes_get_first_data_point; iinfo->get_next_data_point = iscsiSessionAttributes_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_SESSION_ATTR_CACHE_TIMEOUT, iscsiSessionAttributes_load, iscsiSessionAttributes_free, iscsiSessionAttributes_oid, iscsiSessionAttributes_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiSessionAttributes_cache_update(void) { static marker_t iscsiSessionAttributes_cache_marker = NULL; if (iscsiSessionAttributes_cache_marker && (!atime_ready(iscsiSessionAttributes_cache_marker, ISCSI_SESSION_ATTR_CACHE_TIMEOUT * 1000))) return; if (iscsiSessionAttributes_cache_marker) atime_setMarker(iscsiSessionAttributes_cache_marker); else iscsiSessionAttributes_cache_marker = atime_newMarker(); iscsiSessionAttributes_load(NULL, NULL); } #endif struct iscsiSessionAttributes_entry *iscsiSessionAttributes_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiSessionAttributes_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiSessionAttributes_cache_update(); #endif *my_loop_context = iscsiSessionAttributes_head; return iscsiSessionAttributes_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiSessionAttributes_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiSessionAttributes_entry *entry = (struct iscsiSessionAttributes_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiSsnNodeIndex, sizeof(entry->iscsiSsnNodeIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiSsnIndex, sizeof(entry->iscsiSsnIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiSessionAttributes table */ int iscsiSessionAttributes_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiSessionAttributes_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiSessionAttributes_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSISSNNODEINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiSsnNodeIndex, sizeof(table_entry->iscsiSsnNodeIndex)); break; case COLUMN_ISCSISSNINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiSsnIndex, sizeof(table_entry->iscsiSsnIndex)); break; case COLUMN_ISCSISSNDIRECTION: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiSsnDirection, sizeof(table_entry->iscsiSsnDirection)); break; case COLUMN_ISCSISSNINITIATORNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiSsnInitiatorName, strlen(table_entry->iscsiSsnInitiatorName)); break; case COLUMN_ISCSISSNTARGETNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiSsnTargetName, strlen(table_entry->iscsiSsnTargetName)); break; case COLUMN_ISCSISSNTSIH: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiSsnTSIH, sizeof(table_entry->iscsiSsnTSIH)); break; case COLUMN_ISCSISSNISID: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiSsnISID, sizeof(table_entry->iscsiSsnISID)); break; case COLUMN_ISCSISSNINITIATORALIAS: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiSsnInitiatorAlias, strlen(table_entry->iscsiSsnInitiatorAlias)); break; case COLUMN_ISCSISSNTARGETALIAS: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiSsnTargetAlias, strlen(table_entry->iscsiSsnTargetAlias)); break; case COLUMN_ISCSISSNINITIALR2T: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiSsnInitialR2T, sizeof(table_entry->iscsiSsnInitialR2T)); break; case COLUMN_ISCSISSNIMMEDIATEDATA: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiSsnImmediateData, sizeof(table_entry->iscsiSsnImmediateData)); break; case COLUMN_ISCSISSNTYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiSsnType, sizeof(table_entry->iscsiSsnType)); break; case COLUMN_ISCSISSNMAXOUTSTANDINGR2T: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiSsnMaxOutstandingR2T, sizeof(table_entry->iscsiSsnMaxOutstandingR2T)); break; case COLUMN_ISCSISSNFIRSTBURSTLENGTH: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiSsnFirstBurstLength, sizeof(table_entry->iscsiSsnFirstBurstLength)); break; case COLUMN_ISCSISSNMAXBURSTLENGTH: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiSsnMaxBurstLength, sizeof(table_entry->iscsiSsnMaxBurstLength)); break; case COLUMN_ISCSISSNCONNECTIONNUMBER: snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *)&table_entry->iscsiSsnConnectionNumber, sizeof(table_entry->iscsiSsnConnectionNumber)); break; case COLUMN_ISCSISSNAUTHIDENTITY: snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, (u_char *)&table_entry->iscsiSsnAuthIdentity, table_entry->iscsiSsnAuthIdentity_len * sizeof(oid)); break; case COLUMN_ISCSISSNDATASEQUENCEINORDER: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiSsnDataSequenceInOrder, sizeof(table_entry->iscsiSsnDataSequenceInOrder)); break; case COLUMN_ISCSISSNDATAPDUINORDER: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiSsnDataPDUInOrder, sizeof(table_entry->iscsiSsnDataPDUInOrder)); break; case COLUMN_ISCSISSNERRORRECOVERYLEVEL: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiSsnErrorRecoveryLevel, sizeof(table_entry->iscsiSsnErrorRecoveryLevel)); break; case COLUMN_ISCSISSNDISCONTINUITYTIME: snmp_set_var_typed_value(request->requestvb, ASN_TIMETICKS, (u_char *)&table_entry->iscsiSsnDiscontinuityTime, sizeof(table_entry->iscsiSsnDiscontinuityTime)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SESSION_ATTR "/proc/iscsi_target/mib/sess_attr" #define ISCSI_SESSION_ATTR_LINE "%lu %lu %lu %s %s %s %lu %02X %02X %02X %02X %02X %02X %s %s %s %lu %lu %lu %lu %s %s %s %lu %lu" static oid ipsAuthMethodNone_oid[] = {OID_LIO_IPS_AUTH_MIB,1,1,1,1}; int iscsiSessionAttributes_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[512]; char direction[12]; char r2t[4]; char immData[4]; char ssnType[12]; char seqOrder[4]; char pduOrder[4]; char authType[8]; struct iscsiSessionAttributes_entry tmp, *entry; if (iscsiSessionAttributes_head) iscsiSessionAttributes_free(NULL, NULL); if (!(fp = fopen(PROC_SESSION_ATTR, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SESSION_ATTR); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_SESSION_ATTR_LINE, &tmp.iscsiInstIndex, &tmp.iscsiSsnNodeIndex, &tmp.iscsiSsnIndex, direction, tmp.iscsiSsnInitiatorName, tmp.iscsiSsnTargetName, &tmp.iscsiSsnTSIH, (u_int *)&tmp.iscsiSsnISID[0], (u_int *)&tmp.iscsiSsnISID[1], (u_int *)&tmp.iscsiSsnISID[2], (u_int *)&tmp.iscsiSsnISID[3], (u_int *)&tmp.iscsiSsnISID[4], (u_int *)&tmp.iscsiSsnISID[5], r2t, immData, ssnType, &tmp.iscsiSsnMaxOutstandingR2T, &tmp.iscsiSsnFirstBurstLength, &tmp.iscsiSsnMaxBurstLength, &tmp.iscsiSsnConnectionNumber, authType, seqOrder, pduOrder, &tmp.iscsiSsnErrorRecoveryLevel, &tmp.iscsiSsnDiscontinuityTime) != 25) continue; if (line != fgets(line, sizeof(line), fp)) break; if (sscanf(line, "intr_alias: %s", tmp.iscsiSsnInitiatorAlias) == 1) { *(line + strlen(line) - 1) = 0; strcpy(tmp.iscsiSsnInitiatorAlias, line + strlen("intr_alias: ")); if (!strcmp(tmp.iscsiSsnInitiatorAlias, "None")) tmp.iscsiSsnInitiatorAlias[0] = 0; } else break; if (line != fgets(line, sizeof(line), fp)) break; if (sscanf(line, "tgt_alias: %s", tmp.iscsiSsnTargetAlias) == 1) { *(line + strlen(line) - 1) = 0; strcpy(tmp.iscsiSsnTargetAlias, line + strlen("tgt_alias: ")); } else break; tmp.iscsiSsnDirection = SSN_DIR_INBOUND; if (!strcmp(r2t, "Yes")) tmp.iscsiSsnInitialR2T = TV_TRUE; else tmp.iscsiSsnInitialR2T = TV_FALSE; if (!strcmp(immData, "Yes")) tmp.iscsiSsnImmediateData = TV_TRUE; else tmp.iscsiSsnImmediateData = TV_FALSE; if (!strcmp(ssnType, "Normal")) tmp.iscsiSsnType = SSN_TYPE_NORMAL; else if (!strcmp(ssnType, "Discovery")) tmp.iscsiSsnType = SSN_TYPE_DISCOVERY; tmp.iscsiSsnAuthIdentity_len = OID_LENGTH(ipsAuthMethodNone_oid); memcpy(tmp.iscsiSsnAuthIdentity, ipsAuthMethodNone_oid, sizeof(ipsAuthMethodNone_oid)); if (!strcmp(authType, "CHAP")) { tmp.iscsiSsnAuthIdentity[tmp.iscsiSsnAuthIdentity_len - 1] = 3; } if (!strcmp(seqOrder, "Yes")) tmp.iscsiSsnDataSequenceInOrder = TV_TRUE; else tmp.iscsiSsnDataSequenceInOrder = TV_FALSE; if (!strcmp(pduOrder, "Yes")) tmp.iscsiSsnDataPDUInOrder = TV_TRUE; else tmp.iscsiSsnDataPDUInOrder = TV_FALSE; entry = SNMP_MALLOC_TYPEDEF(struct iscsiSessionAttributes_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiSessionAttributes_head; iscsiSessionAttributes_head = entry; } fclose(fp); return 0; } void iscsiSessionAttributes_free(netsnmp_cache *cache, void *vmagic) { struct iscsiSessionAttributes_entry *entry; while (iscsiSessionAttributes_head) { entry = iscsiSessionAttributes_head; iscsiSessionAttributes_head = iscsiSessionAttributes_head->next; SNMP_FREE(entry); } } /* * Session Stats Table */ #define ISCSI_SESSION_STATS_CACHE_TIMEOUT 5 /* * Initialize the iscsiSessionStats table */ void initialize_table_iscsiSessionStats(void) { static oid iscsiSessionStats_oid[] = {OID_LIO_ISCSI_MIB,1,10,2}; size_t iscsiSessionStats_oid_len = OID_LENGTH(iscsiSessionStats_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiSessionStats", iscsiSessionStats_handler, iscsiSessionStats_oid, iscsiSessionStats_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* iscsiInstIndex */ ASN_UNSIGNED, /* iscsiSsnNodeIndex */ ASN_UNSIGNED, /* iscsiSsnIndex */ 0); table_info->min_column = 1; table_info->max_column = 9; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiSessionStats_get_first_data_point; iinfo->get_next_data_point = iscsiSessionStats_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_SESSION_STATS_CACHE_TIMEOUT, iscsiSessionStats_load, iscsiSessionStats_free, iscsiSessionStats_oid, iscsiSessionStats_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiSessionStats_cache_update(void) { static marker_t iscsiSessionStats_cache_marker = NULL; if (iscsiSessionStats_cache_marker && (!atime_ready(iscsiSessionStats_cache_marker, ISCSI_SESSION_STATS_CACHE_TIMEOUT * 1000))) return; if (iscsiSessionStats_cache_marker) atime_setMarker(iscsiSessionStats_cache_marker); else iscsiSessionStats_cache_marker = atime_newMarker(); iscsiSessionStats_load(NULL, NULL); } #endif struct iscsiSessionStats_entry *iscsiSessionStats_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiSessionStats_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiSessionStats_cache_update(); #endif *my_loop_context = iscsiSessionStats_head; return iscsiSessionStats_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiSessionStats_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiSessionStats_entry *entry = (struct iscsiSessionStats_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiSsnNodeIndex, sizeof(entry->iscsiSsnNodeIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiSsnIndex, sizeof(entry->iscsiSsnIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiSessionStats table */ int iscsiSessionStats_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiSessionStats_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiSessionStats_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSISSNCMDPDUS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiSsnCmdPDUs, sizeof(table_entry->iscsiSsnCmdPDUs)); break; case COLUMN_ISCSISSNRSPPDUS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiSsnRspPDUs, sizeof(table_entry->iscsiSsnRspPDUs)); break; case COLUMN_ISCSISSNTXDATAOCTETS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64, (u_char *)&table_entry->iscsiSsnTxDataOctets, sizeof(table_entry->iscsiSsnTxDataOctets)); break; case COLUMN_ISCSISSNRXDATAOCTETS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64, (u_char *)&table_entry->iscsiSsnRxDataOctets, sizeof(table_entry->iscsiSsnRxDataOctets)); break; case COLUMN_ISCSISSNLCTXDATAOCTETS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiSsnLCTxDataOctets, sizeof(table_entry->iscsiSsnLCTxDataOctets)); break; case COLUMN_ISCSISSNLCRXDATAOCTETS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiSsnLCRxDataOctets, sizeof(table_entry->iscsiSsnLCRxDataOctets)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SESSION_STATS "/proc/iscsi_target/mib/sess_stats" #define ISCSI_SESSION_STATS_LINE_32 "%lu %lu %lu %lu %lu %llu %llu" #define ISCSI_SESSION_STATS_LINE_64 "%lu %lu %lu %lu %lu %lu %lu" int iscsiSessionStats_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[128]; struct iscsiSessionStats_entry tmp, *entry; u_int64_t txOctets, rxOctets; if (iscsiSessionStats_head) iscsiSessionStats_free(NULL, NULL); if (!(fp = fopen(PROC_SESSION_STATS, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_SESSION_STATS); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, (sizeof(long) == 8)? ISCSI_SESSION_STATS_LINE_64 : ISCSI_SESSION_STATS_LINE_32, &tmp.iscsiInstIndex, &tmp.iscsiSsnNodeIndex, &tmp.iscsiSsnIndex, &tmp.iscsiSsnCmdPDUs, &tmp.iscsiSsnRspPDUs, &txOctets, &rxOctets) != 7) continue; tmp.iscsiSsnTxDataOctets.high = (txOctets >> 32) & 0xffffffff; tmp.iscsiSsnTxDataOctets.low = txOctets & 0xffffffff; tmp.iscsiSsnRxDataOctets.high = (rxOctets >> 32) & 0xffffffff; tmp.iscsiSsnRxDataOctets.low = rxOctets & 0xffffffff; tmp.iscsiSsnLCTxDataOctets = tmp.iscsiSsnTxDataOctets.low; tmp.iscsiSsnLCRxDataOctets = tmp.iscsiSsnRxDataOctets.low; entry = SNMP_MALLOC_TYPEDEF(struct iscsiSessionStats_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiSessionStats_head; iscsiSessionStats_head = entry; } fclose(fp); return 0; } void iscsiSessionStats_free(netsnmp_cache *cache, void *vmagic) { struct iscsiSessionStats_entry *entry; while (iscsiSessionStats_head) { entry = iscsiSessionStats_head; iscsiSessionStats_head = iscsiSessionStats_head->next; SNMP_FREE(entry); } } /* * Session Connection Error Stats Table */ #define ISCSI_SSN_CXN_ERR_CACHE_TIMEOUT 5 /* * Initialize the iscsiSsnCxnErrStats table */ void initialize_table_iscsiSsnCxnErrStats(void) { static oid iscsiSsnCxnErrStats_oid[] = {OID_LIO_ISCSI_MIB,1,10,3}; size_t iscsiSsnCxnErrStats_oid_len = OID_LENGTH(iscsiSsnCxnErrStats_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiSsnCxnErrStats", iscsiSsnCxnErrStats_handler, iscsiSsnCxnErrStats_oid, iscsiSsnCxnErrStats_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* iscsiInstIndex */ ASN_UNSIGNED, /* iscsiSsnNodeIndex */ ASN_UNSIGNED, /* iscsiSsnIndex */ 0); table_info->min_column = 1; table_info->max_column = 5; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiSsnCxnErrStats_get_first_data_point; iinfo->get_next_data_point = iscsiSsnCxnErrStats_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_SSN_CXN_ERR_CACHE_TIMEOUT, iscsiSsnCxnErrStats_load, iscsiSsnCxnErrStats_free, iscsiSsnCxnErrStats_oid, iscsiSsnCxnErrStats_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiSsnCxnErrStats_cache_update(void) { static marker_t iscsiSsnCxnErrStats_cache_marker = NULL; if (iscsiSsnCxnErrStats_cache_marker && (!atime_ready(iscsiSsnCxnErrStats_cache_marker, ISCSI_SSN_CXN_ERR_CACHE_TIMEOUT * 1000))) return; if (iscsiSsnCxnErrStats_cache_marker) atime_setMarker(iscsiSsnCxnErrStats_cache_marker); else iscsiSsnCxnErrStats_cache_marker = atime_newMarker(); iscsiSsnCxnErrStats_load(NULL, NULL); } #endif struct iscsiSsnCxnErrStats_entry *iscsiSsnCxnErrStats_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiSsnCxnErrStats_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiSsnCxnErrStats_cache_update(); #endif *my_loop_context = iscsiSsnCxnErrStats_head; return iscsiSsnCxnErrStats_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiSsnCxnErrStats_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiSsnCxnErrStats_entry *entry = (struct iscsiSsnCxnErrStats_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiSsnNodeIndex, sizeof(entry->iscsiSsnNodeIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiSsnIndex, sizeof(entry->iscsiSsnIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiSsnCxnErrStats table */ int iscsiSsnCxnErrStats_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiSsnCxnErrStats_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiSsnCxnErrStats_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSISSNCXNDIGESTERRORS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiSsnCxnDigestErrors, sizeof(table_entry->iscsiSsnCxnDigestErrors)); break; case COLUMN_ISCSISSNCXNTIMEOUTERRORS: snmp_set_var_typed_value(request->requestvb, ASN_COUNTER, (u_char *)&table_entry->iscsiSsnCxnTimeoutErrors, sizeof(table_entry->iscsiSsnCxnTimeoutErrors)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_SSN_CXN_ERR_STATS "/proc/iscsi_target/mib/sess_conn_err_stats" #define ISCSI_SSN_CXN_ERR_STATS_LINE "%lu %lu %lu %lu %lu" int iscsiSsnCxnErrStats_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[64]; struct iscsiSsnCxnErrStats_entry tmp, *entry; if (iscsiSsnCxnErrStats_head) iscsiSsnCxnErrStats_free(NULL, NULL); if (!(fp = fopen(PROC_SSN_CXN_ERR_STATS, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n",PROC_SSN_CXN_ERR_STATS); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_SSN_CXN_ERR_STATS_LINE, &tmp.iscsiInstIndex, &tmp.iscsiSsnNodeIndex, &tmp.iscsiSsnIndex, &tmp.iscsiSsnCxnDigestErrors, &tmp.iscsiSsnCxnTimeoutErrors) != 5) continue; entry = SNMP_MALLOC_TYPEDEF(struct iscsiSsnCxnErrStats_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiSsnCxnErrStats_head; iscsiSsnCxnErrStats_head = entry; } fclose(fp); return 0; } void iscsiSsnCxnErrStats_free(netsnmp_cache *cache, void *vmagic) { struct iscsiSsnCxnErrStats_entry *entry; while (iscsiSsnCxnErrStats_head) { entry = iscsiSsnCxnErrStats_head; iscsiSsnCxnErrStats_head = iscsiSsnCxnErrStats_head->next; SNMP_FREE(entry); } } /* * Connection Attributes Table */ #define ISCSI_CXN_ATTR_CACHE_TIMEOUT 10 /* * Initialize the iscsiCxnAttributes table */ void initialize_table_iscsiCxnAttributes(void) { static oid iscsiCxnAttributes_oid[] = {OID_LIO_ISCSI_MIB,1,11,1}; size_t iscsiCxnAttributes_oid_len = OID_LENGTH(iscsiCxnAttributes_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("iscsiCxnAttributes", iscsiCxnAttributes_handler, iscsiCxnAttributes_oid, iscsiCxnAttributes_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* iscsiInstIndex */ ASN_UNSIGNED, /* iscsiSsnNodeIndex */ ASN_UNSIGNED, /* iscsiSsnIndex */ ASN_UNSIGNED, /* iscsiCxnIndex */ 0); table_info->min_column = 1; table_info->max_column = 19; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = iscsiCxnAttributes_get_first_data_point; iinfo->get_next_data_point = iscsiCxnAttributes_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); #if HAVE_CACHE_HANDLER /* Initialize the contents of the table */ netsnmp_inject_handler(reg, netsnmp_get_cache_handler(ISCSI_CXN_ATTR_CACHE_TIMEOUT, iscsiCxnAttributes_load, iscsiCxnAttributes_free, iscsiCxnAttributes_oid, iscsiCxnAttributes_oid_len)); #endif } #if !HAVE_CACHE_HANDLER void iscsiCxnAttributes_cache_update(void) { static marker_t iscsiCxnAttributes_cache_marker = NULL; if (iscsiCxnAttributes_cache_marker && (!atime_ready(iscsiCxnAttributes_cache_marker, ISCSI_CXN_ATTR_CACHE_TIMEOUT * 1000))) return; if (iscsiCxnAttributes_cache_marker) atime_setMarker(iscsiCxnAttributes_cache_marker); else iscsiCxnAttributes_cache_marker = atime_newMarker(); iscsiCxnAttributes_load(NULL, NULL); } #endif struct iscsiCxnAttributes_entry *iscsiCxnAttributes_head = NULL; /* * Iterator hook routines */ netsnmp_variable_list * iscsiCxnAttributes_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { #if !HAVE_CACHE_HANDLER iscsiCxnAttributes_cache_update(); #endif *my_loop_context = iscsiCxnAttributes_head; return iscsiCxnAttributes_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * iscsiCxnAttributes_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct iscsiCxnAttributes_entry *entry = (struct iscsiCxnAttributes_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)&entry->iscsiInstIndex, sizeof(entry->iscsiInstIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiSsnNodeIndex, sizeof(entry->iscsiSsnNodeIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiSsnIndex, sizeof(entry->iscsiSsnIndex)); idx = idx->next_variable; snmp_set_var_value(idx, (u_char *)&entry->iscsiCxnIndex, sizeof(entry->iscsiCxnIndex)); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /* * Handles requests for the iscsiCxnAttributes table */ int iscsiCxnAttributes_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct iscsiCxnAttributes_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct iscsiCxnAttributes_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if (!table_entry || !table_info) continue; switch (table_info->colnum) { case COLUMN_ISCSICXNINDEX: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiCxnIndex, sizeof(table_entry->iscsiCxnIndex)); break; case COLUMN_ISCSICXNCID: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiCxnCid, sizeof(table_entry->iscsiCxnCid)); break; case COLUMN_ISCSICXNSTATE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiCxnState, sizeof(table_entry->iscsiCxnState)); break; case COLUMN_ISCSICXNADDRTYPE: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiCxnAddrType, sizeof(table_entry->iscsiCxnAddrType)); break; case COLUMN_ISCSICXNLOCALADDR: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiCxnLocalAddr, (table_entry->iscsiCxnAddrType == INET_ADDR_TYPE_IPV4)? INET_ADDR_TYPE_IPV4_LEN: sizeof(table_entry->iscsiCxnLocalAddr)); break; case COLUMN_ISCSICXNPROTOCOL: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiCxnProtocol, sizeof(table_entry->iscsiCxnProtocol)); break; case COLUMN_ISCSICXNLOCALPORT: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiCxnLocalPort, sizeof(table_entry->iscsiCxnLocalPort)); break; case COLUMN_ISCSICXNREMOTEADDR: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->iscsiCxnRemoteAddr, (table_entry->iscsiCxnAddrType == INET_ADDR_TYPE_IPV4)? INET_ADDR_TYPE_IPV4_LEN: sizeof(table_entry->iscsiCxnRemoteAddr)); break; case COLUMN_ISCSICXNREMOTEPORT: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiCxnRemotePort, sizeof(table_entry->iscsiCxnRemotePort)); break; case COLUMN_ISCSICXNMAXRECVDATASEGLENGTH: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiCxnMaxRecvDataSegLength, sizeof(table_entry->iscsiCxnMaxRecvDataSegLength)); break; case COLUMN_ISCSICXNMAXXMITDATASEGLENGTH: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiCxnMaxXmitDataSegLength, sizeof(table_entry->iscsiCxnMaxXmitDataSegLength)); break; case COLUMN_ISCSICXNHEADERINTEGRITY: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiCxnHeaderIntegrity, sizeof(table_entry->iscsiCxnHeaderIntegrity)); break; case COLUMN_ISCSICXNDATAINTEGRITY: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiCxnDataIntegrity, sizeof(table_entry->iscsiCxnDataIntegrity)); break; case COLUMN_ISCSICXNRECVMARKER: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiCxnRecvMarker, sizeof(table_entry->iscsiCxnRecvMarker)); break; case COLUMN_ISCSICXNSENDMARKER: snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&table_entry->iscsiCxnSendMarker, sizeof(table_entry->iscsiCxnSendMarker)); break; case COLUMN_ISCSICXNVERSIONACTIVE: snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&table_entry->iscsiCxnVersionActive, sizeof(table_entry->iscsiCxnVersionActive)); break; } } break; } return SNMP_ERR_NOERROR; } #define PROC_CXN_ATTR "/proc/iscsi_target/mib/conn_attr" #define ISCSI_CXN_ATTR_LINE "%lu %lu %lu %lu %lu %s %s %08X %s %lu %08X %lu %lu %lu %s %s %s %s %lu" int iscsiCxnAttributes_load(netsnmp_cache *cache, void *vmagic) { FILE *fp; char line[512]; char cxnState[8]; char addrType[12]; char proto[8]; char hdrDgst[16]; char dataDgst[16]; char rcvMarker[4]; char sendMarker[4]; uint32_t addr; struct iscsiCxnAttributes_entry tmp, *entry; if (iscsiCxnAttributes_head) iscsiCxnAttributes_free(NULL, NULL); if (!(fp = fopen(PROC_CXN_ATTR, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_CXN_ATTR); return -1; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_CXN_ATTR_LINE, &tmp.iscsiInstIndex, &tmp.iscsiSsnNodeIndex, &tmp.iscsiSsnIndex, &tmp.iscsiCxnIndex, &tmp.iscsiCxnCid, cxnState, addrType, (u_int *)tmp.iscsiCxnLocalAddr, proto, &tmp.iscsiCxnLocalPort, (u_int *)tmp.iscsiCxnRemoteAddr, &tmp.iscsiCxnRemotePort, &tmp.iscsiCxnMaxRecvDataSegLength, &tmp.iscsiCxnMaxXmitDataSegLength, hdrDgst, dataDgst, rcvMarker, sendMarker, &tmp.iscsiCxnVersionActive) != 19) continue; if (!strcmp(cxnState, "login")) tmp.iscsiCxnState = CXN_STATE_LOGIN; else if (!strcmp(cxnState, "full")) tmp.iscsiCxnState = CXN_STATE_FULL; else if (!strcmp(cxnState, "logout")) tmp.iscsiCxnState = CXN_STATE_LOGOUT; if (!strcmp(addrType, "ipv4")) { tmp.iscsiCxnAddrType = INET_ADDR_TYPE_IPV4; addr = htonl(*(uint32_t *)tmp.iscsiCxnLocalAddr); *(uint32_t *)tmp.iscsiCxnLocalAddr = addr; addr = htonl(*(uint32_t *)tmp.iscsiCxnRemoteAddr); *(uint32_t *)tmp.iscsiCxnRemoteAddr = addr; } if (!strcmp(proto, "TCP")) tmp.iscsiCxnProtocol = TRANSPORT_PROTO_TCP; else if (!strcmp(proto, "SCTP")) tmp.iscsiCxnProtocol = TRANSPORT_PROTO_SCTP; if (!strcmp(hdrDgst, "CRC32C")) tmp.iscsiCxnHeaderIntegrity = ISCSI_DIGEST_CRC32C; else if (!strcmp(hdrDgst, "None")) tmp.iscsiCxnHeaderIntegrity = ISCSI_DIGEST_NODIGEST; else tmp.iscsiCxnHeaderIntegrity = ISCSI_DIGEST_OTHER; if (!strcmp(dataDgst, "CRC32C")) tmp.iscsiCxnDataIntegrity = ISCSI_DIGEST_CRC32C; else if (!strcmp(dataDgst, "None")) tmp.iscsiCxnDataIntegrity = ISCSI_DIGEST_NODIGEST; else tmp.iscsiCxnDataIntegrity = ISCSI_DIGEST_OTHER; if (!strcmp(rcvMarker, "Yes")) tmp.iscsiCxnRecvMarker = TV_TRUE; else tmp.iscsiCxnRecvMarker = TV_FALSE; if (!strcmp(sendMarker, "Yes")) tmp.iscsiCxnSendMarker = TV_TRUE; else tmp.iscsiCxnSendMarker = TV_FALSE; entry = SNMP_MALLOC_TYPEDEF(struct iscsiCxnAttributes_entry); if (!entry) break; memcpy(entry, &tmp, sizeof(tmp)); entry->next = iscsiCxnAttributes_head; iscsiCxnAttributes_head = entry; } fclose(fp); return 0; } void iscsiCxnAttributes_free(netsnmp_cache *cache, void *vmagic) { struct iscsiCxnAttributes_entry *entry; while (iscsiCxnAttributes_head) { entry = iscsiCxnAttributes_head; iscsiCxnAttributes_head = iscsiCxnAttributes_head->next; SNMP_FREE(entry); } } /* * Session Failure Notification */ /* Use 3 sec poll recommended by the draft */ #define ISCSI_SSN_FAIL_POLL_INTERVAL 3 void iscsiInstSessionFailure_load(unsigned int clientreg, void *clientarg); /* Initializes the iscsiInstSessionFailure module */ void initialize_iscsiInstSessionFailure(void) { /* Setup callback for polling for login failure */ snmp_alarm_register(ISCSI_SSN_FAIL_POLL_INTERVAL, SA_REPEAT, iscsiInstSessionFailure_load, NULL); /* Initial load */ iscsiInstSessionFailure_load(0, NULL); } int send_iscsiInstSessionFailure_trap(struct iscsiInstSessionFailure_entry *entry) { netsnmp_variable_list *var_list = NULL; oid iscsiInstSessionFailure_oid[] = {OID_LIO_ISCSI_MIB,0,3}; oid iscsiInstSsnFailures_oid[] = {OID_LIO_ISCSI_MIB,1,1,1,1,10, entry->iscsiInstIndex}; oid iscsiInstLastSsnFailureType_oid[] = {OID_LIO_ISCSI_MIB,1,1,1,1,11, entry->iscsiInstIndex}; oid iscsiInstLastSsnRmtNodeName_oid[] = {OID_LIO_ISCSI_MIB,1,1,1,1,12, entry->iscsiInstIndex}; /* * Set the snmpTrapOid.0 value */ snmp_varlist_add_variable(&var_list, snmptrap_oid, OID_LENGTH(snmptrap_oid), ASN_OBJECT_ID, (u_char *)iscsiInstSessionFailure_oid, sizeof(iscsiInstSessionFailure_oid)); /* * Add any objects from the trap definition */ snmp_varlist_add_variable(&var_list, iscsiInstSsnFailures_oid, OID_LENGTH(iscsiInstSsnFailures_oid), ASN_COUNTER, (u_char *)&entry->iscsiInstSsnFailures, sizeof(entry->iscsiInstSsnFailures)); snmp_varlist_add_variable(&var_list, iscsiInstLastSsnFailureType_oid, OID_LENGTH(iscsiInstLastSsnFailureType_oid), ASN_OBJECT_ID, (u_char *)&entry->iscsiInstLastSsnFailureType, entry->iscsiInstLastSsnFailureType_len * sizeof(oid)); snmp_varlist_add_variable(&var_list, iscsiInstLastSsnRmtNodeName_oid, OID_LENGTH(iscsiInstLastSsnRmtNodeName_oid), ASN_OCTET_STR, (u_char *)entry->iscsiInstLastSsnRmtNodeName, strlen(entry->iscsiInstLastSsnRmtNodeName)); /* * Send the trap to the list of configured destinations and clean up */ send_v2trap(var_list); snmp_free_varbind(var_list); return SNMP_ERR_NOERROR; } static struct iscsiInstSessionFailure_entry ssnFailureData; void iscsiInstSessionFailure_load(unsigned int clientreg, void *clientarg) { FILE *fp; char line[512]; struct iscsiInstSessionFailure_entry tmp; u_long iscsiInstVersionMin; u_long iscsiInstVersionMax; u_long iscsiInstPortalNumber; u_long iscsiInstNodeNumber; u_long iscsiInstSessionNumber; u_long iscsiInstDiscontinuityTime; uint32_t failType; /* Use iSCSI Instance Attributes file */ if (!(fp = fopen(PROC_INST_ATTR, "r"))) { //snmp_log(LOG_DEBUG, "snmpd: cannot open %s\n", PROC_INST_ATTR); return; } while (line == fgets(line, sizeof(line), fp)) { memset(&tmp, 0, sizeof(tmp)); if (sscanf(line, ISCSI_INST_ATTR_LINE, &tmp.iscsiInstIndex, &iscsiInstVersionMin, &iscsiInstVersionMax, &iscsiInstPortalNumber, &iscsiInstNodeNumber, &iscsiInstSessionNumber, &tmp.iscsiInstSsnFailures, &failType, tmp.iscsiInstLastSsnRmtNodeName, &iscsiInstDiscontinuityTime) != 10) continue; #if 0 /* Test code: simulates a session failure */ static int count = 0; if (++count == 3) { tmp.iscsiInstSsnFailures++; failType = 2; strcpy(tmp.iscsiInstLastSsnRmtNodeName, "Trap-Test-Initiator-123"); } #endif if (tmp.iscsiInstSsnFailures != ssnFailureData.iscsiInstSsnFailures) { int oidLen = OID_LENGTH(iscsiInstSsnErrStats_oid); memcpy(tmp.iscsiInstLastSsnFailureType, iscsiInstSsnErrStats_oid, sizeof(iscsiInstSsnErrStats_oid)); tmp.iscsiInstLastSsnFailureType[oidLen] = failType; tmp.iscsiInstLastSsnFailureType_len = oidLen + 1; if (clientreg && tmp.iscsiInstSsnFailures) send_iscsiInstSessionFailure_trap(&tmp); memcpy(&ssnFailureData, &tmp, sizeof(tmp)); } /* Only one instance exists now */ break; } fclose(fp); } lio-utils-3.1+git2.fd0b34fd/mib-modules/iscsiAuthData.c0000644000175000017500000001601111753136721020744 0ustar rrsrrs/* * Copyright (c) 2006 SBE, Inc. * Copyright (c) 2009-2010 Linux-iSCSI.org * * Nicholas A. Bellinger * * 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. */ #include #include #include #include "iscsiAuthData.h" /* * Maintains authentication database with index values */ static uint32_t get_authId_index(authId_entry_t *authId_list, char *authIdName) { static uint32_t authIdIndex = 1; uint32_t index = 0; authId_entry_t *entry = authId_list; /* Use the index from the original list, if found */ while (entry) { if (!strcmp(entry->authIdName, authIdName)) { index = entry->authIdIndex; break; } entry = entry->next; } if (!index) index = authIdIndex++; return index; } #define PROC_IPS_AUTH "/proc/iscsi_target/mib/ips_auth" #define IPS_AUTH_LINE "%u %u" static void update_enforce_auth(authId_entry_t *authId_list) { FILE *fp; char line[80]; u_int tpgt, enforceAuth; authId_entry_t *authId_entry; authCred_entry_t *authCred_entry; if (authId_list == NULL) return; if (!(fp = fopen(PROC_IPS_AUTH, "r"))) { snmp_log(LOG_ERR, "snmpd: cannot open %s\n", PROC_IPS_AUTH); return; } while (line == fgets(line, sizeof(line), fp)) { if (sscanf(line, IPS_AUTH_LINE, &tpgt, &enforceAuth) != 2) continue; for (authId_entry = authId_list; authId_entry; authId_entry = authId_entry->next) { for (authCred_entry = authId_entry->authCred_list; authCred_entry; authCred_entry = authCred_entry->next) { if ((authCred_entry->tpgt == tpgt) && (authCred_entry->enforceAuth != enforceAuth)) authCred_entry->enforceAuth = enforceAuth; } } } fclose(fp); } static void free_auth_data(authId_entry_t *authId_list) { authId_entry_t *authId_entry; authCred_entry_t *authCred_entry; while (authId_list) { authId_entry = authId_list; authId_list = authId_list->next; while (authId_entry->authCred_list) { authCred_entry = authId_entry->authCred_list; authId_entry->authCred_list = authCred_entry->next; SNMP_FREE(authCred_entry); } SNMP_FREE(authId_entry); } } #define AUTH_CONF_FILE "/etc/sysconfig/target_auth" #define AUTH_CONF_LINE "%s %s %d %s" static time_t auth_conf_mtime = 0; static authId_entry_t *authId_list = NULL; int load_auth_data(authId_entry_t **authId_head) { FILE *fp; struct stat sbuf; char line[1024]; authId_entry_t *tmp_authId_list = NULL; authId_entry_t *authId_entry; authId_entry_t tmp_authId; authCred_entry_t tmp_authCred; authCred_entry_t *authCred_entry; char tmpstr[16]; int tmp, found = 0; if (stat(AUTH_CONF_FILE, &sbuf)) { printf("File %s doesn't exist?\n", AUTH_CONF_FILE); free_auth_data(authId_list); *authId_head = NULL; } #if 0 /* Debug code */ printf("mtime1: %s", ctime(&sbuf.st_mtime)); printf("mtime2: %s\n", ctime(&auth_conf_mtime)); #endif if (sbuf.st_mtime == auth_conf_mtime) { /* No changes to the file since the last load */ *authId_head = authId_list; update_enforce_auth(authId_list); return 0; } if (!(fp = fopen(AUTH_CONF_FILE, "r"))) { snmp_log(LOG_ERR, "snmpd: cannot open %s\n", AUTH_CONF_FILE); *authId_head = NULL; return -1; } auth_conf_mtime = sbuf.st_mtime; while (line == fgets(line, sizeof(line), fp)) { memset(&tmp_authId, 0, sizeof(tmp_authId)); memset(&tmp_authCred, 0, sizeof(tmp_authCred)); if (sscanf(line, AUTH_CONF_LINE, tmpstr, tmp_authId.authIdName, &tmp, tmp_authCred.chapUserName) != 4) continue; if (tmpstr[0] == '#') continue; if (tmp_authCred.chapUserName[0] == '"') tmp_authCred.chapUserName[0] = 0; tmp_authCred.tpgt = atoi(tmpstr + 6); /* If this authId entry doesn't exist in the list, add it */ for (authId_entry = tmp_authId_list; authId_entry; authId_entry = authId_entry->next) { if (!strcmp(authId_entry->authIdName, tmp_authId.authIdName)) { found = 1; break; } } if (!found) { tmp_authId.authIdIndex = get_authId_index(authId_list, tmp_authId.authIdName); authId_entry = SNMP_MALLOC_TYPEDEF(authId_entry_t); if (!authId_entry) break; memcpy(authId_entry, &tmp_authId, sizeof(tmp_authId)); authId_entry->next = tmp_authId_list; tmp_authId_list = authId_entry; } /* If this authCred entry doesn't exist, add it */ found = 0; for (authCred_entry = authId_entry->authCred_list; authCred_entry; authCred_entry = authCred_entry->next) { if ((authCred_entry->tpgt == tmp_authCred.tpgt) && !strcmp(authCred_entry->chapUserName, tmp_authCred.chapUserName)) { found = 1; break; } } if (!found) { authCred_entry = SNMP_MALLOC_TYPEDEF(authCred_entry_t); if (!authCred_entry) break; memcpy(authCred_entry, &tmp_authCred, sizeof(tmp_authCred)); authCred_entry->next = authId_entry->authCred_list; authId_entry->authCred_list = authCred_entry; } } update_enforce_auth(tmp_authId_list); #if 0 /* Debug code */ for (authId_entry = tmp_authId_list; authId_entry; authId_entry = authId_entry->next) { printf("index %d, authIdName %s\n", authId_entry->authIdIndex, authId_entry->authIdName); for (authCred_entry = authId_entry->authCred_list; authCred_entry; authCred_entry = authCred_entry->next) { printf("tpgt %d, chapUserName %s\n", authCred_entry->tpgt, authCred_entry->chapUserName); } } #endif /* Update list pointer */ free_auth_data(authId_list); *authId_head = authId_list = tmp_authId_list; fclose(fp); return 0; } uint32_t find_authId_index(char *intrName) { authId_entry_t *authId_head, *authId_entry; uint32_t index = 0; load_auth_data(&authId_head); if (authId_head == NULL) return 0; for (authId_entry = authId_head; authId_entry; authId_entry = authId_entry->next) { if (!strcmp(authId_entry->authIdName, intrName)) { index = authId_entry->authIdIndex; break; } } return index; } lio-utils-3.1+git2.fd0b34fd/mib-modules/iscsiMib.h0000644000175000017500000004366311753136721020002 0ustar rrsrrs/* * Copyright (c) 2006 SBE, Inc. * Copyright (c) 2009-2011 Linux-iSCSI.org * * 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. */ #ifndef ISCSIMIB_H #define ISCSIMIB_H #define ISCSI_NUM_INSTANCES 1 #define ISCSI_NUM_NODES 1 #define ISCSI_MAX_NAME_LEN 224 #define ISCSI_MAX_ALIAS_LEN 256 #define NODE_ROLE_TARGET (1 << 7) #define INET_ADDR_TYPE_IPV4 1 #define INET_ADDR_TYPE_IPV6 2 #define INET_ADDR_TYPE_IPV4_LEN 4 #define TRANSPORT_PROTO_TCP 6 #define TRANSPORT_PROTO_SCTP 132 #define ISCSI_DIGEST_NONE 1 #define ISCSI_DIGEST_OTHER 2 #define ISCSI_DIGEST_NODIGEST 3 #define ISCSI_DIGEST_CRC32C 4 #define SSN_DIR_INBOUND 1 #define SSN_DIR_OUTBOUND 2 #define SSN_TYPE_NORMAL 1 #define SSN_TYPE_DISCOVERY 2 #define CXN_STATE_LOGIN 1 #define CXN_STATE_FULL 2 #define CXN_STATE_LOGOUT 3 /* iSCSI login failure types (sub oids) */ #define ISCSI_LOGIN_FAIL_OTHER 2 #define ISCSI_LOGIN_FAIL_REDIRECT 3 #define ISCSI_LOGIN_FAIL_AUTHORIZE 4 #define ISCSI_LOGIN_FAIL_AUTHENTICATE 5 #define ISCSI_LOGIN_FAIL_NEGOTIATE 6 /* * Instance Attributes Table */ void initialize_table_iscsiInstAttributes(void); Netsnmp_Node_Handler iscsiInstAttributes_handler; Netsnmp_First_Data_Point iscsiInstAttributes_get_first_data_point; Netsnmp_Next_Data_Point iscsiInstAttributes_get_next_data_point; int iscsiInstAttributes_load(netsnmp_cache *cache, void *vmagic); void iscsiInstAttributes_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSIINSTINDEX 1 #define COLUMN_ISCSIINSTDESCR 2 #define COLUMN_ISCSIINSTVERSIONMIN 3 #define COLUMN_ISCSIINSTVERSIONMAX 4 #define COLUMN_ISCSIINSTVENDORID 5 #define COLUMN_ISCSIINSTVENDORVERSION 6 #define COLUMN_ISCSIINSTPORTALNUMBER 7 #define COLUMN_ISCSIINSTNODENUMBER 8 #define COLUMN_ISCSIINSTSESSIONNUMBER 9 #define COLUMN_ISCSIINSTSSNFAILURES 10 #define COLUMN_ISCSIINSTLASTSSNFAILURETYPE 11 #define COLUMN_ISCSIINSTLASTSSNRMTNODENAME 12 #define COLUMN_ISCSIINSTDISCONTINUITYTIME 13 /* Data structure for row entry */ struct iscsiInstAttributes_entry { u_long iscsiInstIndex; char iscsiInstDescr[64]; u_long iscsiInstVersionMin; u_long iscsiInstVersionMax; char iscsiInstVendorID[64]; char iscsiInstVendorVersion[64]; u_long iscsiInstPortalNumber; u_long iscsiInstNodeNumber; u_long iscsiInstSessionNumber; u_long iscsiInstSsnFailures; oid iscsiInstLastSsnFailureType[MAX_OID_LEN]; int iscsiInstLastSsnFailureType_len; char iscsiInstLastSsnRmtNodeName[ISCSI_MAX_NAME_LEN]; u_long iscsiInstDiscontinuityTime; struct iscsiInstAttributes_entry *next; }; /* * Instance Session Failure Stats Table */ void initialize_table_iscsiInstSsnErrStats(void); Netsnmp_Node_Handler iscsiInstSsnErrStats_handler; Netsnmp_First_Data_Point iscsiInstSsnErrStats_get_first_data_point; Netsnmp_Next_Data_Point iscsiInstSsnErrStats_get_next_data_point; int iscsiInstSsnErrStats_load(netsnmp_cache *cache, void *vmagic); void iscsiInstSsnErrStats_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSIINSTSSNDIGESTERRORS 1 #define COLUMN_ISCSIINSTSSNCXNTIMEOUTERRORS 2 #define COLUMN_ISCSIINSTSSNFORMATERRORS 3 /* Data structure for row entry */ struct iscsiInstSsnErrStats_entry { u_long iscsiInstIndex; u_long iscsiInstSsnDigestErrors; u_long iscsiInstSsnCxnTimeoutErrors; u_long iscsiInstSsnFormatErrors; struct iscsiInstSsnErrStats_entry *next; }; /* * Portal Attributes Table */ void initialize_table_iscsiPortalAttributes(void); Netsnmp_Node_Handler iscsiPortalAttributes_handler; Netsnmp_First_Data_Point iscsiPortalAttributes_get_first_data_point; Netsnmp_Next_Data_Point iscsiPortalAttributes_get_next_data_point; int iscsiPortalAttributes_load(netsnmp_cache *cache, void *vmagic); void iscsiPortalAttributes_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSIPORTALINDEX 1 #define COLUMN_ISCSIPORTALROWSTATUS 2 #define COLUMN_ISCSIPORTALROLES 3 #define COLUMN_ISCSIPORTALADDRTYPE 4 #define COLUMN_ISCSIPORTALADDR 5 #define COLUMN_ISCSIPORTALPROTOCOL 6 #define COLUMN_ISCSIPORTALMAXRECVDATASEGLENGTH 7 #define COLUMN_ISCSIPORTALPRIMARYHDRDIGEST 8 #define COLUMN_ISCSIPORTALPRIMARYDATADIGEST 9 #define COLUMN_ISCSIPORTALSECONDARYHDRDIGEST 10 #define COLUMN_ISCSIPORTALSECONDARYDATADIGEST 11 #define COLUMN_ISCSIPORTALRECVMARKER 12 #define COLUMN_ISCSIPORTALSTORAGETYPE 13 /* Data structure for row entry */ struct iscsiPortalAttributes_entry { u_long iscsiInstIndex; u_long iscsiPortalIndex; long iscsiPortalRowStatus; char iscsiPortalRoles; long iscsiPortalAddrType; char iscsiPortalAddr[16]; u_long iscsiPortalProtocol; u_long iscsiPortalMaxRecvDataSegLength; long iscsiPortalPrimaryHdrDigest; long iscsiPortalPrimaryDataDigest; long iscsiPortalSecondaryHdrDigest; long iscsiPortalSecondaryDataDigest; long iscsiPortalRecvMarker; long iscsiPortalStorageType; struct iscsiPortalAttributes_entry *next; }; /* * Target Portal Attributes Table */ void initialize_table_iscsiTgtPortalAttributes(void); Netsnmp_Node_Handler iscsiTgtPortalAttributes_handler; Netsnmp_First_Data_Point iscsiTgtPortalAttributes_get_first_data_point; Netsnmp_Next_Data_Point iscsiTgtPortalAttributes_get_next_data_point; int iscsiTgtPortalAttributes_load(netsnmp_cache *cache, void *vmagic); void iscsiTgtPortalAttributes_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSITGTPORTALNODEINDEXORZERO 1 #define COLUMN_ISCSITGTPORTALPORT 2 #define COLUMN_ISCSITGTPORTALTAG 3 /* Data structure for row entry */ struct iscsiTgtPortalAttributes_entry { u_long iscsiInstIndex; u_long iscsiPortalIndex; u_long iscsiTgtPortalNodeIndexOrZero; u_long iscsiTgtPortalPort; u_long iscsiTgtPortalTag; struct iscsiTgtPortalAttributes_entry *next; }; /* * Node Attributes Table */ void initialize_table_iscsiNodeAttributes(void); Netsnmp_Node_Handler iscsiNodeAttributes_handler; Netsnmp_First_Data_Point iscsiNodeAttributes_get_first_data_point; Netsnmp_Next_Data_Point iscsiNodeAttributes_get_next_data_point; int iscsiNodeAttributes_load(netsnmp_cache *cache, void *vmagic); void iscsiNodeAttributes_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSINODEINDEX 1 #define COLUMN_ISCSINODENAME 2 #define COLUMN_ISCSINODEALIAS 3 #define COLUMN_ISCSINODEROLES 4 #define COLUMN_ISCSINODETRANSPORTTYPE 5 #define COLUMN_ISCSINODEINITIALR2T 6 #define COLUMN_ISCSINODEIMMEDIATEDATA 7 #define COLUMN_ISCSINODEMAXOUTSTANDINGR2T 8 #define COLUMN_ISCSINODEFIRSTBURSTLENGTH 9 #define COLUMN_ISCSINODEMAXBURSTLENGTH 10 #define COLUMN_ISCSINODEMAXCONNECTIONS 11 #define COLUMN_ISCSINODEDATASEQUENCEINORDER 12 #define COLUMN_ISCSINODEDATAPDUINORDER 13 #define COLUMN_ISCSINODEDEFAULTTIME2WAIT 14 #define COLUMN_ISCSINODEDEFAULTTIME2RETAIN 15 #define COLUMN_ISCSINODEERRORRECOVERYLEVEL 16 #define COLUMN_ISCSINODEDISCONTINUITYTIME 17 #define COLUMN_ISCSINODESTORAGETYPE 18 /* Data structure for row entry */ struct iscsiNodeAttributes_entry { u_long iscsiInstIndex; u_long iscsiNodeIndex; char iscsiNodeName[ISCSI_MAX_NAME_LEN]; char iscsiNodeAlias[ISCSI_MAX_ALIAS_LEN]; char iscsiNodeRoles; oid iscsiNodeTransportType[MAX_OID_LEN]; int iscsiNodeTransportType_len; long iscsiNodeInitialR2T; long iscsiNodeImmediateData; u_long iscsiNodeMaxOutstandingR2T; u_long iscsiNodeFirstBurstLength; u_long iscsiNodeMaxBurstLength; u_long iscsiNodeMaxConnections; long iscsiNodeDataSequenceInOrder; long iscsiNodeDataPDUInOrder; u_long iscsiNodeDefaultTime2Wait; u_long iscsiNodeDefaultTime2Retain; u_long iscsiNodeErrorRecoveryLevel; u_long iscsiNodeDiscontinuityTime; long iscsiNodeStorageType; struct iscsiNodeAttributes_entry *next; }; /* * Target Attributes Table and Target Login Failure Notification */ void initialize_iscsiTargetAttributes(void); void initialize_table_iscsiTargetAttributes(void); Netsnmp_Node_Handler iscsiTargetAttributes_handler; Netsnmp_First_Data_Point iscsiTargetAttributes_get_first_data_point; Netsnmp_Next_Data_Point iscsiTargetAttributes_get_next_data_point; void iscsiTargetAttributes_load(unsigned int clientreg, void *clientarg); void iscsiTargetAttributes_free(void); /* column number definitions */ #define COLUMN_ISCSITGTLOGINFAILURES 1 #define COLUMN_ISCSITGTLASTFAILURETIME 2 #define COLUMN_ISCSITGTLASTFAILURETYPE 3 #define COLUMN_ISCSITGTLASTINTRFAILURENAME 4 #define COLUMN_ISCSITGTLASTINTRFAILUREADDRTYPE 5 #define COLUMN_ISCSITGTLASTINTRFAILUREADDR 6 /* Data structure for row entry */ struct iscsiTargetAttributes_entry { u_long iscsiInstIndex; u_long iscsiNodeIndex; u_long iscsiTgtLoginFailures; u_long iscsiTgtLastFailureTime; oid iscsiTgtLastFailureType[MAX_OID_LEN]; int iscsiTgtLastFailureType_len; char iscsiTgtLastIntrFailureName[ISCSI_MAX_NAME_LEN]; long iscsiTgtLastIntrFailureAddrType; char iscsiTgtLastIntrFailureAddr[16]; struct iscsiTargetAttributes_entry *next; }; /* * Target Login Stats Table */ void initialize_table_iscsiTgtLoginStats(void); Netsnmp_Node_Handler iscsiTgtLoginStats_handler; Netsnmp_First_Data_Point iscsiTgtLoginStats_get_first_data_point; Netsnmp_Next_Data_Point iscsiTgtLoginStats_get_next_data_point; int iscsiTgtLoginStats_load(netsnmp_cache *cache, void *vmagic); void iscsiTgtLoginStats_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSITGTLOGINACCEPTS 1 #define COLUMN_ISCSITGTLOGINOTHERFAILS 2 #define COLUMN_ISCSITGTLOGINREDIRECTS 3 #define COLUMN_ISCSITGTLOGINAUTHORIZEFAILS 4 #define COLUMN_ISCSITGTLOGINAUTHENTICATEFAILS 5 #define COLUMN_ISCSITGTLOGINNEGOTIATEFAILS 6 /* Data structure for row entry */ struct iscsiTgtLoginStats_entry { u_long iscsiInstIndex; u_long iscsiNodeIndex; u_long iscsiTgtLoginAccepts; u_long iscsiTgtLoginOtherFails; u_long iscsiTgtLoginRedirects; u_long iscsiTgtLoginAuthorizeFails; u_long iscsiTgtLoginAuthenticateFails; u_long iscsiTgtLoginNegotiateFails; struct iscsiTgtLoginStats_entry *next; }; /* * Target Logout Stats Table */ void initialize_table_iscsiTgtLogoutStats(void); Netsnmp_Node_Handler iscsiTgtLogoutStats_handler; Netsnmp_First_Data_Point iscsiTgtLogoutStats_get_first_data_point; Netsnmp_Next_Data_Point iscsiTgtLogoutStats_get_next_data_point; int iscsiTgtLogoutStats_load(netsnmp_cache *cache, void *vmagic); void iscsiTgtLogoutStats_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSITGTLOGOUTNORMALS 1 #define COLUMN_ISCSITGTLOGOUTOTHERS 2 /* Data structure for row entry */ struct iscsiTgtLogoutStats_entry { u_long iscsiInstIndex; u_long iscsiNodeIndex; u_long iscsiTgtLogoutNormals; u_long iscsiTgtLogoutOthers; struct iscsiTgtLogoutStats_entry *next; }; /* * Target Authorization Attributes Table */ void initialize_table_iscsiTgtAuthAttributes(void); Netsnmp_Node_Handler iscsiTgtAuthAttributes_handler; Netsnmp_First_Data_Point iscsiTgtAuthAttributes_get_first_data_point; Netsnmp_Next_Data_Point iscsiTgtAuthAttributes_get_next_data_point; int iscsiTgtAuthAttributes_load(netsnmp_cache *cache, void *vmagic); void iscsiTgtAuthAttributes_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSITGTAUTHINDEX 1 #define COLUMN_ISCSITGTAUTHROWSTATUS 2 #define COLUMN_ISCSITGTAUTHIDENTITY 3 #define COLUMN_ISCSITGTAUTHSTORAGETYPE 4 /* Data structure for row entry */ struct iscsiTgtAuthAttributes_entry { u_long iscsiInstIndex; u_long iscsiNodeIndex; u_long iscsiTgtAuthIndex; long iscsiTgtAuthRowStatus; oid iscsiTgtAuthIdentity[MAX_OID_LEN]; int iscsiTgtAuthIdentity_len; long iscsiTgtAuthStorageType; struct iscsiTgtAuthAttributes_entry *next; }; /* * Session Attributes Table */ void initialize_table_iscsiSessionAttributes(void); Netsnmp_Node_Handler iscsiSessionAttributes_handler; Netsnmp_First_Data_Point iscsiSessionAttributes_get_first_data_point; Netsnmp_Next_Data_Point iscsiSessionAttributes_get_next_data_point; int iscsiSessionAttributes_load(netsnmp_cache *cache, void *vmagic); void iscsiSessionAttributes_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSISSNNODEINDEX 1 #define COLUMN_ISCSISSNINDEX 2 #define COLUMN_ISCSISSNDIRECTION 3 #define COLUMN_ISCSISSNINITIATORNAME 4 #define COLUMN_ISCSISSNTARGETNAME 5 #define COLUMN_ISCSISSNTSIH 6 #define COLUMN_ISCSISSNISID 7 #define COLUMN_ISCSISSNINITIATORALIAS 8 #define COLUMN_ISCSISSNTARGETALIAS 9 #define COLUMN_ISCSISSNINITIALR2T 10 #define COLUMN_ISCSISSNIMMEDIATEDATA 11 #define COLUMN_ISCSISSNTYPE 12 #define COLUMN_ISCSISSNMAXOUTSTANDINGR2T 13 #define COLUMN_ISCSISSNFIRSTBURSTLENGTH 14 #define COLUMN_ISCSISSNMAXBURSTLENGTH 15 #define COLUMN_ISCSISSNCONNECTIONNUMBER 16 #define COLUMN_ISCSISSNAUTHIDENTITY 17 #define COLUMN_ISCSISSNDATASEQUENCEINORDER 18 #define COLUMN_ISCSISSNDATAPDUINORDER 19 #define COLUMN_ISCSISSNERRORRECOVERYLEVEL 20 #define COLUMN_ISCSISSNDISCONTINUITYTIME 21 /* Data structure for row entry */ struct iscsiSessionAttributes_entry { u_long iscsiInstIndex; u_long iscsiSsnNodeIndex; u_long iscsiSsnIndex; long iscsiSsnDirection; char iscsiSsnInitiatorName[ISCSI_MAX_NAME_LEN]; char iscsiSsnTargetName[ISCSI_MAX_NAME_LEN]; u_long iscsiSsnTSIH; char iscsiSsnISID[6]; char iscsiSsnInitiatorAlias[ISCSI_MAX_ALIAS_LEN]; char iscsiSsnTargetAlias[ISCSI_MAX_ALIAS_LEN]; long iscsiSsnInitialR2T; long iscsiSsnImmediateData; long iscsiSsnType; u_long iscsiSsnMaxOutstandingR2T; u_long iscsiSsnFirstBurstLength; u_long iscsiSsnMaxBurstLength; u_long iscsiSsnConnectionNumber; oid iscsiSsnAuthIdentity[MAX_OID_LEN]; int iscsiSsnAuthIdentity_len; long iscsiSsnDataSequenceInOrder; long iscsiSsnDataPDUInOrder; u_long iscsiSsnErrorRecoveryLevel; u_long iscsiSsnDiscontinuityTime; struct iscsiSessionAttributes_entry *next; }; /* * Session Stats Table */ void initialize_table_iscsiSessionStats(void); Netsnmp_Node_Handler iscsiSessionStats_handler; Netsnmp_First_Data_Point iscsiSessionStats_get_first_data_point; Netsnmp_Next_Data_Point iscsiSessionStats_get_next_data_point; int iscsiSessionStats_load(netsnmp_cache *cache, void *vmagic); void iscsiSessionStats_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSISSNCMDPDUS 1 #define COLUMN_ISCSISSNRSPPDUS 2 #define COLUMN_ISCSISSNTXDATAOCTETS 3 #define COLUMN_ISCSISSNRXDATAOCTETS 4 #define COLUMN_ISCSISSNLCTXDATAOCTETS 5 #define COLUMN_ISCSISSNLCRXDATAOCTETS 6 /* Data structure for row entry */ struct iscsiSessionStats_entry { u_long iscsiInstIndex; u_long iscsiSsnNodeIndex; u_long iscsiSsnIndex; u_long iscsiSsnCmdPDUs; u_long iscsiSsnRspPDUs; U64 iscsiSsnTxDataOctets; U64 iscsiSsnRxDataOctets; u_long iscsiSsnLCTxDataOctets; u_long iscsiSsnLCRxDataOctets; struct iscsiSessionStats_entry *next; }; /* * Session Connection Error Stats Table */ void initialize_table_iscsiSsnCxnErrStats(void); Netsnmp_Node_Handler iscsiSsnCxnErrStats_handler; Netsnmp_First_Data_Point iscsiSsnCxnErrStats_get_first_data_point; Netsnmp_Next_Data_Point iscsiSsnCxnErrStats_get_next_data_point; int iscsiSsnCxnErrStats_load(netsnmp_cache *cache, void *vmagic); void iscsiSsnCxnErrStats_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSISSNCXNDIGESTERRORS 1 #define COLUMN_ISCSISSNCXNTIMEOUTERRORS 2 /* Data structure for row entry */ struct iscsiSsnCxnErrStats_entry { u_long iscsiInstIndex; u_long iscsiSsnNodeIndex; u_long iscsiSsnIndex; u_long iscsiSsnCxnDigestErrors; u_long iscsiSsnCxnTimeoutErrors; struct iscsiSsnCxnErrStats_entry *next; }; /* * Connection Attributes Table */ void initialize_table_iscsiCxnAttributes(void); Netsnmp_Node_Handler iscsiCxnAttributes_handler; Netsnmp_First_Data_Point iscsiCxnAttributes_get_first_data_point; Netsnmp_Next_Data_Point iscsiCxnAttributes_get_next_data_point; int iscsiCxnAttributes_load(netsnmp_cache *cache, void *vmagic); void iscsiCxnAttributes_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_ISCSICXNINDEX 1 #define COLUMN_ISCSICXNCID 2 #define COLUMN_ISCSICXNSTATE 3 #define COLUMN_ISCSICXNADDRTYPE 4 #define COLUMN_ISCSICXNLOCALADDR 5 #define COLUMN_ISCSICXNPROTOCOL 6 #define COLUMN_ISCSICXNLOCALPORT 7 #define COLUMN_ISCSICXNREMOTEADDR 8 #define COLUMN_ISCSICXNREMOTEPORT 9 #define COLUMN_ISCSICXNMAXRECVDATASEGLENGTH 10 #define COLUMN_ISCSICXNMAXXMITDATASEGLENGTH 11 #define COLUMN_ISCSICXNHEADERINTEGRITY 12 #define COLUMN_ISCSICXNDATAINTEGRITY 13 #define COLUMN_ISCSICXNRECVMARKER 14 #define COLUMN_ISCSICXNSENDMARKER 15 #define COLUMN_ISCSICXNVERSIONACTIVE 16 /* Data structure for row entry */ struct iscsiCxnAttributes_entry { u_long iscsiInstIndex; u_long iscsiSsnNodeIndex; u_long iscsiSsnIndex; u_long iscsiCxnIndex; u_long iscsiCxnCid; long iscsiCxnState; long iscsiCxnAddrType; char iscsiCxnLocalAddr[16]; u_long iscsiCxnProtocol; u_long iscsiCxnLocalPort; char iscsiCxnRemoteAddr[16]; u_long iscsiCxnRemotePort; u_long iscsiCxnMaxRecvDataSegLength; u_long iscsiCxnMaxXmitDataSegLength; long iscsiCxnHeaderIntegrity; long iscsiCxnDataIntegrity; long iscsiCxnRecvMarker; long iscsiCxnSendMarker; u_long iscsiCxnVersionActive; struct iscsiCxnAttributes_entry *next; }; /* * Session Failure Notification */ void initialize_iscsiInstSessionFailure(void); struct iscsiInstSessionFailure_entry { u_long iscsiInstIndex; u_long iscsiInstSsnFailures; oid iscsiInstLastSsnFailureType[MAX_OID_LEN]; int iscsiInstLastSsnFailureType_len; char iscsiInstLastSsnRmtNodeName[ISCSI_MAX_NAME_LEN]; }; #endif /* ISCSIMIB_H */ lio-utils-3.1+git2.fd0b34fd/mib-modules/ipsAuthMib.h0000644000175000017500000001120311753136721020266 0ustar rrsrrs/* * Copyright (c) 2006 SBE, Inc. * Copyright (c) 2009-2011 Linux-iSCSI.org * * 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. */ /* * ipsAuthMibModule Definitions */ #ifndef IPSAUTHMIB_H #define IPSAUTHMIB_H #define AUTH_INST_INDEX 1 #define AUTH_ID_NAME_INDEX 1 /* * Instance Attributes Table */ void initialize_table_ipsAuthInstAttr(void); Netsnmp_Node_Handler ipsAuthInstAttr_handler; Netsnmp_First_Data_Point ipsAuthInstAttr_get_first_data_point; Netsnmp_Next_Data_Point ipsAuthInstAttr_get_next_data_point; int ipsAuthInstAttr_load(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_IPSAUTHINSTINDEX 1 #define COLUMN_IPSAUTHINSTDESCR 2 #define COLUMN_IPSAUTHINSTSTORAGETYPE 3 /* Data structure for row entry */ struct ipsAuthInstAttr_entry { u_long ipsAuthInstIndex; char ipsAuthInstDescr[AUTH_MAX_NAME_LEN]; long ipsAuthInstStorageType; struct ipsAuthInstAttr_entry *next; }; /* * User Identity Attributes Table */ void initialize_table_ipsAuthIdentAttr(void); Netsnmp_Node_Handler ipsAuthIdentAttr_handler; Netsnmp_First_Data_Point ipsAuthIdentAttr_get_first_data_point; Netsnmp_Next_Data_Point ipsAuthIdentAttr_get_next_data_point; int ipsAuthIdentAttr_load(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_IPSAUTHIDENTINDEX 1 #define COLUMN_IPSAUTHIDENTDESCRIPTION 2 #define COLUMN_IPSAUTHIDENTROWSTATUS 3 #define COLUMN_IPSAUTHIDENTSTORAGETYPE 4 /* Data structure for row entry */ struct ipsAuthIdentAttr_entry { u_long ipsAuthInstIndex; u_long ipsAuthIdentIndex; char ipsAuthIdentDescription[AUTH_MAX_NAME_LEN]; long ipsAuthIdentRowStatus; long ipsAuthIdentStorageType; struct ipsAuthIdentAttr_entry *next; }; /* * User Initiator Name Attributes Table */ void initialize_table_ipsAuthIdentNameAttr(void); Netsnmp_Node_Handler ipsAuthIdentNameAttr_handler; Netsnmp_First_Data_Point ipsAuthIdentNameAttr_get_first_data_point; Netsnmp_Next_Data_Point ipsAuthIdentNameAttr_get_next_data_point; int ipsAuthIdentNameAttr_load(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_IPSAUTHIDENTNAMEINDEX 1 #define COLUMN_IPSAUTHIDENTNAME 2 #define COLUMN_IPSAUTHIDENTNAMEROWSTATUS 3 #define COLUMN_IPSAUTHIDENTNAMESTORAGETYPE 4 /* Data structure for row entry */ struct ipsAuthIdentNameAttr_entry { u_long ipsAuthInstIndex; u_long ipsAuthIdentIndex; u_long ipsAuthIdentNameIndex; char ipsAuthIdentName[AUTH_MAX_NAME_LEN]; long ipsAuthIdentNameRowStatus; long ipsAuthIdentNameStorageType; struct ipsAuthIdentNameAttr_entry *next; }; /* * Credential Attributes Table */ void initialize_table_ipsAuthCredAttr(void); Netsnmp_Node_Handler ipsAuthCredAttr_handler; Netsnmp_First_Data_Point ipsAuthCredAttr_get_first_data_point; Netsnmp_Next_Data_Point ipsAuthCredAttr_get_next_data_point; int ipsAuthCredAttr_load(netsnmp_cache *cache, void *vmagic); void ipsAuthCredAttr_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_IPSAUTHCREDINDEX 1 #define COLUMN_IPSAUTHCREDAUTHMETHOD 2 #define COLUMN_IPSAUTHCREDROWSTATUS 3 #define COLUMN_IPSAUTHCREDSTORAGETYPE 4 /* Data structure for row entry */ struct ipsAuthCredAttr_entry { u_long ipsAuthInstIndex; u_long ipsAuthIdentIndex; u_long ipsAuthCredIndex; oid ipsAuthCredAuthMethod[MAX_OID_LEN]; int ipsAuthCredAuthMethod_len; long ipsAuthCredRowStatus; long ipsAuthCredStorageType; struct ipsAuthCredAttr_entry *next; }; /* * Credential Chap-Specific Attributes Table */ void initialize_table_ipsAuthCredChapAttr(void); Netsnmp_Node_Handler ipsAuthCredChapAttr_handler; Netsnmp_First_Data_Point ipsAuthCredChapAttr_get_first_data_point; Netsnmp_Next_Data_Point ipsAuthCredChapAttr_get_next_data_point; int ipsAuthCredChapAttr_load(netsnmp_cache *cache, void *vmagic); void ipsAuthCredChapAttr_free(netsnmp_cache *cache, void *vmagic); /* column number definitions */ #define COLUMN_IPSAUTHCREDCHAPUSERNAME 1 #define COLUMN_IPSAUTHCREDCHAPROWSTATUS 2 #define COLUMN_IPSAUTHCREDCHAPSTORAGETYPE 3 /* Data structure for row entry */ struct ipsAuthCredChapAttr_entry { u_long ipsAuthInstIndex; u_long ipsAuthIdentIndex; u_long ipsAuthCredIndex; char ipsAuthCredChapUserName[AUTH_MAX_NAME_LEN]; long ipsAuthCredChapRowStatus; long ipsAuthCredChapStorageType; struct ipsAuthCredChapAttr_entry *next; }; void ipsDummy_free(netsnmp_cache *cache, void *vmagic); #endif /* IPSAUTHMIB_H */ lio-utils-3.1+git2.fd0b34fd/mib-modules/iscsiAuthData.h0000644000175000017500000000202411753136721020750 0ustar rrsrrs/* * Copyright (c) 2006 SBE, Inc. * Copyright (c) 2009-2011 Linux-iSCSI.org * * 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. */ /* * ipsAuthMibModule Definitions */ #ifndef ISCSIAUTHDATA_H #define ISCSIAUTHDATA_H #define AUTH_MAX_NAME_LEN 224 /* * Structures used for maintaining initiator authentication database */ typedef struct authCred_entry_s { uint16_t tpgt; uint16_t enforceAuth; char chapUserName[AUTH_MAX_NAME_LEN]; struct authCred_entry_s *next; } authCred_entry_t; typedef struct authId_entry_s { uint32_t authIdIndex; char authIdName[AUTH_MAX_NAME_LEN]; struct authCred_entry_s *authCred_list; struct authId_entry_s *next; } authId_entry_t; extern int load_auth_data(authId_entry_t **authId_head); extern uint32_t find_authId_index(char *intrName); #endif /* ISCSIAUTHDATA_H */ lio-utils-3.1+git2.fd0b34fd/mib-modules/.make_autoconfig0000644000175000017500000000123011753136721021203 0ustar rrsrrsARCH?=i386 AUTO_CFLAGS?= -DHAS_UTS_RELEASE -DUSE_SCSI_H -I/lib/modules/2.6.28/build/drivers/scsi -DUSE_MSLEEP -DUSE_COMPAT_IOCTL -Dscsi_execute_async_address -DPYX_ISCSI_VENDOR='"Linux-iSCSI.org"' -DIQN_PREFIX='"iqn.2003-01.org.linux-iscsi"' -DLINUX -DLINUX_SCATTERLIST_HAS_PAGE -DSVN_VSN=\"413\" BASENAME?=.i386 DISTRO?=DEBIAN KERNEL?=26 KERNEL_DIR?=/lib/modules/2.6.28/build KERNEL_INCLUDE_DIR?=/lib/modules/2.6.28/build/include KERNEL_SOURCE_DIR?=/lib/modules/2.6.28/build KERNEL_VERSION_INFO?=LINUX_KERNEL_26 LIBL?=ia32 OSTYPE?=LINUX PYX_ISCSI_VERSION?=2.9.0.413 RELEASE?=2.6.28 RELEASES?=ARRAY(0x83348dc) RPM_DIR?=/usr/src/redhat VERSION_IPYXD?=2.9.0.413 lio-utils-3.1+git2.fd0b34fd/MCONFIG_ALL0000644000175000017500000000002211753136721015325 0ustar rrsrrsSNMP_FEATURE ?= 1 lio-utils-3.1+git2.fd0b34fd/autoconfig0000755000175000017500000005544311753136721015735 0ustar rrsrrs#!/usr/bin/perl ################################################################################## # Filename: autoconfig.master # # Copyright (c) 2006-2007 SBE, Inc. All Rights Reserved. # Copyright (c) 2007-2009 Linux-iSCSI.org # # 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. # ################################################################################## use File::Basename; use File::Temp qw/ tempfile tempdir mktemp/; use Cwd; push @INC, dirname($0); my $current_ostype = dirname($0) . "/ostype.pm"; #if (! -e $current_ostype ) #{ # my $OSTYPE="http://linux-iscsi.org/svn/trunk/buildtools/ostype.pm"; # `svn cat $OSTYPE > $current_ostype`; #} require ostype; $options = { root_dir => $ENV{'ROOT_DIR'}, current_directory => getcwd(), product_directory => dirname($0), autoconfig_file => ".make_autoconfig" }; sub setup { my @opts =@_; my @args; foreach my $opt (@opts) { for ($opt) { if (/^--write-to-file(.*)/) { unless ("$1" eq "") { $options->{autoconfig_file} = $1; $options->{autoconfig_file} =~ s/^=//; } $options->{write_to_file}=1; next; } if (/^--root=(.*)/) { $options->{root_dir}=$1; next; } if (/^--product-directory=(.*)/) { $options->{product_directory}=$1; next; } if (/^--jakarta-directory=(.*)/) { $options->{jakarta_directory}=$1; next; } if (/^--current-directory=(.*)/) { $options->{current_directory}=$1; next; } if (/^--arch=(.*)/) { $options->{arch}=$1; next; } if (/^--version=(.*)/) { $options->{version}=$1; next; } if (/^--deliver-rpms-to=(.*)/) { $options->{deliver_rpms_to}=$1; next; } if (/^--/) { die "Invalid option $_\n"; } else { push @args, $opt; } } } if ($options->{write_to_file}) { open(AUTOCONFIGFILE,">$options->{current_directory}/$options->{autoconfig_file}") || die "Could not open $options->{autoconfig_file}"; } return @args; } sub check_and_define { my ($match, $string, @files) = @_; foreach my $file (@files) { next if ( ! -e $file); my $txt = `cat $file`; if ($txt =~ /$match/) { $env->{AUTO_CFLAGS} .=" $string"; return; } } } sub LIO_VERSION { my $lio_ver = "4.0"; my $lio_utils_git_rev = `git rev-list --max-count=1 HEAD`; chomp($lio_utils_git_rev); my $lio_utils_rev = substr $lio_utils_git_rev, 0, 8; $env->{LIO_VERSION} = $lio_ver; $env->{LIO_UTILS_VERSION} = $lio_ver; $env->{LIO_UTILS_REV} = $lio_utils_rev; return($lio_ver) } sub ISNS_VERSION { my $txt = `svnversion $options->{product_directory}`; # get repository revision $txt =~ m/([\d:]*)\D/; $svn_vsn = $1; $svn_vsn =~ s/:/./; $svn_vsn = "0" if ($svn_vsn eq ""); $txt = `grep ISNS_VERSION $options->{product_directory}/include/iSNS.h 2>/dev/null`; if ($txt =~ /ISNS_VERSION\s+(.*)$/) { $txt = $1; } else { $txt = `grep ISNS_VERSION $options->{product_directory}/include/isns.h 2>/dev/null`; if ($txt =~ /ISNS_VERSION\s+(.*)$/) { $txt = $1; } else { return; } } $txt =~ s/SVN_VSN/$svn_vsn/; # put in repository revision $txt =~ s/\"//g; # remove spaces, quotes, and v $txt =~ s/^v//; $txt =~ s/\s//g; $txt =~ s/-.*$//; # trim off -SBE $env->{ISNS_VERSION} = $txt; } sub dump_options { foreach my $key ( sort keys %{$env} ) { if ($options->{write_to_file}) { print AUTOCONFIGFILE "$key?=$env->{$key}\n"; } else { print "$key?=$env->{$key}\n"; } } foreach my $key ( sort keys %{$logic} ) { if ($options->{write_to_file}) { print AUTOCONFIGFILE "$logic->{$key}"; } else { print "$logic->{$key}"; } } } sub dump_config { my $ostype = ostype($options->{root_dir}); foreach my $key ( sort keys %{$ostype} ) { if (($ostype->{BASENAME} =~ /^ELinos/) && ($ostype->{$key} =~ /^\//)) { $env->{$key} = "$options->{root_dir}$ostype->{$key}"; } else { $env->{$key} = $ostype->{$key}; } } check_and_define("UTS_RELEASE", "-DHAS_UTS_RELEASE", "$ostype->{KERNEL_INCLUDE_DIR}/linux/utsrelease.h"); check_and_define("_SCSI_H", "-DUSE_SCSI_H -I$ostype->{KERNEL_SOURCE_DIR}/drivers/scsi ", "$ostype->{KERNEL_SOURCE_DIR}/drivers/scsi/scsi.h"); check_and_define("msleep", "-DUSE_MSLEEP", "$ostype->{KERNEL_INCLUDE_DIR}/linux/delay.h"); if ( ! -e "$ostype->{KERNEL_INCLUDE_DIR}/scsi/scsi_request.h") { $env->{AUTO_CFLAGS} .= " -Dscsi_execute_async_address "; } if ($ENV{'ISCSI_VENDOR'} eq "") { $env->{AUTO_CFLAGS} .= " -DPYX_ISCSI_VENDOR=\'\"Linux-iSCSI.org\"\' "; } else { $env->{AUTO_CFLAGS} .= " -DPYX_ISCSI_VENDOR=\'\"$ENV{'ISCSI_VENDOR'}\"\' "; } if (($ENV{'IQN_VENDOR'}) eq "") { $env->{AUTO_CFLAGS} .= " -DIQN_PREFIX=\'\"iqn.2003-01.org.linux-iscsi\"\' "; } else { $env->{AUTO_CFLAGS} .= " -DIQN_PREFIX=\'\"$ENV{'IQN_VENDOR'}\"\' "; } $env->{AUTO_CFLAGS} .= " -DLINUX" if ($ostype->{OSTYPE} eq "LINUX"); if ($ostype->{KERNEL} eq "26") { $env->{AUTO_CFLAGS} .= " -DLINUX_SCATTERLIST_HAS_PAGE"; } else { $env->{AUTO_CFLAGS} .= " -DLINUX_SCATTERLIST_HAS_ADDRESS"; } $final_svn_vsn = LIO_VERSION(); ISNS_VERSION(); $env->{AUTO_CFLAGS} .= " -DSVN_VSN=\\\"$final_svn_vsn\\\""; if ($ostype->{BASENAME} =~ /^RedHat-R3.*i386/) { my $cputype = "$ENV{'CPUTYPE'}"; if ($cputype eq "i586") { $env->{AUTO_CFLAGS} .= " -D__MODULE_KERNEL_i586=1"; } elsif ($cputype eq "athlon") { $env->{AUTO_CFLAGS} .= " -D__MODULE_KERNEL_athlon=1"; } else { $env->{AUTO_CFLAGS} .= " -D__MODULE_KERNEL_i686=1"; } $env->{AUTO_CFLAGS} .= " -D__BOOT_KERNEL_ENTERPRISE=0"; $env->{AUTO_CFLAGS} .= " -D__BOOT_KERNEL_UP=1"; $env->{AUTO_CFLAGS} .= " -D__BOOT_KERNEL_SMP=1" if ($ostype->{RELEASE} =~ /smp/); $env->{AUTO_CFLAGS} .= " -D__BOOT_KERNEL_HUGEMEM=1" if ($ostype->{RELEASE} =~ /hugemem/); $env->{AUTO_CFLAGS} .= " -D__BOOT_KERNEL_BIGMEM=1" if ($ostype->{RELEASE} =~ /bigmem/); } $env->{SNMP} = 0 unless -e "$options->{root_dir}/usr/include/net-snmp"; dump_options(); if ($options->{write_to_file}) { close (AUTOCONFIGFILE); print "$options->{current_directory}/$options->{autoconfig_file}\n"; } } sub make_target_kernel_rpm { my $ostype = ostype($options->{root_dir}); my $ko = ($ostype->{KERNEL} eq "26") ? "ko" : "o"; my $tcm_base = "/lib/modules/$ostype->{RELEASE}/kernel/drivers/target"; my $lio_base = "/lib/modules/$ostype->{RELEASE}/kernel/drivers/lio-core"; LIO_VERSION(); print "Version: $env->{LIO_VERSION}"; make_rpm({ name => "target_core_mod-$ostype->{RELEASE}", product_name => "Target_Core_Mod/ConfigFS Kernel Module", version => $env->{LIO_VERSION}, release => 1, group => "Target Core_Mod/ConfigFS(kernel)", provides => "target-core-module", post => "depmod -r\n", files => { "$tcm_base/target_core_mod.$ko" => { original => "kernel/drivers/target/target_core_mod.$ko", mode => 644}}}); make_rpm({ name => "iscsi_target_mod-$ostype->{RELEASE}", product_name => "Linux-iSCSI.org Target Kernel Module", version => $env->{LIO_VERSION}, release => 1, group => "LIO-Target Fabric module(kernel)", provides => "iscsi-target-module", post => "depmod -r\n", files => { "$lio_base/iscsi_target_mod.$ko" => { original => "kernel/drivers/lio-core/iscsi_target_mod.$ko", mode => 644}}}); } sub make_target_user_rpm { my $ostype = ostype($options->{root_dir}); my $mandir = "/usr/share/man"; my $value = `python ./get-py-modules-path.py`; my $py_inst_dir = $value = substr($value,0,length($value)-1); LIO_VERSION(); my $text=`rpm --showrc`; if ($text =~ /_mandir\s+(\/.*?)\s/) { $mandir=$1; print "MANDIR: $mandir\n"; } my $iscsid = { name => "lio-utils", product_name => "Linux-iSCSI.org Target v3.x Userspace utils", version => $env->{LIO_UTILS_VERSION}, release => $env->{LIO_UTILS_REV}, group => "Linux-iSCSI.org/Target (applications)", requires => "target-core-modules", requires => "iscsi-target-module", }; $iscsid->{files} = { "/etc/init.d/target" => { original => "scripts/rc.target", mode => 755}, "/etc/target/tcm_start.sh" => { original => "conf/tcm_start.default", config => 1, mode => 700}, "/etc/target/lio_start.sh" => { original => "conf/lio_start.default", config => 1, mode => 700}, "$py_inst_dir/tcm_node.py" => { original => "tcm-py/tcm_node.py", mode => 755}, "$py_inst_dir/tcm_pscsi.py" => { original => "tcm-py/tcm_pscsi.py", mode => 755}, "$py_inst_dir/tcm_iblock.py" => { original => "tcm-py/tcm_iblock.py", mode => 755}, "$py_inst_dir/tcm_fileio.py" => { original => "tcm-py/tcm_fileio.py", mode => 755}, "$py_inst_dir/tcm_ramdisk.py" => { original => "tcm-py/tcm_ramdisk.py", mode => 755}, "$py_inst_dir/tcm_dump.py" => { original => "tcm-py/tcm_dump.py", mode => 755}, "$py_inst_dir/tcm_fabric.py" => { original => "tcm-py/tcm_fabric.py", mode => 755}, "/sbin/iscsi-name" => { original => "tools/iscsi-name", mode => 755}, "$py_inst_dir/lio_node.py" => { original => "lio-py/lio_node.py", mode => 755}, "$py_inst_dir/lio_dump.py" => { original => "lio-py/lio_dump.py", mode => 755}, }; $iscsid->{post} .= "if [ ! -h /usr/sbin/tcm_node ]; then ln -s $py_inst_dir/tcm_node.py /usr/sbin/tcm_node; fi; "; $iscsid->{post} .= "if [ ! -h /usr/sbin/tcm_dump ]; then ln -s $py_inst_dir/tcm_dump.py /usr/sbin/tcm_dump ; fi; "; $iscsid->{post} .= "if [ ! -h /usr/sbin/tcm_fabric ]; then ln -s $py_inst_dir/tcm_fabric.py /usr/sbin/tcm_fabric ; fi; "; $iscsid->{post} .= "if [ ! -h /usr/sbin/lio_node ]; then ln -s $py_inst_dir/lio_node.py /usr/sbin/lio_node ; fi;"; $iscsid->{post} .= "if [ ! -h /usr/sbin/lio_dump ]; then ln -s $py_inst_dir/lio_dump.py /usr/sbin/lio_dump ; fi;"; $iscsid->{preun} .= "if [ \"$1\" = \"0\" ] ; then "; $iscsid->{preun} .= " unlink /usr/sbin/tcm_node ;"; $iscsid->{preun} .= " unlink /usr/sbin/tcm_dump ;"; $iscsid->{preun} .= " unlink /usr/sbin/tcm_fabric ;"; $iscsid->{preun} .= " unlink /usr/sbin/lio_node ;"; $iscsid->{preun} .= " unlink /usr/sbin/lio_dump ;"; $iscsid->{preun} .= "fi; "; $iscsid->{python_obj} = "$py_inst_dir/*.py*"; if ($ostype->{DISTRO} eq "SUSE") { # $iscsid->{files} -> { "/etc/init.d/target" } = # { original => "ipyxd/scripts/suse.target", mode => 755}; # $iscsid->{files} -> { "/sbin/target-ctl" } = # { original => "ipyxd/scripts/target-ctl.wrapper", mode => 755}; $iscsid->{post} .= "insserv target\n"; # no longer set up autostart $iscsid->{preun} .= "insserv -r target\n"; } elsif ($ostype->{DISTRO} =~ /REDHAT|CENTOS|FEDORA|MANDRAKE|ELINOS/) { # $iscsid->{files} -> { "/etc/init.d/target" } = # { original => "ipyxd/scripts/rc.target", mode => 755}; # $iscsid->{files} -> { "/sbin/target-ctl" } = # { original => "ipyxd/scripts/target-ctl.wrapper", mode => 755}; # $iscsid->{post} .= # no longer set up autostart # "chkconfig --add target\n". # "chkconfig target on\n"; $iscsid->{preun} .= "chkconfig target off\n". "chkconfig --del target\n"; } elsif ($ostype->{DISTRO} =~ /GENTOO/) { $iscsid->{files} -> { "/etc/init.d/target" } = { original => "ipyxd/scripts/gentoo.target", mode => 755}; $iscsid->{files} -> { "/sbin/target.sh" } = { original => "ipyxd/scripts/rc.target", mode => 755}; $iscsid->{files} -> { "/sbin/target-ctl" } = { original => "ipyxd/scripts/target-ctl.wrapper", mode => 755}; # $iscsid->{post} .= # "ln -s /etc/init.d/target /etc/runlevels/default/target\n"; $iscsid->{preun} .= "rm -f /etc/runlevels/default/target\n"; } make_rpm($iscsid); } sub make_isns_client_rpm { my $ostype = ostype($options->{root_dir}); ISNS_VERSION(); my $target_files = {"/sbin/isnsc" => { original => ".", mode => 755}, "/sbin/isns_". "{register,deregister,reregister,iscsi_index,nodes,is_node_registered,". "network_portals,update_portals,client,initiators}" => { original => "scripts", mode => 755}, "/sbin/isns_". "{create_dd,delete_dd,". "add_node_to_dd,remove_node_from_dd,list_dd_all,list_dd_members,create_dds,". "delete_dds,enable_dds,disable_dds,add_dd_to_dds,remove_dd_from_dds,list_dds_all,". "list_dds_members,is_control_node,list_node_detail,". "list_nodes_all,". "save_config}" => { original => "scripts", mode => 755}, "/var/{spool,log}/isns" => { dir=>1, mode=>755}, }; # # my $initiator_files = { "/sbin/isnsc" => { original => ".", # mode => 755}, # "/sbin/isns_". # "{register,deregister,reregister,iscsi_index,nodes,is_node_registered,". # "network_portals,update_portals,client,initiators}" => { original => "scripts", # mode => 755}, # # "/var/{spool,log}/isns" => { dir=>1, # mode=>755}, # # }; # if ($ostype->{DISTRO} eq "SUSE") # { # $initiator_files -> {"/etc/init.d/initiator_isns"} = { original => "sysvinit/suse.initiator_isns", # mode => 755, # config =>1}; # $target_files -> {"/etc/init.d/target_isns"} = { original => "sysvinit/suse.target_isns", # mode => 755, # config =>1}; # # } # else # { # $initiator_files -> {"/etc/init.d/initiator_isns"} = { original => "sysvinit/redhat.initiator_isns", # mode => 755, # config =>1}; # $target_files -> {"/etc/init.d/target_isns"} = { original => "sysvinit/redhat.target_isns", # # mode => 755, # config =>1}; # # } make_rpm({ name => "lio-isns-control-client", product_name => "Linux-iSCSI.org iSNS control client toolkit", version => $env->{ISNS_VERSION}, release => 1, group => "Linux-iSCSI.org/iSNS (isnsclient,applications)", files => $target_files}); } sub make_isns_server_rpm { my $ostype = ostype($options->{root_dir}); ISNS_VERSION(); my $server = { name => "lio-isns-server", product_name => "Linux-iSCSI.org iSNS Server Toolkit for iSCSI Control Node", version => $env->{ISNS_VERSION}, release => 1, group => "Linux-iSCSI.org/Name Server (isnsserver,applications)", files => {"/sbin/isnss" => { original => ".", mode => 755}, "/etc/sysconfig/isnsserver.conf" => { original => "sysvinit", mode=>644, config=>1}, "/var/{spool,log}/isns" => { dir=>1, mode=>755}, }, }; if ($ostype->{DISTRO} eq "SUSE") { $server->{files}->{"/etc/init.d/isnsserver"} = { original => "sysvinit/suse.isnsserver", mode => 755}; # $server->{post} .= "insserv isnsserver\n"; # no longer set up autostart $server->{preun} .= "insserv -r isnsserver\n"; } elsif ($ostype->{DISTRO} =~ /REDHAT|CENTOS|FEDORA|MANDRAKE|ELINOS/) { $server->{files}->{"/etc/init.d/isnsserver"} = { original => "sysvinit/redhat.isnsserver", mode => 755}; # $iscsid->{post} .= # no longer set up autostart # "chkconfig --add isnsserver\n". # "chkconfig isnsserver on\n"; $server->{preun} .= "chkconfig isnsserver off\n". "chkconfig --del isnsserver\n"; } elsif ($ostype->{DISTRO} =~ /GENTOO/) { $server->{files}->{"/etc/init.d/isnsserver"} = { original => "sysvinit/redhat.isnsserver", mode => 755}; } make_rpm($server); } sub make_mibs_rpm { my $mibfile = "/usr/lib/snmp/dlmod/iscsiTargetMib.so"; LIO_VERSION(); my $snmpconf = "/etc/snmpd.conf"; $snmpconf = "/etc/snmpd/snmpd.conf" if ( -e "/etc/snmpd/snmpd.conf"); my $rpm = { name => "lio-mibs", product_name => "LIO's Target SCSI and iSCSI MIB file(s)", version => $env->{LIO_UTILS_VERSION}, release => $env->{LIO_UTILS_REV}, group => "TCM and LIO-Target (mibs,$ostype->{ARCH},libraries)", files => { $mibfile => { original => "mib-modules"}, "/etc/iscsi/setup_snmpd" => { original => "mib-modules"}, "/usr/share/snmp/mibs/LIO-{ISCSI,SCSI,IPS-AUTH}-MIB.txt" => { original =>"mib-modules/mibs"}, }, post => "/etc/iscsi/setup_snmpd install\n", preun => "if [ \$1 -eq 0 ]; then /etc/iscsi/setup_snmpd uninstall; fi\n", }; make_rpm($rpm); } sub make_rpm { my $rpm = shift @_; my $arch = shift @_; my $ostype = ostype($options->{root_dir}); $ostype->{RPM_DIR} = "$options->{root_dir}$ostype->{RPM_DIR}" if ($ostype->{BASENAME} =~ /^ELinos/); my $specfile = "$ostype->{RPM_DIR}/SPECS/$rpm->{name}-$rpm->{version}.spec"; my $build_dir = "$ostype->{RPM_DIR}/BUILD/$rpm->{name}-$rpm->{version}"; $arch = $ostype->{ARCH} if ($arch eq ""); open(SPECFILE, ">$specfile") || die "Could not create $specfile"; print SPECFILE "Summary: $rpm->{product_name}\n". "Name: $rpm->{name}\n". "Version: $rpm->{version}\n". "Release: $rpm->{release}\n". "Group: $rpm->{group}\n". "Source: $rpm->{name}.tar.bz2\n". "Distribution: $ostype->{SYSTEM} with kernel $ostype->{RELEASE}\n". "License: $rpm->{product_name}, GPL\n"; # Determine rpmbuild version for BUILDROOT usage in make_rpm() my $rpmbuild_ver = `rpmbuild --version`; my $rpmbuild_major_ver = $rpmbuild_ver; $rpmbuild_major_ver =~ s/^.*?.([0-9]+).*/$1/; my $rpmbuild_minor_ver = $rpmbuild_ver; $rpmbuild_minor_ver =~ s/^.*?\.([0-9]+).*/$1/; my $rpmbuild_legacy = 0; # RHEL 5.x and SLES 11 both use RPM version 4.4.2.3. # For RHEL/CentOS 5.x, we need to set $rpmbuild_legacy, but for SLES 11 # $rpmbuild_legacy currently needs to be disabled with version 4.4.2.3. # # Fedora 11 and OpenSuse 11 use RPM version 4.7.1, and will new the non legacy method if (($rpmbuild_major_ver <= 4) && ($rpmbuild_minor_ver <= 4)) { if (!(lc($ostype->{SYSTEM}) =~ /sles11/)) { print "Setting rpmbuild_legacy=1 for $ostype->{SYSTEM}\n"; $rpmbuild_legacy = 1; } } my $buildroot = ""; if ($rpmbuild_legacy eq 1) { print SPECFILE "Buildroot: ${build_dir}\n"; } else { print SPECFILE "Buildroot: ${build_dir}-root\n"; $buildroot .= "${build_dir}-root"; } print SPECFILE "Prereq: $rpm->{prereqs}\n" unless ($rpm->{prereqs} eq ""); print SPECFILE "%post \n$rpm->{post}\n" unless ($rpm->{post} eq ""); print SPECFILE "%preun \n$rpm->{preun}\n" unless ($rpm->{preun} eq ""); print SPECFILE "%pre \n$rpm->{pre}\n" unless ($rpm->{pre} eq ""); print SPECFILE "%define debug_package %{nil}\n". "\n". "%description\n". "$rpm->{product_name} for $ostype->{SYSTEM}\n". "%prep\n". "%setup -q\n". "%build\n"; if ($rpmbuild_legacy ne 1) { print SPECFILE "%install\n". "cp -ra ${build_dir}/. ${build_dir}-root/.\n"; } print SPECFILE "%files\n"; system("rm -fr $build_dir"); foreach my $file ( sort keys %{$rpm->{files}} ) { my $orig = $rpm->{files}->{$file}->{original}; my @files; if ($file =~ /(.*?){(.*?)}(.*)/) { my $prefix = $1; my $postfix = $3; my @items = split(/,/,$2); foreach my $item ( @items ) { push @files, "$prefix$item$postfix"; } } else { push @files, $file; } foreach my $expanded_file ( @files ) { my $orig_expanded_file = $expanded_file; unless ($orig eq "") { my $real_orig = $orig; if ((-d $orig) && (! -d "$orig/$expanded_file") ) { $real_orig .= "/" . basename($expanded_file); } if ( -e $real_orig ) { system("mkdir -p $build_dir/" . dirname($expanded_file)); if (system("cp -rav $real_orig $build_dir/$expanded_file")!=0) { die "Could not copy from $real_orig\n"; } } } unless ($rpm->{files}->{$file}->{mode} eq "") { if ($ostype->{DISTRO} eq "MANDRAKE") { system("chmod $rpm->{files}->{$file}->{mode} $build_dir/$expanded_file"); } else { system("chmod -v $rpm->{files}->{$file}->{mode} $build_dir/$expanded_file"); } } if (defined $rpm->{files}->{$file}->{compress}) { system("gzip -9 $build_dir/$expanded_file"); if ($ostype->{DISTRO} eq "MANDRAKE") { $expanded_file .= ".bz2"; } else { $expanded_file .= ".gz"; } } if (defined $rpm->{files}->{$file}->{dir}) { `mkdir -p $build_dir/$expanded_file`; $expanded_file = "%dir $expanded_file"; } if (defined $rpm->{files}->{$file}->{config}) { $expanded_file = "%config $expanded_file"; } if ( -e "$build_dir/$orig_expanded_file" || (defined $rpm->{files}->{$file}->{compress} && -e "$build_dir/${orig_expanded_file}.gz")) { print SPECFILE "$expanded_file\n"; } else { print "Skipping: $build_dir/$expanded_file\n"; } } } print SPECFILE "$rpm->{python_obj}\n"; close SPECFILE; $build_dir .= "/." if ($ostype->{NO_RPM} || $options->{NO_RPM}); system("tar cfj $ostype->{RPM_DIR}/SOURCES/$rpm->{name}.tar.bz2 -C " . dirname($build_dir) . " " . basename($build_dir) ); if ($ostype->{NO_RPM} || $options->{NO_RPM}) { if ($arch ne "") { system ("mkdir $ostype->{RPM_DIR}/RPMS/$arch") unless (-e "$ostype->{RPM_DIR}/RPMS/$arch"); system("mv $ostype->{RPM_DIR}/SOURCES/$rpm->{name}.tar.bz2 $ostype->{RPM_DIR}/RPMS/$arch/$rpm->{name}.$arch.tar.bz2"); } else { system("mv $ostype->{RPM_DIR}/SOURCES/$rpm->{name}.tar.bz2 $ostype->{RPM_DIR}/RPMS"); } } else { my $rpmbuild_op = "rpmbuild --target $arch -bb -vv $specfile"; if ($rpmbuild_legacy ne 1) { $rpmbuild_op .= " --buildroot $buildroot"; } die "RPM build failure: $rpmbuild_op" if (system($rpmbuild_op)!=0); } } sub main { my @args = setup(@_); my $cmd = shift @args; for ($cmd) { if (/^$/) { dump_config(); last; } elsif (/^make_target_kernel_rpm$/) { make_target_kernel_rpm(@args); last; } elsif (/^make_target_user_rpm$/) { make_target_user_rpm(@args); last; } elsif (/^make_isns_client_rpm$/) { make_isns_client_rpm(); last; } elsif (/^make_isns_server_rpm$/) { make_isns_server_rpm(); last; } elsif (/^make_mibs_rpm$/) { make_mibs_rpm(@args); last; } } } main(@ARGV); exit(0); lio-utils-3.1+git2.fd0b34fd/get-py-modules-path.py0000755000175000017500000000040311753136721020015 0ustar rrsrrs#!/usr/bin/python from distutils.sysconfig import get_python_lib,re; str = get_python_lib() # Fix up get_python_lib() path for Python v2.6 on Ubuntu 9.10 and SLES 11 if re.search('python2.6', str): print str.replace('/usr','/usr/local') else: print str; lio-utils-3.1+git2.fd0b34fd/lio-py/0000755000175000017500000000000011753136721015047 5ustar rrsrrslio-utils-3.1+git2.fd0b34fd/lio-py/lio_dump.py0000755000175000017500000002135311753136721017240 0ustar rrsrrs#!/usr/bin/python import os, sys import subprocess as sub import string import re import datetime, time from optparse import OptionParser lio_root = "/sys/kernel/config/target/iscsi" def lio_target_configfs_dump(option, opt_str, value, parser): if not os.path.isdir(lio_root): print "Unable to access lio_root: " + lio_root sys.exit(1) iqn_root = os.listdir(lio_root) # This will load up iscsi_target_mod.ko print "mkdir " + lio_root print "#### iSCSI Discovery authentication information" auth_dir = lio_root + "/discovery_auth" if os.path.isdir(auth_dir) == True: for auth in os.listdir(auth_dir): if auth == "authenticate_target": continue auth_file = auth_dir + "/" + auth p = os.open(auth_file, 0) value = os.read(p, 256) ret = value.isspace() if ret: os.close(p) continue print "echo -n " + value.rstrip() + " > " + auth_file os.close(p) iqn_root = os.listdir(lio_root) # Loop through LIO-Target IQN list for iqn in iqn_root: if iqn == "lio_version": continue if iqn == "discovery_auth": continue # Loop through LIO-Target IQN+TPGT list tpg_root = os.listdir(lio_root + "/" + iqn); for tpgt_tmp in tpg_root: if tpgt_tmp == "fabric_statistics": continue tpgt_tmp2 = tpgt_tmp.split('_') tpgt = tpgt_tmp2[1] print "#### Network portals for iSCSI Target Portal Group" np_root = os.listdir(lio_root + "/" + iqn + "/tpgt_" + tpgt + "/np") for np in np_root: print "mkdir -p " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/np/" + np print "#### iSCSI Target Ports" lun_root = os.listdir(lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun") for lun_tmp in lun_root: lun_tmp2 = lun_tmp.split('_') lun = lun_tmp2[1] lun_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun print "mkdir -p " + lun_dir port_root = os.listdir(lun_dir) for port in port_root: if port == "alua_tg_pt_gp": continue if port == "alua_tg_pt_offline": continue if port == "alua_tg_pt_status": continue if port == "alua_tg_pt_write_md": continue if not os.path.islink(lun_dir + "/" + port): continue port_link = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun + "/" + port sourcelink = os.readlink(port_link) sourcelink2 = os.path.join(os.path.dirname(port_link), sourcelink) print "ln -s " + sourcelink2 + " " + port_link # Dump ALUA Target Port Group tg_pt_gp_file = lun_dir + "/alua_tg_pt_gp" p = os.open(tg_pt_gp_file, 0) try: value = os.read(p, 512) except: os.close(p) continue os.close(p) if value: tg_pt_gp_tmp = value.split('\n') tg_pt_gp_out = tg_pt_gp_tmp[0] off = tg_pt_gp_out.index('Alias: ') off += 7 # Skip over "Alias: " tg_pt_gp_name = tg_pt_gp_out[off:] # Only need to dump if LIO-Target Port is NOT partof # the 'default_tg_pt_gp' if not re.search(tg_pt_gp_name, 'default_tg_pt_gp'): print "#### ALUA Target Port Group" print "echo " + tg_pt_gp_name + " > " + tg_pt_gp_file print "lio_node --aluasecmd " + iqn + " " + tpgt + " " + lun # Dump values of iscsi/iqn/tpgt/attrib/ print "#### Attributes for iSCSI Target Portal Group" attrib_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/attrib/" attrib_root = os.listdir(attrib_dir) for attrib in attrib_root: attrib_file = attrib_dir + attrib p = os.open(attrib_file, 0) value = os.read(p, 16) print "echo " + value.rstrip() + " > " + attrib_file os.close(p) # Dump values of iscsi/iqn/tpgt/attrib/ print "#### authentication for iSCSI Target Portal Group" auth_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/auth/" if os.path.isdir(auth_dir): auth_root = os.listdir(auth_dir) for auth in auth_root: auth_file = auth_dir + auth p = os.open(auth_file, 0) value = os.read(p, 256) ret = value.isspace() if ret: os.close(p) continue print "echo -n " + value.rstrip() + " > " + auth_file os.close(p) # Dump values for iscsi/iqn/tpgt/param print "#### Parameters for iSCSI Target Portal Group" param_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/param/" param_root = os.listdir(param_dir) for param in param_root: param_file = param_dir + param p = os.open(param_file, 0) value = os.read(p, 256) print "echo \"" + value.rstrip() + "\" > " + param_file os.close(p) # Dump iSCSI Initiator Node ACLs from iscsi/iqn/tpgt/acls print "#### iSCSI Initiator ACLs for iSCSI Target Portal Group" nacl_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" nacl_root = os.listdir(nacl_dir) for nacl in nacl_root: print "mkdir -p " + nacl_dir + nacl tcq_depth_file = nacl_dir + nacl + "/cmdsn_depth" p = os.open(tcq_depth_file, 0) value = os.read(p, 8) print "echo " + value.rstrip() + " > " + tcq_depth_file os.close(p) # Dump iSCSI Initiator ACL authentication info from iscsi/iqn/tpgt/acls/$INITIATOR/auth print "#### iSCSI Initiator ACL authentication information" auth_dir = nacl_dir + nacl + "/auth" for auth in os.listdir(auth_dir): if auth == "authenticate_target": continue auth_file = auth_dir + "/" + auth p = os.open(auth_file, 0) value = os.read(p, 256) ret = value.isspace() if ret: os.close(p) continue print "echo -n " + value.rstrip() + " > " + auth_file os.close(p) # Dump iSCSI Initiator ACL TPG attributes from iscsi/iqn/tpgt/acls/$INITIATOR/attrib print "#### iSCSI Initiator ACL TPG attributes" nacl_attrib_dir = nacl_dir + nacl + "/attrib" for nacl_attrib in os.listdir(nacl_attrib_dir): nacl_attrib_file = nacl_attrib_dir + "/" + nacl_attrib p = os.open(nacl_attrib_file, 0) value = os.read(p, 8) print "echo " + value.rstrip() + " > " + nacl_attrib_file os.close(p) # Dump iSCSI Initiator LUN ACLs from iscsi/iqn/tpgt/acls/$INITIATOR/lun print "#### iSCSI Initiator LUN ACLs for iSCSI Target Portal Group" lun_acl_dir = nacl_dir + nacl for lun_acl in os.listdir(lun_acl_dir): ret = re.search('lun_', lun_acl) if not ret: continue lun_link_dir = nacl_dir + nacl + "/" + lun_acl print "mkdir -p " + lun_link_dir for lun_acl_link in os.listdir(lun_link_dir): if lun_acl_link == "write_protect": p = os.open(lun_link_dir + "/write_protect", 0) value = os.read(p, 4) print "echo " + value.rstrip() + " > " + lun_link_dir + "/write_protect" os.close(p) continue if not os.path.islink(lun_link_dir + "/" + lun_acl_link): continue sourcelink = os.readlink(lun_link_dir + "/" + lun_acl_link) sourcelink2 = os.path.join(os.path.dirname(lun_link_dir + "/" + lun_acl_link), sourcelink) print "ln -s " + sourcelink2 + " " + lun_link_dir + "/" + lun_acl_link # Dump value of iscsi/iqn/tpgt/enable print "#### Trigger to enable iSCSI Target Portal Group" enable_file = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/enable" p = os.open(enable_file, 0) value = os.read(p, 1) print "echo " + value.rstrip() + " > " + enable_file os.close(p) # lio_target_del_iqn(None, None, iqn, None) return def lio_backup_to_file(option, opt_str, value, parser): now = str(value) if not os.path.isdir(lio_root): print "Unable to access lio_root: " + lio_root sys.exit(1) backup_dir = "/etc/target/backup" if not os.path.isdir(backup_dir): op = "mkdir " + backup_dir ret = os.system(op) if ret: print "Unable to open backup_dir" sys.exit(1) op = "lio_dump --stdout" p = sub.Popen(op, shell=True, stdout=sub.PIPE).stdout if not p: print "Unable to dump LIO-Target/ConfigFS running state" sys.exit(1) print "Making backup of LIO-Target/ConfigFS with timestamp: " + now backup_file = backup_dir + "/lio_backup-" + now + ".sh" if os.path.isfile(backup_file): print "LIO-Target backup_file: " + backup_file + "already exists, exiting" p.close() sys.exit(1) back = open(backup_file, 'w') line = p.readline() while line: print >>back, line.rstrip() line = p.readline() p.close() back.close() return backup_file def main(): parser = OptionParser() parser.add_option("--s","--stdout", action="callback", callback=lio_target_configfs_dump, nargs=0, help="Dump running LIO-Target/ConfigFS syntax to STDOUT") parser.add_option("--t", "--tofile", action="callback", callback=lio_backup_to_file, nargs=1, type="string", dest="DATE_TIME", help="Backup running LIO-Target/ConfigFS syntax to /etc/target/backup/lio_backup-.sh") (options, args) = parser.parse_args() if len(sys.argv) == 1: parser.print_help() sys.exit(0) elif not re.search('--', sys.argv[1]): print "Unknown CLI option: " + sys.argv[1] sys.exit(1) if __name__ == "__main__": main() lio-utils-3.1+git2.fd0b34fd/lio-py/lio_node.py0000755000175000017500000013757311753136721017234 0ustar rrsrrs#!/usr/bin/python import os, sys import subprocess as sub import string import re from optparse import OptionParser tcm_root = "/sys/kernel/config/target/core" lio_root = "/sys/kernel/config/target/iscsi" alua_secondary_md_dir = "/var/target/alua/iSCSI/" def lio_err(msg): print msg sys.exit(1) def lio_alua_check_secondary_md(iqn, tpgt): alua_sec_md_path = alua_secondary_md_dir + iqn + "+" + tpgt + "/" if os.path.isdir(alua_sec_md_path) == False: mkdir_op = "mkdir -p " + alua_sec_md_path ret = os.system(mkdir_op) if ret: lio_err("Unable to create secondary ALUA MD directory: " + alua_sec_md_path) return def lio_alua_delete_secondary_md(iqn, tpgt): alua_sec_md_path = alua_secondary_md_dir + iqn + "+" + tpgt + "/" if os.path.isdir(alua_sec_md_path) == False: return rm_op = "rm -rf " + alua_sec_md_path ret = os.system(rm_op) if ret: lio_err("Unable to remove secondary ALUA MD directory: " + alua_sec_md_path) return def lio_alua_delete_secondary_md_port(iqn, tpgt, lun): alua_sec_md_file = alua_secondary_md_dir + iqn + "+" + tpgt + "/lun_" + lun if os.path.isfile(alua_sec_md_file) == False: return rm_op = "rm -rf "+ alua_sec_md_file ret = os.system(rm_op) if ret: lio_err("Unable to delete ALUA secondary metadata file: " + alua_sec_md_file) return def lio_alua_set_secondary_write_md(iqn, tpgt, lun): alua_write_md_file = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun + "/alua_tg_pt_write_md" if os.path.isfile(alua_write_md_file) == False: return p = open(alua_write_md_file, 'w') if not p: lio_err("Unable to open: " + alua_write_md_file) ret = p.write("1") if ret: lio_err("Unable to enable writeable ALUA secondary metadata for " + alua_write_md_file) p.close() return def lio_alua_process_secondary_md(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); lun = str(value[2]); alua_sec_md_file = alua_secondary_md_dir + iqn + "+" + tpgt + "/lun_" + lun if os.path.isfile(alua_sec_md_file) == False: # Use --aluasecmd as a chance to make sure the directory for this # LIO-Target endpoint (iqn+tpgt) exists.. lio_alua_check_secondary_md(iqn, tpgt) lio_alua_set_secondary_write_md(iqn, tpgt, lun) lio_err("Unable to locate ALUA secondary metadata file: " + alua_sec_md_file) return # print "Using alua_sec_md_file: " + alua_sec_md_file alua_sec_cfs_path = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun # print "Using alua_sec_cfs_path: " + alua_sec_cfs_path p = open(alua_sec_md_file, 'rU') if not p: print "Unable to process ALUA secondary metadata for: " + alua_sec_md_file line = p.readline() while line: buf = line.rstrip() if re.search('alua_tg_pt_offline=', buf): alua_tg_pt_offline = buf[19:] # print "Extracted alua_tg_pt_offline: " + alua_tg_pt_offline cfs = open(alua_sec_cfs_path + "/alua_tg_pt_offline", 'w') if not cfs: p.close() lio_err("Unable to open " + alua_sec_cfs_path + "/alua_tg_pt_offline") ret = cfs.write(alua_tg_pt_offline) cfs.close() if ret: p.close() lio_err("Unable to write " + alua_sec_cfs_path + "/alua_tg_pt_offline") elif re.search('alua_tg_pt_status=', buf): alua_tg_pt_status = buf[18:] # print "Extracted alua_tg_pt_status: " + alua_tg_pt_status cfs = open(alua_sec_cfs_path + "/alua_tg_pt_status", 'w') if not cfs: p.close() lio_err("Unable to open " + alua_sec_cfs_path + "/alua_tg_pt_status") ret = cfs.write(alua_tg_pt_status) cfs.close() if ret: p.close() lio_err("Unable to write " + alua_sec_cfs_path + "/alua_tg_pt_status") line = p.readline() p.close() # Now enable the alua_tg_pt_write_md bit to allow for new updates # to ALUA secondary metadata in struct file for this port lio_alua_set_secondary_write_md(iqn, tpgt, lun) return def __lio_target_del_iqn(option, opt_str, value, parser, delete_tpg_md): iqn = str(value); iqn = iqn.lower(); # Loop through LIO-Target IQN+TPGT list tpg_root = os.listdir(lio_root + "/" + iqn); for tpgt_tmp in tpg_root: if tpgt_tmp == "fabric_statistics": continue tpgt_tmp2 = tpgt_tmp.split('_') tpgt = tpgt_tmp2[1] tpg_val = [iqn,tpgt] if delete_tpg_md == 1: lio_target_del_tpg(None, None, tpg_val, None) else: __lio_target_del_tpg(None, None, tpg_val, None, 0) rmdir_op = "rmdir " + lio_root + "/" + iqn # print "rmdir_op: " + rmdir_op ret = os.system(rmdir_op) if not ret: print "Successfully released iSCSI Target Endpoint IQN: " + iqn else: lio_err("Unable to release iSCSI Target Endpoint IQN: " + iqn) return def lio_target_del_iqn(option, opt_str, value, parser): iqn = str(value); iqn = iqn.lower(); iqn_dir = lio_root + "/" + iqn if os.path.isdir(iqn_dir) == False: lio_err("Unable to locate iSCSI Target IQN: " + iqn_dir) # Passing 1 for delete_tpg_md here means lio_target_del_tpg() # with lio_alua_delete_secondary_md() will get called to delete # all of the secondary ALUA directories for the LIO-Target endpoint # when an explict --deliqn is called. __lio_target_del_iqn(option, opt_str, value, parser, 1) return def __lio_target_del_tpg(option, opt_str, value, parser, delete_tpg_md): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); # This will set TPG Status to INACTIVE force all of the iSCSI sessions for this # tiqn+tpgt tuple to be released. disable_op = "echo 0 > " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/enable" ret = os.system(disable_op) if ret: print "Unable to disable TPG: " + iqn + " TPGT: " + tpgt np_root = os.listdir(lio_root + "/" + iqn + "/tpgt_" + tpgt + "/np") for np in np_root: np_val = [iqn,tpgt,np] lio_target_del_np(None, None, np_val, None) nacl_root = os.listdir(lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls") for nacl in nacl_root: nacl_val = [iqn,tpgt,nacl] lio_target_del_nodeacl(None, None, nacl_val, None) lun_root = os.listdir(lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun") for lun_tmp in lun_root: lun_tmp2 = lun_tmp.split('_') lun = lun_tmp2[1] lun_val = [iqn,tpgt,lun] if delete_tpg_md == 1: lio_target_del_port(None, None, lun_val, None) else: __lio_target_del_port(None, None, lun_val, None) rmdir_op = "rmdir " + lio_root + "/" + iqn + "/tpgt_" + tpgt # print "rmdir_op: " + rmdir_op ret = os.system(rmdir_op) if not ret: print "Successfully released iSCSI Target Portal Group: " + iqn + " TPGT: " + tpgt else: lio_err("Unable to release iSCSI Target Portal Group: " + iqn + " TPGT: " + tpgt) return def lio_target_del_tpg(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); tpgt_file = lio_root + "/" + iqn + "/tpgt_" + tpgt if os.path.isdir(tpgt_file) == False: lio_err("iSCSI Target Port Group: " + tpgt_file + " does not exist") __lio_target_del_tpg(option, opt_str, value, parser, 1) # Delete the ALUA secondary metadata directory on explict --deltpg or # called from --deliqn lio_alua_delete_secondary_md(iqn, tpgt) return def lio_target_add_np(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); np = str(value[2]); # Append default iSCSI Port is non is given. if re.search(']', np)and not re.search(']:', np): np = np + ":3260" elif re.search(':\\Z', np): np = np + "3260" elif not re.search(':', np): np = np + ":3260" # Extract the iSCSI port and make sure it is a valid u16 value if re.search(']:', np): off = np.index(']:') off += 2 port = int(np[off:]) else: off = np.index(':') off += 1 port = int(np[off:]) if port == 0 or port > 65535: lio_err("Illegal port value: " + str(port) + " for iSCSI network portal") mkdir_op = "mkdir -p " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/np/" + np # print "mkdir_op: " + mkdir_op ret = os.system(mkdir_op) if not ret: print "Successfully created network portal: " + np + " created " + iqn + " TPGT: " + tpgt lio_alua_check_secondary_md(iqn, tpgt) else: lio_err("Unable to create network portal: " + np + " created " + iqn + " TPGT: " + tpgt) return def lio_target_del_np(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); np = str(value[2]); rmdir_op = "rmdir " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/np/" + np # print "rmdir_op: " + rmdir_op ret = os.system(rmdir_op) if not ret: print "Successfully released network portal: " + np + " created " + iqn + " TPGT: " + tpgt else: lio_err("Unable to release network portal: " + np + " created " + iqn + " TPGT: " + tpgt) return def lio_target_add_port(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); lun = str(value[2]); port_name = str(value[3]); tcm_obj = str(value[4]); lun_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun if os.path.isdir(lun_dir): lio_err("iSCSI Target Logical Unit ConfigFS directory already exists") mkdir_op = "mkdir -p " + lun_dir # print "mkdir_op: " + mkdir_op ret = os.system(mkdir_op) if ret: lio_err("Unable to create iSCSI Target Logical Unit ConfigFS directory") port_src = tcm_root + "/" + tcm_obj port_dst = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun + "/" + port_name link_op = "ln -s " + port_src + " " + port_dst # print "link_op: " + link_op ret = os.system(link_op) if not ret: print "Successfully created iSCSI Target Logical Unit" lio_alua_check_secondary_md(iqn, tpgt) lio_alua_set_secondary_write_md(iqn, tpgt, lun) else: os.rmdir(lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun) lio_err("Unable to create iSCSI Target Logical Unit symlink") return def lio_target_add_tpg(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); tpg_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt if os.path.isdir(tpg_dir): lio_err("iSCSI Target Portal Group directory already exists") mkdir_op = "mkdir -p " + tpg_dir ret = os.system(mkdir_op) if ret: lio_err("Unable to create iSCSI Target Portal Group ConfigFS directory") else: print "Successfully created iSCSI Target Portal Group" lio_alua_check_secondary_md(iqn, tpgt) return def __lio_target_del_port(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); lun = str(value[2]); lun_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun port_root = os.listdir(lun_dir) for port in port_root: if port == "alua_tg_pt_gp": continue if port == "alua_tg_pt_offline": continue if port == "alua_tg_pt_status": continue if port == "alua_tg_pt_write_md": continue if not os.path.islink(lun_dir + "/" + port): continue unlink_op = lun_dir + "/" + port # print "del_portunlink_op: " + unlink_op ret = os.unlink(unlink_op) if ret: lio_err("Unable to unlink iSCSI Target Logical Unit") rmdir_op= "rmdir " + lun_dir # print "del_port rmdir_op: " + rmdir_op ret = os.system(rmdir_op); if not ret: print "Successfully deleted iSCSI Target Logical Unit" else: lio_err("Unable to rmdir iSCSI Target Logical Unit configfs directory") return def lio_target_del_port(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); lun = str(value[2]); lun_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun if os.path.isdir(lun_dir) == False: lio_err("LIO-Target Port/LUN directory: " + lun_dir + " does not exist") __lio_target_del_port(option, opt_str, value, parser) # Delete the ALUA secondary metadata file for this Port/LUN # during an explict --dellun lio_alua_delete_secondary_md_port(iqn, tpgt, lun) return def lio_target_tpg_disableauth(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); enable_op = "echo 0 > " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/attrib/authentication" ret = os.system(enable_op) if ret: lio_err("Unable to disable iSCSI Authentication on iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully disabled iSCSI Authentication on iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_tpg_demomode(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); enable_op = "echo 1 > " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/attrib/generate_node_acls" ret = os.system(enable_op) if ret: lio_err("Unable to disable Initiator ACL mode (Enable DemoMode) on iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully disabled Initiator ACL mode (Enabled DemoMode) on iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_disable_lunwp(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); mapped_lun = str(value[3]); disable_op = "echo 0 > " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/lun_" + mapped_lun + "/write_protect" ret = os.system(disable_op) if ret: lio_err("Unable to disable WriteProtect for Mapped LUN: " + mapped_lun + " for " + initiator_iqn + " on iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully disabled WRITE PROTECT for Mapped LUN: " + mapped_lun + " for " + initiator_iqn + " on iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_enable_auth(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); enable_op = "echo 1 > " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/attrib/authentication" ret = os.system(enable_op) if ret: lio_err("Unable to enable iSCSI Authentication on iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully enabled iSCSI Authentication on iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_enable_lunwp(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); mapped_lun = str(value[3]); enable_op = "echo 1 > " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/lun_" + mapped_lun + "/write_protect" ret = os.system(enable_op) if ret: lio_err("Unable to enable WriteProtect for Mapped LUN: " + mapped_lun + " for " + initiator_iqn + " on iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully enabled WRITE PROTECT for Mapped LUN: " + mapped_lun + " for " + initiator_iqn + " on iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_enable_tpg(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); enable_op = "echo 1 > " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/enable" ret = os.system(enable_op) if ret: lio_err("Unable to enable iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully enabled iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_disable_tpg(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); disable_op = "echo 0 > " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/enable" ret = os.system(disable_op) if ret: lio_err("Unable to disable iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully disabled iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_enableaclmode(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); enable_op = "echo 0 > " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/attrib/generate_node_acls" ret = os.system(enable_op) if ret: lio_err("Unable to enable Initiator ACL mode (Disabled DemoMode) on iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully enabled Initiator ACL mode (Disabled DemoMode) on iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_add_lunacl(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); tpg_lun = str(value[3]); mapped_lun = str(value[4]); mkdir_op = "mkdir -p " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/lun_" + mapped_lun ret = os.system(mkdir_op) if ret: lio_err("Unable to add iSCSI Initiator Mapped LUN: " + mapped_lun + " ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) addlunacl_op = "ln -s " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + tpg_lun + " " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/lun_" + mapped_lun + "/lio_lun" ret = os.system(addlunacl_op) if ret: lio_err("Unable to add iSCSI Initiator Mapped LUN: " + mapped_lun + " ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully added iSCSI Initiator Mapped LUN: " + mapped_lun + " ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt lio_alua_check_secondary_md(iqn, tpgt) return def lio_target_del_lunacl(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); mapped_lun = str(value[3]); lun_link_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/lun_" + mapped_lun for lun_acl_link in os.listdir(lun_link_dir): if lun_acl_link == "write_protect": continue if not os.path.islink(lun_link_dir + "/" + lun_acl_link): continue; unlink_op = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/lun_" + mapped_lun + "/" + lun_acl_link # print "unlink_op: " + unlink_op ret = os.unlink(unlink_op) if ret: lio_err("Unable to unlink iSCSI Initiator Mapped LUN: " + mapped_lun + " ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) dellunacl_op = "rmdir " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/lun_" + mapped_lun ret = os.system(dellunacl_op) if ret: lio_err("Unable to delete iSCSI Initiator Mapped LUN: " + mapped_lun + " ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully deleted iSCSI Initiator Mapped LUN: " + mapped_lun + " ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_add_nodeacl(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); addnodeacl_op = "mkdir -p " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn ret = os.system(addnodeacl_op) if ret: lio_err("Unable to add iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully added iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt lio_alua_check_secondary_md(iqn, tpgt) return def lio_target_del_nodeacl(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); nacl_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn lun_acl_root = os.listdir(nacl_dir) for lun_acl in lun_acl_root: ret = re.search('lun_', lun_acl) if not ret: continue lun_delacl_val = [iqn,tpgt,initiator_iqn,lun_acl[4:]] lio_target_del_lunacl(None, None, lun_delacl_val, None) delnodeacl_op = "rmdir " + nacl_dir ret = os.system(delnodeacl_op) if ret: lio_err("Unable to delete iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully deleted iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_set_chap_auth(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); user = str(value[3]); password = str(value[4]); auth_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/auth/" if not os.path.isdir(auth_dir): lio_err("iSCSI Initiator ACL " + initiator_iqn + " does not exist for iSCSI Target Portal Group: " + iqn + " " + tpgt) setuser_op = "echo -n " + user + " > " + auth_dir + "/userid" ret = os.system(setuser_op) if ret: lio_err("Unable to set CHAP username for iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) setpassword_op = "echo -n " + password + " > " + auth_dir + "/password" ret = os.system(setpassword_op) if ret: lio_err("Unable to set CHAP password for iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully set CHAP authentication for iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_set_chap_mutual_auth(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); user_mutual = str(value[3]); password_mutual = str(value[4]); auth_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/auth/" if not os.path.isdir(auth_dir): lio_err("iSCSI Initiator ACL " + initiator_iqn + " does not exist for iSCSI Target Portal Group: " + iqn + " " + tpgt) setuser_op = "echo -n " + user_mutual + " > " + auth_dir + "/userid_mutual" ret = os.system(setuser_op) if ret: lio_err("Unable to set mutual CHAP username for iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) setpassword_op = "echo -n " + password_mutual + " > " + auth_dir + "/password_mutual" ret = os.system(setpassword_op) if ret: lio_err("Unable to set mutual CHAP password for iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully set mutual CHAP authentication for iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_set_chap_discovery_auth(option, opt_str, value, parser): user = str(value[0]); password = str(value[1]); auth_dir = lio_root + "/discovery_auth" if not os.path.isdir(auth_dir): lio_err("iSCSI Discovery Authentication directory " + auth_dir + " does not exist") setuser_op = "echo -n " + user + " > " + auth_dir + "/userid" ret = os.system(setuser_op) if ret: lio_err("Unable to set CHAP username for iSCSI Discovery Authentication") setpassword_op = "echo -n " + password + " > " + auth_dir + "/password" ret = os.system(setpassword_op) if ret: lio_err("Unable to set CHAP password for iSCSI Discovery Authentication") else: print "Successfully set CHAP authentication for iSCSI Discovery Authentication" return def lio_target_set_chap_mutual_discovery_auth(option, opt_str, value, parser): user_mutual = str(value[0]); password_mutual = str(value[1]); auth_dir = lio_root + "/discovery_auth" if not os.path.isdir(auth_dir): lio_err("iSCSI Discovery Authentication directory " + auth_dir + " does not exist") setuser_op = "echo -n " + user_mutual + " > " + auth_dir + "/userid_mutual" ret = os.system(setuser_op) if ret: lio_err("Unable to set mutual CHAP username for iSCSI Discovery Authentication") setpassword_op = "echo -n " + password_mutual + " > " + auth_dir + "/password_mutual" ret = os.system(setpassword_op) if ret: lio_err("Unable to set mutual CHAP password for iSCSI Discovery Authentication") else: print "Successfully set mutual CHAP authentication for iSCSI Discovery Authentication" return def lio_target_set_enforce_discovery_auth(option, opt_str, value, parser): value = str(value); da_attr = lio_root + "/discovery_auth/enforce_discovery_auth" if not os.path.isfile(da_attr): lio_err("iSCSI Discovery Authentication directory does not exist") da_op = "echo " + value + " > " + da_attr; ret = os.system(da_op) if ret: lio_err("Unable to set da_attr: " + da_attr) if value == "1": print "Successfully enabled iSCSI Discovery Authentication enforcement" else: print "Successfully disabled iSCSI Discovery Authentication enforcement" return def lio_target_set_node_tcq(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); depth = str(value[3]); setnodetcq_op = "echo " + depth + " > " + lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/cmdsn_depth" ret = os.system(setnodetcq_op) if ret: lio_err("Unable to set TCQ: " + depth + " for iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt) else: print "Successfully set TCQ: " + depth + " for iSCSI Initaitor ACL " + initiator_iqn + " for iSCSI Target Portal Group: " + iqn + " " + tpgt return def lio_target_alua_set_tgptgp(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); lun = str(value[2]); tg_pt_gp_name = str(value[3]) lun_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun if not os.path.isdir(lun_dir): lio_err("LIO-Target Port/LUN: " + lun + " does not exist on: " + iqn + " " + tpgt) set_tp_pt_gp_op = "echo " + tg_pt_gp_name + " > " + lun_dir + "/alua_tg_pt_gp" ret = os.system(set_tp_pt_gp_op) if ret: lio_err("Unable to set ALUA Target Port Group: " + tg_pt_gp_name + " for LUN: " + lun + " on " + iqn + " " + tpgt) else: print "Successfully set ALUA Target Port Group: " + tg_pt_gp_name + " for LUN: " + lun + " on " + iqn + " " + tpgt return def lio_target_alua_set_tgpt_offline(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); lun = str(value[2]); lun_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun if not os.path.isdir(lun_dir): lio_err("LIO-Target Port/LUN: " + lun + " does not exist on: " + iqn + " " + tpgt) set_tg_pt_gp_offline_op = "echo 1 > " + lun_dir + "/alua_tg_pt_offline" ret = os.system(set_tg_pt_gp_offline_op) if ret: lio_err("Unable to set ALUA secondary state OFFLINE bit for LUN: " + lun + " on " + iqn + " " + tpgt) else: print "Successfully set ALUA secondary state OFFLINE for LUN: " + lun + " on " + iqn + " " + tpgt return def lio_target_alua_clear_tgpt_offline(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); lun = str(value[2]); lun_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun if not os.path.isdir(lun_dir): lio_err("LIO-Target Port/LUN: " + lun + " does not exist on: " + iqn + " " + tpgt) set_tg_pt_gp_offline_op = "echo 0 > " + lun_dir + "/alua_tg_pt_offline" ret = os.system(set_tg_pt_gp_offline_op) if ret: lio_err("Unable to clear ALUA secondary state OFFLINE for LUN: " + lun + " on " + iqn + " " + tpgt) else: print "Successfully cleared ALUA secondary state OFFLINE for LUN: " + lun + " on " + iqn + " " + tpgt return def lio_target_show_chap_auth(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); auth_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/auth/" if not os.path.isdir(auth_dir): lio_err("iSCSI Initiator ACL " + initiator_iqn + " does not exist for iSCSI Target Portal Group: " + iqn + " " + tpgt) for auth in os.listdir(auth_dir): p = os.open(auth_dir + "/" + auth, 0) value = os.read(p, 256) print auth + ": " + value.rstrip() os.close(p) return def lio_target_show_chap_discovery_auth(option, opt_str, value, parser): auth_dir = lio_root + "/discovery_auth" if not os.path.isdir(auth_dir): lio_err("iSCSI Discovery Authentication directory " + auth_dir + " does not exist") for auth in os.listdir(auth_dir): p = os.open(auth_dir + "/" + auth, 0) value = os.read(p, 256) print auth + ": " + value.rstrip() os.close(p) return def lio_target_show_node_tcq(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]); initiator_iqn = initiator_iqn.lower(); nacl = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn if not os.path.isdir(nacl): lio_err("iSCSI Initiator ACL: " + initiator_iqn + " does not exist for iSCSI Target Portal Group: " + iqn + " " + tpgt) tcq_depth_file = nacl + "/cmdsn_depth" p = os.open(tcq_depth_file, 0) value = os.read(p, 8) print value.rstrip() os.close(p) return def lio_target_alua_show_tgptgp(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); lun = str(value[2]); lun_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/lun/lun_" + lun if not os.path.isdir(lun_dir): lio_err("LIO-Target Port/LUN: " + lun + " does not exist on: " + iqn + " " + tpgt) show_tp_pt_gp_op = "cat " + lun_dir + "/alua_tg_pt_gp" ret = os.system(show_tp_pt_gp_op) if ret: lio_err("Unable to show ALUA Target Port Group: " + tg_pt_gp_name + " for LUN: " + lun + " on " + iqn + " " + tpgt) return def lio_target_list_endpoints(option, opt_str, value, parser): iqn_root = os.listdir(lio_root) for iqn in iqn_root: if iqn == "lio_version": continue if iqn == "discovery_auth": continue print "\------> " + iqn tpg_root = lio_root + "/" + iqn for tpg in os.listdir(tpg_root): if tpg == "fabric_statistics": continue p = os.open(tpg_root + "/" + tpg + "/param/TargetAlias", 0) value = os.read(p, 256) print " \-------> " + tpg + " TargetAlias: " + value.rstrip() os.close(p) print " TPG Status:", p = os.open(tpg_root + "/" + tpg + "/enable", 0) value = os.read(p, 8) enable_bit = value.rstrip(); if enable_bit == '1': print "ENABLED" else: print "DISABLED" os.close(p) print " TPG Network Portals:" np_root = tpg_root + "/" + tpg + "/np" for np in os.listdir(np_root): print " \-------> " + np print " TPG Logical Units:" lun_root = tpg_root + "/" + tpg + "/lun" for lun in os.listdir(lun_root): port_dir = lun_root + "/" + lun for port in os.listdir(port_dir): if port == "alua_tg_pt_gp": continue if port == "alua_tg_pt_offline": continue if port == "alua_tg_pt_status": continue if port == "alua_tg_pt_write_md": continue if port == "statistics": continue port_link = port_dir + "/" + port if not os.path.islink(port_link): continue sourcelink = os.readlink(port_link) # Skip over ../../../../../ in sourcelink" print " \-------> " + lun + "/" + port + " -> " + sourcelink[18:] return def lio_target_list_lunacls(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); iqn_root = os.listdir(lio_root) nacl_root_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls" nacl_root = os.listdir(nacl_root_dir) for nacl in nacl_root: print "\------> InitiatorName ACL: " + nacl print " Logical Unit ACLs: " lun_root_dir = nacl_root_dir + "/" + nacl lun_root = os.listdir(lun_root_dir) for lun in lun_root: ret = re.search('lun_', lun) if not ret: continue wp_attrib = lun_root_dir + "/" + lun + "/write_protect" wp_file = open(wp_attrib); line = wp_file.readline() wp_bit = line.rstrip() if wp_bit == '1': wp_info = "ENABLED" else: wp_info = "DISABLED" lun_link_dir = lun_root_dir + "/" + lun for lun_link in os.listdir(lun_link_dir): if lun_link == "write_protect": continue if lun_link == "statistics": continue if not os.path.islink(lun_link_dir + "/" + lun_link): continue sourcelink = os.readlink(lun_link_dir + "/" + lun_link) # Skip over ../../../../../../ in sourcelink" print " \-------> " + lun + " -> " + sourcelink[21:] print " \-------> Write Protect for " + lun + ": " + wp_info return def lio_target_list_nodeacls(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); iqn_root = os.listdir(lio_root) nacl_root_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls" nacl_root = os.listdir(nacl_root_dir) for nacl in nacl_root: print "\------> InitiatorName: " + nacl info_attrib = nacl_root_dir + "/" + nacl + "/info" file = open(info_attrib, "r") line = file.readline() ret = re.search('No active iSCSI Session for Initiator Endpoint', line) if ret: print " No active iSCSI Session for Initiator Endpoint" else: line = file.readline() while line: print " " + line.rstrip() line = file.readline() file.close() return def lio_target_list_nps(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); np_root = os.listdir(lio_root + "/" + iqn + "/tpgt_" + tpgt + "/np") for np in np_root: print np return def lio_target_list_targetnames(option, opt_str, value, parser): iqn_root = os.listdir(lio_root) # Loop through LIO-Target IQN list for iqn in iqn_root: if iqn == "lio_version": continue if iqn == "discovery_auth": continue print iqn return def lio_target_list_node_attr(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]) attr_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/attrib/" if os.path.isdir(attr_dir) == False: lio_err("Unable to locate node attr_dir: " + attr_dir) for attr in os.listdir(attr_dir): p = open(attr_dir + "/" + attr, 'rU') if not p: lio_err("Unable to open attr: " + attr_dir + "/" + attr) val = p.read() p.close() print attr + "=" + val.rstrip() return def lio_target_set_node_attr(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]) attr = str(value[3]) val = str(value[4]) attr_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/attrib/" if os.path.isdir(attr_dir) == False: lio_err("Unable to locate node attr_dir: " + attr_dir) p = open(attr_dir + "/" + attr, 'w') if not p: lio_err("Unable to open node attr: " + attr_dir + "/" + attr) ret = p.write(val) if ret: lio_err("Unable to set node attr: " + attr_dir + "/" + attr) p.close() print "Successfully set Initiator Node attribute: " + attr + " to: " + val return def lio_target_list_node_param(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); initiator_iqn = str(value[2]) param_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/acls/" + initiator_iqn + "/param" if os.path.isdir(param_dir) == False: lio_err("Unable to locate node param_dir: " + param_dir) for param in os.listdir(param_dir): p = open(param_dir + "/" + param, 'rU') if not p: lio_err("Unable to open attr: " + param_dir + "/" + param) val = p.read() p.close() print param + "=" + val.rstrip() return def lio_target_list_tpg_attr(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); attr_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/attrib" if os.path.isdir(attr_dir) == False: lio_err("Unable to locate tpg attr_dir: " + attr_dir) for attr in os.listdir(attr_dir): p = open(attr_dir + "/" + attr, 'rU') if not p: lio_err("Unable to open attr: " + attr_dir + "/" + attr) val = p.read() p.close() print attr + "=" + val.rstrip() return def lio_target_set_tpg_attr(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); attr = str(value[2]); val = str(value[3]); attr_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/attrib" if os.path.isdir(attr_dir) == False: lio_err("Unable to locate tpg attr_dir: " + attr_dir) p = open(attr_dir + "/" + attr, 'w') if not p: lio_err("Unable to open tpg attr: " + attr_dir + "/" + attr) ret = p.write(val) if ret: lio_err("Unable to set tpg attr: " + attr_dir + "/" + attr) p.close() print "Successfully set TPG attribute: " + attr + " to: " + val return def lio_target_list_tpg_param(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); param_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/param" if os.path.isdir(param_dir) == False: lio_err("Unable to locate tpg param dir: " + param_dir) for param in os.listdir(param_dir): p = open(param_dir + "/" + param, 'rU') if not p: lio_err("Unable to open param: " + param_dir + "/" + param) val = p.read() p.close() print param + "=" + val.rstrip() return def lio_target_set_tpg_param(option, opt_str, value, parser): iqn = str(value[0]); iqn = iqn.lower(); tpgt = str(value[1]); param = str(value[2]); val = str(value[3]); param_dir = lio_root + "/" + iqn + "/tpgt_" + tpgt + "/param" if os.path.isdir(param_dir) == False: lio_err("Unable to locate tpg param dir: " + param_dir) p = open(param_dir + "/" + param, 'w') if not p: lio_err("Unable to open tpg attr: " + param_dir + "/" + param) val = val + " " ret = p.write(val) if ret: lio_err("Unable to write tpg attr: " + param_dir + "/" + param) p.close() print "Successfully set TPG parameter: " + param + " to: " + val return def lio_target_unload(option, opt_str, value, parser): if not os.path.isdir(lio_root): lio_err("Unable to access lio_root: " + lio_root) iqn_root = os.listdir(lio_root) # Loop through LIO-Target IQN list for iqn in iqn_root: if iqn == "lio_version": continue if iqn == "discovery_auth": continue # Loop through LIO-Target IQN+TPGT list tpg_root = os.listdir(lio_root + "/" + iqn); for tpgt_tmp in tpg_root: if tpgt_tmp == "fabric_statistics": continue tpgt_tmp2 = tpgt_tmp.split('_') tpgt = tpgt_tmp2[1] tpg_val = [iqn,tpgt] __lio_target_del_tpg(None, None, tpg_val, None, 0) __lio_target_del_iqn(None, None, iqn, None, 0) rmdir_op = "rmdir " + lio_root ret = os.system(rmdir_op) if ret: print "Unable to release lio_root: " + lio_root rmmod_op = "rmmod iscsi_target_mod" ret = os.system(rmmod_op) if ret: print "Unable to unload iscsi_target_mod" return def lio_target_version(option, opt_str, value, parser): os.system("cat /sys/kernel/config/target/iscsi/lio_version") return def main(): parser = OptionParser() parser.add_option("--addlunacl", action="callback", callback=lio_target_add_lunacl, nargs=5, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN TPG_LUN MAPPED_LUN", help="Add iSCSI Initiator LUN ACL to LIO-Target Portal Group LUN") parser.add_option("--addnodeacl", action="callback", callback=lio_target_add_nodeacl, nargs=3, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN", help="Add iSCSI Initiator ACL to LIO-Target Portal Group") parser.add_option("--addnp", action="callback", callback=lio_target_add_np, nargs=3, type="string", dest="TARGET_IQN TPGT IP:PORT", help="Add LIO-Target IPv6 or IPv4 network portal") parser.add_option("--addlun", action="callback", callback=lio_target_add_port, nargs=5, type="string", dest="TARGET_IQN TPGT LUN PORT_ALIAS TCM_HBA/DEV ", help="Create LIO-Target Logical Unit") parser.add_option("--addtpg", action="callback", callback=lio_target_add_tpg, nargs=2, type="string", dest="TARGET_IQN TPGT", help="Create LIO-Target portal group") parser.add_option("--aluasecmd", action="callback", callback=lio_alua_process_secondary_md, nargs=3, type="string", dest="TARGET_IQN TPGT LUN", help="Process ALUA secondary metadata for Port/LUN"); parser.add_option("--cleartgptoff","--clearaluaoff", action="callback", callback=lio_target_alua_clear_tgpt_offline, nargs=3, type="string", dest="TARGET_IQN TPGT LUN", help="Clear ALUA Target Port Secondary State OFFLINE") parser.add_option("--dellunacl", action="callback", callback=lio_target_del_lunacl, nargs=4, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN MAPPED_LUN", help="Delete iSCSI Initiator LUN ACL from LIO-Target Portal Group LUN") parser.add_option("--delnodeacl", action="callback", callback=lio_target_del_nodeacl, nargs=3, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN", help="Delete iSCSI Initiator ACL from LIO-Target Portal Group") parser.add_option("--delnp", action="callback", callback=lio_target_del_np, nargs=3, type="string", dest="TARGET_IQN TPGT IP:PORT", help="Delete LIO-Target IPv6 or IPv4 network portal") parser.add_option("--deliqn", action="callback", callback=lio_target_del_iqn, nargs=1, type="string", dest="TARGET_IQN", help="Delete LIO-Target IQN Endpoint") parser.add_option("--dellun", action="callback", callback=lio_target_del_port, nargs=3, type="string", dest="TARGET_IQN TPGT LUN", help="Delete LIO-Target Logical Unit") parser.add_option("--deltpg", action="callback", callback=lio_target_del_tpg, nargs=2, type="string", dest="TARGET_IQN TPGT", help="Delete LIO-Target Portal Group") parser.add_option("--demomode", "--permissive", action="callback", callback=lio_target_tpg_demomode, nargs=2, type="string", dest="TARGET_IQN TPGT", help="Disable all iSCSI Initiator ACL requirements (enable DemoMode) for LIO-Target Portal Group (Disabled by default)") parser.add_option("--disableauth", action="callback", callback=lio_target_tpg_disableauth, nargs=2, type="string", dest="TARGET_IQN TPGT", help="Disable iSCSI Authentication for LIO-Target Portal Group (Enabled by default)") parser.add_option("--disablelunwp", action="callback", callback=lio_target_disable_lunwp, nargs=4, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN MAPPED_LUN", help="Clear Write Protect bit for iSCSI Initiator LUN ACL") parser.add_option("--disabletpg", action="callback", callback=lio_target_disable_tpg, nargs=2, type="string", dest="TARGET_IQN TPGT", help="Disable LIO-Target Portal Group") parser.add_option("--enableaclmode", action="callback", callback=lio_target_enableaclmode, nargs=2, type="string", dest="TARGET_IQN TPGT", help="Enable iSCSI Initiator ACL requirement mode for LIO-Target Portal Group (Enabled by default)") parser.add_option("--enableauth", action="callback", callback=lio_target_enable_auth, nargs=2, type="string", dest="TARGET_IQN TPGT", help="Enable iSCSI Authentication for LIO-Target Portal Group (Enabled by default)") parser.add_option("--enablelunwp", action="callback", callback=lio_target_enable_lunwp, nargs=4, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN MAPPED_LUN", help="Set Write Protect bit for iSCSI Initiator LUN ACL") parser.add_option("--enabletpg", action="callback", callback=lio_target_enable_tpg, nargs=2, type="string", dest="TARGET_IQN TPGT", help="Enable LIO-Target Portal Group") parser.add_option("--listendpoints", action="callback", callback=lio_target_list_endpoints, nargs=0, help="List iSCSI Target Endpoints") parser.add_option("--listlunacls", action="callback", callback=lio_target_list_lunacls, nargs=2, type="string", dest="TARGET_IQN TPGT", help="List iSCSI Initiator LUN ACLs for LIO-Target Portal Group") parser.add_option("--listnodeacls", action="callback", callback=lio_target_list_nodeacls, nargs=2, type="string", dest="TARGET_IQN TPGT", help="List iSCSI Initiator ACLs for LIO-Target Portal Group") parser.add_option("--listnodeattr", action="callback", callback=lio_target_list_node_attr, nargs=3, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN", help="List iSCSI Initiator ACL attributes for LIO-Target Portal Group") parser.add_option("--listnodeparam", action="callback", callback=lio_target_list_node_param, nargs=3, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN", help="List iSCSI Initiator ACL RFC-3720 parameters for LIO-Target Portal Group") parser.add_option("--listnps", action="callback", callback=lio_target_list_nps, nargs=2, type="string", dest="TARGET_IQN TPGT", help="List LIO-Target Portal Group Network Portals") parser.add_option("--listtargetnames", action="callback", callback=lio_target_list_targetnames, nargs=0, help="List iSCSI Target Names") parser.add_option("--listtpgattr", action="callback", callback=lio_target_list_tpg_attr, nargs=2, type="string", dest="TARGET_IQN TPGT", help="List LIO-Target Portal Group attributes") parser.add_option("--listtpgparam", action="callback", callback=lio_target_list_tpg_param, nargs=2, type="string", dest="TARGET_IQN TPGT", help="List LIO-Target Portal Group RFC-3720 parameters") parser.add_option("--setchapauth", action="callback", callback=lio_target_set_chap_auth, nargs=5, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN USER PASS", help="Set CHAP authentication information for iSCSI Initiator Node ACL"); parser.add_option("--setchapmutualauth", action="callback", callback=lio_target_set_chap_mutual_auth, nargs=5, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN USER_IN PASS_IN", help="Set CHAP mutual authentication information for iSCSI Initiator Node ACL"); parser.add_option("--setchapdiscenforce", action="callback", callback=lio_target_set_enforce_discovery_auth, nargs=1, type="string", dest="Enforce=1, NoEnforcement=0", help="Set CHAP authentication enforcement for iSCSI Discovery Sessions"); parser.add_option("--setchapdiscauth", action="callback", callback=lio_target_set_chap_discovery_auth, nargs=2, type="string", dest="USER PASS", help="Set CHAP authentication information for iSCSI Discovery Authentication") parser.add_option("--setchapdiscmutualauth", action="callback", callback=lio_target_set_chap_mutual_discovery_auth, nargs=2, type="string", dest="USER PASS", help="Set CHAP mutual authentication information for iSCSI Discovery Authentication") parser.add_option("--setnodeattr", action="callback", callback=lio_target_set_node_attr, nargs=5, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN ", help="Set iSCSI Initiator ACL Attribute") parser.add_option("--setnodetcq", action="callback", callback=lio_target_set_node_tcq, nargs=4, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN DEPTH", help="Set iSCSI Initiator ACL TCQ Depth for LIO-Target Portal Group") parser.add_option("--settpgattr", action="callback", callback=lio_target_set_tpg_attr, nargs=4, type="string", dest="TARGET_IQN TPGT ", help="Set LIO-Target Port Group Attribute") parser.add_option("--settpgparam", action="callback", callback=lio_target_set_tpg_param, nargs=4, type="string", dest="TARGET_IQN TPGT ", help="Set LIO-Target Port Group RFC-3720 parameter") parser.add_option("--settgptgp","--setaluatpg", action="callback", callback=lio_target_alua_set_tgptgp, nargs=4, type="string", dest="TARGET_IQN TPGT LUN TG_PT_GP_NAME", help="Set ALUA Target Port Group for LIO-Target Port/LUN") parser.add_option("--settgptoff","--setaluaoff", action="callback", callback=lio_target_alua_set_tgpt_offline, nargs=3, type="string", dest="TARGET_IQN TPGT LUN", help="Set ALUA Target Port Secondary State OFFLINE") parser.add_option("--showchapauth", action="callback", callback=lio_target_show_chap_auth, nargs=3, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN", help="Show CHAP authentication information for iSCSI Initiator Node ACL"); parser.add_option("--showchapdiscauth", action="callback", callback=lio_target_show_chap_discovery_auth, nargs=0, help="Show CHAP authentication information for iSCSI Discovery portal"); parser.add_option("--shownodetcq", action="callback", callback=lio_target_show_node_tcq, nargs=3, type="string", dest="TARGET_IQN TPGT INITIATOR_IQN", help="Show iSCSI Initiator ACL TCQ Depth for LIO-Target Portal Group") parser.add_option("--showtgptgp", action="callback", callback=lio_target_alua_show_tgptgp, nargs=3, type="string", dest="TARGET_IQN TPGT LUN", help="Show ALUA Target Port Group for LIO-Target Port/LUN") parser.add_option("--unload", action="callback", callback=lio_target_unload, nargs=0, help="Unload LIO-Target") parser.add_option("--version", action="callback", callback=lio_target_version, nargs=0, help="Display LIO-Target version information") (options, args) = parser.parse_args() if len(sys.argv) == 1: parser.print_help() sys.exit(0) elif not re.search('--', sys.argv[1]): lio_err("Unknown CLI option: " + sys.argv[1]) if __name__ == "__main__": main() lio-utils-3.1+git2.fd0b34fd/lio-py/uninstall.sh0000755000175000017500000000032411753136721017416 0ustar rrsrrs#!/bin/sh SITE_PACKAGES=`python ../get-py-modules-path.py` if [ -f /usr/sbin/lio_dump ]; then rm /usr/sbin/lio_dump fi if [ -f /usr/sbin/lio_node ]; then rm /usr/sbin/lio_node fi rm -rf $SITE_PACKAGES/lio_* lio-utils-3.1+git2.fd0b34fd/lio-py/setup.py0000755000175000017500000000073311753136721016567 0ustar rrsrrs#!/usr/bin/python from distutils.core import setup long_desc="""Python CLI for controlling the LIO-Target/ConfigFS fabric module """ setup(name='lio', version='4.1', description='CLI for controlling LIO-Target/ConfigFS', long_description=long_desc, author='Nicholas A. Bellinger', author_email='nab@linux-iscsi.org', url='http://linux-iscsi.org', license='GPL', requires=['tcm'], py_modules=['lio_dump','lio_node'] ) lio-utils-3.1+git2.fd0b34fd/lio-py/install.sh0000755000175000017500000000050211753136721017051 0ustar rrsrrs#!/bin/sh SITE_PACKAGES=`python ../get-py-modules-path.py` chmod a+x $SITE_PACKAGES/lio_dump.py chmod a+x $SITE_PACKAGES/lio_node.py if [ ! -f /usr/sbin/lio_dump ]; then ln -s $SITE_PACKAGES/lio_dump.py /usr/sbin/lio_dump fi if [ ! -f /usr/sbin/lio_node ]; then ln -s $SITE_PACKAGES/lio_node.py /usr/sbin/lio_node fi lio-utils-3.1+git2.fd0b34fd/tools/0000755000175000017500000000000011753136721014776 5ustar rrsrrslio-utils-3.1+git2.fd0b34fd/tools/md5.c0000644000175000017500000001636211753136721015637 0ustar rrsrrs/* * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. * * To compute the message digest of a chunk of bytes, declare an * MD5Context structure, pass it to MD5Init, call MD5Update as * needed on buffers full of bytes, and then call MD5Final, which * will fill a supplied 16-byte array with the digest. * * Changed so as no longer to depend on Colin Plumb's `usual.h' header * definitions; now uses stuff from dpkg's config.h. * - Ian Jackson . * Still in the public domain. */ #include #include "md5.h" #if BYTE_ORDER == BIG_ENDIAN void byteSwap(uint32_t * buf, unsigned words) { md5byte *p = (md5byte *) buf; do { *buf++ = (uint32_t) ((unsigned) p[3] << 8 | p[2]) << 16 | ((unsigned) p[1] << 8 | p[0]); p += 4; } while (--words); } #else #define byteSwap(buf,words) #endif /* * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious * initialization constants. */ void MD5Init(struct MD5Context *ctx) { ctx->buf[0] = 0x67452301; ctx->buf[1] = 0xefcdab89; ctx->buf[2] = 0x98badcfe; ctx->buf[3] = 0x10325476; ctx->bytes[0] = 0; ctx->bytes[1] = 0; } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ void MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) { uint32_t t; /* Update byte count */ t = ctx->bytes[0]; if ((ctx->bytes[0] = t + len) < t) ctx->bytes[1]++; /* Carry from low to high */ t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ if (t > len) { memcpy((md5byte *) ctx->in + 64 - t, buf, len); return; } /* First chunk is an odd size */ memcpy((md5byte *) ctx->in + 64 - t, buf, t); byteSwap(ctx->in, 16); MD5Transform(ctx->buf, ctx->in); buf += t; len -= t; /* Process data in 64-byte chunks */ while (len >= 64) { memcpy(ctx->in, buf, 64); byteSwap(ctx->in, 16); MD5Transform(ctx->buf, ctx->in); buf += 64; len -= 64; } /* Handle any remaining bytes of data. */ memcpy(ctx->in, buf, len); } /* * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ void MD5Final(md5byte digest[16], struct MD5Context *ctx) { int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ md5byte *p = (md5byte *) ctx->in + count; /* Set the first char of padding to 0x80. There is always room. */ *p++ = 0x80; /* Bytes of padding needed to make 56 bytes (-8..55) */ count = 56 - 1 - count; if (count < 0) { /* Padding forces an extra block */ memset(p, 0, count + 8); byteSwap(ctx->in, 16); MD5Transform(ctx->buf, ctx->in); p = (md5byte *) ctx->in; count = 56; } memset(p, 0, count); byteSwap(ctx->in, 14); /* Append length in bits and transform */ ctx->in[14] = ctx->bytes[0] << 3; ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; MD5Transform(ctx->buf, ctx->in); byteSwap(ctx->buf, 4); memcpy(digest, ctx->buf, 16); memset(ctx, 0, sizeof (ctx)); /* In case it's sensitive */ } #ifndef ASM_MD5 /* The four core functions - F1 is optimized somewhat */ /* #define F1(x, y, z) (x & y | ~x & z) */ #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) F1(z, x, y) #define F3(x, y, z) (x ^ y ^ z) #define F4(x, y, z) (y ^ (x | ~z)) /* This is the central step in the MD5 algorithm. */ #define MD5STEP(f,w,x,y,z,in,s) \ (w += f(x,y,z) + in, w = (w<>(32-s)) + x) /* * The core of the MD5 algorithm, this alters an existing MD5 hash to * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ void MD5Transform(uint32_t buf[4], uint32_t const in[16]) { register uint32_t a, b, c, d; a = buf[0]; b = buf[1]; c = buf[2]; d = buf[3]; MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } #endif lio-utils-3.1+git2.fd0b34fd/tools/Makefile0000644000175000017500000000053611753136721016442 0ustar rrsrrs ISCSI_NAME = iscsi-name ISCSI_NAME_SRCS = iscsi_name.c md5.c ISCSI_NAME_OBJS = $(ISCSI_NAME_SRCS:.c=.o) all:: $(ISCSI_NAME) $(ISCSI_NAME): $(ISCSI_NAME_OBJS) $(CC) -o $@ $(CFLAGS) $(ISCSI_NAME_OBJS) clean: rm -f $(ISCSI_NAME_OBJS) $(ISCSI_NAME) install: install -m 0755 $(ISCSI_NAME) $(DESTDIR)/usr/sbin/iscsi-name lio-utils-3.1+git2.fd0b34fd/tools/md5.h0000644000175000017500000000256011753136721015637 0ustar rrsrrs/* * This is the header file for the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. * * To compute the message digest of a chunk of bytes, declare an * MD5Context structure, pass it to MD5Init, call MD5Update as * needed on buffers full of bytes, and then call MD5Final, which * will fill a supplied 16-byte array with the digest. * * Changed so as no longer to depend on Colin Plumb's `usual.h' * header definitions; now uses stuff from dpkg's config.h * - Ian Jackson . * Still in the public domain. */ #ifndef MD5_H #define MD5_H /* for uint32_t, WORDS_BIGENDIAN */ #define uint32_t unsigned int #define md5byte unsigned char struct MD5Context { uint32_t buf[4]; uint32_t bytes[2]; uint32_t in[16]; }; void MD5Init(struct MD5Context *context); void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len); void MD5Final(unsigned char digest[16], struct MD5Context *context); void MD5Transform(uint32_t buf[4], uint32_t const in[16]); #endif /* !MD5_H */ lio-utils-3.1+git2.fd0b34fd/tools/iscsi_name.c0000644000175000017500000001045711753136721017263 0ustar rrsrrs/* * iSCSI InitiatorName creation utility * Copyright (C) 2001 Cisco Systems, Inc. * Copyright (C) 2005 PyX Technologies, Inc. * * 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. * * iscsi-iname.c - Compute an iSCSI InitiatorName for this host. * Note that to ensure uniqueness, the system time is * a factor. This name must be cached and only regenerated * if there is no cached value. */ #include #include #include #include #include #include #include #include "md5.h" #define RANDOM_NUM_GENERATOR "/dev/urandom" #define INITIATOR_NAME_MAXLEN 256 #define IQN_PREFIX "iqn.2003-01.org.linux-iscsi" int main(int argc, char *argv[]) { char iname[INITIATOR_NAME_MAXLEN + 1], *ptr; struct timeval time; struct utsname system_info; long hostid; struct MD5Context context; unsigned char digest[16]; unsigned char *bytes = digest; unsigned char entropy[16], machine[16]; int e; int fd; char *prefix; /* initialize */ memset(iname, 0, sizeof (iname)); memset(digest, 0, sizeof (digest)); memset(&context, 0, sizeof (context)); MD5Init(&context); /* take a prefix if given, otherwise use a default. */ if (argc > 1 && argv[1]) { prefix = argv[1]; if (( strcmp(prefix, "-h") == 0 ) || ( strcmp(prefix, "--help") == 0 )) { printf("\nDisplays the iSCSI initiator name\n"); exit(0); } else if ( strcmp(prefix, "-p") == 0 ) { prefix = argv[2]; } else { printf("\nUsage: iscsi-iname [-h | --help | " "-p ]\n"); exit(0); } } else { prefix = IQN_PREFIX; } /* try to feed some entropy from the pool to MD5 in order to get * uniqueness properties */ if ((fd = open(RANDOM_NUM_GENERATOR, O_RDONLY))) { e = read(fd, &entropy, 16); if (e >= 1) MD5Update(&context, (md5byte *)entropy, e); close(fd); } /* time the name is created is a factor in order to get * uniqueness properties */ if (gettimeofday(&time, NULL) < 0) { perror("error: gettimeofday failed"); return 1; } MD5Update(&context, (md5byte *) & time.tv_sec, sizeof (time.tv_sec)); MD5Update(&context, (md5byte *) & time.tv_usec, sizeof (time.tv_usec)); /* hostid */ hostid = gethostid(); MD5Update(&context, (md5byte *) & hostid, sizeof (hostid)); /* get the hostname and system name */ if (uname(&system_info) < 0) { perror("error: uname failed"); return 1; } MD5Update(&context, (md5byte *) system_info.sysname, sizeof (system_info.sysname)); MD5Update(&context, (md5byte *) system_info.nodename, sizeof (system_info.nodename)); MD5Update(&context, (md5byte *) system_info.release, sizeof (system_info.release)); MD5Update(&context, (md5byte *) system_info.version, sizeof (system_info.version)); MD5Update(&context, (md5byte *) system_info.machine, sizeof (system_info.machine)); /* compute the md5 hash of all the bits we just collected */ MD5Final(digest, &context); /* vary which md5 bytes we pick (though we probably don't need to do * this, since hopefully MD5 produces results such that each byte is as * good as any other). */ if ((fd = open(RANDOM_NUM_GENERATOR, O_RDONLY))) { if (read(fd, entropy, 1) == 1) bytes = &digest[(entropy[0] % (sizeof(digest) - 6))]; close(fd); } /* Terminate the nodename so that output will append to IQN prefix */ if ((ptr = strstr(system_info.nodename, "."))) (*ptr) = '\0'; snprintf(machine, 16, "%s", system_info.machine); /* * Remove "_" character from uname -m output for x86_64. */ if ((ptr = strstr(machine, "_"))) *ptr = '\0'; /* print the prefix followed by 6 bytes of the MD5 hash */ sprintf(iname, "%s.%s.%s:sn.%x%x%x%x%x%x", prefix, system_info.nodename, machine, bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5]); iname[sizeof (iname) - 1] = '\0'; printf("%s\n", iname); return 0; } lio-utils-3.1+git2.fd0b34fd/scripts/0000755000175000017500000000000011753136721015325 5ustar rrsrrslio-utils-3.1+git2.fd0b34fd/scripts/rc.target0000644000175000017500000002442211753136721017145 0ustar rrsrrs#!/bin/bash # # Filename: /etc/init.d/target # target: Bring up/down target_core_mod and iscsi_target_mod v3.0 # # Bring up/down iscsi target networking # # chkconfig: 2345 18 01 # description: Target_Core_Mod + LIO-target + ConfigFS v3.x # config: /etc/sysconfig/target # ######################################################################### # # For SuSE, the following information is read by "insserv" program and the # start/stoplinks are installed at appropriate runlevels. # The network interface and logger has to be up for starting target service ### BEGIN INIT INFO # Provides: target # Required-Start: $network $syslog # Required-Stop: $network $syslog # Default-Start: 2 3 5 # Default-Stop: 0 1 6 # Description: TCM/ConfigFS and LIO-Target ### END INIT INFO # Source function library. #. /etc/init.d/functions ######################################################################### # Our product file definitions MODNAME="target_core_mod" TCM_CFS_DIR="/sys/kernel/config/target/core" LIO_CFS_DIR="/sys/kernel/config/target/iscsi" FILE_TCFG="/etc/sysconfig/target" LOCK_TARGET="/var/lock/subsys/target" LOG_EVENT="/var/log/iscsi/target.log" TCM_NODE="/usr/sbin/tcm_node" LIO_NODE="/usr/sbin/lio_node" TCM_FABRIC="/usr/sbin/tcm_fabric" SEMA_TARGET="/var/crash/target.fault" CONFIGFS_SCRIPT_DIR="/etc/target" TCM_CONFIGFS_SCRIPT="/etc/target/tcm_start.sh" LIO_CONFIGFS_SCRIPT="/etc/target/lio_start.sh" ######################################################################### # Allows saving command & arguments into a file for subsequent debugging # Enable: Set DEBUG=1 Disable: Set DEBUG=0 DEBUG=0 LOGFILE=/var/log/tgtctl.dbug if [ $DEBUG != 0 ]; then echo "$0 $*" >> $LOGFILE fi ######################################################################### if [ ! -f ${TCM_NODE} ]; then echo "${TCM_NODE} does not exist" exit 1 fi if [ ! -f ${LIO_NODE} ]; then echo "${LIO_NODE} does not exist" exit 1 fi if [ ! -d /var/crash ]; then mkdir /var/crash fi if [ ! -d /var/lock/subsys ]; then mkdir -p /var/lock/subsys fi if [ ! -d /var/target/pr ]; then mkdir -p /var/target/pr fi if [ ! -d /var/target/alua ]; then mkdir -p /var/target/alua fi ARGS_CHECK=2 ARGS_COUNT=$# cd / # to avoid making the CWD unmountable ######################################################################### PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" RETVAL=0 function run_fabric_cfs_ops() { DATETIME=$1 for i in $( ls $CONFIGFS_SCRIPT_DIR); do CONFIGFS_SCRIPT_PATH="$CONFIGFS_SCRIPT_DIR/$i" if [ ! -f $CONFIGFS_SCRIPT_PATH ]; then continue fi # target core is handled in run_tcm_cfs_ops() if [ $i == "tcm_start.sh" ]; then continue fi # iscsi-target fabric module is handled in run_lio_target_cfs_ops() if [ $i == "lio_start.sh" ]; then continue fi # Skip RPM package save+orig+new if [[ $i =~ ".rpmsave" ]]; then continue fi if [[ $i =~ ".rpmorig" ]]; then continue fi if [[ $i =~ ".rpmnew" ]]; then continue fi # Skip dpkg dist if [[ $i =~ ".dpkg-dist" ]]; then continue fi # Skip emacs state files if [[ $i =~ ~$ ]]; then continue fi if [ $DATETIME != "0" ]; then FABRICNAME=`echo $i | sed -e s/_start.sh//` BACKUPFILE=$FABRICNAME"_backup-$DATETIME.sh" CONFIGFS_SCRIPT_PATH="/etc/target/backup/$BACKUPFILE" if [ ! -f $CONFIGFS_SCRIPT_PATH ]; then echo "Unable to locate config file $CONFIGFS_SCRIPT_PATH" exit 1 fi fi echo -n $"Calling ConfigFS script $CONFIGFS_SCRIPT_PATH: " sh ${CONFIGFS_SCRIPT_PATH} > /dev/null 2>&1 RET=$? if [ $RET == 0 ]; then echo " [OK]" else echo " [FAILED]" fi done } function run_lio_target_cfs_ops() { DATETIME=$1 if [ ! -f ${LIO_CONFIGFS_SCRIPT} ]; then exit 1 fi if [ $DATETIME != "0" ]; then LIO_CONFIGFS_SCRIPT="/etc/target/backup/lio_backup-$DATETIME.sh" if [ ! -f $LIO_CONFIGFS_SCRIPT ]; then echo "Unable to locate config file $LIO_CONFIGFS_SCRIPT" exit 1 fi fi echo -n $"Calling ConfigFS script $LIO_CONFIGFS_SCRIPT for iscsi_target_mod: " if [ -f $LIO_CONFIGFS_SCRIPT ]; then sh ${LIO_CONFIGFS_SCRIPT} > /dev/null 2>&1 RET=$? if [ $RET == 0 ]; then echo " [OK]" else echo " [FAILED]" fi fi } function run_tcm_cfs_ops() { DATETIME=$1 if [ ! -f ${TCM_CONFIGFS_SCRIPT} ]; then exit 1 fi if [ $DATETIME != "0" ]; then TCM_CONFIGFS_SCRIPT="/etc/target/backup/tcm_backup-$DATETIME.sh" if [ ! -f $TCM_CONFIGFS_SCRIPT ]; then echo "Unable to locate config file $TCM_CONFIGFS_SCRIPT" exit 1 fi fi echo -n $"Calling ConfigFS script $TCM_CONFIGFS_SCRIPT for target_core_mod: " if [ -f $TCM_CONFIGFS_SCRIPT ]; then sh ${TCM_CONFIGFS_SCRIPT} > /dev/null 2>&1 RET=$? if [ $RET == 0 ]; then echo " [OK]" else echo " [FAILED]" fi fi run_lio_target_cfs_ops $1 run_fabric_cfs_ops $1 } function load_scsi_disk() { if test "x`grep "sd" /proc/devices | awk '{ if ($2 == "sd") print "sd" }'`" != x ; then : else echo -n $"Loading SCSI Disk: " modprobe -q sd_mod if lsmod | grep -q "^sd_mod" ; then echo " [OK]" else echo -n $"SCSI Core ERROR, abort iSCSI Target Stack: " echo "error" exit 1 fi fi } function check_configfs_mount() { if [ ! -d /sys/kernel/config ]; then modprobe configfs mount -t configfs configfs /sys/kernel/config RET=$? if [ $RET != 0 ]; then echo "ERROR: Unable to mount configfs on /sys/kernel/config" return 1 fi fi } function unload_lio_mode() { echo -n $"Unload Linux-iSCSI.org Fabric module" rmmod iscsi_target_mod RETVAL=$? if [ $RETVAL == 0 ]; then echo " [OK]" else echo " [FAILED]: $RETVAL" fi } function load_tcm_mod() { check_configfs_mount RETVAL=$? if [ $RETVAL != 0 ]; then return 1 fi echo -n $"Loading target_core_mod/ConfigFS core: " modprobe -q ${MODNAME} > /dev/null RETVAL=$? if [ $RETVAL == 0 ]; then echo " [OK]" else echo " [FAILED]: $RETVAL" fi return 0 } function shutdown_fabrics() { echo -n $"Unloading fabric/configfs: " ${TCM_FABRIC} --unloadall RETVAL=$? if [ $RETVAL == 0 ]; then echo " [OK]" else echo " [FAILED]: $RETVAL" fi } function shutdown_lio_mod () { if [ ! -d /sys/kernel/config/target/iscsi/ ]; then return 0 fi echo -n $"Unloading LIO-Target/ConfigFS fabric: " ${LIO_NODE} --unload RETVAL=$? if [ $RETVAL == 0 ]; then echo " [OK]" else echo " [FAILED]: $RETVAL" fi } function unload_tcm_mod() { shutdown_fabrics shutdown_lio_mod echo -n $"Unloading target_core_mod/ConfigFS core: " $TCM_NODE --unload RETVAL=$? if [ $RETVAL == 0 ]; then echo " [OK]" return 0 else echo " [FAILED]: $RETVAL" return 1 fi } start () { if [ -d ${TCM_CFS_DIR} ]; then echo -n $"Calling START $0 " RETVAL=1 echo "ERROR, target_core_mod/ConfigFS already active" return $RETVAL fi if test "x `lsmod | grep ${MODNAME} | awk '{ if ($$1 == "${MODNAME}") print $$1 }'`" == x ; then echo -n $"Calling START $0 " RETVAL=1 echo "ERROR, target_core_mod/ConfigFS already active" return $RETVAL else if [ -e ${LOCK_TARGET} ]; then rm -f ${LOCK_TARGET} fi fi # Prevent multiple driver panics from hanging system (probably via scsi or target driver). # HINT: Most likely cause is a problem within '/etc/iscsi/install.target'. # Save a backup of the file, then NULL'd it to troubleshoot this variant. if [ -e ${SEMA_TARGET} ]; then RETVAL=1 echo "See ${SEMA_TARGET}" return $RETVAL fi # Put message in semaphore file to aid in troubleshooting should # the file still exist during a subsequent boot. echo "$0: Created: " `date` > ${SEMA_TARGET} echo "$0: " >> ${SEMA_TARGET} echo "$0: This file has been created as a result of a potentially" >> ${SEMA_TARGET} echo "$0: recursive module startup problem. Probable cause is an" >> ${SEMA_TARGET} echo "$0: iSCSI device configuration problem which finds its way" >> ${SEMA_TARGET} echo "$0: catastrophically into the Target Core Stack." >> ${SEMA_TARGET} echo "$0: " >> ${SEMA_TARGET} echo "$0: You must remove /var/crash/target.fault before attempting" >> ${SEMA_TARGET} echo "$0: to start again." >> ${SEMA_TARGET} echo "$0: " >> ${SEMA_TARGET} echo "$0: Continued startup problems might be researched by saving" >> ${SEMA_TARGET} echo "$0: off the current /etc/iscsi/install.target file and then" >> ${SEMA_TARGET} echo "$0: replacing it with a dummy file which contains no entries." >> ${SEMA_TARGET} echo "$0: If bootup is then successful, contact the iSCSI Target" >> ${SEMA_TARGET} echo "$0: Stack manufacturer for assistance with problems within" >> ${SEMA_TARGET} echo "$0: the target configuration file." >> ${SEMA_TARGET} sync ; sync # load_scsi_disk if [ -e ${LOCK_TARGET} ]; then rm -f ${SEMA_TARGET} echo -n $"Calling START $0 " RETVAL=1 echo "ERROR, target_core_mod already active" return $RETVAL fi load_tcm_mod if [ $RETVAL != 0 ]; then rm -f ${SEMA_TARGET} return $RETVAL fi sleep 1 ${PGM_SET_TNAME} RETVAL=$? if [ $RETVAL == 2 ]; then rm -f ${SEMA_TARGET} unload_tcm_mod return $RETVAL fi run_tcm_cfs_ops $1 touch ${LOCK_TARGET} rm -f ${SEMA_TARGET} return $RETVAL } stop () { rm -f ${SEMA_TARGET} unload_tcm_mod RET=$? if [ $RET != 0 ]; then return 1 fi sleep 1 rm -f ${LOCK_TARGET} echo "Successfully unloaded target_core_mod/ConfigFS core" return $RET } function lio_version () { if [ ! -d ${LIO_CFS_DIR} ]; then exit 1 fi lio_node --version } function lio_status () { if [ ! -d ${LIO_CFS_DIR} ]; then exit 1 fi lio_node --listendpoints } function tcm_version () { if [ ! -d ${TCM_CFS_DIR} ]; then exit 1 fi tcm_node --version } function tcm_status () { if [ ! -d ${TCM_CFS_DIR} ]; then exit 1 fi echo "[---------------------------] TCM/ConfigFS Status [----------------------------]" tcm_node --listhbas echo "" echo "[---------------------------] LIO-Target Status [----------------------------]" lio_status echo "" tcm_version lio_version } restart () { stop 1 start 0 RETVAL=$? } case "$1" in start) start 0 ;; startbak) if [ "$ARGS_COUNT" -ne "$ARGS_CHECK" ]; then echo "Usage: /etc/init.d/target startbak " exit 1 fi start $2 ;; stop) stop 1 ;; status) tcm_status RETVAL=$? ;; restart|reload) restart 1 ;; *) echo $"Usage: $0 {start|startbak|stop|status|restart}" exit 1 esac exit $?