diff options
-rw-r--r-- | core/modules/vmware17/data/addon-required | 19 | ||||
-rwxr-xr-x | core/modules/vmware17/data/opt/openslx/bin/vmplayer | 16 | ||||
l--------- | core/modules/vmware17/data/opt/openslx/bin/vmware | 1 | ||||
l--------- | core/modules/vmware17/data/usr/bin/vmplayer | 1 | ||||
l--------- | core/modules/vmware17/data/usr/bin/vmware | 1 | ||||
-rw-r--r-- | core/modules/vmware17/module.build | 235 | ||||
-rw-r--r-- | core/modules/vmware17/module.conf | 67 | ||||
-rw-r--r-- | core/modules/vmware17/usb-patcher.c | 57 | ||||
l--------- | core/targets/vmware/vmware16 | 1 | ||||
l--------- | core/targets/vmware/vmware17 | 1 |
10 files changed, 398 insertions, 1 deletions
diff --git a/core/modules/vmware17/data/addon-required b/core/modules/vmware17/data/addon-required new file mode 100644 index 00000000..a86e41bc --- /dev/null +++ b/core/modules/vmware17/data/addon-required @@ -0,0 +1,19 @@ +#!/bin/bash + +# the vmware helper needs the kmod msr and the tool rdmsr, +# /dev, /sys and /proc to properly detect the CPU info. + +bindmount=("/dev" "/proc" "/sys") + +for bm in "${bindmount[@]}"; do + mount --bind "$bm" "${NEWROOT}/${bm}" +done + +export PATH="$PATH:/opt/openslx/sbin:/opt/openslx/bin" +version="$(chroot "$NEWROOT" vmware-get-supported-version)" + +for bm in "${bindmount[@]}"; do + umount "${NEWROOT}/${bm}" +done + +[ -n "$version" ] && [ "$version" = "new" ] diff --git a/core/modules/vmware17/data/opt/openslx/bin/vmplayer b/core/modules/vmware17/data/opt/openslx/bin/vmplayer new file mode 100755 index 00000000..05a4ec3a --- /dev/null +++ b/core/modules/vmware17/data/opt/openslx/bin/vmplayer @@ -0,0 +1,16 @@ +#!/bin/ash +# radically simplified version of the original script vmplayer by VMware Inc. +PREFIX=/usr/lib/vmware # depends on the vmware location + +# HACK: Let the OpenGL driver report s3tc capability even if not present, so 3D will be enabled +export force_s3tc_enable=true + +# Turn off "helpful" DE features +export APPMENU_DISPLAY_BOTH=1 +export UBUNTU_MENUPROXY=0 +export GNOME_DISABLE_CRASH_DIALOG=1 + +PROG=$(basename $0) + +exec "$PREFIX/bin/$PROG" "$@" + diff --git a/core/modules/vmware17/data/opt/openslx/bin/vmware b/core/modules/vmware17/data/opt/openslx/bin/vmware new file mode 120000 index 00000000..aa0b74b1 --- /dev/null +++ b/core/modules/vmware17/data/opt/openslx/bin/vmware @@ -0,0 +1 @@ +vmplayer
\ No newline at end of file diff --git a/core/modules/vmware17/data/usr/bin/vmplayer b/core/modules/vmware17/data/usr/bin/vmplayer new file mode 120000 index 00000000..2944838d --- /dev/null +++ b/core/modules/vmware17/data/usr/bin/vmplayer @@ -0,0 +1 @@ +/opt/openslx/bin/vmplayer
\ No newline at end of file diff --git a/core/modules/vmware17/data/usr/bin/vmware b/core/modules/vmware17/data/usr/bin/vmware new file mode 120000 index 00000000..bde6f9c0 --- /dev/null +++ b/core/modules/vmware17/data/usr/bin/vmware @@ -0,0 +1 @@ +/opt/openslx/bin/vmware
\ No newline at end of file diff --git a/core/modules/vmware17/module.build b/core/modules/vmware17/module.build new file mode 100644 index 00000000..a95f720a --- /dev/null +++ b/core/modules/vmware17/module.build @@ -0,0 +1,235 @@ +#!/bin/bash +fetch_source() { + [ -d "${MODULE_WORK_DIR}/src" ] && \ + { rm -r "${MODULE_WORK_DIR}/src" || perror "Could not delete old src dir."; } + mkdir -p "${MODULE_WORK_DIR}/src" || perror "Could not mkdir src" + cde "${MODULE_WORK_DIR}/src" + + local BASE_URL LIST_URL BUILD_NO + #BASE_URL="http://softwareupdate.vmware.com/cds/vmw-desktop/ws/12.5.2/4638234/linux/core/" + BASE_URL="http://softwareupdate.vmware.com/cds/vmw-desktop/" + if [ "$REQUIRED_TYPE" = "workstation" ]; then + BASE_URL+="ws/" + else + BASE_URL+="${REQUIRED_TYPE}/" + fi + BASE_URL+="${REQUIRED_VERSION}/" + # Get directory listing of version to get build number + wget -O "index.html" "$BASE_URL" || perror "Could not download vmware version index from $BASE_URL" + BUILD_NO=$(grep -E -o -i -m 1 'href="[0-9]+/"' "index.html" | awk -F '"' '{print $2}') + [ -z "$BUILD_NO" ] && perror "Could not determine build number of $REQUIRED_VERSION from $MODULE_WORK_DIR/src/index.html" + LIST_URL="${BASE_URL}${BUILD_NO}linux/core/" # BUILD_NO already has trailing slash... + + # Get directory listing of where final archive resides + wget -O "index.html" "$LIST_URL" || perror "Could not download vmware build type core dir index" + VMWARE_BUNDLE_FILE=$(grep -E -o -i -m 1 "href=\"VMware-$REQUIRED_TYPE-[^\"]+[\._\-]$ARCHREGEX[\._\-][^\"]+\"" "index.html" | awk -F '"' '{printf $2}') + [ -z "$VMWARE_BUNDLE_FILE" ] && perror "Could not determine vmware $REQUIRED_TYPE bundle file for current arch from $MODULE_WORK_DIR/src/index.html" + + # Download file + wget -O "$VMWARE_BUNDLE_FILE" "${LIST_URL}${VMWARE_BUNDLE_FILE}" || perror "Could not download ${VMWARE_BUNDLE_FILE} from ${LIST_URL}" + if [[ "$VMWARE_BUNDLE_FILE" == *.tar ]]; then + tar -x "${VMWARE_BUNDLE_FILE%.tar}" -f "$VMWARE_BUNDLE_FILE" || perror "Could not untar downloaded $VMWARE_BUNDLE_FILE" + unlink "$VMWARE_BUNDLE_FILE" + VMWARE_BUNDLE_FILE="${VMWARE_BUNDLE_FILE%.tar}" + fi + + cd - >/dev/null +} + +build() { + local KMOD SHORT PATCH MIN_KERN MAX_KERN + [ -z "$VMWARE_BUNDLE_FILE" ] && VMWARE_BUNDLE_FILE=$(basename "$(find "${MODULE_WORK_DIR}/src" -iname "vmware-*" | head -n 1)") + local DELETE_FILES=$(for LINE in $REQUIRED_VMWARE_DELETIONS;do echo "rm -rf -- $LINE"; done) + + local OFFICIAL_VERSION=$(echo "$VMWARE_BUNDLE_FILE" | cut -f 3 -d '-') + local BUILD_VERSION=$(echo "$VMWARE_BUNDLE_FILE" | cut -f 4 -d '-') + BUILD_VERSION=${BUILD_VERSION%%.*} + [ -z "$OFFICIAL_VERSION" ] && perror "Could not determine vmware version from downloaded file (expected eg. 12.0.0)" + if [ -z "$BUILD_VERSION" ] || [ "$BUILD_VERSION" -lt 10000 ]; then + perror "Could not determine vmware build number from downloaded file" + fi + + # prepare the build directory with the files needed during the chroot + cp "${MODULE_WORK_DIR}/src/$VMWARE_BUNDLE_FILE" "${MODULE_BUILD_DIR}/$VMWARE_BUNDLE_FILE" + local KVER2=$TARGET_KERNEL_SHORT + [ ${#KVER2} -gt 4 ] && KVER2=${KVER2%.*} + git clone --depth 1 -b "w${OFFICIAL_VERSION}-k${KVER2}" "https://github.com/mkubecek/vmware-host-modules.git" "${MODULE_BUILD_DIR}/prepatched" \ + && pinfo "Have prepatched kernel modules" + if ! [ -d "${MODULE_BUILD_DIR}/prepatched" ]; then + # copy required patches + mkdir -p "${MODULE_BUILD_DIR}/patches" + for PATCH in $(find "${MODULE_DIR}/patches/" -name "*__*__*.patch"); do + parse_patch_name "$PATCH" + [ -z "${MIN_KERN}" -o -z "${MAX_KERN}" ] && perror "Could not parse patch filename" + if version_lt "$TARGET_KERNEL_SHORT" "$MIN_KERN" || version_gt "$TARGET_KERNEL_SHORT" "$MAX_KERN"; then + pinfo "*NOT* applying $PATCH (min=$MIN_KERN max=$MAX_KERN cmp=$TARGET_KERNEL_SHORT)" + continue # Not suitable for our kernel + fi + if version_lt "$OFFICIAL_VERSION" "$MIN_VMWARE" || version_gt "$OFFICIAL_VERSION" "$MAX_VMWARE"; then + pinfo "*NOT* applying $PATCH (min=$MIN_VMWARE max=$MAX_VMWARE cmp=$OFFICIAL_VERSION)" + continue # Not suitable for our kernel + fi + pinfo "Kernel: Applying $PATCH (min=$MIN_KERN max=$MAX_KERN cmp=$TARGET_KERNEL_SHORT)" + pinfo "VMware: Applying $PATCH (min=$MIN_VMWARE max=$MAX_VMWARE cmp=$OFFICIAL_VERSION)" + cp "$PATCH" "${MODULE_BUILD_DIR}/patches/" || perror "Could not copy patch $PATCH to $MODULE_BUILD_DIR/patches" + done + fi + + # sanity check to see if KERNEL_HEADERS_DIR is set and exists + [ -z "${KERNEL_HEADERS_DIR}" -o ! -e "${KERNEL_HEADERS_DIR}" ] && perror "KERNEL_HEADERS_DIR ('"${KERNEL_HEADERS_DIR}"') not found. Was the kernel module built?" + + # build in two steps, to be able to use mltk function while patching modules + mkdir -p "${MODULE_BUILD_DIR}/usr/local/bin" + # This is required as there are still some uname calls in the Makefiles, EVEN THOUGH + # YOU SPECIFY ANOTHER KERNEL via -k below. Building will fail for a 5.x kernel if you + # run on a system with a 4.x kernel. + cat > "${MODULE_BUILD_DIR}/usr/local/bin/uname" <<-EOF + #!/bin/sh + if [ "\$1" = "-r" ]; then + echo '${TARGET_KERNEL_LONG}' + else + /bin/uname "\$@" || /usr/bin/uname "\$@" + fi + EOF + chmod +x "${MODULE_BUILD_DIR}/usr/local/bin/uname" + pinfo "Installing vmware per chroot..." + chroot_run "${MODULE_BUILD_DIR}" <<-EOF + perror() { + echo "[ERROR ERROR] " "\$@" >&6 + exit 1 + } + # PS1='\[\e[1;33m\](chroot) \u@\h:\w\$ \[\e[1;32m\]' /bin/bash -norc # un-comment for debugging within chroot + $DELETE_FILES + yes | sh /"${VMWARE_BUNDLE_FILE}" --eulas-agreed --console --required + set -x + # Patch kernel modules + # check if we need to patch modules + if cd /prepatched; then + echo "Found prepatched directory" + for file in *-only; do + [ -d "\$file" ] || continue + KMOD=\${file%-only}.tar + tar cf "/usr/lib/vmware/modules/source/\$KMOD" "\$file/" || perror "repacking prepatched \$file failed" + done + fi + # check if we need to patch modules + cd "/usr/lib/vmware/modules/source" \ + || perror "Could not cd to '/usr/lib/vmware/modules/source'" + for file in /patches/*.patch; do + [ -s "\$file" ] || continue + SHORT="\$(basename "\${file%%__*}")" + [ -d "/prepatched/\${SHORT}-only" ] && continue + KMOD="\${SHORT}.tar" + echo "Applying patch \$file" + [ -s "\$KMOD" ] || perror "Kmod \$KMOD does not exist" + [ ! -d "\${SHORT}-only" ] && tar xf "\$KMOD" + [ ! -d "\${SHORT}-only" ] && perror "untar of \$KMOD failed." + cde "\${SHORT}-only" + if ! patch -p1 < "\$file"; then + cd .. + rm -rf -- "\${SHORT}-only" + perror "Applying \$file failed." + fi + cd .. + if [ -d "\${SHORT}-only" ]; then + tar cf "\$KMOD" "\${SHORT}-only/" || perror "repacking of \$KMOD failed." + rm -rf -- "\${SHORT}-only" + fi + done + vmware-modconfig --console --build-mod -k "${TARGET_KERNEL_LONG}" vmnet $(which gcc) "${KERNEL_HEADERS_DIR}/include" vmplayer vmnet || perror "vmnet build failed" + vmware-modconfig --console --build-mod -k "${TARGET_KERNEL_LONG}" vmmon $(which gcc) "${KERNEL_HEADERS_DIR}/include" vmplayer vmmon || perror "vmmon build failed" + EOF + + cde "${MODULE_WORK_DIR}" + + # cleanup unneeded files + rm -rf -- "${MODULE_BUILD_DIR}/etc/vmware-installer" + rm -rf -- "${MODULE_BUILD_DIR}/usr/lib/vmware-installer" + rm -rf -- "${MODULE_BUILD_DIR}/usr/lib/vmware-ovftool" + unlink "${MODULE_BUILD_DIR}/$VMWARE_BUNDLE_FILE" + + # write vmware.conf config file to be later sourced by vmware/run-virt.include. + mkdir -p "${MODULE_BUILD_DIR}/opt/openslx/vmchooser/plugins/vmware/" || perror "Could not mkdir "${MODULE_BUILD_DIR}/opt/openslx/vmchooser/plugins/vmware/"." + + cat > "${MODULE_BUILD_DIR}/opt/openslx/vmchooser/plugins/vmware/vmware.conf" <<-EOF + # configuration file written by vmware/module.build + vmnet0=true + vmnet1=192.168.101.1/24 + vmnet1nat=true + vmnet8=192.168.102.1/24 + vmware_version=$OFFICIAL_VERSION + vmware_build=${BUILD_VERSION} + maxhardwareversion=${OFFICIAL_VERSION%%.*} + EOF + + # Patch system-wide vmware config + sed -i '/^installerDefaults.autoSoftwareUpdateEnabled/d; + /^installerDefaults.componentDownloadEnabled/d; + /^installerDefaults.dataCollectionEnabled/d; + /^acceptEULA/d; + /^acceptOVFEULA/d + ' "${MODULE_BUILD_DIR}/etc/vmware/config" + + cat >> "${MODULE_BUILD_DIR}/etc/vmware/config" <<-HEREDOC + installerDefaults.autoSoftwareUpdateEnabled = "no" + installerDefaults.componentDownloadEnabled = "no" + installerDefaults.dataCollectionEnabled = "no" + acceptEULA = "yes" + acceptOVFEULA = "yes" + HEREDOC + # XXX: If the previous lines are missing, i.e. if vmware wants you to accept the EULAs first, it + # will try to read these files: + # /usr/share/doc/vmware-player/EULA + # /usr/lib/vmware-ovftool/vmware.eula + # If it cannot open these files (as we deleted them) it will crash with a SIGABRT (signal 6) + # coming from an uncaught exeception in libglibmm's file_get_contents + # Patch vmware-vmx to always enable USB autoconnect for VMs + if [[ "${OFFICIAL_VERSION}" = 17.* ]]; then + gcc -o "${MODULE_WORK_DIR}/patsch" "${MODULE_DIR}/usb-patcher.c" || perror "USB patscher build failed" + "${MODULE_WORK_DIR}/patsch" "${MODULE_BUILD_DIR}/usr/lib/vmware/bin/vmware-vmx" || perror "Patsching vmware-vmx failed" + fi +} + +post_copy() { + # FIXME: gconftool is copied without dependencies + tarcopy "$(find /usr/lib/ /usr/lib64 -name gconv -type d)" "$TARGET_BUILD_DIR" + + # Update Icon cache for vmplayer, older versions had the version in their names, newer do not... + for guid in gtk-update-icon-cache{,-3.0} fail; do + if [ "$guid" = "fail" ]; then + pwarning "Updating icon cache failed." + break + fi + "$guid" "${TARGET_BUILD_DIR}/usr/share/icons/hicolor/" + done + + # fix vmware-usbarbitrator bug + date +'%Y.%m.%d' >"${TARGET_BUILD_DIR}/etc/arch-release" + + mkdir -p "$TARGET_BUILD_DIR/lib/modules/vmware/" + cp "${MODULE_BUILD_DIR}/lib/modules/$TARGET_KERNEL_LONG/vmplayer/"* "$TARGET_BUILD_DIR/lib/modules/vmware/" || perror "Could not cp vmware modules to target!" + +} + +parse_patch_name() { + [ $# -ne 1 ] && perror "parse_patch_name: Wrong parameter count." + local PATCH="$1" + # Module + SHORT=$(echo "$PATCH" | sed -r 's/^([^_]+)__.*$/\1/g') + KMOD="${SHORT}.tar" + # Kernel restriction + MIN_KERN=$(echo "$PATCH" | sed -r 's/^[^_]+__([0-9\.]+)-[0-9\.]+__[^_]+\.patch$/\1/g') + [[ "$MIN_KERN" == /* ]] && MIN_KERN=$(echo "$PATCH" | sed -r 's/^[^_]+__([0-9\.]+)__[^_]+\.patch$/\1/g') + MAX_KERN=$(echo "$PATCH" | sed -r 's/^[^_]+__[0-9\.]+-([0-9\.]+)__[^_]+\.patch$/\1/g') + [[ "$MAX_KERN" == /* ]] && MAX_KERN=$(echo "$PATCH" | sed -r 's/^[^_]+__([0-9\.]+)__[^_]+\.patch$/\1/g') + [[ "$MIN_KERN" == /* ]] && MIN_KERN= + [[ "$MAX_KERN" == /* ]] && MAX_KERN= + # vmware restriction + MIN_VMWARE=$(echo "$PATCH" | sed -r 's/^[^_]+__[^_]+__([0-9\.]+)-[^_]+\.patch$/\1/g') + [[ "$MIN_VMWARE" == /* ]] && MIN_VMWARE=$(echo "$PATCH" | sed -r 's/^[^_]+__[^_]+__([0-9\.]+)\.patch$/\1/g') + MAX_VMWARE=$(echo "$PATCH" | sed -r 's/^[^_]+__[^_]+__[^_]+-([0-9\.]+)\.patch$/\1/g') + [[ "$MAX_VMWARE" == /* ]] && MAX_VMWARE=$(echo "$PATCH" | sed -r 's/^[^_]+__[^_]+__([0-9\.]+)\.patch$/\1/g') + [[ "$MIN_VMWARE" == /* ]] && MIN_VMWARE= + [[ "$MAX_VMWARE" == /* ]] && MAX_VMWARE= +} + diff --git a/core/modules/vmware17/module.conf b/core/modules/vmware17/module.conf new file mode 100644 index 00000000..ebb1a809 --- /dev/null +++ b/core/modules/vmware17/module.conf @@ -0,0 +1,67 @@ +#!/bin/bash +REQUIRED_VERSION="${CONFIG_VMWARE_VERSION:-17.0.0}" +REQUIRED_TYPE="workstation" +REQUIRED_MODULES="kernel vmware-common" +REQUIRED_DIRECTORIES=" + /etc/vmware + /usr/sbin + /usr/lib/vmware/bin + /usr/lib/vmware/icu + /usr/lib/vmware/lib + /usr/lib/vmware/libconf + /usr/lib/vmware/licenses + /usr/lib/vmware/resources + /usr/lib/vmware/roms + /usr/lib/vmware/scripts + /usr/lib/vmware/share + /usr/lib/vmware/xkeymap + /usr/lib/vmware/vnckeymap +" +REQUIRED_FILES=" + /usr/lib/vmware/config + /opt/openslx/vmchooser/plugins/vmware/vmware.conf +" +REQUIRED_BINARIES=" + vmnet-netifup +" + +REQUIRED_VMWARE_DELETIONS=" + /etc/cups/thnuclnt.convs + /etc/cups/thnuclnt.types + /etc/init.d/vmamqpd + /etc/init.d/vmware* + /etc/modprobe.d/vmware-fuse.conf + /etc/pam.d/vmware-authd + /etc/rc?.d/???vmamqp* + /etc/rc?.d/???vmware* + /etc/thnuclnt + /etc/vmware* + /etc/xdg/menus/applications-merged + /lib/modules/*-generic/misc/vmmon.ko + /lib/modules/*-generic/misc/vmnet.ko + /usr/bin/ovftool + /usr/bin/vm-support + /usr/bin/vmnet-bridge + /usr/bin/vmnet-dhcpd + /usr/bin/vmnet-natd + /usr/bin/vmnet-netifup + /usr/bin/vmnet-sniffer + /usr/bin/vmplayer + /usr/bin/vmrun + /usr/bin/vmss2core + /usr/bin/vmware* + /usr/include/vmware-vix + /usr/lib/cups/filter/thnucups + /usr/lib/diskLibWrapper.so + /usr/lib/libvixAllProducts.so + /usr/lib/vmware* + /usr/sbin/vmware* + /usr/share/applications/vmware* + /usr/share/desktop-directories/vmware-ace-vms.directory + /usr/share/doc/vmware* + /usr/share/icons/hicolor/*/apps/vmware* + /usr/share/icons/hicolor/*/mimetypes/*vmware* + /usr/share/man/man1/vmware.1.gz + /usr/share/mime/packages/vmware-player.xml + /var/lib/vmware +" diff --git a/core/modules/vmware17/usb-patcher.c b/core/modules/vmware17/usb-patcher.c new file mode 100644 index 00000000..2374f167 --- /dev/null +++ b/core/modules/vmware17/usb-patcher.c @@ -0,0 +1,57 @@ +#define _GNU_SOURCE +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <sys/mman.h> +#include <errno.h> + +char* findSequence(char *buffer, size_t len, size_t offset); + +int main(int argc, char**argv) +{ + int fd; + ssize_t flen; + char *exe, *offset; + fd = open( argv[1], O_RDWR ); + if ( fd == -1 ) { + perror( "Cannot open argv[1]" ); + return 1; + } + flen = lseek( fd, 0, SEEK_END ); + if ( flen < 0 ) { + perror( "File length bad" ); + return 2; + } + flen &= ~( sysconf( _SC_PAGE_SIZE ) - 1 ); + printf( "Mapping %d bytes.\n", (int)flen ); + exe = mmap( NULL, flen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); + if ( exe == NULL ) { + perror( "mmap failed" ); + return 3; + } + close( fd ); + offset = findSequence( exe, flen, 0 ); + if ( offset == NULL ) { + printf( "Sequence not found\n" ); + return 4; + } + if ( findSequence( exe, flen, ( offset - exe ) + 16 ) != NULL ) { + printf( "Found more than one match\n" ); + return 5; + } + printf( "Mapped at %p, instruction at %p\n", exe, offset ); + offset[2] = '\x34'; + munmap( exe, flen ); + printf( "File patched.\n" ); + return 0; +} + + +char* findSequence(char *buffer, size_t len, size_t offset) +{ + return memmem( buffer + offset, len - offset, + "\x45\x89\x3c\x24\x49\x8d\x7c\x24\x04\x48\x8d\x55\x01\x4c\x89\xf6", 16 ); +} diff --git a/core/targets/vmware/vmware16 b/core/targets/vmware/vmware16 deleted file mode 120000 index b6b5d82b..00000000 --- a/core/targets/vmware/vmware16 +++ /dev/null @@ -1 +0,0 @@ -../../modules/vmware16
\ No newline at end of file diff --git a/core/targets/vmware/vmware17 b/core/targets/vmware/vmware17 new file mode 120000 index 00000000..817e3be6 --- /dev/null +++ b/core/targets/vmware/vmware17 @@ -0,0 +1 @@ +../../modules/vmware17
\ No newline at end of file |