Print this page
NEX-13374 NDMP should be able to backup unmounted ZFS filesystems
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5801 Snapshots left over after failed backups
Reviewed by: Rick Mesta <rick.mesta@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Revert "NEX-5801 Snapshots left over after failed backups"
This reverts commit f182fb95f09036db71fbfc6f0a6b90469b761f21.
NEX-5801 Snapshots left over after failed backups
Reviewed by: Rick Mesta <rick.mesta@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-2990 ndmpd dumping core when used with ndmpcopy
NEX-2911 NDMP logging should use syslog and is too chatty
NEX-2911 NDMP logging should use syslog and is too chatty
NEX-1512 NDMP fails in Restore files with Symantec Netbackup
NEX-1263 socket buffer sizes in NDMP are set to very low value
Reviewed by: sarah.jelinek@nexenta.com
Reviewed by: marcel.telka@nexenta.com
Reviewed by: albert.lee@nexenta.com
Reviewed by: hans.rosenfeld@nexenta.com
NEX-727 Netbackup Catalog verification hangs waiting for NDMP server
NEX-559 NDMP cannot backup/restore a file which spans multiple tapes
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/ndmpd/ndmp/ndmpd_util.c
+++ new/usr/src/cmd/ndmpd/ndmp/ndmpd_util.c
1 1 /*
2 2 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
3 3 */
4 4
5 5 /*
6 6 * BSD 3 Clause License
7 7 *
8 8 * Copyright (c) 2007, The Storage Networking Industry Association.
9 9 *
10 10 * Redistribution and use in source and binary forms, with or without
11 11 * modification, are permitted provided that the following conditions
12 12 * are met:
13 13 * - Redistributions of source code must retain the above copyright
14 14 * notice, this list of conditions and the following disclaimer.
15 15 *
16 16 * - Redistributions in binary form must reproduce the above copyright
17 17 * notice, this list of conditions and the following disclaimer in
18 18 * the documentation and/or other materials provided with the
19 19 * distribution.
20 20 *
21 21 * - Neither the name of The Storage Networking Industry Association (SNIA)
22 22 * nor the names of its contributors may be used to endorse or promote
23 23 * products derived from this software without specific prior written
24 24 * permission.
25 25 *
26 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
30 30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 36 * POSSIBILITY OF SUCH DAMAGE.
37 37 */
38 38 /* Copyright (c) 2007, The Storage Networking Industry Association. */
39 39 /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
40 -/* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
40 +/* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */
41 41
42 42 #include <sys/types.h>
43 +#include <syslog.h>
43 44 #include <assert.h>
44 45 #include <ctype.h>
45 46 #include <errno.h>
46 47 #include <stdio.h>
47 48 #include <stdlib.h>
48 49 #include <unistd.h>
49 50 #include <strings.h>
50 51 #include <time.h>
51 52 #include "ndmpd.h"
52 53 #include <bitmap.h>
53 54 #include <sys/queue.h>
54 55 #include <sys/socket.h>
55 56 #include <netinet/in.h>
56 57 #include <netinet/tcp.h>
57 58 #include <arpa/inet.h>
58 59 #include <sys/socketvar.h>
59 60 #include <net/if.h>
60 61 #include <netdb.h>
61 62 #include <sys/filio.h>
62 63 #include <sys/mtio.h>
63 64 #include <sys/scsi/impl/uscsi.h>
64 65 #include <sys/scsi/scsi.h>
65 66 #include "tlm.h"
66 67
67 68 /*
68 69 * Force to backup all the intermediate directories leading to an object
69 70 * to be backed up in 'dump' format backup.
70 71 */
71 72 boolean_t ndmp_dump_path_node = FALSE;
72 73
73 74
74 75 /*
75 76 * Force to backup all the intermediate directories leading to an object
76 77 * to be backed up in 'tar' format backup.
77 78 */
78 79 boolean_t ndmp_tar_path_node = FALSE;
79 80
80 81
81 82 /*
82 83 * Should the 'st_ctime' be ignored during incremental level backup?
83 84 */
84 85 boolean_t ndmp_ignore_ctime = FALSE;
85 86
86 87 /*
87 88 * Should the 'st_lmtime' be included during incremental level backup?
88 89 */
89 90 boolean_t ndmp_include_lmtime = FALSE;
90 91
91 92 /*
92 93 * Force to send the file history node entries along with the file history
93 94 * dir entries for all directories containing the changed files to the client
94 95 * for incremental backup.
95 96 *
96 97 * Note: This variable is added to support Bakbone Software's Netvault DMA
97 98 * which expects to get the FH ADD NODES for all upper directories which
98 99 * contain the changed files in incremental backup along with the FH ADD DIRS.
99 100 */
100 101 boolean_t ndmp_fhinode = FALSE;
101 102
102 103 /*
103 104 * Maximum permitted sequence number in the token-based backup. The
104 105 * value of this variable can be changed by the administrator and is
105 106 * saved in the NDMP configuration file.
106 107 */
107 108 static int ndmp_max_tok_seq = NDMP_MAX_TOKSEQ;
108 109
109 110 /*
110 111 * Force backup directories in incremental backups. If the
111 112 * directory is not modified itself, it's not backed up by
112 113 * default.
113 114 */
114 115 int ndmp_force_bk_dirs = 0;
115 116
116 117 /*
117 118 * Keeps track of the open SCSI (including tape and robot) devices.
118 119 * When a SCSI device is opened its name must be added to this list and
119 120 * when it's closed its name must be removed from this list. The main
120 121 * purpose of this list is the robot device. If the robot devices are not
121 122 * attached in SASD layer, Local Backup won't see them. If they are
122 123 * attached and we open the robot devices, then wrong commands are sent
123 124 * to robot by SASD since it assumes that the robot is a tape (sequential
124 125 * access) device.
125 126 */
126 127 struct open_list {
127 128 LIST_ENTRY(open_list) ol_q;
128 129 int ol_nref;
129 130 char *ol_devnm;
130 131 int ol_sid;
131 132 int ol_lun;
132 133 int ol_fd;
133 134 ndmp_connection_t *cl_conn;
134 135 };
135 136 LIST_HEAD(ol_head, open_list);
136 137
137 138
138 139 /*
139 140 * Head of the opened SCSI devices list.
140 141 */
141 142 static struct ol_head ol_head;
142 143
143 144 mutex_t ol_mutex = DEFAULTMUTEX;
144 145
145 146
|
↓ open down ↓ |
93 lines elided |
↑ open up ↑ |
146 147 /*
147 148 * List of things to be exluded from backup.
148 149 */
149 150 static char *exls[] = {
150 151 EXCL_PROC,
151 152 EXCL_TMP,
152 153 NULL, /* reserved for a copy of the "backup.directory" */
153 154 NULL
154 155 };
155 156
156 -
157 157 /*
158 - * The counter for creating unique names with "ndmp.%d" format.
158 + * The counter for creating unique names with "NDMP_RCF_BASENAME.%d" format.
159 159 */
160 -#define NDMP_RCF_BASENAME "ndmp."
161 160 static int ndmp_job_cnt = 0;
162 161
163 162 static int scsi_test_unit_ready(int dev_id);
163 +static int ndmpd_mkdir(const char *);
164 164
165 165 /*
166 166 * ndmpd_add_file_handler
167 167 *
168 168 * Adds a file handler to the file handler list.
169 169 * The file handler list is used by ndmpd_api_dispatch.
170 170 *
171 171 * Parameters:
172 172 * session (input) - session pointer.
173 173 * cookie (input) - opaque data to be passed to file hander when called.
174 174 * fd (input) - file descriptor.
175 175 * mode (input) - bitmask of the following:
176 176 * 1 = watch file for ready for reading
177 177 * 2 = watch file for ready for writing
178 178 * 4 = watch file for exception
179 179 * class (input) - handler class. (HC_CLIENT, HC_MOVER, HC_MODULE)
180 180 * func (input) - function to call when the file meets one of the
181 181 * conditions specified by mode.
182 182 *
183 183 * Returns:
184 184 * 0 - success.
185 185 * -1 - error.
186 186 */
187 187 int
188 188 ndmpd_add_file_handler(ndmpd_session_t *session, void *cookie, int fd,
189 189 ulong_t mode, ulong_t class, ndmpd_file_handler_func_t *func)
190 190 {
191 191 ndmpd_file_handler_t *new;
192 192
193 193 new = ndmp_malloc(sizeof (ndmpd_file_handler_t));
194 194 if (new == 0)
195 195 return (-1);
196 196
197 197 new->fh_cookie = cookie;
198 198 new->fh_fd = fd;
199 199 new->fh_mode = mode;
200 200 new->fh_class = class;
201 201 new->fh_func = func;
202 202 new->fh_next = session->ns_file_handler_list;
203 203 session->ns_file_handler_list = new;
204 204 return (0);
205 205 }
206 206
207 207
208 208 /*
209 209 * ndmpd_remove_file_handler
210 210 *
211 211 * Removes a file handler from the file handler list.
212 212 *
213 213 * Parameters:
214 214 * session (input) - session pointer.
215 215 * fd (input) - file descriptor.
216 216 *
217 217 * Returns:
218 218 * 0 - success.
219 219 * -1 - error.
220 220 */
221 221 int
222 222 ndmpd_remove_file_handler(ndmpd_session_t *session, int fd)
223 223 {
224 224 ndmpd_file_handler_t **last;
225 225 ndmpd_file_handler_t *handler;
226 226
227 227 last = &session->ns_file_handler_list;
228 228 while (*last != 0) {
229 229 handler = *last;
230 230
231 231 if (handler->fh_fd == fd) {
232 232 *last = handler->fh_next;
233 233 (void) free(handler);
234 234 return (1);
235 235 }
236 236 last = &handler->fh_next;
237 237 }
238 238
239 239 return (0);
240 240 }
241 241
242 242
243 243 /*
244 244 * ndmp_connection_closed
245 245 *
246 246 * If the connection closed or not.
247 247 *
248 248 * Parameters:
249 249 * fd (input) : file descriptor
250 250 *
251 251 * Returns:
252 252 * 0 - connection is still valid
253 253 * 1 - connection is not valid anymore
254 254 * -1 - Internal kernel error
255 255 */
256 256 int
257 257 ndmp_connection_closed(int fd)
258 258 {
259 259 fd_set fds;
260 260 int closed, ret;
261 261 struct timeval timeout;
262 262
263 263 if (fd < 0) /* We are not using the mover */
264 264 return (-1);
265 265
266 266 timeout.tv_sec = 0;
267 267 timeout.tv_usec = 1000;
268 268
269 269 FD_ZERO(&fds);
270 270 FD_SET(fd, &fds);
271 271 ret = select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
272 272
273 273 closed = (ret == -1 && errno == EBADF);
274 274
275 275 return (closed);
276 276 }
277 277
278 278 /*
279 279 * ndmp_check_mover_state
280 280 *
281 281 * Checks the mover connection status and sends an appropriate
282 282 * NDMP message to client based on that.
283 283 *
284 284 * Parameters:
285 285 * ndmpd_session_t *session (input) : session pointer
286 286 *
287 287 * Returns:
288 288 * void.
289 289 */
290 290 void
291 291 ndmp_check_mover_state(ndmpd_session_t *session)
292 292 {
293 293 int moverfd;
294 294 /*
295 295 * NDMPV3 Spec (Three-way restore):
296 296 * Once all of the files have been recovered, NDMP DATA Server closes
297 297 * the connection to the mover on the NDMP TAPE Server. THEN
298 298 * The NDMP client should receive an NDMP_NOTIFY_MOVER_HALTED message
299 299 * with an NDMP_MOVER_CONNECT_CLOSED reason from the NDMP TAPE Server
300 300 */
|
↓ open down ↓ |
127 lines elided |
↑ open up ↑ |
301 301 moverfd = session->ns_mover.md_sock;
302 302 /* If connection is closed by the peer */
303 303 if (moverfd >= 0 &&
304 304 session->ns_mover.md_mode == NDMP_MOVER_MODE_WRITE) {
305 305 int closed, reason;
306 306
307 307 closed = ndmp_connection_closed(moverfd);
308 308 if (closed) {
309 309 /* Connection closed or internal error */
310 310 if (closed > 0) {
311 - NDMP_LOG(LOG_DEBUG,
311 + syslog(LOG_DEBUG,
312 312 "ndmp mover: connection closed by peer");
313 313 reason = NDMP_MOVER_HALT_CONNECT_CLOSED;
314 314 } else {
315 - NDMP_LOG(LOG_DEBUG,
315 + syslog(LOG_DEBUG,
316 316 "ndmp mover: Internal error");
317 317 reason = NDMP_MOVER_HALT_INTERNAL_ERROR;
318 318 }
319 319 ndmpd_mover_error(session, reason);
320 320
321 321 }
322 322 }
323 323 }
324 324
325 325
326 326 /*
327 327 * ndmpd_select
328 328 *
329 329 * Calls select on the the set of file descriptors from the
330 330 * file handler list masked by the fd_class argument.
331 331 * Calls the file handler function for each
332 332 * file descriptor that is ready for I/O.
333 333 *
334 334 * Parameters:
335 335 * session (input) - session pointer.
336 336 * block (input) - if TRUE, ndmpd_select waits until at least one
337 337 * file descriptor is ready for I/O. Otherwise,
338 338 * it returns immediately if no file descriptors are
339 339 * ready for I/O.
340 340 * class_mask (input) - bit mask of handler classes to be examined.
341 341 * Provides for excluding some of the handlers from
342 342 * being called.
343 343 *
344 344 * Returns:
345 345 * -1 - error.
346 346 * 0 - no handlers were called.
347 347 * 1 - at least one handler was called.
348 348 */
349 349 int
350 350 ndmpd_select(ndmpd_session_t *session, boolean_t block, ulong_t class_mask)
351 351 {
352 352 fd_set rfds;
353 353 fd_set wfds;
354 354 fd_set efds;
355 355 int n;
356 356 ndmpd_file_handler_t *handler;
357 357 struct timeval timeout;
358 358 ndmp_lbr_params_t *nlp;
359 359
360 360 if (session->ns_file_handler_list == 0)
361 361 return (0);
362 362
363 363
364 364 /*
365 365 * If select should be blocked, then we poll every ten seconds.
366 366 * The reason is in case of three-way restore we should be able
367 367 * to detect if the other end closed the connection or not.
368 368 * NDMP client(DMA) does not send any information about the connection
369 369 * that was closed in the other end.
370 370 */
371 371
372 372 if (block == TRUE)
373 373 timeout.tv_sec = 10;
374 374 else
375 375 timeout.tv_sec = 0;
376 376 timeout.tv_usec = 0;
377 377
378 378 do {
379 379 /* Create the fd_sets for select. */
380 380 FD_ZERO(&rfds);
381 381 FD_ZERO(&wfds);
382 382 FD_ZERO(&efds);
383 383
384 384 for (handler = session->ns_file_handler_list; handler != 0;
385 385 handler = handler->fh_next) {
386 386 if ((handler->fh_class & class_mask) == 0)
387 387 continue;
388 388
389 389 if (handler->fh_mode & NDMPD_SELECT_MODE_READ)
390 390 FD_SET(handler->fh_fd, &rfds);
391 391 if (handler->fh_mode & NDMPD_SELECT_MODE_WRITE)
392 392 FD_SET(handler->fh_fd, &wfds);
393 393 if (handler->fh_mode & NDMPD_SELECT_MODE_EXCEPTION)
394 394 FD_SET(handler->fh_fd, &efds);
395 395 }
|
↓ open down ↓ |
70 lines elided |
↑ open up ↑ |
396 396 ndmp_check_mover_state(session);
397 397 n = select(FD_SETSIZE, &rfds, &wfds, &efds, &timeout);
398 398 } while (n == 0 && block == TRUE);
399 399
400 400 if (n < 0) {
401 401 int connection_fd = ndmp_get_fd(session->ns_connection);
402 402
403 403 if (errno == EINTR)
404 404 return (0);
405 405
406 - NDMP_LOG(LOG_DEBUG, "Select error: %m");
407 -
408 406 nlp = ndmp_get_nlp(session);
409 407 (void) mutex_lock(&nlp->nlp_mtx);
410 408 for (handler = session->ns_file_handler_list; handler != 0;
411 409 handler = handler->fh_next) {
412 410 if ((handler->fh_class & class_mask) == 0)
413 411 continue;
414 412
415 413 if (handler->fh_mode & NDMPD_SELECT_MODE_READ) {
416 414 if (FD_ISSET(handler->fh_fd, &rfds) &&
417 415 connection_fd == handler->fh_fd)
418 416 session->ns_eof = TRUE;
419 417 }
420 418 if (handler->fh_mode & NDMPD_SELECT_MODE_WRITE) {
421 419 if (FD_ISSET(handler->fh_fd, &wfds) &&
422 420 connection_fd == handler->fh_fd)
423 421 session->ns_eof = TRUE;
424 422 }
425 423 if (handler->fh_mode & NDMPD_SELECT_MODE_EXCEPTION) {
426 424 if (FD_ISSET(handler->fh_fd, &efds) &&
427 425 connection_fd == handler->fh_fd)
428 426 session->ns_eof = TRUE;
429 427 }
430 428 }
431 429 (void) cond_broadcast(&nlp->nlp_cv);
432 430 (void) mutex_unlock(&nlp->nlp_mtx);
433 431 return (-1);
434 432 }
435 433 if (n == 0)
436 434 return (0);
437 435
438 436 handler = session->ns_file_handler_list;
439 437 while (handler != 0) {
440 438 ulong_t mode = 0;
441 439
442 440 if ((handler->fh_class & class_mask) == 0) {
443 441 handler = handler->fh_next;
444 442 continue;
445 443 }
446 444 if (handler->fh_mode & NDMPD_SELECT_MODE_READ) {
447 445 if (FD_ISSET(handler->fh_fd, &rfds)) {
448 446 mode |= NDMPD_SELECT_MODE_READ;
449 447 FD_CLR(handler->fh_fd, &rfds);
450 448 }
451 449 }
452 450 if (handler->fh_mode & NDMPD_SELECT_MODE_WRITE) {
453 451 if (FD_ISSET(handler->fh_fd, &wfds)) {
454 452 mode |= NDMPD_SELECT_MODE_WRITE;
455 453 FD_CLR(handler->fh_fd, &wfds);
456 454 }
457 455 }
458 456 if (handler->fh_mode & NDMPD_SELECT_MODE_EXCEPTION) {
459 457 if (FD_ISSET(handler->fh_fd, &efds)) {
460 458 mode |= NDMPD_SELECT_MODE_EXCEPTION;
461 459 FD_CLR(handler->fh_fd, &efds);
462 460 }
463 461 }
464 462 if (mode) {
465 463 (*handler->fh_func) (handler->fh_cookie,
466 464 handler->fh_fd, mode);
467 465
468 466 /*
469 467 * K.L. The list can be modified during the execution
470 468 * of handler->fh_func. Therefore, handler will start
471 469 * from the beginning of the handler list after
472 470 * each execution.
473 471 */
474 472 handler = session->ns_file_handler_list;
475 473 } else
476 474 handler = handler->fh_next;
477 475
478 476 }
479 477
480 478 return (1);
481 479 }
482 480
483 481
484 482 /*
485 483 * ndmpd_save_env
486 484 *
487 485 * Saves a copy of the environment variable list from the data_start_backup
488 486 * request or data_start_recover request.
489 487 *
490 488 * Parameters:
491 489 * session (input) - session pointer.
492 490 * env (input) - environment variable list to be saved.
493 491 * envlen (input) - length of variable array.
494 492 *
495 493 * Returns:
496 494 * error code.
497 495 */
498 496 ndmp_error
499 497 ndmpd_save_env(ndmpd_session_t *session, ndmp_pval *env, ulong_t envlen)
500 498 {
501 499 ulong_t i;
502 500 char *namebuf;
503 501 char *valbuf;
504 502
505 503 session->ns_data.dd_env_len = 0;
506 504
507 505 if (envlen == 0)
508 506 return (NDMP_NO_ERR);
509 507
510 508 session->ns_data.dd_env = ndmp_malloc(sizeof (ndmp_pval) * envlen);
511 509 if (session->ns_data.dd_env == 0)
512 510 return (NDMP_NO_MEM_ERR);
513 511
514 512 for (i = 0; i < envlen; i++) {
|
↓ open down ↓ |
97 lines elided |
↑ open up ↑ |
515 513 namebuf = strdup(env[i].name);
516 514 if (namebuf == 0)
517 515 return (NDMP_NO_MEM_ERR);
518 516
519 517 valbuf = strdup(env[i].value);
520 518 if (valbuf == 0) {
521 519 free(namebuf);
522 520 return (NDMP_NO_MEM_ERR);
523 521 }
524 522
525 - NDMP_LOG(LOG_DEBUG, "env(%s): \"%s\"",
523 + syslog(LOG_DEBUG, "env(%s): \"%s\"",
526 524 namebuf, valbuf);
527 525
528 526 (void) mutex_lock(&session->ns_lock);
529 527 session->ns_data.dd_env[i].name = namebuf;
530 528 session->ns_data.dd_env[i].value = valbuf;
531 529 session->ns_data.dd_env_len++;
532 530 (void) mutex_unlock(&session->ns_lock);
533 531 }
534 532
535 533 return (NDMP_NO_ERR);
536 534 }
537 535
538 536
539 537 /*
540 538 * ndmpd_free_env
541 539 *
542 540 * Free the previously saved environment variable array.
543 541 *
544 542 * Parameters:
545 543 * session - NDMP session pointer.
546 544 *
547 545 * Returns:
548 546 * void.
549 547 */
550 548 void
551 549 ndmpd_free_env(ndmpd_session_t *session)
552 550 {
553 551 ulong_t i;
554 552 int count = session->ns_data.dd_env_len;
555 553
556 554 (void) mutex_lock(&session->ns_lock);
557 555 session->ns_data.dd_env_len = 0;
558 556 for (i = 0; i < count; i++) {
559 557 free(session->ns_data.dd_env[i].name);
560 558 free(session->ns_data.dd_env[i].value);
561 559 }
562 560
563 561 free((char *)session->ns_data.dd_env);
564 562 session->ns_data.dd_env = 0;
565 563 (void) mutex_unlock(&session->ns_lock);
566 564 }
567 565
568 566
569 567 /*
570 568 * ndmpd_save_nlist_v2
571 569 *
572 570 * Save a copy of list of file names to be restored.
573 571 *
574 572 * Parameters:
575 573 * nlist (input) - name list from data_start_recover request.
576 574 * nlistlen (input) - length of name list.
577 575 *
578 576 * Returns:
579 577 * array of file name pointers.
580 578 *
581 579 * Notes:
582 580 * free_nlist should be called to free the returned list.
583 581 * A null pointer indicates the end of the list.
584 582 */
585 583 ndmp_error
586 584 ndmpd_save_nlist_v2(ndmpd_session_t *session, ndmp_name *nlist,
|
↓ open down ↓ |
51 lines elided |
↑ open up ↑ |
587 585 ulong_t nlistlen)
588 586 {
589 587 ulong_t i;
590 588 char *namebuf;
591 589 char *destbuf;
592 590
593 591 if (nlistlen == 0)
594 592 return (NDMP_NO_ERR);
595 593
596 594 session->ns_data.dd_nlist_len = 0;
597 - session->ns_data.dd_nlist = ndmp_malloc(sizeof (ndmp_name)*nlistlen);
595 + session->ns_data.dd_nlist =
596 + ndmp_malloc(sizeof (ndmp_name)*(nlistlen + 1));
598 597 if (session->ns_data.dd_nlist == 0)
599 598 return (NDMP_NO_MEM_ERR);
600 599
601 600 for (i = 0; i < nlistlen; i++) {
602 601 namebuf = ndmp_malloc(strlen(nlist[i].name) + 1);
603 602 if (namebuf == 0)
604 603 return (NDMP_NO_MEM_ERR);
605 604
606 605 destbuf = ndmp_malloc(strlen(nlist[i].dest) + 1);
607 606 if (destbuf == 0) {
608 607 free(namebuf);
609 608 return (NDMP_NO_MEM_ERR);
610 609 }
611 610 (void) strlcpy(namebuf, nlist[i].name,
612 611 strlen(nlist[i].name) + 1);
613 612 (void) strlcpy(destbuf, nlist[i].dest,
614 613 strlen(nlist[i].dest) + 1);
615 614
616 615 session->ns_data.dd_nlist[i].name = namebuf;
617 616 session->ns_data.dd_nlist[i].dest = destbuf;
618 617 session->ns_data.dd_nlist[i].ssid = nlist[i].ssid;
619 618 session->ns_data.dd_nlist[i].fh_info = nlist[i].fh_info;
620 619 session->ns_data.dd_nlist_len++;
621 620 }
622 621
623 622 return (NDMP_NO_ERR);
624 623 }
625 624
626 625
627 626 /*
628 627 * ndmpd_free_nlist_v2
629 628 *
630 629 * Free a list created by ndmpd_save_nlist_v2.
631 630 *
632 631 * Parameters:
633 632 * session (input) - session pointer.
634 633 *
635 634 * Returns:
636 635 * void
637 636 */
638 637 void
639 638 ndmpd_free_nlist_v2(ndmpd_session_t *session)
640 639 {
641 640 ulong_t i;
642 641
643 642 for (i = 0; i < session->ns_data.dd_nlist_len; i++) {
644 643 free(session->ns_data.dd_nlist[i].name);
645 644 free(session->ns_data.dd_nlist[i].dest);
646 645 }
647 646
648 647 if (session->ns_data.dd_nlist != NULL)
649 648 free((char *)session->ns_data.dd_nlist);
650 649 session->ns_data.dd_nlist = 0;
651 650 session->ns_data.dd_nlist_len = 0;
652 651 }
653 652
654 653
655 654 /*
656 655 * ndmpd_free_nlist_v3
657 656 *
658 657 * Free a list created by ndmpd_save_nlist_v3.
659 658 *
660 659 * Parameters:
661 660 * session (input) - session pointer.
662 661 *
663 662 * Returns:
664 663 * void
665 664 */
666 665 void
667 666 ndmpd_free_nlist_v3(ndmpd_session_t *session)
668 667 {
669 668 ulong_t i;
670 669 mem_ndmp_name_v3_t *tp; /* destination entry */
671 670
672 671 tp = session->ns_data.dd_nlist_v3;
673 672 for (i = 0; i < session->ns_data.dd_nlist_len; tp++, i++) {
674 673 NDMP_FREE(tp->nm3_opath);
675 674 NDMP_FREE(tp->nm3_dpath);
676 675 NDMP_FREE(tp->nm3_newnm);
677 676 }
678 677
679 678 NDMP_FREE(session->ns_data.dd_nlist_v3);
680 679 session->ns_data.dd_nlist_len = 0;
681 680 }
682 681
683 682
684 683 /*
685 684 * ndmpd_save_nlist_v3
686 685 *
687 686 * Save a copy of list of file names to be restored.
688 687 *
689 688 * Parameters:
690 689 * nlist (input) - name list from data_start_recover request.
691 690 * nlistlen (input) - length of name list.
692 691 *
693 692 * Returns:
694 693 * array of file name pointers.
695 694 *
696 695 * Notes:
697 696 * free_nlist should be called to free the returned list.
698 697 * A null pointer indicates the end of the list.
699 698 */
700 699 ndmp_error
701 700 ndmpd_save_nlist_v3(ndmpd_session_t *session, ndmp_name_v3 *nlist,
702 701 ulong_t nlistlen)
703 702 {
704 703 ulong_t i;
705 704 ndmp_error rv;
706 705 ndmp_name_v3 *sp; /* source entry */
707 706 mem_ndmp_name_v3_t *tp; /* destination entry */
708 707
709 708 if (nlistlen == 0)
710 709 return (NDMP_ILLEGAL_ARGS_ERR);
711 710
712 711 session->ns_data.dd_nlist_len = 0;
713 712 tp = session->ns_data.dd_nlist_v3 =
714 713 ndmp_malloc(sizeof (mem_ndmp_name_v3_t) * nlistlen);
715 714 if (session->ns_data.dd_nlist_v3 == 0)
716 715 return (NDMP_NO_MEM_ERR);
717 716
718 717 rv = NDMP_NO_ERR;
719 718 sp = nlist;
720 719 for (i = 0; i < nlistlen; tp++, sp++, i++) {
721 720 tp->nm3_opath = strdup(sp->original_path);
722 721 if (!tp->nm3_opath) {
723 722 rv = NDMP_NO_MEM_ERR;
724 723 break;
725 724 }
726 725 if (!*sp->destination_dir) {
727 726 tp->nm3_dpath = NULL;
728 727 /* In V4 destination dir cannot be NULL */
729 728 if (session->ns_protocol_version == NDMPV4) {
730 729 rv = NDMP_ILLEGAL_ARGS_ERR;
731 730 break;
732 731 }
733 732 } else if (!(tp->nm3_dpath = strdup(sp->destination_dir))) {
734 733 rv = NDMP_NO_MEM_ERR;
735 734 break;
736 735 }
737 736 if (!*sp->new_name)
738 737 tp->nm3_newnm = NULL;
|
↓ open down ↓ |
131 lines elided |
↑ open up ↑ |
739 738 else if (!(tp->nm3_newnm = strdup(sp->new_name))) {
740 739 rv = NDMP_NO_MEM_ERR;
741 740 break;
742 741 }
743 742
744 743 tp->nm3_node = quad_to_long_long(sp->node);
745 744 tp->nm3_fh_info = quad_to_long_long(sp->fh_info);
746 745 tp->nm3_err = NDMP_NO_ERR;
747 746 session->ns_data.dd_nlist_len++;
748 747
749 - NDMP_LOG(LOG_DEBUG, "orig \"%s\"", tp->nm3_opath);
750 - NDMP_LOG(LOG_DEBUG, "dest \"%s\"", NDMP_SVAL(tp->nm3_dpath));
751 - NDMP_LOG(LOG_DEBUG, "name \"%s\"", NDMP_SVAL(tp->nm3_newnm));
752 - NDMP_LOG(LOG_DEBUG, "node %lld", tp->nm3_node);
753 - NDMP_LOG(LOG_DEBUG, "fh_info %lld", tp->nm3_fh_info);
754 748 }
755 749
756 750 if (rv != NDMP_NO_ERR)
757 751 ndmpd_free_nlist_v3(session);
758 752
759 753 return (rv);
760 754 }
761 755
762 756
763 757 /*
764 758 * ndmpd_free_nlist
765 759 *
766 760 * Free the recovery list based on the version
767 761 *
768 762 * Parameters:
769 763 * session (input) - session pointer.
770 764 *
771 765 * Returns:
772 766 * void
773 767 */
774 768 void
775 769 ndmpd_free_nlist(ndmpd_session_t *session)
776 770 {
777 771 switch (session->ns_protocol_version) {
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
778 772 case 1:
779 773 case 2:
780 774 ndmpd_free_nlist_v2(session);
781 775 break;
782 776 case 3:
783 777 case 4:
784 778 ndmpd_free_nlist_v3(session);
785 779 break;
786 780
787 781 default:
788 - NDMP_LOG(LOG_DEBUG, "Unknown version %d",
782 + syslog(LOG_DEBUG, "Unknown version %d",
789 783 session->ns_protocol_version);
790 784 }
791 785 }
792 786
793 787
794 788 /*
795 789 * fh_cmpv3
796 790 *
797 791 * Comparison function used in sorting the Nlist based on their
798 792 * file history info (offset of the entry on the tape)
799 793 *
800 794 * Parameters:
801 795 * p (input) - pointer to P
802 796 * q (input) - pointer to Q
803 797 *
804 798 * Returns:
805 799 * -1: P < Q
806 800 * 0: P = Q
807 801 * 1: P > Q
808 802 */
809 803 static int
810 804 fh_cmpv3(const void *p,
811 805 const void *q)
812 806 {
813 807 #define FH_INFOV3(p) (((mem_ndmp_name_v3_t *)p)->nm3_fh_info)
814 808
815 809 if (FH_INFOV3(p) < FH_INFOV3(q))
816 810 return (-1);
817 811 else if (FH_INFOV3(p) == FH_INFOV3(q))
818 812 return (0);
819 813 else
820 814 return (1);
821 815
822 816 #undef FH_INFOV3
823 817 }
824 818
825 819
826 820 /*
827 821 * ndmp_sort_nlist_v3
828 822 *
829 823 * Sort the recovery list based on their offset on the tape
830 824 *
831 825 * Parameters:
832 826 * session (input) - session pointer.
833 827 *
834 828 * Returns:
835 829 * void
836 830 */
837 831 void
838 832 ndmp_sort_nlist_v3(ndmpd_session_t *session)
839 833 {
840 834 if (!session || session->ns_data.dd_nlist_len == 0 ||
841 835 !session->ns_data.dd_nlist_v3)
842 836 return;
843 837
844 838 (void) qsort(session->ns_data.dd_nlist_v3,
845 839 session->ns_data.dd_nlist_len,
846 840 sizeof (mem_ndmp_name_v3_t), fh_cmpv3);
847 841 }
848 842
849 843
850 844 /*
851 845 * ndmp_send_reply
852 846 *
853 847 * Send the reply, check for error and print the msg if any error
854 848 * occured when sending the reply.
855 849 *
|
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
856 850 * Parameters:
857 851 * connection (input) - connection pointer.
858 852 *
859 853 * Return:
860 854 * void
861 855 */
862 856 void
863 857 ndmp_send_reply(ndmp_connection_t *connection, void *reply, char *msg)
864 858 {
865 859 if (ndmp_send_response(connection, NDMP_NO_ERR, reply) < 0)
866 - NDMP_LOG(LOG_DEBUG, "%s", msg);
860 + syslog(LOG_DEBUG, "%s", msg);
867 861 }
868 862
869 863
870 864 /*
871 865 * ndmp_mtioctl
872 866 *
873 867 * Performs numerous filemark operations.
874 868 *
875 869 * Parameters:
876 870 * fd - file descriptor of the device
877 871 * cmd - filemark or record command
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
878 872 * count - the number of operations to be performed
879 873 */
880 874 int
881 875 ndmp_mtioctl(int fd, int cmd, int count)
882 876 {
883 877 struct mtop mp;
884 878
885 879 mp.mt_op = cmd;
886 880 mp.mt_count = count;
887 881 if (ioctl(fd, MTIOCTOP, &mp) < 0) {
888 - NDMP_LOG(LOG_ERR, "Failed to send command to tape: %m.");
882 + syslog(LOG_ERR, "Failed to send command to tape: %m.");
889 883 return (-1);
890 884 }
891 885
892 886 return (0);
893 887 }
894 888
895 889
896 890 /*
897 891 * quad_to_long_long
898 892 *
899 893 * Convert type quad to longlong_t
900 894 */
901 895 u_longlong_t
902 896 quad_to_long_long(ndmp_u_quad q)
903 897 {
904 898 u_longlong_t ull;
905 899
906 900 ull = ((u_longlong_t)q.high << 32) + q.low;
907 901 return (ull);
908 902 }
909 903
910 904
911 905 /*
912 906 * long_long_to_quad
913 907 *
914 908 * Convert long long to quad type
915 909 */
916 910 ndmp_u_quad
917 911 long_long_to_quad(u_longlong_t ull)
918 912 {
919 913 ndmp_u_quad q;
920 914
921 915 q.high = (ulong_t)(ull >> 32);
922 916 q.low = (ulong_t)ull;
923 917 return (q);
924 918 }
925 919
926 920 void
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
927 921 set_socket_options(int sock)
928 922 {
929 923 int val;
930 924
931 925 /* set send buffer size */
932 926 val = atoi((const char *)ndmpd_get_prop_default(NDMP_SOCKET_CSS, "60"));
933 927 if (val <= 0)
934 928 val = 60;
935 929 val <<= 10; /* convert the value from kilobytes to bytes */
936 930 if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, sizeof (val)) < 0)
937 - NDMP_LOG(LOG_ERR, "SO_SNDBUF failed: %m");
931 + syslog(LOG_ERR, "SO_SNDBUF failed: %m");
938 932
939 933 /* set receive buffer size */
940 934 val = atoi((const char *)ndmpd_get_prop_default(NDMP_SOCKET_CRS, "60"));
941 935 if (val <= 0)
942 936 val = 60;
943 937 val <<= 10; /* convert the value from kilobytes to bytes */
944 938 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, sizeof (val)) < 0)
945 - NDMP_LOG(LOG_ERR, "SO_RCVBUF failed: %m");
939 + syslog(LOG_ERR, "SO_RCVBUF failed: %m");
946 940
947 941 /* don't wait to group tcp data */
948 942 val = 1;
949 943 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)) != 0)
950 - NDMP_LOG(LOG_ERR, "TCP_NODELAY failed: %m");
944 + syslog(LOG_ERR, "TCP_NODELAY failed: %m");
951 945
952 946 /* tcp keep-alive */
953 947 val = 1;
954 948 if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof (val)) != 0)
955 - NDMP_LOG(LOG_ERR, "SO_KEEPALIVE failed: %m");
949 + syslog(LOG_ERR, "SO_KEEPALIVE failed: %m");
956 950 }
957 951
958 952 /*
959 953 * ndmp_get_max_tok_seq
960 954 *
961 955 * Get the maximum permitted token sequence for token-based
962 956 * backups.
963 957 *
964 958 * Parameters:
965 959 * void
966 960 *
967 961 * Returns:
968 962 * ndmp_max_tok_seq
969 963 */
970 964 int
971 965 ndmp_get_max_tok_seq(void)
972 966 {
973 967 return (ndmp_max_tok_seq);
974 968 }
975 969
976 970 /*
977 971 * ndmp_buffer_get_size
978 972 *
979 973 * Return the NDMP transfer buffer size
980 974 *
981 975 * Parameters:
982 976 * session (input) - session pointer.
983 977 *
984 978 * Returns:
985 979 * buffer size
986 980 */
987 981 long
988 982 ndmp_buffer_get_size(ndmpd_session_t *session)
989 983 {
990 984 long xfer_size;
991 985
|
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
992 986 if (session == NULL)
993 987 return (0);
994 988
995 989 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
996 990 xfer_size = atoi(ndmpd_get_prop_default(NDMP_MOVER_RECSIZE,
997 991 "60"));
998 992 if (xfer_size > 0)
999 993 xfer_size *= KILOBYTE;
1000 994 else
1001 995 xfer_size = REMOTE_RECORD_SIZE;
1002 - NDMP_LOG(LOG_DEBUG, "Remote operation: %d", xfer_size);
996 + syslog(LOG_DEBUG, "Remote operation: %d", xfer_size);
1003 997 } else {
1004 - NDMP_LOG(LOG_DEBUG,
998 + syslog(LOG_DEBUG,
1005 999 "Local operation: %lu", session->ns_mover.md_record_size);
1006 1000 if ((xfer_size = session->ns_mover.md_record_size) == 0)
1007 1001 xfer_size = MAX_RECORD_SIZE;
1008 1002 }
1009 1003
1010 - NDMP_LOG(LOG_DEBUG, "xfer_size: %d", xfer_size);
1004 + syslog(LOG_DEBUG, "xfer_size: %d", xfer_size);
1011 1005 return (xfer_size);
1012 1006 }
1013 1007
1014 1008
1015 1009 /*
1016 1010 * ndmp_lbr_init
1017 1011 *
1018 1012 * Initialize the LBR/NDMP backup parameters
1019 1013 *
1020 1014 * Parameters:
1021 1015 * session (input) - session pointer.
1022 1016 *
1023 1017 * Returns:
1024 1018 * 0: on success
1025 1019 * -1: otherwise
1026 1020 */
1027 1021 int
1028 1022 ndmp_lbr_init(ndmpd_session_t *session)
1029 1023 {
1030 1024 if (session->ns_ndmp_lbr_params != NULL) {
1031 - NDMP_LOG(LOG_DEBUG, "ndmp_lbr_params already allocated.");
1025 + syslog(LOG_DEBUG, "ndmp_lbr_params already allocated.");
1032 1026 return (0);
1033 1027 }
1034 1028
1035 1029 session->ns_ndmp_lbr_params = ndmp_malloc(sizeof (ndmp_lbr_params_t));
1036 1030 if (session->ns_ndmp_lbr_params == NULL)
1037 1031 return (-1);
1038 1032
1039 1033 session->ns_ndmp_lbr_params->nlp_bkmap = -1;
1040 1034 session->ns_ndmp_lbr_params->nlp_session = session;
1041 1035 (void) cond_init(&session->ns_ndmp_lbr_params->nlp_cv, 0, NULL);
1042 1036 (void) mutex_init(&session->ns_ndmp_lbr_params->nlp_mtx, 0, NULL);
1043 1037 (void) mutex_init(&session->ns_lock, 0, NULL);
1044 1038 session->ns_nref = 0;
1045 1039 return (0);
1046 1040 }
1047 1041
1048 1042
1049 1043 /*
1050 1044 * ndmp_lbr_cleanup
1051 1045 *
1052 1046 * Deallocate and cleanup all NDMP/LBR parameters
1053 1047 *
1054 1048 * Parameters:
1055 1049 * session (input) - session pointer.
1056 1050 *
1057 1051 * Returns:
1058 1052 * 0: on success
1059 1053 * -1: otherwise
1060 1054 */
1061 1055 void
1062 1056 ndmp_lbr_cleanup(ndmpd_session_t *session)
1063 1057 {
1064 1058 ndmpd_abort_marking_v2(session);
1065 1059 ndmp_stop_buffer_worker(session);
1066 1060 ndmp_waitfor_op(session);
1067 1061 ndmp_free_reader_writer_ipc(session);
1068 1062 if (session->ns_ndmp_lbr_params) {
1069 1063 if (session->ns_ndmp_lbr_params->nlp_bkmap != -1)
1070 1064 (void) dbm_free(session->ns_ndmp_lbr_params->nlp_bkmap);
1071 1065 tlm_release_list(session->ns_ndmp_lbr_params->nlp_exl);
1072 1066 tlm_release_list(session->ns_ndmp_lbr_params->nlp_inc);
1073 1067 (void) cond_destroy(&session->ns_ndmp_lbr_params->nlp_cv);
1074 1068 (void) mutex_destroy(&session->ns_ndmp_lbr_params->nlp_mtx);
1075 1069 }
1076 1070
1077 1071 NDMP_FREE(session->ns_ndmp_lbr_params);
1078 1072 }
1079 1073
1080 1074 /*
1081 1075 * ndmp_wait_for_mover
1082 1076 *
1083 1077 * Wait for a mover to become active. Waiting is interrupted if session is
1084 1078 * aborted or mover gets to unexpected state.
1085 1079 *
1086 1080 * Parameters:
1087 1081 * session (input) - session pointer.
1088 1082 *
1089 1083 * Returns:
1090 1084 * 0 if success, -1 if failure.
1091 1085 */
1092 1086 int
1093 1087 ndmp_wait_for_mover(ndmpd_session_t *session)
|
↓ open down ↓ |
52 lines elided |
↑ open up ↑ |
1094 1088 {
1095 1089 ndmp_lbr_params_t *nlp;
1096 1090 tlm_cmd_t *lcmd;
1097 1091
1098 1092 if ((nlp = ndmp_get_nlp(session)) == NULL)
1099 1093 return (-1);
1100 1094
1101 1095 (void) mutex_lock(&nlp->nlp_mtx);
1102 1096 while (session->ns_mover.md_state == NDMP_MOVER_STATE_PAUSED) {
1103 1097 if (session->ns_eof) {
1104 - NDMP_LOG(LOG_ERR, "EOF detected");
1098 + syslog(LOG_ERR, "EOF detected");
1105 1099 break;
1106 1100 }
1107 1101 if (session->ns_data.dd_abort) {
1108 - NDMP_LOG(LOG_DEBUG, "Received data abort");
1102 + syslog(LOG_DEBUG, "Received data abort");
1109 1103 break;
1110 1104 }
1111 1105 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
1112 1106 /* remote backup/restore error */
1113 1107 if (session->ns_mover.md_sock == -1 &&
1114 1108 session->ns_mover.md_listen_sock == -1) {
1115 - NDMP_LOG(LOG_ERR,
1109 + syslog(LOG_ERR,
1116 1110 "Remote data connection terminated");
1117 1111 break;
1118 1112 }
1119 1113 } else {
1120 1114 /* local backup/restore error */
1121 1115 if ((lcmd = nlp->nlp_cmds.tcs_command) != NULL) {
1122 1116 if (lcmd->tc_reader == TLM_STOP ||
1123 1117 lcmd->tc_reader == TLM_ABORT ||
1124 1118 lcmd->tc_writer == TLM_STOP ||
1125 1119 lcmd->tc_writer == TLM_ABORT) {
1126 - NDMP_LOG(LOG_ERR,
1120 + syslog(LOG_ERR,
1127 1121 "Local data connection terminated");
1128 1122 break;
1129 1123 }
1130 1124 }
1131 1125 }
1132 1126
1133 1127 (void) cond_wait(&nlp->nlp_cv, &nlp->nlp_mtx);
1134 1128 }
1135 1129 (void) mutex_unlock(&nlp->nlp_mtx);
1136 1130
1137 1131 return ((session->ns_mover.md_state == NDMP_MOVER_STATE_ACTIVE) ?
1138 1132 0 : -1);
1139 1133 }
1140 1134
1141 1135 /*
1142 1136 * is_buffer_erroneous
1143 1137 *
1144 1138 * Run a sanity check on the buffer
1145 1139 *
1146 1140 * returns:
1147 1141 * TRUE: if the buffer seems to have error
1148 1142 * FALSE: if the buffer is full and has valid data.
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
1149 1143 */
1150 1144 boolean_t
1151 1145 is_buffer_erroneous(tlm_buffer_t *buf)
1152 1146 {
1153 1147 boolean_t rv;
1154 1148
1155 1149 rv = (buf == NULL || buf->tb_eot || buf->tb_eof ||
1156 1150 buf->tb_errno != 0);
1157 1151 if (rv) {
1158 1152 if (buf == NULL) {
1159 - NDMP_LOG(LOG_DEBUG, "buf == NULL");
1153 + syslog(LOG_DEBUG, "buf == NULL");
1160 1154 } else {
1161 - NDMP_LOG(LOG_DEBUG, "eot: %u, eof: %u, errno: %d",
1155 + syslog(LOG_DEBUG, "eot: %u, eof: %u, errno: %d",
1162 1156 buf->tb_eot, buf->tb_eof, buf->tb_errno);
1163 1157 }
1164 1158 }
1165 1159
1166 1160 return (rv);
1167 1161 }
1168 1162
1169 1163 /*
1170 1164 * ndmp_execute_cdb
1171 1165 *
1172 1166 * Main SCSI CDB execution program, this is used by message handler
1173 1167 * for the NDMP tape/SCSI execute CDB requests. This function uses
1174 1168 * USCSI interface to run the CDB command and sets all the CDB parameters
1175 1169 * in the SCSI query before calling the USCSI ioctl. The result of the
1176 1170 * CDB is returned in two places:
1177 1171 * cmd.uscsi_status The status of CDB execution
1178 1172 * cmd.uscsi_rqstatus The status of sense requests
1179 1173 * reply.error The general errno (ioctl)
1180 1174 *
1181 1175 * Parameters:
1182 1176 * session (input) - session pointer
1183 1177 * adapter_name (input) - name of SCSI adapter
1184 1178 * sid (input) - SCSI target ID
1185 1179 * lun (input) - LUN number
1186 1180 * request (input) - NDMP client CDB request
1187 1181 *
1188 1182 * Returns:
1189 1183 * void
1190 1184 */
1191 1185 /*ARGSUSED*/
1192 1186 void
1193 1187 ndmp_execute_cdb(ndmpd_session_t *session, char *adapter_name, int sid, int lun,
1194 1188 ndmp_execute_cdb_request *request)
1195 1189 {
1196 1190 ndmp_execute_cdb_reply reply;
1197 1191 struct uscsi_cmd cmd;
1198 1192 int fd;
1199 1193 struct open_list *olp;
1200 1194 char rq_buf[255];
1201 1195
1202 1196 (void) memset((void *)&cmd, 0, sizeof (cmd));
|
↓ open down ↓ |
31 lines elided |
↑ open up ↑ |
1203 1197 (void) memset((void *)&reply, 0, sizeof (reply));
1204 1198 (void) memset((void *)rq_buf, 0, sizeof (rq_buf));
1205 1199
1206 1200 if (request->flags == NDMP_SCSI_DATA_IN) {
1207 1201 cmd.uscsi_flags = USCSI_READ | USCSI_RQENABLE;
1208 1202 if ((cmd.uscsi_bufaddr =
1209 1203 ndmp_malloc(request->datain_len)) == 0) {
1210 1204 reply.error = NDMP_NO_MEM_ERR;
1211 1205 if (ndmp_send_response(session->ns_connection,
1212 1206 NDMP_NO_ERR, (void *)&reply) < 0)
1213 - NDMP_LOG(LOG_DEBUG, "error sending"
1207 + syslog(LOG_DEBUG, "error sending"
1214 1208 " scsi_execute_cdb reply.");
1215 1209 return;
1216 1210 }
1217 1211
1218 1212 cmd.uscsi_buflen = request->datain_len;
1219 1213 } else if (request->flags == NDMP_SCSI_DATA_OUT) {
1220 1214 cmd.uscsi_flags = USCSI_WRITE | USCSI_RQENABLE;
1221 1215 cmd.uscsi_bufaddr = request->dataout.dataout_val;
1222 1216 cmd.uscsi_buflen = request->dataout.dataout_len;
1223 1217 } else {
1224 1218 cmd.uscsi_flags = USCSI_RQENABLE;
1225 1219 cmd.uscsi_bufaddr = 0;
1226 1220 cmd.uscsi_buflen = 0;
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
1227 1221 }
1228 1222 cmd.uscsi_rqlen = sizeof (rq_buf);
1229 1223 cmd.uscsi_rqbuf = rq_buf;
1230 1224
1231 1225 cmd.uscsi_timeout = (request->timeout < 1000) ?
1232 1226 1 : (request->timeout / 1000);
1233 1227
1234 1228 cmd.uscsi_cdb = (caddr_t)request->cdb.cdb_val;
1235 1229 cmd.uscsi_cdblen = request->cdb.cdb_len;
1236 1230
1237 - NDMP_LOG(LOG_DEBUG, "cmd: 0x%x, len: %d, flags: %d, datain_len: %d",
1238 - request->cdb.cdb_val[0] & 0xff, request->cdb.cdb_len,
1239 - request->flags, request->datain_len);
1240 - NDMP_LOG(LOG_DEBUG, "dataout_len: %d, timeout: %d",
1241 - request->dataout.dataout_len, request->timeout);
1242 -
1243 1231 if (request->cdb.cdb_len > 12) {
1244 1232 reply.error = NDMP_ILLEGAL_ARGS_ERR;
1245 1233 ndmp_send_reply(session->ns_connection, (void *) &reply,
1246 1234 "sending execute_cdb reply");
1247 1235 if (request->flags == NDMP_SCSI_DATA_IN)
1248 1236 free(cmd.uscsi_bufaddr);
1249 1237 return;
1250 1238 }
1251 1239
1252 1240 reply.error = NDMP_NO_ERR;
1253 1241
1254 1242 if ((olp = ndmp_open_list_find(adapter_name, sid, lun)) != NULL) {
1255 1243 fd = olp->ol_fd;
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
1256 1244 } else {
1257 1245 reply.error = NDMP_DEV_NOT_OPEN_ERR;
1258 1246 ndmp_send_reply(session->ns_connection, (void *) &reply,
1259 1247 "sending execute_cdb reply");
1260 1248 if (request->flags == NDMP_SCSI_DATA_IN)
1261 1249 free(cmd.uscsi_bufaddr);
1262 1250 return;
1263 1251 }
1264 1252
1265 1253 if (ioctl(fd, USCSICMD, &cmd) < 0) {
1266 - if (errno != EIO && errno != 0)
1267 - NDMP_LOG(LOG_ERR,
1254 + if (errno != EIO && errno != 0) {
1255 + syslog(LOG_ERR,
1268 1256 "Failed to send command to device: %m");
1269 - NDMP_LOG(LOG_DEBUG, "ioctl(USCSICMD) error: %m");
1257 + }
1270 1258 if (cmd.uscsi_status == 0)
1271 1259 reply.error = NDMP_IO_ERR;
1272 1260 }
1273 1261
1274 1262 reply.status = cmd.uscsi_status;
1275 1263
1276 1264 if (request->flags == NDMP_SCSI_DATA_IN) {
1277 1265 reply.datain.datain_len = cmd.uscsi_buflen;
1278 1266 reply.datain.datain_val = cmd.uscsi_bufaddr;
1279 1267 } else {
1280 1268 reply.dataout_len = request->dataout.dataout_len;
1281 1269 }
1282 1270
1283 1271 reply.ext_sense.ext_sense_len = cmd.uscsi_rqlen - cmd.uscsi_rqresid;
1284 1272 reply.ext_sense.ext_sense_val = rq_buf;
1285 1273
1286 1274 if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR,
1287 1275 (void *)&reply) < 0)
1288 - NDMP_LOG(LOG_DEBUG, "Error sending scsi_execute_cdb reply.");
1276 + syslog(LOG_DEBUG, "Error sending scsi_execute_cdb reply.");
1289 1277
1290 1278 if (request->flags == NDMP_SCSI_DATA_IN)
1291 1279 free(cmd.uscsi_bufaddr);
1292 1280 }
1293 1281
1294 1282
1295 1283 /*
1296 1284 * ndmp_stop_local_reader
1297 1285 *
1298 1286 * Stops a mover reader thread (for local backup only)
1299 1287 *
1300 1288 * Parameters:
1301 1289 * session (input) - session pointer
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
1302 1290 * cmds (input) - reader/writer command struct
1303 1291 *
1304 1292 * Returns:
1305 1293 * void
1306 1294 */
1307 1295 void
1308 1296 ndmp_stop_local_reader(ndmpd_session_t *session, tlm_commands_t *cmds)
1309 1297 {
1310 1298 ndmp_lbr_params_t *nlp;
1311 1299
1312 - if (session != NULL && session->ns_data.dd_sock == -1) {
1313 - /* 2-way restore */
1300 + if (session != NULL) {
1314 1301 if (cmds != NULL && cmds->tcs_reader_count > 0) {
1315 1302 if ((nlp = ndmp_get_nlp(session)) != NULL) {
1316 1303 (void) mutex_lock(&nlp->nlp_mtx);
1317 1304 cmds->tcs_command->tc_reader = TLM_STOP;
1318 1305 (void) cond_broadcast(&nlp->nlp_cv);
1319 1306 (void) mutex_unlock(&nlp->nlp_mtx);
1320 1307 }
1321 1308 }
1322 1309 }
1323 1310 }
1324 1311
1325 1312
1326 1313 /*
1327 1314 * Stops a mover reader thread (for remote backup only)
1328 1315 *
1329 1316 * Parameters:
1330 1317 * session (input) - session pointer
1331 1318 * cmds (input) - reader/writer command struct
1332 1319 *
1333 1320 * Returns:
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
1334 1321 * void
1335 1322 */
1336 1323 void
1337 1324 ndmp_stop_remote_reader(ndmpd_session_t *session)
1338 1325 {
1339 1326 if (session != NULL) {
1340 1327 if (session->ns_data.dd_sock >= 0) {
1341 1328 /*
1342 1329 * 3-way restore.
1343 1330 */
1344 - NDMP_LOG(LOG_DEBUG,
1331 + syslog(LOG_DEBUG,
1345 1332 "data.sock: %d", session->ns_data.dd_sock);
1346 1333 (void) close(session->ns_data.dd_sock);
1347 1334 session->ns_data.dd_sock = -1;
1348 1335 }
1349 1336 }
1350 1337 }
1351 1338
1352 1339
1353 1340 /*
1354 1341 * ndmp_wait_for_reader
1355 1342 *
1356 1343 * Wait for a reader until get done (busy wait)
1357 1344 */
1358 1345 void
1359 1346 ndmp_wait_for_reader(tlm_commands_t *cmds)
1360 1347 {
1361 - if (cmds == NULL) {
1362 - NDMP_LOG(LOG_DEBUG, "cmds == NULL");
1363 - } else {
1364 - NDMP_LOG(LOG_DEBUG,
1365 - "reader_count: %d", cmds->tcs_reader_count);
1366 -
1348 + if (cmds != NULL) {
1367 1349 while (cmds->tcs_reader_count > 0)
1368 1350 (void) sleep(1);
1369 1351 }
1370 1352 }
1371 1353
1372 1354
1373 1355 /*
1374 1356 * ndmp_open_list_find
1375 1357 *
1376 1358 * Find a specific device in the open list
1377 1359 *
1378 1360 * Parameters:
1379 1361 * dev (input) - device name
1380 1362 * sid (input) - SCSI target ID
1381 1363 * lun (input) - LUN number
1382 1364 *
|
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
1383 1365 * Returns:
1384 1366 * pointer to the open list entry
1385 1367 */
1386 1368 struct open_list *
1387 1369 ndmp_open_list_find(char *dev, int sid, int lun)
1388 1370 {
1389 1371 struct ol_head *olhp;
1390 1372 struct open_list *olp;
1391 1373
1392 1374 if (dev == NULL || *dev == '\0') {
1393 - NDMP_LOG(LOG_DEBUG, "Invalid argument");
1394 1375 return (NULL);
1395 1376 }
1396 1377
1397 1378 (void) mutex_lock(&ol_mutex);
1398 1379 olhp = &ol_head;
1399 1380 for (olp = LIST_FIRST(olhp); olp != NULL; olp = LIST_NEXT(olp, ol_q))
1400 1381 if (strcmp(olp->ol_devnm, dev) == 0 && olp->ol_sid == sid &&
1401 1382 olp->ol_lun == lun) {
1402 1383 (void) mutex_unlock(&ol_mutex);
1403 1384 return (olp);
1404 1385 }
1405 1386
1406 1387 (void) mutex_unlock(&ol_mutex);
1407 1388 return (NULL);
1408 1389 }
1409 1390
1410 1391
1411 1392 /*
1412 1393 * ndmp_open_list_add
1413 1394 *
1414 1395 * Add a specific device to the open list
1415 1396 *
1416 1397 * Parameters:
1417 1398 * conn (input) - connection pointer
1418 1399 * dev (input) - device name
1419 1400 * sid (input) - SCSI target ID
1420 1401 * lun (input) - LUN number
1421 1402 * fd (input) - the device file descriptor
1422 1403 *
1423 1404 * Returns:
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
1424 1405 * errno
1425 1406 */
1426 1407 int
1427 1408 ndmp_open_list_add(ndmp_connection_t *conn, char *dev, int sid, int lun, int fd)
1428 1409 {
1429 1410 int err;
1430 1411 struct ol_head *olhp;
1431 1412 struct open_list *olp;
1432 1413
1433 1414 if (dev == NULL || *dev == '\0') {
1434 - NDMP_LOG(LOG_DEBUG, "Invalid argument");
1435 1415 return (EINVAL);
1436 1416 }
1437 - NDMP_LOG(LOG_DEBUG,
1438 - "conn: 0x%08x, dev: %s, sid: %d, lun: %d", conn, dev, sid, lun);
1439 1417
1440 1418 err = 0;
1441 1419 olhp = &ol_head;
1442 1420
1443 1421 if ((olp = ndmp_open_list_find(dev, sid, lun)) != NULL) {
1444 - NDMP_LOG(LOG_DEBUG, "already in list");
1445 1422 /*
1446 1423 * The adapter handle can be opened many times by the clients.
1447 1424 * Only when the target is set, we must check and reject the
1448 1425 * open request if the device is already being used by another
1449 1426 * session.
1450 1427 */
1451 1428 if (sid == -1)
1452 1429 olp->ol_nref++;
1453 1430 else
1454 1431 err = EBUSY;
1455 1432 } else if ((olp = ndmp_malloc(sizeof (struct open_list))) == NULL) {
1456 1433 err = ENOMEM;
1457 1434 } else if ((olp->ol_devnm = strdup(dev)) == NULL) {
1458 - NDMP_LOG(LOG_ERR, "Out of memory.");
1435 + syslog(LOG_ERR, "Out of memory.");
1459 1436 free(olp);
1460 1437 err = ENOMEM;
1461 1438 } else {
1462 1439 olp->cl_conn = conn;
1463 1440 olp->ol_nref = 1;
1464 1441 olp->ol_sid = sid;
1465 1442 olp->ol_lun = lun;
1466 1443 if (fd > 0)
1467 1444 olp->ol_fd = fd;
1468 1445 else
1469 1446 olp->ol_fd = -1;
1470 1447 (void) mutex_lock(&ol_mutex);
1471 1448 LIST_INSERT_HEAD(olhp, olp, ol_q);
1472 1449 (void) mutex_unlock(&ol_mutex);
1473 1450 }
1474 1451
1475 1452 return (err);
1476 1453 }
1477 1454
1478 1455
1479 1456 /*
1480 1457 * ndmp_open_list_del
1481 1458 *
1482 1459 * Delete a specific device from the open list
1483 1460 *
1484 1461 * Parameters:
1485 1462 * dev (input) - device name
1486 1463 * sid (input) - SCSI target ID
1487 1464 * lun (input) - LUN number
|
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
1488 1465 *
1489 1466 * Returns:
1490 1467 * errno
1491 1468 */
1492 1469 int
1493 1470 ndmp_open_list_del(char *dev, int sid, int lun)
1494 1471 {
1495 1472 struct open_list *olp;
1496 1473
1497 1474 if (dev == NULL || *dev == '\0') {
1498 - NDMP_LOG(LOG_DEBUG, "Invalid argument");
1475 + syslog(LOG_DEBUG, "Invalid argument");
1499 1476 return (EINVAL);
1500 1477 }
1501 1478 if ((olp = ndmp_open_list_find(dev, sid, lun)) == NULL) {
1502 - NDMP_LOG(LOG_DEBUG, "%s not found", dev);
1479 + syslog(LOG_DEBUG, "%s not found", dev);
1503 1480 return (ENOENT);
1504 1481 }
1505 1482
1506 1483 (void) mutex_lock(&ol_mutex);
1507 1484 if (--olp->ol_nref <= 0) {
1508 - NDMP_LOG(LOG_DEBUG,
1509 - "Removed dev: %s, sid: %d, lun: %d", dev, sid, lun);
1510 1485 LIST_REMOVE(olp, ol_q);
1511 1486 free(olp->ol_devnm);
1512 1487 free(olp);
1513 1488 }
1514 1489 (void) mutex_unlock(&ol_mutex);
1515 1490
1516 1491 return (0);
1517 1492 }
1518 1493
1519 1494
1520 1495 /*
1521 1496 * ndmp_open_list_release
1522 1497 *
1523 1498 * Close all the resources belonging to this connection.
1524 1499 *
1525 1500 * Parameters:
1526 1501 * ndmp_connection_t *conn : connection identifier
1527 1502 *
1528 1503 * Returns:
1529 1504 * void
1530 1505 */
1531 1506 void
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
1532 1507 ndmp_open_list_release(ndmp_connection_t *conn)
1533 1508 {
1534 1509 struct ol_head *olhp = &ol_head;
1535 1510 struct open_list *olp;
1536 1511 struct open_list *next;
1537 1512
1538 1513 (void) mutex_lock(&ol_mutex);
1539 1514 olp = LIST_FIRST(olhp);
1540 1515 while (olp != NULL) {
1541 1516 next = LIST_NEXT(olp, ol_q);
1542 - NDMP_LOG(LOG_DEBUG, "olp->conn 0x%08x", olp->cl_conn);
1543 1517 if (olp->cl_conn == conn) {
1544 - NDMP_LOG(LOG_DEBUG,
1545 - "Removed dev: %s, sid: %d, lun: %d",
1546 - olp->ol_devnm, olp->ol_sid, olp->ol_lun);
1547 1518 LIST_REMOVE(olp, ol_q);
1548 1519 if (olp->ol_fd > 0)
1549 1520 (void) close(olp->ol_fd);
1550 1521 free(olp->ol_devnm);
1551 1522 free(olp);
1552 1523 }
1553 1524 olp = next;
1554 1525 }
1555 1526 (void) mutex_unlock(&ol_mutex);
1556 1527 }
1557 1528
1558 1529
1559 1530 /*
1560 1531 * ndmp_stop_buffer_worker
1561 1532 *
1562 1533 * Stop all reader and writer threads for a specific buffer.
1563 1534 *
1564 1535 * Parameters:
1565 1536 * session (input) - session pointer
1566 1537 *
1567 1538 * Returns:
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
1568 1539 * void
1569 1540 */
1570 1541 void
1571 1542 ndmp_stop_buffer_worker(ndmpd_session_t *session)
1572 1543 {
1573 1544 ndmp_lbr_params_t *nlp;
1574 1545 tlm_commands_t *cmds;
1575 1546
1576 1547 session->ns_tape.td_pos = 0;
1577 1548 if ((nlp = ndmp_get_nlp(session)) == NULL) {
1578 - NDMP_LOG(LOG_DEBUG, "nlp == NULL");
1549 + syslog(LOG_DEBUG, "nlp == NULL");
1579 1550 } else {
1580 1551 cmds = &nlp->nlp_cmds;
1581 - if (cmds->tcs_command == NULL) {
1582 - NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL");
1583 - } else {
1552 + if (cmds->tcs_command != NULL) {
1584 1553 cmds->tcs_reader = cmds->tcs_writer = TLM_ABORT;
1585 1554 cmds->tcs_command->tc_reader = TLM_ABORT;
1586 1555 cmds->tcs_command->tc_writer = TLM_ABORT;
1587 1556 while (cmds->tcs_reader_count > 0 ||
1588 1557 cmds->tcs_writer_count > 0) {
1589 - NDMP_LOG(LOG_DEBUG,
1558 + syslog(LOG_DEBUG,
1590 1559 "trying to stop buffer worker");
1591 1560 (void) sleep(1);
1592 1561 }
1593 1562 }
1594 1563 }
1595 1564 }
1596 1565
1597 1566
1598 1567 /*
1599 1568 * ndmp_stop_reader_thread
1600 1569 *
1601 1570 * Stop only the reader threads of a specific buffer
1602 1571 *
1603 1572 * Parameters:
1604 1573 * session (input) - session pointer
1605 1574 *
|
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
1606 1575 * Returns:
1607 1576 * void
1608 1577 */
1609 1578 void
1610 1579 ndmp_stop_reader_thread(ndmpd_session_t *session)
1611 1580 {
1612 1581 ndmp_lbr_params_t *nlp;
1613 1582 tlm_commands_t *cmds;
1614 1583
1615 1584 if ((nlp = ndmp_get_nlp(session)) == NULL) {
1616 - NDMP_LOG(LOG_DEBUG, "nlp == NULL");
1585 + syslog(LOG_DEBUG, "nlp == NULL");
1617 1586 } else {
1618 1587 cmds = &nlp->nlp_cmds;
1619 - if (cmds->tcs_command == NULL) {
1620 - NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL");
1621 - } else {
1588 + if (cmds->tcs_command != NULL) {
1622 1589 cmds->tcs_reader = TLM_ABORT;
1623 1590 cmds->tcs_command->tc_reader = TLM_ABORT;
1624 1591 while (cmds->tcs_reader_count > 0) {
1625 - NDMP_LOG(LOG_DEBUG,
1592 + syslog(LOG_DEBUG,
1626 1593 "trying to stop reader thread");
1627 1594 (void) sleep(1);
1628 1595 }
1629 1596 }
1630 1597 }
1631 1598 }
1632 1599
1633 1600
1634 1601 /*
1635 1602 * ndmp_stop_reader_thread
1636 1603 *
1637 1604 * Stop only the writer threads of a specific buffer
1638 1605 *
1639 1606 * Parameters:
1640 1607 * session (input) - session pointer
1641 1608 *
|
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
1642 1609 * Returns:
1643 1610 * void
1644 1611 */
1645 1612 void
1646 1613 ndmp_stop_writer_thread(ndmpd_session_t *session)
1647 1614 {
1648 1615 ndmp_lbr_params_t *nlp;
1649 1616 tlm_commands_t *cmds;
1650 1617
1651 1618 if ((nlp = ndmp_get_nlp(session)) == NULL) {
1652 - NDMP_LOG(LOG_DEBUG, "nlp == NULL");
1619 + syslog(LOG_DEBUG, "nlp == NULL");
1653 1620 } else {
1654 1621 cmds = &nlp->nlp_cmds;
1655 - if (cmds->tcs_command == NULL) {
1656 - NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL");
1657 - } else {
1622 + if (cmds->tcs_command != NULL) {
1658 1623 (void) mutex_lock(&nlp->nlp_mtx);
1659 1624 cmds->tcs_writer = TLM_ABORT;
1660 1625 cmds->tcs_command->tc_writer = TLM_ABORT;
1661 1626 (void) cond_broadcast(&nlp->nlp_cv);
1662 1627 (void) mutex_unlock(&nlp->nlp_mtx);
1663 1628 while (cmds->tcs_writer_count > 0) {
1664 - NDMP_LOG(LOG_DEBUG,
1629 + syslog(LOG_DEBUG,
1665 1630 "trying to stop writer thread");
1666 1631 (void) sleep(1);
1667 1632 }
1668 1633 }
1669 1634 }
1670 1635 }
1671 1636
1672 1637
1673 1638 /*
1674 1639 * ndmp_free_reader_writer_ipc
1675 1640 *
1676 1641 * Free and release the reader/writer buffers and the IPC structure
1677 1642 * for reader and writer threads.
1678 1643 *
1679 1644 * Parameters:
1680 1645 * session (input) - session pointer
1681 1646 *
1682 1647 * Returns:
1683 1648 * void
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
1684 1649 */
1685 1650 void
1686 1651 ndmp_free_reader_writer_ipc(ndmpd_session_t *session)
1687 1652 {
1688 1653 ndmp_lbr_params_t *nlp;
1689 1654 tlm_commands_t *cmds;
1690 1655
1691 1656 if ((nlp = ndmp_get_nlp(session)) != NULL) {
1692 1657 cmds = &nlp->nlp_cmds;
1693 1658 if (cmds->tcs_command != NULL) {
1694 - NDMP_LOG(LOG_DEBUG, "cmds->tcs_command->tc_ref: %d",
1659 + syslog(LOG_DEBUG, "cmds->tcs_command->tc_ref: %d",
1695 1660 cmds->tcs_command->tc_ref);
1696 1661 tlm_release_reader_writer_ipc(cmds->tcs_command);
1697 1662 }
1698 1663 }
1699 1664 }
1700 1665
1701 1666
1702 1667 /*
1703 1668 * ndmp_waitfor_op
1704 1669 *
1705 1670 * Wait for a session reference count to drop to zero
1706 1671 *
1707 1672 * Parameters:
1708 1673 * session (input) - session pointer
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
1709 1674 *
1710 1675 * Returns:
1711 1676 * void
1712 1677 */
1713 1678 void
1714 1679 ndmp_waitfor_op(ndmpd_session_t *session)
1715 1680 {
1716 1681 if (session != NULL) {
1717 1682 while (session->ns_nref > 0) {
1718 1683 (void) sleep(1);
1719 - NDMP_LOG(LOG_DEBUG,
1720 - "waiting for session nref: %d", session->ns_nref);
1721 1684 }
1722 1685 }
1723 1686 }
1724 1687
1725 1688
1726 1689 /*
1727 1690 * ndmp_session_ref
1728 1691 *
1729 1692 * Increment the reference count of the session
1730 1693 *
1731 1694 * Parameters:
1732 1695 * session (input) - session pointer
1733 1696 *
1734 1697 * Returns:
1735 1698 * void
1736 1699 */
1737 1700 void
1738 1701 ndmp_session_ref(ndmpd_session_t *session)
1739 1702 {
1740 1703 (void) mutex_lock(&session->ns_lock);
1741 1704 session->ns_nref++;
1742 1705 (void) mutex_unlock(&session->ns_lock);
1743 1706 }
1744 1707
1745 1708
1746 1709 /*
1747 1710 * ndmp_session_unref
1748 1711 *
1749 1712 * Decrement the reference count of the session
1750 1713 *
1751 1714 * Parameters:
1752 1715 * session (input) - session pointer
1753 1716 *
1754 1717 * Returns:
1755 1718 * void
1756 1719 */
1757 1720 void
1758 1721 ndmp_session_unref(ndmpd_session_t *session)
1759 1722 {
1760 1723 (void) mutex_lock(&session->ns_lock);
1761 1724 session->ns_nref--;
1762 1725 (void) mutex_unlock(&session->ns_lock);
1763 1726 }
1764 1727
1765 1728
1766 1729 /*
1767 1730 * ndmp_addr2str_v3
1768 1731 *
1769 1732 * Convert the address type to a string
1770 1733 *
1771 1734 * Parameters:
1772 1735 * type (input) - address type
1773 1736 *
1774 1737 * Returns:
1775 1738 * type in string
1776 1739 */
1777 1740 char *
1778 1741 ndmp_addr2str_v3(ndmp_addr_type type)
1779 1742 {
1780 1743 char *rv;
1781 1744
1782 1745 switch (type) {
1783 1746 case NDMP_ADDR_LOCAL:
1784 1747 rv = "Local";
1785 1748 break;
1786 1749 case NDMP_ADDR_TCP:
1787 1750 rv = "TCP";
1788 1751 break;
1789 1752 case NDMP_ADDR_FC:
1790 1753 rv = "FC";
1791 1754 break;
1792 1755 case NDMP_ADDR_IPC:
1793 1756 rv = "IPC";
1794 1757 break;
1795 1758 default:
1796 1759 rv = "Unknown";
1797 1760 }
1798 1761
1799 1762 return (rv);
1800 1763 }
1801 1764
1802 1765
1803 1766 /*
1804 1767 * ndmp_valid_v3addr_type
1805 1768 *
1806 1769 * Make sure that the NDMP address is from any of the
1807 1770 * valid types
1808 1771 *
1809 1772 * Parameters:
1810 1773 * type (input) - address type
1811 1774 *
1812 1775 * Returns:
1813 1776 * 1: valid
1814 1777 * 0: invalid
1815 1778 */
1816 1779 boolean_t
1817 1780 ndmp_valid_v3addr_type(ndmp_addr_type type)
1818 1781 {
1819 1782 boolean_t rv;
1820 1783
1821 1784 switch (type) {
1822 1785 case NDMP_ADDR_LOCAL:
1823 1786 case NDMP_ADDR_TCP:
1824 1787 case NDMP_ADDR_FC:
1825 1788 case NDMP_ADDR_IPC:
1826 1789 rv = TRUE;
1827 1790 break;
1828 1791 default:
1829 1792 rv = FALSE;
1830 1793 }
1831 1794
1832 1795 return (rv);
1833 1796 }
1834 1797
1835 1798
1836 1799 /*
1837 1800 * ndmp_copy_addr_v3
1838 1801 *
1839 1802 * Copy NDMP address from source to destination (V2 and V3 only)
1840 1803 *
1841 1804 * Parameters:
1842 1805 * dst (ouput) - destination address
1843 1806 * src (input) - source address
1844 1807 *
1845 1808 * Returns:
1846 1809 * void
1847 1810 */
1848 1811 void
1849 1812 ndmp_copy_addr_v3(ndmp_addr_v3 *dst, ndmp_addr_v3 *src)
1850 1813 {
1851 1814 dst->addr_type = src->addr_type;
1852 1815 switch (src->addr_type) {
1853 1816 case NDMP_ADDR_LOCAL:
1854 1817 /* nothing */
1855 1818 break;
1856 1819 case NDMP_ADDR_TCP:
1857 1820 dst->tcp_ip_v3 = htonl(src->tcp_ip_v3);
1858 1821 dst->tcp_port_v3 = src->tcp_port_v3;
1859 1822 break;
1860 1823 case NDMP_ADDR_FC:
1861 1824 case NDMP_ADDR_IPC:
1862 1825 default:
1863 1826 break;
1864 1827 }
1865 1828 }
1866 1829
1867 1830
1868 1831 /*
1869 1832 * ndmp_copy_addr_v4
1870 1833 *
1871 1834 * Copy NDMP address from source to destination. V4 has a extra
1872 1835 * environment list inside the address too which needs to be copied.
1873 1836 *
1874 1837 * Parameters:
1875 1838 * dst (ouput) - destination address
1876 1839 * src (input) - source address
1877 1840 *
1878 1841 * Returns:
1879 1842 * void
1880 1843 */
1881 1844 void
1882 1845 ndmp_copy_addr_v4(ndmp_addr_v4 *dst, ndmp_addr_v4 *src)
1883 1846 {
1884 1847 int i;
1885 1848
1886 1849 dst->addr_type = src->addr_type;
1887 1850 dst->tcp_len_v4 = src->tcp_len_v4;
1888 1851 switch (src->addr_type) {
1889 1852 case NDMP_ADDR_LOCAL:
1890 1853 /* nothing */
1891 1854 break;
1892 1855 case NDMP_ADDR_TCP:
1893 1856 dst->tcp_addr_v4 = ndmp_malloc(sizeof (ndmp_tcp_addr_v4) *
1894 1857 src->tcp_len_v4);
1895 1858 if (dst->tcp_addr_v4 == 0)
1896 1859 return;
1897 1860
1898 1861 for (i = 0; i < src->tcp_len_v4; i++) {
1899 1862 dst->tcp_ip_v4(i) = htonl(src->tcp_ip_v4(i));
1900 1863 dst->tcp_port_v4(i) = src->tcp_port_v4(i);
1901 1864 dst->tcp_env_v4(i).addr_env_len = 0; /* Solaris */
1902 1865 dst->tcp_env_v4(i).addr_env_val = 0; /* Solaris */
1903 1866 }
1904 1867 break;
1905 1868 case NDMP_ADDR_FC:
1906 1869 case NDMP_ADDR_IPC:
1907 1870 default:
1908 1871 break;
1909 1872 }
1910 1873 }
1911 1874
1912 1875
1913 1876 /*
1914 1877 * ndmp_connect_sock_v3
1915 1878 *
1916 1879 * Creates a socket and connects to the specified address/port
1917 1880 *
1918 1881 * Parameters:
1919 1882 * addr (input) - IP address
1920 1883 * port (input) - port number
1921 1884 *
|
↓ open down ↓ |
191 lines elided |
↑ open up ↑ |
1922 1885 * Returns:
1923 1886 * 0: on success
1924 1887 * -1: otherwise
1925 1888 */
1926 1889 int
1927 1890 ndmp_connect_sock_v3(ulong_t addr, ushort_t port)
1928 1891 {
1929 1892 int sock;
1930 1893 struct sockaddr_in sin;
1931 1894
1932 - NDMP_LOG(LOG_DEBUG, "addr %s:%d", inet_ntoa(IN_ADDR(addr)), port);
1933 1895
1934 1896 sock = socket(AF_INET, SOCK_STREAM, 0);
1935 1897 if (sock < 0) {
1936 - NDMP_LOG(LOG_DEBUG, "Socket error: %m");
1898 + syslog(LOG_DEBUG, "Socket error: %m");
1937 1899 return (-1);
1938 1900 }
1939 1901
1940 1902 (void) memset((void *) &sin, 0, sizeof (sin));
1941 1903 sin.sin_family = AF_INET;
1942 1904 sin.sin_addr.s_addr = htonl(addr);
1943 1905 sin.sin_port = htons(port);
1944 1906 if (connect(sock, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
1945 - NDMP_LOG(LOG_DEBUG, "Connect error: %m");
1907 + syslog(LOG_DEBUG, "Connect error: %m");
1946 1908 (void) close(sock);
1947 1909 return (-1);
1948 1910 }
1949 1911
1912 + syslog(LOG_DEBUG, "Remote addr %s:%d", inet_ntoa(IN_ADDR(addr)), port);
1913 +
1950 1914 set_socket_options(sock);
1951 - NDMP_LOG(LOG_DEBUG, "sock %d", sock);
1952 1915
1953 1916 return (sock);
1954 1917 }
1955 1918
1956 1919 /*
1957 1920 * ndmp_create_socket
1958 1921 *
1959 1922 * Creates a socket for listening for accepting data connections.
1960 1923 *
1961 1924 * Parameters:
1962 1925 * session (input) - session pointer.
1963 1926 * addr (output) - location to store address of socket.
1964 1927 * port (output) - location to store port of socket.
1965 1928 *
1966 1929 * Returns:
1967 1930 * 0 - success.
1968 1931 * -1 - error.
1969 1932 */
1970 1933 int
1971 1934 ndmp_create_socket(ulong_t *addr, ushort_t *port)
1972 1935 {
1973 1936 char *p;
1974 1937 int length;
1975 1938 int sd;
1976 1939 struct sockaddr_in sin;
1977 1940
1978 1941 /* Try the user's prefered NIC IP address */
1979 1942 p = ndmpd_get_prop(NDMP_MOVER_NIC);
1980 1943
|
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
1981 1944 /* Try host's IP address */
1982 1945 if (!p || *p == 0)
1983 1946 p = gethostaddr();
1984 1947
1985 1948 /* Try default NIC's IP address (if DNS failed) */
1986 1949 if (!p)
1987 1950 p = get_default_nic_addr();
1988 1951
1989 1952 /* Fail if no IP can be obtained */
1990 1953 if (!p) {
1991 - NDMP_LOG(LOG_ERR, "Undetermined network port.");
1954 + syslog(LOG_ERR, "Undetermined network port.");
1992 1955 return (-1);
1993 1956 }
1994 1957
1995 1958 *addr = inet_addr(p);
1996 1959
1997 1960 sd = socket(AF_INET, SOCK_STREAM, 0);
1998 1961 if (sd < 0) {
1999 - NDMP_LOG(LOG_DEBUG, "Socket error: %m");
1962 + syslog(LOG_DEBUG, "Socket error: %m");
2000 1963 return (-1);
2001 1964 }
2002 1965 sin.sin_family = AF_INET;
2003 1966 sin.sin_addr.s_addr = INADDR_ANY;
2004 1967 sin.sin_port = 0;
2005 1968 length = sizeof (sin);
2006 1969
2007 1970 if (bind(sd, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
2008 - NDMP_LOG(LOG_DEBUG, "Bind error: %m");
1971 + syslog(LOG_DEBUG, "Bind error: %m");
2009 1972 (void) close(sd);
2010 1973 sd = -1;
2011 1974 } else if (getsockname(sd, (struct sockaddr *)&sin, &length) < 0) {
2012 - NDMP_LOG(LOG_DEBUG, "getsockname error: %m");
1975 + syslog(LOG_DEBUG, "getsockname error: %m");
2013 1976 (void) close(sd);
2014 1977 sd = -1;
2015 1978 } else if (listen(sd, 5) < 0) {
2016 - NDMP_LOG(LOG_DEBUG, "Listen error: %m");
1979 + syslog(LOG_DEBUG, "Listen error: %m");
2017 1980 (void) close(sd);
2018 1981 sd = -1;
2019 1982 } else
2020 1983 *port = sin.sin_port;
2021 1984
2022 1985 return (sd);
2023 1986 }
2024 1987
2025 1988
2026 1989 /*
2027 1990 * cctime
2028 1991 *
2029 1992 * Convert the specified time into a string. It's like
2030 1993 * ctime(), but:
2031 1994 * - chops the trailing '\n' of ctime.
2032 1995 * - and returns "the epoch" if time is 0.
2033 1996 *
2034 1997 * Returns:
2035 1998 * "": invalid argument.
2036 1999 * "the epoch": if time is 0.
2037 2000 * string format of the time.
2038 2001 */
2039 2002 char *
2040 2003 cctime(time_t *t)
2041 2004 {
2042 2005 char *bp, *cp;
2043 2006 static char tbuf[BUFSIZ];
2044 2007
2045 2008 if (!t)
2046 2009 return ("");
2047 2010
2048 2011 if (*t == (time_t)0)
2049 2012 return ("the epoch");
2050 2013
2051 2014 if ((bp = ctime_r(t, tbuf, BUFSIZ)) == NULL)
2052 2015 return ("");
2053 2016
2054 2017 cp = strchr(bp, '\n');
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
2055 2018 if (cp)
2056 2019 *cp = '\0';
2057 2020
2058 2021 return (bp);
2059 2022 }
2060 2023
2061 2024
2062 2025 /*
2063 2026 * ndmp_new_job_name
2064 2027 *
2065 - * Create a job name for each backup/restore to keep track
2028 + * Copy, at most, 'n' characters of the current backup
2029 + * job name to the buffer in parameter 's1'.
2066 2030 *
2067 2031 * Parameters:
2068 - * jname (output) - job name
2069 2032 *
2033 + * s1 (input) - pointer to a user supplied buffer
2034 + * n (input) - number of bytes to copy
2035 + *
2070 2036 * Returns:
2071 - * jname
2037 + * count of bytes in name
2072 2038 */
2073 -char *
2074 -ndmp_new_job_name(char *jname)
2075 -{
2076 - if (jname != NULL) {
2077 - (void) snprintf(jname, TLM_MAX_BACKUP_JOB_NAME, "%s%d",
2078 - NDMP_RCF_BASENAME, ndmp_job_cnt++);
2079 - NDMP_LOG(LOG_DEBUG, "jname: \"%s\"", jname);
2080 - }
2081 2039
2082 - return (jname);
2040 +int
2041 +ndmp_new_job_name(char *s1, size_t n) {
2042 +
2043 + if (n >= TLM_MAX_BACKUP_JOB_NAME) {
2044 + /*
2045 + * TLM_MAX_BACKUP_JOB_NAME is the fixed length of
2046 + * the encoded job name in the format `NdmpBackup.nnnn\0`,
2047 + * where nnnn is a job sequence number. A null byte
2048 + * is included. It is okay if the buffer is bigger than that.
2049 + */
2050 + return (snprintf(s1, n, "%10s.%04d",
2051 + NDMP_RCF_BASENAME, ndmp_job_cnt++%1000));
2052 + }
2053 + return (0);
2083 2054 }
2084 2055
2056 +/*
2057 + * Check if the volume is already checkpointed. Assume it is not
2058 + * by setting nlp_snapname to '\0' at first. It will be filled
2059 + * in with the checkpoint (snapshot name) if one is found.
2060 + */
2061 +boolean_t
2062 +fs_is_checkpointed(ndmp_lbr_params_t *nlp)
2063 +{
2064 + zfs_handle_t *zhp;
2065 + snap_data_t si;
2085 2066
2067 + (void) mutex_lock(&zlib_mtx);
2068 + if ((zhp = zfs_open(zlibh, nlp->nlp_vol, ZFS_TYPE_DATASET)) != NULL) {
2069 + nlp->nlp_snapname[0] = '\0';
2070 + si.creation_time = (time_t)0;
2071 + si.last_snapshot = nlp->nlp_snapname;
2072 + if (ndmp_find_latest_autosync(zhp, (void *) &si) != 0) {
2073 + syslog(LOG_ERR,
2074 + "Find AutoSync failed (err=%d): %s",
2075 + errno, libzfs_error_description(zlibh));
2076 + zfs_close(zhp);
2077 + (void) mutex_unlock(&zlib_mtx);
2078 + return (B_FALSE);
2079 + }
2080 + zfs_close(zhp);
2081 + if (strlen(nlp->nlp_snapname) == 0) {
2082 + syslog(LOG_DEBUG, "Apparently not an "
2083 + "Auto-Sync - continue as normal backup");
2084 + (void) mutex_unlock(&zlib_mtx);
2085 + return (B_FALSE);
2086 + }
2087 + }
2088 + (void) mutex_unlock(&zlib_mtx);
2089 + syslog(LOG_DEBUG, "It is an autosync:");
2090 + syslog(LOG_DEBUG, "nlp->nlp_vol = [%s]", nlp->nlp_vol);
2091 + syslog(LOG_DEBUG, "nlp->nlp_snapname = [%s]", nlp->nlp_snapname);
2092 + return (B_TRUE);
2093 +}
2094 +
2086 2095 /*
2087 2096 * fs_is_valid_logvol
2088 2097 *
2089 2098 * Check if the log path exists
2090 2099 *
2091 2100 * Parameters:
2092 2101 * path (input) - log path
2093 2102 *
2094 2103 * Returns:
2095 2104 * FALSE: invalid
2096 2105 * TRUE: valid
2097 2106 */
2098 2107 boolean_t
2099 2108 fs_is_valid_logvol(char *path)
2100 2109 {
2101 2110 struct stat64 st;
2102 2111
2103 2112 if (stat64(path, &st) < 0)
2104 - return (FALSE);
2113 + return (B_FALSE);
2105 2114
2106 - return (TRUE);
2115 + return (B_TRUE);
2107 2116 }
2108 2117
2109 2118
2110 2119 /*
2111 2120 * ndmpd_mk_temp
2112 2121 *
2113 2122 * Make a temporary file using the working directory path and the
2114 2123 * jobname
2115 2124 *
2116 2125 * Parameters:
2117 2126 * buf (output) - the temporary file name path
2118 2127 *
2119 2128 * Returns:
2120 2129 * buf
2121 2130 */
2122 2131 char *
2123 -ndmpd_mk_temp(char *buf)
2132 +ndmpd_mk_temp(char * fname, char *buf)
2124 2133 {
2125 - char fname[TLM_MAX_BACKUP_JOB_NAME];
2126 2134 const char *dir;
2127 2135 char *rv;
2128 2136
2129 2137 if (!buf)
2130 2138 return (NULL);
2131 2139
2132 2140 dir = ndmpd_get_prop(NDMP_DEBUG_PATH);
2133 2141 if (dir == 0 || *dir == '\0') {
2134 - NDMP_LOG(LOG_DEBUG, "NDMP work path not specified");
2142 + syslog(LOG_DEBUG, "NDMP work path not specified");
2135 2143 return (0);
2136 2144 }
2137 2145
2146 + /*
2147 + * Make sure the NDMP work directory exists.
2148 + */
2149 + if (ndmpd_mkdir(dir) < 0) {
2150 + syslog(LOG_DEBUG,
2151 + "Could not create NDMP work path %s", dir);
2152 + return (0);
2153 + }
2154 +
2138 2155 if (!fs_is_valid_logvol((char *)dir)) {
2139 - NDMP_LOG(LOG_ERR,
2140 - "Log file path cannot be on system volumes.");
2156 + syslog(LOG_ERR,
2157 + "Log file path cannot be on system volumes");
2141 2158 return (0);
2142 2159 }
2143 2160
2144 2161 dir += strspn(dir, " \t");
2145 2162 if (!*dir) {
2146 - NDMP_LOG(LOG_DEBUG, "NDMP work path not specified");
2163 + syslog(LOG_DEBUG, "NDMP work path not specified");
2147 2164 return (0);
2148 2165 }
2149 2166
2150 2167 rv = buf;
2151 - (void) ndmp_new_job_name(fname);
2168 +
2152 2169 (void) tlm_cat_path(buf, (char *)dir, fname);
2153 2170
2154 2171 return (rv);
2155 2172 }
2156 2173
2174 +/*
2175 + * ndmp_mkdir
2176 + *
2177 + * If the temporary bitmap database directory doesn't exist
2178 + * create it. This keep from having to create directory
2179 + * by hand when it is changed with svcadm.
2180 + *
2181 + * Parameters:
2182 + * dir (input) - the path to create
2183 + *
2184 + * Returns:
2185 + * 0 - success.
2186 + * -1 - error.
2187 + */
2188 +static int
2189 +ndmpd_mkdir(const char *dir)
2190 +{
2191 + char tmp[PATH_MAX];
2192 + char *p = NULL;
2193 + size_t len;
2157 2194
2195 + (void) snprintf(tmp, sizeof (tmp), "%s", dir);
2196 + len = strlen(tmp);
2197 + if (tmp[len - 1] == '/')
2198 + tmp[len - 1] = '\0';
2199 + for (p = tmp + 1; *p; p++) {
2200 + if (*p == '/') {
2201 + *p = '\0';
2202 + if (mkdir(tmp, S_IRWXU) < 0) {
2203 + if (errno != EEXIST) {
2204 + syslog(LOG_ERR,
2205 + "failed to create intermediate path %s\n",
2206 + tmp);
2207 + return (-1);
2208 + }
2209 + }
2210 + *p = '/';
2211 + }
2212 + }
2213 + if (mkdir(tmp, S_IRWXU) < 0) {
2214 + if (errno != EEXIST) {
2215 + syslog(LOG_ERR,
2216 + "failed to create full path %s\n", tmp);
2217 + return (-1);
2218 + }
2219 + }
2220 + return (0);
2221 +}
2222 +
2158 2223 /*
2159 2224 * ndmpd_make_bk_dir_path
2160 2225 *
2161 2226 * Make a directory path for temporary files under the NDMP
2162 2227 * working directory.
2163 2228 *
2164 2229 * Parameters:
2165 2230 * buf (output) - result path
2166 2231 * fname (input) - the file name
2167 2232 *
2168 2233 * Returns:
2169 2234 * buf
2170 2235 */
2171 2236 char *
2172 2237 ndmpd_make_bk_dir_path(char *buf, char *fname)
2173 2238 {
2174 2239 const char *p;
2175 2240 char *name;
2176 2241 char path[PATH_MAX];
2177 2242
2178 2243 if (!buf || !fname || !*fname)
2179 2244 return (NULL);
2180 2245
2181 2246 p = ndmpd_get_prop(NDMP_DEBUG_PATH);
2182 2247 if (p == NULL || *p == '\0' || !fs_is_valid_logvol((char *)p)) {
2183 2248 return (NULL);
2184 2249 }
2185 2250
|
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
2186 2251 (void) strlcpy(path, (char *)p, PATH_MAX);
2187 2252 (void) trim_whitespace(path);
2188 2253
2189 2254 if ((name = strrchr(fname, '/')) == 0)
2190 2255 name = fname;
2191 2256
2192 2257 (void) tlm_cat_path(buf, path, name);
2193 2258 return (buf);
2194 2259 }
2195 2260
2261 +static int
2262 +ndmp_match_checkpoint_name(zfs_handle_t *zhp, void *arg)
2263 +{
2264 + snap_data_t *sd = (snap_data_t *)arg;
2265 + time_t snap_creation;
2266 + nvlist_t *userprops = NULL;
2196 2267
2268 + if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) {
2269 + if ((userprops = zfs_get_user_props(zhp)) != NULL) {
2270 + /*
2271 + * Destination AutoSync snap-shots have
2272 + * 'nms:autosyncmark' property whereas the
2273 + * source dataset snap-shot has has
2274 + * 'nms:service' property. This finds either
2275 + * for use as backup.
2276 + */
2277 + if (nvlist_exists(userprops, "nms:autosyncmark") ||
2278 + nvlist_exists(userprops,
2279 + "com.nexenta.nef:hprsvcid") ||
2280 + nvlist_exists(userprops, "nms:service")) {
2281 + snap_creation = (time_t)zfs_prop_get_int(zhp,
2282 + ZFS_PROP_CREATION);
2283 + if (snap_creation > sd->creation_time) {
2284 + (void) strncpy(
2285 + (char *) sd->last_snapshot,
2286 + zfs_get_name(zhp),
2287 + ZFS_MAX_DATASET_NAME_LEN);
2288 + sd->creation_time = snap_creation;
2289 + }
2290 + }
2291 + }
2292 + }
2293 + zfs_close(zhp);
2294 + return (0);
2295 +}
2296 +
2197 2297 /*
2298 + * ndmp_find_latest_autosync
2299 + *
2300 + * Given a dataset zfs_handlt_t find the latest "AutoSync" snapshot
2301 + */
2302 +int
2303 +ndmp_find_latest_autosync(zfs_handle_t *zhp, void *arg)
2304 +{
2305 + int err;
2306 + snap_data_t *si = (snap_data_t *)arg;
2307 +
2308 + err = zfs_iter_dependents(zhp, B_FALSE,
2309 + ndmp_match_checkpoint_name, (void *)si);
2310 + if (err) {
2311 + syslog(LOG_DEBUG,
2312 + "Trying to find AutoSync zfs_iter_snapshots: %d", err);
2313 + si->last_snapshot = '\0';
2314 + return (-1);
2315 + } else {
2316 + syslog(LOG_DEBUG, "Found most recent AutoSync -> [%s]\n",
2317 + si->last_snapshot);
2318 + }
2319 + return (0);
2320 +}
2321 +
2322 +/*
2198 2323 * ndmp_is_chkpnt_root
2199 2324 *
2200 2325 * Is this a root checkpoint (snapshot) directory.
2201 2326 * Note: a temporary function
2202 2327 */
2203 2328 boolean_t
2204 2329 ndmp_is_chkpnt_root(char *path)
2205 2330 {
2206 2331 struct stat64 st;
2207 2332
2208 2333 if (stat64(path, &st) != 0) {
2209 - NDMP_LOG(LOG_DEBUG, "Couldn't stat path \"%s\"", path);
2334 + syslog(LOG_DEBUG, "Couldn't stat path \"%s\"", path);
2210 2335 return (TRUE);
2211 2336 }
2212 2337 return (FALSE);
2213 2338 }
2214 2339
2215 2340
2216 2341 /*
2217 2342 * ndmpd_make_exc_list
2218 2343 *
2219 2344 * Make a list of files that should not be backed up.
2220 2345 *
2221 2346 * Parameters:
2222 2347 * void
2223 2348 *
2224 2349 * Returns:
2225 2350 * list - array of character strings
2226 2351 */
2227 2352 char **
2228 2353 ndmpd_make_exc_list(void)
2229 2354 {
2230 2355 char *val, **cpp;
2231 2356 int i, n;
2232 2357
2233 2358 n = sizeof (exls);
2234 2359 if ((cpp = ndmp_malloc(n)) != NULL) {
2235 2360 for (i = 0; exls[i] != NULL; i++)
2236 2361 cpp[i] = exls[i];
2237 2362
2238 2363 /*
2239 2364 * If ndmpd_get_prop returns NULL, the array will be
2240 2365 * null-terminated.
2241 2366 */
2242 2367 val = ndmpd_get_prop(NDMP_DEBUG_PATH);
2243 2368 cpp[i] = val;
2244 2369 }
2245 2370
2246 2371 return (cpp);
2247 2372 }
2248 2373
2249 2374
2250 2375 /*
2251 2376 * ndmp_get_bk_dir_ino
2252 2377 *
|
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
2253 2378 * Get the inode number of the backup directory
2254 2379 */
2255 2380 int
2256 2381 ndmp_get_bk_dir_ino(ndmp_lbr_params_t *nlp)
2257 2382 {
2258 2383 int rv;
2259 2384 struct stat64 st;
2260 2385
2261 2386 if (stat64(nlp->nlp_backup_path, &st) != 0) {
2262 2387 rv = -1;
2263 - NDMP_LOG(LOG_DEBUG, "Getting inode # of \"%s\"",
2388 + syslog(LOG_ERR, "Failed to get inode # of \"%s\"",
2264 2389 nlp->nlp_backup_path);
2265 2390 } else {
2266 2391 rv = 0;
2267 2392 nlp->nlp_bkdirino = st.st_ino;
2268 - NDMP_LOG(LOG_DEBUG, "nlp_bkdirino: %lu",
2269 - (uint_t)nlp->nlp_bkdirino);
2270 2393 }
2271 2394
2272 2395 return (rv);
2273 2396 }
2274 2397
2275 2398
2276 2399 /*
2277 2400 * ndmp_check_utf8magic
2278 2401 *
2279 2402 * Check if the magic string for exists in the tar header. This
2280 2403 * magic string (which also indicates that the file names are in
2281 2404 * UTF8 format) is used as a crest to indetify our own tapes.
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
2282 2405 * This checking is always done before all restores except DAR
2283 2406 * restores.
2284 2407 */
2285 2408 boolean_t
2286 2409 ndmp_check_utf8magic(tlm_cmd_t *cmd)
2287 2410 {
2288 2411 char *cp;
2289 2412 int err, len, actual_size;
2290 2413
2291 2414 if (cmd == NULL) {
2292 - NDMP_LOG(LOG_DEBUG, "cmd == NULL");
2415 + syslog(LOG_DEBUG, "cmd == NULL");
2293 2416 return (FALSE);
2294 2417 }
2295 2418 if (cmd->tc_buffers == NULL) {
2296 - NDMP_LOG(LOG_DEBUG, "cmd->tc_buffers == NULL");
2419 + syslog(LOG_DEBUG, "cmd->tc_buffers == NULL");
2297 2420 return (FALSE);
2298 2421 }
2299 2422
2300 2423 /* wait until the first buffer gets full. */
2301 2424 tlm_buffer_in_buf_wait(cmd->tc_buffers);
2302 2425
2303 2426 err = actual_size = 0;
2304 2427 cp = tlm_get_read_buffer(RECORDSIZE, &err, cmd->tc_buffers,
2305 2428 &actual_size);
2306 2429 if (cp == NULL) {
2307 - NDMP_LOG(LOG_DEBUG, "Can't read from buffers, err: %d", err);
2430 + syslog(LOG_DEBUG, "Can't read from buffers, err: %d", err);
2308 2431 return (FALSE);
2309 2432 }
2310 2433 len = strlen(NDMPUTF8MAGIC);
2311 2434 if (actual_size < len) {
2312 - NDMP_LOG(LOG_DEBUG, "Not enough data in the buffers");
2435 + syslog(LOG_DEBUG, "Not enough data in the buffers");
2313 2436 return (FALSE);
2314 2437 }
2315 2438
2316 2439 return ((strncmp(cp, NDMPUTF8MAGIC, len) == 0) ? TRUE : FALSE);
2317 2440 }
2318 2441
2319 2442
2320 2443 /*
2321 2444 * ndmp_get_cur_bk_time
2322 2445 *
2323 2446 * Get the backup checkpoint time.
2324 2447 */
2325 2448 int
2326 -ndmp_get_cur_bk_time(ndmp_lbr_params_t *nlp, time_t *tp, char *jname)
2449 +ndmp_get_cur_bk_time(ndmp_lbr_params_t *nlp, time_t *tp)
2327 2450 {
2328 2451 int err;
2329 2452
2330 - if (!nlp || !nlp->nlp_backup_path || !tp) {
2331 - NDMP_LOG(LOG_DEBUG, "Invalid argument");
2453 + if (!nlp || !tp) {
2454 + syslog(LOG_ERR, "Invalid argument");
2332 2455 return (-1);
2333 2456 }
2334 2457
2335 - if (!fs_is_chkpnt_enabled(nlp->nlp_backup_path)) {
2336 - NDMP_LOG(LOG_DEBUG, "Not a chkpnt volume %s",
2337 - nlp->nlp_backup_path);
2338 - *tp = time(NULL);
2339 - return (0);
2340 - }
2341 -
2342 - err = tlm_get_chkpnt_time(nlp->nlp_backup_path, !NLP_ISCHKPNTED(nlp),
2343 - tp, jname);
2458 + err = tlm_get_chkpnt_time(nlp->nlp_snapname, tp);
2344 2459 if (err != 0) {
2345 - NDMP_LOG(LOG_DEBUG, "Can't checkpoint time");
2460 + syslog(LOG_ERR, "Can't checkpoint time from [%s]",
2461 + nlp->nlp_snapname);
2346 2462 } else {
2347 - NDMP_LOG(LOG_DEBUG, "%s", cctime(tp));
2463 + syslog(LOG_DEBUG, "Checkpoint time of [%s] is [%s]",
2464 + nlp->nlp_snapname, cctime(tp));
2348 2465 }
2349 2466
2350 2467 return (err);
2351 2468 }
2352 2469
2353 2470
2354 2471 /*
2355 2472 * get_relative_path
2356 2473 */
2357 2474 char *
2358 2475 ndmp_get_relative_path(char *base, char *fullpath)
2359 2476 {
2360 2477 char *p = fullpath;
2361 2478
2362 2479 if (!base || !*base)
2363 2480 return (fullpath);
2364 2481
2365 2482 while (*base) {
2366 2483 if (*base != *p)
2367 2484 break;
2368 2485 p++; base++;
2369 2486 }
2370 2487
2371 2488 if (*p == '/')
2372 2489 p++;
2373 2490
2374 2491 return ((*base) ? fullpath : p);
2375 2492 }
2376 2493
2377 2494
2378 2495 /*
2379 2496 * ndmp_get_nlp
2380 2497 *
2381 2498 * Get NDMP local backup parameters
2382 2499 *
2383 2500 * Parameter:
2384 2501 * session cooke
2385 2502 *
2386 2503 * Returns:
2387 2504 * LBR structure
2388 2505 */
2389 2506 ndmp_lbr_params_t *
2390 2507 ndmp_get_nlp(void *cookie)
2391 2508 {
2392 2509 if (cookie == NULL)
2393 2510 return (NULL);
2394 2511
2395 2512 return (((ndmpd_session_t *)cookie)->ns_ndmp_lbr_params);
2396 2513 }
2397 2514
2398 2515
2399 2516 /*
2400 2517 * is_tape_unit_ready
2401 2518 *
2402 2519 * Check if the tape device is ready or not
2403 2520 */
2404 2521 boolean_t
2405 2522 is_tape_unit_ready(char *adptnm, int dev_id)
2406 2523 {
2407 2524 int try;
2408 2525 int fd = 0;
|
↓ open down ↓ |
51 lines elided |
↑ open up ↑ |
2409 2526
2410 2527 try = TUR_MAX_TRY;
2411 2528 if (dev_id <= 0) {
2412 2529 if ((fd = open(adptnm, O_RDONLY | O_NDELAY)) < 0)
2413 2530 return (FALSE);
2414 2531 } else {
2415 2532 fd = dev_id;
2416 2533 }
2417 2534 do {
2418 2535 if (scsi_test_unit_ready(fd) >= 0) {
2419 - NDMP_LOG(LOG_DEBUG, "Unit is ready");
2536 + syslog(LOG_DEBUG, "Unit is ready");
2420 2537
2421 2538 if (dev_id <= 0)
2422 2539 (void) close(fd);
2423 2540
2424 2541 return (TRUE);
2425 2542 }
2426 2543
2427 - NDMP_LOG(LOG_DEBUG, "Unit not ready");
2544 + syslog(LOG_DEBUG, "Unit not ready");
2428 2545 (void) usleep(TUR_WAIT);
2429 2546
2430 2547 } while (--try > 0);
2431 2548
2432 2549 if (dev_id <= 0)
2433 2550 (void) close(fd);
2434 2551
2435 - NDMP_LOG(LOG_DEBUG, "Unit didn't get ready");
2552 + syslog(LOG_DEBUG, "Unit didn't get ready");
2436 2553 return (FALSE);
2437 2554 }
2438 2555
2439 2556
2440 2557 /*
2441 2558 * scsi_test_unit_ready
2442 2559 *
2443 2560 * This is for Test Unit Read, without this function, the only
2444 2561 * impact is getting EBUSY's before each operation which we have
2445 2562 * busy waiting loops checking EBUSY error code.
2446 2563 */
2447 2564 static int
2448 2565 scsi_test_unit_ready(int dev_id)
2449 2566 {
2450 2567 struct uscsi_cmd ucmd;
2451 2568 union scsi_cdb cdb;
2452 2569 int retval;
2453 2570
2454 2571 (void) memset(&ucmd, 0, sizeof (struct uscsi_cmd));
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
2455 2572 (void) memset(&cdb, 0, sizeof (union scsi_cdb));
2456 2573 cdb.scc_cmd = SCMD_TEST_UNIT_READY;
2457 2574 ucmd.uscsi_cdb = (caddr_t)&cdb;
2458 2575 ucmd.uscsi_cdblen = CDB_GROUP0;
2459 2576 ucmd.uscsi_flags |= USCSI_SILENT;
2460 2577 ucmd.uscsi_timeout = 60; /* Allow maximum 1 min */
2461 2578
2462 2579 retval = ioctl(dev_id, USCSICMD, &ucmd);
2463 2580
2464 2581 if (retval != 0 && errno != EIO) {
2465 - NDMP_LOG(LOG_ERR,
2582 + syslog(LOG_ERR,
2466 2583 "Failed to send inquiry request to device: %m.");
2467 - NDMP_LOG(LOG_DEBUG, "Inquiry request failed for"
2584 + syslog(LOG_DEBUG, "Inquiry request failed for"
2468 2585 " dev_id:%d err=%d -%m", dev_id, errno);
2469 2586 retval = -errno;
2470 2587 } else
2471 2588 retval = -(ucmd.uscsi_status);
2472 2589
2473 2590 return (retval);
2474 2591 }
2475 2592
2476 2593
2477 2594 /*
2478 2595 * ndmp_load_params
2479 2596 *
2480 2597 * Load the parameters.
2481 2598 *
2482 2599 * Parameter:
2483 2600 * void
2484 2601 *
2485 2602 * Returns:
2486 2603 * void
2487 2604 */
2488 2605 void
2489 2606 ndmp_load_params(void)
2490 2607 {
2491 2608 ndmp_dump_path_node = ndmpd_get_prop_yorn(NDMP_DUMP_PATHNODE_ENV) ?
2492 2609 TRUE : FALSE;
2493 2610 ndmp_tar_path_node = ndmpd_get_prop_yorn(NDMP_TAR_PATHNODE_ENV) ?
2494 2611 TRUE : FALSE;
2495 2612 ndmp_ignore_ctime =
2496 2613 ndmpd_get_prop_yorn(NDMP_IGNCTIME_ENV) ? TRUE : FALSE;
2497 2614 ndmp_include_lmtime = ndmpd_get_prop_yorn(NDMP_INCLMTIME_ENV) ?
2498 2615 TRUE : FALSE;
|
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
2499 2616 ndmp_max_tok_seq = atoi(ndmpd_get_prop_default(NDMP_MAXSEQ_ENV, "9"));
2500 2617
2501 2618 ndmp_full_restore_path = ndmpd_get_prop_yorn(NDMP_FULL_RESTORE_PATH) ?
2502 2619 TRUE : FALSE;
2503 2620
2504 2621 ndmp_fhinode = ndmpd_get_prop_yorn(NDMP_FHIST_INCR_ENV) ? TRUE : FALSE;
2505 2622
2506 2623 /* Get the value from ndmp SMF property. */
2507 2624 ndmp_dar_support = ndmpd_get_prop_yorn(NDMP_DAR_SUPPORT);
2508 2625
2626 + ndmp_autosync_support = ndmpd_get_prop_yorn(NDMP_AUTOSYNC_SUPPORT);
2627 + ndmp_hpr_support = ndmpd_get_prop_yorn(NDMP_HPR_SUPPORT);
2628 + /*
2629 + * The HPR snapshot feature superscedes autosync and the two can't be
2630 + * active together on the same system.
2631 + */
2632 + if (ndmp_hpr_support) {
2633 + ndmp_autosync_support = 0;
2634 + syslog(LOG_DEBUG, "NDMP_HPR_SUPPORT set to [%d]",
2635 + ndmp_hpr_support);
2636 + }
2637 +
2638 + if (ndmp_autosync_support) {
2639 + syslog(LOG_DEBUG, "NDMP_AUTOSYNC_SUPPORT set to [%d]",
2640 + ndmp_autosync_support);
2641 + }
2642 +
2509 2643 if ((ndmp_ver = atoi(ndmpd_get_prop(NDMP_VERSION_ENV))) == 0)
2510 2644 ndmp_ver = NDMPVER;
2511 2645 }
2512 2646
2513 2647 /*
2514 2648 * randomize
2515 2649 *
2516 2650 * Randomize the contents of a buffer
2517 2651 *
2518 2652 * Parameter:
2519 2653 * buffer (output) - destination buffer
2520 2654 * size (input) - buffer size
2521 2655 *
2522 2656 * Returns:
2523 2657 * void
2524 2658 */
2525 2659 void
2526 2660 randomize(unsigned char *buffer, int size)
2527 2661 {
2528 2662 /* LINTED improper alignment */
2529 2663 unsigned int *p = (unsigned int *)buffer;
2530 2664 unsigned int dwlen = size / sizeof (unsigned int);
2531 2665 unsigned int remlen = size % sizeof (unsigned int);
2532 2666 unsigned int tmp;
2533 2667 unsigned int i;
2534 2668
2535 2669 for (i = 0; i < dwlen; i++)
2536 2670 *p++ = random();
2537 2671
2538 2672 if (remlen) {
2539 2673 tmp = random();
2540 2674 (void) memcpy(p, &tmp, remlen);
2541 2675 }
2542 2676 }
2543 2677
2544 2678 /*
2545 2679 * ndmpd_get_file_entry_type
2546 2680 *
2547 2681 * Converts the mode to the NDMP file type
2548 2682 *
2549 2683 * Parameter:
2550 2684 * mode (input) - file mode
2551 2685 * ftype (output) - file type
2552 2686 *
2553 2687 * Returns:
2554 2688 * void
2555 2689 */
2556 2690 void
2557 2691 ndmpd_get_file_entry_type(int mode, ndmp_file_type *ftype)
2558 2692 {
2559 2693 switch (mode & S_IFMT) {
2560 2694 case S_IFIFO:
2561 2695 *ftype = NDMP_FILE_FIFO;
2562 2696 break;
2563 2697 case S_IFCHR:
2564 2698 *ftype = NDMP_FILE_CSPEC;
2565 2699 break;
2566 2700 case S_IFDIR:
2567 2701 *ftype = NDMP_FILE_DIR;
2568 2702 break;
2569 2703 case S_IFBLK:
2570 2704 *ftype = NDMP_FILE_BSPEC;
2571 2705 break;
2572 2706 case S_IFREG:
2573 2707 *ftype = NDMP_FILE_REG;
2574 2708 break;
2575 2709 case S_IFLNK:
2576 2710 *ftype = NDMP_FILE_SLINK;
2577 2711 break;
2578 2712 default:
2579 2713 *ftype = NDMP_FILE_SOCK;
2580 2714 break;
2581 2715 }
2582 2716 }
2583 2717
2584 2718 /*
2585 2719 * Set a private data in the plugin context
2586 2720 */
2587 2721 void
2588 2722 ndmp_context_set_specific(ndmp_context_t *nctx, void *ptr)
2589 2723 {
2590 2724 nctx->nc_pldata = ptr;
2591 2725 }
2592 2726
2593 2727 /*
2594 2728 * Get a private data in the plugin context
2595 2729 */
2596 2730 void *
2597 2731 ndmp_context_get_specific(ndmp_context_t *nctx)
2598 2732 {
2599 2733 return (nctx->nc_pldata);
2600 2734 }
2601 2735
2602 2736 ndmpd_backup_type_t
2603 2737 ndmp_get_backup_type(ndmp_context_t *ctx)
2604 2738 {
2605 2739 ndmpd_session_t *session = (ndmpd_session_t *)ctx->nc_ddata;
2606 2740
2607 2741 return (session->ns_butype);
2608 2742 }
|
↓ open down ↓ |
90 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX