Fix: Patch for Parallel Tools 9.0.23350 to support Linux Kernel 3.12 (Ubuntu 14.04)

eugenesan

Bit poster
Below is a patch to fix recent changes in uid/gid treatment for filesystems.
Above also required changes in parameters parsing, so I replaced custom parameters parsing with Kernel's native routines.
Not extensively tested but works fine for me.

(I had to paste it here inline since Attachment upload is broken under Chrome and Firefox... which means TABs are not preserved)

Usage:
1) Mount Parallells Tools CD in virtual machine (Virtual Machine -> Install/Reinstall Parallels Tools)
2) Make temporary copy of Parallels Tools, enter and patch it:
$ cp -R /media/$USER/Parallels\ Tools /tmp/
$ cd /tmp/Parallels\ Tools/kmods
$ tar -xaf prl_mod.tar.gz
$ patch -p1 -d prl_fs < parallels-tools-linux-3.12-prl-fs-9.0.23350.941886.patch
$ tar -czf prl_mod.tar.gz prl_eth prl_fs prl_fs_freeze prl_tg Makefile.kmods dkms.conf
3) Install normally:
$ sudo /tmp/Parallels\ Tools/install
4) If successfully installed, reboot

Code:
diff -Nru prl_fs.orig/SharedFolders/Guest/Linux/prl_fs/inode.c prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c
--- prl_fs.orig/SharedFolders/Guest/Linux/prl_fs/inode.c	2013-11-11 17:56:58.000000000 +0200
+++ prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c	2013-11-29 20:41:53.689167040 +0200
@@ -199,10 +199,18 @@
 	if (attr->valid & _PATTR_MODE)
 		inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 0777);
 	if ((attr->valid & _PATTR_UID) &&
-	    (sbi->plain || sbi->share || attr->uid == -1))
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+	    (sbi->plain || sbi->share || __kuid_val(attr->uid) == -1))
+#else
+	    (sbi->plain || sbi->share || attr->uid == -1)))
+#endif
 		inode->i_uid = attr->uid;
 	if ((attr->valid & _PATTR_GID) &&
-	    (sbi->plain || sbi->share || attr->gid == -1))
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+	    (sbi->plain || sbi->share || __kgid_val(attr->gid) == -1))
+#else
+	    (sbi->plain || sbi->share || attr->gid == -1)))
+#endif
 		inode->i_gid = attr->gid;
 	return;
 }
@@ -521,13 +529,21 @@
 
 	generic_fillattr(dentry->d_inode, stat);
 	if (PRLFS_SB(dentry->d_sb)->share) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+		if (__kuid_val(stat->uid) != -1)
+#else
 		if (stat->uid != -1)
+#endif
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
 			stat->uid = current->fsuid;
 #else
 			stat->uid = current->cred->fsuid;
 #endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+		if (__kgid_val(stat->gid) != -1)
+#else
 		if (stat->gid != -1)
+#endif
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
 			stat->gid = current->fsgid;
 #else
@@ -577,9 +593,17 @@
 	mode = inode->i_mode;
 	isdir = S_ISDIR(mode);
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+	if (__kuid_val(inode->i_uid) != -1)
+#else
 	if (inode->i_uid != -1)
+#endif
 		mode = mode >> 6;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+	else if (__kgid_val(inode->i_gid) != -1)
+#else
 	else if (inode->i_gid != -1)
+#endif
 		mode = mode >> 3;
 	mode &= 0007;
 	mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
diff -Nru prl_fs.orig/SharedFolders/Guest/Linux/prl_fs/prlfs.h prl_fs/SharedFolders/Guest/Linux/prl_fs/prlfs.h
--- prl_fs.orig/SharedFolders/Guest/Linux/prl_fs/prlfs.h	2013-11-11 17:56:58.000000000 +0200
+++ prl_fs/SharedFolders/Guest/Linux/prl_fs/prlfs.h	2013-11-29 20:46:27.662771996 +0200
@@ -28,8 +28,13 @@
 	struct	pci_dev *pdev;
 	unsigned sfid;
 	unsigned ttl;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+	kuid_t uid;
+	kgid_t gid;
+#else
 	uid_t uid;
 	gid_t gid;
+#endif
 	int readonly;
 	int share;
 	int plain;
diff -Nru prl_fs.orig/SharedFolders/Guest/Linux/prl_fs/super.c prl_fs/SharedFolders/Guest/Linux/prl_fs/super.c
--- prl_fs.orig/SharedFolders/Guest/Linux/prl_fs/super.c	2013-11-11 17:56:58.000000000 +0200
+++ prl_fs/SharedFolders/Guest/Linux/prl_fs/super.c	2013-11-29 20:28:39.212000000 +0200
@@ -13,6 +13,7 @@
 #include <linux/seq_file.h>
 #include <linux/ctype.h>
 #include <linux/vfs.h>
+#include <linux/parser.h>
 #include "prlfs.h"
 #include "prlfs_compat.h"
 
@@ -26,38 +27,35 @@
 extern struct file_operations prlfs_names_fops;
 extern struct inode_operations prlfs_names_iops;
 
-static int prlfs_strtoui(char *cp, unsigned *result){
-	int ret = 0;
-	unsigned ui = 0;
-	unsigned digit;
-
-	if (!cp || (*cp == 0))
-		return -EINVAL;
-
-	while (*cp) {
-		if (isdigit(*cp)) {
-			digit = *cp - '0';
-		} else {
-			ret = -EINVAL;
-			break;
-		}
-		if (ui > ui * 10U + digit)
-			return -EINVAL;
-		ui = ui * 10U + digit;
-		cp++;
-	}
-
-	if (ret == 0)
-		*result = ui;
-
-	return ret;
-}
+enum {
+	Opt_uid,
+	Opt_gid,
+	Opt_ttl,
+	Opt_nls,
+	Opt_share,
+	Opt_plain,
+	Opt_sf,
+	Opt_err,
+};
+
+static const match_table_t prlfs_tokens = {
+	{Opt_uid, "uid=%d"},
+	{Opt_gid, "gid=%d"},
+	{Opt_ttl, "ttl=%u"},
+	{Opt_nls, "nls=%s"},
+	{Opt_share, "share"},
+	{Opt_plain, "plain"},
+	{Opt_sf, "sf=%s"},
+	{Opt_err, NULL}
+};
 
 static int
 prlfs_parse_mount_options(char *options, struct prlfs_sb_info *sbi)
 {
+	substring_t args[MAX_OPT_ARGS];
 	int ret = 0;
-	char *opt, *val;
+	int val;
+	char *opt;
 
 	DPRINTK("ENTER\n");
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
@@ -70,35 +68,54 @@
 	sbi->ttl = HZ;
 
 	if (!options)
-	       goto out;
+		goto out;
 
-	while (!ret && (opt = strsep(&options, ",")) != NULL)
+	while (!ret && ((opt = strsep(&options, ",")) != NULL))
 	{
+		int token;
 		if (!*opt)
 			continue;
 
-		val = strchr(opt, '=');
-		if (val) {
-			*(val++) = 0;
-			if (strlen(val) == 0)
-				val = NULL;
-		}
-		if (!strcmp(opt, "ttl") && val)
-			ret = prlfs_strtoui(val, &sbi->ttl);
-		else if (!strcmp(opt, "uid") && val)
-			ret = prlfs_strtoui(val, &sbi->uid);
-		else if (!strcmp(opt, "gid") && val)
-			ret = prlfs_strtoui(val, &sbi->gid);
-		else if (!strcmp(opt, "nls") && val)
-			strncpy(sbi->nls, val, LOCALE_NAME_LEN - 1);
-		else if (!strcmp(opt, "share"))
+		token = match_token(opt, prlfs_tokens, args);
+		switch (token) {
+		case Opt_uid:
+			if (!(ret = match_int(&args[0], &val)))
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+			sbi->uid = KUIDT_INIT(val);
+#else
+			sbi->uid = val;
+#endif
+			break;
+		case Opt_gid:
+			if (!(ret = match_int(&args[0], &val)))
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+			sbi->gid = KGIDT_INIT(val);
+#else
+			sbi->gid = val;
+#endif
+			break;
+		case Opt_ttl:
+			if (!(ret = match_int(&args[0], &val)))
+				sbi->ttl = val;
+			break;
+		case Opt_nls:
+			if (!match_strlcpy(sbi->nls, &args[0], LOCALE_NAME_LEN - 1))
+				ret = -EINVAL;
+			break;
+		case Opt_share:
 			sbi->share = 1;
-		else if (!strcmp(opt, "plain"))
+			break;
+		case Opt_plain:
 			sbi->plain = 1;
-		else if (!strcmp(opt, "sf") && val)
-			strncpy(sbi->name, val, sizeof(sbi->name));
-		else
+			break;
+		case Opt_sf:
+			if (!match_strlcpy(sbi->name, &args[0], sizeof(sbi->name)))
+				ret = -EINVAL;
+			break;
+		default:
 			ret = -EINVAL;
+		}
+		DPRINTK("PARSE interating %d:%d:%s\n", token, val, args[0]);
 	}
 out:
 	DPRINTK("EXIT returning %d\n", ret);
diff -Nru prl_fs.orig/SharedFolders/Interfaces/sf_lin.h prl_fs/SharedFolders/Interfaces/sf_lin.h
--- prl_fs.orig/SharedFolders/Interfaces/sf_lin.h	2013-11-11 18:11:49.000000000 +0200
+++ prl_fs/SharedFolders/Interfaces/sf_lin.h	2013-11-29 03:11:48.924415600 +0200
@@ -40,8 +40,13 @@
 	unsigned long long mtime;
 	unsigned long long ctime;
 	unsigned int mode;
-	unsigned int uid;
-	unsigned int gid;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+	kuid_t uid;
+	kgid_t gid;
+#else
+	uid_t uid;
+	gid_t gid;
+#endif
 	unsigned int valid;
 } PACKED;
 SFLIN_CHECK_SIZE(prlfs_attr, sizeof(struct prlfs_attr), 48)

(Sorry for "stealing" formatting from similar post)
 
Last edited:
help

Hi folks,

I'm a complete linux novice... how do I 'patch' the parallels tools? I'm running Parallels 8 on an retina mbp. I'm trying to install parallels tools on a kali linux running 3.12 kernel.

I tried creating a parallels-tools-linux-3.12-prl-fs-9.0.23350.941886.patch file using the attached code.

But I keep getting errors throughout. I need some help please.

Thanks in advance!
 
almost there..

Hello guys,

Here is my parallels-tools-install.log


Code:
Qua Jan 22 16:37:58 BRT 2014
Start installation or upgrade of Guest Tools
new version of parallels tools
Installed Guest Tools were not found
Perform installation into the /usr/lib/parallels-tools directory
cat: /usr/lib/parallels-tools/kmods/../version: Arquivo ou diretório não encontrado
/root/ptools/installer/install-kmods.sh: 41: [: Illegal number: 12-kali1-amd64
Start installation of prl_eth kernel module
make: Entrando no diretório `/usr/lib/parallels-tools/kmods'
cd prl_eth/pvmnet && make
make[1]: Entrando no diretório `/usr/lib/parallels-tools/kmods/prl_eth/pvmnet'
make -C /lib/modules/3.12-kali1-amd64/build M=/usr/lib/parallels-tools/kmods/prl_eth/pvmnet
make[2]: Entrando no diretório `/usr/src/linux-headers-3.12-kali1-amd64'
  LD      /usr/lib/parallels-tools/kmods/prl_eth/pvmnet/built-in.o
  CC [M]  /usr/lib/parallels-tools/kmods/prl_eth/pvmnet/pvmnet.o
  LD [M]  /usr/lib/parallels-tools/kmods/prl_eth/pvmnet/prl_eth.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /usr/lib/parallels-tools/kmods/prl_eth/pvmnet/prl_eth.mod.o
  LD [M]  /usr/lib/parallels-tools/kmods/prl_eth/pvmnet/prl_eth.ko
make[2]: Saindo do diretório `/usr/src/linux-headers-3.12-kali1-amd64'
make[1]: Saindo do diretório `/usr/lib/parallels-tools/kmods/prl_eth/pvmnet'
cd prl_tg/Toolgate/Guest/Linux/prl_tg && make
make[1]: Entrando no diretório `/usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg'
make -C /lib/modules/3.12-kali1-amd64/build SUBDIRS=/usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg SRCROOT=/usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg modules
make[2]: Entrando no diretório `/usr/src/linux-headers-3.12-kali1-amd64'
  CC [M]  /usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg.o
  LD [M]  /usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prl_tg.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prl_tg.mod.o
  LD [M]  /usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prl_tg.ko
make[2]: Saindo do diretório `/usr/src/linux-headers-3.12-kali1-amd64'
make[1]: Saindo do diretório `/usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg'
cp -f prl_tg/Toolgate/Guest/Linux/prl_tg/*.symvers prl_fs/SharedFolders/Guest/Linux/prl_fs ||:
cd prl_fs/SharedFolders/Guest/Linux/prl_fs && make
make[1]: Entrando no diretório `/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs'
make -C /lib/modules/3.12-kali1-amd64/build M=/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs
make[2]: Entrando no diretório `/usr/src/linux-headers-3.12-kali1-amd64'
  LD      /usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/built-in.o
  CC [M]  /usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/super.o
  CC [M]  /usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.o
  CC [M]  /usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.o
/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.c:400:2: error: unknown field ‘readdir’ specified in initializer
/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.c:400:2: warning: initialization from incompatible pointer type [enabled by default]
/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.c:400:2: warning: (near initialization for ‘prlfs_dir_fops.flush’) [enabled by default]
/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.c:407:2: error: unknown field ‘readdir’ specified in initializer
/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.c:407:2: warning: initialization from incompatible pointer type [enabled by default]
/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.c:407:2: warning: (near initialization for ‘prlfs_root_fops.flush’) [enabled by default]
make[5]: ** [/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.o] Erro 1
make[4]: ** [_module_/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs] Erro 2
make[3]: ** [sub-make] Erro 2
make[2]: ** [all] Erro 2
make[2]: Saindo do diretório `/usr/src/linux-headers-3.12-kali1-amd64'
make[1]: ** [all] Erro 2
make[1]: Saindo do diretório `/usr/lib/parallels-tools/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs'
make: ** [installme] Erro 2
make: Saindo do diretório `/usr/lib/parallels-tools/kmods'
Error: could not build kernel modules
Error: failed to install kernel modules
2014-01-22T16:38:02-0300: execCmd: ./install --install [143]
2014-01-22T16:38:02-0300: Error: An error occurred when installing Parallels Tools. Please go to /var/log/parallels-tools-install.log for more information.
2014-01-22T16:38:06-0300: Exiting with code 1

What am I doing wrong?
Thanks
 
ok cant' you say me how i must the patch in kmods folder other in prl_fs.orig/SharedFolders/Guest/Linux/prl_fs folders ?

i have create the patch fil but nothing works ...

thanks
 
I know but when i would make the redirection from the file to the command i have a error that the file don't existe.

Sorry i debute with debian ...
 
I know but when i would make the redirection from the file to the command i have a error that the file don't existe.

Sorry i debute with debian ...


When you create the patch, you name it parallels-tools-linux-3.12-prl-fs-9.0.23350.941886.patch
and you copy it in directory : /tmp/Parallels\ Tools/kmods (where you have extract prl_mod.tar.gz)
Il the file patch is named # you can adapt the commande line :
patch -p1 -d prl_fs < file_name_of.patch
 
When you create the patch, you name it parallels-tools-linux-3.12-prl-fs-9.0.23350.941886.patch
and you copy it in directory : /tmp/Parallels\ Tools/kmods (where you have extract prl_mod.tar.gz)
Il the file patch is named # you can adapt the commande line :
patch -p1 -d prl_fs < file_name_of.patch

Let me ask you, if I may. Does the name of the actual file (parallels-tools-linux-3.12-prl-fs-9.0.23350.941886.patch) has anything to do with the effectiveness of the patch or can I name it anything I want?

Cheers
 
No, patch file name is absolutely irrelevant.
Let me ask you, if I may. Does the name of the actual file (parallels-tools-linux-3.12-prl-fs-9.0.23350.941886.patch) has anything to do with the effectiveness of the patch or can I name it anything I want?
Cheers
 
Applied the patch to a Fedora 19 (kernel 3.12.11-201) system under Parallells 9.0.24172 and it worked like a champ.

Tried to apply it to a Fedora 20 (kernel 3.13.3-201) system, but gdm bounces four times and quits. Even tried removing and reinstalling. No luck there, so far. Judging from Xorg.0.log, there might be an issue with prlmouse masquerading under Generic Explorer Mouse. /dev/input/mouse0 never gets generated: "No input driver specified, ignoring this device."
 
...check that, 19 had the same note in the log. However, PRL_GLX had a lot of stuff that ran in 19 that never seemed to kick off in 20, which seems to be the primary difference in the logs here.
 
Sure enough, kernel 3.13.4-200 was just released, amongst other things. Updated the kernel, rebuilt/updated Parallel Tools, and voila... now it works with Fedora 20. It's quirky in that the display settings don't completely recognize it, nor does it remember the last screen size, but at least gdm no longer crashes.
 
Hello,
This method works fine with linux kali 3.12 kernel.
First, copy the code to a file and rename as "parallels-tools-linux-3.12-prl-fs-9.0.23350.941886.patch"; then do as eugenesan said.
Second, this patch do work with latest parallels desktop version 9.024172.951362 and it's parallels tools, but in my apple mac air, a message will popup every time when I restart it, says that the system will not work at resolution 1280x800. I will check it when I free.
Third, after you create the patch file, you have to move it into the directory of kmods.

Thanks for eugenesan .

Bye
 
Back
Top