1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
5 * Author: Phil Schwan <phil@clusterfs.com>
7 * This file is part of Lustre, http://www.lustre.org.
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Darwin porting library
23 * Make things easy to port
25 #define DEBUG_SUBSYSTEM S_LNET
27 #include <mach/mach_types.h>
29 #include <sys/errno.h>
30 #include <sys/types.h>
31 #include <sys/fcntl.h>
32 #include <lnet/types.h>
34 #include <libcfs/libcfs.h>
40 return (c == ' ' || c == '\t' || c == '\n' || c == '\12');
44 char * strpbrk(const char * cs,const char * ct)
48 for( sc1 = cs; *sc1 != '\0'; ++sc1) {
49 for( sc2 = ct; *sc2 != '\0'; ++sc2) {
57 char * strsep(char **s, const char *ct)
59 char *sbegin = *s, *end;
63 end = strpbrk(sbegin, ct);
71 size_t strnlen(const char * s, size_t count)
75 for (sc = s; count-- && *sc != '\0'; ++sc)
81 strstr(const char *in, const char *str)
88 return (char *) in; // Trivial empty string case
97 } while (strncmp(in, str, len) != 0);
98 return (char *) (in - 1);
102 strrchr(const char *p, int ch)
104 const char *end = p + strlen(p);
106 if (*end == (char)ch)
108 } while (--end >= p);
113 ul2dstr(unsigned long address, char *buf, int len)
115 char *pos = buf + len - 1;
117 if (len <= 0 || !buf)
122 *--pos = address % 10 + '0';
129 * miscellaneous libcfs stuff
133 * Convert server error code to client format.
139 * cc /usr/include/asm/errno.h -E -dM | grep '#define E' | sort -n -k3,3
178 LINUX_ENAMETOOLONG = 36,
181 LINUX_ENOTEMPTY = 39,
212 LINUX_EMULTIHOP = 72,
215 LINUX_EOVERFLOW = 75,
229 LINUX_EDESTADDRREQ = 89,
231 LINUX_EPROTOTYPE = 91,
232 LINUX_ENOPROTOOPT = 92,
233 LINUX_EPROTONOSUPPORT = 93,
234 LINUX_ESOCKTNOSUPPORT = 94,
235 LINUX_EOPNOTSUPP = 95,
236 LINUX_EPFNOSUPPORT = 96,
237 LINUX_EAFNOSUPPORT = 97,
238 LINUX_EADDRINUSE = 98,
239 LINUX_EADDRNOTAVAIL = 99,
240 LINUX_ENETDOWN = 100,
241 LINUX_ENETUNREACH = 101,
242 LINUX_ENETRESET = 102,
243 LINUX_ECONNABORTED = 103,
244 LINUX_ECONNRESET = 104,
247 LINUX_ENOTCONN = 107,
248 LINUX_ESHUTDOWN = 108,
249 LINUX_ETOOMANYREFS = 109,
250 LINUX_ETIMEDOUT = 110,
251 LINUX_ECONNREFUSED = 111,
252 LINUX_EHOSTDOWN = 112,
253 LINUX_EHOSTUNREACH = 113,
254 LINUX_EALREADY = 114,
255 LINUX_EINPROGRESS = 115,
261 LINUX_EREMOTEIO = 121,
263 LINUX_ENOMEDIUM = 123,
264 LINUX_EMEDIUMTYPE = 124,
267 * we don't need these, but for completeness..
269 LINUX_EDEADLOCK = LINUX_EDEADLK,
270 LINUX_EWOULDBLOCK = LINUX_EAGAIN
273 int convert_server_error(__u64 ecode)
278 static int errno_xlate[] = {
279 /* success is always success */
281 [LINUX_EPERM] = EPERM,
282 [LINUX_ENOENT] = ENOENT,
283 [LINUX_ESRCH] = ESRCH,
284 [LINUX_EINTR] = EINTR,
286 [LINUX_ENXIO] = ENXIO,
287 [LINUX_E2BIG] = E2BIG,
288 [LINUX_ENOEXEC] = ENOEXEC,
289 [LINUX_EBADF] = EBADF,
290 [LINUX_ECHILD] = ECHILD,
291 [LINUX_EAGAIN] = EAGAIN,
292 [LINUX_ENOMEM] = ENOMEM,
293 [LINUX_EACCES] = EACCES,
294 [LINUX_EFAULT] = EFAULT,
295 [LINUX_ENOTBLK] = ENOTBLK,
296 [LINUX_EBUSY] = EBUSY,
297 [LINUX_EEXIST] = EEXIST,
298 [LINUX_EXDEV] = EXDEV,
299 [LINUX_ENODEV] = ENODEV,
300 [LINUX_ENOTDIR] = ENOTDIR,
301 [LINUX_EISDIR] = EISDIR,
302 [LINUX_EINVAL] = EINVAL,
303 [LINUX_ENFILE] = ENFILE,
304 [LINUX_EMFILE] = EMFILE,
305 [LINUX_ENOTTY] = ENOTTY,
306 [LINUX_ETXTBSY] = ETXTBSY,
307 [LINUX_EFBIG] = EFBIG,
308 [LINUX_ENOSPC] = ENOSPC,
309 [LINUX_ESPIPE] = ESPIPE,
310 [LINUX_EROFS] = EROFS,
311 [LINUX_EMLINK] = EMLINK,
312 [LINUX_EPIPE] = EPIPE,
314 [LINUX_ERANGE] = ERANGE,
315 [LINUX_EDEADLK] = EDEADLK,
316 [LINUX_ENAMETOOLONG] = ENAMETOOLONG,
317 [LINUX_ENOLCK] = ENOLCK,
318 [LINUX_ENOSYS] = ENOSYS,
319 [LINUX_ENOTEMPTY] = ENOTEMPTY,
320 [LINUX_ELOOP] = ELOOP,
321 [LINUX_ENOMSG] = ENOMSG,
322 [LINUX_EIDRM] = EIDRM,
323 [LINUX_ECHRNG] = EINVAL /* ECHRNG */,
324 [LINUX_EL2NSYNC] = EINVAL /* EL2NSYNC */,
325 [LINUX_EL3HLT] = EINVAL /* EL3HLT */,
326 [LINUX_EL3RST] = EINVAL /* EL3RST */,
327 [LINUX_ELNRNG] = EINVAL /* ELNRNG */,
328 [LINUX_EUNATCH] = EINVAL /* EUNATCH */,
329 [LINUX_ENOCSI] = EINVAL /* ENOCSI */,
330 [LINUX_EL2HLT] = EINVAL /* EL2HLT */,
331 [LINUX_EBADE] = EINVAL /* EBADE */,
332 [LINUX_EBADR] = EBADRPC,
333 [LINUX_EXFULL] = EINVAL /* EXFULL */,
334 [LINUX_ENOANO] = EINVAL /* ENOANO */,
335 [LINUX_EBADRQC] = EINVAL /* EBADRQC */,
336 [LINUX_EBADSLT] = EINVAL /* EBADSLT */,
337 [LINUX_EBFONT] = EINVAL /* EBFONT */,
338 [LINUX_ENOSTR] = EINVAL /* ENOSTR */,
339 [LINUX_ENODATA] = EINVAL /* ENODATA */,
340 [LINUX_ETIME] = EINVAL /* ETIME */,
341 [LINUX_ENOSR] = EINVAL /* ENOSR */,
342 [LINUX_ENONET] = EINVAL /* ENONET */,
343 [LINUX_ENOPKG] = EINVAL /* ENOPKG */,
344 [LINUX_EREMOTE] = EREMOTE,
345 [LINUX_ENOLINK] = EINVAL /* ENOLINK */,
346 [LINUX_EADV] = EINVAL /* EADV */,
347 [LINUX_ESRMNT] = EINVAL /* ESRMNT */,
348 [LINUX_ECOMM] = EINVAL /* ECOMM */,
349 [LINUX_EPROTO] = EPROTOTYPE,
350 [LINUX_EMULTIHOP] = EINVAL /* EMULTIHOP */,
351 [LINUX_EDOTDOT] = EINVAL /* EDOTDOT */,
352 [LINUX_EBADMSG] = EINVAL /* EBADMSG */,
353 [LINUX_EOVERFLOW] = EOVERFLOW,
354 [LINUX_ENOTUNIQ] = EINVAL /* ENOTUNIQ */,
355 [LINUX_EBADFD] = EINVAL /* EBADFD */,
356 [LINUX_EREMCHG] = EINVAL /* EREMCHG */,
357 [LINUX_ELIBACC] = EINVAL /* ELIBACC */,
358 [LINUX_ELIBBAD] = EINVAL /* ELIBBAD */,
359 [LINUX_ELIBSCN] = EINVAL /* ELIBSCN */,
360 [LINUX_ELIBMAX] = EINVAL /* ELIBMAX */,
361 [LINUX_ELIBEXEC] = EINVAL /* ELIBEXEC */,
362 [LINUX_EILSEQ] = EILSEQ,
363 [LINUX_ERESTART] = EINVAL /* because ERESTART is
364 * negative in XNU */,
365 [LINUX_ESTRPIPE] = EINVAL /* ESTRPIPE */,
366 [LINUX_EUSERS] = EUSERS,
367 [LINUX_ENOTSOCK] = ENOTSOCK,
368 [LINUX_EDESTADDRREQ] = EDESTADDRREQ,
369 [LINUX_EMSGSIZE] = EMSGSIZE,
370 [LINUX_EPROTOTYPE] = EPROTOTYPE,
371 [LINUX_ENOPROTOOPT] = ENOPROTOOPT,
372 [LINUX_EPROTONOSUPPORT] = EPROTONOSUPPORT,
373 [LINUX_ESOCKTNOSUPPORT] = ESOCKTNOSUPPORT,
374 [LINUX_EOPNOTSUPP] = EOPNOTSUPP,
375 [LINUX_EPFNOSUPPORT] = EPFNOSUPPORT,
376 [LINUX_EAFNOSUPPORT] = EAFNOSUPPORT,
377 [LINUX_EADDRINUSE] = EADDRINUSE,
378 [LINUX_EADDRNOTAVAIL] = EADDRNOTAVAIL,
379 [LINUX_ENETDOWN] = ENETDOWN,
380 [LINUX_ENETUNREACH] = ENETUNREACH,
381 [LINUX_ENETRESET] = ENETRESET,
382 [LINUX_ECONNABORTED] = ECONNABORTED,
383 [LINUX_ECONNRESET] = ECONNRESET,
384 [LINUX_ENOBUFS] = ENOBUFS,
385 [LINUX_EISCONN] = EISCONN,
386 [LINUX_ENOTCONN] = ENOTCONN,
387 [LINUX_ESHUTDOWN] = ESHUTDOWN,
388 [LINUX_ETOOMANYREFS] = ETOOMANYREFS,
389 [LINUX_ETIMEDOUT] = ETIMEDOUT,
390 [LINUX_ECONNREFUSED] = ECONNREFUSED,
391 [LINUX_EHOSTDOWN] = EHOSTDOWN,
392 [LINUX_EHOSTUNREACH] = EHOSTUNREACH,
393 [LINUX_EALREADY] = EALREADY,
394 [LINUX_EINPROGRESS] = EINPROGRESS,
395 [LINUX_ESTALE] = ESTALE,
396 [LINUX_EUCLEAN] = EINVAL /* EUCLEAN */,
397 [LINUX_ENOTNAM] = EINVAL /* ENOTNAM */,
398 [LINUX_ENAVAIL] = EINVAL /* ENAVAIL */,
399 [LINUX_EISNAM] = EINVAL /* EISNAM */,
400 [LINUX_EREMOTEIO] = EINVAL /* EREMOTEIO */,
401 [LINUX_EDQUOT] = EDQUOT,
402 [LINUX_ENOMEDIUM] = EINVAL /* ENOMEDIUM */,
403 [LINUX_EMEDIUMTYPE] = EINVAL /* EMEDIUMTYPE */,
412 if (code < (sizeof errno_xlate) / (sizeof errno_xlate[0])) {
413 code = errno_xlate[code];
423 LINUX_O_CREAT = 0100,
425 LINUX_O_NOCTTY = 0400,
426 LINUX_O_TRUNC = 01000,
427 LINUX_O_APPEND = 02000,
428 LINUX_O_NONBLOCK = 04000,
429 LINUX_O_NDELAY = LINUX_O_NONBLOCK,
430 LINUX_O_SYNC = 010000,
431 LINUX_O_FSYNC = LINUX_O_SYNC,
432 LINUX_O_ASYNC = 020000,
433 LINUX_O_DIRECT = 040000,
434 LINUX_O_NOFOLLOW = 0400000
437 static inline void obit_convert(int *cflag, int *sflag,
438 unsigned cmask, unsigned smask)
440 if (*cflag & cmask != 0) {
447 * convert <fcntl.h> flag from XNU client to Linux _i386_ server.
449 int convert_client_oflag(int cflag, int *result)
454 obit_convert(&cflag, &sflag, O_RDONLY, LINUX_O_RDONLY);
455 obit_convert(&cflag, &sflag, O_WRONLY, LINUX_O_WRONLY);
456 obit_convert(&cflag, &sflag, O_RDWR, LINUX_O_RDWR);
457 obit_convert(&cflag, &sflag, O_NONBLOCK, LINUX_O_NONBLOCK);
458 obit_convert(&cflag, &sflag, O_APPEND, LINUX_O_APPEND);
459 obit_convert(&cflag, &sflag, O_ASYNC, LINUX_O_ASYNC);
460 obit_convert(&cflag, &sflag, O_FSYNC, LINUX_O_FSYNC);
461 obit_convert(&cflag, &sflag, O_NOFOLLOW, LINUX_O_NOFOLLOW);
462 obit_convert(&cflag, &sflag, O_CREAT, LINUX_O_CREAT);
463 obit_convert(&cflag, &sflag, O_TRUNC, LINUX_O_TRUNC);
464 obit_convert(&cflag, &sflag, O_EXCL, LINUX_O_EXCL);
465 obit_convert(&cflag, &sflag, O_CREAT, LINUX_O_CREAT);
466 obit_convert(&cflag, &sflag, O_NDELAY, LINUX_O_NDELAY);
467 obit_convert(&cflag, &sflag, O_NOCTTY, LINUX_O_NOCTTY);
469 * Some more obscure BSD flags have no Linux counterparts:
485 #else /* !__DARWIN8__ */
486 extern int unix_syscall();
487 extern int unix_syscall_return();
489 extern int ktrsysret();
492 extern int ast_taken();
493 extern int ast_check();
496 extern int syscall_trace();
498 static int is_addr_in_range(void *addr, void *start, void *end)
500 return start <= addr && addr <= end;
503 extern void cfs_thread_agent (void);
505 static int is_last_frame(void *addr)
509 else if (is_addr_in_range(addr, unix_syscall, unix_syscall_return))
511 else if (is_addr_in_range(addr, ktrsysret, ktrace))
513 else if (is_addr_in_range(addr, ast_taken, ast_check))
515 else if (is_addr_in_range(addr, trap, syscall_trace))
517 else if (is_addr_in_range(addr, cfs_thread_agent, cfs_kernel_thread))
523 static void *get_frame(int i)
527 #define CASE(i) case (i): result = __builtin_return_address(i); break
550 panic("impossible frame number: %d\n", i);
556 void cfs_stack_trace_fill(struct cfs_stack_trace *trace)
560 memset(trace, 0, sizeof *trace);
561 for (i = 0; i < sizeof_array(trace->frame); ++ i) {
565 trace->frame[i] = addr;
566 if (is_last_frame(addr))
571 void *cfs_stack_trace_frame(struct cfs_stack_trace *trace, int frame_no)
573 if (0 <= frame_no && frame_no < sizeof_array(trace->frame))
574 return trace->frame[frame_no];
578 #endif /* !__DARWIN8__ */