1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2006 Cluster File Systems, Inc. All rights reserved.
6 * This file is part of the Lustre file system, http://www.lustre.org
7 * Lustre is a trademark of Cluster File Systems, Inc.
9 * This file is confidential source code owned by Cluster File Systems.
10 * No viewing, modification, compilation, redistribution, or any other
11 * form of use is permitted except through a signed license agreement.
13 * If you have not signed such an agreement, then you have no rights to
14 * this file. Please destroy it immediately and contact CFS.
21 static struct semaphore ptltrace_mutex;
22 static struct semaphore ptltrace_signal;
25 kptllnd_ptltrace_to_file(char *filename)
27 CFS_DECL_JOURNAL_DATA;
38 CWARN("dumping ptltrace to %s\n", filename);
40 LIBCFS_ALLOC(tmpbuf, PAGE_SIZE);
42 CERROR("Can't allocate page buffer to dump %s\n", filename);
48 filp = cfs_filp_open(filename,
49 O_CREAT|O_EXCL|O_WRONLY|O_LARGEFILE, 0600, &rc);
52 CERROR("Error %d creating %s\n", rc, filename);
60 len = ptl_proc_read(tmpbuf, &start, offset,
61 PAGE_SIZE, &eof, NULL);
63 /* we don't allow ptl_proc_read to mimic case 0 or 1 behavior
64 * for a proc_read method, only #2: from proc_file_read
66 * 2) Set *start = an address within the buffer.
67 * Put the data of the requested offset at *start.
68 * Return the number of bytes of data placed there.
69 * If this number is greater than zero and you
70 * didn't signal eof and the reader is prepared to
71 * take more data you will be called again with the
72 * requested offset advanced by the number of bytes
76 if (len == 0) /* end of file */
80 CERROR("ptl_proc_read: error %d\n", len);
84 if (start < tmpbuf || start + len > tmpbuf + PAGE_SIZE) {
85 CERROR("ptl_proc_read bug: %p for %d not in %p for %d\n",
86 start, len, tmpbuf, PAGE_SIZE);
90 rc = cfs_filp_write(filp, start, len, cfs_filp_poff(filp));
93 CERROR("Error %d writing %s\n", rc, filename);
95 CERROR("Partial write %d(%d) to %s\n",
105 rc = cfs_filp_fsync(filp);
107 CERROR("Error %d syncing %s\n", rc, filename);
109 cfs_filp_close(filp);
112 LIBCFS_FREE(tmpbuf, PAGE_SIZE);
116 kptllnd_dump_ptltrace_thread(void *arg)
118 static char fname[1024];
120 libcfs_daemonize("ptltracedump");
122 /* serialise with other instances of me */
123 mutex_down(&ptltrace_mutex);
125 snprintf(fname, sizeof(fname), "%s.%ld.%ld",
126 *kptllnd_tunables.kptl_ptltrace_basename,
127 cfs_time_current_sec(), (long)arg);
129 kptllnd_ptltrace_to_file(fname);
131 mutex_up(&ptltrace_mutex);
133 /* unblock my creator */
134 mutex_up(&ptltrace_signal);
140 kptllnd_dump_ptltrace(void)
144 if (!*kptllnd_tunables.kptl_ptltrace_on_timeout)
147 rc = cfs_kernel_thread(kptllnd_dump_ptltrace_thread,
148 (void *)(long)cfs_curproc_pid(),
149 CLONE_VM | CLONE_FS | CLONE_FILES);
151 CERROR("Error %d starting ptltrace dump thread\n", rc);
153 /* block until thread completes */
154 mutex_down(&ptltrace_signal);
159 kptllnd_init_ptltrace(void)
161 init_mutex(&ptltrace_mutex);
162 init_mutex_locked(&ptltrace_signal);
168 kptllnd_dump_ptltrace(void)
173 kptllnd_init_ptltrace(void)