4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 #include <nbdkit-filter.h>
52 #include "windows-compat.h"
56 enum type
{ ENTER
, LEAVE
, PRINT
};
58 /* Adds an entry to the logfile. */
60 to_file (struct handle
*h
, log_id_t id
, const char *act
, enum type type
,
61 const char *fmt
, va_list args
)
65 char timestamp
[27] = "Time unknown";
67 /* Logging is best effort, so ignore failure to get timestamp */
68 if (!gettimeofday (&tv
, NULL
)) {
71 gmtime_r (&tv
.tv_sec
, &tm
);
72 s
= strftime (timestamp
, sizeof timestamp
- sizeof ".000000" + 1,
75 snprintf (timestamp
+ s
, sizeof timestamp
- s
, ".%06ld",
84 fprintf (logfile
, "%s connection=%" PRIu64
" %s%s",
85 timestamp
, h
->connection
, type
== LEAVE
? "..." : "", act
);
87 fprintf (logfile
, "%s %s%s",
88 timestamp
, type
== LEAVE
? "..." : "",act
);
91 fprintf (logfile
, " id=%" PRIu64
, id
);
94 fprintf (logfile
, " ");
95 vfprintf (logfile
, fmt
, args
);
98 fprintf (logfile
, " ...");
100 fputc ('\n', logfile
);
102 #ifdef HAVE_FUNLOCKFILE
103 funlockfile (logfile
);
107 /* Runs the script. */
109 to_script (struct handle
*h
, log_id_t id
, const char *act
, enum type type
,
110 const char *fmt
, va_list args
)
113 CLEANUP_FREE
char *str
= NULL
;
117 /* Create the shell variables + script. */
118 fp
= open_memstream (&str
, &len
);
120 /* Not much we can do, but at least record the error. */
121 nbdkit_error ("logscript: open_memstream: %m");
125 fprintf (fp
, "act=%s\n", act
);
127 fprintf (fp
, "connection=%" PRIu64
"\n", h
->connection
);
129 case ENTER
: fprintf (fp
, "type=ENTER\n"); break;
130 case LEAVE
: fprintf (fp
, "type=LEAVE\n"); break;
131 case PRINT
: fprintf (fp
, "type=PRINT\n"); break;
134 fprintf (fp
, "id=%" PRIu64
"\n", id
);
136 vfprintf (fp
, fmt
, args
);
139 fprintf (fp
, "%s", logscript
);
142 /* Run the script. Log the status, but ignore it. */
144 exit_status_to_nbd_error (r
, "logscript");
148 enter (struct handle
*h
, log_id_t id
, const char *act
,
149 const char *fmt
, ...)
154 va_start (args
, fmt
);
155 to_file (h
, id
, act
, ENTER
, fmt
, args
);
159 va_start (args
, fmt
);
160 to_script (h
, id
, act
, ENTER
, fmt
, args
);
166 leave (struct handle
*h
, log_id_t id
, const char *act
,
167 const char *fmt
, ...)
172 va_start (args
, fmt
);
173 to_file (h
, id
, act
, LEAVE
, fmt
, args
);
177 va_start (args
, fmt
);
178 to_script (h
, id
, act
, LEAVE
, fmt
, args
);
184 print (struct handle
*h
, const char *act
, const char *fmt
, ...)
189 va_start (args
, fmt
);
190 to_file (h
, 0, act
, PRINT
, fmt
, args
);
194 va_start (args
, fmt
);
195 to_script (h
, 0, act
, PRINT
, fmt
, args
);
201 leave_simple (struct handle
*h
, log_id_t id
, const char *act
, int r
, int *err
)
205 /* Only decode what server/protocol.c:nbd_errno() recognizes */
227 s
= " error=ESHUTDOWN";
231 #if ENOTSUP != EOPNOTSUPP
234 s
= " error=ENOTSUP";
237 s
= " error=EOVERFLOW";
247 leave (h
, id
, act
, "return=%d%s", r
, s
);
251 leave_simple2 (struct leave_simple_params
*params
)
253 leave_simple (params
->h
, params
->id
, params
->act
, *params
->r
, params
->err
);