2 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
8 * Copyright (c) 2007, The Storage Networking Industry Association.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
21 * - Neither the name of The Storage Networking Industry Association (SNIA)
22 * nor the names of its contributors may be used to endorse or promote
23 * products derived from this software without specific prior written
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
38 /* Copyright (c) 2007, The Storage Networking Industry Association. */
39 /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
40 /* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
48 #include <sys/mnttab.h>
49 #include <sys/mntent.h>
50 #include <sys/mntio.h>
51 #include <sys/statvfs.h>
52 #include <sys/utsname.h>
53 #include <sys/scsi/scsi.h>
55 #include <sys/systeminfo.h>
56 #include "ndmpd_common.h"
59 static void simple_get_attrs(ulong_t
*attributes
);
62 * Number of environment variable for the file system
63 * info in V3 net_fs_info.
65 #define V3_N_FS_ENVS 4
68 * Is the file system a valid one to be reported to the
71 #define IS_VALID_FS(fs) (fs && ( \
72 strcasecmp(fs->mnt_fstype, MNTTYPE_UFS) == 0 || \
73 strcasecmp(fs->mnt_fstype, MNTTYPE_ZFS) == 0 || \
74 strcasecmp(fs->mnt_fstype, MNTTYPE_NFS) == 0 || \
75 strcasecmp(fs->mnt_fstype, MNTTYPE_NFS3) == 0 || \
76 strcasecmp(fs->mnt_fstype, MNTTYPE_NFS4) == 0))
78 #define MNTTYPE_LEN 10
80 extern struct fs_ops sfs2_ops
;
81 extern struct fs_ops sfs2cpv_ops
;
85 * ************************************************************************
87 * ************************************************************************
91 * ndmpd_config_get_host_info_v2
93 * This handler handles the ndmp_config_get_host_info request.
94 * Host specific information is returned.
97 * connection (input) - connection handle.
98 * body (input) - request message body.
105 ndmpd_config_get_host_info_v2(ndmp_connection_t
*connection
, void *body
)
107 ndmp_config_get_host_info_reply_v2 reply
;
108 ndmp_auth_type auth_types
[2];
109 char buf
[HOSTNAMELEN
+ 1];
114 (void) memset(&reply
, 0, sizeof (reply
));
115 (void) memset(buf
, 0, sizeof (buf
));
116 (void) gethostname(buf
, sizeof (buf
));
118 reply
.error
= NDMP_NO_ERR
;
119 reply
.hostname
= buf
;
121 reply
.os_type
= uts
.sysname
;
122 reply
.os_vers
= uts
.release
;
124 if (sysinfo(SI_HW_SERIAL
, hostidstr
, sizeof (hostidstr
)) < 0) {
125 NDMP_LOG(LOG_DEBUG
, "sysinfo error: %m.");
126 reply
.error
= NDMP_UNDEFINED_ERR
;
130 * Convert the hostid to hex. The returned string must match
131 * the string returned by hostid(1).
133 hostid
= strtoul(hostidstr
, 0, 0);
134 (void) snprintf(hostidstr
, sizeof (hostidstr
), "%lx", hostid
);
135 reply
.hostid
= hostidstr
;
137 auth_types
[0] = NDMP_AUTH_TEXT
;
138 reply
.auth_type
.auth_type_len
= 1;
139 reply
.auth_type
.auth_type_val
= auth_types
;
141 ndmp_send_reply(connection
, (void *) &reply
,
142 "sending ndmp_config_get_host_info reply");
147 * ndmpd_config_get_butype_attr_v2
149 * This handler handles the ndmp_config_get_butype_attr request.
150 * Information about the specified backup type is returned.
153 * connection (input) - connection handle.
154 * body (input) - request message body.
160 ndmpd_config_get_butype_attr_v2(ndmp_connection_t
*connection
, void *body
)
162 ndmp_config_get_butype_attr_request
*request
;
163 ndmp_config_get_butype_attr_reply reply
;
165 request
= (ndmp_config_get_butype_attr_request
*)body
;
167 reply
.error
= NDMP_NO_ERR
;
169 if (strcmp(request
->name
, "dump") == 0) {
170 (void) simple_get_attrs(&reply
.attrs
);
171 } else if (strcmp(request
->name
, "tar") == 0) {
172 reply
.attrs
= NDMP_NO_BACKUP_FILELIST
;
174 NDMP_LOG(LOG_ERR
, "Invalid backup type: %s.", request
->name
);
176 "Supported backup types are 'dump' and 'tar' only.");
177 reply
.error
= NDMP_ILLEGAL_ARGS_ERR
;
180 ndmp_send_reply(connection
, (void *) &reply
,
181 "sending ndmp_config_get_butype_attr reply");
186 * ndmpd_config_get_mover_type_v2
188 * This handler handles the ndmp_config_get_mover_type request.
189 * Information about the supported mover types is returned.
192 * connection (input) - connection handle.
193 * body (input) - request message body.
200 ndmpd_config_get_mover_type_v2(ndmp_connection_t
*connection
, void *body
)
202 ndmp_config_get_mover_type_reply reply
;
203 ndmp_addr_type types
[2];
205 types
[0] = NDMP_ADDR_LOCAL
;
206 types
[1] = NDMP_ADDR_TCP
;
208 reply
.error
= NDMP_NO_ERR
;
209 reply
.methods
.methods_len
= 2;
210 reply
.methods
.methods_val
= types
;
212 ndmp_send_reply(connection
, (void *) &reply
,
213 "sending ndmp_config_get_mover_type reply");
219 * ndmpd_config_get_auth_attr_v2
221 * This handler handles the ndmp_config_get_auth_attr request.
222 * Authorization type specific information is returned.
225 * connection (input) - connection handle.
226 * body (input) - request message body.
232 ndmpd_config_get_auth_attr_v2(ndmp_connection_t
*connection
, void *body
)
234 ndmp_config_get_auth_attr_request
*request
;
235 ndmp_config_get_auth_attr_reply reply
;
236 ndmpd_session_t
*session
= ndmp_get_client_data(connection
);
238 request
= (ndmp_config_get_auth_attr_request
*)body
;
240 reply
.error
= NDMP_NO_ERR
;
241 reply
.server_attr
.auth_type
= request
->auth_type
;
243 switch (request
->auth_type
) {
247 /* Create a 64 byte random session challenge */
248 randomize(session
->ns_challenge
, MD5_CHALLENGE_SIZE
);
249 (void) memcpy(reply
.server_attr
.ndmp_auth_attr_u
.challenge
,
250 session
->ns_challenge
, MD5_CHALLENGE_SIZE
);
255 NDMP_LOG(LOG_ERR
, "Invalid authentication type: %d.",
258 "Supported authentication types are md5 and cleartext.");
259 reply
.error
= NDMP_ILLEGAL_ARGS_ERR
;
263 ndmp_send_reply(connection
, (void *) &reply
,
264 "sending ndmp_config_get_auth_attr reply");
269 * ************************************************************************
271 * ************************************************************************
275 * ndmpd_config_get_host_info_v3
277 * This handler handles the ndmp_config_get_host_info request.
278 * Host specific information is returned.
281 * connection (input) - connection handle.
282 * body (input) - request message body.
289 ndmpd_config_get_host_info_v3(ndmp_connection_t
*connection
, void *body
)
291 ndmp_config_get_host_info_reply_v3 reply
;
292 char buf
[HOSTNAMELEN
+1];
297 (void) memset(&reply
, 0, sizeof (reply
));
298 (void) memset(buf
, 0, sizeof (buf
));
299 (void) gethostname(buf
, sizeof (buf
));
302 reply
.error
= NDMP_NO_ERR
;
303 reply
.hostname
= buf
;
305 reply
.os_type
= uts
.sysname
;
306 reply
.os_vers
= uts
.release
;
308 if (sysinfo(SI_HW_SERIAL
, hostidstr
, sizeof (hostidstr
)) < 0) {
310 NDMP_LOG(LOG_DEBUG
, "sysinfo error: %m.");
311 reply
.error
= NDMP_UNDEFINED_ERR
;
315 * Convert the hostid to hex. The returned string must match
316 * the string returned by hostid(1).
318 hostid
= strtoul(hostidstr
, 0, 0);
319 (void) snprintf(hostidstr
, sizeof (hostidstr
), "%lx", hostid
);
320 reply
.hostid
= hostidstr
;
322 ndmp_send_reply(connection
, (void *) &reply
,
323 "sending ndmp_config_get_host_info reply");
328 * ndmpd_config_get_connection_type_v3
330 * This handler handles the ndmp_config_get_connection_type_request.
331 * A list of supported data connection types is returned.
334 * connection (input) - connection handle.
335 * body (input) - request message body.
342 ndmpd_config_get_connection_type_v3(ndmp_connection_t
*connection
,
345 ndmp_config_get_connection_type_reply_v3 reply
;
346 ndmp_addr_type addr_types
[2];
348 (void) memset(&reply
, 0, sizeof (reply
));
350 reply
.error
= NDMP_NO_ERR
;
352 addr_types
[0] = NDMP_ADDR_LOCAL
;
353 addr_types
[1] = NDMP_ADDR_TCP
;
354 reply
.addr_types
.addr_types_len
= 2;
355 reply
.addr_types
.addr_types_val
= addr_types
;
357 ndmp_send_reply(connection
, (void *) &reply
,
358 "sending config_get_connection_type_v3 reply");
364 * ndmpd_config_get_auth_attr_v3
366 * This handler handles the ndmp_config_get_auth_attr request.
367 * Authorization type specific information is returned.
370 * connection (input) - connection handle.
371 * body (input) - request message body.
377 ndmpd_config_get_auth_attr_v3(ndmp_connection_t
*connection
, void *body
)
379 ndmp_config_get_auth_attr_request
*request
;
380 ndmp_config_get_auth_attr_reply reply
;
381 ndmpd_session_t
*session
= ndmp_get_client_data(connection
);
383 request
= (ndmp_config_get_auth_attr_request
*)body
;
385 (void) memset(&reply
, 0, sizeof (reply
));
386 reply
.error
= NDMP_NO_ERR
;
387 reply
.server_attr
.auth_type
= request
->auth_type
;
389 switch (request
->auth_type
) {
393 /* Create a 64 bytes random session challenge */
394 randomize(session
->ns_challenge
, MD5_CHALLENGE_SIZE
);
395 (void) memcpy(reply
.server_attr
.ndmp_auth_attr_u
.challenge
,
396 session
->ns_challenge
, MD5_CHALLENGE_SIZE
);
401 NDMP_LOG(LOG_ERR
, "Invalid authentication type: %d.",
404 "Supported authentication types are md5 and cleartext.");
405 reply
.error
= NDMP_ILLEGAL_ARGS_ERR
;
409 ndmp_send_reply(connection
, (void *) &reply
,
410 "sending ndmp_config_get_auth_attr_v3 reply");
415 * ndmpd_config_get_butype_info_v3
417 * This handler handles the ndmp_config_get_butype_info_request.
418 * Information about all supported backup types are returned.
421 * connection (input) - connection handle.
422 * body (input) - request message body.
429 ndmpd_config_get_butype_info_v3(ndmp_connection_t
*connection
, void *body
)
431 ndmp_config_get_butype_info_reply_v3 reply
;
432 ndmp_butype_info info
[3];
435 ndmp_pval
*envp
= envs
;
437 ndmp_pval zfs_envs
[9];
439 ndmp_pval
*zfs_envp
= zfs_envs
;
441 (void) memset(&reply
, 0, sizeof (reply
));
444 * Supported environment variables and their default values
447 * The environment variables for dump and tar format are the
448 * same, because we use the same backup engine for both.
450 NDMP_SETENV(envp
, "PREFIX", "");
451 NDMP_SETENV(envp
, "TYPE", "");
452 NDMP_SETENV(envp
, "DIRECT", "n");
453 NDMP_SETENV(envp
, "HIST", "n");
454 NDMP_SETENV(envp
, "FILESYSTEM", "");
455 NDMP_SETENV(envp
, "LEVEL", "0");
456 NDMP_SETENV(envp
, "UPDATE", "TRUE");
457 NDMP_SETENV(envp
, "BASE_DATE", "");
459 attrs
= NDMP_BUTYPE_BACKUP_FILE_HISTORY
|
460 NDMP_BUTYPE_RECOVER_FILELIST
|
461 NDMP_BUTYPE_BACKUP_DIRECT
|
462 NDMP_BUTYPE_BACKUP_INCREMENTAL
|
463 NDMP_BUTYPE_BACKUP_UTF8
|
464 NDMP_BUTYPE_RECOVER_UTF8
;
466 /* If DAR supported */
467 if (ndmp_dar_support
)
468 attrs
|= NDMP_BUTYPE_RECOVER_DIRECT
;
470 /* tar backup type */
471 info
[0].butype_name
= "tar";
472 info
[0].default_env
.default_env_len
= ARRAY_LEN(envs
, ndmp_pval
);
473 info
[0].default_env
.default_env_val
= envs
;
474 info
[0].attrs
= attrs
;
476 /* dump backup type */
477 info
[1].butype_name
= "dump";
478 info
[1].default_env
.default_env_len
= ARRAY_LEN(envs
, ndmp_pval
);
479 info
[1].default_env
.default_env_val
= envs
;
480 info
[1].attrs
= attrs
;
483 * Supported environment variables and their default values
487 NDMP_SETENV(zfs_envp
, "PREFIX", "");
488 NDMP_SETENV(zfs_envp
, "FILESYSTEM", "");
489 NDMP_SETENV(zfs_envp
, "TYPE", "zfs");
490 NDMP_SETENV(zfs_envp
, "HIST", "n");
491 NDMP_SETENV(zfs_envp
, "LEVEL", "0");
492 NDMP_SETENV(zfs_envp
, "ZFS_MODE", "recursive");
493 NDMP_SETENV(zfs_envp
, "ZFS_FORCE", "FALSE");
494 NDMP_SETENV(zfs_envp
, "UPDATE", "TRUE");
495 NDMP_SETENV(zfs_envp
, "DMP_NAME", "level");
497 zfs_attrs
= NDMP_BUTYPE_BACKUP_UTF8
|
498 NDMP_BUTYPE_RECOVER_UTF8
|
499 NDMP_BUTYPE_BACKUP_DIRECT
|
500 NDMP_BUTYPE_BACKUP_INCREMENTAL
;
502 /* zfs backup type */
503 info
[2].butype_name
= "zfs";
504 info
[2].default_env
.default_env_len
= ARRAY_LEN(zfs_envs
, ndmp_pval
);
505 info
[2].default_env
.default_env_val
= zfs_envs
;
506 info
[2].attrs
= zfs_attrs
;
508 reply
.error
= NDMP_NO_ERR
;
509 reply
.butype_info
.butype_info_len
= ARRAY_LEN(info
, ndmp_butype_info
);
510 reply
.butype_info
.butype_info_val
= info
;
512 ndmp_send_reply(connection
, (void *)&reply
,
513 "sending ndmp_config_get_butype_info reply");
517 * ndmpd_config_get_fs_info_v3
519 * This handler handles the ndmp_config_get_fs_info_request.
520 * Information about all mounted file systems is returned.
523 * connection (input) - connection handle.
524 * body (input) - request message body.
531 ndmpd_config_get_fs_info_v3(ndmp_connection_t
*connection
, void *body
)
533 ndmp_config_get_fs_info_reply_v3 reply
;
534 ndmp_fs_info_v3
*fsip
= NULL
, *fsip_save
= NULL
; /* FS info pointer */
535 int len
= 0, nmnt
, fd
;
538 struct mnttab mt
, *fs
;
539 struct statvfs64 stat_buf
;
540 ndmp_pval
*envp
, *save
;
542 (void) memset(&reply
, 0, sizeof (reply
));
543 reply
.error
= NDMP_NO_ERR
;
545 if ((fd
= open(MNTTAB
, O_RDONLY
)) == -1) {
546 NDMP_LOG(LOG_ERR
, "File mnttab open error: %m.");
547 reply
.error
= NDMP_UNDEFINED_ERR
;
551 /* nothing was found, send an empty reply */
552 if (ioctl(fd
, MNTIOC_NMNTS
, &nmnt
) != 0 || nmnt
<= 0) {
554 NDMP_LOG(LOG_ERR
, "No file system found.");
558 fp
= fdopen(fd
, "r");
561 NDMP_LOG(LOG_ERR
, "File mnttab open error: %m.");
562 reply
.error
= NDMP_UNDEFINED_ERR
;
566 fsip_save
= fsip
= ndmp_malloc(sizeof (ndmp_fs_info_v3
) * nmnt
);
569 reply
.error
= NDMP_NO_MEM_ERR
;
574 * Re-read the directory and set up file system information.
577 while (len
< nmnt
&& (getmntent(fp
, &mt
) == 0))
581 log_dev_len
= strlen(mt
.mnt_mountp
)+2;
582 if (!IS_VALID_FS(fs
))
585 fsip
->fs_logical_device
= ndmp_malloc(log_dev_len
);
586 fsip
->fs_type
= ndmp_malloc(MNTTYPE_LEN
);
587 if (!fsip
->fs_logical_device
|| !fsip
->fs_type
) {
588 free(fsip
->fs_logical_device
);
590 reply
.error
= NDMP_NO_MEM_ERR
;
593 (void) snprintf(fsip
->fs_type
, MNTTYPE_LEN
, "%s",
595 (void) snprintf(fsip
->fs_logical_device
, log_dev_len
, "%s",
599 if (statvfs64(fs
->mnt_mountp
, &stat_buf
) < 0) {
601 "statvfs(%s) error.", fs
->mnt_mountp
);
603 "statvfs error: unable to determine filesystem"
608 long_long_to_quad((u_longlong_t
)stat_buf
.f_frsize
*
609 (u_longlong_t
)stat_buf
.f_blocks
);
611 long_long_to_quad((u_longlong_t
)stat_buf
.f_frsize
*
612 (u_longlong_t
)(stat_buf
.f_blocks
-stat_buf
.f_bfree
));
615 long_long_to_quad((u_longlong_t
)stat_buf
.f_frsize
*
616 (u_longlong_t
)stat_buf
.f_bfree
);
618 long_long_to_quad((u_longlong_t
)stat_buf
.f_files
);
620 long_long_to_quad((u_longlong_t
)(stat_buf
.f_files
-
622 fsip
->fs_status
= "";
624 save
= envp
= ndmp_malloc(sizeof (ndmp_pval
) * V3_N_FS_ENVS
);
626 free(fsip
->fs_logical_device
);
628 reply
.error
= NDMP_NO_MEM_ERR
;
631 (void) memset(save
, 0,
632 V3_N_FS_ENVS
* sizeof (ndmp_pval
));
634 fsip
->fs_env
.fs_env_val
= envp
;
635 NDMP_SETENV(envp
, "LOCAL", "y");
636 NDMP_SETENV(envp
, "TYPE", fsip
->fs_type
);
637 NDMP_SETENV(envp
, "AVAILABLE_BACKUP", "tar,dump");
639 if (FS_READONLY(fs
) == 0) {
640 NDMP_SETENV(envp
, "AVAILABLE_RECOVERY", "tar,dump");
643 fsip
->fs_env
.fs_env_len
= envp
- save
;
650 if (reply
.error
== NDMP_NO_ERR
) {
651 reply
.fs_info
.fs_info_len
= len
;
652 reply
.fs_info
.fs_info_val
= fsip_save
;
654 ndmp_send_reply(connection
, (void *)&reply
,
655 "error sending ndmp_config_get_fs_info reply");
657 while (fsip
> fsip_save
) {
659 free(fsip
->fs_logical_device
);
660 free(fsip
->fs_env
.fs_env_val
);
669 * ndmpd_config_get_tape_info_v3
671 * This handler handles the ndmp_config_get_tape_info_request.
672 * Information about all connected tape drives is returned.
675 * connection (input) - connection handle.
676 * body (input) - request message body.
683 ndmpd_config_get_tape_info_v3(ndmp_connection_t
*connection
, void *body
)
685 ndmp_config_get_tape_info_reply_v3 reply
;
686 ndmp_device_info_v3
*tip
, *tip_save
= NULL
; /* tape info pointer */
687 ndmp_device_capability_v3
*dcp
;
688 ndmp_device_capability_v3
*dcp_save
= NULL
; /* dev capability pointer */
692 ndmp_pval
*envp
, *envp_save
= NULL
;
693 ndmp_pval
*envp_head
;
695 (void) memset(&reply
, 0, sizeof (reply
));
696 max
= sasd_dev_count();
698 tip_save
= tip
= ndmp_malloc(sizeof (ndmp_device_info_v3
) * max
);
699 dcp_save
= dcp
= ndmp_malloc(sizeof (ndmp_device_capability_v3
) * max
);
700 envp_save
= envp
= ndmp_malloc(sizeof (ndmp_pval
) * max
* 3);
701 if (!tip_save
|| !dcp_save
|| !envp_save
) {
705 reply
.error
= NDMP_NO_MEM_ERR
;
706 ndmp_send_reply(connection
, (void *)&reply
,
707 "error sending ndmp_config_get_tape_info reply");
711 reply
.error
= NDMP_NO_ERR
;
713 for (i
= n
= 0; i
< max
; i
++) {
714 if (!(sl
= sasd_dev_slink(i
)) || !(sd
= sasd_drive(i
)))
716 if (sl
->sl_type
!= DTYPE_SEQUENTIAL
)
719 * Don't report dead links.
721 if ((access(sd
->sd_name
, F_OK
) == -1) && (errno
== ENOENT
))
725 "model \"%s\" dev \"%s\"", sd
->sd_id
, sd
->sd_name
);
728 NDMP_SETENV(envp
, "EXECUTE_CDB", "b");
729 NDMP_SETENV(envp
, "SERIAL_NUMBER", sd
->sd_serial
);
730 NDMP_SETENV(envp
, "WORLD_WIDE_NAME", sd
->sd_wwn
);
732 tip
->model
= sd
->sd_id
; /* like "DLT7000 " */
733 tip
->caplist
.caplist_len
= 1;
734 tip
->caplist
.caplist_val
= dcp
;
735 dcp
->device
= sd
->sd_name
; /* like "isp1t060" */
737 dcp
->capability
.capability_len
= 3;
738 dcp
->capability
.capability_val
= envp_head
;
744 NDMP_LOG(LOG_DEBUG
, "n %d", n
);
747 * We should not receive the get_tape_info when three-way backup is
748 * running and we are acting as just data, but some clients try
749 * to get the Tape information anyway.
751 if (n
== 0 || max
<= 0) {
752 reply
.error
= NDMP_NO_DEVICE_ERR
;
753 ndmp_send_reply(connection
, (void *)&reply
,
754 "error sending ndmp_config_get_tape_info reply");
755 free(tip_save
); free(dcp_save
); free(envp_save
);
760 reply
.tape_info
.tape_info_len
= n
;
761 reply
.tape_info
.tape_info_val
= tip_save
;
763 ndmp_send_reply(connection
, (void *)&reply
,
764 "error sending ndmp_config_get_tape_info reply");
773 * ndmpd_config_get_scsi_info_v3
775 * This handler handles the ndmp_config_get_tape_scsi_request.
776 * Information about all connected scsi tape stacker and jukeboxes
780 * connection (input) - connection handle.
781 * body (input) - request message body.
788 ndmpd_config_get_scsi_info_v3(ndmp_connection_t
*connection
, void *body
)
790 ndmp_config_get_scsi_info_reply_v3 reply
;
791 ndmp_device_info_v3
*sip
, *sip_save
;
792 ndmp_device_capability_v3
*dcp
, *dcp_save
;
796 ndmp_pval
*envp
, *envp_save
= NULL
;
797 ndmp_pval
*envp_head
;
799 (void) memset(&reply
, 0, sizeof (reply
));
800 max
= sasd_dev_count();
801 sip_save
= sip
= ndmp_malloc(sizeof (ndmp_device_info_v3
) * max
);
802 dcp_save
= dcp
= ndmp_malloc(sizeof (ndmp_device_capability_v3
) * max
);
803 envp_save
= envp
= ndmp_malloc(sizeof (ndmp_pval
) * max
* 2);
804 if (!sip_save
|| !dcp_save
|| !envp_save
) {
808 reply
.error
= NDMP_NO_MEM_ERR
;
809 ndmp_send_reply(connection
, (void *)&reply
,
810 "error sending ndmp_config_get_scsi_info reply");
814 reply
.error
= NDMP_NO_ERR
;
815 for (i
= n
= 0; i
< max
; i
++) {
816 if (!(sl
= sasd_dev_slink(i
)) || !(sd
= sasd_drive(i
)))
818 if (sl
->sl_type
!= DTYPE_CHANGER
)
821 * Don't report dead links.
823 if ((access(sd
->sd_name
, F_OK
) == -1) && (errno
== ENOENT
))
827 "model \"%s\" dev \"%s\"", sd
->sd_id
, sd
->sd_name
);
830 NDMP_SETENV(envp
, "SERIAL_NUMBER", sd
->sd_serial
);
831 NDMP_SETENV(envp
, "WORLD_WIDE_NAME", sd
->sd_wwn
);
833 sip
->model
= sd
->sd_id
; /* like "Powerstor L200 " */
834 sip
->caplist
.caplist_len
= 1;
835 sip
->caplist
.caplist_val
= dcp
;
836 dcp
->device
= sd
->sd_name
; /* like "isp1m000" */
839 dcp
->capability
.capability_len
= 2;
840 dcp
->capability
.capability_val
= envp_head
;
846 NDMP_LOG(LOG_DEBUG
, "n %d", n
);
848 reply
.scsi_info
.scsi_info_len
= n
;
849 reply
.scsi_info
.scsi_info_val
= sip_save
;
851 ndmp_send_reply(connection
, (void *)&reply
,
852 "error sending ndmp_config_get_scsi_info reply");
861 * ndmpd_config_get_server_info_v3
863 * This handler handles the ndmp_config_get_server_info request.
864 * Host specific information is returned.
867 * connection (input) - connection handle.
868 * body (input) - request message body.
875 ndmpd_config_get_server_info_v3(ndmp_connection_t
*connection
, void *body
)
877 ndmp_config_get_server_info_reply_v3 reply
;
878 ndmp_auth_type auth_types
[2];
880 ndmpd_session_t
*session
= ndmp_get_client_data(connection
);
882 (void) memset(&reply
, 0, sizeof (reply
));
883 reply
.error
= NDMP_NO_ERR
;
885 if (connection
->conn_authorized
||
886 session
->ns_protocol_version
!= NDMPV4
) {
887 reply
.vendor_name
= VENDOR_NAME
;
888 reply
.product_name
= PRODUCT_NAME
;
889 (void) snprintf(rev_number
, sizeof (rev_number
), "%d",
891 reply
.revision_number
= rev_number
;
893 reply
.vendor_name
= "\0";
894 reply
.product_name
= "\0";
895 reply
.revision_number
= "\0";
899 "vendor \"%s\", product \"%s\" rev \"%s\"",
900 reply
.vendor_name
, reply
.product_name
, reply
.revision_number
);
902 auth_types
[0] = NDMP_AUTH_TEXT
;
903 auth_types
[1] = NDMP_AUTH_MD5
;
904 reply
.auth_type
.auth_type_len
= ARRAY_LEN(auth_types
, ndmp_auth_type
);
905 reply
.auth_type
.auth_type_val
= auth_types
;
907 ndmp_send_reply(connection
, (void *)&reply
,
908 "error sending ndmp_config_get_server_info reply");
914 * ************************************************************************
916 * ************************************************************************
920 * ndmpd_config_get_butype_info_v4
922 * This handler handles the ndmp_config_get_butype_info_request.
923 * Information about all supported backup types are returned.
926 * connection (input) - connection handle.
927 * body (input) - request message body.
934 ndmpd_config_get_butype_info_v4(ndmp_connection_t
*connection
, void *body
)
936 ndmp_config_get_butype_info_reply_v4 reply
;
937 ndmp_butype_info info
[3];
941 ndmp_pval
*envp
= envs
;
943 ndmp_pval zfs_envs
[11];
945 ndmp_pval
*zfs_envp
= zfs_envs
;
948 (void) memset(&reply
, 0, sizeof (reply
));
951 * Supported environment variables and their default values
954 * The environment variables for dump and tar format are the
955 * same, because we use the same backup engine for both.
957 NDMP_SETENV(envp
, "FILESYSTEM", "");
958 NDMP_SETENV(envp
, "DIRECT", "n");
959 NDMP_SETENV(envp
, "RECURSIVE", "n");
960 NDMP_SETENV(envp
, "TYPE", "");
961 NDMP_SETENV(envp
, "USER", "");
962 NDMP_SETENV(envp
, "HIST", "n");
963 NDMP_SETENV(envp
, "PATHNAME_SEPARATOR", "/");
964 NDMP_SETENV(envp
, "LEVEL", "0");
965 NDMP_SETENV(envp
, "EXTRACT", "y");
966 NDMP_SETENV(envp
, "UPDATE", "y");
967 NDMP_SETENV(envp
, "CMD", "");
968 NDMP_SETENV(envp
, "BASE_DATE", "");
970 attrs
= NDMP_BUTYPE_RECOVER_FILELIST
|
971 NDMP_BUTYPE_BACKUP_DIRECT
|
972 NDMP_BUTYPE_BACKUP_INCREMENTAL
|
973 NDMP_BUTYPE_BACKUP_UTF8
|
974 NDMP_BUTYPE_RECOVER_UTF8
|
975 NDMP_BUTYPE_BACKUP_FH_FILE
|
976 NDMP_BUTYPE_BACKUP_FH_DIR
|
977 NDMP_BUTYPE_RECOVER_FH_FILE
|
978 NDMP_BUTYPE_RECOVER_FH_DIR
;
980 /* If DAR supported */
981 if (ndmp_dar_support
)
982 attrs
|= NDMP_BUTYPE_RECOVER_DIRECT
;
984 /* tar backup type */
985 info
[0].butype_name
= "tar";
986 info
[0].default_env
.default_env_len
= ARRAY_LEN(envs
, ndmp_pval
);
987 info
[0].default_env
.default_env_val
= envs
;
988 info
[0].attrs
= attrs
;
990 /* dump backup type */
991 info
[1].butype_name
= "dump";
992 info
[1].default_env
.default_env_len
= ARRAY_LEN(envs
, ndmp_pval
);
993 info
[1].default_env
.default_env_val
= envs
;
994 info
[1].attrs
= attrs
;
997 * Supported environment variables and their default values
1001 NDMP_SETENV(zfs_envp
, "USER", "");
1002 NDMP_SETENV(zfs_envp
, "CMD", "");
1003 NDMP_SETENV(zfs_envp
, "FILESYSTEM", "");
1004 NDMP_SETENV(zfs_envp
, "PATHNAME_SEPARATOR", "/");
1005 NDMP_SETENV(zfs_envp
, "TYPE", "zfs");
1006 NDMP_SETENV(zfs_envp
, "HIST", "n");
1007 NDMP_SETENV(zfs_envp
, "LEVEL", "0");
1008 NDMP_SETENV(zfs_envp
, "ZFS_MODE", "recursive");
1009 NDMP_SETENV(zfs_envp
, "ZFS_FORCE", "n");
1010 NDMP_SETENV(zfs_envp
, "UPDATE", "y");
1011 NDMP_SETENV(zfs_envp
, "DMP_NAME", "level");
1013 zfs_attrs
= NDMP_BUTYPE_BACKUP_UTF8
|
1014 NDMP_BUTYPE_RECOVER_UTF8
|
1015 NDMP_BUTYPE_BACKUP_DIRECT
|
1016 NDMP_BUTYPE_BACKUP_INCREMENTAL
;
1018 /* zfs backup type */
1019 info
[2].butype_name
= "zfs";
1020 info
[2].default_env
.default_env_len
= ARRAY_LEN(zfs_envs
, ndmp_pval
);
1021 info
[2].default_env
.default_env_val
= zfs_envs
;
1022 info
[2].attrs
= zfs_attrs
;
1024 reply
.error
= NDMP_NO_ERR
;
1025 reply
.butype_info
.butype_info_len
= ARRAY_LEN(info
, ndmp_butype_info
);
1026 reply
.butype_info
.butype_info_val
= info
;
1028 ndmp_send_reply(connection
, (void *)&reply
,
1029 "sending ndmp_config_get_butype_info reply");
1034 * ndmpd_config_get_ext_list_v4
1036 * This handler handles the ndmpd_config_get_ext_list_v4 request.
1039 * connection (input) - connection handle.
1040 * body (input) - request message body.
1047 ndmpd_config_get_ext_list_v4(ndmp_connection_t
*connection
, void *body
)
1049 ndmp_config_get_ext_list_reply_v4 reply
;
1050 ndmpd_session_t
*session
= ndmp_get_client_data(connection
);
1052 (void) memset(&reply
, 0, sizeof (reply
));
1054 if (session
->ns_set_ext_list
) {
1056 * Illegal request if extensions have already been selected.
1058 NDMP_LOG(LOG_ERR
, "Extensions have already been selected.");
1059 reply
.error
= NDMP_EXT_DANDN_ILLEGAL_ERR
;
1062 * Reply with an empty set of extensions.
1064 session
->ns_get_ext_list
= B_TRUE
;
1065 reply
.error
= NDMP_NO_ERR
;
1068 reply
.class_list
.class_list_val
= NULL
;
1069 reply
.class_list
.class_list_len
= 0;
1071 ndmp_send_reply(connection
, (void *)&reply
,
1072 "error sending ndmp_config_get_ext_list reply");
1076 * ndmpd_config_set_ext_list_v4
1078 * This handler handles the ndmpd_config_get_ext_list_v4 request.
1081 * connection (input) - connection handle.
1082 * body (input) - request message body.
1088 ndmpd_config_set_ext_list_v4(ndmp_connection_t
*connection
, void *body
)
1090 ndmp_config_set_ext_list_reply_v4 reply
;
1091 ndmp_config_set_ext_list_request_v4
*request
;
1092 ndmpd_session_t
*session
= ndmp_get_client_data(connection
);
1094 request
= (ndmp_config_set_ext_list_request_v4
*)body
;
1096 (void) memset(&reply
, 0, sizeof (reply
));
1098 if (!session
->ns_get_ext_list
) {
1100 * The DMA is required to issue a NDMP_GET_EXT_LIST request
1101 * prior sending a NDMP_SET_EXT_LIST request.
1103 NDMP_LOG(LOG_ERR
, "No prior ndmp_config_get_ext_list issued.");
1104 reply
.error
= NDMP_PRECONDITION_ERR
;
1105 } else if (session
->ns_set_ext_list
) {
1107 * Illegal request if extensions have already been selected.
1109 NDMP_LOG(LOG_ERR
, "Extensions have already been selected.");
1110 reply
.error
= NDMP_EXT_DANDN_ILLEGAL_ERR
;
1113 * We currently do not support any extensions, but the DMA
1114 * may test NDMP_CONFIG_SET_EXT_LIST with an empty list.
1116 if (request
->ndmp_selected_ext
.ndmp_selected_ext_len
!= 0) {
1117 reply
.error
= NDMP_CLASS_NOT_SUPPORTED_ERR
;
1119 session
->ns_set_ext_list
= B_TRUE
;
1120 reply
.error
= NDMP_NO_ERR
;
1124 ndmp_send_reply(connection
, (void *)&reply
,
1125 "error sending ndmp_config_set_ext_list reply");
1131 * ************************************************************************
1133 * ************************************************************************
1139 * Set the default attrs for dump mode
1142 * attributes (output) - the attributes for dump mode
1148 simple_get_attrs(ulong_t
*attributes
)
1150 *attributes
= NDMP_NO_RECOVER_FHINFO
;