Parallels Tools for Linux not compatible with Linux 6.12

Discussion in 'Linux Virtual Machine' started by tytso, Jan 2, 2025.

Tags:
  1. tytso

    tytso Bit poster

    Messages:
    3
    The Linxu 6.12 kernel version is now in Debian Testing, and will be the new Long-Term Stable kernel as it was the last kernel released in 2024. As a result, many Linux distributions will be upgrading to it soon, if they have not done so already (as in the case of Debian).

    The failure appears to be due to a change in the function prototype of write_end() address operations function between 6.11 and 6.12:

    /var/lib/dkms/parallels-tools/20.1.2.55742/build/prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c:930:27: error: initialization of 'int (*)(struct file *, struct address_space *, loff_t, unsigned int, unsigned int, struct folio *, void *)' {aka 'int (*)(struct file *, struct address_space *, long long int, unsigned int, unsigned int, struct folio *, void *)'} from incompatible pointer type 'int (*)(struct file *, struct address_space *, loff_t, unsigned int, unsigned int, struct page *, void *)' {aka 'int (*)(struct file *, struct address_space *, long long int,, unsigned int, unsigned int, struct page *, void *)'} [-Wincompatible-pointer-types]
    930 | .write_end = prlfs_write_end,
    | ^~~~~~~~~~~~~~~


    If you are using Debian Testing, the short-term workaround is to run "sudo apt remove linux-image-6.12.6-arm64 linux-headers-6.12.6-arm64 linux-image-arm64 linux-headers-arm64". This will remove the new 6.12 Linux, to prevent you from rebooting into the 6.12 kernel since it won't have Parallels Tools support. Once Parallels updates to a new version that has 6.12 LTS support, then run "sudo apt install linux-image-arm64 linux-headers-arm64" so you can get back on the Linux kernel update track. In the short-term staying on the 6.11.10 or 6.11.4 kernel means you won't get any later security fixes, but hopefully Parallels will get this fixed soon rather than later. (Or perhaps some Linux kernel hacker will have the time to figure out how to bludgeon prl_fs/inode.c so it will compile on the latest Linux kernel.....)
     
  2. MichaelT67

    MichaelT67

    Messages:
    1
    I can suggest a workaround that will allow you to use 6.12.x until Parallels updates the tools. I was getting a kernel panic on reboot when loading a 6.12.x kernel:

    - After your dnf update, reboot and go into your last kernel before 6.12.x and reinstall the Parallel tools.
    - Reboot again into 6.12.x kernel. The Parallels tools will not work, they will even try to reinstall but will fail, but you'll be on the more secure kernel.

    This was tested on Gnome Fedora 40 and KDE Fedora 41, both machines are now running on 6.12.7 and awaiting updated tools from Parallels.
     
  3. tytso

    tytso Bit poster

    Messages:
    3
    Yes, that's an alternative. At least for me, having working Parallels Tools is more important than having a more secure kernel. One of my primary use cases is to build software (e.g., the Linux kernel, e2fsprogs, etc.) in the Linux VM, and for that, being able to share files between the MacOS and Linux worlds is critically important for me.

    I do most of my e-mail reading and web browsing using MacOS, and I even test Linux kernels on MacOS to avoid the double-virtualization performance hit. (My Linux Kernel test appliance in addition to running in Google Cloud and on Android devices, can also run on qemu using MacOS's Hypervisor:framework). So the main thing that I use the the Linux VM in Parallels is for (a) running C compiles, and (b) sending e-mail (since I haven't been able to configure MacOS's exim4 to work correctly with Secure SMTP). For the latter, I use Parallel Tools to share my locally mirrored IMAP inbox (using offlineimap) between the MacOS and Linux worlds, and I do most of mail reading using mutt on MacOS (to reduce battery consumption when on an airplane), and then fire up Linux and use mutt in the LinuxVM to reply to e-mails, which then get queued and will get sent when I can reconnect to the Internet.
     
  4. DmitrijK7

    DmitrijK7

    Messages:
    1
    I've met the same problem and got the solution.
    0. Mount parallels tools
    1. copy content of mounting dir to temp (ex: /media/<user>/Parallels Tools/)
    2. extract kmods/prl_mod.tar.gz
    3. in extract dir apply the following patch:
    Code:
     .../SharedFolders/Guest/Linux/prl_fs/inode.c  | 52 +++++++++++++++++++
     .../Linux/prl_freeze/prlfs_freeze_compat.h    | 11 +++-
     2 files changed, 61 insertions(+), 2 deletions(-)
    
    diff --git a/prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c b/prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c
    index 4fa559e..c98ff62 100644
    --- a/prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c
    +++ b/prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c
    @@ -158,6 +158,16 @@ static int do_prlfs_getattr(struct dentry *dentry, struct prlfs_attr *attr)
    
     #define SET_INODE_TIME(t, time)    do { (t).tv_sec = (time); } while (0)
    
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
    +#define TIME_TO_SEC(t) t##_sec
    +#define SET_INODE_TIME(t, time)    do {TIME_TO_SEC(t) = (time); } while (0)
    +
    +#define prlfs_inode_get_ctime inode_get_ctime
    +#define prlfs_inode_set_ctime_to_ts inode_set_ctime_to_ts
    +#define prlfs_inode_set_ctime inode_set_ctime
    +
    +#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
    +
     #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
    
     #define prlfs_inode_get_ctime inode_get_ctime
    @@ -194,6 +204,27 @@ static inline struct prlfs_timespec prlfs_inode_set_ctime(struct inode *inode,
     }
    
     #endif // #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) #else
    +static inline struct prlfs_timespec prlfs_inode_get_ctime(const struct inode *inode)
    +{
    +    struct timespec64 timespec = {inode->i_ctime_sec, inode->i_ctime_ns};
    +    return timespec;
    +}
    +static inline struct prlfs_timespec prlfs_inode_set_ctime_to_ts(struct inode *inode,
    +                             struct prlfs_timespec ts)
    +{
    +    inode->i_ctime_sec = ts.tv_sec;
    +    inode->i_ctime_nsec = ts.tv_nsec;
    +    return ts;
    +}
    +static inline struct prlfs_timespec prlfs_inode_set_ctime(struct inode *inode,
    +                        prlfs_kerneltime sec, long nsec)
    +{
    +    struct prlfs_timespec ts = { .tv_sec  = sec,
    +                .tv_nsec = nsec };
    +
    +    return prlfs_inode_set_ctime_to_ts(inode, ts);
    +}
    +#endif // #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0) #else
    
    
     static void prlfs_change_attributes(struct inode *inode,
    @@ -951,8 +982,19 @@ static struct inode *prlfs_get_inode(struct super_block *sb, prl_umode_t mode)
        if (inode) {
            inode->i_mode = mode;
            inode->i_blocks = 0;
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
    +        struct timespec64 ts = prlfs_inode_set_ctime_to_ts(inode,
    +                                                  prlfs_current_time(inode));
    +
    +        inode->i_atime_sec = ts.tv_sec;
    +        inode->i_atime_nsec = ts.tv_nsec;
    +        inode->i_mtime_sec = ts.tv_sec;
    +        inode->i_mtime_nsec = ts.tv_nsec;
    +
    +#else
            inode->i_atime = inode->i_mtime =
                prlfs_inode_set_ctime_to_ts(inode, prlfs_current_time(inode));
    +#endif // LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
            if (PRLFS_SB(sb)->share) {
                inode->i_uid = current->cred->uid;
                inode->i_gid = current->cred->gid;
    @@ -997,8 +1039,18 @@ void prlfs_read_inode(struct inode *inode)
        struct prlfs_fd *pfd;
    
        inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
    +    struct timespec64 ts = prlfs_inode_set_ctime_to_ts(inode, prlfs_current_time(inode));
    +
    +    inode->i_atime_sec = ts.tv_sec;
    +    inode->i_atime_nsec = ts.tv_nsec;
    +    inode->i_mtime_sec = ts.tv_sec;
    +    inode->i_mtime_nsec = ts.tv_nsec;
    +
    +#else
        inode->i_atime = inode->i_mtime =
            prlfs_inode_set_ctime_to_ts(inode, prlfs_current_time(inode));
    +#endif // LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
        if (PRLFS_SB(sb)->share) {
            inode->i_uid = current->cred->uid;
            inode->i_gid = current->cred->gid;
    diff --git a/prl_fs_freeze/Snapshot/Guest/Linux/prl_freeze/prlfs_freeze_compat.h b/prl_fs_freeze/Snapshot/Guest/Linux/prl_freeze/prlfs_freeze_compat.h
    index 5327712..adf724e 100644
    --- a/prl_fs_freeze/Snapshot/Guest/Linux/prl_freeze/prlfs_freeze_compat.h
    +++ b/prl_fs_freeze/Snapshot/Guest/Linux/prl_freeze/prlfs_freeze_compat.h
    @@ -45,7 +45,14 @@
     #define prl_freeze_bdev(bdev) freeze_bdev(bdev)
     #define prl_thaw_bdev(bdev, sb) thaw_bdev(bdev)
    
    -#else
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
    +
    +#define prl_freeze_bdev(bdev) bdev_freeze(bdev)
    +#define prl_thaw_bdev(bdev, sb) bdev_thaw(bdev)
    +
    +#endif // LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
    +
    +#else // LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
    
     int prl_freeze_bdev(struct block_device *bdev)
     {
    @@ -62,6 +69,6 @@ int prl_freeze_bdev(struct block_device *bdev)
    
     #define prl_thaw_bdev(bdev, sb) thaw_bdev((bdev), (sb))
     
    -#endif
    +#endif // LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
    
     #endif
    --
    2.45.2
    
    5. tar patched code and replace extracted archive
    6. run install script
     

Share This Page