-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathdisks_in_Qubes
125 lines (104 loc) · 6.78 KB
/
disks_in_Qubes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
The standard presentation of disks in Qubes is for disks xvda,etc to be
presented as SCSI disks.
In 2017, the default controller was changed to use the qemu mptsas1068
controller because the standard controller was not recognised by Windows
7 and Windows 10 installers.
An unintended side effect of this was that some *other* installers now failed to
work - e.g ReactOS and Android. These installers no longer see disks on
which they can install.
The relevant patch is in vmm-xen/patch-stubdom-linux-0005.patch, which patches
tools/libxl/libxl_dm.c - this sets the device parameter in the qemu boot.
+ if (b_info->stubdomain_version == LIBXL_STUBDOMAIN_VERSION_LINUX)
+ flexarray_append_pair(dm_args, "-device", "mptsas1068,id=scsi0");
It may be worth testing other qemu SCSI controllers to see if any are compatible both
with Windows and ReactOS.
In the meantime, it's possible to work around the problem, by redefining the
device on the fly when the relevant qube is started.
Let's look at the process - create a new HVM, and start it - no need to attach a
boot device at this stage.
`qvm-ls --format full new_HVM` will give the UUID for the qube.
The UUID canbe used to access the relevant entries in xenstore, like this:
`xenstore-list /vm/c4f3fb4f-e6ec-427d-81d4-9b5e35657099 `. Digging a
little further, there is an an entry for dmargs -
`xenstore-read /vm/c4f3fb4f-e6ec-427d-81d4-9b5e35657099/image/dmargs` produces
this output:
-xen-domid\x1b446\x1b-nodefaults\x1b-no-user-config\x1b-name\x1breactor\x1b-display\x1bnone\x1b-device\x1bcirrus-vga,vgamem_mb=8\x1b-boot\x1border=dc\x1b-device\x1busb-ehci,id=ehci\x1b-device\x1busb-tablet,bus=ehci.0\x1b-net\x1bnone\x1b-display\x1bqubes-gui\x1b-machine\x1bxenfv\x1b-m\x1b2040\x1b-device\x1bmptsas1068,id=scsi0\x1b-drive\x1bfile=/dev/xvda,if=none,id=disk0,format=host_device,cache=writeback,readonly=off\x1b-device\x1bscsi-hd,bus=scsi0.0,drive=disk0,wwn=0x3525400051756265\x1b-drive\x1bfile=/dev/xvdb,if=none,id=disk1,format=host_device,cache=writeback,readonly=off\x1b-device\x1bscsi-hd,bus=scsi0.0,drive=disk1,wwn=0x3525400051756266\x1b-drive\x1bfile=/dev/xvdc,if=none,id=disk2,format=host_device,cache=writeback,readonly=off\x1b-device\x1bscsi-hd,bus=scsi0.0,drive=disk2,wwn=0x3525400051756267\x1b-drive\x1bif=ide,readonly=on,media=cdrom,id=ide-51840,file=/dev/xvdi,format=host_device
It's clear that \x1b is used as the delimiter here: replacing it with a space,and breaking
down what's there produces this clearer output:
-device mptsas1068,id=scsi0
-drive file=/dev/xvda,if=none,id=disk0,format=host_device,cache=writeback,readonly=off -device scsi-hd,bus=scsi0.0,drive=disk0,wwn=0x3525400051756265
-drive file=/dev/xvdb,if=none,id=disk1,format=host_device,cache=writeback,readonly=off -device scsi-hd,bus=scsi0.0,drive=disk1,wwn=0x3525400051756266
-drive file=/dev/xvdc,if=none,id=disk2,format=host_device,cache=writeback,readonly=off -device scsi-hd,bus=scsi0.0,drive=disk2,wwn=0x3525400051756267
-drive if=ide,readonly=on,media=cdrom,id=ide-51840,file=/dev/xvdi,format=host_device
This shows where the device driver is set, and also the handling of the
disks, as well as the cdrom device.
In a Qubes system, the HVM boot process runs from /usr/lib/xen/boot,
and the root files can be found at /usr/lib/xen/boot/stubdom-linux-rootfs.
This is a gzipped archive, as `file` will show.
`cp /usr/lib/xen/boot/stubdom-linux-rootfs stubdom-linux-rootfs `
`mv stubdom-linux-rootfs stubdom-linux-rootfs.gz`
`gunzip stubdom-linux-rootfs `
`file` shows that the resulting file is an ASCII cpio archive, and the
relevant structure can be extracted as follows:
`cpio -i -d -H newc --no-absolute-filenames < stubdom-linux-rootfs`
Remove the archive file - `rm stubdom-linux-rootfs`
In the init file, the qemu call is clear:
```
# $dm_args and $kernel are separated with \x1b to allow for spaces in arguments.
IFS=$'\x1b'
set -f
qemu -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-chardev pipe,path=/tmp/qmp/qemu,id=m -mon chardev=m,mode=control \
$dm_args $kernel &
set +f
unset IFS
```
where dm_args=$(xenstore-read -R "$vm_path/image/dmargs") .
The init file is a shell script, and if the arguments are manipulated
here, then the HVM will boot with a different configuration. It is simple
to add *more* arguments to the boot parameters, or to change existing
arguments.
In this case, change the parameters in dm_args for the xvda device using sed,
referring back to the earlier argument list.
`sed "s%-drive\\${IFS}file=/dev/xvda,if=none,id=disk0,format=host_device,cache=writeback,readonly=off\\${IFS}-device\\${IFS}scsi-hd,bus=scsi0.0,drive=disk.,wwn=0x352540005175626.%-drive\\${IFS}if=ide,media=disk,file=/dev/xvda,id=disk0,format=host_device,cache=writeback,readonly=off%g"
It would be simple to reduce this somewhat using a regexp.
`sed "s%-drive\\${IFS}file=/dev/xvda.*wwn=0x352540005175626.%-drive\\${IFS}if=ide,media=disk,file=/dev/xvda,id=disk0,format=host_device,cache=writeback,readonly=off%g"
Now, the HVM will boot, and the xvda device will be presented as a standard
disk on the IDE bus.
The changed file looks like this:
```
# $dm_args and $kernel are separated with \x1b to allow for spaces in arguments.
IFS=$'\x1b'
dm_args=$(echo "$dm_args" | sed "s%-drive\\${IFS}file=/dev/xvda.*wwn=0x352540005175626.%-drive\\${IFS}if=ide,media=disk,file=/dev/xvda,id=disk0,format=host_device,cache=writeback,readonly=off%g")
set -f
qemu -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-chardev pipe,path=/tmp/qmp/qemu,id=m -mon chardev=m,mode=control \
$dm_args $kernel &
set +f
unset IFS
```
Once the file has been changed, rebuild the archive:
`find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../stubdom-linux-rootfs-new`
`cp ../stubdom-linux-rootfs-new /usr/lib/xen/boot/stubdom-linux-rootfs `
Now when the HVM is booted with a ReactOS CD attached, the installer identifies
a target for installation, and the install proceeds.
As it stands, this change applies to **all** HVMs.
It is possible to target the change using the name of the HVM - this
imposes on the user some degree of consistency in the naming of qubes.
For example, it is possible to get the name of a qube using xenstore-read,
and to use that as a condition in applying the `sed` command.
So the above sed line could be wrapped in a conditional:
```
IFS=$'\x1b'
qube_name=$(xenstore-read "/local/domain/$domid/name")
case "$qube_name" in
react*)
dm_args=$(echo "$dm_args" | sed "s%-drive\\${IFS}file=/dev/xvda.*wwn=0x352540005175626.%-drive\\${IFS}if=ide,media=disk,file=/dev/xvda,id=disk0,format=host_device,cache=writeback,readonly=off%g") ;;
esac
set -f
qemu -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-chardev pipe,path=/tmp/qmp/qemu,id=m -mon chardev=m,mode=control \
$dm_args $kernel &
set +f
unset IFS
```