Failed to add external hard disk with FreeBSD 10.1

I am trying to add a 4 TB external hard disk to my FreeBSD server connected to a USB3 port and I am facing the following problem.

I am able to format this disk using :

Code:
sudo gpart create -s GPT da1
sudo gpart add -t freebsd-ufs da1
sudo newfs -U /dev/da1p1
sudo mkdir /backup
sudo chmod 775 /backup

Then, I test it with a manual mount :

sudo mount /dev/da1p1 /backup

This works as I am able to create a file ( touch /backup/foo)

Then, I unmount it and add a new line in /etc/fstab

Code:
/dev/da1p1 /backup ufs rw 0 3

Which I test with :

sudo mount -a

and it works as well.

The problem is when I reboot the machine, there is a systematic error during boot with following error :

Code:
FreeBSD EFI Boot Block
Loader path : /boot/loader.efi

I have then to delete the line I have added in /etc/fstab in order for it to start.

If I understand correctly, the mount -a command is using the content of /etc/fstab which indicates the file content is ok (no hidden characters or wrong syntax). So, why doesn't it work during boot ?

Thanks for your help.
 
It might be mounted a bit too soon. You could try this:
Code:
 /dev/da1p1 /backup ufs rw,late 0 3
The late keyword will make it mount later in the boot process.

Order is important too. Are there other filesystems mounted in /etc/fstab? If /backup is mounted before / you're going to have problems too.
 
Full /etc/fstab is :
Code:
# Device        Mountpoint      FStype  Options Dump    Pass#
/dev/ada0p2     /               ufs     rw      1       1
/dev/ada0p3     none            swap    sw      0       0
/dev/ada1p1     /data           ufs     rw      2       2
/dev/da1p1 /backup ufs rw 0 3
 
Two potentials I can think of:

Were you trying to boot without the disk plugged in? Unless you intend to leave the disk connected for every boot, you need to adjust your /etc/fstab entry to include the noauto option (see the fstab(5) man page) and then mount it manually.

Will the server boot at all with the external disk with the UFS partition plugged in? The reason that I ask is that the UEFI boot loader for FreeBSD 10.1-RELEASE searches for the first partition of type UFS, irrespective of what disk it is on. Perhaps your UEFI BIOS is ordering the external drive ahead of the internal one, so your system is trying and failing to find the second stage boot loader on the external drive.

Edit: Reference for point two on the UEFI page of the FreeBSD wiki.
 
Can you provide some more information? What version of FreeBSD are you using? Are you trying to boot with the external disk plugged in? Or without it plugged in? What happens when the computer does not boot? What error message(s), if any, can you see? When does the computer boot successfully? What is your partition layout (output of gpart show)?
 
  • FreeBSD 10.1
  • Yes, I try to boot with the external disk connected
  • When it boots, the only error displayed is
FreeBSD EFI Boot Block
Loader path : /boot/loader.efi

  • gpart show

$ gpart show
=> 34 468862061 ada0 GPT (224G)
34 1600 1 efi (800K)
1634 461371840 2 freebsd-ufs (220G)
461373474 7488620 3 freebsd-swap (3.6G)
468862094 1 - free - (512B)

=> 34 3907029101 ada1 GPT (1.8T)
34 6 - free - (3.0K)
40 3907029088 1 freebsd-ufs (1.8T)
3907029128 7 - free - (3.5K)

=> 6 976746229 da1 GPT (3.6T)
6 976746229 1 freebsd-ufs (3.6T)

=> 6 976746229 diskid/DISK-574343344533545837543332 GPT (3.6T)
6 976746229 1 freebsd-ufs (3.6T)
 
I was busy replying to the original version of your post last post... which I now see you have edited:
It boots without any error.

So, with a quick U-turn... I believe that the issue is what I suggested in my first post; that the FreeBSD UEFI bootloader finds the UFS partition on the external disk first and tries (unsuccessfully) to boot from it. The "correct" fix is for the UEFI boot loader to be developed further to offer more sophisticated boot options. However, this won't help you right now.

There are a number of options for a work-around:
  1. Always boot with the external disk unplugged and plug it in when you want to use it
  2. Change the partition type of the external disk UFS partition to something that isn't freebsd-ufs like linux-data so that the UEFI boot loader will ignore it. If in /etc/fstab you specify the partition is actually UFS it will mount without issue.
  3. Stop using the UEFI boot loader and reconfigure your system to use old style BIOS ("legacy" boot) and the MBR FreeBSD bootloaders.
My recommended option would be option 2, since this involves minimal changes to your FreeBSD system and means you don't have to be physically present to reboot the server. Edit: However, it does require destroying the UFS partition on the external hard disk and therefore losing any data contained on it. Unfortunately gpart(8) does not support modifying the partition type of an existing partition and I'm not about to recommend manually editing the GPT data with a hex editor!

The steps you need to take are below. I see you are using security/sudo and have assumed you are logged in as a user that is configured to have root access via sudo:

Edited since I unnecessarily instructed to destroy the old partition:

  1. Unplug the external hard disk and boot your system (I assume this works fine?)
  2. Once booted, plug in the external hard disk
  3. Destroy the existing UFS partition on the external disk with sudo gpart destroy /dev/da1p1
  4. Create a new partition. Change the partition type. I'm going to suggest making it of type linux-data but if you also have GNU/Linux systems that might be confusing for you later and so you might want to choose something different (see the gpart(8) man page for options) like apple-tv-recovery; it doesn't matter as long as it is not freebsd-ufs: sudo gpart add -t linux-data /dev/da1
  5. Format the new partition as UFS - I see you wanted to enable soft updates: sudo newfs -U /dev/da1p1
  6. Add a line into /etc/fstab if you want for easy mounting. Note I couldn't get tabs in the forum editor. I have suggested the noauto flag since the disk is removable and may not be present at boot, though this will also mean you have to mount it manually or through a script:
    Code:
    # Device Mountpoint FStype Options Dump Pass#
    /dev/da1p1 /backup ufs rw,noauto 0 0
Try rebooting with the disk plugged in :)

Edit: Reworded for clarity on recommended option and remembered to add the noauto option
Further edit: Added notes to say I was wrong about not being able to change partition type - thank you tobik
 
Last edited:
Unfortunately gpart(8) does not support modifying the partition type of an existing partition
Are you sure? The man page suggests otherwise:
modify
Modify a partition from geom geom and further identified by the
-i index option. Only the type and/or label of the partition
can be modified. To change the type of a partition, specify
the new type with the -t type option.
 
I stand corrected! Thierry Leloup, you don't need to destroy the partition on the external hard disk. Just change its type with gpart modify -i 1 -t linux-data /dev/da1p1 :)

Edit: Corrected from "configure" to "modify" for the command before tobik can point it out. I'm obviously having a bad day reading documentation. Note to self - don't write any important code! And where did strike-through go from the old forums?
Further edit (head in hands): To correct as tobik's post below
 
I just tried to change the partition type with
sudo gpart modify -i 1 -t linux-data da1
without any related line in /etc/fstab which is as follows :
Code:
# Device        Mountpoint      FStype  Options Dump    Pass#
/dev/ada0p2     /               ufs     rw      1       1
/dev/ada0p3     none            swap    sw      0       0
/dev/ada1p1     /data           ufs     rw      2       2

Note : ada0 is a 240 GB SSD and ada1 a 2 TB hard disk...

I rebooted the server and the error is still there. I then need to unplug the external disk in order for the server to boot...
 
Hmmm. So either my diagnosis is incorrect, or my assumption that the UEFI boot loader chooses the boot partition based on the GPT type is incorrect.

I didn't have any ideas for a different cause, so I had a look at the source code for the UEFI boot loader. I had expected that it would examine the GPT partition type for each partition and attempt to load the next stage from the first partition of type freebsd-ufs. However, I believe it ignores the partition type and instead tests each disk partition to see whether it has a UFS filesystem, attempting to load the next stage from the first it finds. I've posted my code investigation* at the bottom, since it is quite long.

If I am correct, this means that changing the GPT partition type as I suggested would not work. Thierry Leloup: Can you test my theory by trying the following and reporting back what happens:
  • Deleting the partition on the external disk ( sudo gpart delete -i 1 /dev/da1) and trying to boot your server with the disk plugged in.
  • Creating a partition of type UFS ( sudo gpart add -t freebsd-ufs /dev/da1) but writing an invalid file system (Warning: destroys data on the disk! sudo dd if=/dev/urandom of=/dev/da1p1 bs=1m count=64 to write 64MB of pseudo-random data to the start of the partition) and trying to boot your server with the disk plugged in.
I expect that in both situations your server will boot correctly. If so, a horrible work-around might be to create the partition on your external drive so that FreeBSD can recognise it but the UEFI bootloader does not. My first thought was to use old-style FreeBSD partitioning, with a MBR partitioning scheme for the external disk, a slice for the BSD label and then a UFS partition within that. Since the UEFI bootloader will find the BSD label and not the UFS filesystem that might work. Before we try that, let's see how you get on with the tests I proposed.

* Ad:
I had a look at the source code for the UEFI boot loader. In the efi_main() function I can see the lines (128, 129) that print the last messages Thierry Leloup sees:
Code:
128 printf(" \n>> FreeBSD EFI boot block\n");
129 printf(" Loader path: %s\n", path);
I believe the next lines (131-154) loop through the list of block devices attached to the system. Devices that are not disk partitions are skipped (lines 149-150 and see the UEFI Specification version 2.5 page 601). For each partition, the domount() function is called. When a UFS filesystem is successfully mounted, the loop ends.
Code:
131 status = systab->BootServices->LocateHandle(ByProtocol,
132 &BlockIoProtocolGUID, NULL, &nparts, handles);
133 nparts /= sizeof(handles[0]);
134
135 for (i = 0; i < nparts; i++) {
136 status = systab->BootServices->HandleProtocol(handles[i],
137 &DevicePathGUID, (void **)&devpath);
138 if (EFI_ERROR(status))
139 continue;
140
141 while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
142 devpath = NextDevicePathNode(devpath);
143
144 status = systab->BootServices->HandleProtocol(handles[i],
145 &BlockIoProtocolGUID, (void **)&blkio);
146 if (EFI_ERROR(status))
147 continue;
148
149 if (!blkio->Media->LogicalPartition)
150 continue;
151
152 if (domount(devpath, blkio, 1) >= 0)
153 break;
154 }
[/i][/i]
The domount() function calls fsread() from ufsread.c:
Code:
267 static int
268 domount(EFI_DEVICE_PATH *device, EFI_BLOCK_IO *blkio, int quiet)
269 {
270
271 dmadat = &__dmadat;
272 bootdev = blkio;
273 bootdevpath = device;
274 if (fsread(0, NULL, 0)) {
275 if (!quiet)
276 printf("domount: can't read superblock\n");
277 return (-1);
278 }
279 if (!quiet)
280 printf("Succesfully mounted UFS filesystem\n");
281 return (0);
282 }
The fsread() function (I've cut it down to the crucial parts), I believe reads the blocks at the start of the partition to determine whether or not it is a UFS file system. At no point is the GPT partition type considered.
Code:
static ssize_t
168 fsread(ufs_ino_t inode, void *buf, size_t nbyte)
169 {
[...]
192 for (n = 0; sblock_try[n] != -1; n++) {
193 if (dskread(dmadat->sbbuf, sblock_try[n] / DEV_BSIZE,
194 SBLOCKSIZE / DEV_BSIZE))
195 return -1;
196 memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
197 if ((
198 #if defined(UFS1_ONLY)
199 fs.fs_magic == FS_UFS1_MAGIC
200 #elif defined(UFS2_ONLY)
201 (fs.fs_magic == FS_UFS2_MAGIC &&
202 fs.fs_sblockloc == sblock_try[n])
203 #else
204 fs.fs_magic == FS_UFS1_MAGIC ||
205 (fs.fs_magic == FS_UFS2_MAGIC &&
206 fs.fs_sblockloc == sblock_try[n])
207 #endif
208 ) &&
209 fs.fs_bsize <= MAXBSIZE &&
210 fs.fs_bsize >= sizeof(struct fs))
211 break;
212 }
213 if (sblock_try[n] == -1) {
214 printf("Not ufs\n");
215 return -1;
216 }[...]
304 }
 
@ asteriskRoss : thanks for your help.

Here is the result of what you proposed :
  • Deleting the partition on the external disk ( sudo gpart delete -i 1 /dev/da1) and trying to boot your server with the disk plugged in. => The server has booted.
  • Creating a partition of type UFS ( sudo gpart add -t freebsd-ufs /dev/da1) but writing an invalid file system (Warning: destroys data on the disk! sudo dd if=/dev/urandom of=/dev/da1p1 bs=1m count=64 to write 64MB of pseudo-random data to the start of the partition) and trying to boot your server with the disk plugged in. => The server is not booting.
It might be a stupid question (I am not a newbie in FreeBSD) : is it normal that gpart show shows 2 devices for my external disk :
Code:
$ gpart show
=>       34  468862061  ada0  GPT  (224G)
          34       1600     1  efi  (800K)[/INDENT]
       1634  461371840     2  freebsd-ufs  (220G)
  461373474    7488620     3  freebsd-swap  (3.6G)
  468862094          1        - free -  (512B)

=>        34  3907029101  ada1  GPT  (1.8T)
          34           6        - free -  (3.0K)
          40  3907029088     1  freebsd-ufs  (1.8T)
  3907029128           7        - free -  (3.5K)

=>        6  976746229  da1  GPT  (3.6T)
          6  976746229    1  freebsd-ufs  (3.6T)

=>        6  976746229  diskid/DISK-574343344533545837543332  GPT  (3.6T)
          6  976746229                                     1  freebsd-ufs  (3.6T)
 
It might be a stupid question (I am not a newbie in FreeBSD) : is it normal that 'gpart show' shows 2 devices for my external disk
I checked on my UEFI FreeBSD laptop and saw the same behaviour for all disks connected to my system except the disk with my FreeBSD system installed. The man page for gpart(8) says it will show "all geoms if none are specified" but I agree the behaviour with multiple entries for some disks but not others is not what I would expect. I don't think this is the cause of your issue though, since it appears your boot fails at the point where the first stage UEFI boot loader runs, before even the kernel has loaded.

Deleting the partition on the external disk (sudo gpart delete -i 1 /dev/da1) and trying to boot your server with the disk plugged in. => The server has booted.
Great - that's what I expected.
Creating a partition of type UFS (sudo gpart add -t freebsd-ufs /dev/da1) but writing an invalid file system (Warning: destroys data on the disk! sudo dd if=/dev/urandom of=/dev/da1p1 bs=1m count=64 to write 64MB of pseudo-random data to the start of the partition) and trying to boot your server with the disk plugged in. => The server is not booting.
Interesting and not what I expected. Could you check for me that the UFS file system is invalid by booting to FreeBSD and then trying to mount it?

Since that wasn't what I expected, I am also going to try a second approach of "trying anything that might get the job done" in addition to "fully understanding what is going wrong".

I expect that your UEFI firmware, if it complies with the UEFI specifications, will be able to read GPT and MBR partitioning schemes. I would not expect it to be able to read BSD labels, dangerously dedicated or otherwise. Could you therefore also try configuring your external disk in each of the following ways and trying to boot with it plugged in:
  • Using a GPT partitioning scheme, create a single partition of another type (FAT32, NTFS, ZFS as you choose -- anything except UFS) and formatting it with a valid filesystem of that type (ending up as /dev/da1p1).
  • Creating an old-style FreeBSD partitioning scheme on the external disk with MBR disk partitioning, then a slice with a BSD label and within that a UFS partition (that will therefore end up as /dev/da1s1a).
  • Creating a dangerously dedicated BSD label and within that a UFS partition (ending up as /dev/da1a).
I am not a newbie in FreeBSD
I have taken you at your word and assumed knowledge in my requests above but if you need more information just ask :)
 
Sorry for the long delay, asteriskRoss. I will try what you have suggested in the next days.

And, BTW, I made a typo when I mentioned "I am not a newbie in FreeBSD": don't know why I put the "not" word as I REALLY am a newbie in FreeBSD...
 
I finally found a solution. I don't like it but it works.

Before that, FYI, I tried following things :
  1. Linux partition with no reference to da1 in fstab => FAILED
  2. NTFS partition with no reference to da1 in fstab => FAILED
  3. NTFS partition with reference to da1 in fstab and rw,noauto => FAILED
  4. NTFS partition with reference to da1 in fstab and xx => FAILED
Then, I finally ends up doing the following :
  1. Destroy da1
  2. Leave the external disk connected
  3. reboot => OK
  4. in crontab, when a backup is needed :
    1. create da1 and da1p1
    2. mount da1p1
    3. Copy necessary files for the backup task
    4. unmount da1p1
    5. destroy da1
 
I finally found a solution. I don't like it but it works.
Before that, FYI, I tried following things :
[...]
Did you try the three things I suggested in my last post?
Could you therefore also try configuring your external disk in each of the following ways and trying to boot with it plugged in:
  • Using a GPT partitioning scheme, create a single partition of another type (FAT32, NTFS, ZFS as you choose -- anything except UFS) and formatting it with a valid filesystem of that type (ending up as /dev/da1p1).
  • Creating an old-style FreeBSD partitioning scheme on the external disk with MBR disk partitioning, then a slice with a BSD label and within that a UFS partition (that will therefore end up as /dev/da1s1a).
  • Creating a dangerously dedicated BSD label and within that a UFS partition (ending up as /dev/da1a).
I was hopeful that MBR partitioning with a slice (BSD label) and then a UFS partition underneath (ending up as /dev/da1s1a) would work.
If you're not familiar with how to do any of these then just say and I'll prepare some instructions.
 
Back
Top