2 * error.c -- Common error handling functions
4 * Copyright (C) 2007 Oracle. All rights reserved.
5 * Copyright (C) 2007 Chuck Lever <chuck.lever@oracle.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public
18 * License along with this program; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 021110-1307, USA.
23 * + Proper support for internationalization
31 #include <sys/types.h>
44 #ifdef HAVE_RPCSVC_NFS_PROT_H
45 #include <rpcsvc/nfs_prot.h>
47 #include <linux/nfs.h>
48 #define nfsstat nfs_stat
51 extern char *progname;
53 static char errbuf[BUFSIZ];
54 static char *erreob = &errbuf[BUFSIZ];
56 /* Convert RPC errors into strings */
57 static int rpc_strerror(int spos)
59 int cf_stat = rpc_createerr.cf_stat;
60 int pos = 0, cf_errno = rpc_createerr.cf_error.re_errno;
61 char *ptr, *estr = clnt_sperrno(cf_stat);
65 if ((ptr = index(estr, ':')))
69 if (cf_stat == RPC_SYSTEMERROR)
70 pos = snprintf(tmp, (erreob - tmp),
71 _("System Error: %s"),
75 pos = snprintf(tmp, (erreob - tmp),
76 _("RPC Error:%s; errno = %s"),
77 estr, strerror(cf_errno));
79 pos = snprintf(tmp, (erreob - tmp),
80 _("RPC Error:%s"), estr);
87 * rpc_mount_errors - log an RPC error that occurred during a user-space mount
88 * @server: C string containing name of server we are attempting to mount
89 * @will_retry: one indicates mount will retry at some later point
90 * @bg: one indicates this is a background mount
92 * Extracts the error code from the user-space RPC library, and reports it
93 * on stderr (fg mount) or in the system log (bg mount).
95 void rpc_mount_errors(char *server, int will_retry, int bg)
99 static int onlyonce = 0;
103 pos = snprintf(tmp, (erreob - tmp),
104 _("mount to NFS server '%s' failed: "),
107 pos = snprintf(tmp, (erreob - tmp),
108 _("%s: mount to NFS server '%s' failed: "),
112 if (rpc_createerr.cf_stat == RPC_TIMEDOUT) {
114 pos = snprintf(tmp, (erreob - tmp),
115 _("timed out, retrying"));
117 pos = snprintf(tmp, (erreob - tmp),
118 _("timed out, giving up"));
120 pos += rpc_strerror(pos);
124 pos = snprintf(tmp, (erreob - tmp),
127 pos = snprintf(tmp, (erreob - tmp),
134 openlog("mount", LOG_CONS|LOG_PID, LOG_AUTH);
135 syslog(LOG_ERR, "%s", errbuf);
137 fprintf(stderr, "%s\n", errbuf);
141 * sys_mount_errors - log an error that occurred during a mount system call
142 * @server: C string containing name of server we are attempting to mount
143 * @error: errno value to report
144 * @will_retry: one indicates mount will retry at some later point
145 * @bg: one indicates this is a background mount
147 * Passed an errno value generated by a mount system call, and reports it
148 * on stderr (fg mount) or in the system log (bg mount).
150 void sys_mount_errors(char *server, int error, int will_retry, int bg)
154 static int onlyonce = 0;
158 pos = snprintf(tmp, (erreob - tmp),
159 _("mount to NFS server '%s' failed: "),
162 pos = snprintf(tmp, (erreob - tmp),
163 _("%s: mount to NFS server '%s' failed: "),
167 if (error == ETIMEDOUT) {
169 pos = snprintf(tmp, (erreob - tmp),
170 _("timed out, retrying"));
172 pos = snprintf(tmp, (erreob - tmp),
173 _("timed out, giving up"));
177 pos = snprintf(tmp, (erreob - tmp),
181 pos = snprintf(tmp, (erreob - tmp),
189 openlog("mount", LOG_CONS|LOG_PID, LOG_AUTH);
190 syslog(LOG_ERR, "%s", errbuf);
192 fprintf(stderr, "%s\n", errbuf);
196 * mount_error - report a foreground mount error
197 * @spec: C string containing the device name being mounted
198 * @mount_point: C string containing the pathname of the local mounted on dir
199 * @error: errno value to report
202 void mount_error(const char *spec, const char *mount_point, int error)
206 nfs_error(_("%s: access denied by server while mounting %s"),
210 nfs_error(_("%s: an incorrect mount option was specified"), progname);
213 nfs_error(_("%s: requested NFS version or transport"
214 " protocol is not supported"),
218 nfs_error(_("%s: mount point %s is not a directory"),
219 progname, mount_point);
222 nfs_error(_("%s: %s is busy or already mounted"),
223 progname, mount_point);
227 nfs_error(_("%s: mounting %s failed, "
228 "reason given by server:\n %s"),
229 progname, spec, strerror(error));
231 nfs_error(_("%s: mount point %s does not exist"),
232 progname, mount_point);
235 rpc_mount_errors((char *)spec, 0, 0);
238 nfs_error(_("%s: mount system call failed"), progname);
241 nfs_error(_("%s: encountered unexpected error condition."),
243 nfs_error(_("%s: please report the error to" PACKAGE_BUGREPORT),
247 nfs_error(_("%s: %s"),
248 progname, strerror(error));
253 * umount_error - report a failed umount request
254 * @err: errno value to report
255 * @dev: C string containing the pathname of the local mounted on dir
258 void umount_error(int err, const char *dev)
262 nfs_error(_("%s: %s: invalid block device"),
266 nfs_error(_("%s: %s: not mounted"),
270 nfs_error(_("%s: %s: can't write superblock"),
274 nfs_error(_("%s: %s: device is busy"),
278 nfs_error(_("%s: %s: not found"),
282 nfs_error(_("%s: %s: must be superuser to umount"),
286 nfs_error(_("%s: %s: block devices not permitted on fs"),
290 nfs_error(_("%s: %s: %s"),
291 progname, dev, strerror(err));
297 * We need to translate between nfs status return values and
298 * the local errno values which may not be the same.
300 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
301 * "after #include <errno.h> the symbol errno is reserved for any use,
302 * it cannot even be used as a struct tag or field name".
306 #define EDQUOT ENOSPC
309 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
316 { NFSERR_PERM, EPERM },
317 { NFSERR_NOENT, ENOENT },
319 { NFSERR_NXIO, ENXIO },
320 { NFSERR_ACCES, EACCES },
321 { NFSERR_EXIST, EEXIST },
322 { NFSERR_NODEV, ENODEV },
323 { NFSERR_NOTDIR, ENOTDIR },
324 { NFSERR_ISDIR, EISDIR },
326 { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
328 { NFSERR_FBIG, EFBIG },
329 { NFSERR_NOSPC, ENOSPC },
330 { NFSERR_ROFS, EROFS },
331 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
332 { NFSERR_NOTEMPTY, ENOTEMPTY },
333 { NFSERR_DQUOT, EDQUOT },
334 { NFSERR_STALE, ESTALE },
336 { NFSERR_WFLUSH, EWFLUSH },
338 /* Throw in some NFSv3 values for even more fun (HP returns these) */
342 char *nfs_strerror(unsigned int stat)
345 static char buf[256];
347 for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) {
348 if (nfs_errtbl[i].stat == stat)
349 return strerror(nfs_errtbl[i].errnum);
351 sprintf(buf, _("unknown nfs status return value: %u"), stat);