Esempio n. 1
0
    def __init__(self, devicename, expanderid, filename, verbosity=0):
        self.devicename = devicename
        self.expanderid = expanderid
        self.filename = filename
        self.verbosity = verbosity

        if os.geteuid() != 0:
            raise Exception("You must be running as root.")
        self.sp = SesPageSas(devicename)
Esempio n. 2
0
 def __init__(self, devicename, expanderid, filename, verbosity=0):
     self.devicename = devicename
     self.expanderid = expanderid
     self.filename   = filename
     self.verbosity  = verbosity
     
     if os.geteuid() != 0:
         raise Exception("You must be running as root.")
     self.sp = SesPageSas(devicename)
Esempio n. 3
0
 def __init__(self, ptdev, expanderid=None):
     """
     pt is a SCSI passthrough device file name
     expanderid can have one of the values
       0x01: SBB Canister A
       0x02: SBB Canister B
       0x03: FEM Canister A SAS Expander 1
       0x04: FEM Canister A SAS Expander 2
       0x05: FEM Canister B SAS Expander 1
       0x06: FEM Canister B SAS Expander 2
     Alternately, the first parameter may be a sequence of (ptdev,expanderid).
     """
     super(CliCmdSas, self).__init__()
     if not isinstance(ptdev, str):
         # If it's not a string, assume it's a sequence.
         ptdev, expanderid = ptdev
     self.ses = SesPageSas(ptdev)
     self.pt = ScsiPT(ptdev)
     self.expanderid = expanderid
Esempio n. 4
0
class CliCmdSas(CliCmd):

    def __init__(self, ptdev, expanderid=None):
        """
        pt is a SCSI passthrough device file name
        expanderid can have one of the values
          0x01: SBB Canister A
          0x02: SBB Canister B
          0x03: FEM Canister A SAS Expander 1
          0x04: FEM Canister A SAS Expander 2
          0x05: FEM Canister B SAS Expander 1
          0x06: FEM Canister B SAS Expander 2
        Alternately, the first parameter may be a sequence of (ptdev,expanderid).
        """
        super(CliCmdSas, self).__init__()
        if not isinstance(ptdev, str):
            # If it's not a string, assume it's a sequence.
            ptdev, expanderid = ptdev
        self.ses = SesPageSas(ptdev)
        self.pt = ScsiPT(ptdev)
        self.expanderid = expanderid

    def close(self):
        pass

    def __del__(self):
        #del self.ses
        pass

    def execute(self, command):
        """
        Send a CLI command through SES page 0xe8.
        """
        cmd = Cmd.clicommandout(self.expanderid, command)
        cdb = CDB(cmd.cdb)
        cdb.set_data_out(cmd.dat)
        self.pt.sendcdb(cdb)

        page = self.ses.parse(self.ses.readpage(0xe8))
        return page["data"].response.val
Esempio n. 5
0
class CliCmdSas(CliCmd):
    def __init__(self, ptdev, expanderid=None):
        """
        pt is a SCSI passthrough device file name
        expanderid can have one of the values
          0x01: SBB Canister A
          0x02: SBB Canister B
          0x03: FEM Canister A SAS Expander 1
          0x04: FEM Canister A SAS Expander 2
          0x05: FEM Canister B SAS Expander 1
          0x06: FEM Canister B SAS Expander 2
        Alternately, the first parameter may be a sequence of (ptdev,expanderid).
        """
        super(CliCmdSas, self).__init__()
        if not isinstance(ptdev, str):
            # If it's not a string, assume it's a sequence.
            ptdev, expanderid = ptdev
        self.ses = SesPageSas(ptdev)
        self.pt = ScsiPT(ptdev)
        self.expanderid = expanderid

    def close(self):
        pass

    def __del__(self):
        #del self.ses
        pass

    def execute(self, command):
        """
        Send a CLI command through SES page 0xe8.
        """
        cmd = Cmd.clicommandout(self.expanderid, command)
        cdb = CDB(cmd.cdb)
        cdb.set_data_out(cmd.dat)
        self.pt.sendcdb(cdb)

        page = self.ses.parse(self.ses.readpage(0xe8))
        return page["data"].response.val
Esempio n. 6
0
 def __init__(self, ptdev, expanderid=None):
     """
     pt is a SCSI passthrough device file name
     expanderid can have one of the values
       0x01: SBB Canister A
       0x02: SBB Canister B
       0x03: FEM Canister A SAS Expander 1
       0x04: FEM Canister A SAS Expander 2
       0x05: FEM Canister B SAS Expander 1
       0x06: FEM Canister B SAS Expander 2
     Alternately, the first parameter may be a sequence of (ptdev,expanderid).
     """
     super(CliCmdSas, self).__init__()
     if not isinstance(ptdev, str):
         # If it's not a string, assume it's a sequence.
         ptdev, expanderid = ptdev
     self.ses = SesPageSas(ptdev)
     self.pt = ScsiPT(ptdev)
     self.expanderid = expanderid
Esempio n. 7
0
 def probe():
     """
     Create Discovery.capabilities.  It is a dictionary indexed by capability.
     Value is a set of tuples:
       [0] is an arbitrary quality value, the lower the better.
       [1] is either a class or a sequence of classes used to create the access object.  If it's a sequence, the parameters are supplied to the last element, then the result is passed to the previous element, etc.
       [2] is a parameter to send to the class to construct the access object.
     """
     Discovery.capabilities = collections.defaultdict(set)
     for devfile in Discovery.discover_sas():
         for expanderid in (1, 2, 3, 5):
             cli = CliCmdSas(devfile, expanderid)
             for capability in Discovery.probe_cli(cli):
                 #print "cli capability of", devfile, expanderid, "=", Discovery.description[capability]
                 definition = (1, CliCmdSas, (devfile, expanderid))
                 Discovery.capabilities[capability].add(definition)
             cli.close()
         sp = SesPageSas(devfile)
         for capability in Discovery.probe_ses(sp):
             #print "ses capability of", devfile, "=", Discovery.description[capability]
             definition = (1, SesPageSas, devfile)
             Discovery.capabilities[capability].add(definition)
         sp.close()
     for devfile in Discovery.discover_serial():
         cli = None
         try:
             cli = CliCmdSerial(devfile)
         except:
             if cli:
                 cli.close()
             continue
         for capability in Discovery.probe_cli(cli):
             #print "cli capability of", devfile, "=", Discovery.description[capability]
             definition = (3, CliCmdSerial, devfile)
             Discovery.capabilities[capability].add(definition)
         sp = SesPageCli(cli)
         for capability in Discovery.probe_ses(sp):
             #print "ses capability of", devfile, "=", Discovery.description[capability]
             definition = (3, (SesPageCli, CliCmdSerial), devfile)
             Discovery.capabilities[capability].add(definition)
         sp.close()
Esempio n. 8
0
 def probe():
     """
     Create Discovery.capabilities.  It is a dictionary indexed by capability.
     Value is a set of tuples:
       [0] is an arbitrary quality value, the lower the better.
       [1] is either a class or a sequence of classes used to create the access object.  If it's a sequence, the parameters are supplied to the last element, then the result is passed to the previous element, etc.
       [2] is a parameter to send to the class to construct the access object.
     """
     Discovery.capabilities = collections.defaultdict(set)
     for devfile in Discovery.discover_sas():
         for expanderid in (1,2,3,5):
             cli = CliCmdSas(devfile, expanderid)
             for capability in Discovery.probe_cli(cli):
                 #print "cli capability of", devfile, expanderid, "=", Discovery.description[capability]
                 definition = ( 1, CliCmdSas, (devfile,expanderid) )
                 Discovery.capabilities[capability].add(definition)
             cli.close()
         sp = SesPageSas(devfile)
         for capability in Discovery.probe_ses(sp):
             #print "ses capability of", devfile, "=", Discovery.description[capability]
             definition = (1, SesPageSas, devfile)
             Discovery.capabilities[capability].add(definition)
         sp.close()
     for devfile in Discovery.discover_serial():
         cli = None
         try:
             cli = CliCmdSerial(devfile)
         except:
             if cli:
                 cli.close()
             continue
         for capability in Discovery.probe_cli(cli):
             #print "cli capability of", devfile, "=", Discovery.description[capability]
             definition = (3, CliCmdSerial, devfile)
             Discovery.capabilities[capability].add(definition)
         sp = SesPageCli(cli)
         for capability in Discovery.probe_ses(sp):
             #print "ses capability of", devfile, "=", Discovery.description[capability]
             definition = ( 3, (SesPageCli,CliCmdSerial), devfile )
             Discovery.capabilities[capability].add(definition)
         sp.close()
Esempio n. 9
0
class FirmwareSes:
    """
    Update firmware on one device.
    """

    chunksize = 4096  # Maximum number of bytes to send to device at one time.

    def __init__(self, devicename, expanderid, filename, verbosity=0):
        self.devicename = devicename
        self.expanderid = expanderid
        self.filename = filename
        self.verbosity = verbosity

        if os.geteuid() != 0:
            raise Exception("You must be running as root.")
        self.sp = SesPageSas(devicename)

    def set_filename(self, filename):
        self.filename = filename

    def update(self, callback=None):
        def mycallback(total_packets, success_count, error_count):
            if cb:
                cb(total_packets, success_count, error_count, file_packets)

        self.previous_line = ''

        def statuscallback(total_packets, success_count, error_count,
                           file_packets):
            #global previous_line
            this_line = " %d%%  %d err\r" % (total_packets * 100 /
                                             file_packets, error_count)
            if this_line != self.previous_line:
                self.previous_line = this_line
                sys.stdout.write(this_line)
                sys.stdout.flush()

        if callback:
            cb = callback
        else:
            if self.verbosity >= 1:
                cb = statuscallback
            else:
                cb = None
        file_packets = (os.path.getsize(self.filename) -
                        1) / FirmwareSes.chunksize + 1

        fwfile = open(self.filename, 'rb')
        offset = 0  # We're at the beginning of the file.

        microcode = fwfile.read()
        for offset in range(0, len(microcode), FirmwareSes.chunksize):
            mycallback(offset / FirmwareSes.chunksize, 0, 0)
            sesdat = self.sp.page_0e_fill(
                {
                    "mode": 0x0e,
                    "buf_offset": offset,
                    "data_len": min(FirmwareSes.chunksize,
                                    len(microcode[offset:])),
                    "firmware_image_id": 1,
                    "sas_expander_id": self.expanderid,
                }, microcode)
            result = self.sp.writepage(sesdat)
            if result != 0:
                print "aborting; result =", result
                break
            page0e_desc = self.sp.parse(
                self.sp.readpage(0x0e))["data"].descriptors.val[0]
            if page0e_desc.status.val not in (0x01, 0x13):
                print "aborting; status =", page0e_desc.status.val
                break
            if page0e_desc.status.val == 0x13:
                print "done? status =", page0e_desc.status.val
        sesdat = self.sp.page_0e_fill(
            {
                "mode": 0x0f,
                "buf_offset": offset,
                "data_len": min(FirmwareSes.chunksize, len(
                    microcode[offset:])),
                "firmware_image_id": 1,
                "sas_expander_id": self.expanderid,
            }, microcode)
        result = self.sp.writepage(sesdat)
        if result != 0:
            print "result =", result
        page0e = self.sp.parse(self.sp.readpage(0x0e))["data"]
        for descriptor in page0e.descriptors.val:
            print "Enclosure #" + str(descriptor.subid.val)
            print "    status                : %.2X - %s" % (
                descriptor.status.val, descriptor.status_text.val)
            print "    additional status     : %.2X" % descriptor.additional_status.val
            print "    maximum size          : %s" % format(
                descriptor.maxsize.val, ",d")
            print "    expected buffer id    : %.2X" % descriptor.expected_id.val
            print "    expected buffer offset: %.8X" % descriptor.expected_offset.val

    def identifyfile(self):
        """ Attempt to determine version and productid of a firmware file. """
        return FirmwareFile("").identifyfile(self.filename)
Esempio n. 10
0
class FirmwareSes:
    """
    Update firmware on one device.
    """
    
    chunksize = 4096  # Maximum number of bytes to send to device at one time.
    
    def __init__(self, devicename, expanderid, filename, verbosity=0):
        self.devicename = devicename
        self.expanderid = expanderid
        self.filename   = filename
        self.verbosity  = verbosity
        
        if os.geteuid() != 0:
            raise Exception("You must be running as root.")
        self.sp = SesPageSas(devicename)

    def set_filename(self, filename):
        self.filename = filename
    
    def update(self, callback=None):
        def mycallback(total_packets, success_count, error_count):
            if cb:
                cb(total_packets, success_count, error_count, file_packets)

        self.previous_line = ''
        def statuscallback(total_packets, success_count, error_count, file_packets):
            #global previous_line
            this_line = " %d%%  %d err\r" % (total_packets*100/file_packets, error_count)
            if this_line != self.previous_line:
                self.previous_line = this_line
                sys.stdout.write(this_line)
                sys.stdout.flush()

        if callback:
            cb = callback
        else:
            if self.verbosity >= 1:
                cb = statuscallback
            else:
                cb = None        
        file_packets = (os.path.getsize(self.filename)-1)/FirmwareSes.chunksize+1

        fwfile = open(self.filename, 'rb')
        offset = 0  # We're at the beginning of the file.
        
        microcode = fwfile.read()
        for offset in range(0, len(microcode), FirmwareSes.chunksize):
            mycallback(offset/FirmwareSes.chunksize, 0, 0)
            sesdat = self.sp.page_0e_fill({
                "mode":0x0e,
                "buf_offset":offset,
                "data_len":min(FirmwareSes.chunksize, len(microcode[offset:])),
                "firmware_image_id":1,
                "sas_expander_id":self.expanderid,
                }, microcode)
            result = self.sp.writepage(sesdat)
            if result != 0:
                print "aborting; result =", result
                break
            page0e_desc = self.sp.parse(self.sp.readpage(0x0e))["data"].descriptors.val[0]
            if page0e_desc.status.val not in (0x01, 0x13):
                print "aborting; status =", page0e_desc.status.val
                break
            if page0e_desc.status.val == 0x13:
                print "done? status =", page0e_desc.status.val
        sesdat = self.sp.page_0e_fill({
            "mode":0x0f,
            "buf_offset":offset,
            "data_len":min(FirmwareSes.chunksize, len(microcode[offset:])),
            "firmware_image_id":1,
            "sas_expander_id":self.expanderid,
            }, microcode)
        result = self.sp.writepage(sesdat)
        if result != 0:
            print "result =", result
        page0e = self.sp.parse(self.sp.readpage(0x0e))["data"]
        for descriptor in page0e.descriptors.val:
            print "Enclosure #" + str(descriptor.subid.val)
            print "    status                : %.2X - %s" % (descriptor.status.val, descriptor.status_text.val)
            print "    additional status     : %.2X" % descriptor.additional_status.val
            print "    maximum size          : %s" % format(descriptor.maxsize.val, ",d")
            print "    expected buffer id    : %.2X" % descriptor.expected_id.val
            print "    expected buffer offset: %.8X" % descriptor.expected_offset.val


    def identifyfile(self):
        """ Attempt to determine version and productid of a firmware file. """
        return FirmwareFile("").identifyfile(self.filename)