In this article, users will learn how to add an external storage device to the hardware NVR manufactured by Ubiquiti. I took this information straight out of the Ubiquiti knowledge base, used it to install a few drives and was looking for an easy way to refer to it each time I do this so here it is where I can find it and you can benefit too!
You can add any USB external storage device. However, for best peformance and longevity, I recommend using a USB 3.0 mechanical hard drive. UniFi-Video involves high bit rate transfers and as such, involves a lot of read/write cycles. With flash based memory, such as USB flash drives, Solid State Drives (SSDs), SD cards, microSD cards, etc, performance and longevity is reduced over time with a high number of read/write cycles and therefore may not be the best use case for a security system storage method.
Also, make note of the type of USB drive you’re using. I do not recommend using a USB 1.1 drive as it is too slow. USB 2.0 is OK for a couple of cameras. USB 3.0 is the fastest. The UVC-NVR/airVision-C comes equipped with 6 total USB ports; 2 USB 3.0 drives on the front of the unit and 4 USB 2.0 ports on the rear of the unit. If you’re using a USB 3.0 drive, please make sure that you have it plugged in to the front of the unit, otherwise you will not be getting the full potential of the unit.
To complete this process, you will need:
- A UVC-NVR/airVision-C powered up and plugged in to the network (In the rest of this article, I’ll simply rerfer to this as “NVR”)
- The IP address of the NVR
- Your USB external storage device
- An SSH client. For Linux and Mac users, this is built in natively in to your Terminal application. For Windows users, you’ll need to download an SSH client such as PuTTy.
- About 15 minutes of time
A few warnings before we begin
You will lose everything on your external USB storage drive following this guide, please make sure everything is backed up.
One of these steps involves rebooting the NVR to ensure that the external storage drive mounts properly upon reboot. If your system is mission critical, it is recommended that you perform these steps during off hours.
I will be showing examples from my system which is using a 16GB USB flash drive for demonstration purposes only so that you have a visual idea of what you’re looking for on your own system.
The Steps:
- Plug your external drive in to an appropriate USB port
- SSH in to the NVR. For Linux and Mac users using Terminal. For Windows users using PuTTy. The default credentials are Username: root Password: ubnt
- Find out what your drive designator is. You can do this by issuing the following command:
fdisk -l
Sample Output:
root@UniFi-NVR:~# fdisk -l Disk /dev/sda: 500.1 GB, 500107862016 bytes 255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disk identifier: 0x0008ce59 Device Boot Start End Blocks Id System /dev/sda1 * 4096 1957887 976896 83 Linux /dev/sda2 1957888 976773119 487407616 f W95 Ext'd (LBA) /dev/sda5 1959936 9771007 3905536 82 Linux swap / Solaris /dev/sda6 9773056 15624191 2925568 83 Linux /dev/sda7 15626240 976773119 480573440 8e Linux LVM Disk /dev/mapper/lvm-data0: 492.1 GB, 492105105408 bytes 255 heads, 63 sectors/track, 59828 cylinders, total 961142784 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disk identifier: 0x00000000 Disk /dev/mapper/lvm-data0 doesn't contain a valid partition table Disk /dev/sdb: 15.8 GB, 15846080512 bytes 255 heads, 63 sectors/track, 1926 cylinders, total 30949376 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x2f08ac3c Device Boot Start End Blocks Id System /dev/sdb1 16065 30941189 15462562+ f W95 Ext'd (LBA) /dev/sdb5 16128 30941189 15462531 7 HPFS/NTFS/exFAT
Note that Linux drive designators always start with “/dev/sd” and usually go in alphabetical order. The first drive plugged in is /dev/sda, the second drive plugged in is /dev/sdb. Note that you never want to do anything with /dev/sda. That is where the operating system is stored. Messing with /dev/sda may result in an unusable system!. After /dev/sdb, you see a number, this designates the partition number. Again, these are assigned in order; in this case, numerical. This doesn’t matter much because we’re going to remove all partitions on the external drive and create only one.
In the above output, my target drive is /dev/sdb, which is most likely the same for your system. I have bolded the sections of output that you should be looking for. Since I am using a 16GB external drive, 15.8GB is pretty close, so that’s how I know that’s my drive. - Now, we need to edit the partitions of the drive, we can do so by:
parted /dev/sdb
- Next, we set the partition table to GPT, like so:
(parted) mklabel gpt
and type “yes” to accept the following warning
- Now, we create the new partition, which we do so by first establishing the units that we’re working with either GB or TB, then establishing the beginning and end of the partition. Take care that the second size here should be the max size of your drive, 16GB is the size of my drive and is only shown as sample output. As such:
(parted) unit GB (parted) mkpart primary 0.00GB 16.00GB (parted)
- Then confirm everything looks correct by printing the partition table with print:
(parted) print Model: Patriot Memory (scsi) Disk /dev/sdb: 15.8GB Sector size (logical/physical): 512B/512B Partition Table: gpt Number Start End Size File system Name Flags 1 0.00GB 15.8GB 15.8GB ext4 primary
- Finally, we write these changes with quit, hich should then drop you back to the regular shell
- Now we make the filesystem:
mkfs.ext4 /dev/sdb1
- Optional and somewhat risky: All filesystems have a reserved amount of space for overhead. In this case, it’s 5%. For 16GB, this isn’t much and is probably very much so necessary. But if you’re using a 1TB+ drive, it’s probably not all that necessary to keep 51GB+ reserved. If you like, you can reduce this reservation. Note that we do not recommend going below 2%. If you choose to do this, you’re doing so at your own risk and can do so by:
tune2fs -m 2 /dev/sdb1
Where the number following the -m is the percentage to keep reserved
- Optional and somewhat risky: All filesystems have a reserved amount of space for overhead. In this case, it’s 5%. For 16GB, this isn’t much and is probably very much so necessary. But if you’re using a 1TB+ drive, it’s probably not all that necessary to keep 51GB+ reserved. If you like, you can reduce this reservation. Note that we do not recommend going below 2%. If you choose to do this, you’re doing so at your own risk and can do so by:
- Now, create a mount point where we will be mounting our partition. For simplicity and to avoid confusion, we recommend naming it something indicative that it’s an external storage device and putting it somewhere where it’s not confusing. For demonstration purposes, we’re going with /exthd. So:
mkdir /exthd
- Mount the parition:
mount -t ext4 /dev/sdb1 /exthd
- Make the mount occur at boot time. If you’re familiar with Linux, you can use vi which is installed already, but we’re going to install nano for a simple, more notepad like editor:
apt-get update; apt-get install nano
Then:
nano /etc/rc.local
And insert your mount command from step 11, your whole file should look like this:
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. mount -t ext4 /dev/sdb1 /exthd exit 0
Ctrl+x to exit, you’ll be prompted to save, press y on your keyboard followed by enter on your keyboard.
- Reboot the NVR:
reboot
- When the system comes back up, SSH back in. Issue the mount command:
mount
You should see something like this:
root@UniFi-NVR:~# mount sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) udev on /dev type devtmpfs (rw,relatime,size=10240k,nr_inodes=503334,mode=755
) devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode =000) tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=403736k,mode=755) /dev/disk/by-label/boot on /boot type ext2 (ro,noatime,errors=continue,user_xattr,acl) /dev/loop0 on /mnt/.rofs type squashfs (ro,relatime) /dev/disk/by-label/user.0 on /mnt/.rwfs type ext4 (rw,noatime,data=ordered) aufs-root on / type aufs (rw,relatime,si=8458a27b1bc70b71) tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k) tmpfs on /run/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=1588560k) tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime,nodiratime,size=807468k) /dev/mapper/lvm-data0 on /srv type ext4 (rw,noatime,nodiratime,data=ordered) /dev/mapper/lvm-data0 on /var/lib/unifi type ext4 (rw,noatime,nodiratime,data=ordered) /dev/mapper/lvm-data0 on /var/lib/mfi type ext4 (rw,noatime,nodiratime,data=ordered) tmpfs on /var/cache/unifi-video type tmpfs (rw,noexec,noatime,nodiratime,size=524288k,mode=77 7,uid=104) /dev/sdb1 on /exthd type ext4 (rw,relatime,data=ordered) That means that the partition mounts on boot, we’re in the home stretch.
- Now change the permissions of the mount point of /exthd:
chown unifi-video:unifi-video /exthd
- Log in to your UniFi-Video web interface
- Go to Settings in the lower left hand corner
- Click the NVR SETTINGS button in the upper left hand corner
- Expand the CONFIGURE tab if it isn’t already
- Change your Recording Path to “/exthd” (without quotations)
- Change your Space To Keep Free to about 5% of your overall drive space
- Save these settings
- Keep an eye on your records in the web interface and/or the /exthd directory with the ls command:
ls /exthd
to ensure that there’s data being stored there.
- You’re all done!
Trackbacks/Pingbacks