--- a/usr/src/cmd/beadm/BootEnvironment.py Thu Dec 16 09:43:44 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,444 +0,0 @@
-# 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
-# or http://www.opensolaris.org/os/licensing.
-# 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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-"""Boot Environment classes used by beadm."""
-
-import datetime
-
-class BootEnvironment:
- """Boot Environment object that is used by beadm to manage command line
- options, arguments and the log."""
-
- def __init__(self):
- self.trgt_rpool = None
- self.trgt_be_name_or_snapshot = None
- self.src_be_name_or_snapshot = None
- self.properties = {}
- self.log_id = None
- self.log = None
- self.msg_buf = {}
- self.description = None
-
-class listBootEnvironment:
- """Base class for beadm list
- Determine the BE's to display. Prints command output according to option:
- -d - dataset
- -s - snapshot
- -a - all (both dataset and snapshot)
- <none> - only BE information
- The -H option produces condensed, parseable output
- The ';' delimits each field in the output. BEs with multiple
- datasets will have multiple lines in the output.
- """
-
- def list(self, be_list, ddh, be_name):
- """ print all output for beadm list command
- be_list - list of all BEs
- ddh - if True, Do not Display Headers - just parseable data
- be_name - user-specified BE, if any
-
- returns 0 for success
- side effect: beadm list output printed to stdout
- """
-
- #If we're listing Headers, initialize the array holding the
- #column widths with the header widths themselves. Later on,
- #the data in this array will get adjusted as we process actual
- #row data and find that a piece of data is wider than its
- #column header.
- bemaxout = [0 for i in range(len(self.hdr[0]))]
- if not ddh:
- #iterate all header rows since their fields may not
- #be of equal length.
- for header in self.hdr:
- icol = 0
- for hc in header:
- if len(hc) + 1 > bemaxout[icol]:
- bemaxout[icol] = len(hc) + 1
- icol += 1
-
- #collect BEs
- beout = {} #matrix of output text [row][attribute]
- beoutname = {} #list of BE names [row]
- be_space = {} #space used totals for BE [BE name]['space_used','ibei']
- ibe = 0 #BE index
- spacecol = -1 #to contain column where space used is displayed
- for be in be_list:
- if 'orig_be_name' in be:
- cur_be = be['orig_be_name']
- cur_be_obj = be
-
- #if BE name specified, collect matching BEs
- if be_name is not None and not self.beMatch(be, be_name):
- continue
- attrs = ()
- #identify BE|dataset|snapshot attributes
- att = ''
- for att in ('orig_be_name', 'dataset', 'snap_name'):
- if att in be and att in self.lattrs:
- attrs = self.lattrs[att]
- if att == 'orig_be_name':
- be_space[cur_be] = {}
- be_space[cur_be]['space_used'] = 0
- be_space[cur_be]['ibe'] = ibe
- if not ddh and len(cur_be) + 1 > bemaxout[0]:
- bemaxout[0] = len(cur_be) + 1
- break
- beout[ibe] = {}
- beoutname[ibe] = cur_be
-
- icol = 0 #first column
- for at in attrs:
- #for option -s, withhold subordinate datasets
- if self.__class__.__name__ == 'SnapshotList' and \
- att == 'snap_name' and 'snap_name' in be and \
- '/' in be[att]:
- break
- #convert output to readable format and save
- save = self.getAttr(at, be, ddh, cur_be_obj)
- beout[ibe][at] = save
- #maintain maximum column widths
- if not ddh and len(save) + 1 > bemaxout[icol]:
- bemaxout[icol] = len(save) + 1
- #sum all snapshots for BE
- if at == 'space_used' and 'space_used' in be:
- spacecol = icol
- icol += 1 #next column
- ibe += 1
- if 'space_used' in be:
- #sum all snapshots and datasets for BE in 'beadm list'
- if isinstance(self, BEList):
- be_space[cur_be]['space_used'] += be.get('space_used')
- elif cur_be in be_space and \
- ('space_used' not in be_space[cur_be] or
- be_space[cur_be]['space_used'] == 0):
- #list space used separately for other options
- be_space[cur_be]['space_used'] = be.get('space_used')
-
- #output format total lengths for each BE with any snapshots
- for cur_be in be_space:
- save = self.getSpaceValue(be_space[cur_be]['space_used'], ddh)
- ibe = be_space[cur_be]['ibe']
- beout[ibe]['space_used'] = save
- #expand column if widest column entry
- if (spacecol != -1) and \
- (not ddh and len(save) + 1 > bemaxout[spacecol]):
- bemaxout[spacecol] = len(save) + 1
-
- #print headers in columns
- if not ddh:
- for header in self.hdr:
- outstr = ''
- for icol in range(len(header)):
- outstr += header[icol].ljust(bemaxout[icol])
- if outstr != '':
- print outstr
-
- #print collected output in columns
- outstr = ''
- prev_be = None
- cur_be = None
- for ibe in beout: #index output matrix
- if beoutname[ibe] != None:
- cur_be = beoutname[ibe]
- #find attributes for BE type
- curtype = None
- for att in ('orig_be_name', 'dataset', 'snap_name'):
- if att in beout[ibe]:
- attrs = self.lattrs[att]
- curtype = att
- break
-
- if curtype == None: #default to BE
- curtype = 'orig_be_name'
- if 'orig_be_name' in self.lattrs:
- attrs = self.lattrs['orig_be_name']
- else: attrs = ()
-
- if not ddh:
- if prev_be != cur_be and cur_be != None:
- #for -d,-s,-a, print BE alone on line
- if self.__class__.__name__ != 'BEList':
- print cur_be
- prev_be = cur_be
-
- #print for one BE/snapshot/dataset
- icol = 0 #first column
-
- #if this is a 'dataset' or 'snap_name', start line with BE
- #name token
- if ddh and curtype != 'orig_be_name':
- outstr = cur_be
-
- for at in attrs: #for each attribute specified in table
- if ddh: #add separators for parsing
- if outstr != '':
- outstr += ';' #attribute separator
- if at in beout[ibe] and beout[ibe][at] != '-' and \
- beout[ibe][at] != '':
- outstr += beout[ibe][at]
- else: #append text justified in column
- if at in beout[ibe]:
- outstr += beout[ibe][at].ljust(bemaxout[icol])
- icol += 1 #next column
-
- if outstr != '':
- print outstr
- outstr = ''
-
- return 0
-
- def beMatch(self, be, be_name):
- """find match on user-specified BE."""
-
- if 'orig_be_name' in be:
- return be.get('orig_be_name') == be_name
- if 'dataset' in be:
- if be.get('dataset') == be_name:
- return True
- out = be.get('dataset').split("/")
- return out[0] == be_name
- if 'snap_name' in be:
- if be.get('snap_name') == be_name:
- return True
- out = be.get('snap_name').split('@')
- if out[0] == be_name:
- return True
- out = be.get('snap_name').split('/')
- return out[0] == be_name
- return False
-
- def getAttr(self, at, be, ddh, beobj):
- """
- Extract information by attribute and format for printing
- returns '?' if normally present attribute not found - error.
- """
- if at == 'blank':
- return ' '
- if at == 'dash':
- return '-'
- if at == 'orig_be_name':
- if at not in be:
- return '-'
- ret = be[at]
- if ddh or self.__class__.__name__ == 'BEList':
- return ret
- return ' ' + ret #indent
- if at == 'snap_name':
- if at not in be:
- return '-'
- if self.__class__.__name__ == 'CompleteList':
- ret = self.prependRootDS(be[at], beobj)
- else:
- ret = be[at]
- if ddh:
- return ret
- return ' ' + ret #indent
- if at == 'dataset':
- if at not in be:
- return '-'
- if self.__class__.__name__ == 'DatasetList' or \
- self.__class__.__name__ == 'CompleteList':
- ret = self.prependRootDS(be[at], beobj)
- else:
- ret = be[at]
- if ddh:
- return ret
- return ' ' + ret #indent
- if at == 'active':
- if at not in be:
- return '-'
- ret = ''
- if 'active' in be and be['active']:
- ret += 'N'
- if 'active_boot' in be and be['active_boot']:
- ret += 'R'
- if ret == '':
- return '-'
- return ret
- if at == 'mountpoint':
- if at not in be:
- return '-'
- if 'mounted' not in be or not be['mounted']:
- return '-'
- return be[at]
- if at == 'space_used':
- if at not in be:
- return '0'
- return self.getSpaceValue(be[at], ddh)
- if at == 'mounted':
- if at not in be:
- return '-'
- return be[at]
- if at == 'date':
- if at not in be:
- return '?'
- if ddh:
- return str(be[at]) #timestamp in seconds
- sec = str(datetime.datetime.fromtimestamp(be[at]))
- return sec[0:len(sec)-3] #trim seconds
- if at == 'policy':
- if at not in be:
- return '?'
- return be[at]
- if at == 'root_ds':
- if at not in be:
- return '?'
- if ddh or self.__class__.__name__ == 'BEList':
- return be[at]
- return ' ' + be[at]
- if at == 'uuid_str':
- if at not in be:
- return '-'
- return be[at]
- #default case - no match on attribute
- return be[at]
-
- def getSpaceValue(self, num, ddh):
- """Readable formatting for disk space size."""
-
- if ddh:
- return str(num) #return size in bytes as string
-
- kilo = 1024.0
- mega = 1048576.0
- giga = 1073741824.0
- tera = 1099511627776.0
-
- if num == None:
- return '0'
- if num < kilo:
- return str(num) + 'B'
- if num < mega:
- return str('%.1f' % (num / kilo)) + 'K'
- if num < giga:
- return str('%.2f' % (num / mega)) + 'M'
- if num < tera:
- return str('%.2f' % (num / giga)) + 'G'
- return str('%.2f' % (num / tera)) + 'T'
-
- def prependRootDS(self, val, beobj):
- """Prepend root dataset name with BE name stripped."""
-
- root_ds = beobj.get('root_ds')
- return root_ds[0:root_ds.rfind('/')+1] + val
-
-
-"""Top level "beadm list" derived classes defined here.
- Only table definition is done here - all methods are in the base class.
- Tables driving list:
- hdr - list of text to output for each column
- lattrs - dictionary of attributes
- Each entry specifies either BE, dataset, snapshot with
- an attribute key:
- orig_be_name - for BEs
- dataset - for datasets
- snap_name - for snapshots
- Each list item in entry indicates specific datum for
- column
- Number of hdr columns must equal number of lattrs entries
- unless ddh (dontDisplayHeaders) is true.
-"""
-class BEList(listBootEnvironment):
- """specify header and attribute information for BE-only output"""
-
- def __init__(self, ddh):
- """Init function for the class."""
- self.hdr = \
- ('BE','Active','Mountpoint','Space','Policy','Created'), \
- ('--','------','----------','-----','------','-------')
- if ddh:
- self.lattrs = {'orig_be_name':('orig_be_name', 'uuid_str',
- 'active', 'mountpoint', 'space_used', 'policy',
- 'date')}
- else:
- self.lattrs = {'orig_be_name':('orig_be_name', 'active',
- 'mountpoint', 'space_used', 'policy', 'date')}
-
-class DatasetList(listBootEnvironment):
- """
- specify header and attribute information for dataset output,
- -d option
- """
- def __init__(self, ddh):
- """Init function for the class."""
-
- self.hdr = \
- ('BE/Dataset','Active','Mountpoint','Space','Policy','Created'), \
- ('----------','------','----------','-----','------','-------')
- if ddh:
- self.lattrs = { \
- 'orig_be_name':('orig_be_name', 'root_ds', 'active',
- 'mountpoint', 'space_used', 'policy', 'date'), \
- 'dataset':('dataset', 'dash', 'mountpoint', 'space_used',
- 'policy', 'date')}
- else:
- self.lattrs = { \
- 'orig_be_name':('root_ds', 'active', 'mountpoint',
- 'space_used', 'policy', 'date'), \
- 'dataset':('dataset', 'dash', 'mountpoint', 'space_used',
- 'policy', 'date')}
-
-class SnapshotList(listBootEnvironment):
- """
- specify header and attribute information for snapshot output,
- -s option
- """
- def __init__(self, ddh):
- """Init function for the class."""
-
- self.hdr = \
- ('BE/Snapshot','Space','Policy','Created'), \
- ('-----------','-----','------','-------')
- self.lattrs = {'snap_name':('snap_name', 'space_used', 'policy',
- 'date')}
-
-class CompleteList(listBootEnvironment):
- """
- specify header and attribute information for BE and/or dataset and/or
- snapshot output,
- -a or -ds options
- """
- def __init__(self, ddh):
- """Init function for the class."""
-
- self.hdr = \
- ('BE/Dataset/Snapshot','Active','Mountpoint','Space','Policy','Created'), \
- ('-------------------','------','----------','-----','------','-------')
- if ddh:
- self.lattrs = { \
- 'orig_be_name':('orig_be_name', 'root_ds', 'active',
- 'mountpoint', 'space_used', 'policy', 'date'),
- 'dataset':('dataset', 'dash', 'mountpoint', 'space_used',
- 'policy', 'date'),
- 'snap_name':('snap_name', 'dash', 'dash', 'space_used',
- 'policy', 'date')}
- else:
- self.lattrs = { \
- 'orig_be_name':('root_ds', 'active', 'mountpoint',
- 'space_used', 'policy', 'date'), \
- 'dataset':('dataset', 'dash', 'mountpoint', 'space_used',
- 'policy', 'date'),
- 'snap_name':('snap_name', 'dash', 'dash', 'space_used',
- 'policy', 'date')}
--- a/usr/src/cmd/beadm/Makefile Thu Dec 16 09:43:44 2010 -0800
+++ b/usr/src/cmd/beadm/Makefile Mon Dec 27 21:47:11 2010 +0300
@@ -18,60 +18,45 @@
#
# CDDL HEADER END
#
-
-#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
+# Copyright 2010 Nexenta Systems, Inc. All rights reserved.
+#
+
+PROG= beadm
+OBJS= beadm.o
+SRCS= $(OBJS:%.o=%.c)
+POFILE= beadm.po
include ../Makefile.cmd
-FILEMODE=0444
-
-PYTHON= $(PYTHON_26)
-ROOTPYDIR= $(ROOT)/usr/lib/python2.6/vendor-packages
-ROOTMODDIR= $(ROOTPYDIR)/beadm
-
-PYCMD= beadm.py
-PYCMDFILE= $(PYCMD:%.py=%)
+LDLIBS += -lnvpair -lbe
-PYMODULES= __init__.py BootEnvironment.py messages.py
-PYMODOBJS= $(PYMODULES:%.py=%.pyc)
-PYMODFILES= $(PYMODULES) $(PYMODOBJS)
+$(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG
-ROOTCMDFILE= $(PYCMDFILE:%=$(ROOTSBIN)/%)
-$(ROOTCMDFILE) := FILEMODE = 0555
-ROOTMODFILES= $(PYMODFILES:%=$(ROOTMODDIR)/%)
-ROOTUSRSBINLINKS= $(PYCMDFILE:%=$(ROOTUSRSBIN)/%)
-
-POFILE = beadm.po
-MSGFILES = beadm.py messages.py
-XGETTEXT = $(GNUXGETTEXT)
-XGETFLAGS = $(GNUXGETFLAGS)
+ROOTUSRSBINLINKS = $(PROG:%=$(ROOTUSRSBIN)/%)
.KEEP_STATE:
-all: $(PYCMDFILE) $(PYMODOBJS)
+.PARALLEL:
+
+all: $(PROG)
-install: all $(ROOTCMDFILE) $(ROOTMODFILES) $(ROOTUSRSBINLINKS)
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTSBINPROG) $(ROOTUSRSBINLINKS)
clean:
- $(RM) $(PYCMDFILE) $(PYMODOBJS)
-
-clobber: clean
+ $(RM) $(OBJS)
-$(ROOTCMDDIR)/%: %
- $(INS.pyfile)
-
-$(ROOTMODDIR)/%: %
- $(INS.pyfile)
+lint: lint_SRCS
+# Links from /usr/sbin to /sbin
$(ROOTUSRSBINLINKS):
- -$(RM) $@; $(SYMLINK) ../../sbin/$(@F) $@
+ -$(RM) $@; $(SYMLINK) ../../sbin/$(PROG) $@
-$(POFILE): $(MSGFILES)
- $(BUILDPO.msgfiles)
+FRC:
-_msg: $(MSGDOMAINPOFILE)
-
-include $(SRC)/Makefile.msg.targ
include ../Makefile.targ
--- a/usr/src/cmd/beadm/__init__.py Thu Dec 16 09:43:44 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-# 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
-# or http://www.opensolaris.org/os/licensing.
-# 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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-import gettext
-
-_ = gettext.translation("beadm", "/usr/lib/locale",
- fallback=True).gettext
-
-__all__ = ["messages", "BootEnvironment"]
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/beadm/beadm.c Mon Dec 27 21:47:11 2010 +0300
@@ -0,0 +1,1677 @@
+/*
+ * 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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * System includes
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <strings.h>
+#include <libzfs.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <sys/types.h>
+
+#include "libbe.h"
+
+#ifndef lint
+#define _(x) gettext(x)
+#else
+#define _(x) (x)
+#endif
+
+#ifndef TEXT_DOMAIN
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+
+#define DT_BUF_LEN (128)
+#define NUM_COLS (6)
+
+static int be_do_activate(int argc, char **argv);
+static int be_do_create(int argc, char **argv);
+static int be_do_create_snapshot(int argc, char **argv);
+static int be_do_destroy(int argc, char **argv);
+static int be_do_destroy_snapshot(int argc, char **argv);
+static int be_do_list(int argc, char **argv);
+static int be_do_mount(int argc, char **argv);
+static int be_do_unmount(int argc, char **argv);
+static int be_do_rename(int argc, char **argv);
+static int be_do_rollback(int argc, char **argv);
+static void usage(void);
+
+/*
+ * single column name/width output format description
+ */
+struct col_info {
+ const char *col_name;
+ size_t width;
+};
+
+/*
+ * all columns output format
+ */
+struct hdr_info {
+ struct col_info cols[NUM_COLS];
+};
+
+/*
+ * type of possible output formats
+ */
+enum be_fmt {
+ BE_FMT_DEFAULT,
+ BE_FMT_DATASET,
+ BE_FMT_SNAPSHOT,
+ BE_FMT_ALL,
+ BE_NUM_FMTS
+};
+
+/*
+ * command id
+ */
+enum be_cmd {
+ BE_CMD_ACTIVATE,
+ BE_CMD_CREATE,
+ BE_CMD_CREATE_SNAP,
+ BE_CMD_DESTROY,
+ BE_CMD_DESTROY_SNAP,
+ BE_CMD_LIST,
+ BE_CMD_MOUNT,
+ BE_CMD_UNMOUNT,
+ BE_CMD_RENAME,
+ BE_CMD_ROLLBACK,
+
+ BE_NUM_COMMANDS
+};
+
+/*
+ * command handler description
+ */
+typedef struct be_command {
+ const char *name;
+ int (*func)(int argc, char **argv);
+} be_command_t;
+
+/*
+ * sorted list of be commands
+ */
+static const be_command_t be_command_tbl[BE_NUM_COMMANDS] = {
+ { "activate", be_do_activate },
+ { "create", be_do_create },
+ { "create_snap", be_do_create_snapshot },
+ { "destroy", be_do_destroy },
+ { "destroy_snap", be_do_destroy_snapshot },
+ { "list", be_do_list },
+ { "mount", be_do_mount },
+ { "unmount", be_do_unmount },
+ { "rename", be_do_rename },
+ { "rollback", be_do_rollback },
+};
+
+static struct hdr_info hdrs[BE_NUM_FMTS] = { 0 };
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, _("usage:\n"
+ "\tbeadm subcommand cmd_options\n"
+ "\n"
+ "\tsubcommands:\n"
+ "\n"
+ "\tbeadm create [-d BE_desc]\n"
+ "\t\t[-o property=value] ... [-p zpool] \n"
+ "\t\t[-e nonActiveBe | beName@snapshot] beName\n"
+ "\tbeadm create [-d BE_desc]\n"
+ "\t\t[-o property=value] ... [-p zpool] beName@snapshot\n"
+ "\tbeadm create_snap [-p policy] beName [snapshot]\n"
+ "\tbeadm destroy [-Ffs] beName \n"
+ "\tbeadm destroy [-F] beName@snapshot \n"
+ "\tbeadm destroy_snap beName snapshot\n"
+ "\tbeadm list [[-a] | [-d] [-s]] [-H] [beName]\n"
+ "\tbeadm mount [-s ro|rw] beName [mountpoint]\n"
+ "\tbeadm unmount [-f] beName\n"
+ "\tbeadm rename origBeName newBeName\n"
+ "\tbeadm rollback beName snapshot\n"
+ "\tbeadm rollback beName@snapshot\n"));
+}
+
+static int
+run_be_cmd(const char *cmdname, int argc, char **argv)
+{
+ int cmd;
+ for (cmd = 0; cmd < BE_NUM_COMMANDS; cmd++) {
+ const be_command_t *command = &be_command_tbl[cmd];
+ if (strcmp(command->name, cmdname) == 0)
+ return (command->func(argc, argv));
+ }
+
+ (void) fprintf(stderr, _("Invalid command: %s\n"), cmdname);
+ usage();
+ return (1);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *cmdname;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+ if (argc < 2) {
+ usage();
+ return (1);
+ }
+
+ cmdname = argv[1];
+
+ /* Turn error printing off */
+ libbe_print_errors(B_FALSE);
+
+ return (run_be_cmd(cmdname, --argc, ++argv));
+}
+
+static void
+print_hdr(struct hdr_info *hdr_info)
+{
+ boolean_t first = B_TRUE;
+ size_t i;
+ for (i = 0; i < NUM_COLS; i++) {
+ struct col_info *col_info = &hdr_info->cols[i];
+ const char *name = col_info->col_name;
+ size_t width = col_info->width;
+ if (name == NULL)
+ continue;
+
+ if (first) {
+ (void) printf("%-*s", width, name);
+ first = B_FALSE;
+ } else
+ (void) printf(" %-*s", width, name);
+ }
+ (void) putchar('\n');
+}
+
+static void
+init_hdr_cols(enum be_fmt be_fmt, struct hdr_info *hdr)
+{
+ struct col_info *col = hdr->cols;
+ size_t i;
+
+ col[1].col_name = _("Active");
+ col[2].col_name = _("Mountpoint");
+ col[3].col_name = _("Space");
+ col[4].col_name = _("Policy");
+ col[5].col_name = _("Created");
+ col[6].col_name = NULL;
+
+ switch (be_fmt) {
+ case BE_FMT_ALL:
+ col[0].col_name = _("BE/Dataset/Snapshot");
+ break;
+ case BE_FMT_DATASET:
+ col[0].col_name = _("BE/Dataset");
+ break;
+ case BE_FMT_SNAPSHOT:
+ col[0].col_name = _("BE/Snapshot");
+ col[1].col_name = NULL;
+ col[2].col_name = NULL;
+ break;
+ case BE_FMT_DEFAULT:
+ default:
+ col[0].col_name = _("BE");
+ }
+
+ for (i = 0; i < NUM_COLS; i++) {
+ const char *name = col[i].col_name;
+ col[i].width = 0;
+
+ if (name != NULL) {
+ wchar_t wname[128];
+ size_t sz = mbstowcs(wname, name, sizeof (wname) /
+ sizeof (wchar_t));
+ if (sz > 0)
+ col[i].width = wcswidth(wname, sz);
+ }
+ }
+}
+
+static void
+nicenum(uint64_t num, char *buf, size_t buflen)
+{
+ uint64_t n = num;
+ int index = 0;
+ char u;
+
+ while (n >= 1024) {
+ n /= 1024;
+ index++;
+ }
+
+ u = " KMGTPE"[index];
+
+ if (index == 0) {
+ (void) snprintf(buf, buflen, "%llu", n);
+ } else {
+ int i;
+ for (i = 2; i >= 0; i--) {
+ if (snprintf(buf, buflen, "%.*f%c", i,
+ (double)num / (1ULL << 10 * index), u) <= 5)
+ break;
+ }
+ }
+}
+
+static void
+count_widths(enum be_fmt be_fmt, struct hdr_info *hdr, be_node_list_t *be_nodes)
+{
+ size_t len[NUM_COLS];
+ char buf[DT_BUF_LEN];
+ int i;
+ be_node_list_t *cur_be;
+
+ for (i = 0; i < NUM_COLS; i++)
+ len[i] = hdr->cols[i].width;
+
+ for (cur_be = be_nodes; cur_be != NULL; cur_be = cur_be->be_next_node) {
+ char name[ZFS_MAXNAMELEN+1];
+ const char *be_name = cur_be->be_node_name;
+ const char *root_ds = cur_be->be_root_ds;
+ char *pos;
+ size_t node_name_len = strlen(cur_be->be_node_name);
+ size_t root_ds_len = strlen(cur_be->be_root_ds);
+ size_t mntpt_len = strlen(cur_be->be_mntpt);
+ size_t policy_len = strlen(cur_be->be_policy_type);
+ size_t used_len;
+
+ uint64_t used = cur_be->be_space_used;
+ be_snapshot_list_t *snap = NULL;
+
+ (void) strncpy(name, root_ds, sizeof (name));
+ pos = strstr(name, be_name);
+
+ if (be_fmt == BE_FMT_DEFAULT) {
+ if (node_name_len > len[0])
+ len[0] = node_name_len;
+ } else {
+ if (root_ds_len + 3 > len[0])
+ len[0] = root_ds_len + 3;
+ }
+
+ if (mntpt_len > len[2])
+ len[2] = mntpt_len;
+ if (policy_len > len[4])
+ len[4] = policy_len;
+
+ for (snap = cur_be->be_node_snapshots; snap != NULL;
+ snap = snap->be_next_snapshot) {
+ uint64_t snap_used = snap->be_snapshot_space_used;
+ const char *snap_name = snap->be_snapshot_name;
+ (void) strcpy(pos, snap_name);
+
+ if (be_fmt == BE_FMT_DEFAULT)
+ used += snap_used;
+ else if (be_fmt & BE_FMT_SNAPSHOT) {
+ int snap_len = strlen(name) + 3;
+ if (be_fmt == BE_FMT_SNAPSHOT)
+ snap_len -= pos - name;
+ if (snap_len > len[0])
+ len[0] = snap_len;
+ nicenum(snap_used, buf, sizeof (buf));
+ used_len = strlen(buf);
+ if (used_len > len[3])
+ len[3] = used_len;
+ }
+ }
+
+ if (be_fmt == BE_FMT_DEFAULT) {
+ int used_len;
+ nicenum(used, buf, sizeof (buf));
+ used_len = strlen(buf);
+ if (used_len > len[3])
+ len[3] = used_len;
+ }
+
+ nicenum(used, buf, sizeof (buf));
+ }
+
+ for (i = 0; i < NUM_COLS; i++)
+ hdr->cols[i].width = len[i];
+}
+
+static void
+print_be_nodes(const char *be_name, boolean_t parsable, be_node_list_t *nodes)
+{
+ char buf[64];
+ char datetime[DT_BUF_LEN];
+ struct hdr_info *hdr = NULL;
+ enum be_fmt be_fmt = BE_FMT_DEFAULT;
+ be_node_list_t *cur_be;
+
+ if (!parsable) {
+ hdr = hdrs;
+ init_hdr_cols(be_fmt, hdr);
+ count_widths(be_fmt, hdr, nodes);
+ print_hdr(hdr);
+ }
+
+ for (cur_be = nodes; cur_be != NULL; cur_be = cur_be->be_next_node) {
+ char active[3] = "-\0";
+ int ai = 0;
+ const char *datetime_fmt = "%F %R";
+ const char *name = cur_be->be_node_name;
+ const char *mntpt = cur_be->be_mntpt;
+ be_snapshot_list_t *snap = NULL;
+ uint64_t used = cur_be->be_space_used;
+ time_t creation = cur_be->be_node_creation;
+ struct tm *tm;
+
+ if (be_name != NULL && strcmp(be_name, name) != 0)
+ continue;
+
+ if (parsable)
+ active[0] = '\0';
+
+ tm = localtime(&creation);
+ (void) strftime(datetime, DT_BUF_LEN, datetime_fmt, tm);
+
+ for (snap = cur_be->be_node_snapshots; snap != NULL;
+ snap = snap->be_next_snapshot)
+ used += snap->be_snapshot_space_used;
+
+ if (cur_be->be_active)
+ active[ai++] = 'N';
+ if (cur_be->be_active_on_boot)
+ active[ai] = 'R';
+
+ nicenum(used, buf, sizeof (buf));
+ if (parsable)
+ (void) printf("%s;%s;%s;%s;%llu;%s;%ld\n",
+ name,
+ cur_be->be_uuid_str,
+ active,
+ (cur_be->be_mounted ? mntpt: ""),
+ used,
+ cur_be->be_policy_type,
+ creation);
+ else
+ (void) printf("%-*s %-*s %-*s %-*s %-*s %-*s\n",
+ hdr->cols[0].width, name,
+ hdr->cols[1].width, active,
+ hdr->cols[2].width, (cur_be->be_mounted ? mntpt:
+ "-"),
+ hdr->cols[3].width, buf,
+ hdr->cols[4].width, cur_be->be_policy_type,
+ hdr->cols[5].width, datetime);
+ }
+}
+
+static void
+print_be_snapshots(be_node_list_t *be, struct hdr_info *hdr, boolean_t parsable)
+{
+ char buf[64];
+ char datetime[DT_BUF_LEN];
+ be_snapshot_list_t *snap = NULL;
+
+ for (snap = be->be_node_snapshots; snap != NULL;
+ snap = snap->be_next_snapshot) {
+ char name[ZFS_MAXNAMELEN+1];
+ const char *datetime_fmt = "%F %R";
+ const char *be_name = be->be_node_name;
+ const char *root_ds = be->be_root_ds;
+ const char *snap_name = snap->be_snapshot_name;
+ char *pos;
+ uint64_t used = snap->be_snapshot_space_used;
+ time_t creation = snap->be_snapshot_creation;
+ struct tm *tm = localtime(&creation);
+
+ (void) strncpy(name, root_ds, sizeof (name));
+ pos = strstr(name, be_name);
+ (void) strcpy(pos, snap_name);
+
+ (void) strftime(datetime, DT_BUF_LEN, datetime_fmt, tm);
+ nicenum(used, buf, sizeof (buf));
+
+ if (parsable)
+ if (hdr->cols[1].width != 0)
+ (void) printf("%s;%s;%s;%s;%llu;%s;%ld\n",
+ be_name,
+ snap_name,
+ "",
+ "",
+ used,
+ be->be_policy_type,
+ creation);
+ else
+ (void) printf("%s;%s;%llu;%s;%ld\n",
+ be_name,
+ snap_name,
+ used,
+ be->be_policy_type,
+ creation);
+ else
+ if (hdr->cols[1].width != 0)
+ (void) printf(" %-*s %-*s %-*s %-*s %-*s "
+ "%-*s\n",
+ hdr->cols[0].width-3, name,
+ hdr->cols[1].width, "-",
+ hdr->cols[2].width, "-",
+ hdr->cols[3].width, buf,
+ hdr->cols[4].width, be->be_policy_type,
+ hdr->cols[5].width, datetime);
+ else
+ (void) printf(" %-*s %-*s %-*s %-*s\n",
+ hdr->cols[0].width-3, snap_name,
+ hdr->cols[3].width, buf,
+ hdr->cols[4].width, be->be_policy_type,
+ hdr->cols[5].width, datetime);
+ }
+}
+
+static void
+print_fmt_nodes(const char *be_name, enum be_fmt be_fmt, boolean_t parsable,
+ be_node_list_t *nodes)
+{
+ char buf[64];
+ char datetime[DT_BUF_LEN];
+ struct hdr_info *hdr = NULL;
+ be_node_list_t *cur_be;
+
+ if (!parsable) {
+ hdr = hdrs + be_fmt;
+ init_hdr_cols(be_fmt, hdr);
+ count_widths(be_fmt, hdr, nodes);
+ print_hdr(hdr);
+ }
+
+ for (cur_be = nodes; cur_be != NULL; cur_be = cur_be->be_next_node) {
+ char active[3] = "-\0";
+ int ai = 0;
+ const char *datetime_fmt = "%F %R";
+ const char *name = cur_be->be_node_name;
+ const char *mntpt = cur_be->be_mntpt;
+ uint64_t used = cur_be->be_space_used;
+ time_t creation = cur_be->be_node_creation;
+ struct tm *tm;
+
+ if (be_name != NULL && strcmp(be_name, name) != 0)
+ continue;
+
+ if (!parsable)
+ (void) printf("%-s\n", name);
+ else
+ active[0] = '\0';
+
+ tm = localtime(&creation);
+ (void) strftime(datetime, DT_BUF_LEN, datetime_fmt, tm);
+
+ if (cur_be->be_active)
+ active[ai++] = 'N';
+ if (cur_be->be_active_on_boot)
+ active[ai] = 'R';
+
+ nicenum(used, buf, sizeof (buf));
+ if (be_fmt & BE_FMT_DATASET)
+ if (parsable)
+ (void) printf("%s;%s;%s;%s;%llu;%s;%ld\n",
+ cur_be->be_node_name,
+ cur_be->be_root_ds,
+ active,
+ (cur_be->be_mounted ? mntpt: ""),
+ used,
+ cur_be->be_policy_type,
+ creation);
+ else
+ (void) printf(" %-*s %-*s %-*s %-*s %-*s "
+ "%-*s\n",
+ hdr->cols[0].width-3, cur_be->be_root_ds,
+ hdr->cols[1].width, active,
+ hdr->cols[2].width, (cur_be->be_mounted ?
+ mntpt: "-"),
+ hdr->cols[3].width, buf,
+ hdr->cols[4].width, cur_be->be_policy_type,
+ hdr->cols[5].width, datetime);
+
+ if (be_fmt & BE_FMT_SNAPSHOT)
+ print_be_snapshots(cur_be, hdr, parsable);
+ }
+}
+
+static void
+print_nodes(const char *be_name, boolean_t dsets, boolean_t snaps,
+ boolean_t parsable, be_node_list_t *be_nodes)
+{
+ enum be_fmt be_fmt = BE_FMT_DEFAULT;
+
+ if (dsets)
+ be_fmt |= BE_FMT_DATASET;
+ if (snaps)
+ be_fmt |= BE_FMT_SNAPSHOT;
+
+ if (be_fmt == BE_FMT_DEFAULT)
+ print_be_nodes(be_name, parsable, be_nodes);
+ else
+ print_fmt_nodes(be_name, be_fmt, parsable, be_nodes);
+}
+
+static boolean_t
+confirm_destroy(const char *name)
+{
+ boolean_t res = B_FALSE;
+ const char *yesre = nl_langinfo(YESEXPR);
+ const char *nore = nl_langinfo(NOEXPR);
+ regex_t yes_re;
+ regex_t no_re;
+ char buf[128];
+ char *answer;
+ int cflags = REG_EXTENDED;
+
+ if (regcomp(&yes_re, yesre, cflags) != 0) {
+ /* should not happen */
+ (void) fprintf(stderr, _("Failed to compile 'yes' regexp\n"));
+ return (res);
+ }
+ if (regcomp(&no_re, nore, cflags) != 0) {
+ /* should not happen */
+ (void) fprintf(stderr, _("Failed to compile 'no' regexp\n"));
+ regfree(&yes_re);
+ return (res);
+ }
+
+ (void) printf(_("Are you sure you want to destroy %s?\n"
+ "This action cannot be undone (y/[n]): "), name);
+
+ answer = fgets(buf, sizeof (buf), stdin);
+ if (answer == NULL || *answer == '\0' || *answer == 10)
+ goto out;
+
+ if (regexec(&yes_re, answer, 0, NULL, 0) == 0) {
+ res = B_TRUE;
+ } else if (regexec(&no_re, answer, 0, NULL, 0) != 0) {
+ (void) fprintf(stderr, _("Invalid response. "
+ "Please enter 'y' or 'n'.\n"));
+ }
+
+out:
+ regfree(&yes_re);
+ regfree(&no_re);
+ return (res);
+}
+
+static int
+be_nvl_alloc(nvlist_t **nvlp)
+{
+ assert(nvlp != NULL);
+
+ if (nvlist_alloc(nvlp, NV_UNIQUE_NAME, 0) != 0) {
+ (void) perror(_("nvlist_alloc failed.\n"));
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
+be_nvl_add_string(nvlist_t *nvl, const char *name, const char *val)
+{
+ assert(nvl != NULL);
+
+ if (nvlist_add_string(nvl, name, val) != 0) {
+ (void) fprintf(stderr, _("nvlist_add_string failed for "
+ "%s (%s).\n"), name, val);
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
+be_nvl_add_nvlist(nvlist_t *nvl, const char *name, nvlist_t *val)
+{
+ assert(nvl != NULL);
+
+ if (nvlist_add_nvlist(nvl, name, val) != 0) {
+ (void) fprintf(stderr, _("nvlist_add_nvlist failed for %s.\n"),
+ name);
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
+be_nvl_add_uint16(nvlist_t *nvl, const char *name, uint16_t val)
+{
+ assert(nvl != NULL);
+
+ if (nvlist_add_uint16(nvl, name, val) != 0) {
+ (void) fprintf(stderr, _("nvlist_add_uint16 failed for "
+ "%s (%hu).\n"), name, val);
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
+be_do_activate(int argc, char **argv)
+{
+ nvlist_t *be_attrs;
+ int err = 1;
+ char *obe_name;
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ usage();
+ return (1);
+ }
+
+ obe_name = argv[0];
+
+ if (be_nvl_alloc(&be_attrs) != 0)
+ return (1);
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
+ goto out;
+
+ err = be_activate(be_attrs);
+
+ switch (err) {
+ case BE_SUCCESS:
+ (void) printf(_("Activated successfully\n"));
+ break;
+ case BE_ERR_BE_NOENT:
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid BE.\nPlease check that the name of "
+ "the BE provided is correct.\n"), obe_name);
+ break;
+ case BE_ERR_PERM:
+ case BE_ERR_ACCESS:
+ (void) fprintf(stderr, _("Unable to activate %s.\n"), obe_name);
+ (void) fprintf(stderr, _("You have insufficient privileges to "
+ "execute this command.\n"));
+ break;
+ case BE_ERR_ACTIVATE_CURR:
+ default:
+ (void) fprintf(stderr, _("Unable to activate %s.\n"), obe_name);
+ (void) fprintf(stderr, "%s\n", be_err_to_str(err));
+ }
+
+out:
+ nvlist_free(be_attrs);
+ return (err);
+}
+
+static int
+be_do_create(int argc, char **argv)
+{
+ nvlist_t *be_attrs;
+ nvlist_t *zfs_props = NULL;
+ boolean_t activate = B_FALSE;
+ boolean_t is_snap = B_FALSE;
+ int c;
+ int err = 1;
+ char *obe_name = NULL;
+ char *snap_name = NULL;
+ char *nbe_zpool = NULL;
+ char *nbe_name = NULL;
+ char *nbe_desc = NULL;
+ char *propname = NULL;
+ char *propval = NULL;
+ char *strval = NULL;
+
+ while ((c = getopt(argc, argv, "ad:e:io:p:")) != -1) {
+ switch (c) {
+ case 'a':
+ activate = B_TRUE;
+ break;
+ case 'd':
+ nbe_desc = optarg;
+ break;
+ case 'e':
+ obe_name = optarg;
+ break;
+ case 'o':
+ if (zfs_props == NULL && be_nvl_alloc(&zfs_props) != 0)
+ return (1);
+
+ propname = optarg;
+ if ((propval = strchr(propname, '=')) == NULL) {
+ (void) fprintf(stderr, _("missing "
+ "'=' for -o option\n"));
+ goto out2;
+ }
+ *propval = '\0';
+ propval++;
+ if (nvlist_lookup_string(zfs_props, propname,
+ &strval) == 0) {
+ (void) fprintf(stderr, _("property '%s' "
+ "specified multiple times\n"), propname);
+ goto out2;
+
+ }
+ if (be_nvl_add_string(zfs_props, propname, propval)
+ != 0)
+ goto out2;
+
+ break;
+ case 'p':
+ nbe_zpool = optarg;
+ break;
+ default:
+ usage();
+ goto out2;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ usage();
+ goto out2;
+ }
+
+ nbe_name = argv[0];
+
+ if ((snap_name = strrchr(nbe_name, '@')) != NULL) {
+ if (snap_name[1] == '\0') {
+ usage();
+ goto out2;
+ }
+
+ snap_name[0] = '\0';
+ snap_name++;
+ is_snap = B_TRUE;
+ }
+
+ if (obe_name) {
+ if (is_snap) {
+ usage();
+ goto out2;
+ }
+
+ /*
+ * Check if obe_name is really a snapshot name.
+ * If so, split it out.
+ */
+ if ((snap_name = strrchr(obe_name, '@')) != NULL) {
+ if (snap_name[1] == '\0') {
+ usage();
+ goto out2;
+ }
+
+ snap_name[0] = '\0';
+ snap_name++;
+ }
+ } else if (is_snap) {
+ obe_name = nbe_name;
+ nbe_name = NULL;
+ }
+
+ if (be_nvl_alloc(&be_attrs) != 0)
+ goto out2;
+
+
+ if (zfs_props != NULL && be_nvl_add_nvlist(be_attrs,
+ BE_ATTR_ORIG_BE_NAME, zfs_props) != 0)
+ goto out;
+
+ if (obe_name != NULL && be_nvl_add_string(be_attrs,
+ BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
+ goto out;
+
+ if (snap_name != NULL && be_nvl_add_string(be_attrs,
+ BE_ATTR_SNAP_NAME, snap_name) != 0)
+ goto out;
+
+ if (nbe_zpool != NULL && be_nvl_add_string(be_attrs,
+ BE_ATTR_NEW_BE_POOL, nbe_zpool) != 0)
+ goto out;
+
+ if (nbe_name != NULL && be_nvl_add_string(be_attrs,
+ BE_ATTR_NEW_BE_NAME, nbe_name) != 0)
+ goto out;
+
+ if (nbe_desc != NULL && be_nvl_add_string(be_attrs,
+ BE_ATTR_NEW_BE_DESC, nbe_desc) != 0)
+ goto out;
+
+ if (is_snap)
+ err = be_create_snapshot(be_attrs);
+ else
+ err = be_copy(be_attrs);
+
+ switch (err) {
+ case BE_SUCCESS:
+ if (!is_snap && !nbe_name) {
+ /*
+ * We requested an auto named BE; find out the
+ * name of the BE that was created for us and
+ * the auto snapshot created from the original BE.
+ */
+ if (nvlist_lookup_string(be_attrs, BE_ATTR_NEW_BE_NAME,
+ &nbe_name) != 0) {
+ (void) fprintf(stderr, _("failed to get %s "
+ "attribute\n"), BE_ATTR_NEW_BE_NAME);
+ break;
+ } else
+ (void) printf(_("Auto named BE: %s\n"),
+ nbe_name);
+
+ if (nvlist_lookup_string(be_attrs, BE_ATTR_SNAP_NAME,
+ &snap_name) != 0) {
+ (void) fprintf(stderr, _("failed to get %s "
+ "attribute\n"), BE_ATTR_SNAP_NAME);
+ break;
+ } else
+ (void) printf(_("Auto named snapshot: %s\n"),
+ snap_name);
+ }
+
+ if (!is_snap && activate) {
+ char *args[] = { "activate", "", NULL };
+ args[1] = nbe_name;
+ optind = 1;
+
+ err = be_do_activate(2, args);
+ goto out;
+ }
+
+ (void) printf(_("Created successfully\n"));
+ break;
+ case BE_ERR_BE_EXISTS:
+ (void) fprintf(stderr, _("BE %s already exists\n."
+ "Please choose a different BE name.\n"), nbe_name);
+ break;
+ case BE_ERR_SS_EXISTS:
+ (void) fprintf(stderr, _("BE %s snapshot %s already exists.\n"
+ "Please choose a different snapshot name.\n"), obe_name,
+ snap_name);
+ break;
+ case BE_ERR_PERM:
+ case BE_ERR_ACCESS:
+ if (is_snap)
+ (void) fprintf(stderr, _("Unable to create snapshot "
+ "%s.\n"), snap_name);
+ else
+ (void) fprintf(stderr, _("Unable to create %s.\n"),
+ nbe_name);
+ (void) fprintf(stderr, _("You have insufficient privileges to "
+ "execute this command.\n"));
+ break;
+ default:
+ if (is_snap)
+ (void) fprintf(stderr, _("Unable to create snapshot "
+ "%s.\n"), snap_name);
+ else
+ (void) fprintf(stderr, _("Unable to create %s.\n"),
+ nbe_name);
+ (void) fprintf(stderr, "%s\n", be_err_to_str(err));
+ }
+
+out:
+ nvlist_free(be_attrs);
+out2:
+ if (zfs_props != NULL)
+ nvlist_free(zfs_props);
+
+ return (err);
+}
+
+static int
+be_do_create_snapshot(int argc, char **argv)
+{
+ nvlist_t *be_attrs;
+ int err = 1;
+ int c;
+ char *obe_name = NULL;
+ char *snap_name = NULL;
+ char *policy = NULL;
+
+ while ((c = getopt(argc, argv, "p:")) != -1) {
+ switch (c) {
+ case 'p':
+ policy = optarg;
+ break;
+ default:
+ usage();
+ return (1);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1 || argc > 2) {
+ usage();
+ return (1);
+ }
+
+ obe_name = argv[0];
+
+ if (argc > 1) {
+ /* Snapshot name provided */
+ snap_name = argv[1];
+ }
+
+ if (be_nvl_alloc(&be_attrs) != 0)
+ return (1);
+
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
+ goto out;
+
+ if (policy != NULL && be_nvl_add_string(be_attrs,
+ BE_ATTR_POLICY, policy) != 0)
+ goto out;
+
+ if (snap_name != NULL && be_nvl_add_string(be_attrs,
+ BE_ATTR_SNAP_NAME, snap_name) != 0)
+ goto out;
+
+ err = be_create_snapshot(be_attrs);
+
+ switch (err) {
+ case BE_SUCCESS:
+ if (!snap_name) {
+ /*
+ * We requested an auto named snapshot; find out
+ * the snapshot name that was created for us.
+ */
+ if (nvlist_lookup_string(be_attrs, BE_ATTR_SNAP_NAME,
+ &snap_name) != 0) {
+ (void) fprintf(stderr, _("failed to get %s "
+ "attribute\n"), BE_ATTR_SNAP_NAME);
+ err = 1;
+ break;
+ }
+
+ (void) printf(_("Auto named snapshot: %s\n"),
+ snap_name);
+ }
+ (void) printf(_("Created successfully\n"));
+ break;
+ case BE_ERR_BE_NOENT:
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid BE.\nPlease check that the name of "
+ "the BE provided is correct.\n"), obe_name);
+ break;
+ case BE_ERR_SS_EXISTS:
+ (void) fprintf(stderr, _("BE %s snapshot %s already exists.\n"
+ "Please choose a different snapshot name.\n"), obe_name,
+ snap_name);
+ break;
+ case BE_ERR_PERM:
+ case BE_ERR_ACCESS:
+ (void) fprintf(stderr, _("Unable to create snapshot %s.\n"),
+ snap_name);
+ (void) fprintf(stderr, _("You have insufficient privileges to "
+ "execute this command.\n"));
+ break;
+ default:
+ (void) fprintf(stderr, _("Unable to create snapshot %s.\n"),
+ snap_name);
+ (void) fprintf(stderr, "%s\n", be_err_to_str(err));
+ }
+
+out:
+ nvlist_free(be_attrs);
+ return (err);
+}
+
+static int
+be_do_destroy(int argc, char **argv)
+{
+ nvlist_t *be_attrs;
+ boolean_t is_snap = B_FALSE;
+ boolean_t suppress_prompt = B_FALSE;
+ int err = 1;
+ int c;
+ int destroy_flags = 0;
+ char *snap_name;
+ char *be_name;
+
+ while ((c = getopt(argc, argv, "fFs")) != -1) {
+ switch (c) {
+ case 'f':
+ destroy_flags |= BE_DESTROY_FLAG_FORCE_UNMOUNT;
+ break;
+ case 's':
+ destroy_flags |= BE_DESTROY_FLAG_SNAPSHOTS;
+ break;
+ case 'F':
+ suppress_prompt = B_TRUE;
+ break;
+ default:
+ usage();
+ return (1);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ usage();
+ return (1);
+ }
+
+ be_name = argv[0];
+ if (!suppress_prompt && !confirm_destroy(be_name)) {
+ (void) printf(_("%s has not been destroyed.\n"), be_name);
+ return (0);
+ }
+
+ if ((snap_name = strrchr(be_name, '@')) != NULL) {
+ if (snap_name[1] == '\0') {
+ usage();
+ return (1);
+ }
+
+ is_snap = B_TRUE;
+ *snap_name = '\0';
+ snap_name++;
+ }
+
+ if (be_nvl_alloc(&be_attrs) != 0)
+ return (1);
+
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, be_name) != 0)
+ goto out;
+
+ if (is_snap) {
+ if (be_nvl_add_string(be_attrs, BE_ATTR_SNAP_NAME,
+ snap_name) != 0)
+ goto out;
+
+ err = be_destroy_snapshot(be_attrs);
+ } else {
+ if (be_nvl_add_uint16(be_attrs, BE_ATTR_DESTROY_FLAGS,
+ destroy_flags) != 0)
+ goto out;
+
+ err = be_destroy(be_attrs);
+ }
+
+ switch (err) {
+ case BE_SUCCESS:
+ (void) printf(_("Destroyed successfully\n"));
+ break;
+ case BE_ERR_MOUNTED:
+ (void) fprintf(stderr, _("Unable to destroy %s.\n"), be_name);
+ (void) fprintf(stderr, _("It is currently mounted and must be "
+ "unmounted before it can be destroyed.\n" "Use 'beadm "
+ "unmount %s' to unmount the BE before destroying\nit or "
+ "'beadm destroy -f %s'.\n"), be_name, be_name);
+ break;
+ case BE_ERR_DESTROY_CURR_BE:
+ (void) fprintf(stderr, _("%s is the currently active BE and "
+ "cannot be destroyed.\nYou must boot from another BE in "
+ "order to destroy %s.\n"), be_name, be_name);
+ break;
+ case BE_ERR_ZONES_UNMOUNT:
+ (void) fprintf(stderr, _("Unable to destroy one of " "%s's "
+ "zone BE's.\nUse 'beadm destroy -f %s' or "
+ "'zfs -f destroy <dataset>'.\n"), be_name, be_name);
+ break;
+ case BE_ERR_SS_NOENT:
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid snapshot.\nPlease check that the name of "
+ "the snapshot provided is correct.\n"), snap_name);
+ break;
+ case BE_ERR_PERM:
+ case BE_ERR_ACCESS:
+ (void) fprintf(stderr, _("Unable to destroy %s.\n"), be_name);
+ (void) fprintf(stderr, _("You have insufficient privileges to "
+ "execute this command.\n"));
+ break;
+ default:
+ (void) fprintf(stderr, _("Unable to destroy %s.\n"), be_name);
+ (void) fprintf(stderr, "%s\n", be_err_to_str(err));
+ }
+
+out:
+ nvlist_free(be_attrs);
+ return (err);
+}
+
+static int
+be_do_destroy_snapshot(int argc, char **argv)
+{
+ nvlist_t *be_attrs;
+ boolean_t suppress_prompt = B_FALSE;
+ int err = 1;
+ char c;
+ char *obe_name;
+ char *snap_name;
+ char *sn;
+ int sz;
+
+ while ((c = getopt(argc, argv, "F")) != -1) {
+ switch (c) {
+ case 'F':
+ suppress_prompt = B_TRUE;
+ break;
+ default:
+ usage();
+ return (1);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2) {
+ usage();
+ return (1);
+ }
+
+ obe_name = argv[0];
+ snap_name = argv[1];
+
+ sz = asprintf(&sn, "%s@%s", obe_name, snap_name);
+ if (sz < 0) {
+ (void) fprintf(stderr, _("internal error: "
+ "out of memory\n"));
+ return (1);
+ }
+
+ if (!suppress_prompt && !confirm_destroy(sn)) {
+ (void) printf(_("%s has not been destroyed.\n"), sn);
+ free(sn);
+ return (0);
+ }
+
+ free(sn);
+
+
+ if (be_nvl_alloc(&be_attrs) != 0)
+ return (1);
+
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
+ goto out;
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name) != 0)
+ goto out;
+
+ err = be_destroy_snapshot(be_attrs);
+
+ switch (err) {
+ case BE_SUCCESS:
+ (void) printf(_("Destroyed successfully\n"));
+ break;
+ case BE_ERR_BE_NOENT:
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid BE.\nPlease check that the name of "
+ "the BE provided is correct.\n"), obe_name);
+ break;
+ case BE_ERR_SS_NOENT:
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid snapshot.\nPlease check that the name of "
+ "the snapshot provided is correct.\n"), snap_name);
+ break;
+ case BE_ERR_PERM:
+ case BE_ERR_ACCESS:
+ (void) fprintf(stderr, _("Unable to destroy snapshot %s.\n"),
+ snap_name);
+ (void) fprintf(stderr, _("You have insufficient privileges to "
+ "execute this command.\n"));
+ break;
+ default:
+ (void) fprintf(stderr, _("Unable to destroy snapshot %s.\n"),
+ snap_name);
+ (void) fprintf(stderr, "%s\n", be_err_to_str(err));
+ }
+
+out:
+ nvlist_free(be_attrs);
+ return (err);
+}
+
+static int
+be_do_list(int argc, char **argv)
+{
+ be_node_list_t *be_nodes = NULL;
+ boolean_t all = B_FALSE;
+ boolean_t dsets = B_FALSE;
+ boolean_t snaps = B_FALSE;
+ boolean_t parsable = B_FALSE;
+ int err = 1;
+ int c = 0;
+ char *be_name = NULL;
+
+ while ((c = getopt(argc, argv, "nadsH")) != -1) {
+ switch (c) {
+ case 'a':
+ all = B_TRUE;
+ break;
+ case 'd':
+ dsets = B_TRUE;
+ break;
+ case 's':
+ snaps = B_TRUE;
+ break;
+ case 'H':
+ parsable = B_TRUE;
+ break;
+ default:
+ usage();
+ return (1);
+ }
+ }
+
+ if (all) {
+ if (dsets) {
+ (void) fprintf(stderr, _("Invalid options: -a and %s "
+ "are mutually exclusive.\n"), "-d");
+ usage();
+ return (1);
+ }
+ if (snaps) {
+ (void) fprintf(stderr, _("Invalid options: -a and %s "
+ "are mutually exclusive.\n"), "-s");
+ usage();
+ return (1);
+ }
+
+ dsets = B_TRUE;
+ snaps = B_TRUE;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+
+ if (argc == 1)
+ be_name = argv[0];
+
+ err = be_list(be_name, &be_nodes);
+
+ switch (err) {
+ case BE_SUCCESS:
+ print_nodes(be_name, dsets, snaps, parsable, be_nodes);
+ break;
+ case BE_ERR_BE_NOENT:
+ if (be_name == NULL)
+ (void) fprintf(stderr, _("No boot environments found "
+ "on this system.\n"));
+ else {
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid BE.\nPlease check that the name of "
+ "the BE provided is correct.\n"), be_name);
+ }
+ break;
+ default:
+ (void) fprintf(stderr, _("Unable to display Boot "
+ "Environment\n"));
+ (void) fprintf(stderr, "%s\n", be_err_to_str(err));
+ }
+
+ if (be_nodes != NULL)
+ be_free_list(be_nodes);
+ return (err);
+}
+
+static int
+be_do_mount(int argc, char **argv)
+{
+ nvlist_t *be_attrs;
+ boolean_t shared_fs = B_FALSE;
+ int err = 1;
+ int c;
+ int mount_flags = 0;
+ char *obe_name;
+ char *mountpoint;
+ char *tmp_mp = NULL;
+
+ while ((c = getopt(argc, argv, "s:")) != -1) {
+ switch (c) {
+ case 's':
+ shared_fs = B_TRUE;
+
+ mount_flags |= BE_MOUNT_FLAG_SHARED_FS;
+
+ if (strcmp(optarg, "rw") == 0) {
+ mount_flags |= BE_MOUNT_FLAG_SHARED_RW;
+ } else if (strcmp(optarg, "ro") != 0) {
+ (void) fprintf(stderr, _("The -s flag "
+ "requires an argument [ rw | ro ]\n"));
+ usage();
+ return (1);
+ }
+
+ break;
+ default:
+ usage();
+ return (1);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1 || argc > 2) {
+ usage();
+ return (1);
+ }
+
+ obe_name = argv[0];
+
+ if (argc == 2) {
+ mountpoint = argv[1];
+ if (mountpoint[0] != '/') {
+ (void) fprintf(stderr, _("Invalid mount point %s. "
+ "Mount point must start with a /.\n"), mountpoint);
+ return (1);
+ }
+ } else {
+ const char *tmpdir = getenv("TMPDIR");
+ const char *tmpname = "tmp.XXXXXX";
+ int sz;
+
+ if (tmpdir == NULL)
+ tmpdir = "/tmp";
+
+ sz = asprintf(&tmp_mp, "%s/%s", tmpdir, tmpname);
+ if (sz < 0) {
+ (void) fprintf(stderr, _("internal error: "
+ "out of memory\n"));
+ return (1);
+ }
+
+ mountpoint = mkdtemp(tmp_mp);
+ }
+
+ if (be_nvl_alloc(&be_attrs) != 0)
+ return (1);
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
+ goto out;
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_MOUNTPOINT, mountpoint) != 0)
+ goto out;
+
+ if (shared_fs && be_nvl_add_uint16(be_attrs, BE_ATTR_MOUNT_FLAGS,
+ mount_flags) != 0)
+ goto out;
+
+ err = be_mount(be_attrs);
+
+ switch (err) {
+ case BE_SUCCESS:
+ (void) printf(_("Mounted successfully on: '%s'\n"), mountpoint);
+ break;
+ case BE_ERR_BE_NOENT:
+ err = 1;
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid BE.\nPlease check that the name of "
+ "the BE provided is correct.\n"), obe_name);
+ break;
+ case BE_ERR_MOUNTED:
+ (void) fprintf(stderr, _("%s is already mounted.\n"
+ "Please unmount the BE before mounting it again.\n"),
+ obe_name);
+ break;
+ case BE_ERR_PERM:
+ case BE_ERR_ACCESS:
+ err = 1;
+ (void) fprintf(stderr, _("Unable to mount %s.\n"), obe_name);
+ (void) fprintf(stderr, _("You have insufficient privileges to "
+ "execute this command.\n"));
+ break;
+ default:
+ err = 1;
+ (void) fprintf(stderr, _("Unable to mount %s.\n"), obe_name);
+ (void) fprintf(stderr, "%s\n", be_err_to_str(err));
+ }
+
+out:
+ if (tmp_mp != NULL)
+ free(tmp_mp);
+ nvlist_free(be_attrs);
+ return (err);
+}
+
+static int
+be_do_unmount(int argc, char **argv)
+{
+ nvlist_t *be_attrs;
+ char *obe_name;
+ int err = 1;
+ int c;
+ int unmount_flags = 0;
+
+ while ((c = getopt(argc, argv, "f")) != -1) {
+ switch (c) {
+ case 'f':
+ unmount_flags |= BE_UNMOUNT_FLAG_FORCE;
+ break;
+ default:
+ usage();
+ return (1);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ usage();
+ return (1);
+ }
+
+ obe_name = argv[0];
+
+ if (be_nvl_alloc(&be_attrs) != 0)
+ return (1);
+
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
+ goto out;
+
+ if (be_nvl_add_uint16(be_attrs, BE_ATTR_UNMOUNT_FLAGS,
+ unmount_flags) != 0)
+ goto out;
+
+ err = be_unmount(be_attrs);
+
+ switch (err) {
+ case BE_SUCCESS:
+ (void) printf(_("Unmounted successfully\n"));
+ break;
+ case BE_ERR_BE_NOENT:
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid BE.\nPlease check that the name of "
+ "the BE provided is correct.\n"), obe_name);
+ break;
+ case BE_ERR_UMOUNT_CURR_BE:
+ (void) fprintf(stderr, _("%s is the currently active BE.\n"
+ "It cannot be unmounted unless another BE is the "
+ "currently active BE.\n"), obe_name);
+ break;
+ case BE_ERR_UMOUNT_SHARED:
+ (void) fprintf(stderr, _("%s is a shared file system and it "
+ "cannot be unmounted.\n"), obe_name);
+ break;
+ case BE_ERR_PERM:
+ case BE_ERR_ACCESS:
+ (void) fprintf(stderr, _("Unable to unmount %s.\n"), obe_name);
+ (void) fprintf(stderr, _("You have insufficient privileges to "
+ "execute this command.\n"));
+ break;
+ default:
+ (void) fprintf(stderr, _("Unable to unmount %s.\n"), obe_name);
+ (void) fprintf(stderr, "%s\n", be_err_to_str(err));
+ }
+
+out:
+ nvlist_free(be_attrs);
+ return (err);
+}
+
+static int
+be_do_rename(int argc, char **argv)
+{
+ nvlist_t *be_attrs;
+ char *obe_name;
+ char *nbe_name;
+ int err = 1;
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2) {
+ usage();
+ return (1);
+ }
+
+ obe_name = argv[0];
+ nbe_name = argv[1];
+
+ if (be_nvl_alloc(&be_attrs) != 0)
+ return (1);
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
+ goto out;
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_NEW_BE_NAME, nbe_name) != 0)
+ goto out;
+
+ err = be_rename(be_attrs);
+
+ switch (err) {
+ case BE_SUCCESS:
+ (void) printf(_("Renamed successfully\n"));
+ break;
+ case BE_ERR_BE_NOENT:
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid BE.\nPlease check that the name of "
+ "the BE provided is correct.\n"), obe_name);
+ break;
+ case BE_ERR_PERM:
+ case BE_ERR_ACCESS:
+ (void) fprintf(stderr, _("Rename of BE %s failed.\n"),
+ obe_name);
+ (void) fprintf(stderr, _("You have insufficient privileges to "
+ "execute this command.\n"));
+ break;
+ default:
+ (void) fprintf(stderr, _("Rename of BE %s failed.\n"),
+ obe_name);
+ (void) fprintf(stderr, "%s\n", be_err_to_str(err));
+ }
+
+out:
+ nvlist_free(be_attrs);
+ return (err);
+}
+
+static int
+be_do_rollback(int argc, char **argv)
+{
+ nvlist_t *be_attrs;
+ char *obe_name;
+ char *snap_name;
+ int err = 1;
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1 || argc > 2) {
+ usage();
+ return (1);
+ }
+
+ obe_name = argv[0];
+ if (argc == 2)
+ snap_name = argv[1];
+ else { /* argc == 1 */
+ if ((snap_name = strrchr(obe_name, '@')) != NULL) {
+ if (snap_name[1] == '\0') {
+ usage();
+ return (1);
+ }
+
+ snap_name[0] = '\0';
+ snap_name++;
+ } else {
+ usage();
+ return (1);
+ }
+ }
+
+ if (be_nvl_alloc(&be_attrs) != 0)
+ return (1);
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
+ goto out;
+
+ if (be_nvl_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name) != 0)
+ goto out;
+
+ err = be_rollback(be_attrs);
+
+ switch (err) {
+ case BE_SUCCESS:
+ (void) printf(_("Rolled back successfully\n"));
+ break;
+ case BE_ERR_BE_NOENT:
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid BE.\nPlease check that the name of "
+ "the BE provided is correct.\n"), obe_name);
+ break;
+ case BE_ERR_SS_NOENT:
+ (void) fprintf(stderr, _("%s does not exist or appear "
+ "to be a valid snapshot.\nPlease check that the name of "
+ "the snapshot provided is correct.\n"), snap_name);
+ break;
+ case BE_ERR_PERM:
+ case BE_ERR_ACCESS:
+ (void) fprintf(stderr, _("Rollback of BE %s snapshot %s "
+ "failed.\n"), obe_name, snap_name);
+ (void) fprintf(stderr, _("You have insufficient privileges to "
+ "execute this command.\n"));
+ break;
+ default:
+ (void) fprintf(stderr, _("Rollback of BE %s snapshot %s "
+ "failed.\n"), obe_name, snap_name);
+ (void) fprintf(stderr, "%s\n", be_err_to_str(err));
+ }
+
+out:
+ nvlist_free(be_attrs);
+ return (err);
+}
--- a/usr/src/cmd/beadm/beadm.py Thu Dec 16 09:43:44 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1058 +0,0 @@
-#!/usr/bin/python2.6
-#
-# 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
-# or http://www.opensolaris.org/os/licensing.
-# 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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-"""
-beadm - The Boot Environment Administration tool. Use this CLI to
-manage boot environments.
-"""
-
-import getopt
-import gettext
-import os
-import sys
-import shutil
-import traceback
-import time
-import subprocess
-
-from beadm import _
-from beadm.BootEnvironment import *
-import beadm.messages as msg
-import libbe_py as lb
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def usage():
- '''Defines parameters and options of the command beadm.'''
- print >> sys.stderr, _("""
-Usage:
- beadm subcommand cmd_options
-
- subcommands:
-
- beadm activate beName
- beadm create [-a] [-d description]
- [-e non-activeBeName | beName@snapshot]
- [-o property=value] ... [-p zpool] beName
- beadm create beName@snapshot
- beadm destroy [-fF] beName | beName@snapshot
- beadm list [[-a] | [-d] [-s]] [-H] [beName]
- beadm mount beName mountpoint
- beadm rename beName newBeName
- beadm unmount [-f] beName""")
- sys.exit(1)
-
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Public Command Line functions described in beadm(1)
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def activate(opts):
- """
- Function: activate
-
- Description: Activate a Boot Environment.The following is the
- subcommand, options and args that make up the
- opts object passed in:
-
- Parameters:
- opts - A string containing the active subcommand
-
- Returns:
- 0 - Success
- 1 - Failure
- """
-
- if len(opts) != 1:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- be = BootEnvironment()
-
- if lb.beVerifyBEName(opts[0]) != 0:
- msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1)
- return 1
-
- rc = lb.beActivate(opts[0])
- if rc == 0:
- return 0
-
- be.msg_buf["0"] = opts[0]
- if rc == msg.Msgs.BE_ERR_BE_NOENT:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, opts[0])
- elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc)
- msg.printMsg(msg.Msgs.BEADM_ERR_ACTIVATE, be.msg_buf, -1)
- return 1
- else:
- be.msg_buf["1"] = lb.beGetErrDesc(rc)
- if be.msg_buf["1"] == None:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_ACTIVATE, be.msg_buf, -1)
- return 1
-
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def create(opts):
- """
- Function: create
-
- Description: Create a Boot Environment. The following is the
- subcommand, options and args that make up the
- opts object passed in:
-
- create [-a] [-d description]
- [-e non-activeBeName | beName@Snapshot]
- [-o property=value] ... [-p zpool] beName
-
- create beName@Snapshot
-
- Parameters:
- opts - A object containing the create subcommand
- and all the options and arguments passed in
- on the command line mentioned above.
-
- Returns:
- 0 - Success
- 1 - Failure
- """
-
- be = BootEnvironment()
-
- activate = False
-
- try:
- opts_args, be.trgt_be_name_or_snapshot = getopt.getopt(opts,
- "ad:e:o:p:")
- except getopt.GetoptError:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- # Counters for detecting multiple options.
- # e.g. beadm create -p rpool -p rpool2 newbe
- num_a_opts = 0
- num_e_opts = 0
- num_p_opts = 0
- num_d_opts = 0
-
- for opt, arg in opts_args:
- if opt == "-a":
- activate = True
- num_a_opts += 1
- elif opt == "-e":
- be.src_be_name_or_snapshot = arg
- num_e_opts += 1
- elif opt == "-o":
- key, value = arg.split("=")
- be.properties[key] = value
- elif opt == "-p":
- be.trgt_rpool = arg
- num_p_opts += 1
- elif opt == "-d":
- be.description = arg
- num_d_opts += 1
-
- if num_a_opts > 1 or num_e_opts > 1 or num_p_opts > 1 or num_d_opts > 1:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- # Check that all info provided from the user is legitimate.
- if (verifyCreateOptionsArgs(be) != 0):
- usage()
-
- if initBELog("create", be) != 0:
- return 1
-
- msg.printMsg(msg.Msgs.BEADM_MSG_BE_CREATE_START,
- be.trgt_be_name_or_snapshot[0], be.log_id)
-
- if '@' in be.trgt_be_name_or_snapshot[0]:
- # Create a snapshot
- rc = createSnapshot(be)
- else:
- if lb.beVerifyBEName(be.trgt_be_name_or_snapshot[0]) != 0:
- msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1)
- return 1
-
- # Create a BE based on a snapshot
- if be.src_be_name_or_snapshot is not None and \
- '@' in be.src_be_name_or_snapshot:
- # Create a BE from a snapshot
- rc = createBEFromSnapshot(be)
- else:
- rc = createBE(be)
-
- # Activate the BE if the user chose to.
- if activate and rc == 0:
- rc = activateBE(be)
- cleanupBELog(be)
-
- return rc
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def destroy(opts):
- """
- Function: destroy
-
- Description: Destroy a Boot Environment. The following is the
- subcommand, options and args that make up the
- opts object passed in:
-
- destroy [-fF] beName | beName@snapshot
-
- Parameters:
- opts - A object containing the destroy subcommand
- and all the options and arguments passed in
- on the command line mentioned above.
-
- Returns:
- 0 - Success
- 1 - Failure
- """
-
- force_unmount = 0
- suppress_prompt = False
- be_active_on_boot = None
- be = BootEnvironment()
-
- try:
- opts_args, be.trgt_be_name_or_snapshot = getopt.getopt(opts, "fF")
- except getopt.GetoptError:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- # Counters for detecting multiple options.
- # e.g. beadm destroy -f -f newbe
- num_f_opts = 0
- num_sf_opts = 0
-
- for opt, arg in opts_args:
- if opt == "-f":
- force_unmount = 1
- num_sf_opts += 1
- elif opt == "-F":
- suppress_prompt = True
- num_f_opts += 1
-
- if num_sf_opts > 1 or num_f_opts > 1:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- if len(be.trgt_be_name_or_snapshot) != 1:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- is_snapshot = False
-
- if "@" in be.trgt_be_name_or_snapshot[0]:
- is_snapshot = True
- be_name, snap_name = be.trgt_be_name_or_snapshot[0].split("@")
- if lb.beVerifyBEName(be_name) != 0:
- msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1)
- return 1
- else:
- if lb.beVerifyBEName(be.trgt_be_name_or_snapshot[0]) != 0:
- msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1)
- return 1
-
- # Get the 'active' BE and the 'active on boot' BE.
- be_active, be_active_on_boot = getActiveBEAndActiveOnBootBE()
-
- # If the user is trying to destroy the 'active' BE then quit now.
- if not is_snapshot and be_active == be.trgt_be_name_or_snapshot[0]:
- be.msg_buf["0"] = be.msg_buf["1"] = be_active
- msg.printMsg(msg.Msgs.BEADM_ERR_DESTROY_ACTIVE, be.msg_buf, -1)
- return 1
-
- if not suppress_prompt:
-
- # Display a destruction question and wait for user response.
- # Quit if negative user response.
-
- if not displayDestructionQuestion(be):
- return 0
-
- if is_snapshot:
-
- # Destroy a snapshot.
- rc = lb.beDestroySnapshot(be_name, snap_name)
- else:
-
- # Destroy a BE. Passing in 1 for the second arg destroys
- # any snapshots the BE may have as well.
-
- rc = lb.beDestroy(be.trgt_be_name_or_snapshot[0], 1, force_unmount)
-
- # Check if the BE that was just destroyed was the
- # 'active on boot' BE. If it was, display a message letting
- # the user know that the 'active' BE is now also the
- # 'active on boot' BE.
- if be_active_on_boot == be.trgt_be_name_or_snapshot[0] and rc == 0:
- msg.printMsg(msg.Msgs.BEADM_MSG_ACTIVE_ON_BOOT,
- be_active, -1)
-
- if rc == 0:
- try:
- shutil.rmtree("/var/log/beadm/" + \
- be.trgt_be_name_or_snapshot[0], True)
- except:
- msg.printMsg(msg.Msgs.BEADM_ERR_LOG_RM,
- "/var/log/beadm/" + be.trgt_be_name_or_snapshot[0], -1)
-
- return 0
-
- be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0]
- if rc == msg.Msgs.BE_ERR_MOUNTED:
- be.msg_buf["1"] = be.msg_buf["2"] = be.trgt_be_name_or_snapshot[0]
- msg.printMsg(msg.Msgs.BEADM_ERR_MOUNTED, be.msg_buf, -1)
- return 1
- elif rc == msg.Msgs.BE_ERR_DESTROY_CURR_BE:
- msg.printMsg(msg.Msgs.BEADM_ERR_DESTROY_ACTIVE, \
- be.msg_buf["0"], -1)
- return 1
- elif rc == msg.Msgs.BE_ERR_ZONES_UNMOUNT:
- be.msg_buf["1"] = be.trgt_be_name_or_snapshot[0]
- msg.printMsg(msg.Msgs.BE_ERR_ZONES_UNMOUNT, be.msg_buf, -1)
- return 1
- elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc)
- msg.printMsg(msg.Msgs.BEADM_ERR_DESTROY, be.msg_buf, -1)
- return 1
- else:
- be.msg_buf["1"] = lb.beGetErrDesc(rc)
- if be.msg_buf["1"] == None:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_DESTROY, be.msg_buf, -1)
- return 1
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def list(opts):
- """
- Description: List the attributes of a Boot Environment.
- The following is the subcommand, options
- and args that make up the opts object
- passed in:
-
- list [[-a] | [-d] [-s]] [-H] [beName]
-
- -a displays all info
- -d displays BE info plus dataset info
- -s displays BE info plus snapshot info
- -H displays info parsable by a computer
-
- Parameters:
- opts - A object containing the list subcommand
- and all the options and arguments passed in
- on the command line mentioned above.
-
- Returns:
- 0 - Success
- 1 - Failure
- """
-
- be = BootEnvironment()
-
- list_all_attrs = ""
- list_datasets = ""
- list_snapshots = ""
- dont_display_headers = False
- be_name = None
- be_list = None
-
- # Counters for detecting multiple options.
- # e.g. beadm list -a -a newbe
- num_a_opts = 0
- num_d_opts = 0
- num_s_opts = 0
- num_h_opts = 0
-
- try:
- opts_args, be.trgt_be_name_or_snapshot = getopt.getopt(opts, "adHs")
- except getopt.GetoptError:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- for opt, arg in opts_args:
- if opt == "-a":
- list_all_attrs = opt
- num_a_opts += 1
- elif opt == "-d":
- list_datasets = opt
- num_d_opts += 1
- elif opt == "-s":
- list_snapshots = opt
- num_s_opts += 1
- elif opt == "-H":
- dont_display_headers = True
- num_h_opts += 1
-
- if num_a_opts > 1 or num_d_opts > 1 or num_s_opts > 1 or num_h_opts > 1:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- if len(be.trgt_be_name_or_snapshot) > 1:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- if len(be.trgt_be_name_or_snapshot) == 1:
- be_name = be.trgt_be_name_or_snapshot[0]
- if lb.beVerifyBEName(be_name) != 0:
- msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1)
- return 1
-
- if (list_all_attrs == "-a" and (list_datasets == "-d" \
- or list_snapshots == "-s")):
- msg.printMsg(msg.Msgs.BEADM_ERR_MUTUALLY_EXCL,
- list_all_attrs + " " + list_datasets + " " +
- list_snapshots, -1)
- usage()
-
- list_options = ""
-
- # When zones are implemented add "listZones == "-z" below
-
- # Coelesce options to pass to displayBEs
-
- if (list_datasets == "-d" and list_snapshots == "-s" or \
- list_all_attrs == "-a"):
- list_options = "-a"
- elif list_datasets != "" or list_snapshots != "" or list_all_attrs != "":
- list_options = list_datasets + " " + list_snapshots
-
- rc, be_list = lb.beList()
- if rc != 0:
- if rc == msg.Msgs.BE_ERR_BE_NOENT:
- if be_name == None:
- msg.printMsg(msg.Msgs.BEADM_ERR_NO_BES_EXIST,
- None, -1)
- return 1
-
- string = \
- msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST,
- be_name)
- else:
- string = lb.beGetErrDesc(rc)
- if string == None:
- string = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_LIST, string, -1)
- return 1
-
- # classify according to command line options
- if list_options.find("-a") != -1 or \
- (list_options.find("-d") != -1 and list_options.find("-s") != -1):
- list_object = CompleteList(dont_display_headers) #all
- elif list_options.find("-d") != -1:
- list_object = DatasetList(dont_display_headers) #dataset
- elif list_options.find("-s") != -1:
- list_object = SnapshotList(dont_display_headers) #snapshot
- else: list_object = BEList(dont_display_headers) #only BE
-
- # use list method for object
- if list_object.list(be_list, dont_display_headers, be_name) != 0:
- msg.printMsg(msg.Msgs.BEADM_ERR_LIST_DATA, None, -1)
- return 1
-
- return 0
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def mount(opts):
- """
- Description: Mount a Boot Environment on a directory.
- The following is the subcommand, options
- and args that make up the opts object
- passed in:
-
- mount beName [mountpoint]
-
- Parameters:
- opts - A object containing the mount subcommand
- and all the options and arguments passed in
- on the command line mentioned above.
-
- Returns:
- 0 - Success
- 1 - Failure
- """
-
- be = BootEnvironment()
-
- mountpoint = None
-
- try:
- be_name_mnt_point = getopt.getopt(opts, "")[1]
- except getopt.GetoptError:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- mnt_point_len = len(be_name_mnt_point)
-
- if mnt_point_len != 2:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
- else:
- # Check for leading / in mount point
- mountpoint = be_name_mnt_point[1]
- if not mountpoint.startswith('/'):
- msg.printMsg(msg.Msgs.BEADM_ERR_MOUNTPOINT,
- mountpoint, -1)
- return 1
-
- if lb.beVerifyBEName(be_name_mnt_point[0]) != 0:
- msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1)
- return 1
-
- rc = lb.beMount(be_name_mnt_point[0], mountpoint)
- if rc == 0:
- return 0
-
- be.msg_buf["0"] = be_name_mnt_point[0]
- if rc == msg.Msgs.BE_ERR_MOUNTED:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_MOUNT_EXISTS,
- be_name_mnt_point[0])
- elif rc == msg.Msgs.BE_ERR_BE_NOENT:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST,
- be_name_mnt_point[0])
- elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc)
- msg.printMsg(msg.Msgs.BEADM_ERR_MOUNT, be.msg_buf, -1)
- return 1
- else:
- be.msg_buf["1"] = lb.beGetErrDesc(rc)
- if be.msg_buf["1"] == None:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_MOUNT, be.msg_buf, -1)
- return 1
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def unmount(opts):
- """
- Description: Unmount a Boot Environment.
- The following is the subcommand, options
- and args that make up the opts object
- passed in:
-
- unmount [-f] beName
-
- Parameters:
- opts - A object containing the unmount subcommand
- and all the options and arguments passed in
- on the command line mentioned above.
-
- Returns:
- 0 - Success
- 1 - Failure
- """
-
- be = BootEnvironment()
-
- force_unmount = 0
-
- # Counter for detecting multiple options.
- # e.g. beadm unmount -f -f newbe
- num_f_opts = 0
-
- try:
- optlist, args = getopt.getopt(opts, "f")
- except getopt.GetoptError:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- for opt, arg in optlist:
- if opt == "-f":
- force_unmount = 1
- num_f_opts += 1
-
- if num_f_opts > 1:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- if len(args) != 1:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- if lb.beVerifyBEName(args[0]) != 0:
- msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1)
- return 1
-
- rc = lb.beUnmount(args[0], force_unmount)
- if rc == 0:
- return 0
-
- be.msg_buf["0"] = args[0]
- if rc == msg.Msgs.BE_ERR_UMOUNT_CURR_BE:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_UNMOUNT_ACTIVE,
- args[0])
- elif rc == msg.Msgs.BE_ERR_UMOUNT_SHARED:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_SHARED_FS, args[0])
- elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc)
- msg.printMsg(msg.Msgs.BEADM_ERR_UNMOUNT, be.msg_buf, -1)
- return 1
- else:
- be.msg_buf["1"] = lb.beGetErrDesc(rc)
- if be.msg_buf["1"] == None:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_UNMOUNT, be.msg_buf, -1)
- return 1
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def rename(opts):
- """
- Description: Rename the name of a Boot Environment.
- The following is the subcommand, options
- and args that make up the opts object
- passed in:
-
- rename beName newBeName
-
- Parameters:
- opts - A object containing the mount subcommand
- and all the options and arguments passed in
- on the command line mentioned above.
-
- Returns:
- 0 - Success
- 1 - Failure
- """
-
- be = BootEnvironment()
-
- try:
- be_names = getopt.getopt(opts, "")[1]
- except getopt.GetoptError:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- if len(be_names) != 2:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- usage()
-
- if lb.beVerifyBEName(be_names[0]) != 0:
- msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1)
- return 1
-
- if lb.beVerifyBEName(be_names[1]) != 0:
- msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1)
- return 1
-
- rc = lb.beRename(be_names[0], be_names[1])
-
- if rc == 0:
- return 0
-
- be.msg_buf["0"] = be_names[0]
- if rc == msg.Msgs.BE_ERR_BE_NOENT:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST,
- be_names[0])
- elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc)
- msg.printMsg(msg.Msgs.BEADM_ERR_RENAME, be.msg_buf, -1)
- return 1
- else:
- be.msg_buf["1"] = lb.beGetErrDesc(rc)
- if be.msg_buf["1"] == None:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_RENAME, be.msg_buf, -1)
- return 1
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# End of CLI public functions
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Verify the options and arguments for the beadm create subcommand
-
-def verifyCreateOptionsArgs(be):
- """Check valid BE names."""
-
- len_be_args = len(be.trgt_be_name_or_snapshot)
- if len_be_args < 1:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- return 1
- if len_be_args > 1:
- msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1)
- idx = 0
- while len_be_args > idx:
- msg.printMsg(msg.Msgs.BEADM_MSG_FREE_FORMAT,
- be.trgt_be_name_or_snapshot[idx], -1)
- idx += 1
- return 1
-
- return 0
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def parseCLI(cli_opts_args):
- """Parse command line interface arguments."""
-
- gettext.install("beadm", "/usr/lib/locale")
-
- if len(cli_opts_args) == 0:
- usage()
-
- subcommand = cli_opts_args[0]
- opts_args = cli_opts_args[1:]
-
- if subcommand == "activate":
- rc = activate(opts_args)
- elif subcommand == "create":
- rc = create(opts_args)
- elif subcommand == "destroy":
- rc = destroy(opts_args)
- elif subcommand == "list":
- rc = list(opts_args)
- elif subcommand == "mount":
- rc = mount(opts_args)
- elif subcommand == "rename":
- rc = rename(opts_args)
- elif subcommand == "upgrade":
- rc = upgrade(opts_args)
- elif subcommand == "unmount" or \
- subcommand == "umount": #aliased for convenience
- rc = unmount(opts_args)
- elif subcommand == "verify":
- rc = verify()
- else:
- msg.printMsg(msg.Msgs.BEADM_ERR_ILL_SUBCOMMAND,
- subcommand, -1)
- usage()
-
- return(rc)
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def main():
- """main function."""
-
- gettext.install("beadm", "/usr/lib/locale")
-
- if not isBeadmSupported():
- return(1)
-
- return(parseCLI(sys.argv[1:]))
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def initBELog(log_id, be):
- """
- Initiate the BE log
-
- Format of the log
- yyyymmdd_hhmmss - 20071130_140558
- yy - year; 2007
- mm - month; 11
- dd - day; 30
- hh - hour; 14
- mm - minute; 05
- ss - second; 58
- """
-
- # /var/log/beadm/<beName>/<logId>.log.<yyyymmdd_hhmmss>
-
- date = time.strftime("%Y%m%d_%H%M%S", time.localtime())
-
- be.log = "/var/log/beadm/" + be.trgt_be_name_or_snapshot[0] + \
- "/" + log_id + ".log" + "." + date
-
- if not os.path.isfile(be.log) and not os.path.islink(be.log):
- if not os.path.isdir(os.path.dirname(be.log)):
- try:
- os.makedirs(os.path.dirname(be.log), 0644)
- except OSError:
- be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0]
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS,
- 0)
- msg.printMsg(msg.Msgs.BEADM_ERR_CREATE,
- be.msg_buf, -1)
- return 1
- try:
- be.log_id = open(be.log, "a")
- except IOError:
- msg.printMsg(msg.Msgs.BEADM_ERR_LOG_CREATE,
- None, -1)
- return 1
- else:
- # Should never happen due to new time stamp each call
- msg.printMsg(msg.Msgs.BEADM_ERR_LOG_CREATE, None, -1)
- return 1
-
- return 0
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def cleanupBELog(be):
- """Clean up BE log."""
-
- be.log_id.close()
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def displayDestructionQuestion(be):
- """Display a destruction question and wait for user response."""
-
- msg.printMsg(msg.Msgs.BEADM_MSG_DESTROY, be.trgt_be_name_or_snapshot[0], -1)
- while True:
- try:
- value = raw_input().strip().upper()
- except KeyboardInterrupt:
- return False
- if (value == 'Y' or value == 'YES'):
- return True
- elif len(value) == 0 or value == 'N' or value == 'NO':
- msg.printMsg(msg.Msgs.BEADM_MSG_DESTROY_NO,
- be.trgt_be_name_or_snapshot[0], -1)
- return False
- else:
- msg.printMsg(msg.Msgs.BEADM_ERR_INVALID_RESPONSE,
- -1)
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def setMaxColumnWidths(be_max_w, ds_max_w, ss_max_w, be_list):
- """Figure out max column widths for BE's, Datasets and Snapshots."""
-
- for be_item in be_list:
- if be_item.get("orig_be_name") is not None:
- determineMaxBEColWidth(be_item, be_max_w)
- if be_item.get("dataset") is not None:
- determineMaxDSColWidth(be_item, ds_max_w)
- if be_item.get("snap_name") is not None:
- determineMaxSSColWidth(be_item, ss_max_w)
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def getActiveBEAndActiveOnBootBE():
- """Return the 'active on boot' BE, the 'active' BE or None."""
-
- active_be = None
- active_be_on_boot = None
-
- rc, be_list = lb.beList()
-
- if rc != 0:
- if rc == msg.Msgs.BE_ERR_BE_NOENT:
- string = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_BES_EXIST)
- else:
- string = lb.beGetErrDesc(rc)
- if string == None:
- string = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_LIST, string, -1)
- return None
-
- for be_vals in be_list:
- srcBeName = be_vals.get("orig_be_name")
- if be_vals.get("active"):
- active_be = srcBeName
- if be_vals.get("active_boot"):
- active_be_on_boot = srcBeName
- if active_be is not None and active_be_on_boot is not None:
- break
-
- return active_be, active_be_on_boot
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def createSnapshot(be):
- """Create a snapshot."""
-
- be_name, snap_name = be.trgt_be_name_or_snapshot[0].split("@")
-
- rc = lb.beCreateSnapshot(be_name, snap_name)[0]
-
- if rc == 0:
- return 0
-
- be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0]
- if rc == msg.Msgs.BE_ERR_BE_NOENT:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST,
- be_name)
- elif rc == msg.Msgs.BE_ERR_SS_EXISTS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_SNAP_EXISTS,
- be.trgt_be_name_or_snapshot[0])
- elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc)
- msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, -1)
- return 1
- else:
- be.msg_buf["1"] = lb.beGetErrDesc(rc)
- if be.msg_buf["1"] == None:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, -1)
-
- return 1
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def createBE(be):
- """Create a Boot Environment."""
-
- rc = lb.beCopy(be.trgt_be_name_or_snapshot[0], be.src_be_name_or_snapshot,
- None, be.trgt_rpool, be.properties, be.description)[0]
-
- if rc == 0:
- msg.printMsg(msg.Msgs.BEADM_MSG_BE_CREATE_SUCCESS,
- be.trgt_be_name_or_snapshot[0], be.log_id)
- return 0
-
- be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0]
- if rc == msg.Msgs.BE_ERR_BE_NOENT:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST,
- be.src_be_name_or_snapshot)
- elif rc == msg.Msgs.BE_ERR_BE_EXISTS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_BE_EXISTS,
- be.trgt_be_name_or_snapshot[0])
- elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc)
- msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, -1)
- return 1
- else:
- be.msg_buf["1"] = lb.beGetErrDesc(rc)
- if be.msg_buf["1"] == None:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, be.log_id)
-
- return 1
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def createBEFromSnapshot(be):
- """Create a BE based off a snapshot."""
-
- be_name, snap_name = be.src_be_name_or_snapshot.split("@")
-
- rc = lb.beCopy(be.trgt_be_name_or_snapshot[0], be_name, snap_name,
- be.trgt_rpool, be.properties, be.description)[0]
-
- if rc == 0:
- msg.printMsg(msg.Msgs.BEADM_MSG_BE_CREATE_SUCCESS,
- be.trgt_be_name_or_snapshot[0], be.log_id)
- return 0
-
- be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0]
- if rc == msg.Msgs.BE_ERR_SS_NOENT:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_SNAP_DOES_NOT_EXISTS,
- be.src_be_name_or_snapshot)
- elif rc == msg.Msgs.BE_ERR_BE_EXISTS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_BE_EXISTS, \
- be.trgt_be_name_or_snapshot[0])
- elif rc == msg.Msgs.BE_ERR_BE_NOENT:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, \
- be_name)
- elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS:
- be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc)
- msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, -1)
- return 1
- else:
- be.msg_buf["1"] = lb.beGetErrDesc(rc)
- if be.msg_buf["1"] == None:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, be.log_id)
-
- return 1
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def activateBE(be):
- """
- Activate a BE. Called from create() when -a is provided as CLI
- Option.
- """
-
- rc = lb.beActivate(be.trgt_be_name_or_snapshot[0])
- if rc == 0:
- return 0
-
- be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0]
- if rc == msg.Msgs.BE_ERR_BE_NOENT:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, opts[0])
- else:
- be.msg_buf["1"] = lb.beGetErrDesc(rc)
- if be.msg_buf["1"] == None:
- be.msg_buf["1"] = \
- msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc)
-
- msg.printMsg(msg.Msgs.BEADM_ERR_ACTIVATE, be.msg_buf, -1)
-
- return 1
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-def isBeadmSupported():
- """
- Currently the only environment that beadm is supported in is
- a global zone. Check that beadm is executing in a
- global zone and not in a non-global zone.
- """
-
- try:
- proc = subprocess.Popen("/sbin/zonename",
- stdout = subprocess.PIPE,
- stderr = subprocess.STDOUT)
- # Grab stdout.
- zonename = proc.communicate()[0].rstrip('\n')
- except OSError, (errno, strerror):
- msg.printMsg(msg.Msgs.BEADM_ERR_OS, strerror, -1)
- # Ignore a failed attempt to retreive the zonename.
- return True
-
- if zonename != "global":
- msg.printMsg(msg.Msgs.BEADM_ERR_NOT_SUPPORTED_NGZ, None, -1)
- return False
-
- return True
-
-
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-if __name__ == "__main__":
- try:
- RC = main()
- except SystemExit, e:
- raise e
- except:
- traceback.print_exc()
- sys.exit(99)
- sys.exit(RC)
--- a/usr/src/cmd/beadm/messages.py Thu Dec 16 09:43:44 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,264 +0,0 @@
-# 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
-# or http://www.opensolaris.org/os/licensing.
-# 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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-"""
-beadm - The Boot Environment Administration tool.
-
-A module containing all of the messages output by beadm.
-"""
-
-import sys
-from beadm import _
-
-class Msgs:
- """Indices corresponding to message numbers for beadm."""
-
- (BEADM_ERR_ACTIVATE,
- BEADM_ERR_BE_EXISTS,
- BEADM_ERR_SNAP_EXISTS,
- BEADM_ERR_CREATE,
- BEADM_ERR_DESTROY,
- BEADM_ERR_DESTROY_ACTIVE,
- BEADM_ERR_BE_DOES_NOT_EXIST,
- BEADM_ERR_NO_BES_EXIST,
- BEADM_ERR_MSG_SUB,
- BEADM_ERR_ILL_SUBCOMMAND,
- BEADM_ERR_INVALID_RESPONSE,
- BEADM_ERR_LIST,
- BEADM_ERR_LIST_DATA,
- BEADM_ERR_LOG_CREATE,
- BEADM_ERR_LOG_RM,
- BEADM_ERR_MOUNT,
- BEADM_ERR_MOUNT_EXISTS,
- BEADM_ERR_MOUNTED,
- BEADM_ERR_MOUNTPOINT,
- BEADM_ERR_MUTUALLY_EXCL,
- BEADM_ERR_NO_MSG,
- BEADM_ERR_NO_ZPOOL,
- BEADM_ERR_NOT_SUPPORTED_NGZ,
- BEADM_ERR_OPT_ARGS,
- BEADM_ERR_OS,
- BEADM_ERR_PERMISSIONS,
- BEADM_ERR_RENAME,
- BEADM_ERR_SHARED_FS,
- BEADM_ERR_SNAP_DOES_NOT_EXISTS,
- BEADM_ERR_UNMOUNT,
- BEADM_ERR_UNMOUNT_ACTIVE,
- BEADM_ERR_BENAME,
- BEADM_MSG_ACTIVE_ON_BOOT,
- BEADM_MSG_DESTROY,
- BEADM_MSG_DESTROY_NO,
- BEADM_MSG_BE_CREATE_START,
- BEADM_MSG_BE_CREATE_SUCCESS,
- BEADM_MSG_FREE_FORMAT,
- ) = range(38)
-
- # Indices corresponding to message numbers for libbe that we are
- # interested in expanding messages.
- (BE_ERR_ACCESS,
- BE_ERR_ACTIVATE_CURR,
- BE_ERR_AUTONAME,
- BE_ERR_BE_NOENT,
- BE_ERR_BUSY,
- BE_ERR_CANCELED,
- BE_ERR_CLONE,
- BE_ERR_COPY,
- BE_ERR_CREATDS,
- BE_ERR_CURR_BE_NOT_FOUND,
- BE_ERR_DESTROY,
- BE_ERR_DEMOTE,
- BE_ERR_DSTYPE,
- BE_ERR_BE_EXISTS,
- BE_ERR_INIT,
- BE_ERR_INTR,
- BE_ERR_INVAL,
- BE_ERR_INVALPROP,
- BE_ERR_INVALMOUNTPOINT,
- BE_ERR_MOUNT,
- BE_ERR_MOUNTED,
- BE_ERR_NAMETOOLONG,
- BE_ERR_NOENT,
- BE_ERR_POOL_NOENT,
- BE_ERR_NODEV,
- BE_ERR_NOTMOUNTED,
- BE_ERR_NOMEM,
- BE_ERR_NONINHERIT,
- BE_ERR_NXIO,
- BE_ERR_NOSPC,
- BE_ERR_NOTSUP,
- BE_ERR_OPEN,
- BE_ERR_PERM,
- BE_ERR_UNAVAIL,
- BE_ERR_PROMOTE,
- BE_ERR_ROFS,
- BE_ERR_READONLYDS,
- BE_ERR_READONLYPROP,
- BE_ERR_SS_EXISTS,
- BE_ERR_SS_NOENT,
- BE_ERR_UMOUNT,
- BE_ERR_UMOUNT_CURR_BE,
- BE_ERR_UMOUNT_SHARED,
- BE_ERR_UNKNOWN,
- BE_ERR_ZFS,
- BE_ERR_DESTROY_CURR_BE,
- BE_ERR_GEN_UUID,
- BE_ERR_PARSE_UUID,
- BE_ERR_NO_UUID,
- BE_ERR_ZONE_NO_PARENTBE,
- BE_ERR_ZONE_MULTIPLE_ACTIVE,
- BE_ERR_ZONE_NO_ACTIVE_ROOT,
- BE_ERR_ZONE_ROOT_NOT_LEGACY,
- BE_ERR_NO_MOUNTED_ZONE,
- BE_ERR_MOUNT_ZONEROOT,
- BE_ERR_UMOUNT_ZONEROOT,
- BE_ERR_ZONES_UNMOUNT,
- BE_ERR_FAULT,
- BE_ERR_RENAME_ACTIVE,
- BE_ERR_NO_MENU,
- BE_ERR_DEV_BUSY,
- BE_ERR_BAD_MENU_PATH,
- BE_ERR_ZONE_SS_EXISTS
- ) = range(4000, 4063)
-
- # Error message dictionaries.
- mBeadmErr = {}
- mBeadmOut = {}
- mBeadmLog = {}
-
- # Errors from beadm (to stderr).
- mBeadmErr[BEADM_ERR_ACTIVATE] = _("Unable to activate %(0)s.\n%(1)s")
- mBeadmErr[BEADM_ERR_BE_EXISTS] = _("BE %s already exists. Please choose a different BE name.")
- mBeadmErr[BEADM_ERR_BE_DOES_NOT_EXIST] = _("%s does not exist or appear to be a valid BE.\nPlease check that the name of the BE provided is correct.")
- mBeadmErr[BEADM_ERR_NO_BES_EXIST] = _("No boot environments found on this system.")
- mBeadmErr[BEADM_ERR_CREATE] = _("Unable to create %(0)s.\n%(1)s")
- mBeadmErr[BEADM_ERR_DESTROY] = _("Unable to destroy %(0)s.\n%(1)s")
- mBeadmErr[BEADM_ERR_DESTROY_ACTIVE] = _("%(0)s is the currently active BE and cannot be destroyed.\nYou must boot from another BE in order to destroy %(1)s.")
- mBeadmErr[BEADM_ERR_MSG_SUB] = _("Fatal error. No message associated with index %d")
- mBeadmErr[BEADM_ERR_ILL_SUBCOMMAND] = _("Illegal subcommand %s")
- mBeadmErr[BEADM_ERR_INVALID_RESPONSE] = _("Invalid response. Please enter 'y' or 'n'.")
- mBeadmErr[BEADM_ERR_LIST] = _("Unable to display Boot Environment: %s")
- mBeadmErr[BEADM_ERR_LIST_DATA] = _("Unable to process list data.")
- mBeadmErr[BEADM_ERR_LOG_CREATE] = _("Unable to create log file.")
- mBeadmErr[BEADM_ERR_LOG_RM] = _("Unable to remove %s")
- mBeadmErr[BEADM_ERR_MOUNT] = _("Unable to mount %(0)s.\n%(1)s")
- mBeadmErr[BEADM_ERR_MOUNT_EXISTS] = _("%s is already mounted.\nPlease unmount the BE before mounting it again.")
- mBeadmErr[BEADM_ERR_MOUNTED] = _("Unable to destroy %(0)s.\nIt is currently mounted and must be unmounted before it can be destroyed.\nUse 'beadm unmount %(1)s' to unmount the BE before destroying\nit or 'beadm destroy -fF %(2)s'.")
- mBeadmErr[BEADM_ERR_MOUNTPOINT] = _("Invalid mount point %s. Mount point must start with a /.")
- mBeadmErr[BEADM_ERR_MUTUALLY_EXCL] = _("Invalid options: %s are mutually exclusive.")
- mBeadmErr[BEADM_ERR_NO_MSG] = _("Unable to find message for error code: %d")
- mBeadmErr[BEADM_ERR_NO_ZPOOL] = _("BE: %s was not found in any pool.\n The pool may not exist or the name of the BE is not correct.")
- mBeadmErr[BEADM_ERR_NOT_SUPPORTED_NGZ] = _("beadm is not supported in a non-global zone.")
- mBeadmErr[BEADM_ERR_OPT_ARGS] = _("Invalid options and arguments:")
- mBeadmErr[BEADM_ERR_OS] = _("System error: %s")
- mBeadmErr[BEADM_ERR_RENAME] = _("Rename of BE %(0)s failed.\n%(1)s")
- mBeadmErr[BEADM_ERR_SHARED_FS] = _("%s is a shared file system and it cannot be unmounted.")
- mBeadmErr[BEADM_ERR_SNAP_DOES_NOT_EXISTS] = _("%s does not exist or appear to be a valid snapshot.\nPlease check that the name of the snapshot provided is correct.")
- mBeadmErr[BEADM_ERR_SNAP_EXISTS] = _("Snapshot %s already exists.\n Please choose a different snapshot name.")
- mBeadmErr[BEADM_ERR_UNMOUNT] = _("Unable to unmount %(0)s.\n%(1)s")
- mBeadmErr[BEADM_ERR_UNMOUNT_ACTIVE] = _("%s is the currently active BE.\nIt cannot be unmounted unless another BE is the currently active BE.")
- mBeadmErr[BE_ERR_ZONES_UNMOUNT] = _("Unable to destroy one of %(0)s's zone BE's.\nUse 'beadm destroy -fF %(1)s' or 'zfs -f destroy <dataset>'.")
- mBeadmErr[BEADM_ERR_PERMISSIONS] = _("You have insufficient privileges to execute this command.\nEither use 'pfexec' to execute the command or become superuser.")
- mBeadmErr[BEADM_ERR_BENAME] = _("The BE name provided is invalid.\n Please check it and try again.")
-
- # Catchall
- mBeadmErr[BEADM_MSG_FREE_FORMAT] = "%s"
-
- # Messages from beadm (to stdout).
- mBeadmOut[BEADM_MSG_ACTIVE_ON_BOOT] = _("The BE that was just destroyed was the 'active on boot' BE.\n%s is now the 'active on boot' BE. Use 'beadm activate' to change it.\n")
- mBeadmOut[BEADM_MSG_DESTROY] = _("Are you sure you want to destroy %s? This action cannot be undone(y/[n]):")
- mBeadmOut[BEADM_MSG_DESTROY_NO] = _("%s has not been destroyed.\n")
-
- # Messages from beadm (to log only).
- mBeadmLog[BEADM_MSG_BE_CREATE_START] = "Attempting to create %s"
- mBeadmLog[BEADM_MSG_BE_CREATE_SUCCESS] = "%s was created successfully"
-
-msgLog, msgOut, msgErr = range(3)
-
-def printLog(string, log_fd):
- """Print log."""
-
- sendMsg(string, msgLog, log_fd)
-
-def printStdout(string, log_fd):
- """Print standard output."""
-
- sendMsg(string, msgOut, log_fd)
-
-def printStderr(string, log_fd):
- """Print standard error."""
-
- sendMsg(string, msgErr, log_fd)
-
-def composeMsg(string, txt=None):
- """
- Compose the message to be dispayed.
- txt can be either a list or string object.
- Return the newly composed string.
- """
-
- try:
- msg = string % txt
- except TypeError:
- msg = string
-
- return (msg)
-
-def sendMsg(string, mode, log_fd=-1):
- """Send message."""
-
- if mode == msgOut:
- print >> sys.stdout, string,
- if mode == msgErr:
- print >> sys.stderr, string
- if log_fd != -1 or mode == msgLog:
- log_fd.write(string + "\n")
-
-def printMsg(msg_idx=-1, txt="", log_fd=-1):
- """Print the message based on the message index."""
-
- if msg_idx in Msgs.mBeadmErr:
- printStderr(composeMsg(Msgs.mBeadmErr[msg_idx], txt),
- log_fd)
- elif msg_idx in Msgs.mBeadmOut:
- printStdout(composeMsg(Msgs.mBeadmOut[msg_idx], txt),
- log_fd)
- elif msg_idx in Msgs.mBeadmLog:
- printLog(composeMsg(Msgs.mBeadmLog[msg_idx], txt), log_fd)
- else:
- printStderr(composeMsg(Msgs.mLibbe[BEADM_ERR_MSG_SUB],
- msg_idx), -1)
- sys.exit(1)
-
-def getMsg(msg_idx=-1, txt=""):
- """Print the message based on the message index."""
-
- if msg_idx in Msgs.mBeadmErr:
- return(composeMsg(Msgs.mBeadmErr[msg_idx], txt))
- elif msg_idx in Msgs.mBeadmOut:
- return(composeMsg(Msgs.mBeadmOut[msg_idx], txt))
- elif msg_idx in Msgs.mBeadmLog:
- return(composeMsg(Msgs.mBeadmLog[msg_idx], txt))
- else:
- return(composeMsg(Msgs.mLibbe[BEADM_ERR_MSG_SUB]))
- sys.exit(1)
--- a/usr/src/lib/libbe/Makefile Thu Dec 16 09:43:44 2010 -0800
+++ b/usr/src/lib/libbe/Makefile Mon Dec 27 21:47:11 2010 +0300
@@ -31,14 +31,12 @@
HDRDIR= common
SUBDIRS= $(MACH)
-TESTDIR= tbeadm
all := TARGET= all
clean := TARGET= clean
clobber := TARGET= clobber
install := TARGET= install
lint := TARGET= lint
-test := TARGET= test
POFILE = libbe.po
MSGFILES = `$(GREP) -l gettext $(HDRDIR)/*.[ch]`
@@ -47,7 +45,7 @@
all install lint: install_h $(SUBDIRS)
-clean clobber: $(SUBDIRS) $(TESTDIR)
+clean clobber: $(SUBDIRS)
$(POFILE): pofile_MSGFILES
@@ -57,12 +55,6 @@
_msg: $(MSGDOMAINPOFILE)
-test:
- cd tbeadm; pwd; $(MAKE) install
-
-$(TESTDIR): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
$(SUBDIRS): FRC
@cd $@; pwd; $(MAKE) $(TARGET)
--- a/usr/src/lib/libbe/tbeadm/Makefile Thu Dec 16 09:43:44 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-#
-# 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
-# or http://www.opensolaris.org/os/licensing.
-# 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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-ARCH = $(TARGET_ARCH:-%=%)
-
-PROG = tbeadm
-
-
-OBJS = tbeadm.o
-SRCS = $(OBJS:%.o=../%.c)
-
-include ../../Makefile.lib
-
-#LIBS= $(DYNLIB)
-
-INCLUDE = -I../common
-
-STATICDEPLIBS = ../$(ARCH)/libbe.a
-STATICLDLIBS += -linstzones -L/lib -L../$(ARCH) -lzfs -lnvpair \
- -luuid -lgen -Bstatic -lbe -Bdynamic
-
-DEPLIBS = ../$(ARCH)/libbe.so.1
-LDLIBS += -L/lib -L../pics/$(ARCH) -lzfs -lnvpair -lbe
-
-CPPFLAGS += -D_LARGEFILE64_SOURCE=1 -D_REENTRANT ${INCLUDE}
-CFLAGS += -g -DDEBUG
-
-
-$(PROG): $(OBJS) $(STATICDEPLIBS)
- $(LINK.c) -o $@ [email protected] $(OBJS) $(STATICLDLIBS)
- $(POST_PROCESS)
-
-all: $(PROG)
-
-install_h:
-
-install: all
-
-lint:
- $(LINT.c) $(SRCS) $(LDLIBS)
-
-clobber: clean
- $(RM) tbeadm.o
-
-clean:
- $(RM) tbeadm
-
--- a/usr/src/lib/libbe/tbeadm/tbeadm.c Thu Dec 16 09:43:44 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,837 +0,0 @@
-/*
- * 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
- * or http://www.opensolaris.org/os/licensing.
- * 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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- */
-
-/*
- * System includes
- */
-
-#include <stdio.h>
-#include <strings.h>
-#include <libzfs.h>
-
-#include "libbe.h"
-
-static int be_do_create(int argc, char **argv);
-static int be_do_destroy(int argc, char **argv);
-static int be_do_list(int argc, char **argv);
-static int be_do_mount(int argc, char **argv);
-static int be_do_unmount(int argc, char **argv);
-static int be_do_rename(int argc, char **argv);
-static int be_do_activate(int argc, char **argv);
-static int be_do_create_snapshot(int argc, char **argv);
-static int be_do_destroy_snapshot(int argc, char **argv);
-static int be_do_rollback(int argc, char **argv);
-static void usage(void);
-
-typedef struct be_command {
- const char *name;
- int (*func)(int argc, char **argv);
-} be_command_t;
-
-static be_command_t command_table[] = {
- { "create", be_do_create },
- { "destroy", be_do_destroy },
- { "list", be_do_list },
- { "mount", be_do_mount },
- { "unmount", be_do_unmount },
- { "rename", be_do_rename },
- { "activate", be_do_activate },
- { "create_snap", be_do_create_snapshot },
- { "destroy_snap", be_do_destroy_snapshot },
-};
-
-static int fs_num = 2;
-static int shared_fs_num = 2;
-static char *fs_names[2] = {"/", "/opt"};
-static char *shared_fs_names[4] = {"/export", "/export/home"};
-
-static void
-usage(void)
-{
- (void) printf("usage:\n"
- "\ttbeadm\n"
- "\ttbeadm create [-d BE_desc] [-e nonActiveBe | -i] \n"
- "\t\t[-o property=value] ... [-p zpool] [beName]\n"
- "\ttbeadm destroy [-fs] beName\n"
- "\ttbeadm create_snap [-p policy] beName [snapshot]\n"
- "\ttbeadm destroy_snap beName snapshot\n"
- "\ttbeadm list [-s] [beName]\n"
- "\ttbeadm mount [-s ro|rw] beName mountpoint\n"
- "\ttbeadm unmount [-f] beName\n"
- "\ttbeadm rename origBeName newBeName\n"
- "\ttbeadm activate beName\n"
- "\ttbeadm rollback beName snapshot\n");
-}
-
-int
-main(int argc, char **argv) {
-
- if (argc < 2) {
- usage();
- return (1);
- }
-
- /* Turn error printing on */
- libbe_print_errors(B_TRUE);
-
- if (strcmp(argv[1], "create") == 0) {
- return (be_do_create(argc - 1, argv + 1));
- } else if (strcmp(argv[1], "destroy") == 0) {
- return (be_do_destroy(argc - 1, argv + 1));
- } else if (strcmp(argv[1], "list") == 0) {
- return (be_do_list(argc - 1, argv + 1));
- } else if (strcmp(argv[1], "mount") == 0) {
- return (be_do_mount(argc - 1, argv + 1));
- } else if (strcmp(argv[1], "unmount") == 0) {
- return (be_do_unmount(argc - 1, argv + 1));
- } else if (strcmp(argv[1], "rename") == 0) {
- return (be_do_rename(argc - 2, argv + 2));
- } else if (strcmp(argv[1], "activate") == 0) {
- return (be_do_activate(argc - 2, argv + 2));
- } else if (strcmp(argv[1], "create_snap") == 0) {
- return (be_do_create_snapshot(argc - 1, argv + 1));
- } else if (strcmp(argv[1], "destroy_snap") == 0) {
- return (be_do_destroy_snapshot(argc - 2, argv + 2));
- } else if (strcmp(argv[1], "rollback") == 0) {
- return (be_do_rollback(argc - 2, argv + 2));
- } else {
- usage();
- return (1);
- }
-
- /* NOTREACHED */
-}
-
-static int
-be_do_create(int argc, char **argv)
-{
- nvlist_t *be_attrs;
- char *obe_name = NULL;
- char *snap_name = NULL;
- char *nbe_zpool = NULL;
- char *nbe_name = NULL;
- char *nbe_desc = NULL;
- nvlist_t *zfs_props = NULL;
- char *propname = NULL;
- char *propval = NULL;
- char *strval = NULL;
- boolean_t init = B_FALSE;
- int c;
- int ret = BE_SUCCESS;
-
- if (nvlist_alloc(&zfs_props, NV_UNIQUE_NAME, 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
-
- while ((c = getopt(argc, argv, "d:e:io:p:")) != -1) {
- switch (c) {
- case 'd':
- nbe_desc = optarg;
- break;
- case 'e':
- obe_name = optarg;
- break;
- case 'i':
- /* Special option to test be_init() function */
- init = B_TRUE;
- break;
- case 'o':
- if (zfs_props == NULL) {
- if (nvlist_alloc(&zfs_props, NV_UNIQUE_NAME,
- 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
- }
-
- propname = optarg;
- if ((propval = strchr(propname, '=')) == NULL) {
- (void) fprintf(stderr, "missing "
- "'=' for -o option\n");
- return (1);
- }
- *propval = '\0';
- propval++;
- if (nvlist_lookup_string(zfs_props, propname,
- &strval) == 0) {
- (void) fprintf(stderr, "property '%s' "
- "specified multiple times\n", propname);
- return (1);
- }
- if (nvlist_add_string(zfs_props, propname, propval)
- != 0) {
- (void) fprintf(stderr, "internal "
- "error: out of memory\n");
- return (1);
- }
- break;
- case 'p':
- nbe_zpool = optarg;
- break;
- default:
- usage();
- return (1);
- }
- }
-
- if (init && obe_name) {
- printf("ERROR: -e and -i are exclusive options\n");
- usage();
- return (1);
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc == 1) {
- nbe_name = argv[0];
- } else if (argc > 1) {
- usage();
- return (1);
- }
-
- if (obe_name) {
- /*
- * Check if obe_name is really a snapshot name.
- * If so, split it out.
- */
- char *cp = NULL;
-
- cp = strrchr(obe_name, '@');
- if (cp != NULL) {
- cp[0] = '\0';
- if (cp[1] != NULL && cp[1] != '\0') {
- snap_name = cp+1;
- }
- }
- }
-
- if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
-
- if (zfs_props) {
- if (nvlist_add_nvlist(be_attrs, BE_ATTR_ZFS_PROPERTIES,
- zfs_props) != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_ZFS_PROPERTES (%s).\n", zfs_props);
- return (1);
- }
- }
-
- if (obe_name != NULL) {
- if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name);
- return (1);
- }
- }
-
- if (snap_name != NULL) {
- if (nvlist_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_SNAP_NANE (%s).\n", snap_name);
- return (1);
- }
- }
-
- if (nbe_zpool != NULL) {
- if (nvlist_add_string(be_attrs, BE_ATTR_NEW_BE_POOL, nbe_zpool)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_NEW_BE_POOL (%s).\n", nbe_zpool);
- return (1);
- }
- }
-
- if (nbe_name) {
- if (nvlist_add_string(be_attrs, BE_ATTR_NEW_BE_NAME, nbe_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_NEW_BE_NAME (%s).\n", nbe_name);
- return (1);
- }
- }
-
- if (nbe_desc) {
- if (nvlist_add_string(be_attrs, BE_ATTR_NEW_BE_DESC, nbe_desc)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_NEW_BE_DESC (%s)\n", nbe_desc);
- return (1);
- }
- }
-
- if (init) {
- /*
- * Add the default file system test values to test
- * creating an initial BE.
- */
- if (nvlist_add_uint16(be_attrs, BE_ATTR_FS_NUM, fs_num) != 0) {
- printf("nvlist_add_uint16 failed for BE_ATTR_FS_NUM "
- "(%d).\n", fs_num);
- return (1);
- }
-
- if (nvlist_add_string_array(be_attrs, BE_ATTR_FS_NAMES,
- fs_names, fs_num) != 0) {
- printf("nvlist_add_string_array failed for "
- "BE_ATTR_FS_NAMES\n");
- return (1);
- }
-
- if (nvlist_add_uint16(be_attrs, BE_ATTR_SHARED_FS_NUM,
- shared_fs_num) != 0) {
- printf("nvlist_add_uint16 failed for "
- "BE_ATTR_SHARED_FS_NUM (%d).\n", shared_fs_num);
- return (1);
- }
-
- if (nvlist_add_string_array(be_attrs, BE_ATTR_SHARED_FS_NAMES,
- shared_fs_names, shared_fs_num) != 0) {
- printf("nvlist_add_string_array failed for "
- "BE_ATTR_SHARED_FS_NAMES\n");
- return (1);
- }
-
- return (be_init(be_attrs));
- }
-
- ret = be_copy(be_attrs);
-
- if (!nbe_name & ret == BE_SUCCESS) {
- /*
- * We requested an auto named BE; find out the
- * name of the BE that was created for us and
- * the auto snapshot created from the original BE.
- */
- if (nvlist_lookup_string(be_attrs, BE_ATTR_NEW_BE_NAME,
- &nbe_name) != 0) {
- printf("failed to get BE_ATTR_NEW_BE_NAME attribute\n");
- ret = 1;
- } else {
- printf("Auto named BE: %s\n", nbe_name);
- }
-
- if (nvlist_lookup_string(be_attrs, BE_ATTR_SNAP_NAME,
- &snap_name) != 0) {
- printf("failed to get BE_ATTR_SNAP_NAME attribute\n");
- ret = 1;
- } else {
- printf("Auto named snapshot: %s\n", snap_name);
- }
- }
-
- return (ret);
-}
-
-static int
-be_do_destroy(int argc, char **argv)
-{
- nvlist_t *be_attrs;
- int c;
- int destroy_flags = 0;
- char *be_name;
-
- while ((c = getopt(argc, argv, "fs")) != -1) {
- switch (c) {
- case 'f':
- destroy_flags |= BE_DESTROY_FLAG_FORCE_UNMOUNT;
- break;
- case 's':
- destroy_flags |= BE_DESTROY_FLAG_SNAPSHOTS;
- break;
- default:
- usage();
- return (1);
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc != 1) {
- usage();
- return (1);
- }
-
- if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, argv[0]) != 0) {
- printf("nvlist_add_string failed for BE_ATTR_NEW_BE_NAME "
- "(%s).\n", argv[0]);
- return (1);
- }
-
- if (nvlist_add_uint16(be_attrs, BE_ATTR_DESTROY_FLAGS, destroy_flags)
- != 0) {
- printf("nvlist_add_uint16 failed for "
- "BE_ATTR_DESTROY_FLAGS.\n");
- return (1);
- }
-
- return (be_destroy(be_attrs));
-}
-
-static int
-be_do_list(int argc, char **argv)
-{
- int err = BE_SUCCESS;
- be_node_list_t *be_nodes;
- be_node_list_t *cur_be;
- boolean_t snaps = B_FALSE;
- int c = 0;
-
- while ((c = getopt(argc, argv, "s")) != -1) {
- switch (c) {
- case 's':
- snaps = B_TRUE;
- break;
- default:
- usage();
- return (1);
- }
- }
-
- argc -= optind;
- argv += optind;
-
-
- if (argc == 1) {
- err = be_list(argv[0], &be_nodes);
- } else {
- err = be_list(NULL, &be_nodes);
- }
-
- if (err == BE_SUCCESS) {
-
- printf(
- "BE name\t\tActive\tActive \tDataset\t\t\tPolicy\tUUID\n");
- printf(
- " \t\t \ton boot\t \t\t\t \t \n");
- printf(
- "-------\t\t------\t-------\t-------\t\t\t------\t----\n");
-
- for (cur_be = be_nodes; cur_be != NULL;
- cur_be = cur_be->be_next_node) {
-
- int name_len = strlen(cur_be->be_node_name);
- int ds_len = strlen(cur_be->be_root_ds);
-
- printf("%s%s%s\t%s\t%s%s%s\t%s\n",
- cur_be->be_node_name,
- name_len < 8 ? "\t\t" : "\t",
- cur_be->be_active ? "yes" : "no",
- cur_be->be_active_on_boot ? "yes" : "no",
- cur_be->be_root_ds,
- ds_len < 8 ? "\t\t\t" :
- (ds_len < 16 ? "\t\t" : "\t"),
- cur_be->be_policy_type,
- cur_be->be_uuid_str ? cur_be->be_uuid_str : "-");
- if (snaps) {
- be_snapshot_list_t *snapshots = NULL;
- printf("Snapshot Name\n");
- printf("--------------\n");
- for (snapshots = cur_be->be_node_snapshots;
- snapshots != NULL; snapshots =
- snapshots->be_next_snapshot) {
- printf("%s\n",
- snapshots->be_snapshot_name);
- }
- }
- }
- }
-
- be_free_list(be_nodes);
- return (err);
-}
-
-static int
-be_do_rename(int argc, char **argv)
-{
- nvlist_t *be_attrs;
- char *obe_name;
- char *nbe_name;
-
- if (argc < 1 || argc > 2) {
- usage();
- return (1);
- }
-
- obe_name = argv[0];
- nbe_name = argv[1];
-
- if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name);
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_NEW_BE_NAME, nbe_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_NEW_BE_NAME (%s).\n", nbe_name);
- return (1);
- }
-
- return (be_rename(be_attrs));
-
-}
-
-static int
-be_do_create_snapshot(int argc, char **argv)
-{
- nvlist_t *be_attrs;
- char *obe_name = NULL;
- char *snap_name = NULL;
- char *policy = NULL;
- int c;
- int ret = BE_SUCCESS;
-
- while ((c = getopt(argc, argv, "p:")) != -1) {
- switch (c) {
- case 'p':
- policy = optarg;
- break;
- default:
- usage();
- return (1);
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc < 1 || argc > 2) {
- usage();
- return (1);
- }
-
- obe_name = argv[0];
-
- if (argc > 1) {
- /* Snapshot name provided */
- snap_name = argv[1];
- }
-
- if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name);
- return (1);
- }
-
- if (policy) {
- if (nvlist_add_string(be_attrs, BE_ATTR_POLICY, policy) != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_POLICY (%s).\n", policy);
- return (1);
- }
- }
-
- if (snap_name) {
- if (nvlist_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_SNAP_NAME (%s).\n", snap_name);
- return (1);
- }
- }
-
- ret = be_create_snapshot(be_attrs);
-
- if (!snap_name && ret == BE_SUCCESS) {
- /*
- * We requested an auto named snapshot; find out
- * the snapshot name that was created for us.
- */
- if (nvlist_lookup_string(be_attrs, BE_ATTR_SNAP_NAME,
- &snap_name) != 0) {
- printf("failed to get BE_ATTR_SNAP_NAME attribute\n");
- ret = 1;
- } else {
- printf("Auto named snapshot: %s\n", snap_name);
- }
- }
-
- return (ret);
-}
-
-static int
-be_do_destroy_snapshot(int argc, char **argv)
-{
- nvlist_t *be_attrs;
- char *obe_name;
- char *snap_name;
-
- if (argc != 2) {
- usage();
- return (1);
- }
-
- obe_name = argv[0];
- snap_name = argv[1];
-
- if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name);
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_SNAP_NAME (%s).\n", snap_name);
- return (1);
- }
-
- return (be_destroy_snapshot(be_attrs));
-}
-
-static int
-be_do_rollback(int argc, char **argv)
-{
- nvlist_t *be_attrs;
- char *obe_name;
- char *snap_name;
-
- if (argc < 1 || argc > 2) {
- usage();
- return (1);
- }
-
- obe_name = argv[0];
- snap_name = argv[1];
-
- if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name);
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_SNAP_NAME (%s).\n", snap_name);
- return (1);
- }
-
- return (be_rollback(be_attrs));
-}
-
-static int
-be_do_activate(int argc, char **argv)
-{
- nvlist_t *be_attrs;
- char *obe_name;
-
- if (argc < 1 || argc > 2) {
- usage();
- return (1);
- }
-
- obe_name = argv[0];
-
- if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name);
- return (1);
- }
-
- return (be_activate(be_attrs));
-}
-
-static int
-be_do_mount(int argc, char **argv)
-{
- nvlist_t *be_attrs;
- int c;
- boolean_t shared_fs = B_FALSE;
- int mount_flags = 0;
- char *obe_name;
- char *mountpoint;
-
- while ((c = getopt(argc, argv, "s:")) != -1) {
- switch (c) {
- case 's':
- shared_fs = B_TRUE;
-
- mount_flags |= BE_MOUNT_FLAG_SHARED_FS;
-
- if (strcmp(optarg, "rw") == 0) {
- mount_flags |= BE_MOUNT_FLAG_SHARED_RW;
- } else if (strcmp(optarg, "ro") != 0) {
- printf("The -s flag requires an argument "
- "[ rw | ro ]\n");
- usage();
- return (1);
- }
-
- break;
- default:
- usage();
- return (1);
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc < 1 || argc > 2) {
- usage();
- return (1);
- }
-
- obe_name = argv[0];
-
- if (argc == 2) {
- mountpoint = argv[1];
- } else {
- /*
- * XXX - Need to generate a random mountpoint here;
- * right now we're just exitting if one isn't supplied.
- */
- usage();
- return (1);
- }
-
- if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name);
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_MOUNTPOINT, mountpoint)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_MOUNTPOINT (%s).\n", mountpoint);
- return (1);
- }
-
- if (shared_fs) {
- if (nvlist_add_uint16(be_attrs, BE_ATTR_MOUNT_FLAGS,
- mount_flags) != 0) {
- printf("nvlist_add_uint16 failed for "
- "BE_ATTR_MOUNT_FLAGS (%d).\n", mount_flags);
- return (1);
- }
- }
-
- return (be_mount(be_attrs));
-}
-
-
-static int
-be_do_unmount(int argc, char **argv)
-{
- nvlist_t *be_attrs;
- int c;
- int unmount_flags = 0;
- char *obe_name;
-
- while ((c = getopt(argc, argv, "f")) != -1) {
- switch (c) {
- case 'f':
- unmount_flags |= BE_UNMOUNT_FLAG_FORCE;
- break;
- default:
- usage();
- return (1);
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc != 1) {
- usage();
- return (1);
- }
-
- obe_name = argv[0];
-
- if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
- printf("nvlist_alloc failed.\n");
- return (1);
- }
-
- if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name)
- != 0) {
- printf("nvlist_add_string failed for "
- "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name);
- return (1);
- }
-
- if (nvlist_add_uint16(be_attrs, BE_ATTR_UNMOUNT_FLAGS, unmount_flags)
- != 0) {
- printf("nvlist_add_uint16 failed for "
- "BE_ATTR_UNMOUNT_FLAGS\n");
- return (1);
- }
-
- return (be_unmount(be_attrs));
-}
--- a/usr/src/pkg/manifests/install-beadm.mf Thu Dec 16 09:43:44 2010 -0800
+++ b/usr/src/pkg/manifests/install-beadm.mf Mon Dec 27 21:47:11 2010 +0300
@@ -20,6 +20,7 @@
#
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2010 Nexenta Systems, Inc. All rights reserved.
#
set name=pkg.fmri value=pkg:/install/beadm@$(PKGVERS)
@@ -41,13 +42,6 @@
file path=usr/lib/libbe.so.1
file path=usr/lib/llib-lbe
file path=usr/lib/llib-lbe.ln
-file path=usr/lib/python2.6/vendor-packages/beadm/BootEnvironment.py mode=0444
-file path=usr/lib/python2.6/vendor-packages/beadm/BootEnvironment.pyc \
- mode=0444
-file path=usr/lib/python2.6/vendor-packages/beadm/__init__.py mode=0444
-file path=usr/lib/python2.6/vendor-packages/beadm/__init__.pyc mode=0444
-file path=usr/lib/python2.6/vendor-packages/beadm/messages.py mode=0444
-file path=usr/lib/python2.6/vendor-packages/beadm/messages.pyc mode=0444
file path=usr/lib/python2.6/vendor-packages/libbe_py.so
license cr_Sun license=cr_Sun
license lic_CDDL license=lic_CDDL