4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * This file contains code to support better NFS error messages. Death to
29 * integer codes in user error messages!
31 * XXX Ideally this code should be more general and available to the entire
32 * kernel (see RFE 1101936). When this happens, this file can go away.
37 #include <sys/systm.h>
38 #include <sys/cmn_err.h>
39 #include <sys/errno.h>
40 #include <sys/varargs.h>
42 /* size of a temporary printf format buffer. */
43 #define FMT_BUF_SIZE 1024
45 static void expand_format_string(int, const char *, char *, int);
46 static char *nfs_strerror(int);
49 * nfs_perror: Works like printf (format string and variable args) except
50 * that it will substitute an error message for a "%m" string (like
51 * syslog), using the given errno value.
55 nfs_perror(int error
, char *fmt
, ...)
58 char buf
[FMT_BUF_SIZE
]; /* massaged version of fmt */
62 expand_format_string(error
, fmt
, buf
, FMT_BUF_SIZE
);
65 * Now pass the massaged format string and its arguments off to
70 (void) vzprintf(getzoneid(), buf
, ap
);
75 * nfs_cmn_err: Works like cmn_err (error level, format string, and
76 * variable args) except that it will substitute an error message for a
77 * "%m" string (like syslog), using the given errno value.
81 nfs_cmn_err(int error
, int level
, char *fmt
, ...)
84 char buf
[FMT_BUF_SIZE
]; /* massaged version of fmt */
88 expand_format_string(error
, fmt
, buf
, FMT_BUF_SIZE
);
91 * Now pass the massaged format string and its arguments off to
96 (void) vzcmn_err(getzoneid(), level
, buf
, ap
);
101 * expand_format_string: copy the printf format string from "fmt" to "buf",
102 * expanding %m to the error string for "error".
106 expand_format_string(int error
, const char *fmt
, char *buf
, int buf_chars
)
108 const char *from
; /* pointer into fmt */
109 char *to
; /* pointer into buf */
110 char *errmsg
; /* expansion for %m */
111 char *trunc_msg
= "Truncated NFS error message: ";
112 zoneid_t zoneid
= getzoneid();
115 * Copy the given format string into the result buffer, expanding
116 * %m as we go. If the result buffer is too short, complain and
117 * truncate the message. (We don't expect this to ever happen,
121 for (from
= fmt
, to
= buf
; *from
; from
++) {
122 if (to
>= buf
+ buf_chars
- 1) {
123 zprintf(zoneid
, trunc_msg
);
126 if (*from
== '%' && *(from
+1) == 'm') {
127 errmsg
= nfs_strerror(error
);
129 * If there's an error message and room to display
130 * it, copy it in. If there's no message or not
131 * enough room, try just printing an error number.
132 * (We assume that the error value is in a
133 * reasonable range.) If there's no room for
134 * anything, bail out.
136 if (errmsg
!= NULL
&&
137 strlen(buf
) + strlen(errmsg
) < buf_chars
) {
138 (void) strcpy(to
, errmsg
);
139 to
+= strlen(errmsg
);
140 } else if (strlen(buf
) + strlen("error XXX") <
142 (void) sprintf(to
, "error %d", error
);
144 * Don't try to guess how many characters
147 to
= buf
+ strlen(buf
);
149 zprintf(zoneid
, trunc_msg
);
161 * nfs_strerror: map an errno value to a string. Not all possible errno
162 * values are supported.
164 * If there is no string for the given errno value, return NULL.
168 nfs_strerror(int errcode
)
174 result
= "Not owner";
177 result
= "No such file or directory";
180 result
= "I/O error";
183 result
= "Permission denied";
186 result
= "File exists";
189 result
= "Not a directory";
192 result
= "Is a directory";
195 result
= "Invalid argument";
198 result
= "File too large";
201 result
= "No space left on device";
204 result
= "Read-only file system";
207 result
= "Disc quota exceeded";
210 result
= "Directory not empty";
213 result
= "Stale NFS file handle";
216 result
= "Not enough memory";