#!/bin/bash /usr/scripts/python.sh # -*- coding: utf-8 -*- # # Auteur : Pierre-Elliott Bécue # Inspiré du travail de Jérémie Dimino # Licence : BSD3 import sys import os from gestion.affich_tools import coul import udev_get_iscsi_name as ugin import subprocess PATH = "/dev/disk/by-path/" def store_iscsi_volumes(): """Extrait la liste des volumes de /dev/disk/by-path/ip-*""" links = {} # os.listdir retourne une liste désordonnée, l'idée est de privilégier # l'ordre lexicographique pour que l'état du retour soit identifié. state = subprocess.Popen(['ls', PATH], stdout=subprocess.PIPE) state = state.stdout.readlines() for line in state: line = line.replace('\n', '') if line.startswith('ip-'): if "storage.p2000g3" in line: baie = "nols" else: baie = "slon" device = os.readlink(PATH+line) # de la forme ../../sdb42 device = device.rsplit('/', 1)[1] symlink = 'iscsi_' + ugin.getname(device, baie) if line.rsplit('-', 1)[1][0:4] == "part": lun = line.rsplit('-', 2)[1] else: lun = line.rsplit('-', 1)[1] if links.has_key(lun): if not (True in [(symlink in tup) for tup in links[lun]]): links[lun].append((symlink, device)) else: links[lun] = [(symlink, device)] return links def make_link(couple): """Crée le symlink /dev/iscsi_nom -> /dev/sdb42""" os.chdir("/dev/") res = [] for (sym, dev) in couple: diskstatus = subprocess.Popen(['file', '-sb', '/dev/' + dev], stdout=subprocess.PIPE) diskstatus = diskstatus.stdout.readlines()[0] if not (os.path.islink(sym)) and not 'empty' in diskstatus and not 'ERROR' in diskstatus: sys.stdout.write("Création du lien /dev/" + sym + " -> /dev/" + dev + " … ") try: os.symlink(dev, sym) res.append(True) sys.stdout.write(coul("OK", 'vert')) except: res.append(False) sys.stdout.write(coul("ECHEC", 'rouge')) sys.stdout.write('\n') elif os.path.islink(sym) and ('empty' in diskstatus or 'ERROR' in diskstatus): sys.stdout.write("Destruction du lien /dev/" + sym + " … ") try: os.remove(sym) res.append(True) sys.stdout.write(coul("OK", 'vert')) except: res.append(False) sys.stdout.write(coul("ECHEC", 'rouge')) sys.stdout.write('\n') elif os.path.islink(sym) and os.readlink(sym) != dev: sys.stdout.write("Mise à jour du lien /dev/" + sym + " -> /dev/" + dev + " … ") try: os.remove(sym) os.symlink(dev, sym) res.append(True) sys.stdout.write(coul("OK", 'vert')) except: res.append(False) sys.stdout.write(coul("ECHEC", 'rouge')) sys.stdout.write('\n') else: res.append(None) return res def clean_iscsi_links(): """Nettoie les liens présents dans /dev/iscsi_*""" links = {} # os.listdir retourne une liste désordonnée, l'idée est de privilégier # l'ordre lexicographique pour que l'état du retour soit identifié. state = subprocess.Popen(['ls', '/dev'], stdout=subprocess.PIPE) state = state.stdout.readlines() for line in state: line = line.replace('\n', '') if line.startswith('iscsi_'): device = os.readlink('/dev/'+line) # de la forme ../../sdb42 symlink = line make_link([(symlink, device)]) return links if __name__ == '__main__': if "-h" in sys.argv or "--help" in sys.argv: print "Usage: udev_update_symlinks.py " print " -h, --help : print this message and exit" print " --clean : clean empty links no longer referenced" if "--clean" in sys.argv: clean_iscsi_links() nothing = True links = store_iscsi_volumes() for path in links.keys(): cmd = make_link(links[path]) if True in cmd or False in cmd: nothing = False if nothing: sys.stdout.write("Terminé, pas de changement pour les liens.\n") else: sys.stdout.write("Terminé.\n")