4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
38 static cfs_mutex_t ptltrace_mutex;
39 static cfs_waitq_t ptltrace_debug_ctlwq;
42 kptllnd_ptltrace_to_file(char *filename)
44 CFS_DECL_JOURNAL_DATA;
55 CWARN("dumping ptltrace to %s\n", filename);
57 LIBCFS_ALLOC(tmpbuf, PAGE_SIZE);
59 CERROR("Can't allocate page buffer to dump %s\n", filename);
65 filp = cfs_filp_open(filename,
66 O_CREAT|O_EXCL|O_WRONLY|O_LARGEFILE, 0600, &rc);
69 CERROR("Error %d creating %s\n", rc, filename);
77 len = ptl_proc_read(tmpbuf, &start, offset,
78 PAGE_SIZE, &eof, NULL);
80 /* we don't allow ptl_proc_read to mimic case 0 or 1 behavior
81 * for a proc_read method, only #2: from proc_file_read
83 * 2) Set *start = an address within the buffer.
84 * Put the data of the requested offset at *start.
85 * Return the number of bytes of data placed there.
86 * If this number is greater than zero and you
87 * didn't signal eof and the reader is prepared to
88 * take more data you will be called again with the
89 * requested offset advanced by the number of bytes
93 if (len == 0) /* end of file */
97 CERROR("ptl_proc_read: error %d\n", len);
101 if (start < tmpbuf || start + len > tmpbuf + PAGE_SIZE) {
102 CERROR("ptl_proc_read bug: %p for %d not in %p for %ld\n",
103 start, len, tmpbuf, PAGE_SIZE);
107 rc = cfs_filp_write(filp, start, len, cfs_filp_poff(filp));
110 CERROR("Error %d writing %s\n", rc, filename);
112 CERROR("Partial write %d(%d) to %s\n",
122 rc = cfs_filp_fsync(filp);
124 CERROR("Error %d syncing %s\n", rc, filename);
126 cfs_filp_close(filp);
129 LIBCFS_FREE(tmpbuf, PAGE_SIZE);
133 kptllnd_dump_ptltrace_thread(void *arg)
135 static char fname[1024];
137 libcfs_daemonize("kpt_ptltrace_dump");
139 /* serialise with other instances of me */
140 cfs_mutex_lock(&ptltrace_mutex);
142 snprintf(fname, sizeof(fname), "%s.%ld.%ld",
143 *kptllnd_tunables.kptl_ptltrace_basename,
144 cfs_time_current_sec(), (long)arg);
146 kptllnd_ptltrace_to_file(fname);
148 cfs_mutex_unlock(&ptltrace_mutex);
150 /* unblock my creator */
151 cfs_waitq_signal(&ptltrace_debug_ctlwq);
156 kptllnd_dump_ptltrace(void)
162 /* taken from libcfs_debug_dumplog */
163 cfs_waitlink_init(&wait);
164 cfs_set_current_state(CFS_TASK_INTERRUPTIBLE);
165 cfs_waitq_add(&ptltrace_debug_ctlwq, &wait);
167 rc = cfs_create_thread(kptllnd_dump_ptltrace_thread,
168 (void *)(long)cfs_curproc_pid(),
169 CFS_DAEMON_FLAGS | CLONE_FS);
171 CERROR("Error %d starting ptltrace dump thread\n", rc);
173 cfs_waitq_wait(&wait, CFS_TASK_INTERRUPTIBLE);
176 /* teardown if cfs_kernel_thread() failed */
177 cfs_waitq_del(&ptltrace_debug_ctlwq, &wait);
178 cfs_set_current_state(CFS_TASK_RUNNING);
183 kptllnd_init_ptltrace(void)
185 cfs_waitq_init(&ptltrace_debug_ctlwq);
186 cfs_mutex_init(&ptltrace_mutex);