Friday, September 3, 2010

Accessing Linux File Systems from within Windows

Near the end of 2009 I ask a question on superuser.com about accessing a Linux XFS filesystem from within Windows. After investigating coLinux I decided to try the VirtualBox route -- and it worked beautifully! I can now access my standard Linux install (which I dual boot into) from within Windows on those few days where I need to be in Windows.

System Configuration

Machine: Windows 7 and Gentoo Linux. Windows is acting as the boot loader. Here's my drive layout:

/dev/sda1 - NTFS - Windows 7
/dev/sda2 - Extended Partition
/dev/sda5 - Boot Partition (EXT3)
/dev/sda6 - Swap
/dev/sda7 - LVM
/dev/sda8 - LVM

The Windows boot loader needs a copy of the boot record to be used. In my case, I had installed grub into /dev/sda5, my boot partition. I copied the boot loader out of /dev/sda5 using dd which makes it possible to copy the first 512 bytes of the partition:

dd if=/dev/sda5 of=/root/sda5_mbr bs=512 count=1

I then copied /root/sda5_mbr over to a thumb drive so it was available on Windows. We will need this file not only for the Windows boot loader, but also for VirtualBox as you'll see shortly.

My Linux machine is publicly accessible on the internet and I have, as a requirement, that it still be accessible on the internet when I'm in Windows with VirtualBox running. Given that requirement, here's my networking configuration:

Windows 7 Host
- 192.168.1.20 - static IP

Linux Host:
- 192.168.1.10 - static IP

Router:
- 192.168.1.1 - primary gateway, forwards desirable ports to 192.168.1.10

I've purposefully given Windows and Linux different static IP's so each is accessible and they don't run into any IP address conflicts.

Install VirtualBox

First, I installed VirtualBox in Windows. Most application installs are pretty much the same in Windows, and VirtualBox was no different, so I'm not going to document installing VirtualBox. If you're reading this, I'm sure you're more than capable.

Configure VirtualBox Hard Drive Access

Like many applications, VirtualBox has some standard directories that it uses:

%USERDIR%\%USERNAME%\.VirtualBox\HardDisks
%USERDIR%\%USERNAME%\.VirtualBox\Machines

%USERDIR% is likely C:\Users and %USERNAME% is the username of the account that you typically log in as.

You can create the above directories by hand if you like, but I'm going to assume they exist. With those directories in hand, we now need to tell VirtualBox about the raw partitions that we want it to use. Since Windows is our host, we do not want to accidentally access it from within Linux as that could cause corruption. Furthermore, we want to use the grub boot loader so we don't have to bother with the standard Windows MBR. Since we're giving VirtualBox access to the physical drive, we need to be a full administrator. So, run cmd as an administrator. Now let's make VirtualBox aware of the rest of our partitions:

C:\>cd \users\kpederson\.virtualbox\harddisks
C:\Users\kpederson\.VirtualBox\HardDisks>"\Program Files\Oracle\VirtualBox\VBoxManage" \
  internalcommands createrawvmdk -filename rawdisk.vmdk -rawdisk \\.\PhysicalDrive0 \
  -partitions 5,6,7,8 -mbr f:\sda5_mbr -register

The above creates two files, rawdisk.vmdk and rawdisk-pt.vmdk:

-r-------- 2 root root     161280 Sep  1 22:19 rawdisk-pt.vmdk
-r-------- 2 root root        994 Sep  2 00:16 rawdisk.vmdk

The files aren't particularly big. They do little more than tell VirtualBox about the partitions that it can access and embed the MBR. Here's some details about the command:

"\Program Files\Oracle\VirtualBox\VBoxManage" - the command we're calling
internalcommands - the main command we're calling
createrawvmdk - the sub command - create a raw virtual disk file
-filename rawdisk.vmdk - specify name of the virtual disk to be created
-rawdisk \\.\PhysicalDrive0 - creating a raw disk and using the main physical drive
-partitions 5,6,7,8 - only give VirtualBox access to the Linux partitions
-mbr f:\sda5_mbr - install a new MBR, the one I copied onto my thumb drive (f:\)
-register - add the drive virtual media manager

If the above command worked successfully, we should see output similar to the following:

Oracle VM VirtualBox Command Line Management Interface Version 3.2.8
(C) 2005-2010 Oracle Corporation
All rights reserved.

RAW host disk access VMDK file rawdisk.vmdk created successfully.

Create your Virtual Machine

Now that VirtualBox knows about my raw Linux partitions and is setup to use the MBR containing grub, I can now configure a Virtual Machine within VirtualBox. Here's the basic steps:

  1. Choose a name and the correct version (note 64-bit option)
  2. Select the amount of available RAM to dedicate to the VM
  3. Make sure "Boot Hard Disk" is checked and select use existing hard disk: FIXME: insert image here
  4. Review settings and select Finish

The system should now boot up when choose start. Hopefully you'll be greeted by a the grub startup screen:

Configure Networking

Most of the configuration is pretty straightforward, but my networking requirements will take a little effort to get right. First, let me show you the obvious correct answer and my first attempt -- bridged networking. Bridge networking should allow the virtual network card presented to Linux by VirtualBox to send out any data it wants on the physical device as if the computer was assigned both IP addresses (192.168.1.10 and 192.168.1.20):

Unfortunately, that didn't work -- I had network access, but it was only local. Windows 7 could communicate with my virtual machine and my virtual machine could communicate with Windows but my virtual machine didn't have internet access and couldn't resolve DNS. I tried for quite a while and couldn't figure out the problem in a reasonable time (I assume it's a bug). However, I found a work around thanks to a post that on the VirtualBox forum that I can no longer find. Instead of letting VirtualBox create the bridge, use Windows to bridge the connections. To do this, we have to configure our virtual machine to use host-only networking:

With host-only networking configured, we'll now boot into Linux. Once up and running, lets bridge the networks. Pull up the network interfaces dialog and select your standard network adapter and the host-only network adapter, then right click and bridge the connection as illustrated below:

That does bring some slight complications, namely, I have to disable the bridge in order to retain internet access when my virtual machine isn't running.

Since the new bridge is in place, you should now be able to resolve network addresses. Here's a quick test using dig:

Configure Samba

Assuming your Linux distribution installs a working samba, the only thing you should need to do is to edit smb.conf to include a share. Here's my most frequently used share definition:

[shared]
   comment = Shared Documents
   path = /home/shared
   force group = smb_users
   guest ok = no
   writable = yes

With that share in place you can restart samba (or have it re-read the configuration file using smbcontrol) to enable the share. And with that, you should be able to access that share from within Windows using your ip address or netbios name.

2 comments:

  1. Hello Kaleb, First of all congratulations on your site it is really informative! I was wondering if you and me could exchange emails, because I am having some trouble on making VTK work on QT and I saw that you managed to make them work together without problem. My email is guilherme__lopez@hotmail.com, Im using linux. Thanks a lot !

    ReplyDelete
  2. Hi, I'm glad you like my bog.

    I don't have the time to do any personal support or e-mail exchanges, but feel free to post a detailed question to stackoverflow.com. If I happen to see it and it looks like a question I might have an answer to, I'll probably answer :).

    ReplyDelete