Disk naming/ Exclude USB from image deployment
-
Hello,
I have some questions as i would like to find a foolproof way to exclude USB-Sticks when selecting deployment targets. That is besides just unplugging them as this would offer us a big quality of live improvement.
If multiple disks are found on the system, which one will be chosen for image deployment when no primary disk is specified for the host?
Is it just the first that is named by udev?
As far as i know udev lists disks in the same order in which they are presented by the disk controller. Is it therefore reliable to expect SATA/SAS Disks before USB attached filesystems?While deploying an image. If mutliple disks are available as targets, are disks that are too small for the image automatically disregarded?
If a disk is selected that is too small for the desired image, then the partition table will be deleted before the imaging tool aborts with an error. Is this correct?
Best Regards
-
@NX06 This depends significantly on the controller.
That said, the only 100% absolute surest way to prevent overwriting a disk you don’t want written to, at this point, IS to ensure it’s disconnected, or unavailable to the system.
The kernel and the controllers detect things at their own speed and pace.
If a “thing” presents it the “order” is only determined by how fast it puts it up.
So it’s techically possible for a drive to show up as /dev/sda this time, and the very next boot cycle show up as /dev/sdd. The following cycle, sdb, so on and so forth. The system and the presentation speed is the only factor on naming.
In normalized channelized controllers: PATA for example:
the end of the ribbon was the first return, and the midport was second. This was on purpose to also ensure the presented in the same order, hda, hdb on channel 0 where a was the end, and b was the mid way. (hdc/hdd followed the same for channel 1)
SATA controllers were presetned using the channel 0, 1, 2, 3 in that order, on purpose, but USB also presents under SATA. There’s no way to know how quick a usb stick powers up and presents what it is, especially in a consistent manner. Because of this, USB can present - sometimes at least, faster than the onboard SATA controller does.
In the world of SSD drives, though, things get a bit more complicated but follow similarly to USB/SATA in that the speed of the drive and the PCI controller presents the “order” of the drive, but this boot can be this device, and that boot can be another device.
Essentially, as I hope this expresses, if you don’t want it to be overwritten, make sure it’s not accessible during the deploy process. That’s really the only surefire way to handle it.
While we haven’t quite figured out a method due to development and time, this could be prevented assuming we know the device UUID in a consistent manner.
There’s a reason most OS’s are now using UUID’s to reference drives. That said, from FOG’s perspective that wouldn’t be a feasible approach as unless all devices are registered, and you know explicitly which drive is the one you intend, what would be the best approach?
When you know it, that works great, but FOG is intended to automate building of systems with as minimal as touch as one can think of.
-
@Tom-Elliott
Thank you for your detailed response.
This makes a lot of sense. But then how does FOG decide which disk to use when multiple options are available?In the world of SSD drives, though, things get a bit more complicated but follow similarly to USB/SATA in that the speed of the drive and the PCI controller presents the “order” of the drive, but this boot can be this device, and that boot can be another device.
So even if the only media present in the system are SSDs it is not consistent which drive slot in the physical enclosure is referenced by udev’s /dev/sdX naming scheme? Depending on how fast each drive was initialized on startup.
Would it be feasible fo me to create a udev rule for my FOS instance by compiling the kernel myself?
https://docs.fogproject.org/en/latest/kb/reference/compile-fos-kernel/In theory i should be able to create a udev rule that creates a symlink for arbitrary SATA-SSDs that points to a predefined name.
If the system does not contain more than one SATA-SSD the symlink should be unique and in turn could then be used as the Primary Disk in FOG’s Web GUI without worrying about mistakenly using a USB-Device?But then i guess this is probably more trouble than it would be worth. And it would at best only be as reliable as my udev rule.
Probably makes more sense then to incorporate the application that runs on the USB-Sticks into a dual boot image that we deploy with FOG.
Aside from this
-
@NX06 This is the code that attempts to get the hard drive:
# Gets the hard drive on the host # Note: This function makes a best guess getHardDisk() { hd="" disks="" local devs=$(lsblk -dpno KNAME -I 3,8,9,179,202,253,259 | uniq | sort -V) if [[ -n $fdrive ]]; then for spec in $(echo $fdrive | tr "," "\n"); do for dev in $devs; do if [[ "x$spec" = "x$dev" || "x$spec" = "x$(trim $(blockdev --getsize64 $dev))" || "x$spec" = "x$(trim $(lsblk -pdno SERIAL $dev))" || "x$spec" = "x$(trim $(lsblk -pdno WWN $dev))" ]]; then disks=$(echo "$disks $dev") escaped_dev=$(echo $dev | sed -e 's/[]"\/$&*.^|[]/\\&/g') devs=$(echo ${devs} | sed "s/[[:space:]]*${escaped_dev}[[:space:]]*/ /") break else p1="$(trim $(blockdev --getsize64 $dev))" p2="$(trim $(lsblk -pdno SERIAL $dev))" p3="$(trim $(lsblk -pdno WWN $dev))" fi done done disks=$( echo "${disks} ${devs}" | xargs) elif [[ -r ${imagePath}/d1.size && -r ${imagePath}/d2.size ]]; then disks=$(echo ${devs}) disk_count=$(echo "$disks" | wc -w) disk_array=() size_information=$(cat ${imagePath}/*.size 2>/dev/null) for disk_number in $(seq 1 $disk_count); do disk=$(echo $disks | cut -d' ' -f $disk_number) if [[ -n "${size_information}" ]]; then disk_size=$(blockdev --getsize64 $disk) image_matching_size=$(echo ${size_information} | grep -o "[0-9][0-9]*:${disk_size}" | head -1 | cut -d':' -f1) if [[ -n $image_matching_size && $image_matching_size -gt 0 && $image_matching_size -le 32 ]]; then disk_number=$image_matching_size else closest_sized_image=$(echo -e "${size_information}\nx:${disk_size}" | sort -t':' -k2 -n | grep -B1 "${disk_size}" | head -1 | cut -d':' -f1 ) if [[ -n $closest_sized_image && $closest_sized_image -gt 0 && $closest_sized_image -le 32 ]]; then disk_number=$closest_sized_image fi fi size_information=$(echo ${size_information} | sed "s/[[:space:]]*[0-9][0-9]*:${disk_size}[[:space:]]*//") fi echo "${disk_array[@]}" | grep -q "$disk" if [[ $? -eq 0 ]]; then handleError "Fatal Error: Disk size information would lead to overwrite the already cloned disk $disk. ($0)" fi disk_array[$disk_number]=$disk done disks=${disk_array[@]} else disks=$(echo ${devs}) fi for hd in $disks; do break done [[ -z $hd || -z $disks ]] && handleError "Cannot find hard disk(s) (${FUNCNAME[0]})\n Args Passed: $*" }
I’ll admit that it’s been a long time since this was written, but essentially it attempts to grab the lowest item first.
So hd is preferred if it exists, mmc, nvme, and finally sd
-
@Tom-Elliott
Thanks, for all the input.
I’ll see if i can find some sensible solution for my setup.