[Orca-checkins] r391 - in trunk/orca: data_gatherers/orcallator lib/SE/3.3.1
dmberezin at hotmail.com
dmberezin at hotmail.com
Tue Sep 14 11:28:56 PDT 2004
Author: dmberezin at hotmail.com
Date: Tue Sep 14 11:27:02 2004
New Revision: 391
Added:
trunk/orca/lib/SE/3.3.1/tapeinfo.se
Modified:
trunk/orca/data_gatherers/orcallator/orcallator.se
Log:
The first update to the disk/tape data collection on Solaris.
* lib/SE/3.3.1/tapeinfo.se
New file, based on diskinfo.se that is included in SE Toolkit.
* data_gatherers/orcallator/orcallator.se
Naming conventions are changed from RAW_disk to KSTAT_IO
Static RAW_disk array is replaced by dynamic ORCA_io_dev_info array
(struct RawDisk): Renamed to struct io_dev_info_t
(raw_disk_update): Renamed to orca_io_info_update
(struct io_dev_info_t): long_name and short_name are now strings, thus dynamic
(orca_io_info_update): Removed some unused variables:
update
delta
time_update
time_void
short_name
(raw_disk_short_name_cmp and raw_disk_map): Removed. Replaced by name lookup
using find_inst
Added tape long name mapping (stxxx is being mapped to rmt/xx) support. This
requires tapeinfo.se (modified version of diskinfo.se)
The following global variables are removed:
RAW_disk_map
RAW_disk_count
RAW_disk_lastupdate
Modified: trunk/orca/data_gatherers/orcallator/orcallator.se
==============================================================================
--- trunk/orca/data_gatherers/orcallator/orcallator.se (original)
+++ trunk/orca/data_gatherers/orcallator/orcallator.se Tue Sep 14 11:27:02 2004
@@ -23,8 +23,8 @@
// The maximum number of columns of data.
#define MAX_COLUMNS 2048
-// Enable the raw disk measuring code.
-#define USE_RAWDISK 1
+// Enable kstat io measuring code.
+#define USE_KSTAT_IO 1
// If WATCH_OS is defined, then measure every part of the operating
// system.
@@ -297,8 +297,9 @@
#endif
-#ifdef USE_RAWDISK
+#ifdef USE_KSTAT_IO
#include <sys_kstat.se>
+#include <tapeinfo.se>
// This code was developed so that the performance of virtual disks
// originating from a Sun A1000 raid controller could be monitored.
// These disks do not show up in the GLOBAL_disk[] io structure of SE.
@@ -306,10 +307,10 @@
// This extension accesses the sys_kstat.se interface to the kstat IO
// queues to extract info on drives not available in the kstat.se
// kstat$disk interface. Global data shared between function calls.
-struct RawDisk {
+struct io_dev_info_t {
// Exposed interface that matches kstat.
- char long_name[48];
- char short_name[8];
+ string long_name;
+ string short_name;
double reads;
double kreads;
double writes;
@@ -337,124 +338,13 @@
};
// Define global for tracking raw disk data.
-#ifndef MAX_RAWDISKS
-#define MAX_RAWDISKS 1024
-#endif
-
-RawDisk RAW_disk[MAX_RAWDISKS];
-int RAW_disk_map=0;
-int RAW_disk_count=0;
-double RAW_disk_lastupdate;
-
-// Compare two short disk names and return if they have on the same
-// physical device name, ignoring slice info.
-int raw_disk_short_name_cmp(char disk1[],
- int disk1_length,
- char disk2[],
- int disk2_length)
-{
- int i;
-
- // Handle dad disks first since they do not have commas.
- if (strncmp("dad", disk1, 3) == 0) {
- return strncmp(disk1, disk2, disk1_length);
- }
-
- // Extract the physical disk name from disk slices. This only works
- // with SCSI disks where slices have commma separators.
- for (i=0; i<disk1_length; ++i) {
- if (disk1[i] == ',') {
- disk1_length = i;
- break;
- }
- }
- for (i=0; i<disk2_length; ++i) {
- if (disk2[i] == ',') {
- disk2_length = i;
- break;
- }
- }
- if (disk1_length != disk2_length) {
- return 1;
- }
- return strncmp(disk1, disk2, disk1_length);
-}
-
-// Function to scan kstat and map short device names to long device names.
-raw_disk_map() {
- int first_name_length;
- char first_name[16];
- int second_name_length;
- char second_name[16];
- char long_name[16];
- char short_name[16];
- int short_name_length;
- int i;
- int j;
-
- // This section is used to map short names to long names. Since
- // raw_disk_update has already identified how many physical devices
- // it simply tries to find theses devices in GLOBAL_disk_info[].
- //
- // SE appears to have a bug where GLOBAL_diskinfo_size can be larger
- // than the number of entries in GLOBAL_disk_info[] under a variety
- // of conditions. In later versions of SE GLOBAL_diskinfo_size has
- // been removed. This appears to fix the above problem. This code
- // uses MAX_RAWDISKS for the table length and the assumption that
- // short disks names come before short disk partition names to
- // detect the end of the table. If it fails to detect the end it
- // will core dump when it addresses unallocated memory.
- //
- // These symbols are used to recognize when we slip past the end of
- // the raw devices in GLOBAL_disk_info. It would be nice to just
- // look for a slice like sd0,a but unfortunately EIDE disks do not
- // have slices.
- //
- // Check for the first and second disk in case the CD-ROM shows up
- // as the first disk since it will not show slice information unless
- // it is mounted.
- strcpy(first_name, GLOBAL_disk_info[0].short_name);
- first_name_length = strlen(first_name);
- if (MAX_RAWDISKS > 1) {
- strcpy(second_name, GLOBAL_disk_info[1].short_name);
- second_name_length = strlen(second_name);
- }
- for (i=0; i<RAW_disk_count; ++i) {
- // Do not map st & fd devices.
- if (strncmp(RAW_disk[i].short_name, "st", 2) != 0 &&
- strncmp(RAW_disk[i].short_name, "fd", 2) != 0) {
- for (j=0; j<MAX_RAWDISKS; ++j) {
- strcpy(short_name, GLOBAL_disk_info[j].short_name);
- if (j > 0) {
- short_name_length = strlen(short_name);
- if (raw_disk_short_name_cmp(first_name,
- first_name_length,
- short_name,
- short_name_length) == 0) {
- break;
- }
- if (j > 1) {
- if (raw_disk_short_name_cmp(second_name,
- second_name_length,
- short_name,
- short_name_length) == 0) {
- break;
- }
- }
- }
- if (strcmp(RAW_disk[i].short_name, short_name) == 0) {
- strcpy(long_name, GLOBAL_disk_info[j].long_name);
- strcpy(RAW_disk[i].long_name, long_name);
- break;
- }
- }
- }
- }
- RAW_disk_map = 0;
-}
-
-raw_disk_update() {
- int rdisk;
+io_dev_info_t ORCA_io_dev_info[];
+int ORCA_io_dev_count=0;
+int ORCA_max_io_dev_count=0;
+
+orca_io_info_update() {
+ int iodev;
+ int index;
ulong ul;
kstat_ctl_t kc[1];
kstat_t kp[1];
@@ -478,21 +368,11 @@
double elapsed_etime;
double hz_etime;
double nanosecond = NANOSEC;
- double update;
- double delta;
- timeval_t time_update[1];
- ulong time_void;
- char short_name[8];
-
- gettimeofday(time_update, time_void);
- update = time_update[0].tv_sec + (time_update[0].tv_usec / 1000000.0);
- delta = update - RAW_disk_lastupdate;
- RAW_disk_lastupdate = update;
kc[0] = kstat_open();
// Read them.
if (kstat_read(kc, kp, 0) == -1) {
- perror("raw_disk_update:kstat_read");
+ perror("orca_io_info_update:kstat_read");
exit(1);
}
@@ -500,40 +380,55 @@
for (ul=kc[0].kc_chain; ul !=0; ul=nkp[0].ks_next) {
struct_fill(nkp[0], ul);
if (nkp[0].ks_type == KSTAT_TYPE_IO) {
- strcpy(short_name, nkp[0].ks_name);
- if (short_name[0] != 'm' &&
- short_name[0] != 'n' &&
- strchr(short_name,',') == nil) {
+ // Look for disk or tape statistics
+ if (nkp[0].ks_class == "disk" || nkp[0].ks_class == "tape") {
// Try to locate device.
- for (rdisk=0; rdisk<RAW_disk_count; ++rdisk) {
- if (strcmp(RAW_disk[rdisk].short_name, short_name) == 0) {
+ for (iodev=0; iodev < ORCA_io_dev_count; ++iodev) {
+ if (ORCA_io_dev_info[iodev].short_name == nkp[0].ks_name) {
break;
}
}
- // It must be new. Add it!
- if (rdisk == RAW_disk_count) {
- // Must be a tape drive or something else. Schedule device
- // name map cycle.
- RAW_disk_map = 1;
- strcpy(RAW_disk[rdisk].long_name, short_name);
- strcpy(RAW_disk[rdisk].short_name, short_name);
- RAW_disk[rdisk]._reads = 0;
- RAW_disk[rdisk]._nread = 0;
- RAW_disk[rdisk]._rlentime = 0;
- RAW_disk[rdisk]._rlastupdate = boot_time;
- RAW_disk[rdisk]._rcnt = 0;
- RAW_disk[rdisk]._writes = 0;
- RAW_disk[rdisk]._nwritten = 0;
- RAW_disk[rdisk]._wlentime = 0;
- RAW_disk[rdisk]._wlastupdate = boot_time;
- RAW_disk[rdisk]._wcnt = 0;
- RAW_disk_count++;
+ // It must be new. Add it!
+ if (iodev == ORCA_io_dev_count) {
+ // Grow the device array if needed
+ if (ORCA_io_dev_count == ORCA_max_io_dev_count) {
+ ORCA_max_io_dev_count += 10;
+ ORCA_io_dev_info = renew ORCA_io_dev_info[ORCA_max_io_dev_count];
+ }
+
+ if (nkp[0].ks_class == "tape") {
+ index = find_tape_inst(nkp[0].ks_name);
+ } else {
+ index = find_inst(nkp[0].ks_name);
+ }
+ if (index != -1) {
+ if (nkp[0].ks_class == "tape") {
+ ORCA_io_dev_info[iodev].long_name = GLOBAL_tape_info[index].long_name;
+ } else {
+ ORCA_io_dev_info[iodev].long_name = GLOBAL_disk_info[index].long_name;
+ }
+ } else {
+ ORCA_io_dev_info[iodev].long_name = nkp[0].ks_name;
+ }
+ ORCA_io_dev_info[iodev].short_name = nkp[0].ks_name;
+
+ ORCA_io_dev_info[iodev]._reads = 0;
+ ORCA_io_dev_info[iodev]._nread = 0;
+ ORCA_io_dev_info[iodev]._rlentime = 0;
+ ORCA_io_dev_info[iodev]._rlastupdate = boot_time;
+ ORCA_io_dev_info[iodev]._rcnt = 0;
+ ORCA_io_dev_info[iodev]._writes = 0;
+ ORCA_io_dev_info[iodev]._nwritten = 0;
+ ORCA_io_dev_info[iodev]._wlentime = 0;
+ ORCA_io_dev_info[iodev]._wlastupdate = boot_time;
+ ORCA_io_dev_info[iodev]._wcnt = 0;
+ ORCA_io_dev_count++;
}
// Update the device registers.
if (kstat_read(kc, nkp, 0) == -1) {
- perror("raw_disk_update:kstat_read error");
+ perror("orca_io_info_update:kstat_read error");
exit(1);
} else {
// Read sys_kstat device IO queue to find out about recent
@@ -546,32 +441,33 @@
// the error forces the IOs to get attributed to the next IO
// cycle.
struct_fill(kio, nkp[0].ks_data);
+
_nread = kio.nread;
- if (RAW_disk[rdisk]._nread > _nread) {
- _nread = RAW_disk[rdisk]._nread;
+ if (ORCA_io_dev_info[iodev]._nread > _nread) {
+ _nread = ORCA_io_dev_info[iodev]._nread;
}
_reads = kio.reads;
- if (RAW_disk[rdisk]._reads > _reads) {
- _reads = RAW_disk[rdisk]._reads;
+ if (ORCA_io_dev_info[iodev]._reads > _reads) {
+ _reads = ORCA_io_dev_info[iodev]._reads;
}
_rlentime = kio.rlentime;
_rtime = kio.rtime;
_rlastupdate = kio.wlastupdate;
_rcnt = kio.rcnt;
_nwritten = kio.nwritten;
- if (RAW_disk[rdisk]._nwritten > _nwritten) {
- _nwritten = RAW_disk[rdisk]._nwritten;
+ if (ORCA_io_dev_info[iodev]._nwritten > _nwritten) {
+ _nwritten = ORCA_io_dev_info[iodev]._nwritten;
}
_writes = kio.writes;
- if (RAW_disk[rdisk]._writes > _writes) {
- _writes = RAW_disk[rdisk]._nwritten;
+ if (ORCA_io_dev_info[iodev]._writes > _writes) {
+ _writes = ORCA_io_dev_info[iodev]._nwritten;
}
_wlentime = kio.wlentime;
_wtime = kio.wtime;
_wlastupdate = kio.wlastupdate;
_wcnt = kio.wcnt;
- elapsed_etime = (_wlastupdate - RAW_disk[rdisk]._wlastupdate);
+ elapsed_etime = (_wlastupdate - ORCA_io_dev_info[iodev]._wlastupdate);
if (elapsed_etime > 0) {
hz_etime = elapsed_etime / nanosecond;
big_etime = 1024.0 * hz_etime;
@@ -580,50 +476,44 @@
hz_etime = 1.0;
big_etime = 1024.0;
}
- RAW_disk[rdisk].reads =(_reads-RAW_disk[rdisk]._reads) /hz_etime;
- RAW_disk[rdisk].kreads =(_nread-RAW_disk[rdisk]._nread) /big_etime;
- RAW_disk[rdisk].writes =(_writes-RAW_disk[rdisk]._writes)/hz_etime;
- RAW_disk[rdisk].kwrites=(_nwritten-RAW_disk[rdisk]._nwritten) / big_etime;
+ ORCA_io_dev_info[iodev].reads =(_reads-ORCA_io_dev_info[iodev]._reads) /hz_etime;
+ ORCA_io_dev_info[iodev].kreads =(_nread-ORCA_io_dev_info[iodev]._nread) /big_etime;
+ ORCA_io_dev_info[iodev].writes =(_writes-ORCA_io_dev_info[iodev]._writes)/hz_etime;
+ ORCA_io_dev_info[iodev].kwrites=(_nwritten-ORCA_io_dev_info[iodev]._nwritten) / big_etime;
- read_writes = elapsed_etime * (RAW_disk[rdisk].reads + RAW_disk[rdisk].writes) / 1024.0;
+ read_writes = elapsed_etime * (ORCA_io_dev_info[iodev].reads + ORCA_io_dev_info[iodev].writes) / 1024.0;
if (read_writes > 0) {
- RAW_disk[rdisk].avg_wait = (_wlentime - RAW_disk[rdisk]._wlentime) / read_writes;
- RAW_disk[rdisk].avg_serv = (_rlentime - RAW_disk[rdisk]._rlentime) / read_writes;
- RAW_disk[rdisk].service = RAW_disk[rdisk].avg_wait + RAW_disk[rdisk].avg_serv;
+ ORCA_io_dev_info[iodev].avg_wait = (_wlentime - ORCA_io_dev_info[iodev]._wlentime) / read_writes;
+ ORCA_io_dev_info[iodev].avg_serv = (_rlentime - ORCA_io_dev_info[iodev]._rlentime) / read_writes;
+ ORCA_io_dev_info[iodev].service = ORCA_io_dev_info[iodev].avg_wait + ORCA_io_dev_info[iodev].avg_serv;
} else {
- RAW_disk[rdisk].avg_wait = 0.0;
- RAW_disk[rdisk].avg_serv = 0.0;
- RAW_disk[rdisk].service = 0.0;
+ ORCA_io_dev_info[iodev].avg_wait = 0.0;
+ ORCA_io_dev_info[iodev].avg_serv = 0.0;
+ ORCA_io_dev_info[iodev].service = 0.0;
}
// Update the counters.
- RAW_disk[rdisk].run_percent = 100.0 * (_rtime - RAW_disk[rdisk]._rtime) / elapsed_etime;
- RAW_disk[rdisk].wait_percent = 100.0 * (_wtime - RAW_disk[rdisk]._wtime) / elapsed_etime;
- RAW_disk[rdisk]._writes = _writes;
- RAW_disk[rdisk]._nwritten = _nwritten;
- RAW_disk[rdisk]._wlastupdate = _wlastupdate;
- RAW_disk[rdisk]._wlentime = _wlentime;
- RAW_disk[rdisk]._wtime = _wtime;
- RAW_disk[rdisk]._wcnt = _wcnt;
- RAW_disk[rdisk]._reads = _reads;
- RAW_disk[rdisk]._nread = _nread;
- RAW_disk[rdisk]._rlastupdate = _rlastupdate;
- RAW_disk[rdisk]._rlentime = _rlentime;
- RAW_disk[rdisk]._rtime = _rtime;
- RAW_disk[rdisk]._rcnt = _rcnt;
+ ORCA_io_dev_info[iodev].run_percent = 100.0 * (_rtime - ORCA_io_dev_info[iodev]._rtime) / elapsed_etime;
+ ORCA_io_dev_info[iodev].wait_percent = 100.0 * (_wtime - ORCA_io_dev_info[iodev]._wtime) / elapsed_etime;
+ ORCA_io_dev_info[iodev]._writes = _writes;
+ ORCA_io_dev_info[iodev]._nwritten = _nwritten;
+ ORCA_io_dev_info[iodev]._wlastupdate = _wlastupdate;
+ ORCA_io_dev_info[iodev]._wlentime = _wlentime;
+ ORCA_io_dev_info[iodev]._wtime = _wtime;
+ ORCA_io_dev_info[iodev]._wcnt = _wcnt;
+ ORCA_io_dev_info[iodev]._reads = _reads;
+ ORCA_io_dev_info[iodev]._nread = _nread;
+ ORCA_io_dev_info[iodev]._rlastupdate = _rlastupdate;
+ ORCA_io_dev_info[iodev]._rlentime = _rlentime;
+ ORCA_io_dev_info[iodev]._rtime = _rtime;
+ ORCA_io_dev_info[iodev]._rcnt = _rcnt;
}
}
}
}
kstat_close(kc);
-
- // Map long device names for any drives that we just discovered.
- if (RAW_disk_map == 1) {
- raw_disk_map();
- }
}
-#endif
-// RAWDISK
+#endif // USE_KSTAT_IO
// Variables for handling output.
string compress = getenv("COMPRESSOR"); // How to compress logs.
@@ -1025,8 +915,8 @@
tmp_tcp = tcp$tcp;
#endif
-#ifdef USE_RAWDISK
- raw_disk_update();
+#ifdef USE_KSTAT_IO
+ orca_io_info_update();
#endif
}
@@ -1598,29 +1488,29 @@
total_tape_writek = 0.0;
tape_count = 0;
-#ifdef USE_RAWDISK
- for (i=0; i<RAW_disk_count; ++i) {
+#ifdef USE_KSTAT_IO
+ for (i=0; i<ORCA_io_dev_count; ++i) {
// Record tape drive st devices differently than regular disk devices.
- if (RAW_disk[i].short_name[0] == 's' && RAW_disk[i].short_name[1] == 't') {
+ if (ORCA_io_dev_info[i].short_name =~ "^st.*") {
tape_count++;
- total_tape_reads += RAW_disk[i].reads;
- total_tape_writes += RAW_disk[i].writes;
- total_tape_readk += RAW_disk[i].kreads;
- total_tape_writek += RAW_disk[i].kwrites;
- put_output(sprintf("tape_runp_%s", RAW_disk[i].long_name),
- sprintf("%16.5f", RAW_disk[i].run_percent));
+ total_tape_reads += ORCA_io_dev_info[i].reads;
+ total_tape_writes += ORCA_io_dev_info[i].writes;
+ total_tape_readk += ORCA_io_dev_info[i].kreads;
+ total_tape_writek += ORCA_io_dev_info[i].kwrites;
+ put_output(sprintf("tape_runp_%s", ORCA_io_dev_info[i].long_name),
+ sprintf("%16.5f", ORCA_io_dev_info[i].run_percent));
continue;
}
// Block the listing of floppy drives for now.
- if (RAW_disk[i].short_name[0] == 'f' && RAW_disk[i].short_name[1] == 'd') {
+ if (ORCA_io_dev_info[i].short_name =~ "^fd.*") {
continue;
}
disk_count++;
- put_output(sprintf("disk_runp_%s", RAW_disk[i].long_name),
- sprintf("%16.5f", RAW_disk[i].run_percent));
+ put_output(sprintf("disk_runp_%s", ORCA_io_dev_info[i].long_name),
+ sprintf("%16.5f", ORCA_io_dev_info[i].run_percent));
- put_output(sprintf("disk_svct_%s", RAW_disk[i].long_name),
- sprintf("%16.5f", RAW_disk[i].service));
+ put_output(sprintf("disk_svct_%s", ORCA_io_dev_info[i].long_name),
+ sprintf("%16.5f", ORCA_io_dev_info[i].service));
// Comments from Damon Atkins <Damon.Atkins at nabaus.com.au>. Check
// [wr]lentime to see if an EMC is using a fake disk for control.
@@ -1637,13 +1527,13 @@
#ifdef HAVE_EMC_DISK_CONTROL
if ((pioGLOB_old_wlentime[i] + pioGLOB_old_rlentime[i]) > 1) {
#endif
- total_disk_reads += RAW_disk[i].reads;
- total_disk_writes += RAW_disk[i].writes;
- total_disk_readk += RAW_disk[i].kreads;
- total_disk_writek += RAW_disk[i].kwrites;
- mean_disk_busy += RAW_disk[i].run_percent;
- if (RAW_disk[i].run_percent > peak_disk_busy) {
- peak_disk_busy = RAW_disk[i].run_percent;
+ total_disk_reads += ORCA_io_dev_info[i].reads;
+ total_disk_writes += ORCA_io_dev_info[i].writes;
+ total_disk_readk += ORCA_io_dev_info[i].kreads;
+ total_disk_writek += ORCA_io_dev_info[i].kwrites;
+ mean_disk_busy += ORCA_io_dev_info[i].run_percent;
+ if (ORCA_io_dev_info[i].run_percent > peak_disk_busy) {
+ peak_disk_busy = ORCA_io_dev_info[i].run_percent;
}
#ifdef HAVE_EMC_DISK_CONTROL
}
Added: trunk/orca/lib/SE/3.3.1/tapeinfo.se
==============================================================================
--- (empty file)
+++ trunk/orca/lib/SE/3.3.1/tapeinfo.se Tue Sep 14 11:27:02 2004
@@ -0,0 +1,277 @@
+//
+// Copyright (c) 1993-2001 by Richard Pettit. All rights reserved.
+//
+// Some of this work was derived from include files containing the following
+// copyrights.
+//
+// Copyright (c) 1986-1994 by Sun Microsystems, Inc.
+// Copyright (c) 1983-1989 by AT&T
+// Copyright (c) 1980-1993 by The Regents of the University of California.
+//
+// The work as a whole represents unique intellectual property and is
+// copyright by Richard Pettit as shown on the first line.
+//
+
+#ifndef _TAPEINFO_SE_
+#define _TAPEINFO_SE_
+
+#include <stdio.se>
+#include <string.se>
+#include <ctype.se>
+#include <stdlib.se>
+#include <unistd.se>
+#include <kstat.se>
+#include <sysdepend.se>
+#include <dirent.se>
+#include <se_trees.se>
+
+#define PATH_TO_INST "/etc/path_to_inst"
+
+// sterr is not defined in kstat.se, so define here
+kstat struct "sterr:" ks_sterr {
+ int number$; // linear counter
+ string name$; // name of error
+ int instance$; // instance number
+
+ uint64_t "Soft Errors";
+ uint64_t "Hard Errors";
+ uint64_t "Transport Errors";
+ string Vendor;
+ string Product;
+ string Revision;
+ string "Serial No";
+};
+
+struct tape_info_t {
+ string short_name;
+ string long_name;
+ ks_sterr errors;
+};
+
+// this is a global array to keep similarity with diskinfo.se
+// use functions provided below as access methods
+
+tape_info_t GLOBAL_tape_info[];
+int GLOBAL_tapeinfo_size = 1;
+ulong_t GLOBAL_tapeinfo_short_tree;
+ulong_t GLOBAL_tapeinfo_long_tree;
+
+int tapeinfo_inst_initialized; // set when data exists
+
+ks_sterr
+find_tape_error(string name)
+{
+ ks_sterr sterr;
+ string short_name;
+
+ if (name =~ "^st.*") {
+ sterr.number$ = 0;
+ for(refresh$(sterr); sterr.number$ != -1; sterr.number$++,refresh$(sterr)) {
+ short_name = sterr.name$;
+ strtok(short_name, ",");
+ if (short_name == name) {
+ break;
+ }
+ }
+ return sterr;
+ }
+}
+
+int
+setup_tapeinfo_inst() // return 1 if OK, 0 if not
+{
+ char buf[BUFSIZ];
+ char points_at[MAXNAMELEN];
+ string p;
+ string full;
+ string path;
+ string tape_dirs[2] = { "/dev/rmt", nil };
+ int count = 0;
+ int i;
+ int n;
+ ulong ld;
+ ulong dirp;
+ ulong input;
+ dirent_t dp;
+ ulong_t path_tree;
+ ulong_t np;
+
+ if (tapeinfo_inst_initialized == 1) {
+ return 1;
+ }
+
+ path_tree = str2int_init();
+ if (path_tree == 0) {
+ return 0;
+ }
+
+ // load up the tree with the paths and quit traversing path_to_inst
+ input = fopen(PATH_TO_INST, "r");
+ if (input == 0) {
+ avlfree(path_tree);
+ return 0;
+ }
+ while (fgets(buf, sizeof(buf), input) != nil) {
+ if ((buf[0] != '#') && (buf[0] != '\n')) {
+ p = strtok(buf, " ");
+ n = atoi(strtok(nil, " "));
+ path = strtok(p, "\"");
+
+ if (str2int_put(path_tree, path, n) == -1) {
+ fclose(input);
+ avlfree(path_tree);
+ return 0;
+ }
+ }
+ }
+ fclose(input);
+
+ // create the global tape info array
+ GLOBAL_tape_info = new tape_info_t[GLOBAL_tapeinfo_size];
+
+ // scan /dev/rmt and insert tape entries
+ for (i=0; tape_dirs[i] != nil; i++) {
+ dirp = opendir(tape_dirs[i]);
+ if (dirp == 0) {
+ if (i > 0) {
+ // first is /dev/rmt
+ break;
+ }
+ avlfree(path_tree);
+ return 0;
+ }
+
+ for (ld = readdir(dirp); ld != 0; ld = readdir(dirp)) {
+ // grow the array if needed
+ if (count == GLOBAL_tapeinfo_size) {
+ GLOBAL_tapeinfo_size += 1;
+ GLOBAL_tape_info = renew GLOBAL_tape_info[GLOBAL_tapeinfo_size];
+ }
+ dp = *((dirent_t *) ld);
+
+ // skip . and ..
+ if (dp.d_name == "." || dp.d_name == "..") {
+ continue;
+ }
+
+ // skip everything but raw devices
+ if ( isdigit(dp.d_name[strlen(dp.d_name)-1]) == 0 ) {
+ continue;
+ }
+
+ // read the link
+ full = sprintf("%s/%s", tape_dirs[i], dp.d_name);
+
+ n = readlink(full, points_at, sizeof(points_at));
+ if (n == -1) {
+ closedir(dirp);
+ avlfree(path_tree);
+ return 0;
+ }
+ points_at[n] = '\0';
+
+ // chop off the :a at the end
+ strcpy(strrchr(points_at, ':'), "");
+
+ // hack off ../../devices from the start
+ sscanf(points_at, "../../devices%s", &points_at);
+
+ // hack off /dev/ from the start
+ // long name is the rmt/<tape device number>
+ sscanf(full, "/dev/%s", &buf);
+ GLOBAL_tape_info[count].long_name = buf;
+
+ GLOBAL_tape_info[count].short_name = nil;
+
+ // construct the short name
+ if ((np = str2int_get(path_tree, points_at)) != 0) {
+ n = ((int) *((ulong_t *) np));
+ p = strrchr(points_at, '/');
+ p = strtok(p, "/");
+ p = strtok(p, "@");
+ GLOBAL_tape_info[count].short_name = sprintf("%s%d", p, n);
+ }
+
+ // hard luck, can't find this device
+ if (GLOBAL_tape_info[count].short_name == nil) {
+ continue;
+ }
+
+ // squirrel this away while we're at it
+ GLOBAL_tape_info[count].errors =
+ find_tape_error(GLOBAL_tape_info[count].short_name);
+
+ count++;
+ }
+ closedir(dirp);
+ }
+
+ // tree the names for fast lookup
+ GLOBAL_tapeinfo_short_tree = str2int_init();
+ GLOBAL_tapeinfo_long_tree = str2int_init();
+ if ((GLOBAL_tapeinfo_short_tree == 0) || (GLOBAL_tapeinfo_long_tree == 0)) {
+ return 0;
+ }
+ for(i=0; i<count; i++) {
+ str2int_put(GLOBAL_tapeinfo_short_tree, GLOBAL_tape_info[i].short_name, i);
+ str2int_put(GLOBAL_tapeinfo_long_tree, GLOBAL_tape_info[i].long_name, i);
+ }
+
+ tapeinfo_inst_initialized = 1;
+ return 1;
+}
+
+// Function names must be changed to prevent conflict with diskinfo.se
+
+// use this function during init to map short names (st0) to indexes
+int
+find_tape_inst(string name) // return index into GLOBAL_tape_info
+{
+ ulong_t lp;
+
+ if (setup_tapeinfo_inst() == 0) {
+ return -1;
+ }
+ lp = str2int_get(GLOBAL_tapeinfo_short_tree, name);
+ if (lp == 0) {
+ return -1;
+ }
+ return ((int) *((ulong_t *) lp));
+}
+#define find_tape_short_name find_tape_inst
+
+// use this function to do the reverse mapping from rmt/0
+int
+find_tape_long_name(string name) // return index into GLOBAL_tape_info
+{
+ ulong_t lp;
+
+ if (setup_tapeinfo_inst() == 0) {
+ return -1;
+ }
+ lp = str2int_get(GLOBAL_tapeinfo_long_tree, name);
+ if (lp == 0) {
+ return -1;
+ }
+ return ((int) *((ulong_t *) lp));
+}
+
+// use this function to get the data for an index
+tape_info_t
+tape_info(int i, string name)
+{
+ tape_info_t no_info;
+
+ if (setup_tapeinfo_inst() == 0) {
+ return no_info;
+ }
+ if (i >= 0 && i < GLOBAL_tapeinfo_size) {
+ return GLOBAL_tape_info[i];
+ } else {
+ no_info.short_name = name;
+ no_info.long_name = name;
+ return no_info;
+ }
+}
+
+#endif
More information about the Orca-checkins
mailing list