def get_disk_details():
    disks = {}
    disks_map = {}
    cmd = cmd_utils.Command('hwinfo --disk')
    out, err, rc = cmd.run()
    if not err:
        out = unicodedata.normalize('NFKD', out).encode('utf8', 'ignore') \
            if isinstance(out, unicode) \
               else unicode(out, errors="ignore").encode('utf8')
        for all_disks in out.split('\n\n'):
            devlist = {"disk_id": "",
                       "hardware_id": "",
                       "parent_id": "",
                       "disk_name": "",
                       "sysfs_id": "",
                       "sysfs_busid": "",
                       "sysfs_device_link": "",
                       "hardware_class": "",
                       "model": "",
                       "vendor": "",
                       "device": "",
                       "rmversion": "",
                       "serial_no": "",
                       "driver_modules": "",
                       "driver": "",
                       "device_files": "",
                       "device_number": "",
                       "bios_id": "",
                       "geo_bios_edd": "",
                       "geo_logical": "",
                       "size": "",
                       "size_bios_edd": "",
                       "geo_bios_legacy": "",
                       "config_status": "",
                       "partitions": {}
                       }
            for disk in all_disks.split('\n'):
                key = disk.split(':')[0]
                if key.strip() == "Unique ID":
                    devlist["hardware_id"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "Parent ID":
                    devlist["parent_id"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "SysFS ID":
                    devlist["sysfs_id"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "SysFS BusID":
                    devlist["sysfs_busid"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "SysFS Device Link":
                    devlist["sysfs_device_link"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "Hardware Class":
                    devlist["hardware_class"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "Model":
                    devlist["model"] = \
                        disk.split(':')[1].lstrip().replace('"', "")
                elif key.strip() == "Vendor":
                    devlist["vendor"] = \
                        disk.split(':')[1].replace(" ", "").replace('"', "")
                elif key.strip() == "Device":
                    devlist["device"] = \
                        disk.split(':')[1].replace(" ", "").replace('"', "")
                elif key.strip() == "Revision":
                    devlist["rmversion"] = \
                        disk.split(':')[1].lstrip().replace('"', "")
                elif key.strip() == "Serial ID":
                    devlist["serial_no"] = \
                        disk.split(':')[1].replace(" ", "").replace('"', "")
                elif key.strip() == "Driver":
                    devlist["driver"] = \
                        disk.split(':')[1].lstrip().replace('"', "")
                elif key.strip() == "Driver Modules":
                    devlist["driver_modules"] = \
                        disk.split(':')[1].lstrip().replace('"', "")
                elif key.strip() == "Device File":
                    _name = disk.split(':')[1].lstrip()
                    devlist["disk_name"] = \
                        "".join(_name.split(" ")[0])
                elif key.strip() == "Device Files":
                    devlist["device_files"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "Device Number":
                    devlist["device_number"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "BIOS id":
                    devlist["bios_id"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "Geometry (Logical)":
                    devlist["geo_logical"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "Capacity":
                    devlist["size"] = \
                        disk.split('(')[1].split()[0]
                elif key.strip() == "Geometry (BIOS EDD)":
                    devlist["geo_bios_edd"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "Size (BIOS EDD)":
                    devlist["size_bios_edd"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "Geometry (BIOS Legacy)":
                    devlist["geo_bios_legacy"] = \
                        disk.split(':')[1].lstrip()
                elif key.strip() == "Config Status":
                    devlist["config_status"] = \
                        disk.split(':')[1].lstrip()
            if ("virtio" in devlist["driver"] and
                    "by-id/virtio" in devlist['device_files']):
                # split from:
                # /dev/vdc, /dev/disk/by-id/virtio-0200f64e-5892-40ee-8,
                #    /dev/disk/by-path/virtio-pci-0000:00:08.0
                for entry in devlist['device_files'].split(','):
                    if "by-id/virtio" in entry:
                        devlist['disk_id'] = entry.split('/')[-1]
                        break
            elif "VMware" in devlist["vendor"]:
                 devlist["disk_id"] = \
                    "{vendor}_{device}_{parent_id}_{hardware_id}".format(**devlist)
            elif (devlist["vendor"] != "" and
                    devlist["device"] != "" and
                    devlist["serial_no"] != ""):
                devlist["disk_id"] = (devlist["vendor"] + "_" +
                                      devlist["device"] + "_" + devlist[
                    "serial_no"])
            else:
                devlist['disk_id'] = devlist['disk_name']
            if devlist["disk_id"] in disks.keys():
                # Multipath is like multiple I/O paths between
                # server nodes and storage arrays into a single device
                # If single device is connected with more than one path
                # then hwinfo and lsblk will give same device details with
                # different device names. To avoid this duplicate entry,
                # If multiple devices exists with same disk_id then
                # device_name which is lower in alphabetical order is stored.
                # It will avoid redundacy of disks and next sync it will
                # make sure same device detail is populated
                if devlist["disk_name"] < disks[
                        devlist['disk_id']]['disk_name']:
                    disks[devlist["disk_id"]] = devlist
                    disks_map[devlist['hardware_id']] = devlist["disk_id"]
            else:
                disks[devlist["disk_id"]] = devlist
                disks_map[devlist['hardware_id']] = devlist["disk_id"]
    return disks, disks_map, err