Image shamelessly borrowed from the Internet |
Background
One of the first steps the end user must perform after installing ZoneMinder is to dedicate an entire partition, drive, or network share for ZoneMinder's event storage. The reason being, ZoneMinder will, by design, fill up your hard disk, and you don't want to do that to your root volume! The traditional method for accomplishing this is documented here, and that method continues to work well.However, due to the mass adoption of Systemd we now have a new way to accomplish this, which happens to give us something the former method did not. Read on to learn more!
First, take a big sip from the Kool-Aid, and let the effects of Systemd wash upon you. See, that wasn't so bad, was it?
Systemd natively integrates all sorts of system admin functions that the legacy sys v init didn't have anything to do with. One of those functions is the ability to create mount points, much in the same way one would create a service (a.k.a. unit) file.
Collect Information
We need to know the following before we get started:- Find the ZoneMinder events and images folders on your filesystem
- Determine the name of the web account user
- For local volumes, determine the device name of the volume
- For local volumes, determine the uuid of the volume
- For remote volumes, determine the sharing protocol to be used e.g. nfs, smb, etc
- For remote volumes, determine the share name
The location of the events and images folder will vary by Linux distro. You are looking for an actual folder, NOT a symlink! Redhat distros tend to put these folders under /var/lib/zoneminder while Debian distros prefer /var/cache/zoneminder. These folder locations are chosen by each distros' packaging guidelines.
On most Linux distros, you can view the uuid of each of your volumes like so:
ls -l /dev/disk/by-uuidOn my system, the items above are as follows:
- /var/lib/zoneminder
- apache
- /dev/sdb1
- 6028c127-5d99-4860-981f-2984b4c10fd9
Migrate existing data
I'm not going to get into the details of this since the necessary steps will vary with each system. What you need to do is migrate whatever happens to be in the ZoneMinder events and images folders over to the new partition, disk, or network share. You do this by mounting the target from the command line via the normal fashion to a temporary folder, issue the appropriate move commands, and finally unmount the target.Do that now.
Create the first Systemd Mount Unit
You will be creating a total of three mount units. The first mount unit mounts the drive or partition to your system. To do that create a new folder. I prefer to put mount points under /mnt and give the name of the subfolder the same name as the device or share. In my case, that would be sdb1.sudo mkdir /mnt/sdb1When creating mount units with systemd, the filename describing the mount point has to be named in a specific manner. Since the folder I just created is at /mnt/sdb1, one has to name the mount unit mnt-sdb1.mount. Create that file in the /etc/systemd/system folder, then add the following contents, changing the path and uuid to match that of your system:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # systemd mount unit for ZoneMinder event storage [Unit] Description=systemd mount unit for ZoneMinder event storage Before=zoneminder [Mount] What=/dev/disk/by-uuid/6028c127-5d99-4860-981f-2984b4c10fd9 Where=/mnt/sdb1 Type=ext4 Options=defaults,noatime,commit=120,data=writeback [Install] WantedBy=multi-user.target |
Now enable and start the unit:
sudo systemctl enable mnt-sdb1.mount
sudo systemctl start mnt-sdb1.mount
Set Folder Permissions
We've created our primary mount point, but we aren't done yet. First, let's create some folders and set the correct permissions:sudo suRemember that, if you are not running a Redhat distro, the web user account might be named something other than apache on your system.
mkdir -p /mnt/sdb1/zoneminder/events
mkdir -p /mnt/sdb1/zoneminder/images
chmod -R apache:apache /mnt/sdb1/zoneminder
exit
Create two Systemd Bind Mount Units
With the events and images folders created, we want to create two mount units, which bind mount those folders into the desired places.Create the file /etc/systemd/system/var-lib-zoneminder-events.mount then add the following content to it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # systemd bind mount unit for ZoneMinder event storage [Unit] Description=systemd bind mount unit for ZoneMinder event storage After=mnt-sdb1.mount Requires=mnt-sdb1.mount [Mount] What=/mnt/sdb1/zoneminder/events Where=/var/lib/zoneminder/events Type=none Options=bind [Install] WantedBy=local-fs.target |
Now enable and start the unit:
sudo systemctl enable var-lib-zoneminder-events.mountWe now need to do the same thing to the images folder. Create the file /etc/systemd/system/var-lib-zoneminder-images.mount then add the following content to it:
sudo systemctl start var-lib-zoneminder-events.mount
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # systemd bind mount unit for ZoneMinder image storage [Unit] Description=systemd bind mount unit for ZoneMinder image storage After=mnt-sdb1.mount Requires=mnt-sdb1.mount [Mount] What=/mnt/sdb1/zoneminder/images Where=/var/lib/zoneminder/images Type=none Options=bind [Install] WantedBy=local-fs.target |
Now enable and start the unit:
sudo systemctl enable var-lib-zoneminder-images.mountNow reboot and verify all three mount points were successful:
sudo systemctl start var-lib-zoneminder-images.mount
df -aThat's it!
Bonus Points. Leverage the Power of Systemd
If you recall, I mentioned that using systemd to manage your mount points has an advantage over the previous method. With your mount points configured with systemd, you can easily prevent ZoneMinder from starting, should the mount point fail for any reason. Anyone who has ever started ZoneMinder without realizing there was a problem reading from the events folder can tell you what happens when this occurs. You lose all your events, and yes this is by design.To prevent that from happening we need to modify our zoneminder service file. First, make a copy of it:
sudo cp /usr/lib/systemd/system/zoneminder.service /etc/systemd/system/Then open the copy and add "Requires=mnt-sdb1.mount" under the [unit] block:
1 2 3 4 5 6 7 8 | # ZoneMinder systemd unit file for CentOS 7 [Unit] Description=ZoneMinder CCTV recording and security system After=network.target mariadb.service httpd.service After=zfs.target zfs-mount.service zfs-share.service Requires=mariadb.service httpd.service Requires=mnt-sdb1.mount |
Now issue a daemon reload to tell systemd to pick up the change:
sudo systemctl daemon-reloadShould the mount point fail during startup, systemd will prevent the ZoneMinder service from starting with a message stating a failed dependency. Your events are saved from deletion!