Untitled diff

Created Diff never expires
7 removals
283 lines
18 additions
290 lines
#!/bin/bash -e
#!/bin/bash -e
# Some colored makepkg-like functions
# Some colored makepkg-like functions
msg() {
msg() {
printf "${green}==>${bold} $1${all_off}\n"
printf "${green}==>${bold} $1${all_off}\n"
}
}
msg_yellow() {
msg_yellow() {
printf "${yellow}==>${bold} $1${all_off}\n"
printf "${yellow}==>${bold} $1${all_off}\n"
}
}
msg2() {
msg2() {
printf "${blue} ->${bold} $1${all_off}\n"
printf "${blue} ->${bold} $1${all_off}\n"
}
}
msg2_yellow() {
msg2_yellow() {
printf "${yellow} ->${bold} $1${all_off}\n"
printf "${yellow} ->${bold} $1${all_off}\n"
}
}
read_msg2() {
read_msg2() {
read -p "${blue} ->${bold} $1${all_off}"
read -p "${blue} ->${bold} $1${all_off}"
}
}
msg3() {
msg3() {
printf "${yellow} ->${bold} $1${all_off}\n"
printf "${yellow} ->${bold} $1${all_off}\n"
}
}
error() {
error() {
printf "${red}==> error:${bold} $1${all_off}\n"
printf "${red}==> error:${bold} $1${all_off}\n"
}
}
error2() {
error2() {
printf "${red} *${bold} $1${all_off}\n"
printf "${red} *${bold} $1${all_off}\n"
}
}
# Colors
# Colors
all_off="$(tput sgr0)"
all_off="$(tput sgr0)"
bold="${all_off}$(tput bold)"
bold="${all_off}$(tput bold)"
blue="${bold}$(tput setaf 4)"
blue="${bold}$(tput setaf 4)"
green="${bold}$(tput setaf 2)"
green="${bold}$(tput setaf 2)"
red="${bold}$(tput setaf 1)"
red="${bold}$(tput setaf 1)"
yellow="${bold}$(tput setaf 3)"
yellow="${bold}$(tput setaf 3)"
# Help message
# Help message
usage() {
usage() {
echo "Usage: $(basename $0) [-f|-v|-V|-h]"
echo "Usage: $(basename $0) [-f|-v|-V|-h]"
echo "Automate the compilation of VMware modules for Arch Linux."
echo "Automate the compilation of VMware modules for Arch Linux."
echo
echo
echo "Available options:"
echo "Available options:"
echo " -f, --force Force reinstallation even, if modules already built"
echo " -f, --force Force reinstallation even, if modules already built"
echo " -v, --verbose Use verbose output (patching, vmware-modconfig)"
echo " -v, --verbose Use verbose output (patching, vmware-modconfig)"
echo " -V, --version Print version information"
echo " -V, --version Print version information"
echo " -h, --help Print this help"
echo " -k <v>, --kernel=<v> Patch the specified Linux kernel version"
echo " -h, --help Print this help"
}
}
# Version information
# Version information
version() {
version() {
echo "$(basename $0) $(pacman -Q vmware-patch | cut -d ' ' -f2)"
echo "$(basename $0) $(pacman -Q vmware-patch | cut -d ' ' -f2)"
echo "Copyright (c) 2013-2014 Nobody"
echo "Copyright (c) 2013-2014 Nobody"
echo
echo
echo "THIS SCRIPT IS PROVIDED AS-IS FOR ANY PURPOSE WHATSOEVER. YOU ARE FREE TO SHARE IT, MODIFY IT,"
echo "THIS SCRIPT IS PROVIDED AS-IS FOR ANY PURPOSE WHATSOEVER. YOU ARE FREE TO SHARE IT, MODIFY IT,"
echo "TAKE CREDIT OF IT, AND SELL IT ON THE STREETS."
echo "TAKE CREDIT OF IT, AND SELL IT ON THE STREETS."
echo
echo
echo "FIGHT THE POWER."
echo "FIGHT THE POWER."
}
}
# Flags
# Flags
while [[ "$1" ]]; do
while [[ "$1" ]]; do
# Can't change $1
# Can't change $1
opt="$1"
opt="$1"
# Parse current one
# Parse current one
while [[ "$opt" != "-" ]]; do
while [[ "$opt" != "-" ]]; do
# Define actions
# Define actions
case "$opt" in
case "$opt" in
-f* | --force) force=1 ;;
-f* | --force) force=1 ;;
-v* | --verbose) verbose=1 ;;
-v* | --verbose) verbose=1 ;;
-k) shift; kernel_version="$1" ;;
--kernel=*) kernel_version="${opt#*=}" ;;
-V* | --version) version; exit 0 ;;
-V* | --version) version; exit 0 ;;
-h* | --help) usage; exit 0 ;;
-h* | --help) usage; exit 0 ;;
-*) echo "$(basename $0): error: bad argument: $opt"
-*) echo "$(basename $0): error: bad argument: $opt"
echo
echo
usage $1; exit 0 ;;
usage $1; exit 0 ;;
*) break ;;
*) break ;;
esac
esac
# Support single dash (-fv)
# Support single dash (-fv)
# Remove first match ("${opt#-[fv]}")
# Remove first match ("${opt#-[fv]}")
nextopt="${opt#-[fv]}"
nextopt="${opt#-[fv]}"
if [[ "$opt" != "$nextopt" ]]; then
if [[ "$opt" != "$nextopt" ]]; then
# Multiple short flags
# Multiple short flags
opt="-$nextopt"
opt="-$nextopt"
else
else
# Long form (--force/--verbose)
# Long form (--force/--verbose)
break
break
fi
fi
done
done
shift
shift
done
done
# Make sure we are root
# Make sure we are root
if (( $EUID != 0 )); then
if (( $EUID != 0 )); then
error "This script needs to be run as root."
error "This script needs to be run as root."
exit 1
exit 1
fi
fi
# Is a VMware product installed?
# Is a VMware product installed?
if [[ ! -f /usr/bin/vmware-installer ]]; then
if [[ ! -f /usr/bin/vmware-installer ]]; then
error "No VMware product found. Exiting.."
error "No VMware product found. Exiting.."
exit 1
exit 1
fi
fi
# Set some variables (|&: hide errors by redirecting all output)
# Set some variables (|&: hide errors by redirecting all output)
kernel=$(uname -r | cut -d "." -f-2)
if [[ -z $kernel_version ]]; then
kernel_version=$(uname -r)
fi
[[ "$verbose" ]] && msg "Using Linux kernel $kernel_version"
kernel=$(echo $kernel_version | cut -d "." -f-2)
ver=$(vmware-installer -l |& grep -Po "(player|workstation) *\K(\d+\.){2}\d+")
ver=$(vmware-installer -l |& grep -Po "(player|workstation) *\K(\d+\.){2}\d+")
if vmware-installer -l |& grep -q "workstation"; then
if vmware-installer -l |& grep -q "workstation"; then
name="VMware Workstation"
name="VMware Workstation"
else
else
name="VMware Player (Plus)"
name="VMware Player (Plus)"
fi
fi
# Make sure vmware.service includes our USB Arbitrator service
# Make sure vmware.service includes our USB Arbitrator service
if ! grep -q "usbarbitrator" /usr/lib/systemd/system/vmware.service; then
if ! grep -q "usbarbitrator" /usr/lib/systemd/system/vmware.service; then
msg "Updating vmware.service.."
msg "Updating vmware.service.."
sed '/Description/a Requires=vmware-usbarbitrator.service\nBefore=vmware-usbarbitrator.service' \
sed '/Description/a Requires=vmware-usbarbitrator.service\nBefore=vmware-usbarbitrator.service' \
-i /usr/lib/systemd/system/vmware.service
-i /usr/lib/systemd/system/vmware.service
fi
fi
# Make sure there's a version in /etc/arch-release for Workstation 9 / Player 5
# Make sure there's a version in /etc/arch-release for Workstation 9 / Player 5
# https://wiki.archlinux.org/index.php?title=VMware&oldid=274532#2.29_The_vmware-usbarbitrator_binary_is_segfaulting
# https://wiki.archlinux.org/index.php?title=VMware&oldid=274532#2.29_The_vmware-usbarbitrator_binary_is_segfaulting
if [[ "$ver" = 9.* ]] || [[ "$ver" = 5.* ]]; then
if [[ "$ver" = 9.* ]] || [[ "$ver" = 5.* ]]; then
if [[ ! $(cat /etc/arch-release) ]]; then
if [[ ! $(cat /etc/arch-release) ]]; then
msg "Updating /etc/arch-release.."
msg "Updating /etc/arch-release.."
curl -s https://www.archlinux.org/releng/releases/ | grep -Pom1 'for \K[^"]*' > /etc/arch-release
curl -s https://www.archlinux.org/releng/releases/ | grep -Pom1 'for \K[^"]*' > /etc/arch-release
fi
fi
fi
fi
# Fix Vmci/Vsock loading
# Fix Vmci/Vsock loading
if grep -q '$vsock_alias' /etc/init.d/vmware; then
if grep -q '$vsock_alias' /etc/init.d/vmware; then
sed -e 's/mod=$(vmwareRealModName $vmci $vmci_alias)/mod=vmci/' \
sed -e 's/mod=$(vmwareRealModName $vmci $vmci_alias)/mod=vmci/' \
-e 's/mod=$(vmwareRealModName $vsock $vsock_alias)/mod=vsock/' \
-e 's/mod=$(vmwareRealModName $vsock $vsock_alias)/mod=vsock/' \
-i /etc/init.d/vmware
-i /etc/init.d/vmware
fi
fi
# Remove leftover module locations
# Remove leftover module locations
for i in /usr/lib/modules/*; do
for i in /usr/lib/modules/*; do
if [[ $(ls "$i") = 'misc' ]]; then
if [[ $(ls "$i") = 'misc' ]]; then
misc+=("$i")
misc+=("$i")
fi
fi
done
done
if [[ "$misc" ]]; then
if [[ "$misc" ]]; then
msg_yellow "Removing leftover module location.."
msg_yellow "Removing leftover module location.."
for i in ${misc[@]}; do
for i in ${misc[@]}; do
msg2 "$i/"
msg2 "$i/"
rm -r "$i"
rm -r "$i"
done
done
fi
fi
# Remove old backups
# Remove old backups
cd /usr/lib/vmware/modules/
cd /usr/lib/vmware/modules/
# Use "ls" instead of the builtin -d for multiple arguments
# Use "ls" instead of the builtin -d for multiple arguments
if ls -d source-*.*/ 2>/dev/null | grep -qv "$ver/"; then
if ls -d source-*.*/ 2>/dev/null | grep -qv "$ver/"; then
msg_yellow "Cleaning up old backups.."
msg_yellow "Cleaning up old backups.."
# Print full paths
# Print full paths
for i in $(readlink -f source-*.*/ | grep -v "$ver"); do
for i in $(readlink -f source-*.*/ | grep -v "$ver"); do
msg2 "$i/"
msg2 "$i/"
rm -r "$i"
rm -r "$i"
done
done
fi
fi
# Make sure the directory exists
# Make sure the directory exists
if [[ ! -d /usr/lib/modules/$(uname -r)/ ]]; then
if [[ ! -d /usr/lib/modules/$kernel_version/ ]]; then
error "/usr/lib/modules/$(uname -r)/ not found. Exiting.."
error "/usr/lib/modules/$kernel_version/ not found. Exiting.."
exit 1
exit 1
fi
fi
# Support the '-f' flag
# Support the '-f' flag
# 1) Have we already built (vsock is built last)?
# 1) Have we already built (vsock is built last)?
# 2) Don't check this until we've removed the leftovers
# 2) Don't check this until we've removed the leftovers
if [[ ! "$force" ]] && [[ -f /usr/lib/modules/$(uname -r)/misc/vsock.ko ]]; then
if [[ ! "$force" ]] && [[ -f /usr/lib/modules/$kernel_version/misc/vsock.ko ]]; then
if [[ "$verbose" ]]; then
if [[ "$verbose" ]]; then
msg "Verifying current state.."
msg "Verifying current state.."
fi
fi
error "VMware modules already installed (use '-f' to override). Exiting.."
error "VMware modules already installed (use '-f' to override). Exiting.."
exit 1
exit 1
fi
fi
# Unload conflicting in-kernel modules (VMware can't handle these in Arch)
# Unload conflicting in-kernel modules (VMware can't handle these in Arch)
if rmmod vmw_vsock_vmci_transport 2>/dev/null; then
if rmmod vmw_vsock_vmci_transport 2>/dev/null; then
rmmod vmw_vmci vsock 2>/dev/null
rmmod vmw_vmci vsock 2>/dev/null
fi
fi
# Patch
# Patch
# 1) Make sure we can build
# 1) Make sure we can build
# 2) &>/dev/null: hide all output (STDIN/STDERR)
# 2) &>/dev/null: hide all output (STDIN/STDERR)
msg "Patching $name v$ver for kernel $(uname -r).."
msg "Patching $name v$ver for kernel $kernel_version.."
if ls patches/*"$ver"*"$kernel"*.patch &>/dev/null; then
if ls patches/*"$ver"*"$kernel"*.patch &>/dev/null; then
# Create a backup/Revert
# Create a backup/Revert
if [[ ! -d "source-$ver" ]]; then
if [[ ! -d "source-$ver" ]]; then
msg2_yellow "Backing up.."
msg2_yellow "Backing up.."
cp -r source/ "source-$ver/"
cp -r source/ "source-$ver/"
else
else
# Get the original sources from the backup (invalidate the need for 'vmware-unpatch')
# Get the original sources from the backup (invalidate the need for 'vmware-unpatch')
cp "source-$ver/"* source/
cp "source-$ver/"* source/
fi
fi
cd source
cd source
# Loop modules that require patching (vmci, vmmon, vmnet and/or vsock)
# Loop modules that require patching (vmci, vmmon, vmnet and/or vsock)
# sort -u: prevent duplicate entries with
# sort -u: prevent duplicate entries with
for mod in $(ls ../patches/v*"$ver"*"$kernel"*.patch 2>&- | grep -Po "s/\K[^-]*" | sort -u); do
for mod in $(ls ../patches/v*"$ver"*"$kernel"*.patch 2>&- | grep -Po "s/\K[^-]*" | sort -u); do
# Print name
# Print name
msg2 "[$mod]"
msg2 "[$mod]"
# Untar
# Untar
if [[ "$verbose" ]]; then
if [[ "$verbose" ]]; then
msg3 "Extracting archives.."
msg3 "Extracting archives.."
fi
fi
tar -xf "$mod.tar"
tar -xf "$mod.tar"
# Patch function
# Patch function
_patch() {
_patch() {
if [[ "$verbose" ]]; then
if [[ "$verbose" ]]; then
msg3 "Patching.."
msg3 "Patching.."
patch -p0 -f -i "$i"
patch -p0 -f -i "$i"
else
else
patch -p0 -s -f -i "$i"
patch -p0 -s -f -i "$i"
fi
fi
}
}
# Loop through all patches
# Loop through all patches
for i in ../patches/"$mod"*"$ver"*"$kernel"*.patch; do
for i in ../patches/"$mod"*"$ver"*"$kernel"*.patch; do
# Patch
# Patch
if ! _patch; then
if ! _patch; then
error "Failed to apply '$(basename "$i")'"
error "Failed to apply '$(basename "$i")'"
read_msg2 "Continue? (Y/n) "
read_msg2 "Continue? (Y/n) "
if [[ "$REPLY" != [Yy] ]]; then
if [[ "$REPLY" != [Yy] ]]; then
# Revert
# Revert
msg "Reverting.."
msg "Reverting.."
cd ..
cd ..
rm -r source/
rm -r source/
mv "source-$ver/" source/
mv "source-$ver/" source/
# Exit
# Exit
msg2 "Done."
msg2 "Done."
exit 1
exit 1
fi
fi
fi
fi
done
done
# Tar patched modules
# Tar patched modules
if [[ "$verbose" ]]; then
if [[ "$verbose" ]]; then
msg3 "Recreating archives.."
msg3 "Recreating archives.."
fi
fi
tar -cf "$mod.tar" "$mod-only"
tar -cf "$mod.tar" "$mod-only"
# Leftovers
# Leftovers
rm -r "$mod-only"
rm -r "$mod-only"
done
done
else
else
msg2 "No patching required.."
msg2 "No patching required.."
fi
fi
# Print 'vmware-modconfig-*.log's and exit
# Print 'vmware-modconfig-*.log's and exit
print_logs() {
print_logs() {
for i in /tmp/vmware-root/vmware-modconfig-*.log; do
for i in /tmp/vmware-root/vmware-modconfig-*.log; do
error2 "$i"
error2 "$i"
done
done
exit 1
exit 1
}
}
# Install
# Install
msg "Installing modules.."
msg "Installing modules.."
if [[ "$verbose" ]]; then
if [[ "$verbose" ]]; then
if ! vmware-modconfig --console --install-all; then
if ! vmware-modconfig --console --install-all -k "$kernel_version"; then
error "Unable to build. See:"
error "Unable to build. See:"
print_logs
print_logs
fi
fi
else
else
if ! vmware-modconfig --console --install-all &>/dev/null; then
if ! vmware-modconfig --console --install-all -k "$kernel_version" &>/dev/null; then
error "Unable to build. Re-run with '-v' (--verbose) or see:"
error "Unable to build. Re-run with '-v' (--verbose) or see:"
print_logs
print_logs
fi
fi
fi
fi
msg2 "Done."
msg2 "Done."