[stgt] [PATCH 1/2] tgt-admin: allow "lun" to be specified per device

Tomasz Chmielewski mangoo at wpkg.org
Wed Oct 1 14:49:39 CEST 2008


Allow custom "lun" to be specified per device.



Signed-off-by: Tomasz Chmielewski <mangoo at wpkg.org>

diff --git a/scripts/tgt-admin b/scripts/tgt-admin
index e4be373..2eded0e 100755
--- a/scripts/tgt-admin
+++ b/scripts/tgt-admin
@@ -211,6 +211,7 @@ sub add_targets {
 					# and other parameters which can be specified globally
 					my %target_options;
 					my $target_options_ref;
+					my $data_key;
 					foreach my $k3 (sort keys %{$conf{$k}{$k2}}) {
 						$lun = 1;
 						$option = $k3;
@@ -218,6 +219,7 @@ sub add_targets {
 						check_value($value);
 						$target_options{$option} = $value;
 						$target_options_ref = \%target_options;
+						$data_key = make_key("lun", $target_options_ref);
 					}
 
 					if (not defined $target_options{"driver"}) {
@@ -230,7 +232,7 @@ sub add_targets {
 						$option = $k3;
 						$value = $conf{$k}{$k2}{$k3};
 						check_value($value);
-						process_options($target_options_ref);
+						process_options($target_options_ref,$data_key);
 						# If there was no option called "initiator-address", it means
 						# we want to allow ALL initiators for this target
 						if ($option eq "initiator-address") {
@@ -258,6 +260,24 @@ sub add_targets {
 	}
 }
 
+# Pre-parse the config and get some values we need
+sub make_key {
+	my $action = $_[0];
+	my $target_options_ref = $_[1];
+	my %data_key;
+	if (ref $$target_options_ref{'backing-store'} eq "HASH") {
+		foreach my $testlun (keys %{$$target_options_ref{'backing-store'}}) {
+			$data_key{$testlun}{'lun'} = $$target_options_ref{'backing-store'}{$testlun}{$action};
+		}
+	}
+	if (ref $$target_options_ref{'direct-store'} eq "HASH") {
+		foreach my $testlun (keys %{$$target_options_ref{'direct-store'}}) {
+			$data_key{$testlun}{'lun'} = $$target_options_ref{'direct-store'}{$testlun}{$action};
+		}
+	}
+	return \%data_key;
+}
+
 # Some options can be specified only once
 sub check_if_hash_array {
 	my $check = $_[0];
@@ -315,27 +335,58 @@ sub add_params {
 	}
 }
 
+# Find next available LUN
+sub find_next_lun {
+	my $backing_store = $_[0];
+	my $data_key_ref = $_[1];
+	my $lun_collision = 0;
+	my $lun_is_free = 0;
+	my $found_lun = 1;
+	while ($lun_is_free == 0) {
+		foreach my $testlun (keys %$data_key_ref) {
+			foreach my $testlun2 (values %{$$data_key_ref{$testlun}}) {
+				if ($found_lun eq $testlun2) {
+					$lun_collision = 1;
+				}
+			}
+		}
+		if ($lun_collision == 0) {
+			$lun_is_free = 1;
+		} else {
+			$found_lun += 1;
+		}
+		$lun_collision = 0;
+	}
+	$$data_key_ref{$backing_store}{'lun'} = $found_lun;
+	return $found_lun;
+}
+
 # Add backing or direct store
 sub add_backing_direct {
 	my $backing_store = $_[0];
 	my $target_options_ref = $_[1];
-	my $lun = $_[2];
+	my $lun;
+	my $data_key_ref = $_[2];
 	my $direct_store = $_[3];
 	my $driver = $$target_options_ref{"driver"};
-
+	
 	# Is the device in use?
 	(my $can_alloc, my $dev) = check_device($backing_store);
-
-	# Needed if the config file has mixed definitions
-	if (ref($backing_store) eq "HASH") {
-		foreach my $backing_store (sort keys %$value) {
-			add_backing_direct($backing_store,$target_options_ref,$lun,$direct_store);
-			$lun += 1;
-		}
-		return $lun;
-	} elsif (-e $backing_store && $can_alloc == 1) {
+	
+	if (-e $backing_store && $can_alloc == 1) {
 		my @exec_commands;
 		my $device_type;
+		my %luns;
+		my @added_luns;
+		# Find out LUNs which are "reserved" in the config file
+		if (ref $value eq "HASH") {
+			if (length $$data_key_ref{$backing_store}{'lun'}) {
+				$lun = $$data_key_ref{$backing_store}{'lun'};
+			} else {
+				# Find an available lun if it wasn't specified
+				$lun = find_next_lun($backing_store,$data_key_ref);
+			}
+		}
 		# Process parameters for each lun / backing store
 		if (ref $value eq "HASH") {
 			my %params_added;
@@ -447,6 +498,11 @@ sub add_backing_direct {
 				check_if_hash_array($$target_options_ref{"device-type"}, "device-type");
 				$device_type = $$target_options_ref{"device-type"};
 			}
+			# lun 
+			if (length $$target_options_ref{"lun"}) {
+				check_if_hash_array($$target_options_ref{"lun"}, "lun");
+				$lun = $$target_options_ref{"lun"};
+			}
 		} else {
 			print "If you got here, this means your config file is not supported.\n";
 			print "Please report it to stgt mailing list and attach your config files.\n";
@@ -471,6 +527,7 @@ sub add_backing_direct {
 # Process options from the config file
 sub process_options {
 	my $target_options_ref = $_[0];
+	my $data_key_ref = $_[1];
 	my $driver = $$target_options_ref{"driver"};
 	if ($option eq "backing-store" || $option eq "direct-store") {
 		my $direct_store = 0;
@@ -495,7 +552,13 @@ sub process_options {
 
 		if (ref($value) eq "HASH") {
 			foreach my $backing_store (sort keys %$value) {
-				$lun = add_backing_direct($backing_store,$target_options_ref,$lun,$direct_store);
+				if ($backing_store =~ m/HASH/) {
+					print "\nYour config file is not supported. See targets.conf.example for details.\n";
+					exit 1;
+				}
+			}
+			foreach my $backing_store (sort keys %$value) {
+				add_backing_direct($backing_store,$target_options_ref,$data_key_ref,$direct_store);
 			}
 		}
 	}



-- 
Tomasz Chmielewski
http://wpkg.org
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list