def resolve_driver_format(self): """Return the driver format for self.path. First checks self.disk_info_path for an entry. If it's not there, calls self._get_driver_format(), and then stores the result in self.disk_info_path See https://bugs.launchpad.net/nova/+bug/1221190 """ def _dict_from_line(line): if not line: return {} try: return jsonutils.loads(line) except (TypeError, ValueError) as e: msg = (_("Could not load line %(line)s, got error " "%(error)s") % { 'line': line, 'error': e }) raise exception.InvalidDiskInfo(reason=msg) @utils.synchronized(self.disk_info_path, external=False, lock_path=self.lock_path) def write_to_disk_info_file(): # Use os.open to create it without group or world write permission. fd = os.open(self.disk_info_path, os.O_RDONLY | os.O_CREAT, 0o644) with os.fdopen(fd, "r") as disk_info_file: line = disk_info_file.read().rstrip() dct = _dict_from_line(line) if self.path in dct: msg = _("Attempted overwrite of an existing value.") raise exception.InvalidDiskInfo(reason=msg) dct.update({self.path: driver_format}) tmp_path = self.disk_info_path + ".tmp" fd = os.open(tmp_path, os.O_WRONLY | os.O_CREAT, 0o644) with os.fdopen(fd, "w") as tmp_file: tmp_file.write('%s\n' % jsonutils.dumps(dct)) os.rename(tmp_path, self.disk_info_path) try: if (self.disk_info_path is not None and os.path.exists(self.disk_info_path)): with open(self.disk_info_path) as disk_info_file: line = disk_info_file.read().rstrip() dct = _dict_from_line(line) for path, driver_format in six.iteritems(dct): if path == self.path: return driver_format driver_format = self._get_driver_format() if self.disk_info_path is not None: fileutils.ensure_tree(os.path.dirname(self.disk_info_path)) write_to_disk_info_file() except OSError as e: raise exception.DiskInfoReadWriteFail(reason=six.text_type(e)) return driver_format
def resolve_driver_format(self): """Return the driver format for self.path. First checks self.disk_info_path for an entry. If it's not there, calls self._get_driver_format(), and then stores the result in self.disk_info_path See https://bugs.launchpad.net/nova/+bug/1221190 """ def _dict_from_line(line): if not line: return {} try: return jsonutils.loads(line) except (TypeError, ValueError) as e: msg = (_("Could not load line %(line)s, got error " "%(error)s") % { 'line': line, 'error': unicode(e) }) raise exception.InvalidDiskInfo(reason=msg) @utils.synchronized(self.disk_info_path, external=False, lock_path=self.lock_path) def write_to_disk_info_file(): # Use os.open to create it without group or world write permission. fd = os.open(self.disk_info_path, os.O_RDWR | os.O_CREAT, 0o644) with os.fdopen(fd, "r+") as disk_info_file: line = disk_info_file.read().rstrip() dct = _dict_from_line(line) if self.path in dct: msg = _("Attempted overwrite of an existing value.") raise exception.InvalidDiskInfo(reason=msg) dct.update({self.path: driver_format}) disk_info_file.seek(0) disk_info_file.truncate() disk_info_file.write('%s\n' % jsonutils.dumps(dct)) # Ensure the file is always owned by the nova user so qemu can't # write it. # TODO chown for windows? # utils.chown(self.disk_info_path, owner_uid=getpass.getuser()) try: LOG.debug('Disk info path %s' % self.disk_info_path) if (self.disk_info_path is not None and os.path.exists(self.disk_info_path)): with open(self.disk_info_path) as disk_info_file: line = disk_info_file.read().rstrip() dct = _dict_from_line(line) for path, driver_format in dct.iteritems(): if path == self.path: return driver_format driver_format = self._get_driver_format() if self.disk_info_path is not None: fileutils.ensure_tree(os.path.dirname(self.disk_info_path)) write_to_disk_info_file() except OSError as e: raise exception.DiskInfoReadWriteFail(reason=unicode(e)) return driver_format