diff --git a/src/virtManager/addhardware.py b/src/virtManager/addhardware.py index 96bfdddcc..4feed3d5d 100644 --- a/src/virtManager/addhardware.py +++ b/src/virtManager/addhardware.py @@ -227,6 +227,10 @@ class vmmAddHardware(gobject.GObject): target_list.pack_start(text, True) target_list.add_attribute(text, 'text', 3) + # Disk cache mode + cache_list = self.window.get_widget("config-storage-cache") + uihelpers.build_cache_combo(self.vm, cache_list) + # Sparse tooltip sparse_info = self.window.get_widget("config-storage-nosparse-info") uihelpers.set_sparse_tooltip(sparse_info) @@ -546,6 +550,13 @@ class vmmAddHardware(gobject.GObject): device = model[idx][1] return bus, device + def get_config_disk_cache(self, label=False): + cache = self.window.get_widget("config-storage-cache") + idx = 0 + if label: + idx = 1 + return cache.get_model()[cache.get_active()][idx] + # Input getters def get_config_input(self): target = self.window.get_widget("input-type") @@ -742,6 +753,7 @@ class vmmAddHardware(gobject.GObject): (_("Disk size:"), size_str), (_("Device type:"), self._dev.device), (_("Bus type:"), self._dev.bus), + (_("Cache mode:"), self.get_config_disk_cache(label=True)), ] title = _("Storage") @@ -1089,6 +1101,7 @@ class vmmAddHardware(gobject.GObject): def validate_page_storage(self): bus, device = self.get_config_disk_target() + cache = self.get_config_disk_cache() # Make sure default pool is running if self.is_default_storage(): @@ -1139,7 +1152,8 @@ class vmmAddHardware(gobject.GObject): sparse = sparse, readOnly = readonly, device = device, - bus = bus) + bus = bus, + driverCache = cache) if (disk.type == virtinst.VirtualDisk.TYPE_FILE and not self.vm.is_hvm() and diff --git a/src/virtManager/details.py b/src/virtManager/details.py index 750ca8f05..99741cfe9 100644 --- a/src/virtManager/details.py +++ b/src/virtManager/details.py @@ -259,6 +259,7 @@ class vmmDetails(gobject.GObject): "on_disk_readonly_changed": self.config_enable_apply, "on_disk_shareable_changed": self.config_enable_apply, + "on_disk_cache_combo_changed": self.config_enable_apply, "on_network_model_combo_changed": self.config_enable_apply, @@ -557,6 +558,10 @@ class vmmDetails(gobject.GObject): txtCol.add_attribute(text, 'sensitive', BOOT_ACTIVE) no_default= not self.is_customize_dialog + # Disk cache combo + disk_cache = self.window.get_widget("disk-cache-combo") + uihelpers.build_cache_combo(self.vm, disk_cache) + # Network model net_model = self.window.get_widget("network-model-combo") uihelpers.build_netmodel_combo(self.vm, net_model) @@ -1248,10 +1253,13 @@ class vmmDetails(gobject.GObject): # Helper for accessing value of combo/label pattern def get_combo_label_value(self, prefix, model_idx=0): combo = self.window.get_widget(prefix + "-combo") + label = self.window.get_widget(prefix + "-label") value = None if combo.get_property("visible"): value = combo.get_model()[combo.get_active()][model_idx] + else: + value = label.get_text() return value @@ -1380,11 +1388,14 @@ class vmmDetails(gobject.GObject): def config_disk_apply(self, dev_id_info): do_readonly = self.window.get_widget("disk-readonly").get_active() do_shareable = self.window.get_widget("disk-shareable").get_active() + cache = self.get_combo_label_value("disk-cache") return self._change_config_helper([self.vm.define_disk_readonly, - self.vm.define_disk_shareable], + self.vm.define_disk_shareable, + self.vm.define_disk_cache], [(dev_id_info, do_readonly), - (dev_id_info, do_shareable)]) + (dev_id_info, do_shareable), + (dev_id_info, cache)]) # Audio options def config_sound_apply(self, dev_id_info): @@ -1753,6 +1764,7 @@ class vmmDetails(gobject.GObject): share = diskinfo[7] bus = diskinfo[8] idx = diskinfo[9] + cache = diskinfo[10] size = _("Unknown") if not path: @@ -1778,6 +1790,7 @@ class vmmDetails(gobject.GObject): self.window.get_widget("disk-readonly").set_sensitive(not is_cdrom) self.window.get_widget("disk-shareable").set_active(share) self.window.get_widget("disk-size").set_text(size) + self.set_combo_label("disk-cache", 0, cache) button = self.window.get_widget("config-cdrom-connect") if is_cdrom or is_floppy: diff --git a/src/virtManager/domain.py b/src/virtManager/domain.py index 0e656286d..a56cb830c 100644 --- a/src/virtManager/domain.py +++ b/src/virtManager/domain.py @@ -418,6 +418,7 @@ class vmmDomainBase(vmmLibvirtObject): readonly = False sharable = False devtype = node.prop("device") + cache = None if devtype == None: devtype = "disk" for child in node.children: @@ -431,6 +432,8 @@ class vmmDomainBase(vmmLibvirtObject): readonly = True elif child.name == "shareable": sharable = True + elif child.name == "driver": + cache = child.prop("cache") if srcpath == None: if devtype == "cdrom" or devtype == "floppy": @@ -440,7 +443,7 @@ class vmmDomainBase(vmmLibvirtObject): # disk device type, disk type, readonly?, sharable?, # bus type, disk idx ] disks.append(["disk", devdst, devdst, srcpath, devtype, typ, - readonly, sharable, bus, 0]) + readonly, sharable, bus, 0, cache]) # Iterate through all disks and calculate what number they are idx_mapping = {} @@ -1825,6 +1828,29 @@ class vmmDomain(vmmDomainBase): return self._redefine(util.xml_parse_wrapper, self._change_disk_param, dev_id_info, "shareable", do_shareable) + def define_disk_cache(self, dev_id_info, new_cache): + devtype = "disk" + if not self._check_device_is_present(devtype, dev_id_info): + return + + def change_cache(doc, ctx): + dev_node = self._get_device_xml_nodes(ctx, devtype, dev_id_info)[0] + tmpnode = dev_node.xpathEval("./driver") + node = tmpnode and tmpnode[0] or None + + if not node: + if new_cache: + node = dev_node.newChild(None, "driver", None) + + if new_cache: + node.setProp("cache", new_cache) + else: + node.unsetProp("cache") + + return doc.serialize() + + return self._redefine(util.xml_parse_wrapper, change_cache) + # Network properties def define_network_model(self, dev_id_info, newmodel): devtype = "interface" diff --git a/src/virtManager/uihelpers.py b/src/virtManager/uihelpers.py index 1715d604d..b54519832 100644 --- a/src/virtManager/uihelpers.py +++ b/src/virtManager/uihelpers.py @@ -223,6 +223,21 @@ def populate_netmodel_combo(vm, combo): for m in mod_list: model.append([m, m]) +def build_cache_combo(vm, combo, no_default=False): + dev_model = gtk.ListStore(str, str) + combo.set_model(dev_model) + text = gtk.CellRendererText() + combo.pack_start(text, True) + combo.add_attribute(text, 'text', 1) + dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING) + + combo.set_active(-1) + for m in virtinst.VirtualDisk.cache_types: + dev_model.append([m, m]) + + if not no_default: + dev_model.append([None, "default"]) + combo.set_active(0) ####################################################################### # Widgets for listing network device options (in create, addhardware) # diff --git a/src/vmm-add-hardware.glade b/src/vmm-add-hardware.glade index 29b5d29bc..cbc729545 100644 --- a/src/vmm-add-hardware.glade +++ b/src/vmm-add-hardware.glade @@ -436,21 +436,12 @@ - + True - 12 - - - True - _Device type: - True - - - False - False - 0 - - + 2 + 2 + 6 + 6 True @@ -460,8 +451,47 @@ - False - 1 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + 0 + _Device type: + True + + + GTK_FILL + + + + + True + Cache _mode: + True + config-storage-cache + + + 1 + 2 + GTK_FILL + + + + + True + + + 1 + 2 + 1 + 2 + GTK_FILL + GTK_FILL diff --git a/src/vmm-details.glade b/src/vmm-details.glade index 73e2bc42d..daa235318 100644 --- a/src/vmm-details.glade +++ b/src/vmm-details.glade @@ -2613,7 +2613,7 @@ I/O: True 3 - 5 + 6 3 8 4 @@ -2766,8 +2766,8 @@ I/O: Storage size: - 4 - 5 + 5 + 6 GTK_FILL @@ -2777,6 +2777,51 @@ I/O: 0 size + + 1 + 2 + 5 + 6 + + + + + True + 1 + Cac_he mode: + True + + + 4 + 5 + GTK_FILL + + + + + True + + + True + + + + False + 0 + + + + + True + 0 + Unknown cache + + + False + 1 + + + 1 2 @@ -2790,6 +2835,9 @@ I/O: + + +