001/* 002 * To change this template, choose Tools | Templates 003 * and open the template in the editor. 004 */ 005package org.anarres.qemu.exec; 006 007import java.util.HashMap; 008import java.util.List; 009import java.util.Map; 010import javax.annotation.Nonnegative; 011import javax.annotation.Nonnull; 012import org.anarres.qemu.exec.util.QEmuIdAllocator; 013import org.anarres.qemu.exec.vm.device.QEmuDevice; 014 015/** 016 * A device frontend, exposed to the guest operating system. 017 * 018 * To list the device types supported by your QEmu installation, run 019 * <code>qemu -device help</code>. 020 * 021 * To list the properties of a device, run 022 * <code>qemu -device <devicetype>,help</code>. 023 * 024 * @see QEmuDevice 025 * @author shevek 026 */ 027public class QEmuDeviceOption extends AbstractQEmuOption { 028 029 public static final String PROP_ID = "id"; 030 public static final String PROP_BUS = "bus"; 031 public static final String PROP_ADDR = "addr"; 032 private final String name; 033 private final Map<String, String> properties = new HashMap<String, String>(); 034 035 public QEmuDeviceOption(@Nonnull String name) { 036 this.name = name; 037 } 038 039 @Nonnull 040 public QEmuDeviceOption withProperties(@Nonnull Map<String, String> properties) { 041 this.properties.putAll(properties); 042 return this; 043 } 044 045 @Nonnull 046 public QEmuDeviceOption withProperty(@Nonnull String key, @Nonnull String value) { 047 properties.put(key, value); 048 return this; 049 } 050 051 @Nonnull 052 public QEmuDeviceOption withProperty(@Nonnull String key) { 053 properties.put(key, null); 054 return this; 055 } 056 057 @Nonnull 058 public QEmuDeviceOption withId(@Nonnull String id) { 059 return withProperty(PROP_ID, id); 060 } 061 062 @Override 063 public void appendTo(List<? super String> line) { 064 StringBuilder buf = new StringBuilder(name); 065 appendTo(buf, properties); 066 add(line, "-device", buf); 067 } 068 069 public static class Pci extends QEmuDeviceOption { 070 071 // virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 072 public Pci(@Nonnull String name) { 073 super(name); 074 withPciBus("pci.0"); 075 } 076 077 @Override 078 public Pci withId(@Nonnull String id) { 079 super.withId(id); 080 return this; 081 } 082 083 @Nonnull 084 public Pci withPciBus(@Nonnull String bus) { 085 withProperty(PROP_BUS, bus); 086 return this; 087 } 088 089 @Nonnull 090 public Pci withPciAddress(@Nonnull String address) { 091 withProperty(PROP_ADDR, address); 092 return this; 093 } 094 095 @Nonnull 096 public Pci withPciAddress(@Nonnull QEmuIdAllocator allocator) { 097 withProperty(PROP_ADDR, allocator.newPciAddress()); 098 return this; 099 } 100 } 101 102 public static class VirtioBalloon extends Pci { 103 104 public VirtioBalloon() { 105 super("virtio-balloon-pci"); 106 } 107 } 108 109 public static class VirtioNet extends Pci { 110 111 // virtio-net-pci,netdev=hostnet0,id=net0,mac=fa:16:3e:13:ff:1f,bus=pci.0,addr=0x3 112 public static final String PROP_NETDEV = "netdev"; 113 public static final String PROP_MAC = "mac"; 114 public static final String PROP_BOOTINDEX = "bootindex"; 115 public static final String PROP_ROMFILE = "romfile"; 116 public static final String PROP_ROMBAR = "rombar"; 117 118 public VirtioNet() { 119 super("virtio-net-pci"); 120 } 121 122 @Nonnull 123 public VirtioNet withMac(@Nonnull String mac) { 124 withProperty(PROP_MAC, mac); 125 return this; 126 } 127 128 @Nonnull 129 public VirtioNet withBackend(@Nonnull QEmuNetdevOption backend) { 130 withProperty(PROP_NETDEV, backend.id); 131 return this; 132 } 133 134 @Nonnull 135 public VirtioNet withBootIndex(@Nonnegative int index) { 136 withProperty(PROP_BOOTINDEX, String.valueOf(index)); 137 return this; 138 } 139 140 @Nonnull 141 public VirtioNet withBootIndex(@Nonnull QEmuIdAllocator allocator) { 142 return withBootIndex(allocator.newNetworkBootIndex()); 143 } 144 } 145 146 /** Usually results in /dev/vda. */ 147 public static class VirtioBlock extends Pci { 148 // virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 149 150 public static final String PROP_SCSI = "scsi"; 151 public static final String PROP_DRIVE = "drive"; 152 public static final String PROP_BOOTINDEX = "bootindex"; 153 154 public VirtioBlock() { 155 super("virtio-blk-pci"); 156 } 157 158 @Nonnull 159 public VirtioBlock withDrive(String id) { 160 withProperty(PROP_DRIVE, id); 161 return this; 162 } 163 164 @Nonnull 165 public VirtioBlock withDrive(@Nonnull QEmuDriveOption option) { 166 return withDrive(option.id); 167 } 168 } 169 170 public static class VirtioScsi extends Pci { 171 172 public VirtioScsi() { 173 super("virtio-scsi-pci"); 174 } 175 } 176 177 public static class VirtioSerial extends Pci { 178 179 public static final String PROP_CHARDEV = "chardev"; 180 181 public VirtioSerial() { 182 super("virtio-serial-pci"); 183 } 184 185 @Override 186 public VirtioSerial withId(@Nonnull String id) { 187 super.withId(id); 188 return this; 189 } 190 191 @Nonnull 192 public VirtioSerial withChardev(String id) { 193 withProperty(PROP_CHARDEV, id); 194 return this; 195 } 196 197 @Nonnull 198 public VirtioSerial withChardev(@Nonnull QEmuChardevOption option) { 199 return withChardev(option.id); 200 } 201 } 202 203 public static class Piix3Usb extends Pci { 204 205 // piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 206 public Piix3Usb() { 207 super("piix3-usb-uhci"); 208 withId("usb"); 209 } 210 211 @Override 212 public Piix3Usb withPciAddress(@Nonnull QEmuIdAllocator allocator) { 213 withProperty(PROP_ADDR, allocator.newPciAddresses(2, ".")); 214 return this; 215 } 216 } 217 218 public static class Isa extends QEmuDeviceOption { 219 220 public Isa(String name) { 221 super(name); 222 } 223 224 @Override 225 public Isa withId(@Nonnull String id) { 226 super.withId(id); 227 return this; 228 } 229 } 230 231 public static class IsaSerial extends Isa { 232 // isa-serial,chardev=charserial0,id=serial0 233 234 public static final String PROP_CHARDEV = "chardev"; 235 236 public IsaSerial() { 237 super("isa-serial"); 238 } 239 240 @Override 241 public IsaSerial withId(@Nonnull String id) { 242 super.withId(id); 243 return this; 244 } 245 246 @Nonnull 247 public IsaSerial withChardev(String id) { 248 withProperty(PROP_CHARDEV, id); 249 return this; 250 } 251 } 252}