1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see [sun.com URL with a
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
40 static struct semaphore ptltrace_mutex;
41 static struct semaphore ptltrace_signal;
44 kptllnd_ptltrace_to_file(char *filename)
46 CFS_DECL_JOURNAL_DATA;
57 CWARN("dumping ptltrace to %s\n", filename);
59 LIBCFS_ALLOC(tmpbuf, PAGE_SIZE);
61 CERROR("Can't allocate page buffer to dump %s\n", filename);
67 filp = cfs_filp_open(filename,
68 O_CREAT|O_EXCL|O_WRONLY|O_LARGEFILE, 0600, &rc);
71 CERROR("Error %d creating %s\n", rc, filename);
79 len = ptl_proc_read(tmpbuf, &start, offset,
80 PAGE_SIZE, &eof, NULL);
82 /* we don't allow ptl_proc_read to mimic case 0 or 1 behavior
83 * for a proc_read method, only #2: from proc_file_read
85 * 2) Set *start = an address within the buffer.
86 * Put the data of the requested offset at *start.
87 * Return the number of bytes of data placed there.
88 * If this number is greater than zero and you
89 * didn't signal eof and the reader is prepared to
90 * take more data you will be called again with the
91 * requested offset advanced by the number of bytes
95 if (len == 0) /* end of file */
99 CERROR("ptl_proc_read: error %d\n", len);
103 if (start < tmpbuf || start + len > tmpbuf + PAGE_SIZE) {
104 CERROR("ptl_proc_read bug: %p for %d not in %p for %ld\n",
105 start, len, tmpbuf, PAGE_SIZE);
109 rc = cfs_filp_write(filp, start, len, cfs_filp_poff(filp));
112 CERROR("Error %d writing %s\n", rc, filename);
114 CERROR("Partial write %d(%d) to %s\n",
124 rc = cfs_filp_fsync(filp);
126 CERROR("Error %d syncing %s\n", rc, filename);
128 cfs_filp_close(filp);
131 LIBCFS_FREE(tmpbuf, PAGE_SIZE);
135 kptllnd_dump_ptltrace_thread(void *arg)
137 static char fname[1024];
139 libcfs_daemonize("ptltracedump");
141 /* serialise with other instances of me */
142 mutex_down(&ptltrace_mutex);
144 snprintf(fname, sizeof(fname), "%s.%ld.%ld",
145 *kptllnd_tunables.kptl_ptltrace_basename,
146 cfs_time_current_sec(), (long)arg);
148 kptllnd_ptltrace_to_file(fname);
150 mutex_up(&ptltrace_mutex);
152 /* unblock my creator */
153 mutex_up(&ptltrace_signal);
159 kptllnd_dump_ptltrace(void)
163 if (!*kptllnd_tunables.kptl_ptltrace_on_timeout)
166 rc = cfs_kernel_thread(kptllnd_dump_ptltrace_thread,
167 (void *)(long)cfs_curproc_pid(),
168 CLONE_VM | CLONE_FS | CLONE_FILES);
170 CERROR("Error %d starting ptltrace dump thread\n", rc);
172 /* block until thread completes */
173 mutex_down(&ptltrace_signal);
178 kptllnd_init_ptltrace(void)
180 init_mutex(&ptltrace_mutex);
181 init_mutex_locked(&ptltrace_signal);
187 kptllnd_dump_ptltrace(void)
192 kptllnd_init_ptltrace(void)