# # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # # BSD 3 Clause License # # Copyright (c) 2007, The Storage Networking Industry Association. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # - Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # - Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # - Neither the name of The Storage Networking Industry Association (SNIA) # nor the names of its contributors may be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # include ../Makefile.cmd PROG= ndmpadm OBJS= ndmpadm_main.o ndmpadm_print.o SRCS = $(OBJS:.o=.c) POFILES= ndmpadm_main.po ndmpadm_print.po POFILE= ndmpadm.po LDLIBS += -lndmp CERRWARN += $(CNOWARN_UNINIT) # Hammerhead: Suppress ndmp_get_session_info pointer type mismatch warning CERRWARN += -Wno-incompatible-pointer-types .KEEP_STATE: all: $(PROG) $(PROG): $(OBJS) $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(POST_PROCESS) install: all $(ROOTUSRSBINPROG) $(POFILE): $(POFILES) $(RM) $@ $(CAT) $(POFILES) > $@ clean: $(RM) $(OBJS) $(POFILES) lint: lint_SRCS include ../Makefile.targ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * BSD 3 Clause License * * Copyright (c) 2007, The Storage Networking Industry Association. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * - Neither the name of The Storage Networking Industry Association (SNIA) * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _NDMPADM_H #define _NDMPADM_H #define NDMP_CAT_TAPE 0x00100 /* Tape request handling */ #define NDMP_CAT_SCSI 0x00200 /* SCSI request handling */ #define NDMP_CAT_DATA 0x00400 /* Data request handling */ #define NDMP_CAT_MOVER 0x04000 /* Data mover */ #define NDMP_CAT_BASIC 0 #define NDMP_CAT_ALL (NDMP_CAT_TAPE|NDMP_CAT_SCSI|NDMP_CAT_DATA|\ NDMP_CAT_MOVER) extern void ndmp_session_all_print(int, ndmp_session_info_t *, uint_t); extern void ndmp_session_print(int, ndmp_session_info_t *); extern void ndmp_devinfo_print(ndmp_devinfo_t *, size_t); #endif /* _NDMPADM_H */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. */ /* * BSD 3 Clause License * * Copyright (c) 2007, The Storage Networking Industry Association. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * - Neither the name of The Storage Networking Industry Association (SNIA) * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ndmpadm.h" typedef enum { HELP_GET_CONFIG, HELP_SET_CONFIG, HELP_SHOW_DEVICES, HELP_SHOW_SESSIONS, HELP_KILL_SESSIONS, HELP_ENABLE_AUTH, HELP_DISABLE_AUTH } ndmp_help_t; typedef struct ndmp_command { const char *nc_name; int (*func)(int argc, char **argv, struct ndmp_command *cur_cmd); ndmp_help_t nc_usage; } ndmp_command_t; static int ndmp_get_config(int, char **, ndmp_command_t *); static int ndmp_set_config(int, char **, ndmp_command_t *); static int ndmp_show_devices(int, char **, ndmp_command_t *); static int ndmp_show_sessions(int, char **, ndmp_command_t *); static int ndmp_kill_sessions(int, char **, ndmp_command_t *); static int ndmp_enable_auth(int, char **, ndmp_command_t *); static int ndmp_disable_auth(int, char **, ndmp_command_t *); static void ndmp_get_config_process(char *); static void ndmp_set_config_process(char *arg); static int ndmp_get_password(char **); static ndmp_command_t command_table[] = { { "get", ndmp_get_config, HELP_GET_CONFIG }, { "set", ndmp_set_config, HELP_SET_CONFIG }, { "show-devices", ndmp_show_devices, HELP_SHOW_DEVICES }, { "show-sessions", ndmp_show_sessions, HELP_SHOW_SESSIONS }, { "kill-sessions", ndmp_kill_sessions, HELP_KILL_SESSIONS }, { "enable", ndmp_enable_auth, HELP_ENABLE_AUTH }, { "disable", ndmp_disable_auth, HELP_DISABLE_AUTH } }; #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0])) static char *prop_table[] = { "debug-path", "dump-pathnode", "tar-pathnode", "ignore-ctime", "token-maxseq", "version", "dar-support", "tcp-port", "backup-quarantine", "restore-quarantine", "overwrite-quarantine", "zfs-force-override", "drive-type", "debug-mode" }; #define NDMPADM_NPROP (sizeof (prop_table) / sizeof (prop_table[0])) typedef struct ndmp_auth { const char *auth_type; const char *username; const char *password; } ndmp_auth_t; static ndmp_auth_t ndmp_auth_table[] = { { "cram-md5", "cram-md5-username", "cram-md5-password" }, { "cleartext", "cleartext-username", "cleartext-password" } }; #define NAUTH (sizeof (ndmp_auth_table) / sizeof (ndmp_auth_table[0])) #define NDMP_PASSWORD_RETRIES 3 #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif static const char * get_usage(ndmp_help_t idx) { switch (idx) { case HELP_SET_CONFIG: return ("\tset [-p] [[-p] property=value] " "...\n"); case HELP_GET_CONFIG: return ("\tget [-p] [property] [[-p] property] ...\n"); case HELP_SHOW_DEVICES: return ("\tshow-devices\n"); case HELP_SHOW_SESSIONS: return ("\tshow-sessions [-i tape,scsi,data,mover] [id] ...\n"); case HELP_KILL_SESSIONS: return ("\tkill-sessions \n"); case HELP_ENABLE_AUTH: return ("\tenable <-a auth-type> <-u username>\n"); case HELP_DISABLE_AUTH: return ("\tdisable <-a auth-type>\n"); } return (NULL); } /* * Display usage message. If we're inside a command, display only the usage for * that command. Otherwise, iterate over the entire command table and display * a complete usage message. */ static void usage(boolean_t requested, ndmp_command_t *current_command) { int i; boolean_t show_properties = B_FALSE; FILE *fp = requested ? stdout : stderr; if (current_command == NULL) { (void) fprintf(fp, gettext("Usage: ndmpadm subcommand args ...\n")); (void) fprintf(fp, gettext("where 'command' is one of the following:\n\n")); for (i = 0; i < NCOMMAND; i++) { (void) fprintf(fp, "%s", get_usage(command_table[i].nc_usage)); } (void) fprintf(fp, gettext("\t\twhere %s can be either " "%s or %s\n"), "'auth-type'", "'cram-md5'", "'cleartext'"); } else { (void) fprintf(fp, gettext("Usage:\n")); (void) fprintf(fp, "%s", get_usage(current_command->nc_usage)); if ((current_command->nc_usage == HELP_ENABLE_AUTH) || (current_command->nc_usage == HELP_DISABLE_AUTH)) (void) fprintf(fp, gettext("\t\twhere %s can be either " "%s or %s\n"), "'auth-type'", "'cram-md5'", "'cleartext'"); } if (current_command != NULL && (strcmp(current_command->nc_name, "set") == 0)) show_properties = B_TRUE; if (show_properties) { (void) fprintf(fp, gettext("\nThe following properties are supported:\n")); (void) fprintf(fp, gettext("\n\tPROPERTY")); (void) fprintf(fp, "\n\t%s", "-------------"); for (i = 0; i < NDMPADM_NPROP; i++) (void) fprintf(fp, "\n\t%s", prop_table[i]); (void) fprintf(fp, "\n"); } exit(requested ? 0 : 2); } /*ARGSUSED*/ static int ndmp_get_config(int argc, char **argv, ndmp_command_t *cur_cmd) { char *propval; int i, c; if (argc == 1) { /* * Get all the properties and variables ndmpadm is allowed * to see. */ for (i = 0; i < NDMPADM_NPROP; i++) { if (ndmp_get_prop(prop_table[i], &propval)) { (void) fprintf(stdout, "\t%s=\n", prop_table[i]); } else { (void) fprintf(stdout, "\t%s=%s\n", prop_table[i], propval); free(propval); } } } else if (argc > 1) { while ((c = getopt(argc, argv, ":p:")) != -1) { switch (c) { case 'p': ndmp_get_config_process(optarg); break; case ':': (void) fprintf(stderr, gettext("Option -%c " "requires an operand\n"), optopt); break; case '?': (void) fprintf(stderr, gettext("Unrecognized " "option: -%c\n"), optopt); } } /* * optind is initialized to 1 if the -p option is not used, * otherwise index to argv. */ argc -= optind; argv += optind; for (i = 0; i < argc; i++) { if (strncmp(argv[i], "-p", 2) == 0) continue; ndmp_get_config_process(argv[i]); } } return (0); } static void ndmp_get_config_process(char *arg) { int j; char *propval; for (j = 0; j < NDMPADM_NPROP; j++) { if (strcmp(arg, prop_table[j]) == 0) { if (ndmp_get_prop(arg, &propval)) { (void) fprintf(stdout, "\t%s=\n", arg); } else { (void) fprintf(stdout, "\t%s=%s\n", arg, propval); free(propval); } break; } } if (j == NDMPADM_NPROP) { (void) fprintf(stdout, gettext("\t%s is invalid property " "or variable\n"), arg); } } /*ARGSUSED*/ static int ndmp_set_config(int argc, char **argv, ndmp_command_t *cur_cmd) { int c, i; if (argc < 2) { (void) fprintf(stderr, gettext("Missing property=value " "argument\n")); usage(B_FALSE, cur_cmd); } while ((c = getopt(argc, argv, ":p:")) != -1) { switch (c) { case 'p': ndmp_set_config_process(optarg); break; case ':': (void) fprintf(stderr, gettext("Option -%c " "requires an operand\n"), optopt); break; case '?': (void) fprintf(stderr, gettext("Unrecognized " "option: -%c\n"), optopt); } } /* * optind is initialized to 1 if the -p option is not used, * otherwise index to argv. */ argc -= optind; argv += optind; for (i = 0; i < argc; i++) { if (strncmp(argv[i], "-p", 2) == 0) continue; ndmp_set_config_process(argv[i]); } return (0); } static void ndmp_set_config_process(char *propname) { char *propvalue; int ret, j; if ((propvalue = strchr(propname, '=')) == NULL) { (void) fprintf(stderr, gettext("Missing value in " "property=value argument for %s\n"), propname); return; } *propvalue = '\0'; propvalue++; if (*propname == '\0') { (void) fprintf(stderr, gettext("Missing property in " "property=value argument for %s\n"), propname); return; } for (j = 0; j < NDMPADM_NPROP; j++) { if (strcmp(propname, prop_table[j]) == 0) break; } if (j == NDMPADM_NPROP) { (void) fprintf(stdout, gettext("%s is invalid property or " "variable\n"), propname); return; } ret = ndmp_set_prop(propname, propvalue); if (ret != -1) { if (!ndmp_door_status()) { if (ndmp_service_refresh() != 0) (void) fprintf(stdout, gettext("Could not " "refesh property of service ndmpd\n")); } } else { (void) fprintf(stdout, gettext("Could not set property for " "%s - %s\n"), propname, ndmp_strerror(ndmp_errno)); } } /*ARGSUSED*/ static int ndmp_show_devices(int argc, char **argv, ndmp_command_t *cur_cmd) { int ret; ndmp_devinfo_t *dip = NULL; size_t size; if (ndmp_door_status()) { (void) fprintf(stdout, gettext("Service ndmpd not running\n")); return (-1); } ret = ndmp_get_devinfo(&dip, &size); if (ret == -1) (void) fprintf(stdout, gettext("Could not get device information\n")); else ndmp_devinfo_print(dip, size); ndmp_get_devinfo_free(dip, size); return (0); } static int ndmp_show_sessions(int argc, char **argv, ndmp_command_t *cur_cmd) { ndmp_session_info_t *sinfo = NULL; ndmp_session_info_t *sp = NULL; uint_t num; int c, ret, i, j; int statarg = 0; char *value; char *type_subopts[] = { "tape", "scsi", "data", "mover", NULL }; if (ndmp_door_status()) { (void) fprintf(stdout, gettext("Service ndmpd not running\n")); return (-1); } /* Detail output if no option is specified */ if (argc == 1) { statarg = NDMP_CAT_ALL; } else { statarg = 0; while ((c = getopt(argc, argv, ":i:")) != -1) { switch (c) { case 'i': while (*optarg != '\0') { switch (getsubopt(&optarg, type_subopts, &value)) { case 0: statarg |= NDMP_CAT_TAPE; break; case 1: statarg |= NDMP_CAT_SCSI; break; case 2: statarg |= NDMP_CAT_DATA; break; case 3: statarg |= NDMP_CAT_MOVER; break; default: (void) fprintf(stderr, gettext("Invalid object " "type '%s'\n"), value); usage(B_FALSE, cur_cmd); } } break; case ':': (void) fprintf(stderr, gettext("Missing argument for " "'%c' option\n"), optopt); usage(B_FALSE, cur_cmd); break; case '?': (void) fprintf(stderr, gettext("Invalid option '%c'\n"), optopt); usage(B_FALSE, cur_cmd); } } /* if -i and its argument are not specified, display all */ if (statarg == 0) statarg = NDMP_CAT_ALL; } /* * optind is initialized to 1 if the -i option is not used, otherwise * index to argv. */ argc -= optind; argv += optind; ret = ndmp_get_session_info(&sinfo, &num); if (ret == -1) { (void) fprintf(stdout, gettext("Could not get session information\n")); } else { if (argc == 0) { ndmp_session_all_print(statarg, sinfo, num); } else { for (i = 0; i < argc; i++) { sp = sinfo; for (j = 0; j < num; j++, sp++) { if (sp->nsi_sid == atoi(argv[i])) { ndmp_session_print(statarg, sp); (void) fprintf(stdout, "\n"); break; } } if (j == num) { (void) fprintf(stdout, gettext("Session %d not " "found\n"), atoi(argv[i])); } } } ndmp_get_session_info_free(sinfo, num); } return (0); } /*ARGSUSED*/ static int ndmp_kill_sessions(int argc, char **argv, ndmp_command_t *cur_cmd) { int ret, i; if (ndmp_door_status()) { (void) fprintf(stdout, gettext("Service ndmpd not running.\n")); return (-1); } /* If no arg is specified, print the usage and exit */ if (argc == 1) usage(B_FALSE, cur_cmd); for (i = 1; i < argc; i++) { if (atoi(argv[i]) > 0) { ret = ndmp_terminate_session(atoi(argv[i])); } else { (void) fprintf(stderr, gettext("Invalid argument %s\n"), argv[i]); continue; } if (ret == -1) (void) fprintf(stdout, gettext("Session id %d not found.\n"), atoi(argv[i])); } return (0); } static int ndmp_get_password(char **password) { char *pw1, pw2[257]; int i; for (i = 0; i < NDMP_PASSWORD_RETRIES; i++) { /* * getpassphrase use the same buffer to return password, so * copy the result in different buffer, before calling the * getpassphrase again. */ if ((pw1 = getpassphrase(gettext("Enter new password: "))) != NULL) { (void) strlcpy(pw2, pw1, sizeof (pw2)); if ((pw1 = getpassphrase(gettext("Re-enter password: "))) != NULL) { if (strncmp(pw1, pw2, strlen(pw1)) == 0) { *password = pw1; return (0); } else { (void) fprintf(stderr, gettext("Both password did not " "match.\n")); } } } } return (-1); } static int ndmp_enable_auth(int argc, char **argv, ndmp_command_t *cur_cmd) { char *auth_type, *username, *password; int c, i, auth_type_flag = 0; char *enc_password; /* enable <-a auth-type> <-u username> */ if (argc != 5) { usage(B_FALSE, cur_cmd); } while ((c = getopt(argc, argv, ":a:u:")) != -1) { switch (c) { case 'a': auth_type = strdup(optarg); break; case 'u': username = strdup(optarg); break; case ':': (void) fprintf(stderr, gettext("Option -%c " "requires an operand\n"), optopt); usage(B_FALSE, cur_cmd); break; case '?': (void) fprintf(stderr, gettext("Unrecognized " "option: -%c\n"), optopt); usage(B_FALSE, cur_cmd); } } if ((auth_type) && (username)) { if (ndmp_get_password(&password)) { (void) fprintf(stderr, gettext("Could not get correct " "password, exiting...")); free(auth_type); free(username); exit(-1); } } else { (void) fprintf(stderr, gettext("%s or %s can not be blank"), "'auth-type'", "'username'"); free(auth_type); free(username); exit(-1); } if ((enc_password = ndmp_base64_encode(password)) == NULL) { (void) fprintf(stdout, gettext("Could not encode password - %s\n"), ndmp_strerror(ndmp_errno)); free(auth_type); free(username); exit(-1); } for (i = 0; i < NAUTH; i++) { if (strncmp(auth_type, ndmp_auth_table[i].auth_type, strlen(ndmp_auth_table[i].auth_type)) == 0) { auth_type_flag = 1; if ((ndmp_set_prop(ndmp_auth_table[i].username, username)) == -1) { (void) fprintf(stdout, gettext("Could not set username - %s\n"), ndmp_strerror(ndmp_errno)); continue; } if ((ndmp_set_prop(ndmp_auth_table[i].password, enc_password)) == -1) { (void) fprintf(stdout, gettext("Could not set password - %s\n"), ndmp_strerror(ndmp_errno)); continue; } if (!ndmp_door_status() && (ndmp_service_refresh()) != 0) { (void) fprintf(stdout, gettext("Could not refesh ndmpd service " "properties\n")); } } } free(auth_type); free(username); free(enc_password); if (!auth_type_flag) usage(B_FALSE, cur_cmd); return (0); } static int ndmp_disable_auth(int argc, char **argv, ndmp_command_t *cur_cmd) { char *auth_type; int c, i, auth_type_flag = 0; /* disable <-a auth-type> */ if (argc != 3) { usage(B_FALSE, cur_cmd); } while ((c = getopt(argc, argv, ":a:")) != -1) { switch (c) { case 'a': auth_type = strdup(optarg); break; case ':': (void) fprintf(stderr, gettext("Option -%c " "requires an operand\n"), optopt); break; case '?': (void) fprintf(stderr, gettext("Unrecognized " "option: -%c\n"), optopt); } } for (i = 0; i < NAUTH; i++) { if (strncmp(auth_type, ndmp_auth_table[i].auth_type, strlen(ndmp_auth_table[i].auth_type)) == 0) { auth_type_flag = 1; if ((ndmp_set_prop(ndmp_auth_table[i].username, "")) == -1) { (void) fprintf(stdout, gettext("Could not clear username - %s\n"), ndmp_strerror(ndmp_errno)); continue; } if ((ndmp_set_prop(ndmp_auth_table[i].password, "")) == -1) { (void) fprintf(stdout, gettext("Could not clear password - %s\n"), ndmp_strerror(ndmp_errno)); continue; } if (!ndmp_door_status() && (ndmp_service_refresh()) != 0) { (void) fprintf(stdout, gettext("Could not " "refesh ndmpd service properties\n")); } } } free(auth_type); if (!auth_type_flag) usage(B_FALSE, cur_cmd); return (0); } int main(int argc, char **argv) { int ret; int i; char *cmdname; ndmp_command_t *current_command = NULL; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); opterr = 0; /* Make sure the user has specified some command. */ if (argc < 2) { (void) fprintf(stderr, gettext("Missing command.\n")); usage(B_FALSE, current_command); } cmdname = argv[1]; /* * Special case '-?' */ if (strcmp(cmdname, "-?") == 0) usage(B_TRUE, current_command); /* * Run the appropriate sub-command. */ for (i = 0; i < NCOMMAND; i++) { if (strcmp(cmdname, command_table[i].nc_name) == 0) { current_command = &command_table[i]; ret = command_table[i].func(argc - 1, argv + 1, current_command); break; } } if (i == NCOMMAND) { (void) fprintf(stderr, gettext("Unrecognized " "command '%s'\n"), cmdname); usage(B_FALSE, current_command); } return (ret); } /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ /* * BSD 3 Clause License * * Copyright (c) 2007, The Storage Networking Industry Association. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * - Neither the name of The Storage Networking Industry Association (SNIA) * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include "ndmpadm.h" /* static functions prototype */ static void ndmp_tprint_addr(char *, ndmp_ad_type_t, char *); static void ndmp_print_env(ndmp_session_info_t *); static void ndmp_connect_print_conn(ndmp_session_info_t *); static void ndmp_connect_print_scsi_v2(ndmp_session_info_t *); static void ndmp_connect_print_tape_v2(ndmp_session_info_t *); static void ndmp_connect_print_mover_v2(ndmp_session_info_t *); static void ndmp_connect_print_data_v2(ndmp_session_info_t *); static void ndmp_connect_print_v2(int, ndmp_session_info_t *); static void ndmp_connect_print_mover_v3(ndmp_session_info_t *); static void ndmp_connect_print_data_v3(ndmp_session_info_t *); static void ndmp_connect_print_v3(int, ndmp_session_info_t *); static void ndmp_connection_print(int, ndmp_session_info_t *); /* Boolean to string. */ #define B2S(b) ((b) ? "Yes" : "No") /* * Print the address type and IP address if the address type is tcp */ static void ndmp_tprint_addr(char *label, ndmp_ad_type_t addr_type, char *tcp_addr) { if ((label == NULL) || (tcp_addr == NULL)) return; switch (addr_type) { case NDMP_AD_LOCAL: (void) fprintf(stdout, gettext("\t%s type:\tLocal\n"), label); break; case NDMP_AD_TCP: (void) fprintf(stdout, gettext("\t%s type:\tTCP\n"), label); (void) fprintf(stdout, gettext("\t%s address:\t%s\n"), label, tcp_addr); break; case NDMP_AD_FC: (void) fprintf(stdout, gettext("\t%s type:\tFC\n"), label); break; case NDMP_AD_IPC: (void) fprintf(stdout, gettext("\t%s type:\tIPC\n"), label); break; default: (void) fprintf(stdout, gettext("\t%s addr type unknown (0x%x)\n"), label, addr_type); } } /* * Print all the data environment variables for the active session */ static void ndmp_print_env(ndmp_session_info_t *si) { int i, n; ndmp_dt_pval_t *ep; n = si->nsi_data.nd_env_len; ep = si->nsi_data.nd_env; for (i = 0; ep && i < n; i++, ep++) { (void) fprintf(stdout, gettext("\tdata.env[%d]:\t%s: "), i, ep->np_name); if ((ep->np_value != NULL) && (*ep->np_value != '\0')) (void) fprintf(stdout, "\"%s\"\n", ep->np_value); } } /* * Print common fields of the active connection. */ static void ndmp_connect_print_conn(ndmp_session_info_t *si) { (void) fprintf(stdout, gettext("\tSession Id:\t%d\n"), si->nsi_sid); (void) fprintf(stdout, gettext("\tProtocol version:\t%d\n"), si->nsi_pver); (void) fprintf(stdout, gettext("\tAuthenticated:\t\t%s\n"), B2S(si->nsi_auth)); (void) fprintf(stdout, gettext("\tEOF:\t\t\t%s\n"), B2S(si->nsi_eof)); if (si->nsi_cl_addr != NULL) (void) fprintf(stdout, gettext("\tClient address:\t\t%s\n"), si->nsi_cl_addr); } /* * Print the connection SCSI info. */ static void ndmp_connect_print_scsi_v2(ndmp_session_info_t *si) { (void) fprintf(stdout, gettext("\tscsi.open:\t\t%s\n"), B2S(si->nsi_scsi.ns_scsi_open != -1)); if (si->nsi_scsi.ns_adapter_name) (void) fprintf(stdout, gettext("\tscsi.adapter:\t\t\"%s\"\n"), si->nsi_scsi.ns_adapter_name); (void) fprintf(stdout, gettext("\tscsi.valid target:\t%s\n"), B2S(si->nsi_scsi.ns_valid_target_set)); if (si->nsi_scsi.ns_valid_target_set) { (void) fprintf(stdout, gettext("\tscsi.SID:\t\t%d\n"), si->nsi_scsi.ns_scsi_id); (void) fprintf(stdout, gettext("\tscsi.LUN:\t\t%d\n"), si->nsi_scsi.ns_lun); } } /* * Print the connection tape info. */ static void ndmp_connect_print_tape_v2(ndmp_session_info_t *si) { if (si->nsi_tape.nt_fd != -1) { (void) fprintf(stdout, gettext("\ttape.fd:\t\t%d\n"), si->nsi_tape.nt_fd); (void) fprintf(stdout, gettext("\ttape.record count:\t%d\n"), (int)si->nsi_tape.nt_rec_count); switch (si->nsi_tape.nt_mode) { case NDMP_TP_READ_MODE: (void) fprintf(stdout, gettext("\ttape.mode:\t\tRead-only\n")); break; case NDMP_TP_WRITE_MODE: (void) fprintf(stdout, gettext("\ttape.mode:\t\tRead/Write\n")); break; case NDMP_TP_RAW1_MODE: (void) fprintf(stdout, gettext("\ttape.mode:\t\tRaw\n")); break; default: (void) fprintf(stdout, gettext("\ttape.mode:\t\tUnknown (0x%x)\n"), si->nsi_tape.nt_mode); } if (si->nsi_tape.nt_dev_name) (void) fprintf(stdout, gettext("\ttape.device name:\t%s\n"), si->nsi_tape.nt_dev_name); if (si->nsi_tape.nt_adapter_name) (void) fprintf(stdout, gettext("\ttape.adapter name:\t\"%s\"\n"), si->nsi_tape.nt_adapter_name); (void) fprintf(stdout, gettext("\ttape.SID:\t\t%d\n"), si->nsi_tape.nt_sid); (void) fprintf(stdout, gettext("\ttape.LUN:\t\t%d\n"), si->nsi_tape.nt_lun); } else (void) fprintf(stdout, gettext("\ttape.device:\t\tNot open\n")); } /* * Print the connection mover info. */ static void ndmp_connect_print_mover_v2(ndmp_session_info_t *si) { switch (si->nsi_mover.nm_state) { case NDMP_MV_STATE_IDLE: (void) fprintf(stdout, gettext("\tmover.state:\t\tIdle\n")); break; case NDMP_MV_STATE_LISTEN: (void) fprintf(stdout, gettext("\tmover.state:\t\tListen\n")); break; case NDMP_MV_STATE_ACTIVE: (void) fprintf(stdout, gettext("\tmover.state:\t\tActive\n")); break; case NDMP_MV_STATE_PAUSED: (void) fprintf(stdout, gettext("\tmover.state:\t\tPaused\n")); break; case NDMP_MV_STATE_HALTED: (void) fprintf(stdout, gettext("\tmover.state:\t\tHalted\n")); break; default: (void) fprintf(stdout, gettext("\tmover.state:\t\tUnknown (0x%x)\n"), si->nsi_mover.nm_state); } switch (si->nsi_mover.nm_mode) { case NDMP_MV_MODE_READ: (void) fprintf(stdout, gettext("\tmover.mode:\t\tRead\n")); break; case NDMP_MV_MODE_WRITE: (void) fprintf(stdout, gettext("\tmover.mode:\t\tWrite\n")); break; default: (void) fprintf(stdout, gettext("\tmover.mode:\t\tUnknown (0x%x)\n"), si->nsi_mover.nm_mode); } switch (si->nsi_mover.nm_pause_reason) { case NDMP_MV_PAUSE_NA: (void) fprintf(stdout, gettext("\tmover.pause reason:\tN/A\n")); break; case NDMP_MV_PAUSE_EOM: (void) fprintf(stdout, gettext("\tmover.pause reason:\tEOM\n")); break; case NDMP_MV_PAUSE_EOF: (void) fprintf(stdout, gettext("\tmover.pause reason:\tEOF\n")); break; case NDMP_MV_PAUSE_SEEK: (void) fprintf(stdout, gettext("\tmover.pause reason:\tSeek\n")); break; case NDMP_MV_PAUSE_MEDIA_ERROR: (void) fprintf(stdout, gettext("\tmover.pause reason:\tMedia Error\n")); break; default: (void) fprintf(stdout, gettext("\tmover.pause reason:\tUnknown (0x%x)\n"), si->nsi_mover.nm_pause_reason); } switch (si->nsi_mover.nm_halt_reason) { case NDMP_MV_HALT_NA: (void) fprintf(stdout, gettext("\tmover.halt reason:\tN/A\n")); break; case NDMP_MV_HALT_CONNECT_CLOSED: (void) fprintf(stdout, gettext("\tmover.halt reason:\tConnection closed\n")); break; case NDMP_MV_HALT_ABORTED: (void) fprintf(stdout, gettext("\tmover.halt reason:\tAborted\n")); break; case NDMP_MV_HALT_INTERNAL_ERROR: (void) fprintf(stdout, gettext("\tmover.halt reason:\tInternal error\n")); break; case NDMP_MV_HALT_CONNECT_ERROR: (void) fprintf(stdout, gettext("\tmover.halt reason:\tConnection error\n")); break; default: (void) fprintf(stdout, gettext("\tmover.halt reason:\tUnknown (0x%x)\n"), si->nsi_mover.nm_halt_reason); } (void) fprintf(stdout, gettext("\tmover.record size:\t%d\n"), (int)si->nsi_mover.nm_rec_size); (void) fprintf(stdout, gettext("\tmover.record number:\t%d\n"), (int)si->nsi_mover.nm_rec_num); (void) fprintf(stdout, gettext("\tmover.pos:\t\t%lld\n"), si->nsi_mover.nm_mov_pos); (void) fprintf(stdout, gettext("\tmover.win off:\t\t%lld\n"), si->nsi_mover.nm_window_offset); (void) fprintf(stdout, gettext("\tmover.win len:\t\t%lld\n"), si->nsi_mover.nm_window_length); (void) fprintf(stdout, gettext("\tmover.data socket:\t%d\n"), si->nsi_mover.nm_sock); } /* * Print the connection data info. */ static void ndmp_connect_print_data_v2(ndmp_session_info_t *si) { int i; ndmp_dt_name_t *np; switch (si->nsi_data.nd_oper) { case NDMP_DT_OP_NOACTION: (void) fprintf(stdout, gettext("\tdata.operation:\t\tNone\n")); break; case NDMP_DT_OP_BACKUP: (void) fprintf(stdout, gettext("\tdata.operation:\t\tBackup\n")); break; case NDMP_DT_OP_RECOVER: (void) fprintf(stdout, gettext("\tdata.operation:\t\tRestore\n")); break; default: (void) fprintf(stdout, gettext("\tdata.operation:\t\tUnknown (0x%x)\n"), si->nsi_data.nd_oper); } switch (si->nsi_data.nd_state) { case NDMP_DT_STATE_IDLE: (void) fprintf(stdout, gettext("\tdata.state:\t\tIdle\n")); break; case NDMP_DT_STATE_ACTIVE: (void) fprintf(stdout, gettext("\tdata.state:\t\tActive\n")); break; case NDMP_DT_STATE_HALTED: (void) fprintf(stdout, gettext("\tdata.state:\t\tHalted\n")); break; default: (void) fprintf(stdout, gettext("\tdata.state:\t\tUnknown (0x%x)\n"), si->nsi_data.nd_state); } switch (si->nsi_data.nd_halt_reason) { case NDMP_DT_HALT_NA: (void) fprintf(stdout, gettext("\tdata.halt reason:\tN/A\n")); break; case NDMP_DT_HALT_SUCCESSFUL: (void) fprintf(stdout, gettext("\tdata.halt reason:\tSuccessful\n")); break; case NDMP_DT_HALT_ABORTED: (void) fprintf(stdout, gettext("\tdata.halt reason:\tAborted\n")); break; case NDMP_DT_HALT_INTERNAL_ERROR: (void) fprintf(stdout, gettext("\tdata.halt reason:\tInternal error\n")); break; case NDMP_DT_HALT_CONNECT_ERROR: (void) fprintf(stdout, gettext("\tdata.halt reason:\tConnection error\n")); break; default: (void) fprintf(stdout, gettext("\tdata.halt reason:\tUnknown (0x%x)\n"), si->nsi_data.nd_halt_reason); } switch (si->nsi_data.nd_addr_type) { case NDMP_AD_LOCAL: (void) fprintf(stdout, gettext("\tdata.mover type:\tLocal\n")); break; case NDMP_AD_TCP: (void) fprintf(stdout, gettext("\tdata.mover type:\tTCP\n")); if (si->nsi_data.nd_tcp_addr) (void) fprintf(stdout, gettext("\tdata.mover address:\t%s\n"), si->nsi_data.nd_tcp_addr); (void) fprintf(stdout, gettext("\tdata.sock:\t%d\n"), si->nsi_data.nd_sock); break; default: (void) fprintf(stdout, gettext("\tdata.mover type:\tUnknown (0x%x)\n"), si->nsi_data.nd_addr_type); } (void) fprintf(stdout, gettext("\tdata.aborted:\t\t%s\n"), B2S(si->nsi_data.nd_abort)); (void) fprintf(stdout, gettext("\tdata.read offset:\t%llu\n"), si->nsi_data.nd_read_offset); (void) fprintf(stdout, gettext("\tdata.read length:\t%llu\n"), si->nsi_data.nd_read_length); (void) fprintf(stdout, gettext("\tdata.total size:\t%llu\n"), si->nsi_data.nd_total_size); ndmp_print_env(si); np = si->nsi_data.nd_nlist.nld_nlist; for (i = 0; np && i < (int)si->nsi_data.nld_nlist_len; i++, np++) { if ((np->nn_name) && (np->nn_dest)) { (void) fprintf(stdout, gettext("\tdata.nlist[%d]:\tname: " "\"%s\"\n\t\tdest:\"%s\"\n"), i, np->nn_name, np->nn_dest); } } } /* * Print V2 connection info for the given category. */ static void ndmp_connect_print_v2(int cat, ndmp_session_info_t *si) { if (cat & NDMP_CAT_SCSI) ndmp_connect_print_scsi_v2(si); if (cat & NDMP_CAT_TAPE) ndmp_connect_print_tape_v2(si); if (cat & NDMP_CAT_MOVER) ndmp_connect_print_mover_v2(si); if (cat & NDMP_CAT_DATA) ndmp_connect_print_data_v2(si); } /* * Print the V3 connection mover info. */ static void ndmp_connect_print_mover_v3(ndmp_session_info_t *si) { switch (si->nsi_mover.nm_state) { case NDMP_MV_STATE_IDLE: (void) fprintf(stdout, gettext("\tmover.state:\t\tIdle\n")); break; case NDMP_MV_STATE_LISTEN: (void) fprintf(stdout, gettext("\tmover.state:\t\tListen\n")); break; case NDMP_MV_STATE_ACTIVE: (void) fprintf(stdout, gettext("\tmover.state:\t\tActive\n")); break; case NDMP_MV_STATE_PAUSED: (void) fprintf(stdout, gettext("\tmover.state:\t\tPaused\n")); break; case NDMP_MV_STATE_HALTED: (void) fprintf(stdout, gettext("\tmover.state:\t\tHalted\n")); break; default: (void) fprintf(stdout, gettext("\tmover.state:\t\tUnknown (0x%x)\n"), si->nsi_mover.nm_state); } switch (si->nsi_mover.nm_mode) { case NDMP_MV_MODE_READ: (void) fprintf(stdout, gettext("\tmover.mode:\t\tRead\n")); break; case NDMP_MV_MODE_WRITE: (void) fprintf(stdout, gettext("\tmover.mode:\t\tWrite\n")); break; default: (void) fprintf(stdout, gettext("\tmover.mode:\t\tUnknown (0x%x)\n"), si->nsi_mover.nm_mode); } switch (si->nsi_mover.nm_pause_reason) { case NDMP_MV_PAUSE_NA: (void) fprintf(stdout, gettext("\tmover.pause reason:\tN/A\n")); break; case NDMP_MV_PAUSE_EOM: (void) fprintf(stdout, gettext("\tmover.pause reason:\tEOM\n")); break; case NDMP_MV_PAUSE_EOF: (void) fprintf(stdout, gettext("\tmover.pause reason:\tEOF\n")); break; case NDMP_MV_PAUSE_SEEK: (void) fprintf(stdout, gettext("\tmover.pause reason:\tSeek\n")); break; case NDMP_MV_PAUSE_MEDIA_ERROR: (void) fprintf(stdout, gettext("\tmover.pause reason:\tMedia Error\n")); break; case NDMP_MV_PAUSE_EOW: (void) fprintf(stdout, gettext("\tmover.pause reason:\tEOW\n")); break; default: (void) fprintf(stdout, gettext("\tmover.pause reason:\tUnknown (0x%x)\n"), si->nsi_mover.nm_pause_reason); } switch (si->nsi_mover.nm_halt_reason) { case NDMP_MV_HALT_NA: (void) fprintf(stdout, gettext("\tmover.halt reason:\tN/A\n")); break; case NDMP_MV_HALT_CONNECT_CLOSED: (void) fprintf(stdout, gettext("\tmover.halt reason:\tConnection closed\n")); break; case NDMP_MV_HALT_ABORTED: (void) fprintf(stdout, gettext("\tmover.halt reason:\tAborted\n")); break; case NDMP_MV_HALT_INTERNAL_ERROR: (void) fprintf(stdout, gettext("\tmover.halt reason:\tInternal error\n")); break; case NDMP_MV_HALT_CONNECT_ERROR: (void) fprintf(stdout, gettext("\tmover.halt reason:\tConnection error\n")); break; default: (void) fprintf(stdout, gettext("\tmover.halt reason:\tUnknown (0x%x)\n"), si->nsi_mover.nm_halt_reason); } (void) fprintf(stdout, gettext("\tmover.record size:\t%d\n"), (int)si->nsi_mover.nm_rec_size); (void) fprintf(stdout, gettext("\tmover.record number:\t%d\n"), (int)si->nsi_mover.nm_rec_num); (void) fprintf(stdout, gettext("\tmover.pos:\t\t%lld\n"), si->nsi_mover.nm_mov_pos, si->nsi_mover.nm_mov_pos); (void) fprintf(stdout, gettext("\tmover.win len:\t\t%lld\n"), si->nsi_mover.nm_window_length, si->nsi_mover.nm_window_length); (void) fprintf(stdout, gettext("\tmover.win off:\t\t%lld\n"), si->nsi_mover.nm_window_offset); switch (si->nsi_mover.nm_state) { case NDMP_MV_STATE_IDLE: if (si->nsi_mover.nm_listen_sock != -1) (void) fprintf(stdout, gettext("\tmover.listenSock:\t%d\n"), si->nsi_mover.nm_listen_sock); if (si->nsi_mover.nm_sock != -1) (void) fprintf(stdout, gettext("\tmover.sock:\t%d\n"), si->nsi_mover.nm_sock); break; case NDMP_MV_STATE_LISTEN: (void) fprintf(stdout, gettext("\tmover.listen socket:\t%d\n"), si->nsi_mover.nm_listen_sock); ndmp_tprint_addr(gettext("mover.listen"), si->nsi_mover.nm_addr_type, si->nsi_mover.nm_tcp_addr); break; case NDMP_MV_STATE_ACTIVE: case NDMP_MV_STATE_PAUSED: case NDMP_MV_STATE_HALTED: (void) fprintf(stdout, gettext("\tmover.data socket:\t%d\n"), si->nsi_mover.nm_sock); ndmp_tprint_addr(gettext("mover.data connection"), si->nsi_mover.nm_addr_type, si->nsi_mover.nm_tcp_addr); break; } } /* * Print the connection data info. */ static void ndmp_connect_print_data_v3(ndmp_session_info_t *si) { int i; ndmp_dt_name_v3_t *np; switch (si->nsi_data.nd_oper) { case NDMP_DT_OP_NOACTION: (void) fprintf(stdout, gettext("\tdata.operation:\t\tNone\n")); break; case NDMP_DT_OP_BACKUP: (void) fprintf(stdout, gettext("\tdata.operation:\t\tBackup\n")); break; case NDMP_DT_OP_RECOVER: (void) fprintf(stdout, gettext("\tdata.operation:\t\tRestore\n")); break; default: (void) fprintf(stdout, gettext("\tdata.operation:\t\tUnknown (0x%x)\n"), si->nsi_data.nd_oper); } switch (si->nsi_data.nd_state) { case NDMP_DT_STATE_IDLE: (void) fprintf(stdout, gettext("\tdata.state:\t\tIdle\n")); break; case NDMP_DT_STATE_ACTIVE: (void) fprintf(stdout, gettext("\tdata.state:\t\tActive\n")); break; case NDMP_DT_STATE_HALTED: (void) fprintf(stdout, gettext("\tdata.state:\t\tHalted\n")); break; case NDMP_DT_STATE_LISTEN: (void) fprintf(stdout, gettext("\tdata.state:\t\tListen\n")); break; case NDMP_DT_STATE_CONNECTED: (void) fprintf(stdout, gettext("\tdata.state:\t\tConnected\n")); break; default: (void) fprintf(stdout, gettext("\tdata.state:\t\tUnknown (0x%x)\n"), si->nsi_data.nd_state); } switch (si->nsi_data.nd_halt_reason) { case NDMP_DT_HALT_NA: (void) fprintf(stdout, gettext("\tdata.halt reason:\tN/A\n")); break; case NDMP_DT_HALT_SUCCESSFUL: (void) fprintf(stdout, gettext("\tdata.halt reason:\tSuccessful\n")); break; case NDMP_DT_HALT_ABORTED: (void) fprintf(stdout, gettext("\tdata.halt reason:\tAborted\n")); break; case NDMP_DT_HALT_INTERNAL_ERROR: (void) fprintf(stdout, gettext("\tdata.halt reason:\tInternal error\n")); break; case NDMP_DT_HALT_CONNECT_ERROR: (void) fprintf(stdout, gettext("\tdata.halt reason:\tConnection error\n")); break; default: (void) fprintf(stdout, gettext("\tdata.halt reason:\tUnknown (0x%x)\n"), si->nsi_data.nd_halt_reason); } switch (si->nsi_data.nd_state) { case NDMP_DT_STATE_IDLE: if (si->nsi_data.nd_sock != -1) (void) fprintf(stdout, gettext("\tdata.data socket:\t%d\n"), si->nsi_data.nd_sock); if (si->nsi_data.nd_nlist.nld_dt_v3.dv3_listen_sock != -1) (void) fprintf(stdout, gettext("\tdata.data socket:\t%d\n"), si->nsi_data.nd_nlist.nld_dt_v3.dv3_listen_sock); break; case NDMP_DT_STATE_LISTEN: (void) fprintf(stdout, gettext("\tdata.listen socket:\t%d\n"), si->nsi_data.nd_nlist.nld_dt_v3.dv3_listen_sock); ndmp_tprint_addr(gettext("data.listen"), si->nsi_data.nd_addr_type, si->nsi_data.nd_tcp_addr); break; case NDMP_DT_STATE_ACTIVE: case NDMP_DT_STATE_HALTED: case NDMP_DT_STATE_CONNECTED: (void) fprintf(stdout, gettext("\tdata.data socket:\t%d\n"), si->nsi_data.nd_sock); ndmp_tprint_addr(gettext("data.data"), si->nsi_data.nd_addr_type, si->nsi_data.nd_tcp_addr); break; } (void) fprintf(stdout, gettext("\tdata.aborted:\t\t%s\n"), B2S(si->nsi_data.nd_abort)); (void) fprintf(stdout, gettext("\tdata.read offset:\t%llu\n"), si->nsi_data.nd_read_offset); (void) fprintf(stdout, gettext("\tdata.read length:\t%llu\n"), si->nsi_data.nd_read_length); (void) fprintf(stdout, gettext("\tdata.total size:\t%llu\n"), si->nsi_data.nd_total_size); (void) fprintf(stdout, gettext("\tdata.bytes processed:\t%lld\n"), si->nsi_data.nd_nlist.nld_dt_v3.dv3_bytes_processed); ndmp_print_env(si); np = si->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist; for (i = 0; np && i < si->nsi_data.nld_nlist_len; i++, np++) { (void) fprintf(stdout, gettext("\tdata.nlist[%d]:\tname:\n"), i); if (np->nn3_opath) (void) fprintf(stdout, gettext("\t\torig: \"%s\"\n"), np->nn3_opath); if (np->nn3_dpath) (void) fprintf(stdout, gettext("\t\tdest: \"%s\"\n"), np->nn3_dpath); else (void) fprintf(stdout, gettext("\t\tdest:\n")); (void) fprintf(stdout, gettext("\t\tnode: %lld\n"), np->nn3_node); (void) fprintf(stdout, gettext("\t\tfh_info: %lld\n"), np->nn3_fh_info); } } /* * Print V3 connection info for given category. */ static void ndmp_connect_print_v3(int cat, ndmp_session_info_t *si) { if (cat & NDMP_CAT_SCSI) ndmp_connect_print_scsi_v2(si); if (cat & NDMP_CAT_TAPE) ndmp_connect_print_tape_v2(si); if (cat & NDMP_CAT_MOVER) ndmp_connect_print_mover_v3(si); if (cat & NDMP_CAT_DATA) ndmp_connect_print_data_v3(si); } /* * Print the list of all active sessions to the clients. For each version, * call the appropriate print function. */ static void ndmp_connection_print(int cat, ndmp_session_info_t *si) { switch (si->nsi_pver) { case NDMP_V2: ndmp_connect_print_conn(si); ndmp_connect_print_v2(cat, si); break; case NDMP_V3: case NDMP_V4: ndmp_connect_print_conn(si); ndmp_connect_print_v3(cat, si); break; default: (void) fprintf(stdout, gettext("Invalid version %d"), si->nsi_pver); } } /* * Print the list of all active sessions to the clients. */ /* Hammerhead: Use uint_t to match declaration in ndmpadm.h */ void ndmp_session_all_print(int cat, ndmp_session_info_t *si, uint_t num) { int i; ndmp_session_info_t *sp; sp = si; for (i = 0; i < num; i++, sp++) { ndmp_connection_print(cat, sp); (void) fprintf(stdout, "\n"); } if (num == 0) { (void) fprintf(stdout, gettext("No active session.\n")); } else { (void) fprintf(stdout, gettext("%d active sessions.\n"), num); } } /* * Print the connection information for the given category. */ void ndmp_session_print(int cat, ndmp_session_info_t *si) { ndmp_connection_print(cat, si); } void ndmp_devinfo_print(ndmp_devinfo_t *dip, size_t size) { int i; if (dip == NULL) { (void) fprintf(stdout, gettext("No device attached.\n")); return; } for (i = 0; i < size; i++, dip++) { /* * Don't print dead links. */ if ((access(dip->nd_name, F_OK) == -1) && (errno == ENOENT)) continue; switch (dip->nd_dev_type) { case NDMP_SINQ_TAPE_ROBOT: (void) fprintf(stdout, gettext("Robot (Changer):\n")); break; case NDMP_SINQ_SEQ_ACCESS_DEVICE: (void) fprintf(stdout, gettext("Tape drive(s):\n")); break; } if (dip->nd_name) (void) fprintf(stdout, gettext("\tName : %s\n"), dip->nd_name); (void) fprintf(stdout, gettext("\tLUN # : %d\n"), dip->nd_lun); (void) fprintf(stdout, gettext("\tSCSI ID # : %d\n"), dip->nd_sid); if (dip->nd_vendor) (void) fprintf(stdout, gettext("\tVendor : %s\n"), dip->nd_vendor); if (dip->nd_product) (void) fprintf(stdout, gettext("\tProduct : %s\n"), dip->nd_product); if (dip->nd_revision) (void) fprintf(stdout, gettext("\tRevision : %s\n"), dip->nd_revision); if (dip->nd_serial) (void) fprintf(stdout, gettext("\tSerial : %s\n"), dip->nd_serial); if (dip->nd_wwn) (void) fprintf(stdout, gettext("\tWWN : %s\n"), dip->nd_wwn); (void) fprintf(stdout, "\n"); } }