Mac OS X Mount NTFS
I had a USB stick laying around and I had to put HFS+ on it to do some Mac OS X specific activities. Initially I had NTFS on it (just so I could use the usb stick across all OSes), and I wanted to format it back to NTFS using Mac OS X. As I was reading up on the process, I realized there are a couple of different ways to the approach.
Install ntfs-3g
I already had mac-ports setup on my mac (check out this post on the install process). After you have mac-ports installed, you can use the following to install ntfs-3g :
~$sudo port install ntfs-3g
That will come with all the necessary tools to use NTFS (mount NTFS as read-write and to actually format partitions as NTFS) on Mac OS X.
~$port contents ntfs-3g | grep bin
/opt/local/bin/lowntfs-3g
/opt/local/bin/ntfs-3g
/opt/local/bin/ntfs-3g.probe
/opt/local/bin/ntfs-3g.secaudit
/opt/local/bin/ntfs-3g.usermap
/opt/local/bin/ntfscat
/opt/local/bin/ntfscluster
/opt/local/bin/ntfscmp
/opt/local/bin/ntfsfix
/opt/local/bin/ntfsinfo
/opt/local/bin/ntfsls
/opt/local/sbin/mkfs.ntfs
/opt/local/sbin/mkntfs
/opt/local/sbin/ntfsclone
/opt/local/sbin/ntfscp
/opt/local/sbin/ntfslabel
/opt/local/sbin/ntfsresize
/opt/local/sbin/ntfsundelete
BTW I was on Mac OS X Mavericks:
~$sw_vers
ProductName: Mac OS X
ProductVersion: 10.9.2
BuildVersion: 13C64
NTFS with MBR Using fdisk
So plug in the drive and check out it’s partitions:
~$diskutil list /dev/disk2
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *8.0 GB disk2
1: DOS_FAT_32 UNTITLED 8.0 GB disk2s1
FDisk_partition_scheme is the MBR style scheme and it looks like it has a FAT filesystem on it. So let’s erase the disk partition information from the drive:
~$sudo dd if=/dev/zero of=/dev/disk2 bs=512 count=1
1+0 records in
1+0 records out
512 bytes transferred in 0.002081 secs (246017 bytes/sec)
Now checking out the drive, I don’t have any partitions on it:
~$diskutil list /dev/disk2
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: *8.0 GB disk2
Now let’s initialize the MBR style partition scheme on the disk
~$sudo fdisk -i -a dos /dev/disk2
-----------------------------------------------------
------ ATTENTION - UPDATING MASTER BOOT RECORD ------
-----------------------------------------------------
Do you wish to write new MBR and partition table? [n] y
The above will also create a FAT partition on the disk. So let’s change the partition type with fdisk to NTFS:
~$sudo fdisk -e /dev/disk2
fdisk: 1> print
Disk: /dev/disk2 geometry: 973/255/63 [15633408 sectors]
Offset: 0 Signature: 0xAA55
Starting Ending
#: id cyl hd sec - cyl hd sec [ start - size]
------------------------------------------------------------------------
1: 0B 1023 254 63 - 1023 254 63 [ 2 - 15633406] Win95 FAT-32
2: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
3: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
4: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
fdisk: 1> edit 1
Starting Ending
#: id cyl hd sec - cyl hd sec [ start - size]
------------------------------------------------------------------------
1: 0B 1023 254 63 - 1023 254 63 [ 2 - 15633406] Win95 FAT-32
Partition id ('0' to disable) [0 - FF]: [B] (? for help) 07
Do you wish to edit in CHS mode? [n] n
Partition offset [0 - 15633408]: [63]
Partition size [1 - 15633345]: [15633345]
fdisk:*1> print
Disk: /dev/disk2 geometry: 973/255/63 [15633408 sectors]
Offset: 0 Signature: 0xAA55
Starting Ending
#: id cyl hd sec - cyl hd sec [ start - size]
------------------------------------------------------------------------
1: 07 0 1 1 - 1023 254 63 [ 63 - 15633345] HPFS/QNX/AUX
2: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
3: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
4: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
fdisk:*1> write
As a side note if you don’t initialize the MBR scheme and you use fdisk it will ask you to initialize the partition table:
~$sudo fdisk -e /dev/disk2
The signature for this MBR is invalid.
Would you like to initialize the partition table? [y] y
Enter 'help' for information
fdisk:*1> print
Disk: /dev/disk2 geometry: 973/255/63 [15633408 sectors]
Offset: 0 Signature: 0xAA55
Starting Ending
#: id cyl hd sec - cyl hd sec [ start - size]
------------------------------------------------------------------------
1: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
2: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
3: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
4: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
Writing MBR at offset 0.
But then you will have create the partition with fdisk manually and it will create a FAT partition, which we will have to change later to NTFS (so inititiazing with disk from the command is faster… I think).
At this point you should see the following on the usb drive:
~$diskutil list /dev/disk2
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *8.0 GB disk2
1: Windows_NTFS 8.0 GB disk2s1
Now we format our partition as NTFS:
~$sudo mkntfs -FQ /dev/disk2s1
The partition start sector was not specified for /dev/disk2s1 and it could not be obtained automatically. It has been set to 0.
The number of sectors per track was not specified for /dev/disk2s1 and it could not be obtained automatically. It has been set to 0.
The number of heads was not specified for /dev/disk2s1 and it could not be obtained automatically. It has been set to 0.
Cluster size has been automatically set to 4096 bytes.
To boot from a device, Windows needs the 'partition start sector', the 'sectors per track' and the 'number of heads' to be set.
Windows will not be able to boot from this device.
Creating NTFS volume structures.
mkntfs completed successfully. Have a nice day.
Lastly we can mount the partition
~$sudo ntfs-3g /dev/disk2s1 /mnt/usb
~$df -Ph -T osxfusefs
Filesystem Size Used Avail Capacity Mounted on
/dev/disk2s1 7.5Gi 39Mi 7.4Gi 1% /mnt/usb
It will be mounted as read-write too:
~$tail /var/log/system.log | grep ntfs-3g
Jul 9 14:12:49 mac ntfs-3g[9795]: Mounted /dev/disk2s1 (Read-Write, label "", NTFS 3.1)
Jul 9 14:12:49 mac ntfs-3g[9795]: Cmdline options:
Jul 9 14:12:49 mac ntfs-3g[9795]: Mount options: allow_other,nonempty,relatime,fsname=/dev/disk2s1,blkdev,blksize=4096
NTFS with MBR Using diskutil and fdisk
We can also use diskutil to create an MBR partition scheme with a FAT partition all one command. First make sure nothing in on the disk:
~$diskutil list disk2
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: *8.0 GB disk2
Then run the following to create the MBR Scheme and FAT 32 Partition
~$diskutil partitionDisk disk2 MBR MS-DOS VOL 100%
Started partitioning on disk2
Unmounting disk
Creating the partition map
Waiting for the disks to reappear
Formatting disk2s1 as MS-DOS (FAT) with name VOL
512 bytes per physical sector
/dev/rdisk2s1: 15602896 sectors in 1950362 FAT32 clusters (4096 bytes/cluster)
bps=512 spc=8 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=2 drv=0x80 bsec=15633406 bspf=15238 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished partitioning on disk2
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *8.0 GB disk2
1: DOS_FAT_32 VOL 8.0 GB disk2s1
From here you can do the same thing, change the partition type with fdisk, and then use mkntfs (from the ntfs-3g package) to format it as NTFS. BTW for reference here is a list of supported file systems by diskutil:
~$diskutil listFilesystems
Formattable file systems
These file system personalities can be used for erasing and partitioning.
When specifying a personality as a parameter to a verb, case is not considered.
Certain common aliases (also case-insensitive) are listed below as well.
------------------------------------------------------------------------
PERSONALITY USER VISIBLE NAME
------------------------------------------------------------------------
ExFAT ExFAT
Free Space Free Space
(or) free
MS-DOS MS-DOS (FAT)
MS-DOS FAT12 MS-DOS (FAT12)
MS-DOS FAT16 MS-DOS (FAT16)
MS-DOS FAT32 MS-DOS (FAT32) (or) fat32
HFS+ Mac OS Extended
Case-sensitive HFS+ Mac OS Extended (Case-sensitive) (or) hfsx
Case-sensitive Journaled HFS+ Mac OS Extended (Case-sensitive, Journaled) (or) jhfsx
Journaled HFS+ Mac OS Extended (Journaled) (or) jhfs+
NTFS with GPT Using gpt and gdisk
Now let’s create a GPT partition scheme and put NTFS on the first partition. Let’s clear out the partitions and make sure nothing is one them:
~$diskutil list disk2
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: *8.0 GB disk2
To put a GPT partition scheme, run the following:
~$sudo gpt create /dev/disk2
~$diskutil list /dev/disk2
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *8.0 GB disk2
You can also use gpt to confirm the GPT Partition scheme is on there:
~$sudo gpt -vv show /dev/disk2
gpt show: disk2: mediasize=8004304896; sectorsize=512; blocks=15633408
gpt show: disk2: PMBR at sector 0
gpt show: disk2: Pri GPT at sector 1
gpt show: disk2: Sec GPT at sector 15633407
start size index contents
0 1 PMBR
1 1 Pri GPT header
2 32 Pri GPT table
34 15633341
15633375 32 Sec GPT table
15633407 1 Sec GPT header
Now let’s use gdisk to create a partition of type NTFS on it:
~$sudo gdisk /dev/disk2
GPT fdisk (gdisk) version 0.8.10
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): n
Partition number (1-128, default 1):
First sector (34-15633374, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-15633374, default = 15633374) or {+-}size{KMGTP}:
Current type is 'Apple HFS/HFS+'
Hex code or GUID (L to show codes, Enter = af00): 0700
Changed type of partition to 'Microsoft basic data'
Command (? for help): print
Disk /dev/disk2: 15633408 sectors, 7.5 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): C7AE32D1-0DBD-4C3F-8EC2-02C26106BEDF
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 15633374
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 15633374 7.5 GiB 0700 Microsoft basic data
Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/disk2.
Warning: The kernel may continue to use old or deleted partitions.
You should reboot or remove the drive.
The operation has completed successfully.
Same thing from here, we can format it with mkntfs and mount it with ntfs-3g.
Remove GPT Partition Scheme
To remove the GPT paritition scheme first unmount the drive and then use gdisk :
~$sudo gdisk /dev/disk2
GPT fdisk (gdisk) version 0.8.10
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): x
Expert command (? for help): z
About to wipe out GPT on /dev/disk2. Proceed? (Y/N): y
Warning: The kernel may continue to use old or deleted partitions.
You should reboot or remove the drive.
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities.
Blank out MBR? (Y/N): Y
At this point the disk should be empty:
~$diskutil list /dev/disk2
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: *8.0 GB disk2
We can also use dd to zero out both locations (GPT is stored/resides in two locations: at the beginning and end of the disk). From the gpt show
command we can see where the end is:
~$sudo gpt -v show /dev/disk2
gpt show: /dev/disk2: mediasize=8004304896; sectorsize=512; blocks=15633408
start size index contents
0 1 PMBR
1 1 Pri GPT header
2 32 Pri GPT table
34 15633341
15633375 32 Sec GPT table
15633407 1 Sec GPT header
First let’s zero out the secondary (end of the disk) GPT table:
~$sudo dd if=/dev/zero of=/dev/disk2 bs=512 seek=15633341
dd: /dev/disk2: end of device
68+0 records in
67+0 records out
34304 bytes transferred in 0.023648 secs (1450607 bytes/sec)
elatok@usxxelatokm1:~$sudo gpt -v show /dev/disk2
gpt show: /dev/disk2: mediasize=8004304896; sectorsize=512; blocks=15633408
start size index contents
0 1 PMBR
1 1 Pri GPT header
2 32 Pri GPT table
34 15633374
The seek value is basically the value of the end of the partition seen from the gpt show
command.
Now let’s do the primary (begining of disk) GPT Table:
~$sudo dd if=/dev/zero of=/dev/disk2 bs=512 count=2
2+0 records in
2+0 records out
1024 bytes transferred in 0.000777 secs (1317879 bytes/sec)
elatok@usxxelatokm1:~$sudo gpt -v show /dev/disk2
gpt show: /dev/disk2: mediasize=8004304896; sectorsize=512; blocks=15633408
gpt show: /dev/disk2: MBR not found at sector 0
start size index contents
0 15633408
And now the GPT partition scheme should be gone:
~$sudo gdisk -l /dev/disk2
GPT fdisk (gdisk) version 0.8.10
Partition table scan:
MBR: not present
BSD: not present
APM: not present
GPT: not present
Creating new GPT entries.
Disk /dev/disk2: 15633408 sectors, 7.5 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 89DB6480-47BC-49C3-B8F9-827D9B7F9A39
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 15633374
Partitions will be aligned on 2048-sector boundaries
Total free space is 15633341 sectors (7.5 GiB)
Number Start (sector) End (sector) Size Code Name
if you want, you can zero out the disk completely with diskutil (this process will be longer and it depends on the size of your usb drive… mine takes 24 mins and it’s 8GB).
~$sudo diskutil zeroDisk /dev/disk2
Started erase on disk2
[ - 0%................................................... ] 3% 0:24:00
NTFS with GPT Using diskutil
diskutil can create a GPT Partition Scheme and an MSDOS partion all in one swoop, make sure no partitions exists:
~$diskutil list /dev/disk2
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: *8.0 GB disk2
Then run the following to partition the drive:
~$diskutil partitionDisk /dev/disk2 GPT MS-DOS VOL 100%
Started partitioning on disk2
Unmounting disk
Creating the partition map
Waiting for the disks to reappear
Formatting disk2s2 as MS-DOS (FAT) with name VOL
512 bytes per physical sector
/dev/rdisk2s2: 15191032 sectors in 1898879 FAT32 clusters (4096 bytes/cluster)
bps=512 spc=8 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=411648 drv=0x80 bsec=15220736 bspf=14836 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished partitioning on disk2
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *8.0 GB disk2
1: EFI EFI 209.7 MB disk2s1
2: Microsoft Basic Data VOL 7.8 GB disk2s2
Then you can just umount the disk and reformat it with NTFS since it’s type is already 07:
~$sudo gdisk -l /dev/disk2
GPT fdisk (gdisk) version 0.8.10
Warning: Devices opened with shared lock will not have their
partition table automatically reloaded!
Partition table scan:
MBR: hybrid
BSD: not present
APM: not present
GPT: present
Found valid GPT with hybrid MBR; using GPT.
Disk /dev/disk2: 15633408 sectors, 7.5 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): FC0453E2-19AB-4D4B-8ED5-CA246662FE1F
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 15633374
Partitions will be aligned on 8-sector boundaries
Total free space is 3005 sectors (1.5 MiB)
Number Start (sector) End (sector) Size Code Name
1 40 409639 200.0 MiB EF00 EFI System Partition
2 411648 15632383 7.3 GiB 0700 VOL
It’s actually strange cause regular fdisk shows it as FAT:
~$sudo fdisk /dev/disk2
Disk: /dev/disk2 geometry: 973/255/63 [15633408 sectors]
Signature: 0xAA55
Starting Ending
#: id cyl hd sec - cyl hd sec [ start - size]
------------------------------------------------------------------------
1: EE 1023 254 63 - 1023 254 63 [ 1 - 409639] <Unknown ID>
2: 0B 1023 254 63 - 1023 254 63 [ 411648 - 15220736] Win95 FAT-32
3: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
4: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
Here is the unmount:
~$sudo diskutil unmount /dev/disk2s2
Volume VOL on disk2s2 unmounted
And to format:
~$sudo mkntfs -QF /dev/disk2s2
The partition start sector was not specified for /dev/disk2s2 and it could not be obtained automatically. It has been set to 0.
The number of sectors per track was not specified for /dev/disk2s2 and it could not be obtained automatically. It has been set to 0.
The number of heads was not specified for /dev/disk2s2 and it could not be obtained automatically. It has been set to 0.
Cluster size has been automatically set to 4096 bytes.
To boot from a device, Windows needs the 'partition start sector', the 'sectors per track' and the 'number of heads' to be set.
Windows will not be able to boot from this device.
Creating NTFS volume structures.
mkntfs completed successfully. Have a nice day.
Just to be safe, I unplugged the usb drive and plugged it back in and Mavericks auto mounted the drive as NTFS.
Replace mount_ntfs with ntfs-3g
By default when Mac OS X sees an NTFS Filesystem it mounts it as read-only. If you feel adventurous, you can follows the instructions laid out here to replace the default Mac OS NTFS mount binary. Here is the process:
Step 1. Install the ntfs-3g port.
sudo port install ntfs-3g
Step 2. Find out your userid and groupid.
User ID:
id -u
Group ID:
id -g
Step 3. Use a modified mount_ntfs executable and save the OS X original to /sbin/mount_ntfs.orig.
sudo mv /sbin/mount_ntfs /sbin/mount_ntfs.orig sudo touch /sbin/mount_ntfs sudo chmod 0755 /sbin/mount_ntfs sudo chown 0:0 /sbin/mount_ntfs sudo nano /sbin/mount_ntfs
Then paste in the following code and save it by typing Control-X and pressing “Y”. NOTE:
- You can optionally substitute in your User ID and Group ID (from Step 2 above) in place of 501 and 20 in lines 4 and 5 below.
This script also assumes the standard MacPorts install location of /opt/local/ so you will need to modify it if yours is different.
#!/bin/bash VOLUME_NAME="${@:$#}" VOLUME_NAME=${VOLUME_NAME#/Volumes/} USER_ID=501 GROUP_ID=20 TIMEOUT=20 if [ `/usr/bin/stat -f "%u" /dev/console` -eq 0 ]; then USERNAME=`/usr/bin/defaults read /Library/Preferences/com.apple.loginwindow | /usr/bin/grep autoLoginUser | /usr/bin/awk '{ print $3 }' | /usr/bin/sed 's/;//'` if [ "$USERNAME" = "" ]; then until [ `stat -f "%u" /dev/console` -ne 0 ] || [ $TIMEOUT -eq 0 ]; do sleep 1 let TIMEOUT-- done if [ $TIMEOUT -ne 0 ]; then USER_ID=`/usr/bin/stat -f "%u" /dev/console` GROUP_ID=`/usr/bin/stat -f "%g" /dev/console` fi else USER_ID=`/usr/bin/id -u $USERNAME` GROUP_ID=`/usr/bin/id -g $USERNAME` fi else USER_ID=`/usr/bin/stat -f "%u" /dev/console` GROUP_ID=`/usr/bin/stat -f "%g" /dev/console` fi /opt/local/bin/ntfs-3g \ -o volname="${VOLUME_NAME}" \ -o local \ -o negative_vncache \ -o auto_xattr \ -o auto_cache \ -o noatime \ -o windows_names \ -o user_xattr \ -o inherit \ -o uid=$USER_ID \ -o gid=$GROUP_ID \ -o allow_other \ "$@" &> /var/log/ntfsmnt.log exit $?;
With that in place, if you ever plugin a usb-drive with NTFS on it, it will auto mount it as read-write.
Strangely enough there is another utility called pdisk, which allows you to create APM (Apple Partition Map) partition schemes, but diskutil can do that as well.