#!/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