public inbox for development@lists.ipfire.org
 help / color / mirror / Atom feed
From: jon <jon.murphy@ipfire.org>
To: development@lists.ipfire.org
Subject: Re: [PATCH 1/8] extrahd.cgi: Add various perl functions deal with block devices
Date: Sat, 24 Jun 2023 22:43:47 -0500	[thread overview]
Message-ID: <E0689922-A5D5-4BDD-8EB2-7BFB48B4FE5D@ipfire.org> (raw)
In-Reply-To: <20230623040124.3826-1-stefan.schantl@ipfire.org>

[-- Attachment #1: Type: text/plain, Size: 10296 bytes --]

Stefan,

I tried to apply this patch but it doesn’t seem to work.

I notice there are no lines that begin with `-`.

Does this patch start from a blank `extrahd.cgi` file?


Jon



> On Jun 22, 2023, at 11:01 PM, Stefan Schantl <stefan.schantl(a)ipfire.org> wrote:
> 
> This functions are going to replace the former used scan/write to file/read from
> file approach by directly collecting the required informations from the
> kernel sysfs and devfs.
> 
> Signed-off-by: Stefan Schantl <stefan.schantl(a)ipfire.org>
> ---
> html/cgi-bin/extrahd.cgi | 360 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 360 insertions(+)
> 
> diff --git a/html/cgi-bin/extrahd.cgi b/html/cgi-bin/extrahd.cgi
> index 36c0efc2e..44065a8a1 100644
> --- a/html/cgi-bin/extrahd.cgi
> +++ b/html/cgi-bin/extrahd.cgi
> @@ -255,3 +255,363 @@ END
> 
> &Header::closebigbox();
> &Header::closepage();
> +
> +#
> +## Function which return an array with all available block devices.
> +#
> +sub get_block_devices () {
> +	my @devices;
> +
> +	# Open directory from kernel sysfs.
> +	opendir(DEVICES, "/sys/block");
> +
> +	# Loop through the directory.
> +	while(readdir(DEVICES)) {
> +		# Skip . and ..
> +		next if($_ =~ /^\.$/);
> +		next if($_ =~ /^\..$/);
> +
> +		# Skip any loopback and ram devices.
> +		next if($_ =~ "^loop");
> +		next if($_ =~ "^ram");
> +
> +		# Add the device to the array of found devices.
> +		push(@devices, $_);
> +	}
> +
> +	# Close directory handle.
> +	closedir(DEVICES);
> +
> +	# Return the devices array.
> +	return @devices;
> +}
> +
> +#
> +## Function which return all partitions of a given block device.
> +#
> +sub get_device_partitions ($) {
> +	my ($device) = @_;
> +
> +	# Array to store the known partitions for the given
> +	# device.
> +	my @partitions;
> +
> +	# Assign device directory.
> +	my $device_dir = "$sysfs_block_dir/$device";
> +
> +	# Abort and return nothing if the device dir does not exist.
> +	return unless(-d "$device_dir");
> +
> +	opendir(DEVICE, "$sysfs_block_dir/$device");
> +	while(readdir(DEVICE)) {
> +		next unless($_ =~ "^$device");
> +
> +		push(@partitions, $_);
> +	}
> +
> +	closedir(DEVICE);
> +
> +	@partitions = sort(@partitions);
> +
> +	return @partitions;
> +}
> +
> +#
> +## Returns the vendor of a given block device.
> +#
> +sub get_device_vendor ($) {
> +	my ($device) = @_;
> +
> +	# Assign device directory.
> +	my $device_dir = "$sysfs_block_dir/$device";
> +
> +	# Abort and return nothing if the device dir does not exist
> +	# or no vendor file exists.
> +	return unless(-d "$device_dir");
> +	return unless(-f "$device_dir/device/vendor");
> +
> +	# Open and read-in the device vendor.
> +	open(VENDOR, "$device_dir/device/vendor");
> +	my $vendor = <VENDOR>;
> +	close(VENDOR);
> +
> +	# Abort and return nothing if no vendor could be read.
> +	return unless($vendor);
> +
> +	# Remove any newlines from the vendor string.
> +	chomp($vendor);
> +
> +	# Return the omited vendor.
> +	return $vendor;
> +}
> +
> +#
> +## Returns the model name (string) of a given block device.
> +#
> +sub get_device_model ($) {
> +	my ($device) = @_;
> +
> +	# Assign device directory.
> +	my $device_dir = "$sysfs_block_dir/$device";
> +
> +	# Abort and return nothing if the device dir does not exist
> +	# or no model file exists.
> +	return unless(-d "$device_dir");
> +	return unless(-f "$device_dir/device/model");
> +
> +	# Open and read-in the device model.
> +	open(MODEL, "$device_dir/device/model");
> +	my $model = <MODEL>;
> +	close(MODEL);
> +
> +	# Abort and return nothing if no model could be read.
> +	return unless($model);
> +
> +	# Remove any newlines from the model string.
> +	chomp($model);
> +
> +	# Return the model string.
> +	return $model;
> +}
> +
> +#
> +## Returns the size of a given device in bytes.
> +#
> +sub get_device_size ($) {
> +	my ($device) = @_;
> +
> +	# Assign device directory.
> +	my $device_dir = "$sysfs_block_dir/$device";
> +
> +	# Abort and return nothing if the device dir does not exist
> +	# or no size file exists.
> +	return unless(-d "$device_dir");
> +	return unless(-f "$device_dir/size");
> +
> +	# Open and read-in the device size.
> +	open(SIZE, "$device_dir/size");
> +	my $size = <SIZE>;
> +	close(SIZE);
> +
> +	# Abort and return nothing if the size could not be read.
> +	return unless($size);
> +
> +	# Remove any newlines for the size string.
> +	chomp($size);
> +
> +	# The omited size only contains the amount of blocks from the
> +	# given device. To convert this into bytes we have to multiply this
> +	# value with 512 bytes for each block. This is a static value used by
> +	# the linux kernel.
> +	$size = $size * 512;
> +
> +	# Return the size in bytes.
> +	return $size;
> +}
> +
> +#
> +## Function which returns all currently mounted devices as a hash.
> +## example: "sda1" -> "/boot"
> +#
> +sub get_mountpoints () {
> +	my %mounts;
> +
> +	# Open and read-in the current mounts from the
> +	# kernel file system.
> +	open(MOUNT, "/proc/mounts");
> +
> +	# Loop through the known mounts.
> +	while(<MOUNT>) {
> +		# Skip mounts which does not belong to a device.
> +		next unless ($_ =~ "^/dev");
> +
> +		# Cut the line into pieces and assign nice variables.
> +		my ($dev, $mpoint, $fs, $options, $a, $b) = split(/ /, $_);
> +
> +		# Split the device name.
> +		my @tmp = split("/", $dev);
> +
> +		# Assign the plain device name to a new variable.
> +		# It is the last element of the array.
> +		my $device = $tmp[-1];
> +
> +		# Add the mountpoint to the hash of mountpoints.
> +		$mounts{"$device"} = $mpoint;
> +	}
> +
> +	# Close file handle.
> +	close(MOUNT);
> +
> +	# Return the hash of known mountpoints.
> +	return %mounts;
> +}
> +
> +sub get_swaps () {
> +	my @swaps;
> +
> +	# Open and read the swaps file.
> +	open(SWAP, "/proc/swaps");
> +
> +	# Loop though the file content.
> +	while(<SWAP>) {
> +		# Skip lines which does not belong to a device.
> +		next unless ($_ =~ "^/dev");
> +
> +		# Split the line and assign nice variables.
> +		my ($dev, $type, $size, $used, $prio) = split(/ /, $_);
> +
> +		# Cut the device line into pieces.
> +		my @tmp = split("/", $dev);
> +
> +		my $device = @tmp[-1];
> +
> +		# Add the found swap to the array of swaps.
> +		push(@swaps, $device);
> +	}
> +
> +	# Close file handle.
> +	close(SWAP);
> +
> +	# Sort the array.
> +	@swaps = sort(@swaps);
> +
> +	# Return the array.
> +	return @swaps;
> +}
> +
> +#
> +## Function with returns the mounted devices and the used filesystems as a hash.
> +## Example: "sda1" -> "ext4"
> +#
> +sub get_mountedfs () {
> +	my %mountedfs;
> +
> +	# Open and read the current mounts from the kernel
> +	# file system.
> +	open(MOUNT, "/proc/mounts");
> +
> +	# Loop through the known mounts.
> +	while(<MOUNT>) {
> +		# Skip mounts which does not belong to a device.
> +		next unless ($_ =~ "^/dev");
> +
> +		# Split line and assign nice variables.
> +		my ($dev, $mpoint, $fs, $options, $a, $b) = split(/ /, $_);
> +
> +		# Cut the device line into pieces.
> +		my @tmp = split("/", $dev);
> +
> +		# Assign the plain device name to a variable
> +		# It is the last element of the temporary array.
> +		my $device = $tmp[-1];
> +
> +		# Convert the filesystem into lower case format.
> +		$fs = lc($fs);
> +
> +		# Add the mounted file system.
> +		$mountedfs{$device} = $fs;
> +	}
> +
> +	# Close file handle.
> +	close(MOUNT);
> +
> +	# Return the hash with the mounted filesystems.
> +	return %mountedfs;
> +}
> +
> +#
> +## Function which returns all known UUID's as a hash.
> +## Example: "sda1" -> "1234-5678-abcd"
> +#
> +sub get_uuids () {
> +	my %uuids;
> +
> +	# Directory where the uuid mappings can be found.
> +	my $uuid_dir = "/dev/disk/by-uuid";
> +
> +	# Open uuid directory and read-in the current known uuids.
> +	opendir(UUIDS, "$uuid_dir");
> +
> +	# Loop through the uuids.
> +	foreach my $uuid (readdir(UUIDS)) {
> +		# Skip . and ..
> +		next if($uuid eq "." or $uuid eq "..");
> +
> +		# Skip everything which is not a symbolic link.
> +		next unless(-l "$uuid_dir/$uuid");
> +
> +		# Resolve the target of the symbolic link.
> +		my $target = readlink("$uuid_dir/$uuid");
> +
> +		# Split the link target into pieces.
> +		my @tmp = split("/", $target);
> +
> +		# Assign the last element of the array to the dev variable.
> +		my $dev = "$tmp[-1]";
> +
> +		# Add the device and uuid to the hash of uuids.
> +		$uuids{$dev} = $uuid;
> +	}
> +
> +	# Close directory handle.
> +	closedir(UUIDS);
> +
> +	# Return the hash of uuids.
> +	return %uuids;
> +}
> +
> +#
> +## Returns the device name of a given uuid.
> +#
> +sub device_by_uuid ($) {
> +	my ($uuid) = @_;
> +
> +	# Reverse the main uuids hash.
> +	my %uuids = reverse %uuids;
> +
> +	# Lookup and return the device name.
> +	return $uuids{$uuid};
> +}
> +
> +#
> +## Returns "True" in case a given path is a known mountpoint.
> +#
> +sub is_mounted ($) {
> +	my ($mpoint) = @_;
> +
> +	my %mountpoints = reverse %mountpoints;
> +
> +	# Return "True" if the requested mountpoint is known and
> +	# therefore mounted.
> +	return 1 if($mountpoints{$mpoint});
> +}
> +
> +#
> +## Returns "True" if a given mountpoint is a subdirectory of one
> +## of the directories specified by the valid_mount_dirs array abouve.
> +#
> +sub is_valid_dir ($) {
> +	my ($mpoint) = @_;
> +
> +	# Split the given mountpoint into pieces and store them
> +	# in a temporay array.
> +	my @tmp = split("/", $mpoint);
> +
> +	# Exit and return nothing if the temporary array is empty.
> +	return unless(@tmp);
> +
> +	# Build the root path based on the given mount point.
> +	my $root_path = "/" . @tmp[1];
> +
> +	# Check if the root path is valid.
> +	return 1 if(grep /$root_path/, @valid_mount_dirs);
> +}
> +
> +#
> +# Returns "True" if a device is used as swap.
> +#
> +sub is_swap ($) {
> +	my ($device) = @_;
> +
> +	return 1 if(grep /$device/, @swaps);
> +}
> -- 
> 2.39.2
> 
> 


  parent reply	other threads:[~2023-06-25  3:43 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-23  4:01 Stefan Schantl
2023-06-23  4:01 ` [PATCH 2/8] extrahd.cgi: Refactor code to use new introduced perl functions Stefan Schantl
2023-06-23  4:01 ` [PATCH 3/8] extrahd.cgi: Abort if a device could not be umounted Stefan Schantl
2023-06-23  4:01 ` [PATCH 4/8] extrahd.cgi: Store configured drives in a hash Stefan Schantl
2023-06-23  4:01 ` [PATCH 5/8] extrahd.cgi: Add is_configured function Stefan Schantl
2023-06-23  4:01 ` [PATCH 6/8] extrahd.cgi: Display mount status next to the corresponding drive Stefan Schantl
2023-06-23  4:01 ` [PATCH 7/8] extrahd.cgi: Re-order sanity check logic Stefan Schantl
2023-06-23  4:01 ` [PATCH 8/8] extrahd.cgi: Add missing translation strings Stefan Schantl
2023-06-25  3:43 ` jon [this message]
2023-07-01  9:19   ` [PATCH 1/8] extrahd.cgi: Add various perl functions deal with block devices Michael Tremer
2023-07-01 14:54     ` Stefan Schantl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E0689922-A5D5-4BDD-8EB2-7BFB48B4FE5D@ipfire.org \
    --to=jon.murphy@ipfire.org \
    --cc=development@lists.ipfire.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox