summaryrefslogtreecommitdiffstats
path: root/core/modules/vmware-common/data/opt/openslx/vmchooser/plugins/vmware/includes/write_final_vmx.inc
blob: 8fb672b74b7e71eb2f5e1a2bde871516dddb677e (plain) (blame)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
#!/bin/bash
################################################
# Include: Create final VMX configuration file #
################################################


# check for vmdk file marker %VM_DISK_PATH% and put vmdk path in it's place: also VM_DISK_MODE
# and VM_DISK_REDOLOGDIR.
replace_placeholders() {
	if [ -n "$VM_DISKFILE_RW" ]; then
		sed -i 's#%VM_DISK_PATH%#'"$VM_DISKFILE_RW"'#g' "${TMPCONFIG}"
		sed -i 's#%VM_DISK_MODE%#'"independent-persistent"'#g' "${TMPCONFIG}"
	else
		sed -i 's#%VM_DISK_PATH%#'"$VM_DISKFILE_RO"'#g' "${TMPCONFIG}"
		sed -i 's#%VM_DISK_MODE%#'"independent-nonpersistent"'#g' "${TMPCONFIG}"
	fi
	sed -i 's#%VM_DISK_REDOLOGDIR%#'"$VM_REDO_DIR"'#g' "${TMPCONFIG}"
}

# Ethernet: All we do is entering a generated MAC, as we do not want to interfere
# in the possible case no networking is wanted.
setup_ethernet() {
	echo 'ethernet0.addressType = "static"'		>> "${TMPCONFIG}"
	echo 'ethernet0.address = "'"${VM_MAC_ADDR}"'"'	>> "${TMPCONFIG}"
	if [ -n "$OTHER_NICS" ]; then
		local devtype mac cnt eth
		# Copy type of eth0, in case the others don't specify a type in the vmx, we'll use the same
		# so we know the drivers are there
		devtype=$(< "${TMPCONFIG}"  grep -m1 -i '^ethernet0\.virtualDev' | sed -r 's/^[^=]+//;s/^(\s|=|")*//;s/(\s|")+$//') # TODO: Make a helper like "getVmxOption"
		cnt=0
		for mac in $OTHER_NICS; do
			vmnet=$(( cnt + 10 ))
			cnt=$(( cnt + 1 ))
			eth="ethernet${cnt}"
			# Check device exists
			if ! [ -c "/dev/vmnet${vmnet}" ]; then
				slxlog "vmware-bridge-setup" "Cannot bridge NIC into VM: /dev/vmnet${vmnet} does not exist"
				continue
			fi
			# Remove lines that could break things
			sed -i "/^${eth}\.connectionType/Id;/^${eth}\.present/Id" "${TMPCONFIG}"
			# Set up devType
			devline=
			if ! grep -q -i "^${eth}\.virtualDev" "${TMPCONFIG}" && [ -n "$devtype" ]; then
				devline="${eth}.virtualDev = "'"'"${devtype}"'"'
			fi
			cat >> "${TMPCONFIG}" <<-HEND
			${eth}.connectionType = "custom"
			${eth}.present = "TRUE"
			${eth}.vnet = "vmnet${vmnet}"
			${eth}.addressType = "static"
			${eth}.address = "${mac}"
			${devline}
			HEND
		done
	fi
}

# DVD, CDROM
setup_optical_drives() {
	# XXX: For now it's safe to assume ide channel 1 is free, as we support only one HDD.
	# If it's IDE, it's on channel 0
	cat >> "${TMPCONFIG}" <<-HEREEND
	ide1:0.present = "$CDROM0"
	ide1:0.autodetect = "TRUE"
	ide1:0.fileName = "auto detect"
	ide1:0.deviceType = "cdrom-raw"
	ide1:1.present = "$CDROM1"
	ide1:1.autodetect = "TRUE"
	ide1:1.fileName = "auto detect"
	ide1:1.deviceType = "cdrom-raw"
	HEREEND
}

setup_floppies() {
	local SLX_FLOPPY
	if isset SLX_FLOPPY_IMG; then
		SLX_FLOPPY="TRUE"
	else
		SLX_FLOPPY="FALSE"
	fi
	(
	# Floppies:
	cat <<-HEREEND
		floppy0.present = "TRUE"
		floppy0.startConnected = "$FLOPPY0"
		floppy0.fileType = "device"
	HEREEND
	if [ -b "$FLOPPY_0" ]; then
		floppy0.autodetect = "FALSE"
		floppy0.fileName = "$FLOPPY_0"
	else
		floppy0.autodetect = "TRUE"
		floppy0.fileName = "auto detect"
	fi
	cat <<-HEREEND
		floppy1.present = "$SLX_FLOPPY"
		floppy1.startConnected = "TRUE"
		floppy1.fileType = "file"
		floppy1.fileName = "$SLX_FLOPPY_IMG"
	HEREEND
	) >> "$TMPCONFIG"
}

setup_serial() {
	# Serial port
	if [ -n "$SERIAL0" ]; then
		cat >> "${TMPCONFIG}" <<-HEREEND
			serial0.present = "TRUE"
			serial0.startConnected = "TRUE"
			serial0.fileType = "device"
			serial0.fileName = "$SERIAL0"
			serial0.tryNoRxLoss = "FALSE"
			serial0.autodetect = "FALSE"
		HEREEND
	fi

	# Parallel port
	if [ -n "$PARALLEL0" ]; then
		cat >> "${TMPCONFIG}" <<-HEREEND
			parallel0.present = "TRUE"
			parallel0.startConnected = "TRUE"
			parallel0.fileType = "device"
			parallel0.fileName = "$PARALLEL0"
			parallel0.bidirectional = "TRUE"
			parallel0.autodetect = "FALSE"
		HEREEND
	fi
}

# CPU and RAM
setup_vcpu_ram() {
	#writelog "numvcpus = ${CPU_CORES} - maxvcpus=${HOST_CORE_COUNT}"
	cat >> "${TMPCONFIG}" <<-HEREEND
	numvcpus = "$CPU_CORES"
	cpuid.coresPerSocket = "$VM_CORES_PER_SOCKET"
	maxvcpus = "$HOST_CORE_COUNT"
	memsize = "${VM_MEM}"
	MemAllowAutoScaleDown = "FALSE"
	MemTrimRate = "-1"
	HEREEND
}

setup_usb() {
	# Force autoconnect
	sed -i '/^usb\.generic\.autoconnect/Id' "${TMPCONFIG}"
	echo 'usb.generic.autoconnect = "TRUE"' >> "${TMPCONFIG}"
	echo 'usb.mangleUsb3Speed = "TRUE"' >> "${TMPCONFIG}"
	# Remove stray autoconnect entries
	sed -i '/^usb\.autoConnect\.device/Id' "${TMPCONFIG}"

	# Workaround for old VMs
	if grep -q -i '^ehci\.present.*TRUE' "${TMPCONFIG}" \
		&& ! grep -q -i '^usb\.present' "${TMPCONFIG}"; then
		echo 'usb.present = "TRUE"' >> "${TMPCONFIG}"
	fi

	# See if there are any USB devices connected that we want to pass through immediately
	get_usb_devices 'usb.autoConnect.deviceXXXXX = "0x%VENDOR%:0x%PRODUCT%"' \
		| sed -r 's/0x0+/0x/g' \
		| awk '{sub(/XXXXX/,NR-1)}1' \
		>> "${TMPCONFIG}"
}

setup_shared_folders() {
	if ! notempty SHARED_FOLDERS HOME_SHARE_PATH HOME_SHARE_NAME COMMON_SHARE_PATH COMMON_SHARE_NAME; then
		writelog "Missing information to setup shared folders."
		return 1
	fi

	cat >> "${TMPCONFIG}" <<-HEREEND
	sharedFolder.option = "alwaysEnabled"
	sharedFolder0.present = "$SHARED_FOLDERS"
	sharedFolder0.enabled = "$SHARED_FOLDERS"
	sharedFolder0.expiration = "never"
	sharedFolder0.guestName = "$HOME_SHARE_NAME"
	sharedFolder0.hostPath = "$HOME_SHARE_PATH"
	sharedFolder0.readAccess = "TRUE"
	sharedFolder0.writeAccess = "TRUE"
	sharedFolder1.present = "$SHARED_FOLDERS"
	sharedFolder1.enabled = "$SHARED_FOLDERS"
	sharedFolder1.expiration = "never"
	sharedFolder1.guestName = "$COMMON_SHARE_NAME"
	sharedFolder1.hostPath = "$COMMON_SHARE_PATH"
	sharedFolder1.readAccess = "TRUE"
	sharedFolder1.writeAccess = "FALSE"
	sharedFolder.maxNum = "2"
	hgfs.mapRootShare = "TRUE"
	hgfs.linkRootShare = "TRUE"
	HEREEND
}

setup_isolation() {
	# Settings for isolation tools (drag & drop, copy & paste, etc...)
	cat >> "${TMPCONFIG}" <<-HEREEND
	isolation.tools.hgfs.disable = "$HGFS_DISABLED"
	isolation.tools.dnd.disable = "FALSE"
	isolation.tools.copy.enable = "TRUE"
	isolation.tools.paste.enabled = "TRUE"
	HEREEND
}

# Serial, parallel: Empty, nothing is being currently set. TODO later.

setup_graphics() {
	# Graphics, GPU: 3D will be enabled (even if vmware doesn't support the chip) if we whitelisted it.
	if isset SLX_VMWARE_3D; then
		writelog "FORCE3D set - overriding 3D in vmx file."
		echo 'mks.gl.allowBlacklistedDrivers = "TRUE"'	>> "${TMPCONFIG}"
#		# We override... play safe and cap the hwVersion to 10, since some i915 chips goofed up with 12
#		# Investigate if we might have to do this in other cases where we don't override
#		if grep -qi '^mks.enable3d.*true' "${TMPCONFIG}"; then
#			vmw_cap_hw_version "10"
#		fi
	else
		writelog "FORCE3D not set - 3D will only work if GPU/driver is whitelisted by vmware."
	fi
	
	# Disable DPI scaling information passing via vmware tools
	sed -i '/^gui.applyHostDisplayScaling/Id' "${TMPCONFIG}"
	echo 'gui.applyHostDisplayScalingToGuest = "FALSE"' >> "${TMPCONFIG}"
	
	# Additinal exam mode settings
	if [ -n "$SLX_EXAM" ]; then
		echo 'gui.restricted = "true"' >> "${TMPCONFIG}"
	fi
	
	# Hack resolution if we know the desired one is not in the default list of vmx_svga
	# For now, only do it on the odd ones, as we don't know if this has any side effects
	# This seems unnecessary on Win7 but is required on WinXP - need more research for other OSs
	case "$RESOLUTION" in
		1600x900|2560x1080|2560x1440|2880x1800|3200x1800|3440x1440)
			X=${RESOLUTION%x*}
			Y=${RESOLUTION#*x}
			BYTES=$(( ( ( X * Y * 4  + 65535 ) / 65536 ) * 65536 ))
			[ "$BYTES" -lt 16777216 ] && BYTES=16777216
			cat >> "${TMPCONFIG}" <<-EOF
			svga.autodetect = "FALSE"
			svga.vramSize = $BYTES
			svga.maxWidth = $X
			svga.maxHeight = $Y
			EOF
			;;
	esac
	
	# Killing duplicate lines (output much nicer than sort -u):
	awk '!a[$0]++' "${TMPCONFIG}" > "${TMPCONFIG}.tmp" && mv -f "${TMPCONFIG}.tmp" "${TMPCONFIG}"
}

finalize_hardware() {
	# Apply $maxhardwareversion to final VMX
	if notempty VM_HW_VERSION && [ "$VM_HW_VERSION" -gt "$maxhardwareversion" ]; then
		writelog "Hardware version capped to $maxhardwareversion (was $VM_HW_VERSION)"
		sed -i 's/^virtualHW\.version.*$/virtualHW.version = "'$maxhardwareversion'"/I' "${TMPCONFIG}"
		VM_HW_VERSION="$maxhardwareversion"
	fi

	# Enable nested virtualization if not specified in remote vmx
	if [ -e "/run/hwinfo" ] && ! grep -qi '^vhv\.enable' "${TMPCONFIG}" \
			&& detect_cpu_flag "ept" "npt" \
			&& [ "$VM_HW_VERSION" -ge "9" ]; then
		. "/run/hwinfo"
		[ "${HW_KVM}" = "ENABLED" ] && echo 'vhv.enable = "TRUE"' >> "${TMPCONFIG}"
	fi

	# Disable space check warnings
	sed -i '/^mainMem.freeSpaceCheck/Id' "${TMPCONFIG}"
	echo 'mainMem.freeSpaceCheck = "FALSE"' >> "${TMPCONFIG}"

	# Fix keymap fuckup when leaving VM
	sed -i '/^mks.x.resetModMap/Id' "${TMPCONFIG}"
	echo 'mks.x.resetModMap = "FALSE"' >> "${TMPCONFIG}"

	# TODO: Need a way to check if supported by hardware before enabling!
	#grep -qi '^vpmc\.enable' "${TMPCONFIG}" || echo 'vpmc.enable = "TRUE"' >> "${TMPCONFIG}"
}


## MAIN ##
write_final_vmx() {
	replace_placeholders
	setup_ethernet
	setup_optical_drives
	setup_floppies
	setup_serial
	setup_vcpu_ram
	setup_usb
	[ "x$HGFS_DISABLED" = "xFALSE" ] && setup_shared_folders
	setup_isolation
	setup_graphics
	finalize_hardware

	# At last: Let's copy it to $VM_CONF_DIR/run-vmware.conf
	if cp -p "${TMPCONFIG}" "${VM_RUN_FILE}"; then
		writelog "Copied '${TMPCONFIG}' to '${VM_RUN_FILE}'"
	else
		writelog "Could not copy TMPDIR/IMGUUID -${TMPCONFIG}- to VM_RUN_FILE ${VM_RUN_FILE}!"
		# cleanexit 1 # that seems not needed!
	fi
}
call_post_source write_final_vmx