def stop_iscsi(): """ stops iscsi """ try: command.execute_cmd("/etc/init.d/iscsi-scst stop") except command.ExecutionError as e: raise ScstException("Failed to stop iscsi-scst", e)
def unregister_target(target): """ unregisters a target """ try: command.execute_cmd("%s --op delete --tid=\"%s\"" % (get_iscsi_scst_path(), target.tid)) except Exception as e: raise ScstException("Failed to unregister target", e)
def change_target_params(target, updated_params): """ update some params of a target Note: target is an updates version of the target """ try: param_str = ",".join(["%s=%s" % (key, update_params[key]) for key in updated_params.keys()]) command.execute_cmd("%s --op update --tid=\"%s\" --params %s" % (get_iscsi_scst_path(), target.tid, param_str)) except Exception as e: raise ScstException("Failed to update params in target", e)
def rm_user_from_target(user, target): """ remove a user from a target user is a User object target is a target object """ try: command.execute_cmd("%s --op delete --tid=\"%s\" --user --params IncomingUser=\"%s\"" % (get_iscsi_scst_path(), target.tid, user.name)) except Exception as e: raise ScstException("Failed to remove user from target", e)
def connect(server, name): """ connects to a given iSCSI target """ execute_cmd("iscsiadm -m node -p %s -T %s -l" % (server, name)) time.sleep(3) devs = filter(lambda d: d.find(server) >= 0 and d.find(name) >= 0, get_device_list()) devs_msg = ["New Device: " + d + "\n" for d in devs] print "".join(devs_msg)
def start_iscsi(group_name, port = None, host = None): """ starts iscsi via the iscsi-scst init.d tool """ try: if not is_iscsi_running(): if not port: port = "3260" if not host: host = "" command.execute_cmd("/etc/init.d/iscsi-scst start %s %s %s" % (group_name, port, host)) sleep(2) except command.ExecutionError as e: raise ScstException("Failed to start iscsi-scst", e)
def update_user_in_target(user, target): """ update a user in a target user is a User object target is a Target object """ try: secret = base64.standard_b64decode(user.secret_hash()) secret = [chr((ord(i) - 13) % 256) for i in secret] secret = "".join(secret) if secret[-1] == chr(0): secret = secret[:-1] # this is totally a hack, but iscsi-scst-adm doesn't support to update user password command.execute_cmd("%s --op delete --tid=\"%s\" --user --params IncomingUser=\"%s\"" % (get_iscsi_scst_path(), target.tid, user.name)) command.execute_cmd("%s --op new --tid=\"%s\" --user --params IncomingUser=\"%s\",Password=\"%s\"" % (get_iscsi_scst_path(), target.tid, user.name, secret)) except Exception as e: raise ScstException("Failed to update user in target", e)
def add_user_to_target(user, target): """ adds a user to a target user is a User object target is a Target object """ try: secret = base64.standard_b64decode(user.secret_hash()) secret = [chr((ord(i) - 13) % 256) for i in secret] secret = "".join(secret) if secret[-1] == chr(0): secret = secret[:-1] if len(secret) < 12 or len(secret) > 256: raise Exception("Invalid secret") command.execute_cmd("%s --op new --tid=\"%s\" --user --params IncomingUser=\"%s\",Password=\"%s\"" % (get_iscsi_scst_path(), target.tid, user.name, secret)) except Exception as e: raise ScstException("Failed to add user to target", e)
def is_target_registered(target): """ checks if the given target is registered at SCST target is a target Object """ try: # This check is a kind of hack, but we have other way to see if # the target is registered command.execute_cmd("%s --op show --tid=\"%s\"" % (get_iscsi_scst_path(), target.tid)) return True except command.ExecutionError as e: if not e.output: raise else: if e.output.find("Invalid argument") >= 0: # If Invalid argument is returned, SCST doesn't know the target return False else: raise # re-raise the ExecutionError
def is_process_running(pid): """ Checks if the process with the given process id (pid) is running """ try: o = execute_cmd("ps -p %s" % str(int(pid))) return o.find(str(pid)) >= 0 except ExecutionError as e: if e.result == 1: return False else: raise
def change_target_auth(target): """ Change the target outgoing authentication target is a Target object """ try: secret = base64.standard_b64decode(target.auth_secret_hash()) secret = [chr((ord(i) - 13) % 256) for i in secret] secret = "".join(secret) if secret[-1] == chr(0): secret = secret[:-1] # this is totally a hack, but iscsi-scst-adm doesn't support to update user password try: command.execute_cmd("%s --op delete --tid=\"%s\" --user --params OutgoingUser=\"%s\"" % (get_iscsi_scst_path(), target.tid, target.auth_username())) except: pass command.execute_cmd("%s --op new --tid=\"%s\" --user --params OutgoingUser=\"%s\",Password=\"%s\"" % (get_iscsi_scst_path(), target.tid, target.auth_username(), secret)) except Exception as e: raise ScstException("Failed to update user in target", e)
def register_target(target): """ registers a target target is a Target object """ try: command.execute_cmd("%s --op new --tid=\"%s\" --params Name=\"%s\"" % (get_iscsi_scst_path(), target.tid, target.name())) if len(target.params()) > 0: params = ["%s=\"%s\"" % (p[0], p[1]) for p in target.params()] params = ",".join(params) command.execute_cmd("%s --op update --tid=\"%s\" --params %s" % (get_iscsi_scst_path(), target.tid, params)) if target.auth_username() or target.auth_secret_hash(): try: secret = base64.standard_b64decode(target.auth_secret_hash()) secret = [chr((ord(i) - 13) % 256) for i in secret] secret = "".join(secret) if secret[-1] == chr(0): secret = secret[:-1] if len(secret) < 12 or len(secret) > 256: raise Exception("Invalid secret") command.execute_cmd("%s --op new --tid=\"%s\" --user --params OutgoingUser=\"%s\",Password=\"%s\"" % (get_iscsi_scst_path(), target.tid, target.auth_username(), secret)) except Exception as e: raise ScstException("Failed to add user to target", e) except Exception as e: raise ScstException("Failed to register target", e)
def check_scst(group_name): """ checks the current state of SCST and tries to correct it This function is usually called with root permissions """ if not kernel_module_loaded("scst"): if group_name: group_gid = grp.getgrnam(group_name).gr_gid execute_cmd("modprobe scst proc_gid=%s" % str(group_gid)) sleep(1) else: execute_cmd("modprobe scst") sleep(1) if not kernel_module_loaded("scst_user"): execute_cmd("modprobe scst_user") sleep(1) if not os.path.exists("/dev/scst_user"): raise ScstException("SCST User target module (scst_user) is not started") else: if group_name: group = grp.getgrnam(group_name) if not check_file_group_access("/dev/scst_user", group.gr_gid): execute_cmd("chgrp %s /dev/scst_user" % group_name) execute_cmd("chmod g+rw /dev/scst_user")
def is_iscsi_running(): """ checks if iscsi scst is running. """ if not os.path.exists("/etc/init.d/iscsi-scst"): return False try: status = command.execute_cmd("ps ax|grep iscsi-scstd|grep -v grep|grep -v supervise") return status.find("iscsi-scstd") >= 0 except command.ExecutionError as e: if e.result == 1: return False else: raise ScstException("Failed to check if iSCSI is running", e)
def is_user_in_target(user_name, target): """ checks if a users from a target user_name is a string containing the username of check target is a Target object """ try: output = command.execute_cmd("%s --op show --tid=%s --user" % (get_iscsi_scst_path(), target.tid)) for line in output.split("\n"): p = line.partition(" ") if len(p[2]): if (p[2] == user_name): return True return False except Exception as e: raise ScstException("Failed to check if user in target", e);
def get_users_in_target(target): """ get all users from a target target is a target object returns a list of User objects """ try: output = command.execute_cmd("%s --op show --tid=%s --user" % (get_iscsi_scst_path(), target.tid)) users = [] for line in output.split("\n"): p = line.partition(" ") user_name = p[2] if len(user_name): u = scst_user.User(user_name, {}) users.append(u) return users except Exception as e: raise ScstException("Failed to get users in target", e);
def discover(server): """ frontend function to open-iscsi and its discovery function """ return execute_cmd("iscsiadm -m discovery -t sendtargets -p %s" % server)
def disconnect(server, name): """ disconnects from a given iSCSI target """ execute_cmd("iscsiadm -m node -p %s -T %s -u" % (server, name))
def start_device(dedupv1_root, monitor, options, config, bypass = False): """ starts the dedupv1 daemon """ def get_logging_output_file(logging_config_file): data = minidom.parse(logging_config_file) for ref in data.getElementsByTagName("param"): param_name = ref.getAttribute("name") if param_name == "filename": return ref.getAttribute("value") return None def uses_log4cxx(): return "LOGGING_LOG4CXX" in dir(cfg) and cfg.LOGGING_LOG4CXX if is_running(config): if options.force: log_info(options, "Lock file exists. Forcing start") lock_filename = config.get("daemon.lockfile") if os.path.exists(lock_filename): os.unlink(lock_filename) else: raise Exception("dedupv1d running") check_group = False daemon_user = config.get("daemon.user") daemon_group = config.get("daemon.group") check_iscsi = True no_iscsi = config.get("daemon.no-iscsi", "False") if no_iscsi == "True" or no_iscsi == "true": check_iscsi = False if check_root() and not daemon_user and not daemon_group: bootstrap_system(dedupv1_root, monitor, options, config) # check and start scst validate_dedupv1(dedupv1_root, daemon_user, daemon_group) scst.validate_scst(group_name = daemon_group) if check_iscsi: iscsi_scst.validate_iscsi() logging_config_file = None if uses_log4cxx(): logging_config_file = config.get("logging") if logging_config_file: if not os.path.exists(logging_config_file): raise Exception("Logging configuration file %s doesn't exists" % logging_config_file) if not os.path.isabs(logging_config_file): raise Exception("Logging configuration file %s must be absolute" % logging_config_file) # We are trying to create to logging output file with the correct user/group data if possible logging_output_file = get_logging_output_file(logging_config_file) if logging_output_file and uses_log4cxx(): if not os.path.exists(logging_output_file): execute_cmd("touch %s" % logging_output_file) if daemon_group: execute_cmd("chgrp %s %s" % (daemon_group, logging_output_file)) execute_cmd("chmod g+w %s" % (logging_output_file)) config.check_files() if not bypass: command = " ".join([os.path.join(dedupv1_root, "bin/dedupv1_starter"), sh_escape(options.configfile)]) else: # bypassing dedupv1_starter. Must run as root command = " ".join([os.path.join(dedupv1_root, "bin/dedupv1d"), sh_escape(options.configfile)]) if options.create: command = command + " --create" if options.force: command = command + " --force" if logging_config_file: command = command + " --logging \"" + logging_config_file + "\"" execute_cmd(command, direct_output = True) # Here we are doing tricks with starting dots if not options.raw: print "dedupv1d starting", try: found_running = False i = 0 while True: if not options.raw: sys.stdout.write(".") sys.stdout.flush() run_state = is_running(config, result_if_lockfile_missing = None) if run_state != None: if run_state and not found_running: found_running = True # Now we have seen the system running elif not run_state and found_running: raise Exception("Failed to start dedupv1") elif run_state and found_running: if check_connection(monitor): break elif not run_state and not found_running: if i > 4: raise Exception("Failed to start dedupv1") else: # If the system has not written a valid pid for so long, something bad as happened if i > 4: raise Exception("Failed to start dedupv1: Failed to check run state") time.sleep(2 * i) # backoff i = i + 1 # Cleanup SCST state, e.g. after a crash unregister_users_direct(options, config) unregister_targets_direct(options, config) unregister_groups_direct(options, config) register_groups(monitor, options, config) register_targets(monitor, options, config) register_volumes(monitor, options, config) register_users(monitor, options) if not options.raw: print print "dedupv1d started" except Exception as e: print "dedupv1 start (partly) failed. Shutting down remaining components." monitor_exception_raised = False; try: monitor.read("status", [("change-state", "fast-stop")]) except: monitor_exception_raised = True # Normally we use raise, but in this situation # We really want raise e, because we want that the original exception # is propagated and not any exception from monitor.read() that is here # only used as a kind of cleanup if monitor_exception_raised: raise e else: # no one destroyed the re-raise exception raise
def get_device_list(): """ returns a list of all block devices. The list does not only contain the iSCSI devices, but really all """ return [l.strip() for l in execute_cmd("ls /dev/disk/by-path")]