diff options
Diffstat (limited to 'usr/src/cmd')
-rw-r--r-- | usr/src/cmd/boot/bootadm/bootadm.c | 125 | ||||
-rw-r--r-- | usr/src/cmd/boot/bootadm/bootadm.h | 7 | ||||
-rw-r--r-- | usr/src/cmd/boot/scripts/update_grub.ksh | 55 | ||||
-rw-r--r-- | usr/src/cmd/dumpadm/Makefile | 4 | ||||
-rw-r--r-- | usr/src/cmd/dumpadm/dconf.c | 11 | ||||
-rw-r--r-- | usr/src/cmd/power/Makefile | 4 | ||||
-rw-r--r-- | usr/src/cmd/power/handlers.c | 171 | ||||
-rw-r--r-- | usr/src/cmd/power/svc-power | 13 | ||||
-rw-r--r-- | usr/src/cmd/svc/milestone/fs-minimal | 2 | ||||
-rw-r--r-- | usr/src/cmd/svc/milestone/fs-usr | 35 | ||||
-rw-r--r-- | usr/src/cmd/svc/shell/fs_include.sh | 13 | ||||
-rw-r--r-- | usr/src/cmd/swap/swap.c | 16 | ||||
-rw-r--r-- | usr/src/cmd/zdb/zdb.c | 3 |
13 files changed, 410 insertions, 49 deletions
diff --git a/usr/src/cmd/boot/bootadm/bootadm.c b/usr/src/cmd/boot/bootadm/bootadm.c index d1ae66bbcb..a0647e0b0e 100644 --- a/usr/src/cmd/boot/bootadm/bootadm.c +++ b/usr/src/cmd/boot/bootadm/bootadm.c @@ -54,6 +54,7 @@ #include <sys/systeminfo.h> #include <sys/dktp/fdisk.h> #include <sys/param.h> +#include <sys/sysmacros.h> #if !defined(_OPB) #include <sys/ucode.h> @@ -197,6 +198,7 @@ static int bam_argc; static int bam_check; static int bam_smf_check; static int bam_lock_fd = -1; +static int bam_zfs; static char rootbuf[PATH_MAX] = "/"; static int bam_update_all; static int bam_alt_platform; @@ -242,6 +244,7 @@ static int s_fputs(char *, FILE *); static char *s_strdup(char *); static int is_readonly(char *); +static int is_zfs(char *, char **); static int is_amd64(void); static int is_sun4u(void); static int is_sun4v(void); @@ -419,7 +422,7 @@ parse_args_internal(int argc, char *argv[]) opterr = 0; error = 0; - while ((c = getopt(argc, argv, "a:d:fm:no:vCR:p:")) != -1) { + while ((c = getopt(argc, argv, "a:d:fm:no:vCR:p:Z")) != -1) { switch (c) { case 'a': if (bam_cmd) { @@ -500,6 +503,9 @@ parse_args_internal(int argc, char *argv[]) bam_error(INVALID_PLAT, bam_platform); } break; + case 'Z': + bam_zfs = 1; + break; case '?': error = 1; bam_error(BAD_OPT, optopt); @@ -893,8 +899,9 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[]) error_t ret; char menu_path[PATH_MAX]; char path[PATH_MAX]; + char full_menu_root[PATH_MAX]; menu_t *menu; - char *mntpt, *menu_root, *logslice, *fstype; + char *mntpt, *menu_root, *logslice, *fstype, *grubSLICEpool, *pool; struct stat sb; int mnted; /* set if we did a mount */ error_t (*f)(menu_t *mp, char *menu_path, char *opt); @@ -919,7 +926,7 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[]) mntpt = NULL; mnted = 0; - logslice = fstype = NULL; + logslice = fstype = grubSLICEpool = pool = NULL; /* * Check for the menu.list file: @@ -931,10 +938,18 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[]) * 4. Use / */ if (bam_alt_root) { - (void) snprintf(path, sizeof (path), "%s%s", bam_root, - GRUB_slice); + if (is_zfs(bam_root, &grubSLICEpool)) + (void) snprintf(path, sizeof (path), "%s/%s%s", + bam_root, grubSLICEpool, GRUB_slice); + else + (void) snprintf(path, sizeof (path), "%s%s", + bam_root, GRUB_slice); } else { - (void) snprintf(path, sizeof (path), "%s", GRUB_slice); + if (is_zfs(bam_root, &grubSLICEpool)) + (void) snprintf(path, sizeof (path), "/%s%s", + grubSLICEpool, GRUB_slice); + else + (void) snprintf(path, sizeof (path), "%s", GRUB_slice); } if (stat(path, &sb) == 0) { @@ -953,7 +968,25 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[]) return (BAM_ERROR); } - elide_trailing_slash(menu_root, menu_path, sizeof (menu_path)); + /* + * menu_root is the root file system of the boot environment being + * operated on. + * full_menu_root is the location of the /boot/grub directory. + * With a ufs root, this is simply menu_root. With a zfs + * root, it's <menu_root>/<poolname> + */ + elide_trailing_slash(menu_root, full_menu_root, + sizeof (full_menu_root)); + + if (is_zfs(menu_root, &pool)) { + (void) strlcat(full_menu_root, "/", sizeof (full_menu_root)); + (void) strlcat(full_menu_root, pool, sizeof (full_menu_root)); + } + + /* + * menu_path is the directory that contains the menu.lst file + */ + (void) strlcpy(menu_path, full_menu_root, sizeof (menu_path)); (void) strlcat(menu_path, GRUB_MENU, sizeof (menu_path)); /* @@ -999,13 +1032,17 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[]) else ret = f(menu, menu_path, opt); if (ret == BAM_WRITE) { - ret = menu_write(menu_root, menu); + ret = menu_write(full_menu_root, menu); } menu_free(menu); umount_grub_slice(mnted, mntpt, NULL, logslice, fstype); + if (grubSLICEpool) + free(grubSLICEpool); + if (pool) + free(pool); return (ret); } @@ -2093,6 +2130,65 @@ is_readonly(char *root) return (0); } +static int +is_zfs(char *root, char **poolname) +{ + struct statvfs64 vfs; + FILE *fp; + struct extmnttab mnt; + dev_t devicenum; + char *special = NULL; + char *cp; + + /* poolname can be null */ + if (poolname) + *poolname = NULL; + + if (statvfs64(root, &vfs) != 0) { + if (bam_verbose) + bam_error(STATVFS_FAIL, root, strerror(errno)); + return (0); + } + + if (strncmp(vfs.f_basetype, "zfs", strlen("zfs")) != 0) + return (0); + + if (poolname == NULL) + return (1); + + /* + * Now find the mnttab entry so that we can extract the + * pool name from the special device field. + */ + fp = fopen(MNTTAB, "r"); + if (fp == NULL) { + bam_error(OPEN_FAIL, MNTTAB, strerror(errno)); + return (0); + } + + resetmnttab(fp); + + while (getextmntent(fp, &mnt, sizeof (mnt)) == 0) { + devicenum = makedevice(mnt.mnt_major, mnt.mnt_minor); + if (devicenum == vfs.f_fsid) { + special = s_strdup(mnt.mnt_special); + if ((cp = strchr(special, '/')) != NULL) + *cp = '\0'; + *poolname = s_strdup(special); + break; + } + } + + (void) fclose(fp); + + if (special) { + free(special); + return (1); + } + + return (0); +} + static error_t update_archive(char *root, char *opt) { @@ -3480,12 +3576,13 @@ update_entry(menu_t *mp, char *menu_root, char *opt) /* add the entry for normal Solaris */ if (bam_direct == BAM_DIRECT_DBOOT) { entry = update_boot_entry(mp, title, grubdisk, - DIRECT_BOOT_KERNEL, NULL, DIRECT_BOOT_ARCHIVE, - osroot == menu_root); + (bam_zfs ? DIRECT_BOOT_KERNEL_ZFS : DIRECT_BOOT_KERNEL), + NULL, DIRECT_BOOT_ARCHIVE, osroot == menu_root); if ((entry != BAM_ERROR) && (bam_is_hv == BAM_HV_PRESENT)) { (void) update_boot_entry(mp, NEW_HV_ENTRY, grubdisk, - XEN_MENU, KERNEL_MODULE_LINE, DIRECT_BOOT_ARCHIVE, - osroot == menu_root); + XEN_MENU, (bam_zfs ? + KERNEL_MODULE_LINE_ZFS : KERNEL_MODULE_LINE), + DIRECT_BOOT_ARCHIVE, osroot == menu_root); } } else { entry = update_boot_entry(mp, title, grubdisk, MULTI_BOOT, @@ -3503,7 +3600,9 @@ update_entry(menu_t *mp, char *menu_root, char *opt) (void) snprintf(failsafe, sizeof (failsafe), "%s%s", osroot, DIRECT_BOOT_FAILSAFE_KERNEL); if (stat(failsafe, &sbuf) == 0) { - failsafe_kernel = DIRECT_BOOT_FAILSAFE_LINE; + failsafe_kernel = + (bam_zfs ? DIRECT_BOOT_FAILSAFE_LINE_ZFS : + DIRECT_BOOT_FAILSAFE_LINE); } else { (void) snprintf(failsafe, sizeof (failsafe), "%s%s", osroot, MULTI_BOOT_FAILSAFE); diff --git a/usr/src/cmd/boot/bootadm/bootadm.h b/usr/src/cmd/boot/bootadm/bootadm.h index f29071d1d0..a4a606e845 100644 --- a/usr/src/cmd/boot/bootadm/bootadm.h +++ b/usr/src/cmd/boot/bootadm/bootadm.h @@ -174,6 +174,9 @@ extern int is_grub(const char *); /* Title used for hv entries */ #define NEW_HV_ENTRY "Solaris xVM" +/* ZFS boot option */ +#define ZFS_BOOT "-B $ZFS-BOOTFS" + /* multiboot */ #define MULTI_BOOT "/platform/i86pc/multiboot" #define MULTI_BOOT_FAILSAFE "/boot/multiboot" @@ -186,6 +189,8 @@ extern int is_grub(const char *); #define DIRECT_BOOT_KERNEL "/platform/i86pc/kernel/$ISADIR/unix" #define DIRECT_BOOT_FAILSAFE_KERNEL "/boot/platform/i86pc/kernel/unix" #define DIRECT_BOOT_FAILSAFE_LINE DIRECT_BOOT_FAILSAFE_KERNEL " -s" +#define DIRECT_BOOT_KERNEL_ZFS DIRECT_BOOT_KERNEL " " ZFS_BOOT +#define DIRECT_BOOT_FAILSAFE_LINE_ZFS DIRECT_BOOT_FAILSAFE_LINE " " ZFS_BOOT /* Boot archives */ #define SUN4U_ARCHIVE "/platform/sun4u/boot_archive" @@ -202,6 +207,8 @@ extern int is_grub(const char *); #define XEN_MENU "/boot/$ISADIR/xen.gz" #define HYPERVISOR_KERNEL "/platform/i86xpv/kernel/$ISADIR/unix" #define KERNEL_MODULE_LINE HYPERVISOR_KERNEL " " HYPERVISOR_KERNEL +#define KERNEL_MODULE_LINE_ZFS \ + HYPERVISOR_KERNEL " " HYPERVISOR_KERNEL " " ZFS_BOOT #ifdef __cplusplus } diff --git a/usr/src/cmd/boot/scripts/update_grub.ksh b/usr/src/cmd/boot/scripts/update_grub.ksh index 86a2ee65c8..d824afd5d1 100644 --- a/usr/src/cmd/boot/scripts/update_grub.ksh +++ b/usr/src/cmd/boot/scripts/update_grub.ksh @@ -21,7 +21,7 @@ # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -43,6 +43,7 @@ done ARCH=`uname -p` is_pcfs_boot=yes +is_zfs_boot=no check_pcfs_boot() { @@ -53,13 +54,42 @@ check_pcfs_boot() fi } +check_zfs_boot() +{ + if [ -f "$ALT_ROOT"/etc/lu/GRUB_slice ]; then + dev=`grep '^PHYS_SLICE=' "$ALT_ROOT"/etc/lu/GRUB_slice | + cut -d= -f2` + if [ "`fstyp $dev`" = "zfs" ]; then + is_zfs_boot=yes + fi + else + rootfstype=`df -n ${ALT_ROOT:-/} | awk '{print $3}'` + if [ "$rootfstype" = "zfs" ]; then + is_zfs_boot=yes + fi + + fi +} + # # Detect SVM root and return the list of raw devices under the mirror # get_rootdev_list() { if [ -f "$ALT_ROOT"/etc/lu/GRUB_slice ]; then - grep '^PHYS_SLICE' "$ALT_ROOT"/etc/lu/GRUB_slice | cut -d= -f2 + dev=`grep '^PHYS_SLICE' "$ALT_ROOT"/etc/lu/GRUB_slice | + cut -d= -f2` + if [ "$is_zfs_boot" = "yes" ]; then + fstyp -a "$dev" | grep 'path: ' | grep -v phys_path: | + cut -d"'" -f2 | sed 's+/dsk/+/rdsk/+' + else + echo "$dev" + fi + return + elif [ "$is_zfs_boot" = "yes" ]; then + rootpool=`df -k ${ALT_ROOT:-/} | tail +2 | cut -d/ -f1` + rootdevlist=`zpool iostat -v "$rootpool" | tail +5 | + grep -v mirror | sed -n -e '/--/q' -e p | awk '{print $1}'` else metadev=`grep -v "^#" "$ALT_ROOT"/etc/vfstab | \ grep "[ ]/[ ]" | nawk '{print $2}'` @@ -70,11 +100,11 @@ get_rootdev_list() rootdevlist=`metastat -p $metavol |\ grep -v "^$metavol[ ]" | nawk '{print $4}'` fi - for rootdev in $rootdevlist - do - echo /dev/rdsk/$rootdev - done fi + for rootdev in $rootdevlist + do + echo /dev/rdsk/$rootdev + done } # @@ -101,16 +131,22 @@ install_grub() fi fi - get_rootdev_list | while read rootdev + grubdevlist=`get_rootdev_list` + zfsarg="" + if [ "$is_zfs_boot" = "yes" ]; then + zfsarg="-Z" + fi + + for rootdev in $grubdevlist do if [ X"$rpcfsdev" != X ]; then echo "create GRUB menu in "$ALT_ROOT"/stubboot" - "$ALT_ROOT"/sbin/bootadm update-menu \ + "$ALT_ROOT"/sbin/bootadm update-menu $zfsarg\ -R "$ALT_ROOT"/stubboot -o $rootdev,"$ALT_ROOT" else echo "Creating GRUB menu in ${ALT_ROOT:-/}" $ALT_ROOT/sbin/bootadm update-menu -R ${ALT_ROOT:-/} \ - -o $rootdev + $zfsarg -o $rootdev fi print "Installing grub on $rootdev" "$ALT_ROOT"/sbin/installgrub $STAGE1 $STAGE2 $rootdev @@ -119,6 +155,7 @@ install_grub() if [ -f "$ALT_ROOT"/platform/i86pc/multiboot -a "$ARCH" = i386 ] ; then check_pcfs_boot + check_zfs_boot install_grub fi diff --git a/usr/src/cmd/dumpadm/Makefile b/usr/src/cmd/dumpadm/Makefile index 406f5dc3a0..fac14347df 100644 --- a/usr/src/cmd/dumpadm/Makefile +++ b/usr/src/cmd/dumpadm/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -44,7 +44,7 @@ GROUP = bin ROOTMANIFESTDIR = $(ROOTSVCSYSTEM) -LDLIBS += -ldiskmgt +LDLIBS += -ldiskmgt -lzfs .KEEP_STATE: diff --git a/usr/src/cmd/dumpadm/dconf.c b/usr/src/cmd/dumpadm/dconf.c index 1fb9216765..3cd5b725da 100644 --- a/usr/src/cmd/dumpadm/dconf.c +++ b/usr/src/cmd/dumpadm/dconf.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,6 +38,7 @@ #include <fcntl.h> #include <errno.h> #include <libdiskmgt.h> +#include <libzfs.h> #include "dconf.h" #include "minfree.h" @@ -343,6 +344,11 @@ dconf_dev_ioctl(dumpconf_t *dcp, int cmd) case EBUSY: warn(gettext("device %s is already in use\n"), dcp->dc_device); break; + case EBADR: + /* ZFS pool is too fragmented to support a dump device */ + warn(gettext("device %s is too fragmented to be used as " + "a dump device\n"), dcp->dc_device); + break; default: /* * NOTE: The stmsboot(1M) command's boot-up script parses this @@ -447,6 +453,9 @@ dconf_update(dumpconf_t *dcp, int checkinuse) goto err; } + if ((error = zvol_check_dump_config( + dcp->dc_device)) > 0) + goto err; if (ioctl(dcp->dc_dump_fd, DIOCGETDUMPSIZE, &d) == -1) { warn(gettext("failed to get kernel dump size")); goto err; diff --git a/usr/src/cmd/power/Makefile b/usr/src/cmd/power/Makefile index 6fc647efc5..0af61cb3fb 100644 --- a/usr/src/cmd/power/Makefile +++ b/usr/src/cmd/power/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -60,7 +60,7 @@ POFILES= $(PMCFG_SRCS:%.c=%.po) OPOFILES= sysidpm.po # pmconfig only needs libdevinfo on sparc -sparc_LDEVINFO= -ldevinfo +sparc_LDEVINFO= -ldevinfo -lefi -ladm -lzfs -lnvpair i386_LDEVINFO= LDEVINFO= -ldevinfo diff --git a/usr/src/cmd/power/handlers.c b/usr/src/cmd/power/handlers.c index 3440d56389..f5fa621c0c 100644 --- a/usr/src/cmd/power/handlers.c +++ b/usr/src/cmd/power/handlers.c @@ -30,11 +30,14 @@ #include <sys/syslog.h> #include <sys/openpromio.h> #include <sys/mnttab.h> +#include <sys/vtoc.h> +#include <sys/efi_partition.h> #include <syslog.h> #include <stdlib.h> #include <sys/pm.h> #include <kstat.h> #include <sys/smbios.h> +#include <libzfs.h> #define STRCPYLIM(dst, src, str) strcpy_limit(dst, src, sizeof (dst), str) @@ -824,7 +827,6 @@ nfsreq(void) return (scan_int(LINEARG(1), &new_cc.nfsreqs_thold)); } - #ifdef sparc static char open_fmt[] = "cannot open \"%s\", %s\n"; @@ -838,6 +840,8 @@ check_mount(char *sfile, dev_t sfdev, int ufs) { char *src, *err_fmt = NULL, *mnttab = MNTTAB; int rgent, match = 0; + struct mnttab zroot = { 0 }; + struct mnttab entry; struct extmnttab ent; FILE *fp; @@ -846,6 +850,18 @@ check_mount(char *sfile, dev_t sfdev, int ufs) return (1); } + if (ufs) { + zroot.mnt_mountp = "/"; + zroot.mnt_fstype = "zfs"; + if (getmntany(fp, &entry, &zroot) == 0) { + err_fmt = "ufs statefile with zfs root is not" + " supported\n"; + mesg(MERR, err_fmt, sfile); + fclose(fp); + return (1); + } + resetmnttab(fp); + } /* * Search for a matching dev_t; * ignore non-ufs filesystems for a regular statefile. @@ -862,14 +878,13 @@ check_mount(char *sfile, dev_t sfdev, int ufs) break; } } - (void) fclose(fp); /* * No match is needed for a block device statefile, * a match is needed for a regular statefile. */ if (match == 0) { - if (new_cc.cf_type == CFT_SPEC) + if (new_cc.cf_type != CFT_UFS) STRCPYLIM(new_cc.cf_devfs, sfile, "block statefile"); else err_fmt = "cannot find ufs mount point for \"%s\"\n"; @@ -882,6 +897,7 @@ check_mount(char *sfile, dev_t sfdev, int ufs) STRCPYLIM(new_cc.cf_path, src, "statefile path"); } else err_fmt = "statefile device \"%s\" is a mounted filesystem\n"; + (void) fclose(fp); if (err_fmt) mesg(MERR, err_fmt, sfile); return (err_fmt != NULL); @@ -893,7 +909,7 @@ check_mount(char *sfile, dev_t sfdev, int ufs) * log any ioctl/conversion error. */ static int -utop(void) +utop(char *fs_name, char *prom_name) { union obpbuf { char buf[OBP_MAXPATHLEN + sizeof (uint_t)]; @@ -911,23 +927,132 @@ utop(void) opp = &oppbuf.oppio; opp->oprom_size = OBP_MAXPATHLEN; - strcpy_limit(opp->oprom_array, new_cc.cf_devfs, + strcpy_limit(opp->oprom_array, fs_name, OBP_MAXPATHLEN, "statefile device"); upval = ioctl(fd, OPROMDEV2PROMNAME, opp); (void) close(fd); - if (upval == OKUP) - STRCPYLIM(new_cc.cf_dev_prom, opp->oprom_array, "prom device"); - else { + if (upval == OKUP) { + strcpy_limit(prom_name, opp->oprom_array, OBP_MAXPATHLEN, + "prom device"); + } else { openlog("pmconfig", 0, LOG_DAEMON); syslog(LOG_NOTICE, gettext("cannot convert \"%s\" to prom device"), - new_cc.cf_devfs); + fs_name); closelog(); } return (upval); } +/* + * given the path to a zvol, return the cXtYdZ name + * returns < 0 on error, 0 if it isn't a zvol, > 1 on success + */ +static int +ztop(char *arg, char *diskname) +{ + zpool_handle_t *zpool_handle; + nvlist_t *config, *nvroot; + nvlist_t **child; + uint_t children; + libzfs_handle_t *lzfs; + char *vname; + char *p; + char pool_name[MAXPATHLEN]; + + if (strncmp(arg, "/dev/zvol/dsk/", 14)) { + return (0); + } + arg += 14; + strncpy(pool_name, arg, MAXPATHLEN); + if (p = strchr(pool_name, '/')) + *p = '\0'; + STRCPYLIM(new_cc.cf_fs, p + 1, "statefile path"); + + if ((lzfs = libzfs_init()) == NULL) { + mesg(MERR, "failed to initialize ZFS library\n"); + return (-1); + } + if ((zpool_handle = zpool_open(lzfs, pool_name)) == NULL) { + mesg(MERR, "couldn't open pool '%s'\n", pool_name); + libzfs_fini(lzfs); + return (-1); + } + config = zpool_get_config(zpool_handle, NULL); + if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, + &nvroot) != 0) { + zpool_close(zpool_handle); + libzfs_fini(lzfs); + return (-1); + } + verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, + &child, &children) == 0); + if (children != 1) { + mesg(MERR, "expected one vdev, got %d\n", children); + zpool_close(zpool_handle); + libzfs_fini(lzfs); + return (-1); + } + vname = zpool_vdev_name(lzfs, zpool_handle, child[0]); + if (vname == NULL) { + mesg(MERR, "couldn't determine vdev name\n"); + zpool_close(zpool_handle); + libzfs_fini(lzfs); + return (-1); + } + strcpy(diskname, "/dev/dsk/"); + strcat(diskname, vname); + free(vname); + zpool_close(zpool_handle); + libzfs_fini(lzfs); + return (1); +} + +/* + * returns NULL if the slice is good (e.g. does not start at block + * zero, or a string describing the error if it doesn't + */ +static boolean_t +is_good_slice(char *sfile, char **err) +{ + int fd, rc; + struct vtoc vtoc; + dk_gpt_t *gpt; + char rdskname[MAXPATHLEN]; + char *x, *y; + + *err = NULL; + /* convert from dsk to rdsk */ + STRCPYLIM(rdskname, sfile, "disk name"); + x = strstr(rdskname, "dsk/"); + y = strstr(sfile, "dsk/"); + if (x != NULL) { + *x++ = 'r'; + strcpy(x, y); + } + + if ((fd = open(rdskname, O_RDONLY)) == -1) { + *err = "could not open '%s'\n"; + } else if ((rc = read_vtoc(fd, &vtoc)) >= 0) { + /* + * we got a slice number; now check the block + * number where the slice starts + */ + if (vtoc.v_part[rc].p_start < 2) + *err = "using '%s' would clobber the disk label\n"; + close(fd); + return (*err ? B_FALSE : B_TRUE); + } else if ((rc == VT_ENOTSUP) && + (efi_alloc_and_read(fd, &gpt)) >= 0) { + /* EFI slices don't clobber the disk label */ + free(gpt); + close(fd); + return (B_TRUE); + } else + *err = "could not read partition table from '%s'\n"; + return (B_FALSE); +} /* * Check for a valid statefile pathname, inode and mount status. @@ -938,6 +1063,7 @@ sfpath(void) static int statefile; char *err_fmt = NULL; char *sfile, *sp, ch; + char diskname[256]; struct stat stbuf; int dir = 0; dev_t dev; @@ -991,12 +1117,20 @@ sfpath(void) new_cc.cf_type = CFT_UFS; dev = stbuf.st_dev; } else if (S_ISBLK(stbuf.st_mode)) { - if (minor(stbuf.st_rdev) != 2) { - new_cc.cf_type = CFT_SPEC; + if (is_good_slice(sfile, &err_fmt)) { + switch (ztop(sfile, diskname)) { + case 1: + new_cc.cf_type = CFT_ZVOL; + break; + case 0: + new_cc.cf_type = CFT_SPEC; + break; + case -1: + default: + return (NOUP); + } dev = stbuf.st_rdev; - } else - err_fmt = "statefile device cannot be slice 2 (%s)\n" - "would clobber the disk label and boot-block\n"; + } } else err_fmt = "bad file type for \"%s\"\n" "statefile must be a regular file or block device\n"; @@ -1004,9 +1138,14 @@ sfpath(void) mesg(MERR, err_fmt, sfile); return (NOUP); } - - if (check_mount(sfile, dev, (new_cc.cf_type == CFT_UFS)) || utop()) + if (check_mount(sfile, dev, (new_cc.cf_type == CFT_UFS))) return (NOUP); + if (new_cc.cf_type == CFT_ZVOL) { + if (utop(diskname, new_cc.cf_dev_prom)) + return (NOUP); + } else if (utop(new_cc.cf_devfs, new_cc.cf_dev_prom)) { + return (NOUP); + } new_cc.cf_magic = CPR_CONFIG_MAGIC; statefile = 1; return (OKUP); diff --git a/usr/src/cmd/power/svc-power b/usr/src/cmd/power/svc-power index 5fabb0b67f..bfef70d7e9 100644 --- a/usr/src/cmd/power/svc-power +++ b/usr/src/cmd/power/svc-power @@ -66,6 +66,19 @@ init_statefile_entry() { return ) + if [ $max_avail -eq 0 ]; then + if [ X`df -n / | awk '{print $3}'` != "Xzfs" ] ; then + return + fi + rootpool=`zfs mount | grep ' \/$' | awk '{print $1 }' |\ + sed 's/\/.*$//'` + if [ X$rootpool = "X" ] || \ + [ ! -L /dev/zvol/dsk/$rootpool/dump ]; then + return + fi + echo "statefile /dev/zvol/dsk/$rootpool/dump" \ + >> /etc/power.conf + fi } case "$1" in diff --git a/usr/src/cmd/svc/milestone/fs-minimal b/usr/src/cmd/svc/milestone/fs-minimal index 6a7141fa1a..ff7cea8a20 100644 --- a/usr/src/cmd/svc/milestone/fs-minimal +++ b/usr/src/cmd/svc/milestone/fs-minimal @@ -58,7 +58,7 @@ for fs in /var /var/adm /tmp; do mountpt=`zfs get -H -o value mountpoint $be$fs 2>/dev/null` if [ $? = 0 ] ; then if [ "x$mountpt" = "x$fs" ] ; then - /sbin/zfs mount $be$fs + /sbin/zfs mount -O $be$fs fi fi fi diff --git a/usr/src/cmd/svc/milestone/fs-usr b/usr/src/cmd/svc/milestone/fs-usr index f4a75e08f9..72f906e82e 100644 --- a/usr/src/cmd/svc/milestone/fs-usr +++ b/usr/src/cmd/svc/milestone/fs-usr @@ -33,18 +33,49 @@ . /lib/svc/share/fs_include.sh # -# Add physical swap. +# Once root is read/write we can enable the dedicated dumpdevice if it exists +# locally. This is an optimization as svc-dumpadm will attempt do this later. # -/sbin/swapadd -1 +dump_setup() +{ + [ -r /etc/dumpadm.conf ] && . /etc/dumpadm.conf + + readswapdev $DUMPADM_DEVICE < $vfstab + + # + # If we have a dedicated dump device, then go ahead and configure it. + # + if [ "x$special" != "x$DUMPADM_DEVICE" ]; then + if [ -x /usr/sbin/zfs ]; then + dataset=`echo $DUMPADM_DEVICE | cut -d'/' -f5-` + [ -n "$dataset" ] && \ + /usr/sbin/zfs list -t volume $dataset > \ + /dev/null 2>&1 + if [ $? -eq 0 ]; then + /usr/sbin/zfs volinit + fi + fi + + if [ -x /usr/sbin/dumpadm -a -b $DUMPADM_DEVICE ]; then + /usr/sbin/dumpadm -u || exit $SMF_EXIT_ERR_CONFIG + fi + fi +} rootiszfs=0 # get the fstype of root readmnttab / </etc/mnttab if [ "$fstype" = zfs ] ; then rootiszfs=1 + dump_setup fi # +# Add physical swap. +# +/sbin/swapadd -1 + +# # Check and remount the / (root) file system. # For NFS mounts, force the llock option on. # diff --git a/usr/src/cmd/svc/shell/fs_include.sh b/usr/src/cmd/svc/shell/fs_include.sh index 7ab7dfdd3e..99810383cc 100644 --- a/usr/src/cmd/svc/shell/fs_include.sh +++ b/usr/src/cmd/svc/shell/fs_include.sh @@ -72,6 +72,19 @@ readvfstab() { done } +readswapdev() { + while read special fsckdev mountp fstype fsckpass automnt mntopts; do + # Ignore comments, empty lines, and no-action lines + case "$special" in + '#'* | '' | '-') continue;; + esac + + [ "$fstype" != swap ] && continue + + [ "x$special" = "x$1" ] && break + done +} + # # readmnttab mount_point # -> (special, mountp, fstype, mntopts, mnttime) diff --git a/usr/src/cmd/swap/swap.c b/usr/src/cmd/swap/swap.c index a38897f70c..91cecd5cb4 100644 --- a/usr/src/cmd/swap/swap.c +++ b/usr/src/cmd/swap/swap.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -63,6 +63,7 @@ #include <locale.h> #include <libintl.h> #include <libdiskmgt.h> +#include <sys/fs/zfs.h> #define LFLAG 0x01 /* swap -l (list swap devices) */ #define DFLAG 0x02 /* swap -d (delete swap device) */ @@ -645,6 +646,19 @@ add(char *path, off_t offset, off_t cnt, int flags) (void) close(fd); + /* + * zvols cannot act as both a swap device and dump device. + */ + if (strncmp(dumpdev, ZVOL_FULL_DEV_DIR, + strlen(ZVOL_FULL_DEV_DIR)) == 0) { + if (strcmp(dumpdev, path) == 0) { + (void) fprintf(stderr, gettext("%s: zvol " + "cannot be used as a swap device and a " + "dump device\n"), path); + return (2); + } + } + } else if (!(flags & P1FLAG)) dumpadm_err(gettext("Warning: failed to open /dev/dump")); diff --git a/usr/src/cmd/zdb/zdb.c b/usr/src/cmd/zdb/zdb.c index 7108c36883..139aa5dd0d 100644 --- a/usr/src/cmd/zdb/zdb.c +++ b/usr/src/cmd/zdb/zdb.c @@ -95,7 +95,7 @@ usage(void) "dataset [object...]\n" " %s -C [pool]\n" " %s -l dev\n" - " %s -R vdev:offset:size:flags\n" + " %s -R pool:vdev:offset:size:flags\n" " %s [-p path_to_vdev_dir]\n" " %s -e pool | GUID | devid ...\n", cmdname, cmdname, cmdname, cmdname, cmdname, cmdname); @@ -1117,7 +1117,6 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) static char *objset_types[DMU_OST_NUMTYPES] = { "NONE", "META", "ZPL", "ZVOL", "OTHER", "ANY" }; -/*ARGSUSED*/ static void dump_dir(objset_t *os) { |