From 71325c297e0436e9930a3e129a26696e78c27f62 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Mon, 19 May 2008 22:47:29 -0600 Subject: [PATCH] Imported Upstream version 2.5.1p1 --- ChangeLog | 85 ++ Makefile.am | 7 - Makefile.in | 9 +- NEWS | 10 + amandad-src/amandad.c | 11 +- client-src/sendbackup-dump.c | 19 +- client-src/sendsize.c | 4 +- common-src/bsdtcp-security.c | 4 +- common-src/dgram.c | 20 +- common-src/packet.c | 26 +- common-src/util.c | 18 +- common-src/util.h | 4 +- common-src/version.c | 6 +- common-src/versuff.c | 6 +- configure | 2 +- configure.in | 2 +- contrib/sst/Makefile | 31 - contrib/sst/README | 113 -- contrib/sst/README.Amanda | 66 - contrib/sst/sst.c | 2533 --------------------------------- contrib/sst/sst.conf | 25 - contrib/sst/sst_def.h | 258 ---- contrib/sst/sstest.c | 181 --- docs/amanda-client.conf.5.txt | 10 + docs/amanda.8.txt | 2 +- docs/amanda.conf.5.txt | 22 +- docs/amcheck.8.txt | 3 +- docs/amcleanup.8.txt | 8 + docs/amcrypt-asym-ossl.8.txt | 12 +- docs/amgetconf.8.txt | 3 +- docs/amtapetype.8.txt | 6 +- docs/howto-auth.txt | 3 +- restore-src/amfetchdump.c | 6 +- restore-src/amidxtaped.c | 47 +- restore-src/restore.c | 19 +- restore-src/restore.h | 8 +- server-src/amcheck.c | 28 +- server-src/amindexd.c | 39 +- server-src/amstatus.pl.in | 26 +- server-src/amtoc.pl.in | 2 +- server-src/changer.c | 18 +- server-src/find.c | 8 +- server-src/logfile.c | 3 +- server-src/planner.c | 3 +- 44 files changed, 337 insertions(+), 3379 deletions(-) delete mode 100644 contrib/sst/Makefile delete mode 100644 contrib/sst/README delete mode 100644 contrib/sst/README.Amanda delete mode 100644 contrib/sst/sst.c delete mode 100644 contrib/sst/sst.conf delete mode 100644 contrib/sst/sst_def.h delete mode 100644 contrib/sst/sstest.c diff --git a/ChangeLog b/ChangeLog index c0c9820..2a827bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,88 @@ +2006-09-27 Jean-Louis Martineau + * Amanda 2.5.1p1 released. + * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.1p1). + * NEWS: Update for 2.5.1p1 + +2006-09-27 Jean-Louis Martineau + * restore-src/restore.c: Improve debugging. + * server-src/changer.c: Make sure to dup the fd out of the 0..2 range. + +2006-09-27 Jean-Louis Martineau + * restore-src/amfetchdump.c: Pass new prompt_in parameter to + search_tapes. + * restore-src/restore.c (search_tapes, load_manual_tape): New prompt_in + parameter. + * restore-src/restore.h (search_tapes): New prompt_in parameter. + * restore-src/amidxtaped.c: Set new 'FILE *' instead of reusing stdin + and stdout. + * server-src/amindexd.c: Set new 'FILE *' instead of reusing stdin + and stdout. + +2006-09-27 Jean-Louis Martineau + Patch by Orion Poplawski + * server-src/planner.c: Add a skip_quoted_line() on error. + +2006-09-23 Jean-Louis Martineau + * server-src/amstatus.pl.in: Fix parsing of 'taper: wrote label' line. + * server-src/amtoc.pl.in: Fix parsing of 'START taper' line. + +2006-09-22 Jean-Louis Martineau + Patch by William Jojo + * client-src/sendsize.c: Fix #endif for AIX. + +2006-09-22 Jean-Louis Martineau + * common-src/packet.c: Fix use of arglist_start/arglist_end. + * server-src/amindexd.c: Fix use of vsnprintf (for IRIX). + * server-src/logfile.c: Fix use of arglist_start/arglist_end. + +2006-09-21 Jean-Louis Martineau + * server-src/amcheck.c: Don't assert if holding use is set to 0. + +2006-09-21 Jean-Louis Martineau + * common-src/util.c: Declare keytable. + * common-src/util.h: Declare keytable as extern. + +2006-09-19 Jean-Louis Martineau + * contrib/sst: Removed + * Makefile.am (EXTRA_DIST): Remove sst files. + +2006-09-19 Jean-Louis Martineau + * server-src/find.c (search_logfile): Count 'PARTIAL taper line'. + +2006-09-19 Jean-Louis Martineau + Patch by Paul Bijens + * server-src/amcheck.c: Print "tapelist" instead of "tapefile". + +2006-09-19 Jean-Louis Martineau + * common-src/dgram.c (dgram_bind): Remove unused variables. + +2006-09-19 Jean-Louis Martineau + * common-src/dgram.c (dgram_bind): Don't set SO_REUSEADDR on socket. + +2006-09-19 Jean-Louis Martineau + * common-src/util.c (connect_port): Make EHOSTUNREACH and ENETUNREACH + fatal error. + +2006-09-18 Jean-Louis Martineau + * common-src/util.c(dump_sockaddr): Convert from network to machine + bytes order before printing. + * common-src/dgram.c (dgram_recv): Print the fromaddr. + +2006-09-15 Jean-Louis Martineau + * amandad-src/amandad.c: Correct order of close/dup. + +2006-09-12 Jean-Louis Martineau + * common-src/bsdtcp-security.c: Use AMANDA_SERVICE_NAME. + +2006-09-12 Jean-Louis Martineau + * server-src/amstatus.pl.in: Check that $dumpers_active is defined. + +2006-09-12 Jean-Louis Martineau + * common-src/util.c (conftoken_getc): Return an int. + +2006-09-11 Jean-Louis Martineau + * client-src/sendbackup-dump.c: Works if rundump is not used. + 2006-09-05 Jean-Louis Martineau * Amanda 2.5.1 released. * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.1). diff --git a/Makefile.am b/Makefile.am index fe62a56..b51faf4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,13 +53,6 @@ EXTRA_DIST = $(SNAPSHOT_STAMP) \ contrib/dbbackup.tcl \ contrib/mkamandisk \ contrib/set_prod_link.pl \ - contrib/sst/Makefile \ - contrib/sst/README \ - contrib/sst/README.Amanda \ - contrib/sst/sst.c \ - contrib/sst/sst.conf \ - contrib/sst/sst_def.h \ - contrib/sst/sstest.c \ contrib/gsc/README \ contrib/gsc/cfggsc.c \ contrib/gsc/defgsc.c \ diff --git a/Makefile.in b/Makefile.in index 488e39f..601f632 100644 --- a/Makefile.in +++ b/Makefile.in @@ -328,13 +328,6 @@ EXTRA_DIST = $(SNAPSHOT_STAMP) \ contrib/dbbackup.tcl \ contrib/mkamandisk \ contrib/set_prod_link.pl \ - contrib/sst/Makefile \ - contrib/sst/README \ - contrib/sst/README.Amanda \ - contrib/sst/sst.c \ - contrib/sst/sst.conf \ - contrib/sst/sst_def.h \ - contrib/sst/sstest.c \ contrib/gsc/README \ contrib/gsc/cfggsc.c \ contrib/gsc/defgsc.c \ @@ -571,7 +564,7 @@ distclean-tags: distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) - $(mkdir_p) $(distdir)/amplot $(distdir)/changer-src $(distdir)/client-src $(distdir)/common-src $(distdir)/contrib $(distdir)/contrib/gsc $(distdir)/contrib/sst $(distdir)/dumper-src $(distdir)/example $(distdir)/patches $(distdir)/regex-src $(distdir)/regex-src/fake $(distdir)/server-src + $(mkdir_p) $(distdir)/amplot $(distdir)/changer-src $(distdir)/client-src $(distdir)/common-src $(distdir)/contrib $(distdir)/contrib/gsc $(distdir)/dumper-src $(distdir)/example $(distdir)/patches $(distdir)/regex-src $(distdir)/regex-src/fake $(distdir)/server-src @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ diff --git a/NEWS b/NEWS index 27a49f0..22a4542 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,13 @@ +Changes in release 2.5.1p1 + * Many bugs fixed: + o Timeout waiting for ACK + o "illegal density" with dump + o IRIX: Parse config file, amrecover + o MacOs: compilation + o amrecover with FreeBSD/OpenBSD + * Some other small cleanup. + * Remove contrib/sst. + Changes in release 2.5.1 * Defects found by Coverity scan and Klocwork K7 analysis tools fixed. diff --git a/amandad-src/amandad.c b/amandad-src/amandad.c index 772cd39..25a5183 100644 --- a/amandad-src/amandad.c +++ b/amandad-src/amandad.c @@ -25,7 +25,7 @@ */ /* - * $Id: amandad.c,v 1.18 2006/08/21 20:17:09 martinea Exp $ + * $Id: amandad.c,v 1.18.2.1 2006/09/15 17:18:06 martinea Exp $ * * handle client-host side of Amanda network communications, including * security checks, execution of the proper service, and acking the @@ -1424,6 +1424,11 @@ service_new( aclose(data_write[0][0]); aclose(data_write[0][1]); + for (i = 0; i < DATA_FD_COUNT; i++) { + aclose(data_read[i + 1][0]); + aclose(data_write[i + 1][1]); + } + /* * Make sure they are not open in the range DATA_FD_OFFSET to * DATA_FD_OFFSET + DATA_FD_COUNT*2 - 1 @@ -1444,7 +1449,7 @@ service_new( data_write[i + 1][0] = newfd; } } - for (i = 0; i < DATA_FD_COUNT; i++) + for (i = 0; i < DATA_FD_COUNT*2; i++) close(DATA_FD_OFFSET + i); /* @@ -1456,7 +1461,6 @@ service_new( error("dup %d to %d failed: %s\n", data_read[i + 1][1], i + DATA_FD_OFFSET, strerror(errno)); } - aclose(data_read[i + 1][0]); aclose(data_read[i + 1][1]); if (dup2(data_write[i + 1][0], i*2 + 1 + DATA_FD_OFFSET) < 0) { @@ -1464,7 +1468,6 @@ service_new( i + DATA_FD_OFFSET, strerror(errno)); } aclose(data_write[i + 1][0]); - aclose(data_write[i + 1][1]); } /* close all unneeded fd */ diff --git a/client-src/sendbackup-dump.c b/client-src/sendbackup-dump.c index c762394..a568fc8 100644 --- a/client-src/sendbackup-dump.c +++ b/client-src/sendbackup-dump.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: sendbackup-dump.c,v 1.90 2006/07/25 18:10:07 martinea Exp $ + * $Id: sendbackup-dump.c,v 1.90.2.1 2006/09/23 19:19:47 martinea Exp $ * * send backup data using BSD dump */ @@ -136,6 +136,7 @@ start_backup( char *device = NULL; char *fstype = NULL; char *cmd = NULL; + char *cmdX = NULL; char *indexcmd = NULL; char level_str[NUM_STR_SIZE]; char *compopt = NULL; @@ -213,12 +214,14 @@ start_backup( #if defined(USE_RUNDUMP) || !defined(DUMP) cmd = vstralloc(libexecdir, "/", "rundump", versionsuffix(), NULL); + cmdX = cmd; if (g_options->config) config = g_options->config; else config = "NOCONFIG"; #else cmd = stralloc(DUMP); + cmdX = skip_argument; config = skip_argument; #endif @@ -233,6 +236,7 @@ start_backup( { char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump", versionsuffix(), NULL); + cmdX = cmd; if (g_options->config) config = g_options->config; else @@ -256,7 +260,7 @@ start_backup( dumpkeys = stralloc(level_str); dumppid = pipespawn(progname, STDIN_PIPE, &dumpin, &dumpout, &mesgf, - config, /* JLM */ + cmdX, config, "xfsdump", options->no_record ? "-J" : skip_argument, "-F", @@ -277,12 +281,14 @@ start_backup( #ifdef USE_RUNDUMP char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump", versionsuffix(), NULL); + cmdX = cmd; if (g_options->config) config = g_options->config; else config = "NOCONFIG"; #else char *progname = cmd = newvstralloc(cmd, VXDUMP, NULL); + cmdX = skip_argument; config = skip_argument; #endif program->backup_name = VXDUMP; @@ -306,7 +312,7 @@ start_backup( dumppid = pipespawn(progname, STDIN_PIPE, &dumpin, &dumpout, &mesgf, - progname, config, /* JLM */ + cmdX, config, "vxdump", dumpkeys, "1048576", @@ -326,6 +332,7 @@ start_backup( { char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump", versionsuffix(), NULL); + cmdX = cmd; if (g_options->config) config = g_options->config; else @@ -352,7 +359,7 @@ start_backup( dumppid = pipespawn(cmd, STDIN_PIPE, &dumpin, &dumpout, &mesgf, - cmd, config, + cmdX, config, "vdump", dumpkeys, "60", @@ -390,7 +397,7 @@ start_backup( dumppid = pipespawn(cmd, STDIN_PIPE, &dumpin, &dumpout, &mesgf, - cmd, config, + cmdX, config, "dump", dumpkeys, "1048576", @@ -422,7 +429,7 @@ start_backup( dumppid = pipespawn(cmd, STDIN_PIPE, &dumpin, &dumpout, &mesgf, - cmd, config, + cmdX, config, "backup", dumpkeys, "-", diff --git a/client-src/sendsize.c b/client-src/sendsize.c index bf3595a..abd30d3 100644 --- a/client-src/sendsize.c +++ b/client-src/sendsize.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: sendsize.c,v 1.171 2006/08/24 01:57:15 paddy_s Exp $ + * $Id: sendsize.c,v 1.171.2.1 2006/09/22 11:51:32 martinea Exp $ * * send estimated backup sizes using dump */ @@ -1339,8 +1339,8 @@ getsize_dump( "0", #endif "1048576", "-", device, (char *)0, safe_env()); -# endif } +# endif #endif { error("exec %s failed or no dump program available: %s", diff --git a/common-src/bsdtcp-security.c b/common-src/bsdtcp-security.c index 9ddf90c..99d20b8 100644 --- a/common-src/bsdtcp-security.c +++ b/common-src/bsdtcp-security.c @@ -25,7 +25,7 @@ */ /* - * $Id: bsdtcp-security.c,v 1.7 2006/07/13 03:22:20 paddy_s Exp $ + * $Id: bsdtcp-security.c,v 1.7.2.1 2006/09/12 14:30:47 martinea Exp $ * * bsdtcp-security.c - security and transport over bsdtcp or a bsdtcp-like command. * @@ -227,7 +227,7 @@ runbsdtcp( uid_t euid; struct tcp_conn * rc = rh->rc; - if ((sp = getservbyname("amanda", "tcp")) == NULL) { + if ((sp = getservbyname(AMANDA_SERVICE_NAME, "tcp")) == NULL) { error("%s/tcp unknown protocol", "amanda"); } diff --git a/common-src/dgram.c b/common-src/dgram.c index 5df3a57..2008fc9 100644 --- a/common-src/dgram.c +++ b/common-src/dgram.c @@ -25,7 +25,7 @@ * University of Maryland at College Park */ /* - * $Id: dgram.c,v 1.32 2006/07/05 19:54:20 martinea Exp $ + * $Id: dgram.c,v 1.32.2.3 2006/09/20 12:48:54 martinea Exp $ * * library routines to marshall/send, recv/unmarshall UDP packets */ @@ -57,10 +57,6 @@ dgram_bind( socklen_t len; struct sockaddr_in name; int save_errno; -#if defined(USE_REUSEADDR) - const int on = 1; - int r; -#endif *portp = (in_port_t)0; if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { @@ -84,16 +80,6 @@ dgram_bind( name.sin_family = (sa_family_t)AF_INET; name.sin_addr.s_addr = INADDR_ANY; -#ifdef USE_REUSEADDR - r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (void *)&on, (socklen_t)sizeof(on)); - if (r < 0) { - dbprintf(("%s: dgram_bind: setsockopt(SO_REUSEADDR) failed: %s\n", - debug_prefix(NULL), - strerror(errno))); - } -#endif - /* * If a port range was specified, we try to get a port in that * range first. Next, we try to get a reserved port. If that @@ -331,8 +317,7 @@ dgram_recv( to.tv_usec = 0; dbprintf(("%s: dgram_recv(dgram=%p, timeout=%u, fromaddr=%p)\n", - debug_prefix_time(NULL), timeout, fromaddr)); - dump_sockaddr(fromaddr); + debug_prefix_time(NULL), dgram, timeout, fromaddr)); nfound = (ssize_t)select(sock+1, &ready, NULL, NULL, &to); if(nfound <= 0 || !FD_ISSET(sock, &ready)) { @@ -376,6 +361,7 @@ dgram_recv( errno = save_errno; return -1; } + dump_sockaddr(fromaddr); dgram->len = (size_t)size; dgram->data[size] = '\0'; dgram->cur = dgram->data; diff --git a/common-src/packet.c b/common-src/packet.c index 7ebda61..e8e20d4 100644 --- a/common-src/packet.c +++ b/common-src/packet.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: packet.c,v 1.8 2006/05/25 01:47:12 johnfranks Exp $ + * $Id: packet.c,v 1.8.2.1 2006/09/22 11:02:12 martinea Exp $ * * Routines for modifying the amanda protocol packet type */ @@ -54,6 +54,7 @@ printf_arglist_function2(void pkt_init, pkt_t *, pkt, pktype_t, type, const char *, fmt) { va_list argp; + int len; assert(pkt != NULL); assert(strcmp(pkt_type2str(type), "BOGUS") != 0); @@ -62,14 +63,16 @@ printf_arglist_function2(void pkt_init, pkt_t *, pkt, pktype_t, type, pkt->type = type; pkt->packet_size = 1000; pkt->body = alloc(pkt->packet_size); - arglist_start(argp, fmt); - while (vsnprintf(pkt->body, pkt->packet_size, fmt, argp) >= - (int)(pkt->packet_size - 1)) { + while(1) { + arglist_start(argp, fmt); + len = vsnprintf(pkt->body, pkt->packet_size, fmt, argp); + arglist_end(argp); + if (len < (int)(pkt->packet_size - 1)) + break; pkt->packet_size *= 2; amfree(pkt->body); pkt->body = alloc(pkt->packet_size); } - arglist_end(argp); pkt->size = strlen(pkt->body); } @@ -79,6 +82,7 @@ printf_arglist_function2(void pkt_init, pkt_t *, pkt, pktype_t, type, printf_arglist_function1(void pkt_cat, pkt_t *, pkt, const char *, fmt) { size_t len; + int lenX; va_list argp; char * pktbody; @@ -87,19 +91,19 @@ printf_arglist_function1(void pkt_cat, pkt_t *, pkt, const char *, fmt) len = strlen(pkt->body); - arglist_start(argp, fmt); - while (vsnprintf(pkt->body + len, pkt->packet_size - len, fmt,argp) >= - (int)(pkt->packet_size - len - 1)) { + while(1) { + arglist_start(argp, fmt); + lenX = vsnprintf(pkt->body + len, pkt->packet_size - len, fmt,argp); + arglist_end(argp); + if (lenX < (int)(pkt->packet_size - len - 1)) + break; pkt->packet_size *= 2; pktbody = alloc(pkt->packet_size); strncpy(pktbody, pkt->body, len); pktbody[len] = '\0'; amfree(pkt->body); pkt->body = pktbody; - arglist_end(argp); - arglist_start(argp, fmt); } - arglist_end(argp); pkt->size = strlen(pkt->body); } diff --git a/common-src/util.c b/common-src/util.c index a5f88f8..3564d6b 100644 --- a/common-src/util.c +++ b/common-src/util.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: util.c,v 1.42 2006/08/24 01:57:15 paddy_s Exp $ + * $Id: util.c,v 1.42.2.4 2006/09/21 11:12:21 martinea Exp $ */ #include "amanda.h" @@ -37,6 +37,7 @@ int token_pushed; tok_t tok, pushed_tok; val_t tokenval; +keytab_t *keytable; int conf_line_num, got_parserror; FILE *conf_conf = (FILE *)NULL; @@ -56,7 +57,7 @@ static int make_socket(void); static int connect_port(struct sockaddr_in *addrp, in_port_t port, char *proto, struct sockaddr_in *svaddr, int nonblock); -char conftoken_getc(void); +int conftoken_getc(void); int conftoken_ungetc(int c); /* @@ -250,10 +251,10 @@ connect_port( } if(servPort == NULL) - dbprintf(("%s: connect_port: Try port %d: Available - ", + dbprintf(("%s: connect_port: Try port %d: Available - \n", debug_prefix_time(NULL), port)); else { - dbprintf(("%s: connect_port: Try port %d: Owned by %s - ", + dbprintf(("%s: connect_port: Try port %d: Owned by %s - \n", debug_prefix_time(NULL), port, servPort->s_name)); } @@ -305,6 +306,8 @@ connect_port( aclose(s); errno = save_errno; if (save_errno == ECONNREFUSED || + save_errno == EHOSTUNREACH || + save_errno == ENETUNREACH || save_errno == ETIMEDOUT) { return -2 ; } @@ -1285,7 +1288,7 @@ unget_conftoken(void) return; } -char +int conftoken_getc(void) { if(conf_line == NULL) @@ -2505,8 +2508,9 @@ void dump_sockaddr( struct sockaddr_in * sa) { - dbprintf(("%s: (sockaddr_in *)%p = { %d, %hd, %s }\n", - debug_prefix(NULL), sa, sa->sin_family, sa->sin_port, + dbprintf(("%s: (sockaddr_in *)%p = { %d, %d, %s }\n", + debug_prefix_time(NULL), sa, sa->sin_family, + (int)ntohs(sa->sin_port), inet_ntoa(sa->sin_addr))); } diff --git a/common-src/util.h b/common-src/util.h index 4ebe39c..029def0 100644 --- a/common-src/util.h +++ b/common-src/util.h @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: util.h,v 1.17 2006/07/26 15:17:36 martinea Exp $ + * $Id: util.h,v 1.17.2.1 2006/09/21 11:12:21 martinea Exp $ */ #ifndef UTIL_H #define UTIL_H @@ -208,7 +208,7 @@ typedef struct { /* token table entry */ tok_t token; } keytab_t; -keytab_t *keytable; +extern keytab_t *keytable; typedef struct { char *name; diff --git a/common-src/version.c b/common-src/version.c index 525284a..534a6f4 100644 --- a/common-src/version.c +++ b/common-src/version.c @@ -1,8 +1,8 @@ /* version.c - generated by genversion.c - DO NOT EDIT! */ const char * const version_info[] = { - "build: VERSION=\"Amanda-2.5.1\"\n", - " BUILT_DATE=\"Tue Sep 5 10:09:05 EDT 2006\"\n", - " BUILT_MACH=\"Linux modemcable197.174-201-24.mc.videotron.ca 2.6.17-1.2174_FC5 #1 SMP Tue Aug 8 15:30:44 EDT 2006 x86_64 x86_64 x86_64 GNU/Linux\"\n", + "build: VERSION=\"Amanda-2.5.1p1\"\n", + " BUILT_DATE=\"Wed Sep 27 11:11:29 EDT 2006\"\n", + " BUILT_MACH=\"Linux modemcable197.174-201-24.mc.videotron.ca 2.6.17-1.2187_FC5 #1 SMP Mon Sep 11 01:16:59 EDT 2006 x86_64 x86_64 x86_64 GNU/Linux\"\n", " CC=\"gcc\"\n", " CONFIGURE_COMMAND=\"'./configure' '--prefix=/home/martinea/linux' '--with-configdir=/home/martinea/etc/amanda' '--with-gnutar-listdir=/var/gnutar-lists' '--with-bsd-security' '--with-ssh-security' '--with-rsh-security' '--with-krb4-security' '--without-krb5-security' '--with-user=martinea' '--with-group=martinea' '--mandir=/home/martinea/man'\"\n", "paths: bindir=\"/home/martinea/linux/bin\"\n", diff --git a/common-src/versuff.c b/common-src/versuff.c index 2cafbd6..7f40f85 100644 --- a/common-src/versuff.c +++ b/common-src/versuff.c @@ -34,13 +34,13 @@ const int VERSION_MAJOR = 2; const int VERSION_MINOR = 5; const int VERSION_PATCH = 1; -const char *const VERSION_COMMENT = ""; +const char *const VERSION_COMMENT = "p1"; const char * versionsuffix(void) { #ifdef USE_VERSION_SUFFIXES - return "-2.5.1"; + return "-2.5.1p1"; #else return ""; #endif @@ -49,5 +49,5 @@ versionsuffix(void) const char * version(void) { - return "2.5.1"; + return "2.5.1p1"; } diff --git a/configure b/configure index a2cdb31..fa38cd0 100755 --- a/configure +++ b/configure @@ -1965,7 +1965,7 @@ fi # Define the identity of the package. PACKAGE=amanda - VERSION=2.5.1 + VERSION=2.5.1p1 cat >>confdefs.h <<_ACEOF diff --git a/configure.in b/configure.in index 3330438..accacca 100644 --- a/configure.in +++ b/configure.in @@ -13,7 +13,7 @@ AC_DEFINE_UNQUOTED(CONFIGURE_COMMAND,"$CONFIGURE_COMMAND", [Saves the original ./configure command line arguments]) AC_SUBST(CONFIGURE_COMMAND) -AM_INIT_AUTOMAKE(amanda, 2.5.1) +AM_INIT_AUTOMAKE(amanda, 2.5.1p1) AM_CONFIG_HEADER(config/config.h) AC_PREREQ(2.57) dnl Minimum Autoconf version required. diff --git a/contrib/sst/Makefile b/contrib/sst/Makefile deleted file mode 100644 index b53a955..0000000 --- a/contrib/sst/Makefile +++ /dev/null @@ -1,31 +0,0 @@ - -# -# Copyright (c) 1996,1997, by Sun Microsystems, Inc. -# All Rights Reserved -# -#ident "@(#)Makefile 1.9 97/09/14 SMI" -# - -TOP= .. - -include $(TOP)/Makefile.master - -.KEEP_STATE: - -MOD=sst - -OBJS= sst.o - -MOD_CONF= $(MOD:%=%.conf) - -all: $(MOD) - -include ../Makefile.driver - -CFLAGS += -D$(INST) $(ENVCPPFLAGS1) $(ENVCPPFLAGS2) -DDEBUG - -sstest: sstest.c - $(CC) -o $(INST)/sstest $(ENVCPPFLAGS1) $(ENVCPPFLAGS2) sstest.c - - -DDICTFLAGS += -D_USCSI diff --git a/contrib/sst/README b/contrib/sst/README deleted file mode 100644 index 7fd30d8..0000000 --- a/contrib/sst/README +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 1996,1997, by Sun Microsystems, Inc. - * All Rights Reserved - */ - - ident "@(#)README 1.11 97/09/09 SMI" - -DRIVER NAME: - sst - Simple SCSI Target driver - -ARCHITECTURES: - SPARC and x86 - -DESCRIPTION OF DRIVER: - This driver is intended as an example of programming a SCSA - target driver for Solaris 2.X; it is not intended for any - particular device. - - This driver has been modified to be 64-bit ready. In - particular it provides an example of how an LP64 driver - can manage an ioctl from an ILP32 application. Refer to - SunOS 5.6 Writing Device Drivers, Appendix F for more - information. - - Source Files - ------------- - - sst.c driver source - sst_def.h driver definitions - sst.conf driver configuration file - sstest.c driver test program - -NOTE: - Areas where you may need to change this code or add your own to - deal with your specific devices are marked "Note". - Other warnings are marked "WARNING". - -DISCLAIMER: - This driver provides an example of programming using the SCSA - DDI/DDK interfaces for Solaris target drivers; it is not intended - for any particular device, although it has been tested on disk - and tape drives. It is meant to be a skeleton that can be - used as a basis for a real-world driver. - -SYSTEM REQUIREMENTS: - The driver requires a SCSI target device to operate. - -COMPILING/LOADING: - To compile and link the driver: - - use the Makefile provided in the driver subdirectory (sst); the - executable files will be built in an architecture-specific - subdirectory depending on the architecture of the build machine - (i.e., sst/sparc) - - to compile and link without using the Makefile: - - % cc -D_KERNEL -c sst.c - % ld -r sst.o -o sst - - To install: - - 1. Copy the module (sparc/sst) and config file (sst.conf) - into /usr/kernel/drv - - 2. (optional) Add an entry to /etc/devlink.tab, of the form: - - type=sample_driver;name=sst;minor=character rsst\A1 - - This will cause devlinks(1M) to create link(s) to /devices with - names of the form "/dev/rsstX" where X is the SCSI target number - (the target number is "5" in the sst.conf file included in the - DDK; you can change it to refer to an appropriate target number - for the target device on your system). - - 3. Run add_drv(1M). - - # add_drv sst - - To compile the test program: - - run "make sstest" in the sst directory; the executable file will be - built in an architecture-specific subdirectory depending on the - architecture of the build machine (sst/sparc or sst/i386) - - The test program takes as arguments the full path to the device - file (e.g., /dev/sst0 or /devices/mc/mcis@3540,0/sst@3,0:character) - and a command (see the sstest program's usage message for available - commands) - - Setting kernel variables: - Variables can be explicitly set from the /etc/system file, by - adding an entry of the form - - "set sst:=" - - The /etc/system file is read only once at boot time, if you change - it you must reboot for the change to take effect. - - Alternatively, you can use adb to set variables and debug as - follows: - - # adb -kw /dev/ksyms /dev/mem - - Or, if you booted under kadb, you can set the a variable from the - kadb prompt. For example, the following command will set the - variable sst_debug to the value 3 (maximum debugging messages): - - kadb[0]: sst_debug:W 3 - -REFERENCES: - - SunOS 5.6 Writing Device Drivers diff --git a/contrib/sst/README.Amanda b/contrib/sst/README.Amanda deleted file mode 100644 index d0a5441..0000000 --- a/contrib/sst/README.Amanda +++ /dev/null @@ -1,66 +0,0 @@ -These are notes specific to using sst with Amanda on Solaris. - -John R. Jackson -21-Nov-2000 - -============== -Access as root -============== - -A change was made to the sst.c source code to allow access from non-root -users. It #if's out a call to drv_priv() that checked against UID 0 -(look for EPERM in the code). Since Amanda does not normally run as -root, this was a problem. Use the file system permissions on /dev/rsst* -to control access. - -======================== -Using the GNU C compiler -======================== - -If you build sst with the GNU C compiler for a 32 bit kernel (see below -for 64 bit kernel notes), you may get warnings like this: - - warning: passing arg 1 of `timeout' from incompatible pointer type - .../include/va-sparc.h:29: warning: `va_start' redefined - .../include/va-sparc.h:29: warning: `va_end' redefined - .../include/va-sparc.h:29: warning: `va_arg' redefined - .../include/stdarg.h:163: warning: redefinition of `va_list' - -These may all be ignored. - -A change was made to the sst.c source code to get around the following -error: - - `__builtin_va_alist' undeclared - -It adds a #include of stdarg.h if __GNUC__ is #define'd. - -============================ -Building for a 64 bit kernel -============================ - -The sst driver build instructions are for a 32 bit kernel. If you want -to build for a 64 bit kernel, compile it like this: - - cc -D_KERNEL -D_SYSCALL32 -xarch=v9 -c sst.c - -Drivers for 64 bit kernels go in /usr/kernel/drv/sparcv9 instead of -/usr/kernel/drv. However their .conf files still go in /usr/kernel/drv, -regardless of bit size. - -At the time this is being written, only the Sun C compiler is able to -(reliably) build kernel drivers for 64 bit architectures. GNU C is not -yet up to the task. - -================== -Using sgen instead -================== - -Solaris 8 comes with a new driver, sgen, that provides raw SCSI access -ala sst, but with (presumably) better long term support (since sst is -intended only as a development starting point). At the time this is -being written, the chg-scsi changer reportedly works with sgen, but be -sure and read the sgen(7D) man page for instructions on setting it up. -In particular, you must edit sgen.conf to get the device entries created. -Also, the default permissions only allow root access, so you'll need to -open them up just enough to allow Amanda to issue commands. diff --git a/contrib/sst/sst.c b/contrib/sst/sst.c deleted file mode 100644 index e2b0493..0000000 --- a/contrib/sst/sst.c +++ /dev/null @@ -1,2533 +0,0 @@ -/* - * Copyright (c) 1997, by Sun Microsystems, Inc. - * All Rights Reserved - */ - -/* - * sst.c - Simple SCSI Target driver; a template character SCSA target - * driver for Solaris 2.x. - * - * This file is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify this file without charge, but are not authorized to - * license or distribute it to anyone else except as part of a product - * or program developed by the user. - * - * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * This file is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even - * if Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 901 San Antonio Rd - * Palo Alto, California 94303 - * - * ------------------------------------------------------------------ - * - * This driver is intended as an example of programming a SCSA - * target driver for Solaris 2.X; it is not intended for any particular - * device. - * - * Areas where you may need to change this code or add your own to - * deal with your specific device are marked "Note". - * Other warnings are marked "WARNING" - * - * To compile: - * % cc -D_KERNEL -c sst.c - * % ld -r sst.o -o sst - * - * To install: - * 1. Copy the module (sst) and config file (sst.conf) into /usr/kernel/drv - * 2. Add an entry to /etc/devlink.tab, of the form: - * "type=sample_driver;name=sst;minor=character rsst\A1" - * This will cause devlinks(1M) to create link(s) to /devices with - * names of the form "/dev/rsstX" where X is the SCSI target number. - * 3. Run add_drv(1M). - * - * Setting variables - * Variables can be explicitly set from the /etc/system file, by - * adding an entry of the form - * "set sst:=" - * Alternatively, you can use adb to set variables and debug as - * follows: - * # adb -kw /dev/ksyms /dev/mem - * The /etc/system file is read only once at boot time, if you change - * it you must reboot for the change to take effect. - */ - -#pragma ident "@(#)sst.c 1.23 97/10/03 SMI" - -/* - * Includes, Declarations and Local Data - */ - -#include -#include -#ifdef __GNUC__ -#include -#endif - -#include "sst_def.h" - -/* - * Local Function Prototypes - */ -static int sst_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p); -static int sst_close(dev_t dev, int flag, int otyp, cred_t *cred_p); -static int sst_read(dev_t dev, struct uio *uio, cred_t *cred_p); -static int sst_write(dev_t dev, struct uio *uio, cred_t *cred_p); -static int sst_aread(dev_t dev, struct aio_req *aio, cred_t *credp); -static int sst_awrite(dev_t dev, struct aio_req *aio, cred_t *credp); -static int sst_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); - -static int sst_strategy(struct buf *bp); -static int sst_ioctl_cmd(dev_t, struct uscsi_cmd *, enum uio_seg, - enum uio_seg, int mode); - -static int sst_unit_ready(dev_t dev); -static void sst_done(struct scsi_target *targ, struct buf *bp); -static void sst_restart(caddr_t arg); -static void sst_callback(struct scsi_pkt *pkt); -static struct scsi_pkt *sst_make_cmd(struct scsi_target *targ, struct buf *bp, - struct scsi_pkt *pktp); -static void sst_fill_cdb(struct scsi_pkt *pkt, struct scsi_target *targ, - struct buf *bp, u_int flags); -static int sst_handle_incomplete(struct scsi_target *targ); -static int sst_handle_arq(struct scsi_pkt *pktp, struct scsi_target *targ, - struct buf *bp); -static int sst_handle_sense(struct scsi_target *targ, struct buf *bp); -static int sst_check_error(struct scsi_target *targ, struct buf *bp); -static void sst_log(struct scsi_device *devp, int level, const char *fmt, ...); -static void hex_print(char *msg, void *cptr, int len); -static void sst_dump_cdb(struct scsi_target *tgt, struct scsi_pkt *pkt, - int cdblen); - -/* - * Local Static Data - */ -static int sst_io_time = SST_IO_TIME; -static int sst_retry_count = SST_RETRY_COUNT; -static void *sst_state; - -/* - * Errors at or above this level will be reported - */ -static int32_t sst_error_reporting = SCSI_ERR_RETRYABLE; - -/* - * Enable the driver debugging code if DEBUG is defined (DEBUG also - * enables other debugging code, e.g. ASSERT statements). - */ -#ifdef DEBUG -#define SST_DEBUG -#endif DEBUG - - -/* - * Debug message control - * Debug Levels: - * 0 = no messages - * 1 = Errors - * 2 = Subroutine calls & control flow - * 3 = I/O Data (verbose!) - * Can be set with adb or in the /etc/system file with - * "set sst:sst_debug=" - * turn on diagnostics if DEBUG is defined (DEBUG also enables - * other debugging code, e.g. ASSERT statements). - */ - -#ifdef SST_DEBUG -static int sst_debug = 3; -static int sst_debug_cdb = 1; -#else -static int sst_debug = 0; -static int sst_debug_cdb = 0; -#endif /* SST_DEBUG */ - -#define SST_DUMP_CDB(tgt, pkt, cdblen) \ - if (sst_debug_cdb) { \ - sst_dump_cdb((tgt), (pkt), (cdblen)); \ - } - -/* - * Array of commands supported by the device, suitable for - * scsi_errmsg(9f) - * Note: Add or remove commands here as appropriate for - * your device. - */ -static struct scsi_key_strings sst_cmds[] = { - 0x00, "test unit ready", - 0x01, "rezero/rewind", - 0x03, "request sense", - 0x04, "format", - 0x05, "read block limits", - 0x07, "reassign", - 0x08, "read", - 0x0a, "write", - 0x0b, "seek", - 0x0f, "read reverse", - 0x10, "write file mark", - 0x12, "inquiry", - 0x13, "verify", - 0x14, "recover buffered data", - 0x15, "mode select", - 0x16, "reserve", - 0x17, "release", - 0x18, "copy", - 0x19, "erase tape", - 0x1a, "mode sense", - 0x1b, "start/stop/load", - 0x1e, "door lock", - 0x37, "read defect data", - -1, NULL, -}; - -/* - * Module Loading/Unloading and Autoconfiguration Routines - */ - -/* - * Device driver ops vector - cb_ops(9s) structure - * Device switch table fields (equivalent to the old 4.x cdevsw and bdevsw). - * Unsupported entry points (e.g. for xxprint() and xxdump()) are set to - * nodev, except for the poll routine, which is set to nochpoll(), a - * routine that returns ENXIO. - * - * Note: This uses ddi_prop_op for the prop_op(9e) routine. If your device - * has its own properties, you should implement a sst_prop_op() routine - * to manage them. - */ -static struct cb_ops sst_cb_ops = { - sst_open, /* b/c open */ - sst_close, /* b/c close */ - sst_strategy, /* b strategy */ - nodev, /* b print */ - nodev, /* b dump */ - sst_read, /* c read */ - sst_write, /* c write */ - sst_ioctl, /* c ioctl */ - nodev, /* c devmap */ - nodev, /* c mmap */ - nodev, /* c segmap */ - nochpoll, /* c poll */ - ddi_prop_op, /* cb_prop_op */ - 0, /* streamtab */ - D_MP | D_NEW, /* Driver compatibility flag */ - CB_REV, /* cb_ops revision number */ - sst_aread, /* c aread */ - sst_awrite /* c awrite */ -}; - - -/* - * dev_ops(9S) structure, defined in sys/devops.h. - * Device Operations table, for autoconfiguration - * - * Note: If you replace the sst_detach entry here with "nulldev", it - * implies that the detach is always successful. We need a real detach to - * free the sense packet and the unit structure. If you don't want the - * driver to ever be unloaded, replace the sst_detach entry with "nodev" - * (which always fails). - */ -static int sst_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, - void **result); -static int sst_probe(dev_info_t *dip); -static int sst_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); -static int sst_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); -static int sst_power(dev_info_t *dip, int component, int level); - -static int sst_doattach(dev_info_t *dip); -static int sst_dodetach(dev_info_t *dip); - -static struct dev_ops sst_ops = { - DEVO_REV, /* devo_rev, */ - 0, /* refcnt */ - sst_info, /* info */ - nulldev, /* identify */ - sst_probe, /* probe */ - sst_attach, /* attach */ - sst_detach, /* detach */ - nodev, /* reset */ - &sst_cb_ops, /* driver operations */ - (struct bus_ops *)0, /* bus operations */ - sst_power /* power */ -}; - -/* - * Module Loading and Unloading - * See modctl.h for external structure definitions. - */ - -static struct modldrv modldrv = { - &mod_driverops, /* Type of module (driver). */ - "SCSI Simple Target Driver Version 1.23", /* Description */ - &sst_ops, /* driver ops */ -}; - -static struct modlinkage modlinkage = { - MODREV_1, (void *)&modldrv, NULL -}; - -/* - * Tell the system that we depend on the general scsi support routines, - * i.e the scsi "misc" module must be loaded - */ -char _depends_on[] = "misc/scsi"; - -/* - * _init(9E) - module Installation - * - * Install the driver and "pre-allocate" space for INIT_UNITS units, - * i.e. instances of the driver. - */ -int -_init(void) -{ - int e; - - if ((e = ddi_soft_state_init(&sst_state, - sizeof (struct scsi_target), 0)) != 0) { - SST_LOG(0, SST_CE_DEBUG2, - "_init, ddi_soft_state_init failed: 0x%x\n", e); - return (e); - } - - if ((e = mod_install(&modlinkage)) != 0) { - SST_LOG(0, SST_CE_DEBUG2, - "_init, mod_install failed: 0x%x\n", e); - ddi_soft_state_fini(&sst_state); - } - - SST_LOG(0, SST_CE_DEBUG2, "_init succeeded\n"); - return (e); -} - - -/* - * _fini(9E) - module removal - */ -int -_fini(void) -{ - int e; - - if ((e = mod_remove(&modlinkage)) != 0) { - SST_LOG(0, SST_CE_DEBUG1, - "_fini mod_remove failed, 0x%x\n", e); - return (e); - } - - ddi_soft_state_fini(&sst_state); - - SST_LOG(0, SST_CE_DEBUG2, "_fini succeeded\n"); - return (e); -} - -/* - * _info(9E) - return module info - */ -int -_info(struct modinfo *modinfop) -{ - SST_LOG(0, SST_CE_DEBUG2, "_info\n"); - return (mod_info(&modlinkage, modinfop)); -} - -/* - * Autoconfiguration Routines - */ - -/* - * probe(9e) - * - * Check that we're talking to the right device on the SCSI bus. - * Calls scsi_probe(9f) to see if there's a device at our target id. - * If there is, scsi_probe will fill in the sd_inq struct (in the devp - * scsi device struct) with the inquiry data. Validate the data here, - * allocate a request sense packet, and start filling in the private data - * structure. - * - * Probe should be stateless, ie it should have no side-effects. Just - * check that we have the right device, don't set up any data or - * initialize the device here. Also, it's a Sun convention to probe - * quietly; send messages to the log file only, not to the console. - * - * The host adapter driver sets up the scsi_device structure and puts - * it into the dev_info structure with ddi_set_driver_private(). - * - * No need to allow for probing/attaching in the open() routine because - * of the loadability - the first reference to the device will auto-load - * it, i.e. will call this routine. - */ - -#define VIDSZ 8 /* Vendor Id length in Inquiry Data */ -#define PIDSZ 16 /* Product Id length in Inquiry Data */ - -static int -sst_probe(dev_info_t *dip) -{ - register struct scsi_device *devp; - int err, rval = DDI_PROBE_FAILURE; - int tgt, lun; - char vpid[VIDSZ+PIDSZ+1]; - - devp = (struct scsi_device *)ddi_get_driver_private(dip); - tgt = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "target", -1); - lun = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "lun", -1); - - SST_LOG(devp, SST_CE_DEBUG2, "sst_probe: target %d, lun %d\n", - tgt, lun); - - /* - * Call the routine scsi_probe to do some of the dirty work. - * This routine uses the SCSI Inquiry command to test for the - * presence of the device. If it's successful, it will fill in - * the sd_inq field in the scsi_device structure. - */ - switch (err = scsi_probe(devp, SLEEP_FUNC)) { - case SCSIPROBE_NORESP: - sst_log(devp, CE_CONT, "No response from target %d, lun %d\n", - tgt, lun); - rval = DDI_PROBE_FAILURE; - break; - - case SCSIPROBE_NONCCS: - case SCSIPROBE_NOMEM: - case SCSIPROBE_FAILURE: - default: - SST_LOG(devp, SST_CE_DEBUG1, - "sst_probe: scsi_slave failed, 0x%x\n", err); - rval = DDI_PROBE_FAILURE; - break; - - case SCSIPROBE_EXISTS: - /* - * Inquiry succeeded, devp->sd_inq is now filled in - * Note: Check inq_dtype, inq_vid, inq_pid and any other - * fields to make sure the target/unit is what's - * expected (sd_inq is a struct scsi_inquiry, - * defined in scsi/generic/inquiry.h). - * Note: Put device-specific checking into the appropriate - * case statement, and delete the rest. - * Note: The DTYPE_* defines are from , - * this is the full list as of "now", check it for new - * types. - */ - switch (devp->sd_inq->inq_dtype) { - case DTYPE_PROCESSOR: - case DTYPE_OPTICAL: - case DTYPE_DIRECT: - case DTYPE_SEQUENTIAL: - case DTYPE_PRINTER: - case DTYPE_WORM: - case DTYPE_RODIRECT: - case DTYPE_SCANNER: - case DTYPE_CHANGER: - case DTYPE_COMM: - /* - * Print what was found on the console. For your - * device, you should send the 'found' message to - * the system log file only, by inserting an - * exclamation point, "!", as the first character of - * the message - see cmn_err(9f). - */ - sst_log(devp, CE_CONT, - "found %s device at tgt%d, lun%d\n", - scsi_dname((int)devp->sd_inq->inq_dtype), tgt, lun); - bcopy(devp->sd_inq->inq_vid, vpid, VIDSZ); - bcopy(devp->sd_inq->inq_pid, vpid+VIDSZ, PIDSZ); - vpid[VIDSZ+PIDSZ] = 0; - sst_log(devp, CE_CONT, "Vendor/Product ID = %s\n", - vpid); - rval = DDI_PROBE_SUCCESS; - break; - - case DTYPE_NOTPRESENT: - sst_log(devp, CE_NOTE, - "Target reports no device present\n"); - rval = DDI_PROBE_FAILURE; - break; - - default: - sst_log(devp, CE_NOTE, - "Unrecognized device type: 0x%x\n", - devp->sd_inq->inq_dtype); - rval = DDI_PROBE_FAILURE; - break; - } - } - - /* - * scsi_unprobe() must be called even if scsi_probe() failed - */ - scsi_unprobe(devp); - - return (rval); -} - - - -/* - * Attach(9E) - */ - -static int -sst_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) -{ - int instance; - struct scsi_target *targ; - struct scsi_device *devp; - - switch (cmd) { - case DDI_ATTACH: - return (sst_doattach(dip)); - - case DDI_RESUME: - /* - * Suspend/Resume - * - * When the driver suspended, there were no - * outstanding cmds and therefore we only need to - * reset the suspended flag and do a cv_broadcast - * on the suspend_cv to wake up any blocked - * threads - */ - instance = ddi_get_instance(dip); - targ = ddi_get_soft_state(sst_state, instance); - if (targ == NULL) - return (DDI_FAILURE); - mutex_enter(SST_MUTEX(targ)); - targ->targ_suspended = 0; - - /* wake up threads blocked in sst_strategy */ - cv_broadcast(&targ->targ_suspend_cv); - - mutex_exit(SST_MUTEX(targ)); - - return (DDI_SUCCESS); - - case DDI_PM_RESUME: - /* - * Power Management suspend - * - * Sinc we have no h/w state to restore, the code to - * handle DDI_PM_RESUME is similar to DDI_RESUME, - * except the driver uses the targ_pm_suspend flag. - */ - instance = ddi_get_instance(dip); - targ = ddi_get_soft_state(sst_state, instance); - if (targ == NULL) - return (DDI_FAILURE); - mutex_enter(SST_MUTEX(targ)); - - targ->targ_pm_suspended = 0; - cv_broadcast(&targ->targ_suspend_cv); - - mutex_exit(SST_MUTEX(targ)); - - return (DDI_SUCCESS); - - default: - SST_LOG(0, SST_CE_DEBUG1, - "sst_attach: unsupported cmd 0x%x\n", cmd); - return (DDI_FAILURE); - } -} - - -/* - * Attach(9E) - DDI_ATTACH handling - * - * - create minor device nodes - * - initialize per-instance mutex's & condition variables - * - device-specific initialization (e.g. read disk label) - */ -static int -sst_doattach(dev_info_t *dip) -{ - int instance; - struct scsi_pkt *rqpkt; - struct scsi_target *targ; - struct scsi_device *devp; - struct buf *bp; - - instance = ddi_get_instance(dip); - devp = (struct scsi_device *)ddi_get_driver_private(dip); - SST_LOG(devp, SST_CE_DEBUG2, "sst_attach: instance %d\n", instance); - - /* - * Re-probe the device to get the Inquiry data; it's used - * elsewhere in the driver. The Inquiry data was validated in - * sst_probe so there's no need to look at it again here. - */ - if (scsi_probe(devp, SLEEP_FUNC) != SCSIPROBE_EXISTS) { - SST_LOG(0, SST_CE_DEBUG1, "sst_attach: re-probe failed\n"); - scsi_unprobe(devp); - return (DDI_FAILURE); - } - - if (ddi_soft_state_zalloc(sst_state, instance) != DDI_SUCCESS) { - scsi_unprobe(devp); - return (DDI_FAILURE); - } - - targ = ddi_get_soft_state(sst_state, instance); - devp->sd_private = (opaque_t)targ; - - targ->targ_sbufp = getrbuf(KM_SLEEP); - if (targ->targ_sbufp == NULL) { - goto error; - } - - targ->targ_devp = devp; - - /* - * Set auto-rqsense, per-target; record whether it's allowed - * in targ_arq - */ - targ->targ_arq = (scsi_ifsetcap(ROUTE(targ), - "auto-rqsense", 1, 1) == 1) ? 1 : 0; - SST_LOG(devp, SST_CE_DEBUG2, "sst_attach: Auto Sensing %s\n", - targ->targ_arq ? "enabled" : "disabled"); - - if (!targ->targ_arq) { - /* - * Allocate a Request Sense packet - */ - bp = scsi_alloc_consistent_buf(&devp->sd_address, NULL, - SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL); - if (!bp) { - goto error; - } - - rqpkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP0, - targ->targ_arq ? sizeof (struct scsi_arq_status) : 1, - sizeof (struct sst_private), - PKT_CONSISTENT, SLEEP_FUNC, NULL); - if (!rqpkt) { - goto error; - } - devp->sd_sense = (struct scsi_extended_sense *)bp->b_un.b_addr; - - (void) scsi_setup_cdb((union scsi_cdb *)rqpkt->pkt_cdbp, - SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0); - - rqpkt->pkt_comp = sst_callback; - rqpkt->pkt_time = sst_io_time; - rqpkt->pkt_flags |= FLAG_SENSING; - targ->targ_rqs = rqpkt; - targ->targ_rqbp = bp; - } - - /* - * Create the minor node(s), see the man page - * for ddi_create_minor_node(9f). - * The 2nd parameter is the minor node name; drvconfig(1M) - * appends it to the /devices entry, after the colon. - * The 4th parameter ('instance') is the actual minor number, - * put into the /devices entry's inode and passed to the driver. - * The 5th parameter ("sample_driver") is the node type; it's used - * by devlinks to match an entry in /etc/devlink.tab to create - * the link from /dev to /devices. The #defines are in . - */ - if (ddi_create_minor_node(dip, "character", S_IFCHR, instance, - "sample_driver", 0) == DDI_FAILURE) { - SST_LOG(0, SST_CE_DEBUG1, "Create Minor Failed\n"); - goto error; - } - - /* - * Initialize power management bookkeeping. - */ - if (pm_create_components(dip, 1) == DDI_SUCCESS) { - if (pm_idle_component(dip, 0) == DDI_FAILURE) { - SST_LOG(devp, SST_CE_DEBUG1, - "pm_idle_component() failed\n"); - goto error; - } - pm_set_normal_power(dip, 0, 1); - targ->targ_power_level = 1; - } else { - SST_LOG(devp, SST_CE_DEBUG1, - "pm_create_component() failed\n"); - ddi_remove_minor_node(dip, NULL); - goto error; - } - - /* - * Since this driver manages devices with "remote" hardware, - * i.e. the devices themselves have no "reg" properties, - * the SUSPEND/RESUME commands in detach/attach will not be - * called by the power management framework unless we request - * it by creating a "pm-hardware-state" property and setting it - * to value "needs-suspend-resume". - */ - if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, - "pm-hardware-state", "needs-suspend-resume") != - DDI_PROP_SUCCESS) { - SST_LOG(devp, SST_CE_DEBUG1, - "ddi_prop_update(\"pm-hardware-state\") failed\n"); - pm_destroy_components(dip); - ddi_remove_minor_node(dip, NULL); - goto error; - } - - /* - * Initialize the condition variables. - * Note: We don't need to initialize the mutex (SST_MUTEX) - * because it's actually devp->sd_mutex (in the struct - * scsi_device) and is initialized by our parent, the - * host adapter driver. - * Note: We don't really need targ_sbuf_cv, we could just wait - * for targ_pkt_cv instead, but it's clearer this way. - */ - cv_init(&targ->targ_sbuf_cv, "targ_sbuf_cv", CV_DRIVER, NULL); - cv_init(&targ->targ_pkt_cv, "targ_pkt_cv", CV_DRIVER, NULL); - cv_init(&targ->targ_suspend_cv, "targ_suspend_cv", CV_DRIVER, - NULL); - - /* - * Note: Do any other pre-open target initialization here, - * e.g. read/verify the disk label for a fixed-disk drive. - */ - - ddi_report_dev(dip); - SST_LOG(devp, SST_CE_DEBUG2, "Attached sst driver\n"); - targ->targ_state = SST_STATE_CLOSED; - return (DDI_SUCCESS); - -error: - if (bp) { - scsi_free_consistent_buf(bp); - } - if (rqpkt) { - scsi_destroy_pkt(rqpkt); - } - if (targ->targ_sbufp) { - freerbuf(targ->targ_sbufp); - } - ddi_soft_state_free(sst_state, instance); - devp->sd_private = (opaque_t)0; - devp->sd_sense = (struct scsi_extended_sense *)0; - scsi_unprobe(devp); - return (DDI_FAILURE); -} - - -/* - * Detach(9E) - */ -static int -sst_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) -{ - int instance; - struct scsi_device *devp; - struct scsi_target *targ; - - switch (cmd) { - - case DDI_DETACH: - return (sst_dodetach(dip)); - - case DDI_SUSPEND: - /* - * Suspend/Resume - * - * To process DDI_SUSPEND, we must do the following: - * - * - wait until outstanding operations complete - * - block new operations - * - cancel pending timeouts - * - save h/w state - * - * We don't have any h/w state in this driver, so - * all we really need to do is to wait for any - * outstanding requests to complete. Once completed, - * we will have no pending timeouts either. - */ - instance = ddi_get_instance(dip); - targ = ddi_get_soft_state(sst_state, instance); - if (targ == NULL) { - return (DDI_FAILURE); - } - - mutex_enter(SST_MUTEX(targ)); - targ->targ_suspended = 1; - - /* - * Wait here till outstanding operations complete - */ - while (targ->targ_pkt_busy) { - cv_wait(&targ->targ_pkt_cv, SST_MUTEX(targ)); - } - - mutex_exit(SST_MUTEX(targ)); - return (DDI_SUCCESS); - - case DDI_PM_SUSPEND: - /* - * Power Management suspend - * - * To process DDI_PM_SUSPEND, we must do the following: - * - * - if busy, fail DDI_PM_SUSPEND - * - save h/w state - * - cancel pending timeouts - * - * Since we have no h/w state in this driver, we - * only have to check our current state. Once idle, - * we have no pending timeouts. - */ - instance = ddi_get_instance(dip); - targ = ddi_get_soft_state(sst_state, instance); - if (targ == NULL) { - return (DDI_FAILURE); - } - - mutex_enter(SST_MUTEX(targ)); - ASSERT(targ->targ_suspended == 0); - - /* - * If we have outstanding operations, fail the - * DDI_PM_SUSPEND. The PM framework will retry after - * the device has been idle for its threshold time. - */ - if (targ->targ_pkt_busy) { - mutex_exit(SST_MUTEX(targ)); - return (DDI_FAILURE); - } - - targ->targ_pm_suspended = 1; - - mutex_exit(SST_MUTEX(targ)); - return (DDI_SUCCESS); - - - default: - SST_LOG(0, SST_CE_DEBUG1, - "sst_detach: bad cmd 0x%x\n", cmd); - return (DDI_FAILURE); - } -} - -/* - * detach(9E) DDI_DETACH handling - * - * Free resources allocated in sst_attach - * Note: If you implement a timeout routine in this driver, cancel it - * here. Note that scsi_init_pkt is called with SLEEP_FUNC, so it - * will wait for resources if none are available. Changing it to - * a callback constitutes a timeout; however this detach routine - * will be called only if the driver is not open, and there should be - * no outstanding scsi_init_pkt's if we're closed. - */ -static int -sst_dodetach(dev_info_t *dip) -{ - int instance; - struct scsi_device *devp; - struct scsi_target *targ; - - devp = (struct scsi_device *)ddi_get_driver_private(dip); - instance = ddi_get_instance(dip); - SST_LOG(devp, SST_CE_DEBUG2, "sst_detach: unit %d\n", instance); - - if ((targ = ddi_get_soft_state(sst_state, instance)) == NULL) { - SST_LOG(devp, CE_WARN, "No Target Struct for sst%d\n", - instance); - return (DDI_SUCCESS); - } - - /* - * Note: Do unit-specific detaching here; e.g. shut down the device - */ - - /* - * Remove other data structures allocated in sst_attach() - */ - cv_destroy(&targ->targ_sbuf_cv); - cv_destroy(&targ->targ_pkt_cv); - cv_destroy(&targ->targ_suspend_cv); - - if (targ->targ_rqbp) { - scsi_free_consistent_buf(targ->targ_rqbp); - } - if (targ->targ_rqs) { - scsi_destroy_pkt(targ->targ_rqs); - } - if (targ->targ_sbufp) { - freerbuf(targ->targ_sbufp); - } - pm_destroy_components(dip); - ddi_soft_state_free(sst_state, instance); - devp->sd_private = (opaque_t)0; - devp->sd_sense = (struct scsi_extended_sense *)0; - ddi_remove_minor_node(dip, NULL); - scsi_unprobe(devp); - return (DDI_SUCCESS); -} - -/* - * Power(9E) - * - * The system calls power(9E) either directly or as a result of - * ddi_dev_is_needed(9F) when the system determines that a - * component's current power level needs to be changed. - * - * Since we don't control any h/w with this driver, this code - * only serves as a place-holder for a real power(9E) implementation - * when the driver is adapted for a real device. - */ -static int -sst_power(dev_info_t *dip, int component, int level) -{ - int instance; - struct scsi_device *devp; - struct scsi_target *targ; - - devp = (struct scsi_device *)ddi_get_driver_private(dip); - instance = ddi_get_instance(dip); - SST_LOG(devp, SST_CE_DEBUG2, "sst_detach: unit %d\n", instance); - - if ((targ = ddi_get_soft_state(sst_state, instance)) == NULL) { - SST_LOG(devp, CE_WARN, "No Target Struct for sst%d\n", - instance); - return (DDI_FAILURE); - } - - mutex_enter(SST_MUTEX(targ)); - - if (targ->targ_power_level == level) { - mutex_exit(SST_MUTEX(targ)); - return (DDI_SUCCESS); - } - - /* - * Set device's power level to 'level' - */ - SST_LOG(devp, SST_CE_DEBUG2, "sst_power: %d -> %d\n", - instance, targ->targ_power_level, level); - targ->targ_power_level = level; - - mutex_exit(SST_MUTEX(targ)); - return (DDI_SUCCESS); -} - - -/* - * Entry Points - */ - - -/* - * open(9e) - * - * Called for each open(2) call on the device. - * Make sure the device is present and correct. Do any initialization that's - * needed (start it up, load media, etc). - * Note: Credp can be used to restrict access to root, by calling drv_priv(9f); - * see also cred(9s). - * Flag shows the access mode (read/write). Check it if the device is - * read or write only, or has modes where this is relevant. - * Otyp is an open type flag, see open.h. - * - * WARNING: Unfortunately there is a bug in SunOS 5.0 that affects driver - * open(). The file's reference count is incremented before the driver's - * open is called. This means that if another process closes (last close) - * the device while we're in the open routine, the close routine will not - * be called. If the open then fails (e.g. it's an exclusive open device), - * the file's ref count is decremented again, but the device is now in an - * inconsistent state - the driver thinks it's open (close was never called), - * but it's really closed. If it is an exclusive open device, it's now - * unusable. This is a particular problem if you want to block in the open - * routine until someone closes the device - close will never be called! - */ -/*ARGSUSED*/ -static int -sst_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p) -{ - register dev_t dev = *dev_p; - register struct scsi_target *targ; - - SST_LOG(0, SST_CE_DEBUG2, "sst_open\n"); - - /* - * Test the open type flag - */ - if (otyp != OTYP_CHR) { - SST_LOG(0, SST_CE_DEBUG1, - "Unsupported open type %d\n", otyp); - return (EINVAL); - } - - targ = ddi_get_soft_state(sst_state, getminor(dev)); - if (targ == NULL) { - return (ENXIO); /* invalid minor number */ - } - - /* - * This is an exclusive open device; fail if it's not closed. - * Otherwise, set the state to open - this will lock out any - * other access attempts. We need the mutex here because the - * state must not change between the test for closed and the - * set to open. - * Note With an exclusive open device, we know that no one else - * will access our data structures so strictly mutexes are - * not required. However since this is an example driver, and - * you may want shared access, the rest of the driver is - * coded with mutexes. - * Note If you need shared access, it's more complex. See bst.c - */ - /* SST_MUTEX(targ) returns sd_mutex in the scsi_device struct */ - mutex_enter(SST_MUTEX(targ)); /* LOCK the targ data struct */ - if (targ->targ_state != SST_STATE_CLOSED) { - mutex_exit(SST_MUTEX(targ)); - return (EBUSY); - } - targ->targ_state = SST_STATE_OPEN; /* lock out other accesses */ - mutex_exit(SST_MUTEX(targ)); /* UNLOCK targ data struct */ - - /*LINTED*/ - _NOTE(NO_COMPETING_THREADS_NOW); - - /* - * Test to make sure unit still is powered on and is ready - * by sending the SCSI Test Unit Ready command. - * - * If this is, for instance, a CD-ROM, we may get an error on the - * first TUR if the disk has never been accessed (a Check Condition - * with extended sense data to tell us why) so do one sst_unit_ready - * and ignore the result. - */ - (void) sst_unit_ready(dev); - - if (sst_unit_ready(dev) == 0) { - SST_LOG(0, SST_CE_DEBUG1, "sst%d_open: not ready\n", - getminor(dev)); - targ->targ_state = SST_STATE_CLOSED; - - /*LINTED*/ - _NOTE(COMPETING_THREADS_NOW); - - return (EIO); - } - - /* - * Do any other initalization work here, e.g. send - * Mode Sense/Select commands to get the target in the - * right state. - */ - /*LINTED*/ - _NOTE(COMPETING_THREADS_NOW); - - return (0); -} - - -/* - * close(9e) - * Called on final close only, i.e. the last close(2) call. - * Shut down the device, and mark it closed in the unit structure. - */ -/*ARGSUSED*/ -static int -sst_close(dev_t dev, int flag, int otyp, cred_t *cred_p) -{ - register struct scsi_target *targ; - - SST_LOG(0, SST_CE_DEBUG2, "sst_close\n"); - - targ = ddi_get_soft_state(sst_state, getminor(dev)); - if (targ == NULL) { - return (ENXIO); - } - - /*LINTED*/ - _NOTE(NO_COMPETING_THREADS_NOW); - - /* - * Note: Close processing here, eg rewind if it's a tape; - * mark offline if removable media, etc. - * WARNING: Since this is an exclusive open device, other - * accesses will be locked out until the state is set - * to closed. If you make the device shareable, you - * need to cope with the open routine being called while - * we're in the close routine, and vice-versa. You could - * serialize open/close calls with a semaphore or with - * a condition variable. See bst.c. - */ - - targ->targ_state = SST_STATE_CLOSED; - - /*LINTED*/ - _NOTE(COMPETING_THREADS_NOW); - - return (0); -} - - -/* - * getinfo(9E) - * - * Device Configuration Routine - * link instance number (unit) with dev_info structure - */ -/*ARGSUSED*/ -static int -sst_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) -{ - dev_t dev; - struct scsi_target *targ; - int instance, error; - - SST_LOG(0, SST_CE_DEBUG2, "sst_info\n"); - - switch (infocmd) { - case DDI_INFO_DEVT2DEVINFO: - dev = (dev_t)arg; - instance = getminor(dev); - targ = ddi_get_soft_state(sst_state, instance); - if (targ == NULL) - return (DDI_FAILURE); - *result = (void *) targ->targ_devp->sd_dev; - error = DDI_SUCCESS; - break; - case DDI_INFO_DEVT2INSTANCE: - *result = (void *)getminor((dev_t)arg); - error = DDI_SUCCESS; - break; - default: - error = DDI_FAILURE; - } - return (error); -} - - -/* - * read(9E) - * - * Character (raw) read and write routines, called via read(2) and - * write(2). These routines perform "raw" (i.e. unbuffered) i/o. - * Just and call strategy via physio. Physio(9f) will take care of - * address mapping and locking, and will split the transfer if ncessary, - * based on minphys, possibly calling the strategy routine multiple times. - */ -/* ARGSUSED2 */ -static int -sst_read(dev_t dev, struct uio *uio, cred_t *cred_p) -{ - SST_LOG(0, SST_CE_DEBUG2, "Read\n"); - return (physio(sst_strategy, (struct buf *)0, dev, B_READ, - minphys, uio)); -} - -/* - * write(9E) - */ -/* ARGSUSED2 */ -static int -sst_write(dev_t dev, struct uio *uio, cred_t *cred_p) -{ - SST_LOG(0, SST_CE_DEBUG2, "Write\n"); - return (physio(sst_strategy, (struct buf *)0, dev, B_WRITE, - minphys, uio)); -} - - -/* - * aread(9E) - asynchronous read - */ -/*ARGSUSED2*/ -static int -sst_aread(dev_t dev, struct aio_req *aio, cred_t *credp) -{ - SST_LOG(0, SST_CE_DEBUG2, "aread\n"); - return (aphysio(sst_strategy, anocancel, dev, B_READ, - minphys, aio)); -} - -/* - * awrite(9E) - asynchronous write - */ -/*ARGSUSED2*/ -static int -sst_awrite(dev_t dev, struct aio_req *aio, cred_t *credp) -{ - SST_LOG(0, SST_CE_DEBUG2, "awrite\n"); - return (aphysio(sst_strategy, anocancel, dev, B_WRITE, - minphys, aio)); -} - - -/* - * strategy(9E) - * - * Main routine for commands to the device. since this is a character - * device, this routine is called only from the read/write routines above, - * and sst_ioctl_cmd for the pass through ioctl (USCSICMD). - * The cv_wait prevents this routine from being called simultaneously by - * two threads. - */ -static int -sst_strategy(struct buf *bp) -{ - struct scsi_target *targ; - - targ = ddi_get_soft_state(sst_state, getminor(bp->b_edev)); - if (targ == NULL) { - bp->b_resid = bp->b_bcount; - bioerror(bp, ENXIO); - biodone(bp); - return (0); - } - - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "sst_strategy\n"); - - /* - * Mark component busy so we won't get powered down - * while trying to resume. - */ - if (pm_busy_component(SST_DEVINFO(targ), 0) != DDI_SUCCESS) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "pm_busy_component() failed\n"); - } - - mutex_enter(SST_MUTEX(targ)); - - /* - * if we are suspended, wait till we are resumed again - */ - do { - /* - * Block commands while suspended via DDI_SUSPEND - */ - while (targ->targ_suspended) { - cv_wait(&targ->targ_suspend_cv, SST_MUTEX(targ)); - } - - /* - * Raise power level back to operational if needed. - * Since ddi_dev_is_needed() will result in our - * power(9E) entry point being called, we must - * drop the mutex. - */ - if (targ->targ_power_level == 0) { - mutex_exit(SST_MUTEX(targ)); - if (ddi_dev_is_needed(SST_DEVINFO(targ), 0, 1) != - DDI_SUCCESS) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "ddi_dev_is_needed() failed\n"); - } - mutex_enter(SST_MUTEX(targ)); - } - - /* - * We need to continue to block commands if still - * suspended via DDI_PM_SUSPEND. Because we dropped - * the mutex to call ddi_dev_is_needed(), we may be - * executing in a thread that came in after the power - * level was raised but before attach was called with - * DDI_PM_RESUME. - */ - while (targ->targ_pm_suspended) { - cv_wait(&targ->targ_suspend_cv, SST_MUTEX(targ)); - } - } while (targ->targ_suspended || (targ->targ_power_level == 0)); - - /* - * Wait for the current request to finish. We can safely release - * the mutex once we have the pkt, because anyone else calling - * strategy will wait here until we release it with a cv_signal. - */ - while (targ->targ_pkt_busy) { - cv_wait(&targ->targ_pkt_cv, SST_MUTEX(targ)); - } - targ->targ_pkt_busy = 1; /* mark busy */ - mutex_exit(SST_MUTEX(targ)); - - if (((targ->targ_pkt = sst_make_cmd(targ, bp, - (struct scsi_pkt *)NULL))) == NULL) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "Unable to create SCSI command\n"); - bp->b_resid = bp->b_bcount; - bioerror(bp, EIO); - biodone(bp); - pm_idle_component(SST_DEVINFO(targ), 0); - return (0); - } - - bp->b_resid = 0; - - SST_DUMP_CDB(targ, targ->targ_pkt, CDB_GROUP0); - - if (scsi_transport(targ->targ_pkt) != TRAN_ACCEPT) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "Command transport failed\n"); - bp->b_resid = bp->b_bcount; - bioerror(bp, EIO); - biodone(bp); - pm_idle_component(SST_DEVINFO(targ), 0); - } - - return (0); -} - - -/* - * ioctl calls. - * Ioctls are device specific. Three are provided here as examples: - * SSTIOC_READY: Send a Test Unit Ready command to the device. This fills - * in the uscsi_cmd structure in the unit struct. The actual - * cdb to be sent to the device is created here; the union - * scsi_cdb is defined in /usr/include/sys/scsi/impl/commands.h. - * SST_ERRLEV: Change the error reporting level. - * USCSICMD: Pass through. Send the user-supplied command to the device. Very - * little checking is done - it's left up to the caller to supply - * a valid cdb. - */ -/* ARGSUSED3 */ -static int -sst_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, - cred_t *cred_p, int *rval_p) -{ - int err = 0; - struct scsi_target *targ; - struct uscsi_cmd uscsi_cmd; - struct uscsi_cmd *ucmd = &uscsi_cmd; - char cmdblk[CDB_GROUP0]; - -#ifdef _MULTI_DATAMODEL - /* - * For use when a 32-bit app makes an ioctl into a 64-bit driver - */ - struct sst_uscsi_cmd32 uscsi_cmd32; - struct sst_uscsi_cmd32 *ucmd32 = &uscsi_cmd32; - model_t model; -#endif /* _MULTI_DATAMODEL */ - - - targ = ddi_get_soft_state(sst_state, getminor(dev)); - if (targ == NULL) { - return (ENXIO); /* invalid minor number */ - } - - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "sst_ioctl: cmd = 0x%x\n", cmd); - - bzero(ucmd, sizeof (struct uscsi_cmd)); - - switch (cmd) { - case SSTIOC_READY: /* Send a Test Unit Ready command */ - ucmd->uscsi_bufaddr = 0; - ucmd->uscsi_buflen = 0; - bzero(cmdblk, CDB_GROUP0); - cmdblk[0] = (char)SCMD_TEST_UNIT_READY; - ucmd->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT|USCSI_WRITE; - ucmd->uscsi_cdb = cmdblk; - ucmd->uscsi_cdblen = CDB_GROUP0; - ucmd->uscsi_timeout = sst_io_time; - - err = sst_ioctl_cmd(dev, ucmd, - UIO_SYSSPACE, UIO_SYSSPACE, mode); - break; - - case SSTIOC_ERRLEV: /* Set the error reporting level */ - if (ddi_copyin((void *)arg, &sst_error_reporting, - sizeof (int32_t), mode)) { - return (EFAULT); - } - break; - - case USCSICMD: - /* - * Run a generic ucsi.h command. - */ - -#if 0 /* allow non-root to do this */ - /* - * Check root permissions - */ - if (drv_priv(cred_p) != 0) { - return (EPERM); - } -#endif - -#ifdef _MULTI_DATAMODEL - switch (model = ddi_model_convert_from(mode & FMODELS)) { - case DDI_MODEL_ILP32: - { - if (ddi_copyin((void *)arg, ucmd32, - sizeof (*ucmd32), mode)) { - return (EFAULT); - } - /* - * Convert 32-bit ILP32 application's uscsi cmd - * into 64-bit LP64 equivalent for internal use - */ - sst_uscsi_cmd32touscsi_cmd(ucmd32, ucmd); - break; - } - case DDI_MODEL_NONE: - if (ddi_copyin((void *)arg, ucmd, - sizeof (*ucmd), mode)) { - return (EFAULT); - } - break; - } - -#else /* ! _MULTI_DATAMODEL */ - if (ddi_copyin((void *)arg, ucmd, - sizeof (*ucmd), mode)) { - return (EFAULT); - } -#endif /* _MULTI_DATAMODEL */ - - err = sst_ioctl_cmd(dev, ucmd, - UIO_USERSPACE, UIO_USERSPACE, mode); - -#ifdef _MULTI_DATAMODEL - switch (model) { - case DDI_MODEL_ILP32: - /* - * Convert LP64 back to IPL32 before copyout - */ - sst_uscsi_cmdtouscsi_cmd32(ucmd, ucmd32); - - if (ddi_copyout(ucmd32, (void *)arg, - sizeof (*ucmd32), mode)) { - return (EFAULT); - } - break; - - case DDI_MODEL_NONE: - if (ddi_copyout(ucmd, (void *)arg, - sizeof (*ucmd), mode)) { - return (EFAULT); - } - break; - } -#else /* ! _MULTI_DATAMODE */ - if (ddi_copyout(ucmd, (void *)arg, - sizeof (*ucmd), mode)) { - return (EFAULT); - } -#endif /* _MULTI_DATAMODE */ - break; - - - default: - err = ENOTTY; - break; - } - return (err); -} - - -/* - * Run a command for user (from sst_ioctl) or from someone else in the driver. - * - * cdbspace is for address space of cdb; dataspace is for address space - * of the buffer - user or kernel. - */ -static int -sst_ioctl_cmd(dev_t dev, struct uscsi_cmd *scmd, - enum uio_seg cdbspace, enum uio_seg dataspace, - int mode) -{ - caddr_t cdb, user_cdbp; - int err, rw; - struct buf *bp; - struct scsi_target *targ; - int flag; - - targ = ddi_get_soft_state(sst_state, getminor(dev)); - if (targ == NULL) { - return (ENXIO); - } - - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "sst_ioctl_cmd\n"); - - /* - * The uscsi structure itself is already in kernel space (copied - * in by sst_ioctl, or declared there by our caller); but - * we need to copy in the cdb here. - */ - cdb = kmem_zalloc((size_t)scmd->uscsi_cdblen, KM_SLEEP); - flag = (cdbspace == UIO_SYSSPACE) ? FKIOCTL : mode; - if (ddi_copyin(scmd->uscsi_cdb, cdb, - (u_int)scmd->uscsi_cdblen, flag)) { - kmem_free(cdb, (size_t)scmd->uscsi_cdblen); - return (EFAULT); - } - - /* - * The cdb pointer in the structure passed by the user is pointing - * to user space. We've just copied the cdb into a local buffer, - * so point uscsi_cdb to it now. We'll restore the user's pointer - * at the end. - */ - user_cdbp = scmd->uscsi_cdb; /* save the user's pointer */ - scmd->uscsi_cdb = cdb; /* point to the local cdb buffer */ - rw = (scmd->uscsi_flags & USCSI_READ) ? B_READ : B_WRITE; - - /* - * Get the 'special command' buffer. - * First lock the targ struct; if the buffer's busy, wait for - * it to become free. Once we get the buffer, mark it busy to - * lock out other requests for it. - * Note cv_wait will release the mutex, allowing other parts - * of the driver to acquire it. - * Note Once we have the special buffer, we can safely release - * the mutex; the buffer is now busy and another thread will - * block in the cv_wait until we release it. All the code - * from here until we unset the busy flag is non-reentrant, - * including the physio/strategy/start/callback/done thread. - */ - mutex_enter(SST_MUTEX(targ)); - while (targ->targ_sbuf_busy) { - cv_wait(&targ->targ_sbuf_cv, SST_MUTEX(targ)); - } - targ->targ_sbuf_busy = 1; - mutex_exit(SST_MUTEX(targ)); - - bp = targ->targ_sbufp; - - if (scmd->uscsi_buflen) { - /* - * We're sending/receiving data; create a uio structure and - * call physio to do the right things. - */ - auto struct iovec aiov; - auto struct uio auio; - register struct uio *uio = &auio; - - bzero(&auio, sizeof (struct uio)); - bzero(&aiov, sizeof (struct iovec)); - aiov.iov_base = scmd->uscsi_bufaddr; - aiov.iov_len = scmd->uscsi_buflen; - uio->uio_iov = &aiov; - - uio->uio_iovcnt = 1; - uio->uio_resid = scmd->uscsi_buflen; - uio->uio_segflg = dataspace; - uio->uio_offset = 0; - uio->uio_fmode = 0; - - /* - * Let physio do the rest... - */ - bp->b_private = (void *) scmd; - err = physio(sst_strategy, bp, dev, rw, minphys, uio); - } else { - /* - * No data transfer, we can call sst_strategy directly - */ - bp->b_private = (void *) scmd; - bp->b_flags = B_BUSY | rw; - bp->b_edev = dev; - bp->b_bcount = bp->b_blkno = 0; - (void) sst_strategy(bp); - err = biowait(bp); - } - - /* - * get the status block, if any, and - * release any resources that we had. - */ - scmd->uscsi_status = 0; - scmd->uscsi_status = SCBP_C(targ->targ_pkt); - - /* - * Lock the targ struct. Clearing the 'busy' flag and signalling - * must be made atomic. - */ - mutex_enter(SST_MUTEX(targ)); /* LOCK the targ struct */ - if (targ->targ_pkt != NULL) - scsi_destroy_pkt(targ->targ_pkt); - targ->targ_sbuf_busy = 0; - cv_signal(&targ->targ_sbuf_cv); /* release the special buffer */ - targ->targ_pkt_busy = 0; - cv_signal(&targ->targ_pkt_cv); /* release the packet */ - mutex_exit(SST_MUTEX(targ)); /* UNLOCK the targ struct */ - - kmem_free(scmd->uscsi_cdb, (size_t)scmd->uscsi_cdblen); - scmd->uscsi_cdb = user_cdbp; /* restore the user's pointer */ - return (err); -} - - -/* - * Check to see if the unit will respond to a Test Unit Ready - * Returns true or false - */ -static int -sst_unit_ready(dev_t dev) -{ - auto struct uscsi_cmd scmd, *com = &scmd; - auto char cmdblk[CDB_GROUP0]; - auto int err; - - com->uscsi_bufaddr = 0; - com->uscsi_buflen = 0; - bzero(cmdblk, CDB_GROUP0); - cmdblk[0] = (char)SCMD_TEST_UNIT_READY; - com->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT|USCSI_WRITE; - com->uscsi_cdb = cmdblk; - com->uscsi_cdblen = CDB_GROUP0; - com->uscsi_timeout = sst_io_time; - - if (err = sst_ioctl_cmd(dev, com, UIO_SYSSPACE, UIO_SYSSPACE, 0)) { - SST_LOG(0, SST_CE_DEBUG1, "sst_unit_ready failed: 0x%x\n", err); - return (0); - } - return (1); -} - - -/* - * Done with a command. - * Start the next command and then call biodone() to tell physio or - * sst_ioctl_cmd that this i/o has completed. - * - */ -static void -sst_done(struct scsi_target *targ, register struct buf *bp) -{ - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "sst_done\n"); - - /* - * Lock the targ struct; we don't want targ_pkt to change - * between taking a copy of it and zeroing it. - */ - mutex_enter(SST_MUTEX(targ)); - - /* - * For regular commands (i.e. not using the special buffer), - * free resources and clear the current request. Sst_ioctl_cmd - * will do its own freeing for special commands. We need the lock - * here because targ_pkt must not change during the operations. - */ - if (bp != targ->targ_sbufp) { - scsi_destroy_pkt(targ->targ_pkt); - targ->targ_pkt_busy = 0; - cv_signal(&targ->targ_pkt_cv); - } - - mutex_exit(SST_MUTEX(targ)); /* UNLOCK the targ struct */ - - /* - * Tell interested parties that the i/o is done - */ - biodone(bp); - pm_idle_component(SST_DEVINFO(targ), 0); -} - - -/* - * Allocate resources for a SCSI command - call scsi_init_pkt to get - * a packet and allocate DVMA resources, and create the SCSI CDB. - * - * Also used to continue an in-progress packet; simply calls scsi_init_pkt - * to update the DMA resources to the next chunk, and re-creates the - * SCSI command. - * - * Note: There are differences in the DMA subsystem between the SPARC - * and x86 platforms. For example, on the x86 platform, DMA uses - * physical rather than virtual addresses as a result the DMA buffer - * may not be contiguous. - * - * Because of these differences, the system may not be able to fully - * satisfy a DMA allocation request from the target driver with resources - * attached to one packet. As a solution, the scsi_init_pkt() routine - * should be called with the PKT_DMA _PARTIAL flag to allow the system - * to break up the DMA request. If a single DMA allocation cannot be - * done, the HBA driver sets the pkt_resid in the scsi_pkt structure - * to the number of bytes of DMA resources it was able to allocate. - * The target driver needs to modify the SCSI command it places into - * the packet for transport to request the proper amount of data specified - * in pkt_resid. When the packet's completion routine is called, the - * process is repeated again. - * - */ -static struct scsi_pkt * -sst_make_cmd(struct scsi_target *targ, struct buf *bp, struct scsi_pkt *pkt) -{ - struct uscsi_cmd *scmd = (struct uscsi_cmd *)bp->b_private; - int tval, blkcnt; - u_int flags; - int pktalloc = 0; - struct sst_private *sstprivp; - - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, - "sst_make_cmd: block %d, count=%d\n", bp->b_blkno, bp->b_bcount); - - /* - * If called with pkt == NULL, this is first time, and we - * must allocate and initialize the packet - */ - if (pkt == (struct scsi_pkt *)NULL) - pktalloc = 1; - - flags = 0; - blkcnt = bp->b_bcount >> DEV_BSHIFT; - - if (bp != targ->targ_sbufp) { - /* - * Allocate a packet. - * ROUTE(targ) is shorthand for sd_address - * Note that if auto request sensing is enabled, we - * specify the status length to hold sense data if needed - */ - if (pktalloc) { - pkt = scsi_init_pkt(ROUTE(targ), - (struct scsi_pkt *)NULL, bp, - (bp->b_blkno + blkcnt > 0x1FFFFF || blkcnt > 0xFF) ? - CDB_GROUP1 : CDB_GROUP0, - targ->targ_arq ? - sizeof (struct scsi_arq_status) : 1, - sizeof (struct sst_private), PKT_DMA_PARTIAL, - SLEEP_FUNC, 0); - if (pkt == (struct scsi_pkt *)0) { - return (NULL); - } - } else { - /* - * Here we're simply calling scsi_init_pkt() for the - * next section of DMA resource for the current - * I/O request (in bp); we needn't worry about - * the associated lengths, or possible failure, - * since scsi_init_pkt() is just moving the DMA win - */ - pkt = scsi_init_pkt(ROUTE(targ), pkt, bp, 0, - targ->targ_arq ? - sizeof (struct scsi_arq_status) : 1, - sizeof (struct sst_private), - PKT_DMA_PARTIAL, NULL_FUNC, 0); - } - - SST_LOG(targ->targ_devp, SST_CE_DEBUG3, - "sst_make_cmd: pkt_resid: %d\n", pkt->pkt_resid); - - sstprivp = (struct sst_private *)pkt->pkt_private; - - if (pktalloc) { - sstprivp->priv_bp = bp; - sstprivp->priv_amtdone = 0; - sstprivp->priv_amt = bp->b_bcount - pkt->pkt_resid; - } - - sst_fill_cdb(pkt, targ, bp, flags); - pkt->pkt_flags = flags; - tval = sst_io_time; - } else { - /* - * All special command come through sst_ioctl_cmd, which - * uses the uscsi interface. Just need to get the CDB - * from scmd and plug it in. Still call scsi_setup_cdb because - * it fills in some of the pkt field for us. Its cdb - * manipulations will be overwritten by the bcopy. - */ - if (scmd->uscsi_flags & USCSI_SILENT) - flags |= FLAG_SILENT; - if (scmd->uscsi_flags & USCSI_DIAGNOSE) - flags |= FLAG_DIAGNOSE; - if (scmd->uscsi_flags & USCSI_ISOLATE) - flags |= FLAG_ISOLATE; - if (scmd->uscsi_flags & USCSI_NODISCON) - flags |= FLAG_NODISCON; - if (scmd->uscsi_flags & USCSI_NOPARITY) - flags |= FLAG_NOPARITY; - - if (pktalloc) { - pkt = scsi_init_pkt(ROUTE(targ), - (struct scsi_pkt *)NULL, - bp->b_bcount ? bp : 0, - scmd->uscsi_cdblen, - targ->targ_arq ? - sizeof (struct scsi_arq_status) : 1, - sizeof (struct sst_private), PKT_DMA_PARTIAL, - SLEEP_FUNC, 0); - if (!pkt) { - return (NULL); - } - } else { - pkt = scsi_init_pkt(ROUTE(targ), pkt, - bp->b_bcount ? bp : 0, 0, - targ->targ_arq ? - sizeof (struct scsi_arq_status) : 1, - sizeof (struct sst_private), - PKT_DMA_PARTIAL, NULL_FUNC, 0); - } - - sstprivp = (struct sst_private *)pkt->pkt_private; - if (pktalloc) { - sstprivp->priv_bp = bp; - sstprivp->priv_amtdone = 0; - sstprivp->priv_amt = bp->b_bcount - pkt->pkt_resid; - } - - (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp, - scmd->uscsi_cdb[0], 0, 0, 0); - - bcopy(scmd->uscsi_cdb, pkt->pkt_cdbp, - scmd->uscsi_cdblen); - tval = scmd->uscsi_timeout; - - /* a timeout of 0 (ie. no timeout) is bad practice */ - if (tval == 0) { - tval = sst_io_time; - } - } - - pkt->pkt_comp = sst_callback; - pkt->pkt_time = tval; - -#ifdef SST_DEBUG - if (sst_debug > 2) { - hex_print("sst_make_cmd, CDB", pkt->pkt_cdbp, 6); - } -#endif SST_DEBUG - - return (pkt); -} - - -/* - * Stuff CDB with SCSI command for current I/O request - */ - -static void -sst_fill_cdb(struct scsi_pkt *pkt, struct scsi_target *targ, struct buf *bp, - u_int flags) -{ - struct sst_private *sstprivp; - u_int blkno, len; - u_int com; - - if ((scsi_options & SCSI_OPTIONS_DR) == 0) - flags |= FLAG_NODISCON; - - sstprivp = (struct sst_private *)(pkt->pkt_private); - - blkno = bp->b_blkno + (sstprivp->priv_amtdone >> DEV_BSHIFT); - /* use result of scsi_init_pkt() as I/O length */ - len = sstprivp->priv_amt; /* pkt->pkt_resid; */ - - SST_LOG(targ->targ_devp, SST_CE_DEBUG3, - "sst_fill_cdb: blkno %x len %x\n", blkno, len); - /* - * Note: We use the group 0 Read/Write commands here - * unless the starting block number or blocks - * requested is too large. - * If your device needs different commands for normal - * data transfer (e.g. Send/Receive, read/write buffer), - * change it here. - */ - - if ((blkno + (len >> DEV_BSHIFT) > 0x1FFFFF) || - ((len >> DEV_BSHIFT) > 0xFF)) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG3, - "sst_make_cmd: using g1 command\n"); - com = (bp->b_flags & B_READ) ? SCMD_READ_G1 : SCMD_WRITE_G1; - } else { - com = (bp->b_flags & B_READ) ? SCMD_READ : SCMD_WRITE; - } - - /* - * Note: The CDB creation differs for sequential and - * direct access devices. We do both here, but - * you should need only one. For sequential access, - * we assume a fixed 512 byte block size. If you - * have a variable block size device, ask for the - * actual number of bytes wanted, and change the last - * parameter, 'fixbit' (1) to zero. - */ - if (targ->targ_devp->sd_inq->inq_dtype == DTYPE_SEQUENTIAL) { - blkno = 0; - } - - (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp, - com, blkno, len >> DEV_BSHIFT, 0); - pkt->pkt_flags = flags; - - if (targ->targ_devp->sd_inq->inq_dtype == DTYPE_SEQUENTIAL) { - ((union scsi_cdb *)(pkt->pkt_cdbp))->t_code = 1; - } -} - - -/* - * ----------------------------------------------------------------------------- - * Interrupt Service Routines - */ - -/* - * Restart a command - the device was either busy or not ready - */ -static void -sst_restart(caddr_t arg) -{ - struct scsi_target *targ = (struct scsi_target *)arg; - struct scsi_pkt *pkt; - struct buf *bp; - - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "sst_restart\n"); - - /* - * No need to lock the targ structure because any other threads - * will wait in sst_strategy for the packet. - */ - pkt = targ->targ_pkt; - bp = ((struct sst_private *)pkt->pkt_private)->priv_bp; - - if (bp) { - struct scsi_pkt *pkt = targ->targ_pkt; - - if (pkt->pkt_flags & FLAG_SENSING) { - pkt = targ->targ_rqs; - } - - SST_DUMP_CDB(targ, targ->targ_pkt, CDB_GROUP0); - - if (scsi_transport(pkt) != TRAN_ACCEPT) { - bp->b_resid = bp->b_bcount; - bioerror(bp, ENXIO); - sst_done(targ, bp); - } - } -} - - -/* - * Command completion processing, called by the host adapter driver - * when it's done with the command. - * No need for mutexes in this routine - there's only one active command - * at a time, anyone else wanting to send a command will wait in strategy - * until we call sst_done. - */ -static void -sst_callback(struct scsi_pkt *pkt) -{ - struct scsi_target *targ; - struct buf *bp; - int action; - struct sst_private *sstprivp; - - sstprivp = (struct sst_private *)pkt->pkt_private; - bp = sstprivp->priv_bp; - targ = ddi_get_soft_state(sst_state, getminor(bp->b_edev)); - - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, - "sst_callback: pkt_reason = 0x%x, pkt_flags = 0x%x, pkt_state = 0x%x\n", - pkt->pkt_reason, pkt->pkt_flags, pkt->pkt_state); - - mutex_enter(SST_MUTEX(targ)); - - if (pkt->pkt_reason != CMD_CMPLT) { - /* - * The command did not complete. Retry if possible. - */ - action = sst_handle_incomplete(targ); - } else if (targ->targ_arq && pkt->pkt_state & STATE_ARQ_DONE) { - /* - * The auto-rqsense happened, and the packet has a - * filled-in scsi_arq_status structure, pointed to by - * pkt_scbp. - */ - action = sst_handle_arq(pkt, targ, bp); - } else if (pkt->pkt_flags & FLAG_SENSING) { - /* - * We were running a REQUEST SENSE. Decode the - * sense data and decide what to do next. - */ - pkt = targ->targ_pkt; /* get the pkt for the orig command */ - pkt->pkt_flags &= ~FLAG_SENSING; - action = sst_handle_sense(targ, bp); - } else { - /* - * Command completed and we're not getting sense. Check - * for errors and decide what to do next. - */ - action = sst_check_error(targ, bp); - } - mutex_exit(SST_MUTEX(targ)); - - switch (action) { - case QUE_SENSE: - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Getting Sense\n"); - pkt->pkt_flags |= FLAG_SENSING; - ((struct sst_private *)targ->targ_rqs->pkt_private)-> - priv_bp = bp; - bzero(targ->targ_devp->sd_sense, SENSE_LENGTH); - SST_DUMP_CDB(targ, targ->targ_rqs, CDB_GROUP0); - if (scsi_transport(targ->targ_rqs) == TRAN_ACCEPT) { - break; - } - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "Request Sense transport failed\n"); - /*FALLTHROUGH*/ - case COMMAND_DONE_ERROR: - bp->b_resid = bp->b_bcount; - bioerror(bp, ENXIO); - /*FALLTHROUGH*/ - case COMMAND_DONE: - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Command Done\n"); - sst_done(targ, bp); - break; - - case QUE_COMMAND: - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Retrying Command\n"); - SST_DUMP_CDB(targ, targ->targ_pkt, CDB_GROUP0); - if (scsi_transport(targ->targ_pkt) != TRAN_ACCEPT) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "Retry transport failed\n"); - bp->b_resid = bp->b_bcount; - bioerror(bp, ENXIO); - sst_done(targ, bp); - return; - } - break; - case JUST_RETURN: - break; - - case CONTINUE_PKT: - /* - * Back from a chunk of a split-up bp. Do next chunk or - * finish up. - */ - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Continuing packet\n"); - (void) sst_make_cmd(targ, bp, pkt); - SST_DUMP_CDB(targ, pkt, CDB_GROUP0); - if (scsi_transport(pkt) != TRAN_ACCEPT) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "Command transport failedn"); - bp->b_resid = bp->b_bcount; - bioerror(bp, EIO); - biodone(bp); - pm_idle_component(SST_DEVINFO(targ), 0); - } - } - -} - - -/* - * Incomplete command handling. Figure out what to do based on - * how far the command did get. - */ -static int -sst_handle_incomplete(struct scsi_target *targ) -{ - register int rval = COMMAND_DONE_ERROR; - register struct scsi_pkt *pkt = targ->targ_pkt; - - if (!targ->targ_arq && pkt->pkt_flags & FLAG_SENSING) { - pkt = targ->targ_rqs; - } - - /* - * The target may still be running the command, - * so try and reset it, to get it into a known state. - * Note: This is forcible, there may be a more polite - * method for your device. - */ - if ((pkt->pkt_statistics & - (STAT_BUS_RESET|STAT_DEV_RESET|STAT_ABORTED)) == 0) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, "Aborting Command\n"); - mutex_exit(SST_MUTEX(targ)); - if (!(scsi_abort(ROUTE(targ), (struct scsi_pkt *)0))) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "Resetting Target\n"); - if (!(scsi_reset(ROUTE(targ), RESET_TARGET))) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "Resetting SCSI Bus\n"); - if (!scsi_reset(ROUTE(targ), RESET_ALL)) { - sst_log(targ->targ_devp, CE_WARN, - "SCSI bus reset failed\n"); - } - mutex_enter(SST_MUTEX(targ)); - return (COMMAND_DONE_ERROR); - } - } - mutex_enter(SST_MUTEX(targ)); - } - - /* - * If we were running a request sense, try it again if possible. - * Some devices can handle retries, others will not. - */ - if (pkt->pkt_flags & FLAG_SENSING) { - if (targ->targ_retry_ct++ < sst_retry_count) { - rval = QUE_SENSE; - } - } else if (targ->targ_retry_ct++ < sst_retry_count) { - rval = QUE_COMMAND; - } else { - rval = COMMAND_DONE_ERROR; - } - - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, "Cmd incomplete, %s\n", - (rval == COMMAND_DONE_ERROR) ? "giving up" : "retrying"); - - return (rval); -} - - -/* - * Decode sense data - */ -static int -sst_handle_sense(struct scsi_target *targ, struct buf *bp) -{ - struct scsi_pkt *rqpkt = targ->targ_rqs; - register rval = COMMAND_DONE_ERROR; - int level, amt; - - - if (SCBP(rqpkt)->sts_busy) { - if (targ->targ_retry_ct++ < sst_retry_count) { - (void) timeout(sst_restart, (caddr_t)targ, - SST_BSY_TIMEOUT); - rval = JUST_RETURN; - } - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, "Target Busy, %s\n", - (rval == JUST_RETURN) ? "restarting" : "giving up"); - return (rval); - } - - if (SCBP(rqpkt)->sts_chk) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, - "Check Condition on Request Sense!\n"); - return (rval); - } - - amt = SENSE_LENGTH - rqpkt->pkt_resid; - if ((rqpkt->pkt_state & STATE_XFERRED_DATA) == 0 || amt == 0) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "no sense data\n"); - return (rval); - } - - /* - * Now, check to see whether we got enough sense data to make any - * sense out if it (heh-heh). - */ - if (amt < SUN_MIN_SENSE_LENGTH) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, - "not enough sense data\n"); - return (rval); - } - - if (sst_debug > 2) { - hex_print("sst Sense Data", targ->targ_devp->sd_sense, - SENSE_LENGTH); - } - - /* - * Decode the sense data - * Note: We only looking at the sense key here. Most devices - * have unique additional sense codes & qualifiers, so - * it's often more useful to look at them instead. - * - */ - switch (targ->targ_devp->sd_sense->es_key) { - case KEY_NOT_READY: - /* - * If we get a not-ready indication, wait a bit and - * try it again, unless this is a special command with - * the 'fail on error' (FLAG_DIAGNOSE) option set. - */ - if ((bp == targ->targ_sbufp) && - (targ->targ_pkt->pkt_flags & FLAG_DIAGNOSE)) { - rval = COMMAND_DONE_ERROR; - level = SCSI_ERR_FATAL; - } else if (targ->targ_retry_ct++ < sst_retry_count) { - (void) timeout(sst_restart, (caddr_t)targ, - SST_BSY_TIMEOUT); - rval = JUST_RETURN; - level = SCSI_ERR_RETRYABLE; - } else { - rval = COMMAND_DONE_ERROR; - level = SCSI_ERR_FATAL; - } - break; - - case KEY_ABORTED_COMMAND: - case KEY_UNIT_ATTENTION: - rval = QUE_COMMAND; - level = SCSI_ERR_INFO; - break; - case KEY_RECOVERABLE_ERROR: - case KEY_NO_SENSE: - rval = COMMAND_DONE; - level = SCSI_ERR_RECOVERED; - break; - case KEY_HARDWARE_ERROR: - case KEY_MEDIUM_ERROR: - case KEY_MISCOMPARE: - case KEY_VOLUME_OVERFLOW: - case KEY_WRITE_PROTECT: - case KEY_BLANK_CHECK: - case KEY_ILLEGAL_REQUEST: - default: - rval = COMMAND_DONE_ERROR; - level = SCSI_ERR_FATAL; - break; - } - - /* - * If this was for a special command, check the options - */ - if (bp == targ->targ_sbufp) { - if ((rval == QUE_COMMAND) && - (targ->targ_pkt->pkt_flags & FLAG_DIAGNOSE)) { - rval = COMMAND_DONE_ERROR; - } - if (((targ->targ_pkt->pkt_flags & FLAG_SILENT) == 0) || - sst_debug) { - scsi_errmsg(targ->targ_devp, targ->targ_pkt, "sst", - level, bp->b_blkno, 0, sst_cmds, - targ->targ_devp->sd_sense); - } - } else if ((level >= sst_error_reporting) || sst_debug) { - scsi_errmsg(targ->targ_devp, targ->targ_pkt, "sst", - level, bp->b_blkno, 0, sst_cmds, targ->targ_devp->sd_sense); - } - - return (rval); -} - - -#define ARQP(pktp) ((struct scsi_arq_status *)((pktp)->pkt_scbp)) - -/* - * Decode auto-rqsense data - */ -static int -sst_handle_arq(struct scsi_pkt *pktp, struct scsi_target *targ, struct buf *bp) -{ - int level, amt, rval = COMMAND_DONE_ERROR; - - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Auto Request Sense done\n"); - - if (ARQP(pktp)->sts_rqpkt_status.sts_chk) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, - "Check Condition on Auto Request Sense!\n"); - return (rval); - } - - amt = SENSE_LENGTH - ARQP(pktp)->sts_rqpkt_resid; - if ((ARQP(pktp)->sts_rqpkt_state & STATE_XFERRED_DATA) == 0 || - amt == 0) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "no auto sense data\n"); - return (rval); - } - - /* - * Stuff the sense data pointer into sd_sense - */ - targ->targ_devp->sd_sense = &(ARQP(pktp)->sts_sensedata); - - /* - * Now, check to see whether we got enough sense data to make any - * sense out if it (heh-heh). - */ - if (amt < SUN_MIN_SENSE_LENGTH) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, - "not enough auto sense data\n"); - return (rval); - } - - if (sst_debug > 2) { - hex_print("sst Auto Sense Data", - &(ARQP(pktp)->sts_sensedata), SENSE_LENGTH); - } - - /* - * Decode the sense data - * Note: I'm only looking at the sense key here. Most devices - * have unique additional sense codes & qualifiers, so - * it's often more useful to look at them instead. - * - */ - switch (ARQP(pktp)->sts_sensedata.es_key) { - case KEY_NOT_READY: - /* - * If we get a not-ready indication, wait a bit and - * try it again, unless this is a special command with - * the 'fail on error' (FLAG_DIAGNOSE) option set. - */ - if ((bp == targ->targ_sbufp) && - (targ->targ_pkt->pkt_flags & FLAG_DIAGNOSE)) { - rval = COMMAND_DONE_ERROR; - level = SCSI_ERR_FATAL; - } else if (targ->targ_retry_ct++ < sst_retry_count) { - (void) timeout(sst_restart, (caddr_t)targ, - SST_BSY_TIMEOUT); - rval = JUST_RETURN; - level = SCSI_ERR_RETRYABLE; - } else { - rval = COMMAND_DONE_ERROR; - level = SCSI_ERR_FATAL; - } - break; - - case KEY_ABORTED_COMMAND: - case KEY_UNIT_ATTENTION: - rval = QUE_COMMAND; - level = SCSI_ERR_INFO; - break; - case KEY_RECOVERABLE_ERROR: - case KEY_NO_SENSE: - rval = COMMAND_DONE; - level = SCSI_ERR_RECOVERED; - break; - case KEY_HARDWARE_ERROR: - case KEY_MEDIUM_ERROR: - case KEY_MISCOMPARE: - case KEY_VOLUME_OVERFLOW: - case KEY_WRITE_PROTECT: - case KEY_BLANK_CHECK: - case KEY_ILLEGAL_REQUEST: - default: - rval = COMMAND_DONE_ERROR; - level = SCSI_ERR_FATAL; - break; - } - - /* - * If this was for a special command, check the options - */ - if (bp == targ->targ_sbufp) { - if ((rval == QUE_COMMAND) && - (targ->targ_pkt->pkt_flags & FLAG_DIAGNOSE)) { - rval = COMMAND_DONE_ERROR; - } - if (((targ->targ_pkt->pkt_flags & FLAG_SILENT) == 0) || - sst_debug) { - scsi_errmsg(targ->targ_devp, targ->targ_pkt, "sst", - level, bp->b_blkno, 0, sst_cmds, - targ->targ_devp->sd_sense); - } - } else if ((level >= sst_error_reporting) || sst_debug) { - scsi_errmsg(targ->targ_devp, targ->targ_pkt, "sst", - level, bp->b_blkno, 0, sst_cmds, targ->targ_devp->sd_sense); - } - - return (rval); -} - - -/* - * Command completion routine. Check the returned status of the - * command - */ -static int -sst_check_error(struct scsi_target *targ, struct buf *bp) -{ - struct scsi_pkt *pkt = targ->targ_pkt; - int action; - struct sst_private *sstprivp = (struct sst_private *)(pkt->pkt_private); - - if (SCBP(pkt)->sts_busy) { - /* - * Target was busy. If we're not out of retries, call - * timeout to restart in a bit; otherwise give up and - * reset the target. If the fail on error flag is - * set, give up immediately. - */ - int tval = (pkt->pkt_flags & FLAG_DIAGNOSE) ? 0 - : SST_BSY_TIMEOUT; - - if (SCBP(pkt)->sts_is) { - /* - * Implicit assumption here is that a device - * will only be reserved long enough to - * permit a single i/o operation to complete. - */ - tval = sst_io_time * drv_usectohz(1000000); - } - - if ((int)targ->targ_retry_ct++ < sst_retry_count) { - if (tval) { - (void) timeout(sst_restart, (caddr_t)targ, - tval); - action = JUST_RETURN; - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, - "Target busy, retrying\n"); - } else { - action = COMMAND_DONE_ERROR; - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, - "Target busy, no retries\n"); - } - } else { - /* - * WARNING: See the warning in sst_handle_incomplete - */ - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "Resetting Target\n"); - if (!scsi_reset(ROUTE(targ), RESET_TARGET)) { -#ifdef SCSI_BUS_RESET - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "Resetting SCSI Bus\n"); - if (!scsi_reset(ROUTE(targ), RESET_ALL)) { - sst_log(targ->targ_devp, CE_WARN, - "SCSI bus reset failed\n"); - } -#else SCSI_BUS_RESET - sst_log(targ->targ_devp, CE_WARN, - "Reset Target failed\n"); -#endif SCSI_BUS_RESET - } - action = COMMAND_DONE_ERROR; - } - } else if (SCBP(pkt)->sts_chk) { - action = QUE_SENSE; /* check condition - get sense */ - if (targ->targ_arq) { - SST_LOG(targ->targ_devp, SST_CE_DEBUG1, - "Check Condition with Auto Sense enabled!\n"); - } else { - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, - "Check Condition\n"); - } - } else { - targ->targ_retry_ct = 0; - SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Command Complete\n"); - /* - * pkt_resid will reflect, at this point, a residual - * of how many bytes were not transferred; a non-zero - * pkt_resid is an error. - */ - if (pkt->pkt_resid) { - action = COMMAND_DONE; - bp->b_resid += pkt->pkt_resid; - } else { - sstprivp->priv_amtdone += sstprivp->priv_amt; - if (sstprivp->priv_amtdone < bp->b_bcount) - action = CONTINUE_PKT; - else - action = COMMAND_DONE; - } - } - return (action); -} - - -/* - * ----------------------------------------------------------------------------- - * Error Message Data and Routines - */ - -/* - * Log a message to the console and/or syslog with cmn_err - */ -/*ARGSUSED*/ -static void -sst_log(struct scsi_device *devp, int level, const char *fmt, ...) -{ - auto char name[16]; - auto char buf[256]; - va_list ap; - - if (devp) { - (void) sprintf(name, "%s%d", ddi_get_name(devp->sd_dev), - ddi_get_instance(devp->sd_dev)); - } else { - (void) sprintf(name, "sst"); - } - - va_start(ap, fmt); - (void) vsprintf(buf, fmt, ap); - va_end(ap); - - switch (level) { - case CE_CONT: - case CE_NOTE: - case CE_WARN: - case CE_PANIC: - cmn_err(level, "%s:\t%s", name, buf); - break; - - case SST_CE_DEBUG4: if (sst_debug < 4) break; - /*FALLTHROUGH*/ - case SST_CE_DEBUG3: if (sst_debug < 3) break; - /*FALLTHROUGH*/ - case SST_CE_DEBUG2: if (sst_debug < 2) break; - /*FALLTHROUGH*/ - case SST_CE_DEBUG1: - /*FALLTHROUGH*/ - default: - cmn_err(CE_CONT, "^%s:\t%s", name, buf); - break; - } -} - -/* - * Print a readable error message - * Note: This uses the arrays 'sst_cmds' and 'sst_errors' defined in - * this file. - */ - -#define BUFSZ 256 - -/* - * Print a buffer readably - */ -static void -hex_print(char *msg, void *cptr, int len) -{ - int i = 0, j; - char buf[BUFSZ]; - char *cp = cptr; - - bzero(buf, BUFSZ); - for (i = 0; i < len; i++) { - /* - * make sure there's room for longest %x (i.e., 8 for - * a negative number) plus space (1) plus zero (1) - */ - if ((j = strlen(buf)) >= (BUFSZ - 10)) { - buf[BUFSZ-2] = '>'; - buf[BUFSZ-1] = 0; - break; /* cp too long, give up */ - } - (void) sprintf(&buf[j], "%x ", cp[i]); - } - cmn_err(CE_CONT, "^%s: %s\n", msg, buf); -} - -static void -sst_dump_cdb(struct scsi_target *tgt, struct scsi_pkt *pkt, int cdblen) -{ - static char hex[] = "0123456789abcdef"; - char buf [256]; - u_char *cdb; - char *p; - int i; - - (void) sprintf(buf, "CDB = ["); - p = &buf[strlen(buf)]; - cdb = pkt->pkt_cdbp; - for (i = 0; i < cdblen; i++, cdb++) { - if (i > 0) - *p++ = ' '; - *p++ = hex[(*cdb >> 4) & 0x0f]; - *p++ = hex[*cdb & 0x0f]; - } - *p++ = ']'; - *p++ = '\n'; - *p = 0; - sst_log(tgt->targ_devp, CE_CONT, buf); -} diff --git a/contrib/sst/sst.conf b/contrib/sst/sst.conf deleted file mode 100644 index 989d9d9..0000000 --- a/contrib/sst/sst.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 1992,1997, by Sun Microsystems, Inc. -# All rights reserved. -# -# "@(#)sst.conf 1.5 97/09/14 SMI" -# -# Hardware Configuration file for sst, a Simple SCSI Target driver -# If you have more than one device attached, add more lines for the -# extra target/lun combinations (see sd.conf for an example) -# - -name="sst" class="scsi" target=5 lun=0; - -# For attaching sst to a specific target: -# name="sst" -# parent="/iommu@f,e0000000/sbus@f,e0001000/espdma@f,400000/esp@f,800000" -# target=4 lun=0; - -# -# For targets which support a logical unit number other than zero, -# change the lun field as appropriate, or for multiple logical -# unit numbers per target, add entries as follows: -# -# name="sst" class="scsi" target=5 lun=1; -# diff --git a/contrib/sst/sst_def.h b/contrib/sst/sst_def.h deleted file mode 100644 index d4bbc85..0000000 --- a/contrib/sst/sst_def.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 1997, by Sun Microsystems, Inc. - * All Rights Reserved - */ - -/* - * This file is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify this file without charge, but are not authorized to - * license or distribute it to anyone else except as part of a product - * or program developed by the user. - * - * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * This file is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even - * if Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -/* - * Defines and structures used only within the driver, sst.c - */ - -#ifndef _SST_DEF_H -#define _SST_DEF_H - -#pragma ident "@(#)sst_def.h 1.13 97/10/02 SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_KERNEL) || defined(_KMEMUSER) - -#include - -/* - * Driver compile options - */ - -/* - * This driver does not reset the SCSI bus. Instead we just give up - * and complain if the target hangs. If the bus is really stuck, one - * of the Sun drivers (e.g. sd) will reset it. If you decide that - * your device is critical and you should in fact reset the bus in - * this driver, turn on this define below: -#define SCSI_BUS_RESET - */ - -/* - * Local definitions, for clarity of code - */ -#define SST_DEVINFO(t) (((t)->targ_devp)->sd_dev) -#define SST_MUTEX(t) (&((t)->targ_devp)->sd_mutex) -#define ROUTE(t) (&((t)->targ_devp)->sd_address) - -#define SCBP(pkt) ((struct scsi_status *)(pkt)->pkt_scbp) -#define SCBP_C(pkt) ((*(pkt)->pkt_scbp) & STATUS_MASK) -#define CDBP(pkt) ((union scsi_cdb *)(pkt)->pkt_cdbp) - -#define SST_CE_DEBUG1 ((1 << 8) | CE_CONT) -#define SST_CE_DEBUG2 ((2 << 8) | CE_CONT) -#define SST_CE_DEBUG3 ((3 << 8) | CE_CONT) -#define SST_CE_DEBUG4 ((4 << 8) | CE_CONT) -#define SST_LOG if (sst_debug) sst_log -#define SST_DEBUG_ENTER if (sst_debug) debug_enter - - -/* - * Private info for scsi targets. - * - * Pointed to by the un_private pointer - * of one of the SCSI_DEVICE structures. - */ -struct scsi_target { - struct scsi_pkt *targ_rqs; /* ptr to request sense command pkt */ - struct scsi_pkt *targ_pkt; /* ptr to current command pkt */ - struct buf *targ_sbufp; /* for use in special io */ - kcondvar_t targ_sbuf_cv; /* conditional variable for sbufp */ - kcondvar_t targ_pkt_cv; /* conditional variable for pkt */ - kcondvar_t targ_suspend_cv; /* conditional variable for */ - /* suspended state */ - int targ_sbuf_busy; /* Wait Variable */ - int targ_pkt_busy; /* Wait Variable */ - int targ_retry_ct; /* retry count */ - u_int targ_state; /* current state */ - u_int targ_arq; /* ARQ mode on this tgt */ - struct scsi_device *targ_devp; /* back pointer to SCSI_DEVICE */ - struct buf *targ_rqbp; /* buf for Request Sense packet */ - int targ_suspended; /* suspend/resume */ - int targ_pm_suspended; /* power management suspend */ - int targ_power_level; /* PM power level */ -}; - -_NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, scsi_target)) - -struct sst_private { - struct buf *priv_bp; /* bp associated with this packet */ - /* - * To handle partial DMA mappings, target may need several - * SCSI commands to satisfy packet. Keep track of remaining - * data in this packet in the following two fields. - */ - u_int priv_amt; /* bytes requested in this chunk */ - u_int priv_amtdone; /* bytes done so far in current pkt */ -}; - -_NOTE(DATA_READABLE_WITHOUT_LOCK(scsi_target::{targ_devp targ_rqs - targ_state targ_sbufp targ_arq})) - -_NOTE(SCHEME_PROTECTS_DATA("stable data", - scsi_device)) - -_NOTE(SCHEME_PROTECTS_DATA("Unshared data", - scsi_target::targ_pkt scsi_arq_status scsi_status - buf scsi_pkt sst_private uio uscsi_cmd scsi_cdb)) - -/* - * Driver states - */ -#define SST_STATE_NIL 0 -#define SST_STATE_CLOSED 1 -#define SST_STATE_OPEN 2 - -/* - * Parameters - */ - -#define SST_IO_TIME 30 /* default command timeout, 30sec */ - -/* - * 5 seconds is what we'll wait if we get a Busy Status back - */ -#define SST_BSY_TIMEOUT (drv_usectohz(5 * 1000000)) - -/* - * Number of times we'll retry a normal operation. - * - * This includes retries due to transport failure - * (need to distinguish between Target and Transport failure) - */ -#define SST_RETRY_COUNT 30 - -/* - * sst_callback action codes - */ -#define COMMAND_DONE 0 -#define COMMAND_DONE_ERROR 1 -#define QUE_COMMAND 2 -#define QUE_SENSE 3 -#define JUST_RETURN 4 -#define CONTINUE_PKT 5 - -/* - * Special pkt flag just for this driver. - * NB: Other pkt_flags defines are in scsi_pkt.h. - */ -#define FLAG_SENSING 0x0400 /* Running request sense for failed pkt */ - -#endif /* defined(_KERNEL) || defined(_KMEMUSER) */ - -/* - * Ioctl commands - */ -#define SSTIOC ('S' << 8) -#define SSTIOC_READY (SSTIOC|0) /* Send a Test Unit Ready command */ -#define SSTIOC_ERRLEV (SSTIOC|1) /* Set Error Reporting level */ - - - -#if defined(_SYSCALL32) - -/* - * This is an example of how to support a 32-bit application issuing - * an ILP32 ioctl into a 64-bit driver. Using fixed data-size - * types, define a 32-bit version of the data structure as used - * by the ioctl, along with functions or macros to convert between - * the ILP32 and LP64 models. The LP64 driver can then use - * ddi_copyin/ddi_copyout to access the application's copy of - * the data structure, but internally use the usual ILP32 or - * LP64 model, as compiled. - */ -struct sst_uscsi_cmd32 { - int uscsi_flags; /* read, write, etc. see below */ - short uscsi_status; /* resulting status */ - short uscsi_timeout; /* Command Timeout */ - caddr32_t uscsi_cdb; /* cdb to send to target */ - caddr32_t uscsi_bufaddr; /* i/o source/destination */ - size32_t uscsi_buflen; /* size of i/o to take place */ - size32_t uscsi_resid; /* resid from i/o operation */ - u_char uscsi_cdblen; /* # of valid cdb bytes */ - u_char uscsi_rqlen; /* size of uscsi_rqbuf */ - u_char uscsi_rqstatus; /* status of request sense cmd */ - u_char uscsi_rqresid; /* resid of request sense cmd */ - caddr32_t uscsi_rqbuf; /* request sense buffer */ - caddr32_t uscsi_reserved_5; /* Reserved for Future Use */ -}; - - -/* - * Convert application's ILP32 uscsi_cmd to LP64 - */ -#define sst_uscsi_cmd32touscsi_cmd(u32, ucmd) \ - ucmd->uscsi_flags = u32->uscsi_flags; \ - ucmd->uscsi_status = u32->uscsi_status; \ - ucmd->uscsi_timeout = u32->uscsi_timeout; \ - ucmd->uscsi_cdb = (caddr_t)u32->uscsi_cdb; \ - ucmd->uscsi_bufaddr = (caddr_t)u32->uscsi_bufaddr; \ - ucmd->uscsi_buflen = (size_t)u32->uscsi_buflen; \ - ucmd->uscsi_resid = (size_t)u32->uscsi_resid; \ - ucmd->uscsi_cdblen = u32->uscsi_cdblen; \ - ucmd->uscsi_rqlen = u32->uscsi_rqlen; \ - ucmd->uscsi_rqstatus = u32->uscsi_rqstatus; \ - ucmd->uscsi_rqresid = u32->uscsi_rqresid; \ - ucmd->uscsi_rqbuf = (caddr_t)u32->uscsi_rqbuf; \ - ucmd->uscsi_reserved_5 = (void *)u32->uscsi_reserved_5; - - -/* - * Convert drivers's LP64 uscsi_cmd back to IPL32 - */ -#define sst_uscsi_cmdtouscsi_cmd32(ucmd, u32) \ - u32->uscsi_flags = ucmd->uscsi_flags; \ - u32->uscsi_status = ucmd->uscsi_status; \ - u32->uscsi_timeout = ucmd->uscsi_timeout; \ - u32->uscsi_cdb = (caddr32_t)ucmd->uscsi_cdb; \ - u32->uscsi_bufaddr = (caddr32_t)ucmd->uscsi_bufaddr; \ - u32->uscsi_buflen = (size32_t)ucmd->uscsi_buflen; \ - u32->uscsi_resid = (size32_t)ucmd->uscsi_resid; \ - u32->uscsi_cdblen = ucmd->uscsi_cdblen; \ - u32->uscsi_rqlen = ucmd->uscsi_rqlen; \ - u32->uscsi_rqstatus = ucmd->uscsi_rqstatus; \ - u32->uscsi_rqresid = ucmd->uscsi_rqresid; \ - u32->uscsi_rqbuf = (caddr32_t)ucmd->uscsi_rqbuf; \ - u32->uscsi_reserved_5 = (caddr32_t)ucmd->uscsi_reserved_5; - -#endif /* _SYSCALL32 */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SST_DEF_H */ diff --git a/contrib/sst/sstest.c b/contrib/sst/sstest.c deleted file mode 100644 index 4cc1365..0000000 --- a/contrib/sst/sstest.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 1992,1997 Sun Microsystems, Inc. All Rights Reserved. - * Sun considers its source code as an unpublished, proprietary - * trade secret, and it is available only under strict license - * provisions. This copyright notice is placed here only to protect - * Sun in the event the source is deemed a published work. - * Disassembly, decompilation, or other means of reducing the - * object code to human readable form is prohibited by the license - * agreement under which this code is provided to the user or - * company in possession of this copy. - * - * RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the - * Government is subject to restrictions as set forth in - * subparagraph (c)(1)(ii) of the Rights in Technical Data and - * Computer Software clause at DFARS 52.227-7013 and in similar - * clauses in the FAR and NASA FAR Supplement. - * - * These examples are provided with no warranties of any kind, - * including without limitation accuracy and usefulness, and Sun - * expressly disclaims all implied warranties of merchantability, - * fitness for a particular purpose and non-infringement. In no - * event shall Sun be liable for any damages, including without - * limitation, direct, special, indirect, or consequential damages - * arising out of, or relating to, use of these examples by customer - * or any third party. Sun is under no obligation to provide support - * to customer for this software. - * - * sstest.c - * A simple tst program for the sample SCSI target driver. - * To compile: cc (or acc) sstest.c -o sstest - * Note: the full ANSI conformance flag, -Xt, fails because of the - * system header files. - * - * Usage: - * sstest [device] [command] [arg] - * Device is the /devices entry - * Command can be: - * open - just open and close the device - * read [arg] - read a block. If arg is specifed, printf the result - * write [arg] - write a block. With arg, write "arg" - * rew - send the SCSI Rewind command (tests the USCSICMD ioctl) - * tur - send the SCSI Test Unit Ready command (SSTIOC_READY ioctl) - * errlev [lev] - set the error reporting level to (see sst_def.h) - */ - -#pragma ident "@(#)sstest.c 1.4 97/04/07 SMI" - -#include -#include -#include -#include -#include -#include "sst_def.h" - -#define BUFSZ 512 - -static void usage(char *name); - -main(int argc, char *argv[]) -{ - int fd, nbytes, level, arg; - char buf[BUFSZ], *progname, *devname, *command, *value; - struct uscsi_cmd scmd; - - if ((argc != 3) && (argc != 4)) { - usage(argv[0]); - /*NOTREACHED*/ - } - - progname = argv[0]; /* name of this program */ - devname = argv[1]; /* full path of device name */ - command = argv[2]; /* command to do */ - value = argv[3]; /* command's argument if present */ - arg = (argc == 4); /* command has arg */ - - - - (void) sprintf(buf, "%s", devname); - if ((fd = open(buf, O_RDWR)) == -1) { - perror(buf); - exit(1); - /*NOTREACHED*/ - } - - (void) memset((void *)buf, 0, BUFSZ); - - if (strcmp(command, "open") == 0) { - fprintf(stdout, "Device opened\n"); - } else if (strcmp(command, "read") == 0) { - if ((nbytes = read(fd, buf, BUFSZ)) != BUFSZ) { - perror("read"); - (void) close(fd); - exit(1); - /*NOTREACHED*/ - } - if (argc == 4) { - fprintf(stdout, "Read \"%s\"\n", buf); - } else { - fprintf(stdout, "Read %d bytes\n", nbytes); - } - - } else if (strcmp(command, "write") == 0) { - if (arg) { - strcpy(buf, value); - } - if ((nbytes = write(fd, buf, BUFSZ)) != BUFSZ) { - perror("write"); - (void) close(fd); - exit(1); - /*NOTREACHED*/ - } - fprintf(stdout, "Wrote %d bytes\n", nbytes); - - } else if (strcmp(command, "rew") == 0) { - (void) memset((void *) &scmd, 0, sizeof (scmd)); - scmd.uscsi_flags = 0; - scmd.uscsi_timeout = 30; - buf[0] = SCMD_REWIND; - scmd.uscsi_cdb = buf; - scmd.uscsi_bufaddr = NULL; - scmd.uscsi_buflen = 0; - scmd.uscsi_cdblen = CDB_GROUP0; - - if (ioctl(fd, USCSICMD, &scmd) == -1) { - perror("rewind ioctl"); - (void) close(fd); - exit(1); - /*NOTREACHED*/ - } - fprintf(stdout, "Device rewound, status = 0x%x\n", - scmd.uscsi_status); - } else if (strcmp(command, "errlev") == 0) { - if (argc != 4) { - usage(progname); - /*NOTREACHED*/ - } else if ((level = atoi(value)) == 0) { - fprintf(stderr, "Bad error level %s\n", value); - exit(1); - } - - if (ioctl(fd, SSTIOC_ERRLEV, &level) == -1) { - perror("Set error level ioctl"); - (void) close(fd); - exit(1); - /*NOTREACHED*/ - } - } else if (strcmp(command, "tur") == 0) { - if (ioctl(fd, SSTIOC_READY, NULL) == -1) { - perror("Ready ioctl"); - (void) close(fd); - exit(1); - /*NOTREACHED*/ - } - fprintf(stdout, "Device is ready\n"); - } else { - fprintf(stderr, "Unknown command: %s\n", command); - usage(progname); - /*NOTREACHED*/ - } - - (void) close(fd); - exit(0); -} - -static void -usage(char *name) -{ - (void) fprintf(stderr, "Usage: %s: [device] [command]\n", name); - (void) fprintf(stderr, "Device is the full path name of device\n"); - (void) fprintf(stderr, "Command is one of:\n"); - (void) fprintf(stderr, "\topen - just open & close\n"); - (void) fprintf(stderr, "\tread - read a block\n"); - (void) fprintf(stderr, "\twrite - write a block\n"); - (void) fprintf(stderr, "\trew - send the SCSI 'rewind' command\n"); - (void) fprintf(stderr, "\terrlev [lev] - Set the error " - "reporting level\n"); - (void) fprintf(stderr, "\ttur - send the SCSI 'test unit ready'" - "command\n"); - exit(1); - /*NOTREACHED*/ -} diff --git a/docs/amanda-client.conf.5.txt b/docs/amanda-client.conf.5.txt index 2444dc8..49dcc76 100644 --- a/docs/amanda-client.conf.5.txt +++ b/docs/amanda-client.conf.5.txt @@ -13,6 +13,8 @@ DESCRIPTION amanda-client.conf is the client configuration file for Amanda. This manpage lists the relevant sections and parameters of this file for quick reference. +The files /amanda-client.conf and //amanda- +client.conf are loaded. PARAMETERS @@ -104,6 +106,14 @@ PARAMETERS private key. If this parameter is not specified, then the deafult ssh key will be used. + gnutar_list_dir string + Default from configure --with-gnutar-listdir=DIR. The directory where + gnutar keep its state file. + + amandates string + Default: /etc/amandates. The file where amanda keep the last date of each + dumplevel. + AUTHOR diff --git a/docs/amanda.8.txt b/docs/amanda.8.txt index 6572c62..5d143b8 100644 --- a/docs/amanda.8.txt +++ b/docs/amanda.8.txt @@ -234,7 +234,7 @@ work instead of defining a new dumptype: hostname diskname [ diskdevice ] { normal - holdingdisk no + holdingdisk never } [ spindle [ interface ] ] diff --git a/docs/amanda.conf.5.txt b/docs/amanda.conf.5.txt index bf94e87..f19acc4 100644 --- a/docs/amanda.conf.5.txt +++ b/docs/amanda.conf.5.txt @@ -13,6 +13,7 @@ DESCRIPTION amanda.conf is the main configuration file for Amanda. This manpage lists the relevant sections and parameters of this file for quick reference. +The file //amanda.conf is loaded. PARAMETERS @@ -308,13 +309,28 @@ The dumptype options and values are: the actual file used would be /var/.amanda.excludes for a backup of /var, /usr/local/.amanda.excludes for a backup of /usr/local, and so on. - holdingdisk boolean - Default: yes. Whether a holding disk should be used for these backups or + holdingdisk [ never|auto|required] ] + Default: auto. Whether a holding disk should be used for these backups or whether they should go directly to tape. If the holding disk is a portion of another file system that Amanda is backing up, that file system should - refer to a dumptype with holdingdisk set to no to avoid backing up the + refer to a dumptype with holdingdisk set to never to avoid backing up the holding disk into itself. + + never|no|false|off + Never use a holdingdisk, the dump will always go directly to tape. + There will be no dump if you have a tape error. + + auto|yes|true|on + Use the holding disk, unless there is a problem with the holding + disk, the dump won't fit there or the medium doesn't require + spooling (e.g., VFS device) + + required + Always dump to holdingdisk, never directly to tape. There will be + no dump if it doesn't fit on holdingdisk + + ignore boolean Default: no. Whether disks associated with this backup type should be backed up or not. This option is useful when the disklist file is shared diff --git a/docs/amcheck.8.txt b/docs/amcheck.8.txt index 91bcb32..7ce680a 100644 --- a/docs/amcheck.8.txt +++ b/docs/amcheck.8.txt @@ -34,7 +34,8 @@ OPTIONS Run the tape server local and tape checks (same as -lt). -c - Run the client host checks. + Run the client host checks.Multiple specific clients can be checked by + specifying the client name. -l Run the local tests (e.g. permissions) on the server host. diff --git a/docs/amcleanup.8.txt b/docs/amcleanup.8.txt index 8bb79bc..c09e7b3 100644 --- a/docs/amcleanup.8.txt +++ b/docs/amcleanup.8.txt @@ -21,6 +21,14 @@ for some reason (usually because of a tape server host crash), amcleanup must be run some time later (usually during system boot). See the amanda(8) man page for more details about Amanda. +OPTIONS + + + + -k + Kill all Amanda processes. + + EXAMPLES This example runs the Amanda cleanup process by hand after a failure. diff --git a/docs/amcrypt-asym-ossl.8.txt b/docs/amcrypt-asym-ossl.8.txt index 5d287b4..711be5c 100644 --- a/docs/amcrypt-asym-ossl.8.txt +++ b/docs/amcrypt-asym-ossl.8.txt @@ -27,14 +27,14 @@ GENERATING PUBLIC AND PRIVATE KEYS RSA keys can be generated with the standard OpenSSL commands, e.g.: $ cd /var/lib/amanda - $ openssl genrsa -aes128 -out backup-key.pem 1024 + $ openssl genrsa -aes128 -out backup-privkey.pem 1024 Generating RSA private key, 1024 bit long modulus [...] - Enter pass phrase for backup-key.pem: ENTER YOUR PASS PHRASE + Enter pass phrase for backup-privkey.pem: ENTER YOUR PASS PHRASE Verifying - Enter pass phrase for backup-key.pem: ENTER YOUR PASS PHRASE - $ openssl rsa -in backup-key.pem -pubout -out backup-pubkey.pem - Enter pass phrase for backup-key.pem: ENTER YOUR PASS PHRASE + $ openssl rsa -in backup-privkey.pem -pubout -out backup-pubkey.pem + Enter pass phrase for backup-privkey.pem: ENTER YOUR PASS PHRASE Writing RSA key To generate a private key without a passphrase, omit the -aes128 option. See @@ -71,8 +71,8 @@ FILES /var/lib/amanda/backup-pubkey.pem File containing the RSA public key. - /var/lib/amanda/.pass - File containing the pass phrase. It should not be readable by any user + /var/lib/amanda/.am_passphrase + File containing the passphrase. It should not be readable by any user other than the Amanda user. diff --git a/docs/amgetconf.8.txt b/docs/amgetconf.8.txt index 2282127..b6ea3f6 100644 --- a/docs/amgetconf.8.txt +++ b/docs/amgetconf.8.txt @@ -66,8 +66,7 @@ MESSAGES amgetconf: no such parameter param Parameter param is not a known keyword (e.g. not a valid amanda.conf - keyword). In this case, amgetconf will write "BUGGY" to stdout as the - value. + keyword). SEE ALSO diff --git a/docs/amtapetype.8.txt b/docs/amtapetype.8.txt index 4e726a4..7813ddd 100644 --- a/docs/amtapetype.8.txt +++ b/docs/amtapetype.8.txt @@ -10,7 +10,7 @@ amtapetype  generate a tapetype definition. Synopsis -amtapetype [-h ] [-c ] [-o ] [-b blocksize] [-e estsize] [-f tapedev] [- +amtapetype [-h ] [-c ] [-o ] [-b blocksize] -e estsize [-f tapedev] [- t typename] DESCRIPTION @@ -35,7 +35,7 @@ OPTIONS record block size (default: 32k) -eestsize - estimated tape size (default: 1g == 1024m) + estimated tape size (No default!) -ftapedev tape device name (default: $TAPE) The device to perform the test. @@ -48,7 +48,7 @@ EXAMPLE Generate a tapetype definition for your tape device: -% amtapetype -f /dev/nst0 +% amtapetype -f /dev/nst0 -e 150G NOTES diff --git a/docs/howto-auth.txt b/docs/howto-auth.txt index 9699de6..6e3ffc5 100644 --- a/docs/howto-auth.txt +++ b/docs/howto-auth.txt @@ -155,8 +155,7 @@ For security reason, you must prepend the line with the following: That will limit that key to connect only from your server and only be able to execute amandad. Like rsh if your server username and client username are different, you must -add the client_username option in all DLE for that -host: +add the client_username option in all DLE for that host: client_username "client_username" diff --git a/restore-src/amfetchdump.c b/restore-src/amfetchdump.c index f3b282f..d1f2b7c 100644 --- a/restore-src/amfetchdump.c +++ b/restore-src/amfetchdump.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: amfetchdump.c,v 1.16 2006/08/24 01:57:15 paddy_s Exp $ + * $Id: amfetchdump.c,v 1.16.2.1 2006/09/27 12:04:09 martinea Exp $ * * retrieves specific dumps from a set of amanda tapes */ @@ -491,7 +491,7 @@ main( */ if(rst_flags->inventory_log){ fprintf(stderr, "Beginning tape-by-tape search.\n"); - search_tapes(stderr, 1, NULL, match_list, rst_flags, NULL); + search_tapes(stderr, stdin, 1, NULL, match_list, rst_flags, NULL); exit(0); } @@ -505,7 +505,7 @@ main( if(get_lock == 0) { error("%s exists: amdump or amflush is already running, or you must run amcleanup", rst_conf_logfile); } - search_tapes(NULL, 1, needed_tapes, match_list, rst_flags, NULL); + search_tapes(NULL, stdin, 1, needed_tapes, match_list, rst_flags, NULL); cleanup(); free_match_list(match_list); diff --git a/restore-src/amidxtaped.c b/restore-src/amidxtaped.c index 54dcfa1..93d9350 100644 --- a/restore-src/amidxtaped.c +++ b/restore-src/amidxtaped.c @@ -23,7 +23,7 @@ * Authors: the Amanda Development Team. Its members are listed in a * file named AUTHORS, in the root directory of this distribution. */ -/* $Id: amidxtaped.c,v 1.73 2006/07/25 19:06:46 martinea Exp $ +/* $Id: amidxtaped.c,v 1.73.2.1 2006/09/27 12:04:09 martinea Exp $ * * This daemon extracts a dump image off a tape for amrecover and * returns it over the network. It basically, reads a number of @@ -60,8 +60,9 @@ static am_feature_t *their_features = NULL; static g_option_t *g_options = NULL; static int ctlfdin, ctlfdout, datafdout; static char *amandad_auth = NULL; +static FILE *cmdin, *cmdout; -static char *get_client_line(void); +static char *get_client_line(FILE *in); static void check_security_buffer(char *); static char *get_client_line_fd(int); @@ -73,7 +74,7 @@ int main(int argc, char **argv); /* get a line from client - line terminated by \r\n */ static char * -get_client_line(void) +get_client_line(FILE *in) { static char *line = NULL; char *part = NULL; @@ -81,7 +82,7 @@ get_client_line(void) amfree(line); while(1) { - if((part = agets(stdin)) == NULL) { + if((part = agets(in)) == NULL) { if(errno != 0) { dbprintf(("%s: read error: %s\n", debug_prefix_time(NULL), strerror(errno))); @@ -239,7 +240,6 @@ main( char *their_feature_string = NULL; rst_flags_t *rst_flags; int use_changer = 0; - FILE *prompt_stream = NULL; int re_end; char *re_config = NULL; char *conf_tapetype; @@ -353,7 +353,10 @@ main( /* do the security thing */ amfree(buf); - buf = stralloc(get_client_line()); + fflush(stdout); + cmdout = stdout; + cmdin = stdin; + buf = stralloc(get_client_line(cmdin)); check_security_buffer(buf); } else { @@ -390,10 +393,16 @@ main( printf("CONNECT CTL %d DATA %d\n", DATA_FD_OFFSET, DATA_FD_OFFSET+1); printf("\n"); fflush(stdout); - fflush(stdin); - if ((dup2(ctlfdout, fileno(stdout)) < 0) - || (dup2(ctlfdin, fileno(stdin)) < 0)) { - error("amandad: Failed to setup stdin or stdout"); + fclose(stdin); + fclose(stdout); + cmdout = fdopen(ctlfdout, "a"); + if (!cmdout) { + error("amidxtaped: Can't fdopen(ctlfdout): %s", strerror(errno)); + /*NOTREACHED*/ + } + cmdin = fdopen(ctlfdin, "r"); + if (!cmdin) { + error("amidxtaped: Can't fdopen(ctlfdin): %s", strerror(errno)); /*NOTREACHED*/ } } @@ -408,7 +417,7 @@ main( for (re_end = 0; re_end == 0; ) { amfree(buf); - buf = stralloc(get_client_line()); + buf = stralloc(get_client_line(cmdin)); if(strncmp(buf, "LABEL=", 6) == 0) { tapes = unmarshal_tapelist_str(buf+6); } @@ -426,10 +435,10 @@ main( amfree(their_feature_string); our_feature_string = am_feature_to_string(our_features); if(from_amandad == 1) - printf("FEATURES=%s\r\n", our_feature_string); + fprintf(cmdout,"FEATURES=%s\r\n", our_feature_string); else - printf("%s", our_feature_string); - fflush(stdout); + fprintf(cmdout,"%s", our_feature_string); + fflush(cmdout); amfree(our_feature_string); } else if(strncmp(buf, "DEVICE=", 7) == 0) { @@ -532,7 +541,6 @@ main( if(am_has_feature(their_features, fe_recover_splits)) { if(from_amandad == 1) { rst_flags->pipe_to_fd = datafdout; - prompt_stream = stdout; } else { int data_fd; @@ -563,12 +571,11 @@ main( check_security_buffer(buf); rst_flags->pipe_to_fd = data_fd; - prompt_stream = stdout; } } else { rst_flags->pipe_to_fd = fileno(stdout); - prompt_stream = stderr; + cmdout = stderr; } dbprintf(("%s: Sending output to file descriptor %d\n", get_pname(), rst_flags->pipe_to_fd)); @@ -579,7 +586,7 @@ main( (use_changer || (rst_flags->alt_tapedev && strcmp(rst_flags->alt_tapedev, getconf_str(CNF_TAPEDEV)) == 0) ) ) { - send_message(prompt_stream, rst_flags, their_features, + send_message(cmdout, rst_flags, their_features, "%s exists: amdump or amflush is already running, " "or you must run amcleanup", rst_conf_logfile); @@ -592,13 +599,13 @@ main( if (check_rst_flags(rst_flags) == -1) { if (rst_flags->pipe_to_fd != -1) aclose(rst_flags->pipe_to_fd); - send_message(prompt_stream, rst_flags, their_features, + send_message(cmdout, rst_flags, their_features, "restore flags are crazy"); exit(1); } /* actual restoration */ - search_tapes(prompt_stream, use_changer, tapes, match_list, rst_flags, + search_tapes(cmdout, cmdin, use_changer, tapes, match_list, rst_flags, their_features); dbprintf(("%s: Restoration finished\n", debug_prefix_time(NULL))); diff --git a/restore-src/restore.c b/restore-src/restore.c index da4e5f7..0e05169 100644 --- a/restore-src/restore.c +++ b/restore-src/restore.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: restore.c,v 1.52 2006/08/23 11:41:54 martinea Exp $ + * $Id: restore.c,v 1.52.2.2 2006/09/27 14:04:27 martinea Exp $ * * retrieves files from an amanda tape */ @@ -98,7 +98,7 @@ char *label_of_current_slot(char *cur_tapedev, FILE *prompt_out, int load_next_tape(char **cur_tapedev, FILE *prompt_out, int backwards, rst_flags_t *flags, am_feature_t *their_features, tapelist_t *desired_tape); -int load_manual_tape(char **cur_tapedev, FILE *prompt_out, +int load_manual_tape(char **cur_tapedev, FILE *prompt_out, FILE *prompt_in, rst_flags_t *flags, am_feature_t *their_features, tapelist_t *desired_tape); void search_a_tape(char *cur_tapedev, FILE *prompt_out, rst_flags_t *flags, @@ -1349,6 +1349,7 @@ int load_manual_tape( char **cur_tapedev, FILE *prompt_out, + FILE *prompt_in, rst_flags_t *flags, am_feature_t *their_features, tapelist_t *desired_tape) @@ -1363,7 +1364,7 @@ load_manual_tape( fprintf(prompt_out, "FEEDME %s\r\n", desired_tape->label); fflush(prompt_out); - input = agets(stdin);/* Strips \n but not \r */ + input = agets(prompt_in);/* Strips \n but not \r */ if(!input) { error("Connection lost with amrecover"); /*NOTREACHED*/ @@ -1672,6 +1673,7 @@ search_a_tape( void search_tapes( FILE * prompt_out, + FILE *prompt_in, int use_changer, tapelist_t * tapelist, match_list_t * match_list, @@ -1690,10 +1692,11 @@ search_tapes( seentapes_t *seentapes = NULL; int ret; - dbprintf(("search_tapes(prompt=%p, use_changer=%d, tapelist=%p, " + dbprintf(("search_tapes(prompt_out=%d, prompt_in=%d, use_changer=%d, " + "tapelist=%p, " "match_list=%p, flags=%p, features=%p)\n", - prompt_out, use_changer, tapelist, match_list, - flags, their_features)); + fileno(prompt_out), fileno(prompt_in), use_changer, tapelist, + match_list, flags, their_features)); if(!prompt_out) prompt_out = stderr; @@ -1759,7 +1762,7 @@ search_tapes( char *input = NULL; fprintf(prompt_out,"Press enter when ready\n"); fflush(prompt_out); - input = agets(stdin); + input = agets(prompt_in); amfree(input); fprintf(prompt_out, "\n"); fflush(prompt_out); @@ -1841,7 +1844,7 @@ search_tapes( } if (label == NULL) { - ret = load_manual_tape(&cur_tapedev, prompt_out, + ret = load_manual_tape(&cur_tapedev, prompt_out, prompt_in, flags, their_features, desired_tape); if (ret == 0) { diff --git a/restore-src/restore.h b/restore-src/restore.h index 06cdadf..70868d1 100644 --- a/restore-src/restore.h +++ b/restore-src/restore.h @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: restore.h,v 1.8 2006/06/22 17:16:39 martinea Exp $ + * $Id: restore.h,v 1.8.2.1 2006/09/27 12:04:09 martinea Exp $ * * */ @@ -75,9 +75,9 @@ ssize_t read_file_header(dumpfile_t *file, int tapefd, int isafile, ssize_t restore(dumpfile_t *file, char *filename, int tapefd, int isafile, rst_flags_t *flags); void flush_open_outputs(int reassemble, dumpfile_t *only_file); -void search_tapes(FILE *prompt_out, int use_changer, tapelist_t *tapelist, - match_list_t *restorethese, rst_flags_t *flags, - am_feature_t *their_features); +void search_tapes(FILE *prompt_out, FILE *prompt_in, int use_changer, + tapelist_t *tapelist, match_list_t *restorethese, + rst_flags_t *flags, am_feature_t *their_features); int have_all_parts(dumpfile_t *file, int upto); rst_flags_t *new_rst_flags(void); int check_rst_flags(rst_flags_t *flags); diff --git a/server-src/amcheck.c b/server-src/amcheck.c index 9e83962..2ccaf54 100644 --- a/server-src/amcheck.c +++ b/server-src/amcheck.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: amcheck.c,v 1.149 2006/08/24 01:57:16 paddy_s Exp $ + * $Id: amcheck.c,v 1.149.2.2 2006/09/21 11:16:57 martinea Exp $ * * checks for common problems in server and clients */ @@ -764,7 +764,7 @@ start_server_check( } else if(stat(tapefile, &statbuf) == -1) { quoted = quote_string(tape_dir); - fprintf(outf, "ERROR: tapefile %s (%s), " + fprintf(outf, "ERROR: tapelist %s (%s), " "you must create an empty file.\n", quoted, strerror(errno)); tapebad = 1; @@ -772,24 +772,24 @@ start_server_check( } else if(!S_ISREG(statbuf.st_mode)) { quoted = quote_string(tapefile); - fprintf(outf, "ERROR: tapefile %s: should be a regular file.\n", + fprintf(outf, "ERROR: tapelist %s: should be a regular file.\n", quoted); tapebad = 1; amfree(quoted); } else if(access(tapefile, F_OK) != 0) { quoted = quote_string(tapefile); - fprintf(outf, "ERROR: can't access tape list %s\n", quoted); + fprintf(outf, "ERROR: can't access tapelist %s\n", quoted); tapebad = 1; amfree(quoted); } else if(access(tapefile, F_OK) == 0 && access(tapefile, W_OK) != 0) { quoted = quote_string(tapefile); - fprintf(outf, "ERROR: tape list %s: not writable\n", quoted); + fprintf(outf, "ERROR: tapelist %s: not writable\n", quoted); tapebad = 1; amfree(quoted); } else if(read_tapelist(tapefile)) { quoted = quote_string(tapefile); - fprintf(outf, "ERROR: tape list %s: parse error\n", quoted); + fprintf(outf, "ERROR: tapelist %s: parse error\n", quoted); tapebad = 1; amfree(quoted); } @@ -840,6 +840,11 @@ start_server_check( quoted, (OFF_T_FMT_TYPE)holdingdisk_get_disksize(hdp)); disklow = 1; } + else if(holdingdisk_get_disksize(hdp) == (off_t)0) { + fprintf(outf, "WARNING: holding disk %s: " + "use nothing because 'use' is set to 0\n", + quoted); + } else if(holdingdisk_get_disksize(hdp) > (off_t)0) { if(fs.avail < holdingdisk_get_disksize(hdp)) { fprintf(outf, @@ -855,14 +860,17 @@ start_server_check( else { fprintf(outf, "Holding disk %s: " OFF_T_FMT - " %sB disk space available, that's plenty\n", - quoted, (OFF_T_FMT_TYPE)(fs.avail/(off_t)unitdivisor), + " %sB disk space available," + " using " OFF_T_FMT " %sB as requested\n", + quoted, + (OFF_T_FMT_TYPE)(fs.avail/(off_t)unitdivisor), + displayunit, + (OFF_T_FMT_TYPE)(holdingdisk_get_disksize(hdp)/(off_t)unitdivisor), displayunit); } } else { - assert(holdingdisk_get_disksize(hdp) < (off_t)0); - if((fs.avail + holdingdisk_get_disksize(hdp)) <= (off_t)0) { + if((fs.avail + holdingdisk_get_disksize(hdp)) < (off_t)0) { fprintf(outf, "WARNING: holding disk %s: " "only " OFF_T_FMT " %sB free, using nothing\n", diff --git a/server-src/amindexd.c b/server-src/amindexd.c index 96e2483..34587d4 100644 --- a/server-src/amindexd.c +++ b/server-src/amindexd.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: amindexd.c,v 1.106 2006/07/25 18:27:57 martinea Exp $ + * $Id: amindexd.c,v 1.106.2.2 2006/09/27 12:04:09 martinea Exp $ * * This is the server daemon part of the index client/server system. * It is assumed that this is launched from inetd instead of being @@ -92,6 +92,8 @@ static int process_ls_dump(char *, DUMP_ITEM *, int, char **); static size_t reply_buffer_size = 1; static char *reply_buffer = NULL; static char *amandad_auth = NULL; +static FILE *cmdin; +static FILE *cmdout; static void reply(int, char *, ...) __attribute__ ((format (printf, 2, 3))); @@ -295,7 +297,7 @@ printf_arglist_function1(static void reply, int, n, char *, fmt) len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args); arglist_end(args); - if (len > -1 && (size_t)len < reply_buffer_size) + if (len > -1 && (size_t)len < reply_buffer_size-1) break; reply_buffer_size *= 2; @@ -303,14 +305,14 @@ printf_arglist_function1(static void reply, int, n, char *, fmt) reply_buffer = alloc(reply_buffer_size); } - if (printf("%03d %s\r\n", n, reply_buffer) < 0) + if (fprintf(cmdout,"%03d %s\r\n", n, reply_buffer) < 0) { dbprintf(("%s: ! error %d (%s) in printf\n", debug_prefix_time(NULL), errno, strerror(errno))); uncompress_remove = remove_files(uncompress_remove); exit(1); } - if (fflush(stdout) != 0) + if (fflush(cmdout) != 0) { dbprintf(("%s: ! error %d (%s) in fflush\n", debug_prefix_time(NULL), errno, strerror(errno))); @@ -334,7 +336,7 @@ printf_arglist_function1(static void lreply, int, n, char *, fmt) len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args); arglist_end(args); - if (len > -1 && (size_t)len < reply_buffer_size) + if (len > -1 && (size_t)len < reply_buffer_size-1) break; reply_buffer_size *= 2; @@ -342,14 +344,14 @@ printf_arglist_function1(static void lreply, int, n, char *, fmt) reply_buffer = alloc(reply_buffer_size); } - if (printf("%03d-%s\r\n", n, reply_buffer) < 0) + if (fprintf(cmdout,"%03d-%s\r\n", n, reply_buffer) < 0) { dbprintf(("%s: ! error %d (%s) in printf\n", debug_prefix_time(NULL), errno, strerror(errno))); uncompress_remove = remove_files(uncompress_remove); exit(1); } - if (fflush(stdout) != 0) + if (fflush(cmdout) != 0) { dbprintf(("%s: ! error %d (%s) in fflush\n", debug_prefix_time(NULL), errno, strerror(errno))); @@ -375,7 +377,7 @@ printf_arglist_function1(static void fast_lreply, int, n, char *, fmt) len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args); arglist_end(args); - if (len > -1 && (size_t)len < reply_buffer_size) + if (len > -1 && (size_t)len < reply_buffer_size-1) break; reply_buffer_size *= 2; @@ -383,7 +385,7 @@ printf_arglist_function1(static void fast_lreply, int, n, char *, fmt) reply_buffer = alloc(reply_buffer_size); } - if (printf("%03d-%s\r\n", n, reply_buffer) < 0) + if (fprintf(cmdout,"%03d-%s\r\n", n, reply_buffer) < 0) { dbprintf(("%s: ! error %d (%s) in printf\n", debug_prefix_time(NULL), errno, strerror(errno))); @@ -1177,6 +1179,8 @@ main( remote_hostname = newstralloc(remote_hostname, fp); s[-1] = (char)ch; amfree(fp); + cmdout = stdout; + cmdin = stdin; } else { cmdfdout = DATA_FD_OFFSET + 0; @@ -1211,9 +1215,18 @@ main( printf("\n"); fflush(stdin); fflush(stdout); - if ((dup2(cmdfdout, fileno(stdout)) < 0) - || (dup2(cmdfdin, fileno(stdin)) < 0)) { - error("amandad: Failed to setup stdin or stdout"); + fclose(stdin); + fclose(stdout); + + cmdout = fdopen(cmdfdout, "a"); + if (!cmdout) { + error("amindexd: Can't fdopen(cmdfdout): %s", strerror(errno)); + /*NOTREACHED*/ + } + + cmdin = fdopen(cmdfdin, "r"); + if (!cmdin) { + error("amindexd: Can't fdopen(cmdfdin): %s", strerror(errno)); /*NOTREACHED*/ } } @@ -1241,7 +1254,7 @@ main( { /* get a line from the client */ while(1) { - if((part = agets(stdin)) == NULL) { + if((part = agets(cmdin)) == NULL) { if(errno != 0) { dbprintf(("%s: ? read error: %s\n", debug_prefix_time(NULL), strerror(errno))); diff --git a/server-src/amstatus.pl.in b/server-src/amstatus.pl.in index e4ad2aa..f95d33c 100644 --- a/server-src/amstatus.pl.in +++ b/server-src/amstatus.pl.in @@ -717,20 +717,22 @@ while() { %free = split (/ +/, $2); %qlen = split (/ +/, $5); - if($status_driver ne "") { - $dumpers_active[$dumpers_active_prev] - +=$current_time-$state_time_prev; - $dumpers_held[$dumpers_active_prev]{$status_driver} - +=$current_time-$state_time_prev; - } - $state_time_prev=$current_time; - $dumpers_active_prev=$dumpers_active; - $status_driver=$6; - if(! defined($dumpers_held[$dumpers_active]{$status_driver})) { - $dumpers_held[$dumpers_active]{$status_driver}=0; + if(defined($dumpers_active)) { + if($status_driver ne "") { + $dumpers_active[$dumpers_active_prev] + +=$current_time-$state_time_prev; + $dumpers_held[$dumpers_active_prev]{$status_driver} + +=$current_time-$state_time_prev; + } + $state_time_prev=$current_time; + $dumpers_active_prev=$dumpers_active; + $status_driver=$6; + if(! defined($dumpers_held[$dumpers_active]{$status_driver})) { + $dumpers_held[$dumpers_active]{$status_driver}=0; + } } } - elsif(/taper: wrote label `(\S*)'/) { + elsif(/taper: .*wrote label `(\S*)'/) { $nb_tape++; $ntlabel{$nb_tape} = $1; $ntpartition{$nb_tape} = 0; diff --git a/server-src/amtoc.pl.in b/server-src/amtoc.pl.in index d250102..f32075a 100644 --- a/server-src/amtoc.pl.in +++ b/server-src/amtoc.pl.in @@ -166,7 +166,7 @@ while ( <$IF> ) { $level = $6; switch: { /START taper/ && do { - $tocfilename=&tfn($level) if ($#subs >= 0); + $tocfilename=&tfn($chunk) if ($#subs >= 0); if (!$tocfilename || ($tocfilename eq '-')) {$OF=STDOUT;} else { die ("Cannot open tocfile $tocfilename") unless open(OF,">$tocfilename"); diff --git a/server-src/changer.c b/server-src/changer.c index 02519c5..0d2898c 100644 --- a/server-src/changer.c +++ b/server-src/changer.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: changer.c,v 1.36 2006/08/24 01:57:16 paddy_s Exp $ + * $Id: changer.c,v 1.36.2.1 2006/09/27 14:04:27 martinea Exp $ * * interface routines for tape changers */ @@ -331,6 +331,7 @@ changer_command( char num2[NUM_STR_SIZE]; char *cmdstr; pid_t pid, changer_pid = 0; + int fd_to_close[4], *pfd_to_close = fd_to_close; if (*tapechanger != '/') { tapechanger = vstralloc(libexecdir, "/", tapechanger, versionsuffix(), @@ -360,12 +361,21 @@ changer_command( goto failed; } - /* make sure fd[0] != 1 */ - if(fd[0] == 1) { + /* make sure fd[0] > 2 && fd[1] > 2 */ + pfd_to_close = fd_to_close; + while(fd[0] <= 2) { int a = dup(fd[0]); - close(fd[0]); + *pfd_to_close++ = fd[0]; fd[0] = a; } + while(fd[1] <= 2) { + int a = dup(fd[1]); + *pfd_to_close++ = fd[1]; + fd[1] = a; + } + while (pfd_to_close > fd_to_close) { + close(*--pfd_to_close); + } if(fd[0] < 0 || fd[0] >= (int)FD_SETSIZE) { snprintf(num1, SIZEOF(num1), "%d", fd[0]); diff --git a/server-src/find.c b/server-src/find.c index 5a9310f..1b77150 100644 --- a/server-src/find.c +++ b/server-src/find.c @@ -25,7 +25,7 @@ * University of Maryland at College Park */ /* - * $Id: find.c,v 1.33 2006/07/06 13:13:15 martinea Exp $ + * $Id: find.c,v 1.33.2.1 2006/09/19 19:34:27 martinea Exp $ * * controlling process for the Amanda backup system */ @@ -782,7 +782,7 @@ search_logfile( filenum = (off_t)0; passlabel = 1; while(get_logline(logf) && passlabel) { - if((curlog == L_SUCCESS || curlog == L_CHUNK) && + if((curlog == L_SUCCESS || curlog == L_CHUNK || curlog == L_PARTIAL) && curprog == P_TAPER && passlabel){ filenum++; } @@ -796,7 +796,7 @@ search_logfile( } } partnum = "--"; - if(curlog == L_SUCCESS || curlog == L_FAIL || curlog == L_CHUNK) { + if(curlog == L_SUCCESS || curlog == L_PARTIAL || curlog == L_FAIL || curlog == L_CHUNK) { s = curstr; ch = *s++; @@ -889,6 +889,8 @@ search_logfile( new_output_find->filenum=filenum; if(curlog == L_SUCCESS || curlog == L_CHUNK) new_output_find->status=stralloc("OK"); + else if(curlog == L_PARTIAL) + new_output_find->status=stralloc("PARTIAL"); else new_output_find->status=stralloc(rest); *output_find=new_output_find; diff --git a/server-src/logfile.c b/server-src/logfile.c index c1d3e26..9741f43 100644 --- a/server-src/logfile.c +++ b/server-src/logfile.c @@ -25,7 +25,7 @@ * University of Maryland at College Park */ /* - * $Id: logfile.c,v 1.31 2006/06/01 14:54:39 martinea Exp $ + * $Id: logfile.c,v 1.31.2.1 2006/09/22 11:02:13 martinea Exp $ * * common log file writing routine */ @@ -104,6 +104,7 @@ printf_arglist_function2(char *log_genstring, logtype_t, typ, char *, pname, cha arglist_start(argp, format); vsnprintf(linebuf, SIZEOF(linebuf)-1, format, argp); /* -1 to allow for '\n' */ + arglist_end(argp); return(vstralloc(leader, linebuf, "\n", NULL)); } diff --git a/server-src/planner.c b/server-src/planner.c index caa6396..160b860 100644 --- a/server-src/planner.c +++ b/server-src/planner.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: planner.c,v 1.206 2006/08/10 23:57:27 paddy_s Exp $ + * $Id: planner.c,v 1.206.2.1 2006/09/27 11:24:39 martinea Exp $ * * backup schedule planner for the Amanda backup system. */ @@ -1736,6 +1736,7 @@ static void handle_result( && pkt->type == P_NAK && (strcmp(t - 1, "unknown service: noop") == 0 || strcmp(t - 1, "noop: invalid service") == 0)) { + skip_quoted_line(s, ch); continue; } errbuf = vstralloc(hostp->hostname, -- 2.30.2