def delete(self): if self.is_empty(): return item = store.get(f"{self.SSPL_UNSENT_MESSAGES}/{self.head}") store.delete(f"{self.SSPL_UNSENT_MESSAGES}/{self.head}") self.head += 1 self.current_size -= sys.getsizeof(item)
def rss_cliapi_poll_disks(self, disk): """Retreive realstor disk info using cli api /show/disks""" # make ws request url = self.rssencl.build_url(self.rssencl.URI_CLIAPI_SHOWDISKS) if (disk != self.RSS_DISK_GET_ALL): diskId = disk.partition("0.")[2] if (diskId.isdigit()): url = f"{url}/{disk}" url = f"{url}/detail" response = self.rssencl.ws_request(url, self.rssencl.ws.HTTP_GET) if not response: logger.warn( f"{self.rssencl.LDR_R1_ENCL}:: Disks status unavailable as ws request {url} failed" ) return if response.status_code != self.rssencl.ws.HTTP_OK: if url.find(self.rssencl.ws.LOOPBACK) == -1: logger.error( f"{self.rssencl.LDR_R1_ENCL}:: http request {url} to poll disks failed with \ err {response.status_code}") return try: jresponse = json.loads(response.content) except ValueError as badjson: logger.error(f"{url} returned mal-formed json:\n{badjson}") if jresponse: api_resp = self.rssencl.get_api_status(jresponse['status']) #logger.debug("%s api response:%d" % (url.format(),api_resp)) if ((api_resp == -1) and (response.status_code == self.rssencl.ws.HTTP_OK)): logger.warn("/show/disks api response unavailable, " "marking success as http code is 200") api_resp = 0 if api_resp == 0: drives = jresponse['drives'] # reset latest drive cache to build new self.latest_disks = {} self.invalidate_latest_disks_info = False for drive in drives: slot = drive.get("slot", -1) sn = drive.get("serial-number", "NA") health = drive.get("health", "NA") if slot != -1: self.latest_disks[slot] = { "serial-number": sn, "health": health } #dump drive data to persistent cache dcache_path = f"{self.disks_prcache}disk_{slot}.json" # If drive is replaced, previous drive info needs # to be retained in disk_<slot>.json.prev file and # then only dump new data to disk_<slot>.json path_exists, ret_val = store.exists(dcache_path) if path_exists and ret_val == "Success": prevdrive = store.get(dcache_path) if prevdrive is not None: prevsn = prevdrive.get("serial-number", "NA") prevhealth = prevdrive.get("health", "NA") if prevsn != sn or prevhealth != health: # Rename path store.put(store.get(dcache_path), dcache_path + ".prev") store.delete(dcache_path) store.put(drive, dcache_path) elif not path_exists and ret_val == "Success": store.put(drive, dcache_path) else: # Invalidate latest disks info if persistence store error encountered logger.warn( f"store.exists {dcache_path} return value {ret_val}" ) self.invalidate_latest_disks_info = True break if self.invalidate_latest_disks_info is True: # Reset latest disks info self.latest_disks = {} #If no in-memory cache, build from persistent cache if not self.memcache_disks: self._rss_build_disk_cache_from_persistent_cache() # if no memory cache still if not self.memcache_disks: self.memcache_disks = self.latest_disks
def _rss_check_disks_presence(self): """Match cached realstor disk info with latest retrieved disks info """ self.rss_cliapi_poll_disks(self.RSS_DISK_GET_ALL) if not self.memcache_disks: if self.rssencl.active_ip != self.rssencl.ws.LOOPBACK: logger.warn( "Last polled drives info in-memory cache " "unavailable , unable to check drive presence change") return if not self.latest_disks: if self.rssencl.active_ip != self.rssencl.ws.LOOPBACK: logger.warn( "Latest polled drives info in-memory cache " "unavailable, unable to check drive presence change") return # keys are disk slot numbers removed_disks = set(self.memcache_disks.keys()) - set( self.latest_disks.keys()) inserted_disks = set(self.latest_disks.keys()) - set( self.memcache_disks.keys()) # get populated slots in both caches populated = set(self.memcache_disks.keys()) & set( self.latest_disks.keys()) # check for replaced disks for slot in populated: if self.memcache_disks[slot]['serial-number'] != self.latest_disks[ slot]['serial-number']: if slot not in removed_disks: removed_disks.add(slot) if slot not in inserted_disks: inserted_disks.add(slot) # If no difference seen between cached & latest set of disk list, # means no disk removal or insertion happened if not (removed_disks or inserted_disks): #logger.info("Disk presence state _NOT_ changed !!!") return self._event = Event() for slot in removed_disks: #get removed drive data from disk cache disk_datafile = f"{self.disks_prcache}disk_{slot}.json.prev" path_exists, _ = store.exists(disk_datafile) if not path_exists: disk_datafile = f"{self.disks_prcache}disk_{slot}.json" disk_info = store.get(disk_datafile) #raise alert for missing drive self._rss_raise_disk_alert(self.rssencl.FRU_MISSING, disk_info) # Wait till msg is sent to rabbitmq or added in consul for resending. # If timed out, do not update cache if self._event.wait(self.rssencl.PERSISTENT_DATA_UPDATE_TIMEOUT): store.delete(disk_datafile) self._event.clear() self._event = None for slot in inserted_disks: #get inserted drive data from disk cache disk_info = store.get(f"{self.disks_prcache}disk_{slot}.json") #raise alert for added drive self._rss_raise_disk_alert(self.rssencl.FRU_INSERTION, disk_info) # Update cached disk data after comparison self.memcache_disks = self.latest_disks self.rssencl.memcache_frus.update({"disks": self.memcache_disks}) return
def _rss_check_disks_presence(self): """Match cached realstor disk info with latest retrieved disks info """ self.rss_cliapi_poll_disks(self.RSS_DISK_GET_ALL) if not self.memcache_disks: if self.rssencl.active_ip != self.rssencl.ws.LOOPBACK: logger.warn("Last polled drives info in-memory cache " "unavailable , unable to check drive presence change") return if not self.latest_disks: if self.rssencl.active_ip != self.rssencl.ws.LOOPBACK: logger.warn("Latest polled drives info in-memory cache " "unavailable, unable to check drive presence change") return # keys are disk slot numbers removed_disks = set(self.memcache_disks.keys()) - set(self.latest_disks.keys()) inserted_disks = set(self.latest_disks.keys()) - set(self.memcache_disks.keys()) # get populated slots in both caches populated = set(self.memcache_disks.keys()) & set(self.latest_disks.keys()) # check for replaced disks for slot in populated: if self.memcache_disks[slot]['serial-number'] != self.latest_disks[slot]['serial-number']: if slot not in removed_disks: removed_disks.add(slot) if slot not in inserted_disks: inserted_disks.add(slot) # If no difference seen between cached & latest set of disk list, # means no disk removal or insertion happened if not (removed_disks or inserted_disks): #logger.info("Disk presence state _NOT_ changed !!!") return self._event = Event() for slot in removed_disks: #get removed drive data from disk cache disk_datafile = f"{self.disks_prcache}disk_{slot}.json.prev" path_exists, _ = store.exists(disk_datafile) if not path_exists: disk_datafile = f"{self.disks_prcache}disk_{slot}.json" disk_info = store.get(disk_datafile) #raise alert for missing drive self._rss_raise_disk_alert(self.rssencl.FRU_MISSING, disk_info) # Wait till msg is sent to message bus or added in consul for resending. # If timed out, do not update cache if self._event.wait(self.rssencl.PERSISTENT_DATA_UPDATE_TIMEOUT): store.delete(disk_datafile) self._event.clear() self._event = None for slot in inserted_disks: #get inserted drive data from disk cache disk_info = store.get(f"{self.disks_prcache}disk_{slot}.json") #raise alert for added drive self._rss_raise_disk_alert(self.rssencl.FRU_INSERTION, disk_info) # Update health status for inserted disk in memfault cache, # to raise fault alert after insertion if inserted disk status is not OK. if disk_info["health"] != "OK": for id_fault, cached_fault in enumerate(self.rssencl.memcache_faults): #fetch disk slot from component_id present in memcache_faults. try: component_id = cached_fault["component-id"] if component_id.startswith('Disk 0'): disk_id = int(cached_fault["component-id"].split()[1].split('.')[1]) if disk_id == slot: self.rssencl.memcache_faults[id_fault]['health'] = "OK" except Exception as e: logger.error(f"Error in updating health status for \ inserted disk in memfault cache {e}") # Update cached disk data after comparison self.memcache_disks = self.latest_disks self.rssencl.memcache_frus.update({"disks":self.memcache_disks}) return