mmsadm.c revision cee0fb94c0d4227de0a00efc162fb2739844b641
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <errno.h>
#include <libnvpair.h>
#include "mms_trace.h"
#include "mms_mgmt.h"
#include "mgmt_acsls.h"
#include "mgmt_library.h"
#include "mgmt_media.h"
#include "mms_cfg.h"
extern char *optarg;
static char *usemsg =
"Usage: mmsadm [-h] <subcommand>\n\
Subcommands:\n\
\tdiscover\n\
\tcreate\n\
\tdelete\n\
\tset\n\
\tlist\n\
\tpasswd\n\
\tonline\n\
\toffline\n\
\tadd-volume\n\
\tremove-volume\n\
\tlabel\n\
\tshowreq\n\
\taccept\n\
\treject\n\
\tmount\n\
\tunmount\n\
\tdbbackup\n\
\tdbrestore\n\
the mmsadm man page.\n";
static char discover_usemsg[] =
"\nUsage: mmsadm discover [-a] [-H] [-S ACSLS-server:port] \
[-t library|drive|vol]\n\
\t-a\tShow all, including already-configured resources\n\
\t-H\tScripting mode\n\
\t-S\tACSLS server name and optional port number\n\
\t\tIf not specified, displays locally connected tape drives\n\
\t-t\tResource type\n";
static char create_usemsg[] =
"\nUsage: mmsadm create -t <type> -o option=x [-o option2=y ...] name\n\
\t-t\tResource type - library, drive, mpool, app, dkvol, dkdrive or voltype\n";
static char delete_usemsg[] =
"\nUsage: mmsadm delete -t <type> [-f] name\n\
\t-t\tResource type - library, drive, mpool, app, dkvol, dkdrive or voltype\n\
\t-f\tForce\n";
static char set_usemsg[] =
"\nUsage: mmsadm set -t <type> -o option=x [-o option2=y ...] name\n\
\t-t\tResource type - system, library, drive, mpool, app, dkvol, dkdrive \
or voltype\n";
static char passwd_usemsg[] =
"\nUsage: mmsadm passwd [-P passwdfile] name\n\
\t-P\tPath to a temporary file containing the password\n\
\tname\tApplication name. Use 'admin' to change the MMS Administrative \
password\n";
static char online_usemsg[] =
"\nUsage: mmsadm online -t library|drive name\n\
\t-t\t Resource type\n";
static char offline_usemsg[] =
"\nUsage: mmsadm offline -t library|drive name\n\
\t-t\t Resource type\n";
static char label_usemsg[] =
"\nUsage: mmsadm label -l library -A application [-f] volume[,volume]\n\
\t-l\tLibrary holding the volume\n\
\t-A\tApplication to which this volume will be assigned after labeling\n\
\t-f\tForce label. Use this option to relabel a tape that has previously \
been labeled.\n";
static char add_usemsg[] =
"\nUsage: mmsadm add-volume -l library -x vol[,vol2...] mpool\n\
\t-l\tLibrary from which the volume will be selected\n\
\t-x\tComma separated list of volumes to be added\n\
\tmpool\tName of media pool to which the volumes will be added\n";
static char remove_usemsg[] =
"\nUsage: mmsadm remove-volume -l library [-f] -x vol[,vol2...] mpool\n\
\t-l\tLibrary from which the volume will be selected\n\
\t-x\tComma separated list of volumes to be added\n\
\t-f\tForce. Use this option to remove a volume which has previously \
been used\n\
\tmpool\tName of media pool to which the volumes will be added\n";
static char show_usemsg[] =
"\nUsage: mmsadm showreq [-H]\n\
\t-H\tScripting mode.\n";
static char accept_usemsg[] =
"\nUsage: mmsadm accept [-r \"response text\"] requestid\n\
\t-r\tOptional text message\n\
\trequestid\tRequest ID as displayed by the 'mmsadm showreq' command\n";
static char reject_usemsg[] =
"\nUsage: mmsadm reject [-r \"response text\"] requestid\n\
\t-r\tOptional text message\n\
\trequestid\tRequest ID as displayed by the 'mmsadm showreq' command\n";
static char back_usemsg[] =
"\nUsage: mmsadm dbbackup <directory>\n\
\tdirectory\tDirectory where the database backup file will be stored\n";
static char rest_usemsg[] =
"\nUsage: mmsadm dbrestore <filename>\n\
\tfilename\tComplete path to the file containing the backup to be restored\n";
static char mount_usemsg[] =
"\nUsage: mmsadm mount [-n] [-N] [-d drive] [-D density] [-A application] \
-l library [-P passwdfile] [-u username] [-b blocksize] [-R] \
[-M mode[,mode...]] volume\n\
\t-n\tnorewind\n\
\t-N\tnowait\n\
\t-d\tdrive on which to mount the volume\n\
\t-D\tdensity\n\
\t-A\tapplication name\n\
\t-l\tlibrary containing the volume to be mounted\n\
\t-P\tPath to a temporary file containing the password\n\
\t-u\tThe username who will have ownership of pseudodevice created by mount\n\
\t-b\tblocksize\n\
\t-R\treadonly\n\
\t-M\tmode. One or more of creat, trunc, append. old, st_nobsd, st_tm, raw, \n\
\t\tmms, compression, nocompression, variable, block\n";
static char unmount_usemsg[] =
"\nUsage: mmsadm unmount [-U] [-l library] [-A application] [-P passwdfile] \
volume|pseudodevice\n\
\t-U\tPhysically unload the tape from the drive\n\
\t-l\tLibrary containing the volume to be unmounted\n\
\t-A\tapplication name\n\
\t-P\tPath to a temporary file containing the password\n\
\tvolume\tVolume to be unmounted \n\
\tpseudodevice\tName of pseudodevice as returned from the \
'mmsadm mount' command\n";
static char *setphrases[2] = {
"Enter password: ",
"Re-enter password: "
};
static char *getphrases[2] = {
"Enter application password: ",
};
typedef struct {
char *subopt;
char *usemsg;
} adminfuncs_t;
static adminfuncs_t mmsadmfuncs[] = {
};
static char *cmdopts = ":aA:b:d:D:fF:hHl:L:m:M:nNo:P:r:Rs:S:t:u:Uv?x:V:";
int
{
int st = 0;
int i;
int cmdidx = -1;
char c;
char buf[2048];
char *bufp;
int hflag = 0;
char *tmpstr;
if (argc < 2) {
hflag++;
st = 1;
goto done;
}
/* see if this host has been initialized. If not, fail. */
if (st != 0) {
" use on this system. Please run the mmsinit command.\n");
goto done;
}
/*
* see if we've got a subcommand. If we don't, fall through
* to getopt() anyway.
*/
/* reset options for getopt */
newargc--;
cmdidx = i;
}
break;
}
}
hflag++;
st = 1;
goto done;
}
st = 1;
goto done;
}
if (st != 0) {
goto done;
}
if (st != 0) {
goto done;
}
if (listing) {
}
while (st == 0) {
if (c == -1) {
break;
}
switch (c) {
case 'a':
B_TRUE);
break;
case 'A':
break;
case 'b':
optarg);
break;
case 'd':
break;
case 'D':
break;
case 'f':
B_TRUE);
break;
case 'F':
if (!listing) {
optarg);
} else {
/* list filter */
B_TRUE);
}
break;
case 'H':
B_TRUE);
break;
case 'l':
case 'L':
break;
case 'm':
break;
case 'M':
/* possibly multi-value */
break;
}
break;
case 'n':
B_TRUE);
break;
case 'N':
B_TRUE);
break;
case 'o':
if (!listing) {
} else {
/* possibly multi-value */
break;
}
"printopts", nvl);
}
break;
case 'P':
/* read password from file */
optarg);
break;
case 'r':
break;
case 'R':
break;
case 's':
/* possibly multi-value */
break;
}
nvl);
break;
case 'S':
*bufp++ = '\0';
bufp);
}
if (st == 0) {
buf);
}
break;
case 't':
}
break;
case 'u':
break;
case 'U':
B_TRUE);
break;
case 'v':
B_TRUE);
break;
case 'V':
break;
case 'x':
/* process list of volumes */
/* possibly multi-value */
break;
}
nvl);
break;
case '?':
case 'h':
hflag++;
break;
case ':':
"Option %s requires an operand\n",
st = 1;
break;
default:
break;
}
}
goto done;
}
/* get object name[s] we're to act on, if any */
/* possibly multi-value */
goto done;
}
if (st != 0) {
goto done;
}
} else {
/* see if this subcommand requires one or more objects */
"Error, command requires an object name\n");
goto done;
}
}
/* hmm, leftover cmd args? */
"Error: extra arguments after command line processing.\n");
hflag++;
st = 1;
goto done;
}
done:
if (hflag) {
}
}
if (st != 0) {
int nvi = 0;
const char *nve;
if (nve) {
}
if (errs) {
} else {
}
}
}
}
}
return (st);
}
static void
{
} else {
}
}
static int
{
int st = 0;
char *bufp;
char *fmt = "%-8s%-10s%-20s%-20s%-20s\n";
char *sfmt = "%s\t%s\t%s\t%s\t%s\n";
char buf[128];
char *fmtp;
return (EINVAL);
}
/* not set, report on both libraries and drives */
} else if (st == 0) {
if (*bufp == 'l') {
} else if (*bufp == 'd') {
} else if (*bufp == 'v') {
/* volumes */
return (st);
} else {
if (errs) {
}
return (st);
}
} else {
return (st);
}
if (st == 0) {
host = "localhost";
st = 0;
} else if (st == 0) {
"Remote discovery not yet supported\n");
st = EOPNOTSUPP;
}
}
}
if (st != 0) {
return (st);
}
if (!dolocal) {
/* get ACSLS information */
} else {
/* Local drives only */
goto done;
}
goto done;
}
/* print header */
if (!doscript) {
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
} else {
}
/* print out what we found */
if (lib) {
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
}
}
continue;
}
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
}
}
}
done:
return (st);
}
static int
{
int st;
if (!nvl) {
return (EFAULT);
}
if (st != 0) {
return (st);
}
if (st == 0) {
}
} else {
return (EINVAL);
}
return (st);
}
static int
{
int st;
if (!nvl) {
return (EFAULT);
}
if (st == 0) {
}
if (st != 0) {
return (st);
}
if (st != 0) {
return (st);
}
}
return (st);
}
return (st);
}
return (st);
}
return (st);
}
return (st);
}
return (st);
}
} else {
return (EINVAL);
}
return (st);
}
static int
{
int st;
if (!nvl) {
return (EFAULT);
}
if (st != 0) {
return (st);
}
} else {
return (EINVAL);
}
return (st);
}
static int
{
int st;
char **printopts;
int pcount = 0;
if (st != 0) {
st = 0;
} else {
return (st);
}
}
if (st == 0) {
}
}
if (st == 0) {
}
}
if (st == 0) {
}
}
if (st == 0) {
}
}
if (st == 0) {
}
}
if (st == 0) {
}
}
if (st == 0) {
}
}
if (st == 0) {
}
}
st = EOPNOTSUPP;
}
if (outlist) {
}
return (st);
}
static int
{
char *key;
char *val;
int i;
return (EFAULT);
}
if (!doscript) {
}
if (printopts) {
for (i = 0; i < pcount; i++) {
if (!printopts[i]) {
continue;
}
break;
}
}
if (!printme) {
continue;
}
}
if (!doscript) {
} else {
if (first) {
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
} else {
}
}
}
printf("\n");
}
}
return (0);
}
static int
{
int st;
if (!nvl) {
return (EFAULT);
}
return (st);
}
static int
{
int st;
if (!nvl) {
return (EFAULT);
}
return (st);
}
static int
{
int st;
char *fname;
if (!nvl) {
return (EFAULT);
}
if (st == 0) {
} else {
if (errs) {
}
}
if (st == 0) {
}
return (st);
}
static int
{
int st;
char *fname;
if (!nvl) {
return (EFAULT);
}
if (st == 0) {
if (st == MMS_MGMT_DBDUMP_MISSING) {
}
}
} else {
if (errs) {
}
}
return (st);
}
static int
{
int st;
char *fmt = "%-10s%-10s%-30s%-20s\n";
char *sfmt = "%s\t%s\t%s\t%s\n";
char *fmtp;
if (!nvl) {
return (EFAULT);
}
if (st != 0) {
return (st);
}
/* print header */
if (!doscript) {
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
} else {
}
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
}
return (st);
}
static int
{
int st;
if (!nvl) {
return (EFAULT);
}
return (st);
}
static int
{
int st;
if (!nvl) {
return (EFAULT);
}
return (st);
}
static int
{
int st;
char *val;
char *fmt = "%-20s%-20s%-20s%-20s\n";
char *sfmt = "%s\t%s\t%s\t%s\n";
char *fmtp;
char *sn;
char *ty;
char *dv;
char *id;
if (!nvl) {
return (EFAULT);
}
if (st != 0) {
return (st);
}
printf("No drives attached to this system.\n");
return (0);
}
/* print header */
if (!doscript) {
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
} else {
}
/* get list of drives from MM, if any */
do {
sn = "";
id = "";
dv = "";
ty = "";
if (st != 0) {
break;
}
/*
* while serial number is the best way to look up
* devices, need an alternate if device is busy when
* we ran the probe. When filtering is enabled for
* listing drives, list only those attached to this
* system. Then we can do device name lookups.
*/
if (st == 0) {
!= NULL) {
if (st != 0) {
continue;
}
"DriveSerialNum", &val);
if (st != 0) {
continue;
}
"DriveName", &val);
if (st == 0) {
}
}
}
}
/* reset, lookup failures shouldn't be reported to user */
st = 0;
continue;
}
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
return (0);
}
static int
{
int st;
if (!nvl) {
return (EFAULT);
}
if (st != 0) {
if (errs) {
}
return (st);
}
if (st != 0) {
if (errs) {
}
return (st);
}
return (st);
}
static int
{
int st;
if (st != 0) {
return (st);
}
return (st);
}
static int
{
int st;
if (!nvl) {
return (EFAULT);
}
if (!reqID) {
return (st);
}
return (st);
}
static int
{
int st;
if (!nvl) {
return (EFAULT);
}
if (!reqID) {
return (st);
}
return (st);
}
static int
{
char yesno = 'n';
if (!objname) {
return (MMS_MGMT_NOARG);
}
"To delete %s from a script, please use the -f option.\n",
objname);
return (1);
}
"Do you really want to delete %s? ([y]|n)",
objname);
return (0);
}
return (1);
}
static int
{
int st;
if (!nvl) {
return (EINVAL);
}
if (st != 0) {
}
return (st);
}
if (st != 0) {
return (st);
}
}
return (st);
}
static int
{
int st;
if (!nvl) {
return (EINVAL);
}
if (st != 0) {
}
return (st);
}
if (st != 0) {
return (st);
}
}
if (st == 0) {
}
if (st == 0) {
}
return (st);
}
static int
{
int st;
if (!nvl) {
return (EINVAL);
}
if (st != 0) {
}
return (st);
}
if (st != 0) {
return (st);
}
}
return (st);
}