The initial commit of 0.9.5-pre1 version
[mirror/scst/.git] / scstadmin / SCST / SCST.pm
1 package SCST::SCST;
2
3 # Author:       Mark R. Buechler
4 # Copyright (c) 2005, 2006 Mark R. Buechler
5
6 use 5.005;
7 use IO::Handle;
8 use IO::File;
9 use strict;
10 use Carp;
11
12 my $TRUE  = 1;
13 my $FALSE = 0;
14
15 my $_SCST_DIR_           = '/proc/scsi_tgt';
16 my $_SCST_IO_            = $_SCST_DIR_.'/scsi_tgt';
17 my $_SCST_CDROM_IO_      = $_SCST_DIR_.'/dev_cdrom/dev_cdrom';
18 my $_SCST_CHANGER_IO_    = $_SCST_DIR_.'/dev_changer/dev_changer';
19 my $_SCST_DISK_IO_       = $_SCST_DIR_.'/dev_disk/dev_disk';
20 my $_SCST_DISK_FILE_IO_  = $_SCST_DIR_.'/disk_fileio/disk_fileio';
21 my $_SCST_CDROM_FILE_IO_ = $_SCST_DIR_.'/cdrom_fileio/cdrom_fileio';
22 my $_SCST_DISKP_IO_      = $_SCST_DIR_.'/dev_disk_perf/dev_disk_perf';
23 my $_SCST_MODISK_IO_     = $_SCST_DIR_.'/dev_modisk/dev_modisk';
24 my $_SCST_MODISKP_IO_    = $_SCST_DIR_.'/dev_modisk_perf/dev_modisk_perf';
25 my $_SCST_TAPE_IO_       = $_SCST_DIR_.'/dev_tape/dev_tape';
26 my $_SCST_TAPEP_IO_      = $_SCST_DIR_.'/dev_tape_perf/dev_tape_perf';
27 my $_SCST_GROUPS_DIR_    = $_SCST_DIR_.'/groups';
28 my $_SCST_SGV_STATS_     = $_SCST_DIR_.'/sgv';
29 my $_SCST_SESSIONS_      = $_SCST_DIR_.'/sessions';
30 my $_SCST_VERSION_IO_    = $_SCST_DIR_.'/version';
31
32 my $_SCST_USERS_IO_      = 'names';
33 my $_SCST_DEVICES_IO_    = 'devices';
34
35 my @_AVAILABLE_OPTIONS_  = ('WRITE_THROUGH', 'O_DIRECT', 'READ_ONLY', 'NULLIO', 'NV_CACHE');
36
37 use vars qw(@ISA @EXPORT $VERSION $CDROM_TYPE $CHANGER_TYPE $DISK_TYPE $DISKFILE_TYPE
38             $CDROMFILE_TYPE $DISKPERF_TYPE $MODISK_TYPE $MODISKPERF_TYPE $TAPE_TYPE
39             $TAPEPERF_TYPE);
40
41 $CDROM_TYPE      = 1;
42 $CHANGER_TYPE    = 2;
43 $DISK_TYPE       = 3;
44 $DISKFILE_TYPE   = 4;
45 $CDROMFILE_TYPE  = 5;
46 $DISKPERF_TYPE   = 6;
47 $MODISK_TYPE     = 7;
48 $MODISKPERF_TYPE = 8;
49 $TAPE_TYPE       = 9;
50 $TAPEPERF_TYPE   = 10;
51
52 $VERSION = 0.6;
53
54 my $_SCST_MIN_MAJOR_   = 0;
55 my $_SCST_MIN_MINOR_   = 9;
56 my $_SCST_MIN_RELEASE_ = 5;
57
58 my %_IO_MAP_ = ($CDROM_TYPE => $_SCST_CDROM_IO_,
59                 $CHANGER_TYPE => $_SCST_CHANGER_IO_,
60                 $DISK_TYPE => $_SCST_DISK_IO_,
61                 $DISKFILE_TYPE => $_SCST_DISK_FILE_IO_,
62                 $CDROMFILE_TYPE => $_SCST_CDROM_FILE_IO_,
63                 $DISKPERF_TYPE => $_SCST_DISKP_IO_,
64                 $MODISK_TYPE => $_SCST_MODISK_IO_,
65                 $MODISKPERF_TYPE => $_SCST_MODISKP_IO_,
66                 $TAPE_TYPE => $_SCST_TAPE_IO_,
67                 $TAPEPERF_TYPE => $_SCST_TAPEP_IO_);
68
69 my %_TYPE_MAP_ = ('dev_cdrom' => $CDROM_TYPE,
70                   'dev_changer' => $CHANGER_TYPE,
71                   'dev_disk' => $DISK_TYPE,
72                   'disk_fileio' => $DISKFILE_TYPE,
73                   'cdrom_fileio' => $CDROMFILE_TYPE,
74                   'dev_disk_perf' => $DISKPERF_TYPE,
75                   'dev_modisk' => $MODISK_TYPE,
76                   'dev_modisk_perf' => $MODISKPERF_TYPE,
77                   'dev_tape' => $TAPE_TYPE,
78                   'dev_tape_perf' => $TAPEPERF_TYPE);
79
80 sub new {
81         my $this = shift;
82         my $debug = shift;
83         my $badVersion = $TRUE;
84         
85         my $class = ref($this) || $this;
86         my $self = {};
87
88         bless($self, $class);
89
90         $self->{'debug'} = $debug if $debug;
91
92         my $scstVersion = $self->scstVersion();
93
94         my($major, $minor, $release) = split(/\./, $scstVersion, 3);
95
96         $badVersion = $FALSE if (($major > $_SCST_MIN_MAJOR_) ||
97                                  (($major == $_SCST_MIN_MAJOR_) && ($minor > $_SCST_MIN_MINOR_)) ||
98                                  (($major == $_SCST_MIN_MAJOR_) && ($minor == $_SCST_MIN_MINOR_) && ($release >= $_SCST_MIN_RELEASE_)));
99
100         croak("This module requires at least SCST version $_SCST_MIN_MAJOR_\.$_SCST_MIN_MINOR_\.".
101               "$_SCST_MIN_RELEASE_ and version $scstVersion was found") if ($badVersion);
102
103         return $self;
104 }
105
106 sub scstVersion {
107         my $self = shift;
108
109         my $io = new IO::File $_SCST_VERSION_IO_, O_RDONLY;
110         return $TRUE if (!$io);
111
112         my $version = <$io>;
113         chomp $version;
114
115         return $version;
116 }
117
118 sub groups {
119         my $self = shift;
120         my @groups;
121         my $dirHandle = new IO::Handle;
122
123         opendir $dirHandle, $_SCST_GROUPS_DIR_ or return undef;
124       
125         foreach my $entry (readdir($dirHandle)) {
126                 next if (($entry eq '.') || ($entry eq '..'));
127
128                 push @groups, $entry;
129         }
130
131         close $dirHandle;
132
133         return \@groups;
134 }
135
136 sub groupExists {
137         my $self = shift;
138         my $group = shift;
139         my $groups = $self->groups();
140
141         foreach my $_group (@{$groups}) {
142                 return $TRUE if ($group eq $_group);
143         }
144
145         return $FALSE;
146 }
147
148 sub addGroup {
149         my $self = shift;
150         my $group = shift;
151
152         return 2 if ($self->groupExists($group));
153
154         my $io = new IO::File $_SCST_IO_, O_WRONLY;
155         return $TRUE if (!$io);
156
157         my $cmd = "add_group $group\n";
158
159         if ($self->{'debug'}) {
160                 print "DBG($$): $_SCST_IO_ -> $cmd\n";
161         } else {
162                 print $io $cmd;
163         }
164
165         close $io;
166
167         return $FALSE if ($self->{'debug'});
168         return !$self->groupExists($group);
169 }
170
171 sub removeGroup {
172         my $self = shift;
173         my $group = shift;
174
175         return 2 if (!$self->groupExists($group));
176
177         my $io = new IO::File $_SCST_IO_, O_WRONLY;
178         return $TRUE if (!$io);
179
180         my $cmd = "del_group $group\n";
181
182         if ($self->{'debug'}) {
183                 print "DBG($$): $_SCST_IO_ -> $cmd\n";
184         } else {
185                 print $io $cmd;
186         }
187
188         close $io;
189
190         return $FALSE if ($self->{'debug'});
191         return $self->groupExists($group);
192 }
193
194 sub sgvStats {
195         my $self = shift;
196         my $io = new IO::File $_SCST_SGV_STATS_, O_RDONLY;
197         my %stats;
198         my $first = $TRUE;
199
200         return undef if (!$io);
201
202         while (my $line = <$io>) {
203                 chomp $line;
204
205                 if ($first || !$line) {
206                         $first = $FALSE;
207                         next;
208                 }
209
210                 my $size;
211                 my $stat;
212                 my $hit;
213                 my $total;
214
215                 if ($line !~ /^\s/) {
216                         ($stat, $hit, $total) = split(/\s+/, $line);
217
218                         $size = 'ALL';
219                         if ($stat eq 'big') {
220                                 $total = $hit;
221                                 $hit = -1;
222                         }
223                 } else {
224                         (undef, $stat, $hit, $total) = split(/\s+/, $line);
225
226                         if ($stat =~ /(\d+)K$/) {
227                                 $size = $1;
228                                 $stat =~ s/\-$size\K//;
229                         }
230                 }
231
232                 $stats{$stat}->{$size}->{'HITS'} = $hit;
233                 $stats{$stat}->{$size}->{'TOTAL'} = $total;
234         }
235
236         close $io;
237
238         return \%stats;
239 }
240
241 sub sessions {
242         my $self = shift;
243         my $io = new IO::File $_SCST_SESSIONS_, O_RDONLY;
244         my %sessions;
245         my $first = $TRUE;
246
247         return undef if (!$io);
248
249         while (my $line = <$io>) {
250                 chomp $line;
251
252                 if ($first) {
253                         $first = $FALSE;
254                         next;
255                 }
256
257                 my($target, $user, $group, $commands) = split(/\s+/, $line);
258
259                 $sessions{$target}->{$group}->{$user} = $commands;
260         }
261
262         close $io;
263
264         return \%sessions;
265 }
266
267 sub devices {
268         my $self = shift;
269         my $io = new IO::File $_SCST_IO_, O_RDONLY;
270         my %devices;
271         my $first = $TRUE;
272
273         return undef if (!$io);
274
275         while (my $line = <$io>) {
276                 chomp $line;
277
278                 if ($first) {
279                         $first = $FALSE;
280                         next;
281                 }
282
283                 my($vname, $handler) = split(/\s+/, $line);
284                 $devices{$vname} = $_TYPE_MAP_{$handler};
285         }
286
287         close $io;
288
289         return \%devices;
290 }
291
292 sub handlerDevices {
293         my $self = shift;
294         my $handler = shift;
295         my $handler_io = $_IO_MAP_{$handler};
296         my $first = $TRUE;
297         my %devices;
298
299         return undef if (!$handler_io);
300         return undef if (!$self->handlerExists($handler));
301
302         my $io = new IO::File $handler_io, O_RDONLY;
303         return undef if (!$io);
304
305         while (my $line = <$io>) {
306                 chomp $line;
307
308                 if ($first) {
309                         $first = $FALSE;
310                         next;
311                 }
312
313                 my ($vname, $size, $blocksize, $options, $path) = split(/\s+/, $line);
314
315                 if ($options =~ /^\//) {
316                         $path = $options;
317                         $options = "";
318                 }
319
320                 $devices{$vname}->{'OPTIONS'} = $self->cleanupString($options);
321                 $devices{$vname}->{'SIZE'} = $self->cleanupString($size);
322                 $devices{$vname}->{'PATH'} = $self->cleanupString($path);
323                 $devices{$vname}->{'BLOCKSIZE'} = $self->cleanupString($blocksize);
324         }
325
326         close $io;
327
328         return \%devices;
329 }
330
331 sub handlerDeviceExists {
332         my $self = shift;
333         my $handler = shift;
334         my $device = shift;
335         my $devices = $self->handlerDevices($handler);
336
337         return -1 if (!defined($devices));
338         return $TRUE if (defined($$devices{$device}));
339
340         return $FALSE;
341 }
342
343 sub openDevice {
344         my $self = shift;
345         my $handler = shift;
346         my $device = shift;
347         my $path = shift;
348         my $options = shift;
349         my $blocksize = shift;
350         my $handler_io = $_IO_MAP_{$handler};
351
352         return $TRUE if ($self->checkOptions($options));
353         return $TRUE if (!$handler_io);
354         return $TRUE if (!$self->handlerExists($handler));
355         return 2 if ($self->handlerDeviceExists($handler, $device));
356
357         $options = $self->cleanupString($options);
358
359         my $cmd = "open $device $path $blocksize $options\n";
360
361         $cmd = $self->cleanupString($cmd);
362
363         my $rc = $self->handler_private($handler_io, $cmd);
364
365         return $FALSE if ($self->{'debug'});
366         return $rc if ($rc);
367         return !$self->handlerDeviceExists($handler, $device);
368 }
369
370 sub closeDevice {
371         my $self = shift;
372         my $handler = shift;
373         my $device = shift;
374         my $path = shift;
375         my $handler_io = $_IO_MAP_{$handler};
376
377         return $TRUE if (!$handler_io);
378         return $TRUE if (!$self->handlerExists($handler));
379         return 2 if (!$self->handlerDeviceExists($handler, $device));
380
381         my $cmd = "close $device $path\n";
382
383         my $rc = $self->handler_private($handler_io, $cmd);
384
385         return $FALSE if ($self->{'debug'});
386         return $rc if ($rc);
387         return $self->handlerDeviceExists($handler, $device);
388 }
389
390 sub userExists {
391         my $self = shift;
392         my $user = shift;
393         my $group = shift;
394
395         my $users = $self->users($group);
396
397         return -1 if (!defined($users));
398
399         foreach my $_user (@{$users}) {
400                 return $TRUE if ($user eq $_user);
401         }
402
403         return $FALSE;
404 }
405
406 sub users {
407         my $self = shift;
408         my $group = shift;
409         my @users;
410
411         return undef if (!$self->groupExists($group));
412
413         my $io = new IO::File $_SCST_GROUPS_DIR_."/$group/".$_SCST_USERS_IO_, O_RDONLY;
414         return undef if (!$io);
415
416         while (my $line = <$io>) {
417                 chomp $line;
418                 
419                 push @users, $line;
420         }
421
422         close $io;
423
424         return \@users;
425 }
426
427 sub addUser {
428         my $self = shift;
429         my $user = shift;
430         my $group = shift;
431
432         return $TRUE if (!$self->groupExists($group));
433         return 2 if ($self->userExists($user, $group));
434
435         my $cmd = "add $user\n";
436
437         my $rc = $self->group_private($group, $_SCST_USERS_IO_, $cmd);
438
439         return $FALSE if ($self->{'debug'});
440         return $rc if ($rc);
441         return !$self->userExists($user, $group);
442 }
443
444 sub removeUser {
445         my $self = shift;
446         my $user = shift;
447         my $group = shift;
448
449         return $TRUE if (!$self->groupExists($group));
450         return 2 if (!$self->userExists($user, $group));
451
452         my $cmd = "del $user\n";
453
454         my $rc = $self->group_private($group, $_SCST_USERS_IO_, $cmd);
455
456         return $FALSE if ($self->{'debug'});
457         return $rc if ($rc);
458         return $self->userExists($user, $group);
459 }
460
461 sub clearUsers {
462         my $self = shift;
463         my $group = shift;
464
465         return $TRUE if (!$self->groupExists($group));
466
467         my $cmd = "clear\n";
468
469         my $rc = $self->group_private($group, $_SCST_USERS_IO_, $cmd);
470
471         return $FALSE if ($self->{'debug'});
472         return $rc if ($rc);
473
474         my $users = $self->users($group);
475
476         return ($#{$users} + 1);
477 }
478
479 sub handlerExists {
480         my $self = shift;
481         my $handler = shift;
482         my $handlers = $self->handlers();
483
484         foreach my $_handler (@{$handlers}) {
485                 return $TRUE if ($handler eq $_handler);
486         }
487
488         return $FALSE;
489 }
490
491 sub handlers {
492         my $self = shift;
493         my @handlers;
494
495         my $dirHandle = new IO::Handle;
496
497         opendir $dirHandle, $_SCST_DIR_ or return undef;
498
499         foreach my $entry (readdir($dirHandle)) {
500                 next if (($entry eq '.') || ($entry eq '..'));
501
502                 if ((-d $_SCST_DIR_.'/'.$entry ) && (-f $_SCST_DIR_.'/'.$entry.'/type')) {
503                         push @handlers, $_TYPE_MAP_{$entry} if ($_TYPE_MAP_{$entry});
504                 }
505         }
506
507         close $dirHandle;
508
509         return \@handlers;
510 }
511
512 sub groupDeviceExists {
513         my $self = shift;
514         my $device = shift;
515         my $group = shift;
516         my $lun = shift;
517         my $devices = $self->groupDevices($group);
518
519         return -1 if (!defined($devices));
520
521         if (defined($lun)) {
522                 return $TRUE if ($$devices{$device} eq $lun);
523         } else {
524                 return $TRUE if (defined($$devices{$device}));
525         }
526
527         return $FALSE;
528 }
529
530 sub groupDevices {
531         my $self = shift;
532         my $group = shift;
533         my %devices;
534         my $first = $TRUE;
535
536         return undef if (!$self->groupExists($group));
537
538         my $io = new IO::File $_SCST_GROUPS_DIR_."/$group/".$_SCST_DEVICES_IO_, O_RDONLY;
539         return undef if (!$io);
540
541         while (my $line = <$io>) {
542                 chomp $line;
543
544                 if ($first) {
545                         $first = $FALSE;
546                         next;
547                 }
548
549                 my($vname, $lun) = split(/\s+/, $line);
550                 
551                 $devices{$vname} = $lun;
552         }
553
554         close $io;
555
556         return \%devices;
557 }
558
559 sub assignDeviceToGroup {
560         my $self = shift;
561         my $device = shift;
562         my $group = shift;
563         my $lun = shift;
564
565         return $TRUE if (!$self->groupExists($group));
566         return 2 if ($self->groupDeviceExists($device, $group, $lun));
567
568         my $cmd = "add $device $lun\n";
569
570         my $rc = $self->group_private($group, $_SCST_DEVICES_IO_, $cmd);
571
572         return $FALSE if ($self->{'debug'});
573         return $rc if ($rc);
574         return !$self->groupDeviceExists($device, $group, $lun);
575 }
576
577 sub assignDeviceToHandler {
578         my $self = shift;
579         my $device = shift;
580         my $handler = shift;
581         my $handler_io = $_IO_MAP_{$handler};
582         
583         return $TRUE if (!$handler_io);
584         return $TRUE if (!$self->handlerExists($handler));
585         return 2 if ($self->handlerDeviceExists($handler, $device));
586
587         my $cmd = "assign $device $handler\n";
588
589         my $rc = $self->scst_private($cmd);
590
591         return $FALSE if ($self->{'debug'});
592         return $rc if($rc);
593         return !$self->handlerDeviceExists($handler, $device);
594 }
595
596 sub removeDeviceFromGroup {
597         my $self = shift;
598         my $device = shift;
599         my $group = shift;
600
601         return $TRUE if (!$self->groupExists($group));
602         return 2 if (!$self->groupDeviceExists($device, $group));
603
604         my $cmd = "del $device\n";
605
606         my $rc = $self->group_private($group, $_SCST_DEVICES_IO_, $cmd);
607
608         return $FALSE if ($self->{'debug'});
609         return $rc if ($rc);
610         return $self->groupDeviceExists($device, $group);
611 }
612
613 sub clearGroupDevices {
614         my $self = shift;
615         my $group = shift;
616
617         return $TRUE if (!$self->groupExists($group));
618
619         my $cmd = "clear\n";
620
621         my $rc = $self->group_private($group, $_SCST_DEVICES_IO_, $cmd);
622
623         return $FALSE if ($self->{'debug'});
624         return $rc if ($rc);
625
626         my $devices = $self->groupDevices($group);
627
628         return (keys %{$devices});
629 }
630
631 sub handler_private {
632         my $self = shift;
633         my $handler_io = shift;
634         my $cmd = shift;
635
636         my $io = new IO::File $handler_io, O_WRONLY;
637         return $TRUE if (!$io);
638
639         if ($self->{'debug'}) {
640                 print "DBG($$): '$handler_io' -> '$cmd'\n";
641         } else {
642                 print $io "$cmd\0";
643         }
644
645         close $io;
646
647         return $FALSE;
648 }
649
650 sub scst_private {
651         my $self = shift;
652         my $cmd = shift;
653
654         my $io = new IO::File $_SCST_IO_, O_WRONLY;
655         return $TRUE if (!$io);
656
657         if ($self->{'debug'}) {
658                 print "DBG($$): '$_SCST_IO_' -> '$cmd'\n";
659         } else {
660                 print $io "$cmd\0";
661         }
662
663         close $io;
664
665         return $FALSE;
666 }
667
668 sub group_private {
669         my $self = shift;
670         my $group = shift;
671         my $file = shift;
672         my $cmd = shift;
673
674         my $io = new IO::File $_SCST_GROUPS_DIR_."/$group/".$file, O_WRONLY;
675         return $TRUE if (!$io);
676
677         if ($self->{'debug'}) {
678                 print "DBG($$): $_SCST_GROUPS_DIR_/$group/$file -> $cmd\n";
679         } else {
680                 print $io "$cmd\0";
681         }
682
683         close $io;
684
685         return $FALSE;
686 }
687
688 sub checkOptions {
689         my $self = shift;
690         my $options = shift;
691
692         return if (!$options);
693
694         foreach my $option (split(/\s+/, $options)) {
695                 foreach my $avail (@_AVAILABLE_OPTIONS_) {
696                         return $FALSE if ($avail eq $option);
697                 }
698         }
699
700         return $TRUE;
701 }
702
703 sub cleanupString {
704         my $self = shift;
705         my $string = shift;
706
707         $string =~ s/^\s+//;
708         $string =~ s/\s+$//;
709
710         return $string;
711 }
712
713 ;1 __END__
714
715 =head1 NAME
716
717 SCST::SCST - Generic SCST methods.
718
719 =head1 SYNOPSIS
720
721     use SCST::SCST;
722
723     $p = SCST::SCST->new();
724     
725     print "Using SCST version".$p->scstVersion()."\n";
726     
727     if ($p->handlerDeviceExists($SCST::SCST::DISKFILE_TYPE)) {
728          print "openDevice() failed\n"
729            if ($p->openDevice($SCST::SCST::DISKFILE_TYPE, 'DISK01', '/vdisk/disk01.dsk'));
730     }
731     
732     undef $p;
733
734 =head1 DESCRIPTION
735
736 Generic SCST methods.
737
738 =head2 Methods
739
740 =over 5
741
742 =item SCST::SCST->new();
743
744 Create a new SCST object. If the argument $debug is non-zero no changes
745 will be made.
746
747 Arguments: (bool) $debug
748
749 Returns: (object) $new
750
751 =item SCST::SCST->scstVersion();
752
753 Returns the version of SCST running.
754
755 Arguments: void
756
757 Returns: (string) $version
758
759 =item SCST::SCST->groups();
760
761 Returns a list of security groups configured.
762
763 Arguments: void
764
765 Returns: (array ref) $groups
766
767 =item SCST::SCST->groupExists();
768
769 Checks for a specified group's existance.
770
771 Arguments: (string) $group
772
773 Returns: (boolean) $groupExists
774
775 =item SCST::SCST->addGroup();
776
777 Adds a security group to SCST's configuration. Returns 0 upon success, 1 if
778 unsuccessfull and  2 if the group already exists.
779
780 Arguments: (string) $group
781
782 Returns: (int) $success
783
784 =item SCST::SCST->removeGroup();
785
786 Removes a group from SCST's configuration. Returns 0 upon success, 1 if
787 unsuccessfull and 2 if group does not exist.
788
789 =item SCST::SCST->sgvStats();
790
791 Returns a hash of stats gathered from /proc/scsi_tgt/sgv.
792
793 Arguments: void
794
795 Returns: (hash ref) $stats
796
797 Hash Layout: See /proc/scsi_tgt/sgv for tokens. This methods simply hashes
798 what's found there and returns it with no further processing.
799
800 =item SCST::SCST->sessions();
801
802 Returns a hash of current SCST initiator sessions. 
803
804 Arguments: void
805
806 Returns: (hash ref) $sessions
807
808 Hash Layout: See /proc/scsi_tgt/sessions for tokens. This methods simply hashes
809 what's found there and returns it with no further processing.
810
811 =item SCST::SCST->devices();
812
813 Returns a hash of devices configured without regard to device handler.
814
815 Arguments: void
816
817 Returns: (hash ref) $devices
818
819 Hash Layout: (string) $device = (int) $handler
820
821 =item SCST::SCST->handlerDevices();
822
823 Returns a hash of devices configured for a specified device handler.
824
825 Arguments: (int) $handler
826
827 Returns: (hash ref) $devices
828
829 Hash Layout: (string) $device -> SIZE = (int) $deviceSize
830              (string) $device -> PATH = (string) $devicePath
831              (string) $device -> OPTIONS = (string) $options (comma seperated)
832
833 =item SCST::SCST->handlerDeviceExists();
834
835 Checks for a specified device is configured for a specified device handler.
836
837 Arguments: (int) $handler, (string) $device
838
839 Returns: (boolean) $deviceExists
840
841 =item SCST::SCST->openDevice();
842
843 Opens an already existing specified device for the specified device handler.
844 Returns 0 upon success, 1 if unsuccessfull and 2 if the device already exists.
845
846 Available options for the parameter $options are: WRITE_THROUGH, READ_ONLY, O_DIRECT
847
848 Arguments: (int) $handler, (string) $device, (string) $path [, (string) $options]
849
850 Returns: (int) $success
851
852 =item SCST::SCST->closeDevice();
853
854 Closes an open device configured for the specified device handler. Returns
855 0 upon success, 1 if unsuccessfull and 2 of the device does not exist.
856
857 Arguments: (int) $handler, (string) $device, (string) $path
858
859 Returns: (int) $success
860
861 =item SCST::SCST->userExists();
862
863 Checks for a specified user with the specified security group.
864
865 Arguments: (string) $user, (string) $group
866
867 Returns (boolean) $userExists
868
869 =item SCST::SCST->users();
870
871 Returns a list of users configured for a given security group.
872
873 Arguments: (string) $group
874
875 Returns: (hash ref) $users
876
877 =item SCST::SCST->addUser();
878
879 Adds the specified user to the specified security group. Returns 0
880 upon success, 1 if unsuccessfull and 2 if the user already exists.
881
882 Arguments: (string) $user, (string) $group
883
884 Returns: (int) $success
885
886 =item SCST::SCST->removeUser();
887
888 Removed the specified user from the specified security group. Returns
889 0 upon success, 1 if unsuccessfull and 2 if the user does not exist.
890
891 Arguments: (string) $user, (string) $group
892
893 Returns: (int) $success
894
895 =item SCST::SCST->clearUsers();
896
897 Removes all users from the specified security group. Returns 0 upon
898 success or 1 if unsuccessfull.
899
900 Arguments: (string) $group
901
902 Returns: (int) $success
903
904 =item SCST::SCST->handlerExists();
905
906 Checks if a specified device handler exists within SCST's configuration.
907
908 Arguments: (int) $handler
909
910 Returns: (boolean) $handlerExists
911
912 =item SCST::SCST->handlers();
913
914 Returns a list of configured device handlers.
915
916 Arguments: void
917
918 Returns: (array ref) $handlers
919
920 =item SCST::SCST->groupDeviceExists();
921
922 Checks if a specified device is assigned to a specified security group.
923 If the optional $lun argument is specified, this method also matches
924 the lun.
925
926 Arguments: (string) $device, (string) $group [, (int) $lun]
927
928 Returns: (boolean) $deviceExists
929
930 =item SCST::SCST->groupDevices();
931
932 Returns a hash if devices assigned to the specified security group.
933
934 Arguments: (string) $group
935
936 Returns: (hash ref) $devices
937
938 Hash Layout: (string) $device = (int) $lun
939
940 =item SCST::SCST->assignDeviceToGroup();
941
942 Assigns the specified device to the specified security group. Returns
943 0 upon success, 1 if unsuccessfull and 2 if the device has already
944 been assigned to the specified security group.
945
946 Arguments: (string) $device, (string) $group, (int) $lun
947
948 Returns: (int) $success
949
950 =item SCST::SCST->assignDeviceToHandler();
951
952 Assigns specified device to specified handler. Returns 0 upon success,
953 1 if unsuccessfull and 2 if the specified device is already assigned to
954 the specified handler.
955
956 Arguments: (string) $device, (string) $handler
957
958 Returns: (int) $success
959
960 =item SCST::SCST->removeDeviceFromGroup();
961
962 Removes the specified device from the specified security group. Returns
963 0 upon success, 1 if unsuccessfull and 2 if the device has not been
964 assigned to the specified security group.
965
966 Arguments: (string) $device, (string) $group
967
968 Returns: (int) $success
969
970 =item SCST::SCST->clearGroupDevices();
971
972 Removes all devices from the specified security group. Returns 0 upon
973 success or 1 if unsuccessfull.
974
975 Arguments: (string) $group
976
977 Returns: (int) $success
978
979 =back
980
981 =head1 WARNING
982
983 None at this time.
984
985 =head1 NOTES
986
987 If the $debug parameter is specified on package new(), no actions are 
988 performed. Rather they are printed to STDOUT and 0 is returned.
989
990 Available Device Handlers:
991
992 CDROM_TYPE,
993 CHANGER_TYPE,
994 DISK_TYPE,
995 DISKFILE_TYPE,
996 CDROMFILE_TYPE,
997 DISKPERF_TYPE,
998 MODISK_TYPE,
999 MODISKPERF_TYPE,
1000 TAPE_TYPE,
1001 TAPEPERF_TYPE
1002
1003 To specify a device handler to a method, use the following syntax:
1004
1005 $SCST::SCST::<handler type>
1006
1007 For example:
1008
1009 $SCST::SCST::MODISK_TYPE
1010
1011 =cut