diff options
Diffstat (limited to 'usr/src')
39 files changed, 1148 insertions, 203 deletions
diff --git a/usr/src/cmd/dumpadm/Makefile b/usr/src/cmd/dumpadm/Makefile index 64084c9094..108a0f9fe4 100644 --- a/usr/src/cmd/dumpadm/Makefile +++ b/usr/src/cmd/dumpadm/Makefile @@ -20,7 +20,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -32,6 +32,7 @@ SVCMETHOD= svc-dumpadm OBJS = main.o dconf.o minfree.o utils.o swap.o SRCS = $(OBJS:.o=.c) + lint := LINTFLAGS = -mx include ../Makefile.cmd @@ -45,6 +46,8 @@ GROUP = bin ROOTMANIFESTDIR = $(ROOTSVCSYSTEM) $(ROOTMANIFEST) := FILEMODE = 0444 +LDLIBS += -ldiskmgt + .KEEP_STATE: all: $(PROG) diff --git a/usr/src/cmd/dumpadm/dconf.c b/usr/src/cmd/dumpadm/dconf.c index a67f1a55ec..ec287078d7 100644 --- a/usr/src/cmd/dumpadm/dconf.c +++ b/usr/src/cmd/dumpadm/dconf.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,6 +38,7 @@ #include <stdio.h> #include <fcntl.h> #include <errno.h> +#include <libdiskmgt.h> #include "dconf.h" #include "minfree.h" @@ -50,6 +51,7 @@ typedef struct dc_token { int (*tok_print)(const dumpconf_t *, FILE *); } dc_token_t; + static int print_device(const dumpconf_t *, FILE *); static int print_savdir(const dumpconf_t *, FILE *); static int print_content(const dumpconf_t *, FILE *); @@ -344,9 +346,25 @@ dconf_dev_ioctl(dumpconf_t *dcp, int cmd) } int -dconf_update(dumpconf_t *dcp) +dconf_update(dumpconf_t *dcp, int checkinuse) { - int oconf; + int oconf; + int error; + char *msg; + + error = 0; + + if (checkinuse && (dm_inuse(dcp->dc_device, &msg, DM_WHO_DUMP, + &error) || error)) { + if (error != 0) { + warn(gettext("failed to determine if %s is" + " in use"), dcp->dc_device); + } else { + warn(msg); + free(msg); + return (-1); + } + } /* * Save the existing dump configuration in case something goes wrong. diff --git a/usr/src/cmd/dumpadm/dconf.h b/usr/src/cmd/dumpadm/dconf.h index 0a35bc9217..b22488ec2a 100644 --- a/usr/src/cmd/dumpadm/dconf.h +++ b/usr/src/cmd/dumpadm/dconf.h @@ -20,8 +20,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #ifndef _DCONF_H @@ -64,7 +64,7 @@ extern int dconf_open(dumpconf_t *, const char *, const char *, int); extern int dconf_getdev(dumpconf_t *); extern int dconf_close(dumpconf_t *); extern int dconf_write(dumpconf_t *); -extern int dconf_update(dumpconf_t *); +extern int dconf_update(dumpconf_t *, int); extern void dconf_print(dumpconf_t *, FILE *); extern int dconf_str2device(dumpconf_t *, char *); diff --git a/usr/src/cmd/dumpadm/main.c b/usr/src/cmd/dumpadm/main.c index e6c8c45f6d..a1255a7ae6 100644 --- a/usr/src/cmd/dumpadm/main.c +++ b/usr/src/cmd/dumpadm/main.c @@ -20,8 +20,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1998-2000 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -53,7 +53,7 @@ main(int argc, char *argv[]) u_longlong_t minf; struct stat st; int c; - + int dflag = 0; /* for checking in use during -d ops */ int dcmode = DC_CURRENT; /* kernel settings override unless -u */ int modified = 0; /* have we modified the dump config? */ char *minfstr = NULL; /* string value of -m argument */ @@ -116,10 +116,10 @@ main(int argc, char *argv[]) return (E_USAGE); modified++; break; - case 'd': if (dconf_str2device(&dc, optarg) == -1) return (E_USAGE); + dflag++; modified++; break; @@ -166,7 +166,7 @@ main(int argc, char *argv[]) * fails, we re-load the kernel configuration and write that * out to the file in order to force the file in sync. */ - if (dconf_update(&dc) == -1) + if (dconf_update(&dc, 0) == -1) (void) dconf_getdev(&dc); if (dconf_write(&dc) == -1) return (E_ERROR); @@ -176,7 +176,8 @@ main(int argc, char *argv[]) * If we're modifying the configuration, then try * to update it, and write out the file if successful. */ - if (dconf_update(&dc) == -1 || dconf_write(&dc) == -1) + if (dconf_update(&dc, dflag) == -1 || + dconf_write(&dc) == -1) return (E_ERROR); } diff --git a/usr/src/cmd/format/Makefile b/usr/src/cmd/format/Makefile index bcc9f27f91..72ab8f3888 100644 --- a/usr/src/cmd/format/Makefile +++ b/usr/src/cmd/format/Makefile @@ -20,7 +20,7 @@ # CDDL HEADER END # # -# Copyright 1991-1997,2002,2003 Sun Microsystems, Inc. All rights reserved. +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -28,7 +28,7 @@ PROG= format -COBJS= add_definition.o analyze.o checkmount.o ctlr_scsi.o \ +COBJS= add_definition.o analyze.o checkdev.o ctlr_scsi.o \ defect.o init_menus.o io.o label.o main.o \ menu.o menu_analyze.o menu_cache.o menu_command.o menu_defect.o \ menu_partition.o misc.o modify_partition.o partition.o \ @@ -56,7 +56,7 @@ $(ROOTETCDATA) := FILEMODE = 0644 $(ROOTETCDATA) := OWNER = root $(ROOTETCDATA) := GROUP = sys -LDLIBS += -ladm -lefi +LDLIBS += -ladm -lefi -ldiskmgt -lnvpair .KEEP_STATE: diff --git a/usr/src/cmd/format/analyze.c b/usr/src/cmd/format/analyze.c index 1980e23a67..3a8499a077 100644 --- a/usr/src/cmd/format/analyze.c +++ b/usr/src/cmd/format/analyze.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 1998-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -37,7 +37,7 @@ #include "defect.h" #include "label.h" #include "param.h" -#include "checkmount.h" +#include "checkdev.h" /* diff --git a/usr/src/cmd/format/checkmount.c b/usr/src/cmd/format/checkdev.c index 22079abacb..8310abe09c 100644 --- a/usr/src/cmd/format/checkmount.c +++ b/usr/src/cmd/format/checkdev.c @@ -20,17 +20,18 @@ * CDDL HEADER END */ /* - * Copyright 1991-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ + #pragma ident "%Z%%M% %I% %E% SMI" /* - * This file contians miscellaneous routines. + * This file contains miscellaneous device validation routines. */ -#include "global.h" +#include "global.h" #include <sys/mnttab.h> #include <sys/mntent.h> #include <sys/autoconf.h> @@ -47,26 +48,30 @@ #include <sys/swap.h> #include <sys/sysmacros.h> #include <ctype.h> +#include <libdiskmgt.h> +#include <libnvpair.h> #include "misc.h" -#include "checkmount.h" +#include "checkdev.h" /* Function prototypes */ #ifdef __STDC__ -static struct swaptable *getswapentries(void); -static void freeswapentries(struct swaptable *); +static struct swaptable *getswapentries(void); +static void freeswapentries(struct swaptable *); static int getpartition(char *pathname); -static int checkpartitions(int mounted); +static int checkpartitions(int bm_mounted); #else /* __STDC__ */ static struct swaptable *getswapentries(); static void freeswapentries(); static int getpartition(); -static int checkpartitions(); +static int checkpartitions(); #endif /* __STDC__ */ +extern char *getfullname(); + static struct swaptable * getswapentries(void) { @@ -256,7 +261,246 @@ checkswap(start, end) } +/* + * Determines if there are partitions that are a part of an SVM, VxVM, zpool + * volume or a live upgrade device, overlapping a given portion of a disk. + * Mounts and swap devices are checked in legacy format code. + */ +int +checkdevinuse(char *cur_disk_path, diskaddr_t start, diskaddr_t end, int print, + int check_label) +{ + + int error; + int found = 0; + int check = 0; + int i; + int bm_inuse = 0; + int part = 0; + uint64_t slice_start, slice_size; + dm_descriptor_t *slices = NULL; + nvlist_t *attrs = NULL; + char *usage; + char *name; + + /* + * For format, we get basic 'in use' details from libdiskmgt. After + * that we must do the appropriate checking to see if the 'in use' + * details require a bit of additional work. + */ + + dm_get_slices(cur_disk_path, &slices, &error); + if (error) { + err_print("Error occurred with device in use checking: %s\n", + strerror(error)); + return (found); + } + if (slices == NULL) + return (found); + + for (i = 0; slices[i] != NULL; i++) { + /* + * If we are checking the whole disk + * then any and all in use data is + * relevant. + */ + if (start == UINT_MAX64) { + name = dm_get_name(slices[i], &error); + if (error != 0 || !name) { + err_print("Error occurred with device " + "in use checking: %s\n", + strerror(error)); + continue; + } + if (dm_inuse(name, &usage, DM_WHO_FORMAT, &error) || + error) { + if (error != 0) { + dm_free_name(name); + name = NULL; + err_print("Error occurred with device " + "in use checking: %s\n", + strerror(error)); + continue; + } + dm_free_name(name); + name = NULL; + /* + * If this is a dump device, then it is + * a failure. You cannot format a slice + * that is a dedicated dump device. + */ + + if (strstr(usage, DM_USE_DUMP)) { + if (print) { + err_print(usage); + free(usage); + } + dm_free_descriptors(slices); + return (1); + } + /* + * We really found a device that is in use. + * Set 'found' for the return value, and set + * 'check' to indicate below that we must + * get the partition number to set bm_inuse + * in the event we are trying to label this + * device. check_label is set when we are + * checking modifications for in use slices + * on the device. + */ + found ++; + check = 1; + if (print) { + err_print(usage); + free(usage); + } + } + } else { + /* + * Before getting the in use data, verify that the + * current slice is within the range we are checking. + */ + attrs = dm_get_attributes(slices[i], &error); + if (error) { + err_print("Error occurred with device in use " + "checking: %s\n", strerror(error)); + continue; + } + if (attrs == NULL) { + continue; + } + (void) nvlist_lookup_uint64(attrs, DM_START, + &slice_start); + (void) nvlist_lookup_uint64(attrs, DM_SIZE, + &slice_size); + if (start >= (slice_start + slice_size) || + (end < slice_start)) { + nvlist_free(attrs); + attrs = NULL; + continue; + } + name = dm_get_name(slices[i], &error); + if (error != 0 || !name) { + err_print("Error occurred with device " + "in use checking: %s\n", + strerror(error)); + nvlist_free(attrs); + attrs = NULL; + continue; + } + if (dm_inuse(name, &usage, + DM_WHO_FORMAT, &error) || error) { + if (error != 0) { + dm_free_name(name); + name = NULL; + err_print("Error occurred with device " + "in use checking: %s\n", + strerror(error)); + nvlist_free(attrs); + attrs = NULL; + continue; + } + dm_free_name(name); + name = NULL; + /* + * If this is a dump device, then it is + * a failure. You cannot format a slice + * that is a dedicated dump device. + */ + if (strstr(usage, DM_USE_DUMP)) { + if (print) { + err_print(usage); + free(usage); + } + dm_free_descriptors(slices); + nvlist_free(attrs); + return (1); + } + /* + * We really found a device that is in use. + * Set 'found' for the return value, and set + * 'check' to indicate below that we must + * get the partition number to set bm_inuse + * in the event we are trying to label this + * device. check_label is set when we are + * checking modifications for in use slices + * on the device. + */ + found ++; + check = 1; + if (print) { + err_print(usage); + free(usage); + } + } + } + /* + * If check is set it means we found a slice(the current slice) + * on this device in use in some way. We potentially want + * to check this slice when labeling is + * requested. We set bm_inuse with this partition value + * for use later if check_label was set when called. + */ + if (check) { + name = dm_get_name(slices[i], &error); + if (error != 0 || !name) { + err_print("Error occurred with device " + "in use checking: %s\n", + strerror(error)); + nvlist_free(attrs); + attrs = NULL; + continue; + } + part = getpartition(name); + dm_free_name(name); + name = NULL; + if (part != -1) { + bm_inuse |= 1 << part; + } + check = 0; + } + /* + * If we have attributes then we have successfully + * found the slice we were looking for and we also + * know this means we are not searching the whole + * disk so break out of the loop + * now. + */ + if (attrs) { + nvlist_free(attrs); + break; + } + } + + if (slices) { + dm_free_descriptors(slices); + } + + /* + * The user is trying to label the disk. We have to do special + * checking here to ensure they are not trying to modify a slice + * that is in use in an incompatible way. + */ + if (check_label && bm_inuse) { + /* + * !0 indicates that we found a + * problem. In this case, we have overloaded + * the use of checkpartitions to work for + * in use devices. bm_inuse is representative + * of the slice that is in use, not that + * is mounted as is in the case of the normal + * use of checkpartitions. + * + * The call to checkpartitions will return !0 if + * we are trying to shrink a device that we have found + * to be in use above. + */ + return (checkpartitions(bm_inuse)); + } + + return (found); +} /* * This routine checks to see if there are mounted partitions overlapping * a given portion of a disk. If the start parameter is < 0, it means @@ -432,13 +676,11 @@ check_label_with_mount() } /* - * This Routine checks if any partitions specified by the - * bit-map of mounted/swap partitions are affected by - * writing the new label + * This Routine checks if any partitions specified + * are affected by writing the new label */ static int -checkpartitions(bm_mounted) -int bm_mounted; +checkpartitions(int bm_mounted) { struct dk_map32 *n; struct dk_map *o; diff --git a/usr/src/cmd/format/checkmount.h b/usr/src/cmd/format/checkdev.h index 75605d5671..8e4910d8b3 100644 --- a/usr/src/cmd/format/checkmount.h +++ b/usr/src/cmd/format/checkdev.h @@ -20,12 +20,12 @@ * CDDL HEADER END */ /* - * Copyright 1991-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#ifndef _CHECKMOUNT_H -#define _CHECKMOUNT_H +#ifndef _CHECKDEV_H +#define _CHECKDEV_H #pragma ident "%Z%%M% %I% %E% SMI" @@ -33,7 +33,6 @@ extern "C" { #endif - /* * Prototypes for ANSI C */ @@ -41,10 +40,12 @@ int checkmount(diskaddr_t start, diskaddr_t end); int checkswap(diskaddr_t start, diskaddr_t end); int check_label_with_mount(void); int check_label_with_swap(void); +int checkdevinuse(char *cur_disk_path, diskaddr_t start, diskaddr_t end, + int print, int check_label); #ifdef __cplusplus } #endif -#endif /* _CHECKMOUNT_H */ +#endif /* _CHECKDEV_H */ diff --git a/usr/src/cmd/format/disk_generic.c b/usr/src/cmd/format/disk_generic.c index 7269a2cb9b..5c06688745 100644 --- a/usr/src/cmd/format/disk_generic.c +++ b/usr/src/cmd/format/disk_generic.c @@ -20,8 +20,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1998-2001 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -57,7 +57,7 @@ #include "startup.h" #include "partition.h" #include "prompts.h" -#include "checkmount.h" +#include "checkdev.h" #include "io.h" #include "ctlr_scsi.h" #include "auto_sense.h" diff --git a/usr/src/cmd/format/main.c b/usr/src/cmd/format/main.c index 242fc7bb6d..79735841a5 100644 --- a/usr/src/cmd/format/main.c +++ b/usr/src/cmd/format/main.c @@ -25,7 +25,6 @@ */ #pragma ident "%Z%%M% %I% %E% SMI" - /* * This file contains the main entry point of the program and other * routines relating to the general flow. @@ -54,7 +53,7 @@ #include "menu_command.h" #include "menu_partition.h" #include "prompts.h" -#include "checkmount.h" +#include "checkdev.h" #include "label.h" extern struct menu_item menu_command[]; @@ -541,6 +540,13 @@ Continue")) err_print("Warning: Current Disk has mounted partitions.\n"); /* + * If any part of this device is also part of an SVM, VxVM or + * Live Upgrade device, print a warning. + */ + (void) checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1, + (diskaddr_t)-1, 1, 0); + + /* * Get the Solaris Fdisk Partition information */ (void) copy_solaris_part(&cur_disk->fdisk_part); diff --git a/usr/src/cmd/format/menu_cache.c b/usr/src/cmd/format/menu_cache.c index 1d824b2943..b903b3e4e7 100644 --- a/usr/src/cmd/format/menu_cache.c +++ b/usr/src/cmd/format/menu_cache.c @@ -21,7 +21,8 @@ */ /* - * Copyright (c) 1999-2001 by Sun Microsystems, Inc. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -50,7 +51,7 @@ #include "startup.h" #include "partition.h" #include "prompts.h" -#include "checkmount.h" +#include "checkdev.h" #include "io.h" #include "ctlr_scsi.h" #include "auto_sense.h" diff --git a/usr/src/cmd/format/menu_command.c b/usr/src/cmd/format/menu_command.c index b679017d7d..e570d07dcb 100644 --- a/usr/src/cmd/format/menu_command.c +++ b/usr/src/cmd/format/menu_command.c @@ -56,7 +56,7 @@ #include "startup.h" #include "partition.h" #include "prompts.h" -#include "checkmount.h" +#include "checkdev.h" #include "io.h" #include "ctlr_scsi.h" #include "auto_sense.h" @@ -607,6 +607,18 @@ c_type() currently being used for swapping.\n"); return (-1); } + + /* + * Check for partitions being used in SVM, VxVM or LU devices + */ + + if ((tptr != oldtype) && + checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1, + (diskaddr_t)-1, 0, 0)) { + err_print("Cannot set disk type while its " + "partitions are currently in use.\n"); + return (-1); + } /* * If the type selected is different from the previous type, * mark the disk as not labelled and reload the current @@ -748,7 +760,6 @@ c_current() fmt_print("\n"); return (0); } - /* * This routine implements the 'format' command. It allows the user * to format and verify any portion of the disk. @@ -757,11 +768,11 @@ int c_format() { diskaddr_t start, end; - time_t clock; - int format_time, format_tracks, format_cyls; - int format_interval; - int deflt, status; - u_ioparam_t ioparam; + time_t clock; + int format_time, format_tracks, format_cyls; + int format_interval; + int deflt, status; + u_ioparam_t ioparam; /* * There must be a current disk type and a current disk @@ -857,6 +868,16 @@ c_format() currently being used for swapping.\n"); return (-1); } + /* + * Check for partitions being used in SVM, VxVM or LU devices + * in this format zone + */ + if (checkdevinuse(cur_disk->disk_name, start, end, 0, 0)) { + err_print("Cannot format disk while its partitions " + "are currently in use.\n"); + return (-1); + } + if (SCSI && (format_time = scsi_format_time()) > 0) { fmt_print( "Ready to format. Formatting cannot be interrupted\n" @@ -1118,6 +1139,12 @@ being used for swapping.\ncontinue")) return (-1); } + if (checkdevinuse(cur_disk->disk_name, bn, bn, 0, 0)) { + if (check("Repair is in a partition which is currently " + "in use.\ncontinue")) + return (-1); + } + /* * Try to read the sector before repairing it. If we can * get good data out of it, we can write that data back @@ -1288,8 +1315,8 @@ c_show() int c_label() { - int status; - int deflt, *defltptr = NULL; + int status; + int deflt, *defltptr = NULL; /* * There must be a current disk type (and therefore a current disk). @@ -1341,6 +1368,17 @@ c_label() } } + /* + * Check to see if any partitions used for svm, vxvm or live upgrade + * are on the disk. If so, refuse to label the disk, but only + * if we are trying to shrink a partition in use. + */ + if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1, + (diskaddr_t)-1, 0, 1)) { + err_print("Cannot label disk when " + "partitions are in use as described.\n"); + return (-1); + } /* * If there is not a current partition map, warn the user we diff --git a/usr/src/cmd/format/menu_developer.c b/usr/src/cmd/format/menu_developer.c index c7a303466d..5ed1b23ff1 100644 --- a/usr/src/cmd/format/menu_developer.c +++ b/usr/src/cmd/format/menu_developer.c @@ -21,7 +21,8 @@ */ /* - * Copyright (c) 1993-2001 by Sun Microsystems, Inc. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -50,7 +51,7 @@ #include "startup.h" #include "partition.h" #include "prompts.h" -#include "checkmount.h" +#include "checkdev.h" #include "io.h" #include "ctlr_scsi.h" #include "auto_sense.h" diff --git a/usr/src/cmd/format/menu_fdisk.c b/usr/src/cmd/format/menu_fdisk.c index e7bdbd4506..f0642d2dea 100644 --- a/usr/src/cmd/format/menu_fdisk.c +++ b/usr/src/cmd/format/menu_fdisk.c @@ -55,7 +55,7 @@ #include "startup.h" #include "partition.h" #include "prompts.h" -#include "checkmount.h" +#include "checkdev.h" #include "io.h" #include "ctlr_scsi.h" #include "auto_sense.h" diff --git a/usr/src/cmd/format/menu_scsi.c b/usr/src/cmd/format/menu_scsi.c index 3d8ddfdd0a..31e3406143 100644 --- a/usr/src/cmd/format/menu_scsi.c +++ b/usr/src/cmd/format/menu_scsi.c @@ -21,7 +21,7 @@ */ /* - * Copyright 1991-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -45,7 +45,7 @@ #include "menu_scsi.h" #include "ctlr_scsi.h" #include "startup.h" -#include "checkmount.h" +#include "checkdev.h" #ifdef __STDC__ @@ -565,6 +565,15 @@ do_format() currently being used for swapping.\n\n"); return (-1); } + /* + * Are any being used for SVM, VxVM or live upgrade. + */ + if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1, + (diskaddr_t)-1, 0, 0)) { + err_print("Cannot format disk while its partitions are " + "currently being used as described.\n"); + return (-1); + } /* * Let the user choose between formatting with either diff --git a/usr/src/cmd/format/modify_partition.c b/usr/src/cmd/format/modify_partition.c index 375e8dbf43..497d05a1f6 100644 --- a/usr/src/cmd/format/modify_partition.c +++ b/usr/src/cmd/format/modify_partition.c @@ -34,7 +34,7 @@ #include "menu_partition.h" #include "menu_command.h" #include "modify_partition.h" -#include "checkmount.h" +#include "checkdev.h" #include "misc.h" #include "label.h" #include "auto_sense.h" diff --git a/usr/src/cmd/fs.d/Makefile b/usr/src/cmd/fs.d/Makefile index 6e73bf7714..38039de5ab 100644 --- a/usr/src/cmd/fs.d/Makefile +++ b/usr/src/cmd/fs.d/Makefile @@ -153,7 +153,7 @@ umount: umount.o $(FSLIB) $(POST_PROCESS) $(SPPROG): switchout.o deffs.o fssnapsup.o - $(LINK.c) -o $@ switchout.o deffs.o fssnapsup.o $(LDLIBS) + $(LINK.c) -o $@ switchout.o deffs.o fssnapsup.o $(LDLIBS) -ldiskmgt $(POST_PROCESS) install: $(FSLIB) .WAIT $(SUBDIRS) .WAIT install_local diff --git a/usr/src/cmd/fs.d/switchout.c b/usr/src/cmd/fs.d/switchout.c index 7777382c10..2870df7b6b 100644 --- a/usr/src/cmd/fs.d/switchout.c +++ b/usr/src/cmd/fs.d/switchout.c @@ -24,7 +24,7 @@ /* - * Copyright 1996-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -41,6 +41,11 @@ #include <sys/stat.h> #include <fcntl.h> #include <string.h> +#include <libdiskmgt.h> +#include "fslib.h" + + +static int match(char **opts, char *s); #define FSTYPE_MAX 8 #define ARGV_MAX 1024 @@ -117,13 +122,18 @@ char *argv[]; char *vfs_path = VFS_PATH; char *alt_path = ALT_PATH; int i; + int j; int verbose = 0; /* set if -V is specified */ int F_flg = 0; int mflag = 0; + int Nflag = 0; char *oopts = NULL; + char *tmpopts = NULL; /* used for in use checking */ int iflag = 0; int usgflag = 0; int arg; /* argument from getopt() */ + char *msg; + int error; extern char *optarg; /* getopt specific */ extern int optind; extern int opterr; @@ -167,6 +177,10 @@ char *argv[]; newargv[newargc++] = "-o"; newargv[newargc++] = optarg; oopts = optarg; + if (!Nflag) { + tmpopts = optarg; + Nflag = has_Nflag(tmpopts); + } break; case '?': /* print usage message */ newargv[newargc++] = "-?"; @@ -192,14 +206,15 @@ char *argv[]; optarg = NULL; } if (F_flg > 1) { - fprintf(stderr, gettext("%s: more than one FSType specified\n"), - cbasename); + (void) fprintf(stderr, + gettext("%s: more than one FSType specified\n"), + cbasename); usage(cbasename, c_ptr->c_usgstr); exit(2); } if (fstype != NULL) { if (strlen(fstype) > FSTYPE_MAX) { - fprintf(stderr, + (void) fprintf(stderr, gettext("%s: FSType %s exceeds %d characters\n"), cbasename, fstype, FSTYPE_MAX); exit(2); @@ -224,18 +239,19 @@ char *argv[]; } if ((special == NULL) && (!usgflag)) { - fprintf(stderr, gettext("%s: special not specified\n"), + (void) fprintf(stderr, gettext("%s: special not specified\n"), cbasename); usage(cbasename, c_ptr->c_usgstr); exit(2); } + if ((fstype == NULL) && (usgflag)) usage(cbasename, c_ptr->c_usgstr); if (fstype == NULL) lookup(); if (fstype == NULL) { - fprintf(stderr, gettext("%s: FSType cannot be identified\n"), - cbasename); + (void) fprintf(stderr, + gettext("%s: FSType cannot be identified\n"), cbasename); usage(cbasename, c_ptr->c_usgstr); exit(2); } @@ -257,6 +273,29 @@ char *argv[]; } /* + * Prior to executing the command for mkfs check for device in use. + * If the mflag is set, user wants to see command that created + * an already existing filesystem. Do not check for in use in this + * case. If Nflag is set user wants to see what the parameters + * would be to create the filesystem. Do not check for in use in + * this case. + */ + if (strcmp(cbasename, "mkfs") == 0 && !mflag && !Nflag) { + if (dm_inuse(special, &msg, DM_WHO_MKFS, &error) || + error) { + if (error != 0) { + (void) fprintf(stderr, gettext("Error occurred" + " with device in use checking: %s\n"), + strerror(error)); + } else { + (void) fprintf(stderr, "%s", msg); + free(msg); + exit(2); + } + } + } + + /* * Execute the FSType specific command. */ execv(full_path, &newargv[1]); @@ -279,18 +318,18 @@ char *argv[]; } if (errno != ENOENT) { perror(cbasename); - fprintf(stderr, gettext("%s: cannot execute %s\n"), cbasename, - full_path); + (void) fprintf(stderr, gettext("%s: cannot execute %s\n"), + cbasename, full_path); exit(2); } if (sysfs(GETFSIND, fstype) == (-1)) { - fprintf(stderr, + (void) fprintf(stderr, gettext("%s: FSType %s not installed in the kernel\n"), cbasename, fstype); exit(2); } - fprintf(stderr, + (void) fprintf(stderr, gettext("%s: Operation not applicable for FSType %s \n"), cbasename, fstype); exit(2); @@ -301,9 +340,10 @@ char *cmd; char **usg; { int i; - fprintf(stderr, gettext("Usage:\n")); + (void) fprintf(stderr, gettext("Usage:\n")); for (i = 0; usg[i] != NULL; i++) - fprintf(stderr, "%s %s\n", gettext(cmd), gettext(usg[i])); + (void) fprintf(stderr, "%s %s\n", gettext(cmd), + gettext(usg[i])); exit(2); } @@ -323,7 +363,8 @@ lookup() struct vfstab vget, vref; if ((fd = fopen(vfstab, "r")) == NULL) { - fprintf(stderr, gettext("%s: cannot open vfstab\n"), cbasename); + (void) fprintf(stderr, gettext("%s: cannot open vfstab\n"), + cbasename); exit(1); } vfsnull(&vref); @@ -345,13 +386,13 @@ lookup() fstype = vget.vfs_fstype; break; case VFS_TOOLONG: - fprintf(stderr, + (void) fprintf(stderr, gettext("%s: line in vfstab exceeds %d characters\n"), cbasename, VFS_LINE_MAX-2); exit(1); break; case VFS_TOOFEW: - fprintf(stderr, + (void) fprintf(stderr, gettext("%s: line in vfstab has too few entries\n"), cbasename); exit(1); @@ -376,8 +417,9 @@ char *opts; if (errstr == NULL) errstr = gettext("Unknown error"); - fprintf(stderr, gettext("%s: %s: error %d: %s\n"), - cmd, mountpoint, en, errstr); + (void) fprintf(stderr, + gettext("%s: %s: error %d: %s\n"), + cmd, mountpoint, en, errstr); exit(2); } @@ -385,3 +427,55 @@ char *opts; } fssnap_show_status(mountpoint, opts, 1, (opts ? 0 : 1)); } +static int +has_Nflag(char *opts) +{ + while (opts != NULL && *opts != '\0') { + if (match(&opts, "N")) { + return (1); + } + if (!opts) + break; + if (*opts == ',') + opts ++; + if (*opts == ' ') + opts ++; + } + return (0); +} +/* + * Parses the -o [fs specific options string] to search for the UFS -N flag. + * Return the opts string pointing to the next position in the string if + * match is not found. A delimiter of , or ' ' can be used depending on the + * caller, newfs or mkfs. + */ +static int +match(char **opts, char *s) +{ + char *cs; + char *tmp_str; + + cs = *opts; + + while (*cs++ == *s) { + if (*s++ == '\0') { + goto true; + } + } + if (*s != '\0') { + /* + * If we cannot find the delimiter it means we + * have hit the end of the string. + */ + tmp_str = strchr(*opts, ','); + if (!tmp_str) + tmp_str = strchr(*opts, ' '); + + *opts = tmp_str; + return (0); + } +true: + cs--; + *opts = cs; + return (1); +} diff --git a/usr/src/cmd/swap/Makefile.com b/usr/src/cmd/swap/Makefile.com index a2e5cf53a4..c5d4e75ef6 100644 --- a/usr/src/cmd/swap/Makefile.com +++ b/usr/src/cmd/swap/Makefile.com @@ -20,7 +20,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -46,6 +46,7 @@ CLEANFILES += $(OBJS) all: $(PROG) +LDLIBS += -ldiskmgt $(PROG): $(OBJS) $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) diff --git a/usr/src/cmd/swap/swap.c b/usr/src/cmd/swap/swap.c index 4e9883f58a..3587df15db 100644 --- a/usr/src/cmd/swap/swap.c +++ b/usr/src/cmd/swap/swap.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -63,6 +63,7 @@ #include <fcntl.h> #include <locale.h> #include <libintl.h> +#include <libdiskmgt.h> #define LFLAG 0x01 /* swap -l (list swap devices) */ #define DFLAG 0x02 /* swap -d (delete swap device) */ @@ -85,9 +86,11 @@ main(int argc, char **argv) { int c, flag = 0; int ret; + int error = 0; off_t s_offset = 0; off_t length = 0; char *pathname; + char *msg; (void) setlocale(LC_ALL, ""); @@ -185,9 +188,6 @@ main(int argc, char **argv) exit(1); } } - if ((ret = valid(pathname, - s_offset * 512, length * 512)) == 0) - ret = add(pathname, s_offset, length, flag); break; case '1': @@ -203,6 +203,32 @@ main(int argc, char **argv) exit(1); } } + /* + * do the add here. Check for in use prior to add. + * The values for length and offset are set above. + */ + if (flag & AFLAG) { + /* + * If device is in use for a swap device, print message + * and exit. + */ + if (dm_inuse(pathname, &msg, DM_WHO_SWAP, &error) || + error) { + if (error != 0) { + (void) fprintf(stderr, gettext("Error occurred" + " with device in use checking: %s\n"), + strerror(error)); + } else { + (void) fprintf(stderr, "%s", msg); + free(msg); + exit(1); + } + } + if ((ret = valid(pathname, + s_offset * 512, length * 512)) == 0) { + ret = add(pathname, s_offset, length, flag); + } + } if (!flag) { usage(); exit(1); diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index f4d589a7d8..8e93cef77c 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -275,6 +275,7 @@ HDRSUBDIRS= libaio \ libdevice \ libdevid \ libdevinfo \ + libdiskmgt \ libdladm \ libdlpi \ libdhcpagent \ diff --git a/usr/src/lib/libdiskmgt/Makefile b/usr/src/lib/libdiskmgt/Makefile index ad9854966a..6c88d6c133 100644 --- a/usr/src/lib/libdiskmgt/Makefile +++ b/usr/src/lib/libdiskmgt/Makefile @@ -20,7 +20,7 @@ # CDDL HEADER END # # -# Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -29,20 +29,27 @@ include ../Makefile.lib HDRS = libdiskmgt.h +ROOTHDRDIR= $(ROOT)/usr/include +ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%) +CHECKDIRS= $(HDRS:%.h=%.check) HDRDIR = common SUBDIRS = spec .WAIT $(MACH) $(BUILD64) $(MACH64) +$(ROOTHDRDIR)/%: % + $(INS.file) + all := TARGET = all clean := TARGET = clean clobber := TARGET = clobber install := TARGET = install lint := TARGET = lint +install_h:= TARGET = install_h .KEEP_STATE: all clean clobber install lint: $(SUBDIRS) -install_h: +install_h: $(ROOTHDRS) check: $(CHECKHDRS) diff --git a/usr/src/lib/libdiskmgt/Makefile.com b/usr/src/lib/libdiskmgt/Makefile.com index e376e7b5c3..5e8c824fc5 100644 --- a/usr/src/lib/libdiskmgt/Makefile.com +++ b/usr/src/lib/libdiskmgt/Makefile.com @@ -20,7 +20,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -32,7 +32,7 @@ OBJECTS = assoc_types.o \ entry.o cache.o drive.o controller.o alias.o path.o \ media.o slice.o partition.o findevs.o events.o \ bus.o inuse_mnt.o inuse_svm.o inuse_lu.o inuse_fs.o \ - inuse_vxvm.o inuse_dump.o + inuse_vxvm.o inuse_dump.o inuse_zpool.o include ../../Makefile.lib diff --git a/usr/src/lib/libdiskmgt/common/cache.c b/usr/src/lib/libdiskmgt/common/cache.c index 411d6c41b7..1670aa3698 100644 --- a/usr/src/lib/libdiskmgt/common/cache.c +++ b/usr/src/lib/libdiskmgt/common/cache.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -652,8 +652,13 @@ initialize() cache_loaded = 1; - if ((status = events_start_event_watcher()) != 0) { - return (status); + /* + * Only start the event thread if we are not doing an install + */ + if (getenv("_LIBDISKMGT_INSTALL") == NULL) { + if ((status = events_start_event_watcher()) != 0) { + return (status); + } } return (0); diff --git a/usr/src/lib/libdiskmgt/common/disks_private.h b/usr/src/lib/libdiskmgt/common/disks_private.h index 3239925853..99e8801640 100644 --- a/usr/src/lib/libdiskmgt/common/disks_private.h +++ b/usr/src/lib/libdiskmgt/common/disks_private.h @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -262,6 +262,7 @@ int libdiskmgt_str_eq(char *nm1, char *nm2); int inuse_mnt(char *slice, nvlist_t *attrs, int *errp); int inuse_svm(char *slice, nvlist_t *attrs, int *errp); int inuse_lu(char *slice, nvlist_t *attrs, int *errp); +int inuse_zpool(char *slice, nvlist_t *attrs, int *errp); int inuse_dump(char *slice, nvlist_t *attrs, int *errp); int inuse_vxvm(char *slice, nvlist_t *attrs, int *errp); int inuse_fs(char *slice, nvlist_t *attrs, int *errp); diff --git a/usr/src/lib/libdiskmgt/common/drive.c b/usr/src/lib/libdiskmgt/common/drive.c index 00fd979ae3..aed1db3b59 100644 --- a/usr/src/lib/libdiskmgt/common/drive.c +++ b/usr/src/lib/libdiskmgt/common/drive.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -682,7 +682,7 @@ drive_open_disk(disk_t *diskp, char *opath, int len) } if ((dentp = (struct dirent *)malloc(sizeof (struct dirent) + - _PC_NAME_MAX + 1)) == NULL) { + PATH_MAX + 1)) == NULL) { /* out of memory */ (void) close(fd); return (-1); diff --git a/usr/src/lib/libdiskmgt/common/entry.c b/usr/src/lib/libdiskmgt/common/entry.c index cc760dbb83..ac08b47b7f 100644 --- a/usr/src/lib/libdiskmgt/common/entry.c +++ b/usr/src/lib/libdiskmgt/common/entry.c @@ -34,11 +34,16 @@ #include <unistd.h> #include <stdlib.h> #include <string.h> +#include <libintl.h> +#include <locale.h> +#include <sys/debug.h> #include "libdiskmgt.h" #include "disks_private.h" #include "partition.h" +extern char *getfullblkname(); + extern dm_desc_type_t drive_assoc_types[]; extern dm_desc_type_t bus_assoc_types[]; @@ -49,8 +54,11 @@ extern dm_desc_type_t partition_assoc_types[]; extern dm_desc_type_t path_assoc_types[]; extern dm_desc_type_t alias_assoc_types[]; + static dm_descriptor_t *ptr_array_to_desc_array(descriptor_t **ptrs, int *errp); static descriptor_t **desc_array_to_ptr_array(dm_descriptor_t *da, int *errp); +static int build_usage_string(char *dname, char *by, char *data, char **use, + int *found, int *errp); void dm_free_descriptor(dm_descriptor_t desc) @@ -403,46 +411,57 @@ dm_get_stats(dm_descriptor_t desc, int stat_type, int *errp) cache_rlock(); if (!cache_is_valid_desc(dp)) { - cache_unlock(); - *errp = EBADF; - return (NULL); + cache_unlock(); + *errp = EBADF; + return (NULL); } /* verify that the descriptor is still valid */ if (dp->p.generic == NULL) { - cache_unlock(); - *errp = ENODEV; - return (NULL); + cache_unlock(); + *errp = ENODEV; + return (NULL); } switch (dp->type) { case DM_DRIVE: - stats = drive_get_stats(dp, stat_type, errp); - break; + stats = drive_get_stats(dp, stat_type, errp); + break; case DM_BUS: - stats = bus_get_stats(dp, stat_type, errp); - break; + stats = bus_get_stats(dp, stat_type, errp); + break; case DM_CONTROLLER: - stats = controller_get_stats(dp, stat_type, errp); - break; + stats = controller_get_stats(dp, stat_type, errp); + break; case DM_MEDIA: - stats = media_get_stats(dp, stat_type, errp); - break; + stats = media_get_stats(dp, stat_type, errp); + break; case DM_SLICE: - stats = slice_get_stats(dp, stat_type, errp); - break; + if (stat_type == DM_SLICE_STAT_USE) { + /* + * If NOINUSE_CHECK is set, we do not perform + * the in use checking if the user has set stat_type + * DM_SLICE_STAT_USE + */ + if (getenv("NOINUSE_CHECK") != NULL) { + stats = NULL; + break; + } + } + stats = slice_get_stats(dp, stat_type, errp); + break; case DM_PARTITION: - stats = partition_get_stats(dp, stat_type, errp); - break; + stats = partition_get_stats(dp, stat_type, errp); + break; case DM_PATH: - stats = path_get_stats(dp, stat_type, errp); - break; + stats = path_get_stats(dp, stat_type, errp); + break; case DM_ALIAS: - stats = alias_get_stats(dp, stat_type, errp); - break; + stats = alias_get_stats(dp, stat_type, errp); + break; default: - *errp = EINVAL; - break; + *errp = EINVAL; + break; } cache_unlock(); @@ -468,7 +487,284 @@ dm_get_type(dm_descriptor_t desc) return (dp->type); } +/* + * Returns, via slices paramater, a dm_descriptor_t list of + * slices for the named disk drive. + */ +void +dm_get_slices(char *drive, dm_descriptor_t **slices, int *errp) +{ + dm_descriptor_t alias; + dm_descriptor_t *media; + dm_descriptor_t *disk; + *slices = NULL; + *errp = 0; + + if (drive == NULL) { + return; + } + + alias = dm_get_descriptor_by_name(DM_ALIAS, drive, errp); + + /* + * Errors must be handled by the caller. The dm_descriptor_t * + * values will be NULL if an error occured in these calls. + */ + + if (alias != NULL) { + disk = dm_get_associated_descriptors(alias, DM_DRIVE, errp); + dm_free_descriptor(alias); + if (disk != NULL) { + media = dm_get_associated_descriptors(*disk, + DM_MEDIA, errp); + dm_free_descriptors(disk); + if (media != NULL) { + *slices = dm_get_associated_descriptors(*media, + DM_SLICE, errp); + dm_free_descriptors(media); + } + } + } +} +/* + * Convenience function to get slice stats + */ +void +dm_get_slice_stats(char *slice, nvlist_t **dev_stats, int *errp) +{ + dm_descriptor_t devp; + + *dev_stats = NULL; + *errp = 0; + + if (slice == NULL) { + return; + } + + /* + * Errors must be handled by the caller. The dm_descriptor_t * + * values will be NULL if an error occured in these calls. + */ + devp = dm_get_descriptor_by_name(DM_SLICE, slice, errp); + if (devp != NULL) { + *dev_stats = dm_get_stats(devp, DM_SLICE_STAT_USE, + errp); + dm_free_descriptor(devp); + } +} + +/* + * Returns 'in use' details, if found, about a specific dev_name, + * based on the caller(who). It is important to note that it is possible + * for there to be more than one 'in use' statistic regarding a dev_name. + * The **msg parameter returns a list of 'in use' details. This message + * is formatted via gettext(). + */ +int +dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp) +{ + nvlist_t *dev_stats = NULL; + char *by, *data; + nvpair_t *nvwhat = NULL; + nvpair_t *nvdesc = NULL; + int found = 0; + char *dname = NULL; + + *errp = 0; + *msg = NULL; + + dname = getfullblkname(dev_name); + /* + * If we cannot find the block name, we cannot check the device + * for in use statistics. So, return found, which is == 0. + */ + if (dname == NULL || *dname == '\0') { + return (found); + } + + dm_get_slice_stats(dname, &dev_stats, errp); + if (dev_stats == NULL) { + /* + * If there is an error, but it isn't a no device found error + * return the error as recorded. Otherwise, with a full + * block name, we might not be able to get the slice + * associated, and will get an ENODEV error. For example, + * an SVM metadevice will return a value from getfullblkname() + * but libdiskmgt won't be able to find this device for + * statistics gathering. This is expected and we should not + * report errnoneous errors. + */ + if (*errp) { + if (*errp == ENODEV) { + *errp = 0; + } + } + free(dname); + return (found); + } + + for (;;) { + + nvwhat = nvlist_next_nvpair(dev_stats, nvdesc); + nvdesc = nvlist_next_nvpair(dev_stats, nvwhat); + + /* + * End of the list found. + */ + if (nvwhat == NULL || nvdesc == NULL) { + break; + } + /* + * Otherwise, we check to see if this client(who) cares + * about this in use scenario + */ + + ASSERT(strcmp(nvpair_name(nvwhat), DM_USED_BY) == 0); + ASSERT(strcmp(nvpair_name(nvdesc), DM_USED_NAME) == 0); + /* + * If we error getting the string value continue on + * to the next pair(if there is one) + */ + if (nvpair_value_string(nvwhat, &by)) { + continue; + } + if (nvpair_value_string(nvdesc, &data)) { + continue; + } + + switch (who) { + case DM_WHO_MKFS: + /* + * mkfs is not in use for these cases. + * All others are in use. + */ + if (strcmp(by, DM_USE_LU) == 0 || + strcmp(by, DM_USE_FS) == 0) { + break; + } + if (build_usage_string(dname, + by, data, msg, &found, errp) != 0) { + if (*errp) { + goto out; + } + } + break; + case DM_WHO_SWAP: + /* + * Not in use for this. + */ + if (strcmp(by, DM_USE_DUMP) == 0 || + strcmp(by, DM_USE_FS) == 0) { + break; + } + + if (build_usage_string(dname, + by, data, msg, &found, errp) != 0) { + if (*errp) { + goto out; + } + } + break; + case DM_WHO_DUMP: + /* + * Not in use for this. + */ + if ((strcmp(by, DM_USE_MOUNT) == 0 && + strcmp(data, "swap") == 0) || + strcmp(by, DM_USE_DUMP) == 0 || + strcmp(by, DM_USE_FS) == 0) { + break; + } + if (build_usage_string(dname, + by, data, msg, &found, errp)) { + if (*errp) { + goto out; + } + } + break; + + case DM_WHO_FORMAT: + if (strcmp(by, DM_USE_FS) == 0) + break; + if (build_usage_string(dname, + by, data, msg, &found, errp) != 0) { + if (*errp) { + goto out; + } + } + break; + default: + /* + * nothing found in use for this client + * of libdiskmgt. Default is 'not in use'. + */ + break; + } + } +out: + if (dname != NULL) + free(dname); + if (dev_stats != NULL) + nvlist_free(dev_stats); + + return (found); +} + +void +dm_get_usage_string(char *what, char *how, char **usage_string) +{ + + + if (usage_string == NULL || what == NULL) { + return; + } + *usage_string = NULL; + + if (strcmp(what, DM_USE_MOUNT) == 0) { + if (strcmp(how, "swap") == 0) { + *usage_string = dgettext(TEXT_DOMAIN, + "%s is currently used by swap. Please see swap(1M)." + "\n"); + } else { + *usage_string = dgettext(TEXT_DOMAIN, + "%s is currently mounted on %s." + " Please see umount(1M).\n"); + } + } else if (strcmp(what, DM_USE_VFSTAB) == 0) { + *usage_string = dgettext(TEXT_DOMAIN, + "%s is normally mounted on %s according to /etc/vfstab. " + "Please remove this entry to use this device.\n"); + } else if (strcmp(what, DM_USE_FS) == 0) { + *usage_string = dgettext(TEXT_DOMAIN, + "Warning: %s contains a %s filesystem.\n"); + } else if (strcmp(what, DM_USE_SVM) == 0) { + if (strcmp(how, "mdb") == 0) { + *usage_string = dgettext(TEXT_DOMAIN, + "%s contains an SVM %s. Please see " + "metadb(1M).\n"); + } else { + *usage_string = dgettext(TEXT_DOMAIN, + "%s is part of SVM volume %s. " + "Please see metaclear(1M).\n"); + } + } else if (strcmp(what, DM_USE_VXVM) == 0) { + *usage_string = dgettext(TEXT_DOMAIN, + "%s is part of VxVM volume %s.\n"); + } else if (strcmp(what, DM_USE_LU) == 0) { + *usage_string = dgettext(TEXT_DOMAIN, + "%s is in use for live upgrade %s. Please see ludelete(1M)." + "\n"); + } else if (strcmp(what, DM_USE_DUMP) == 0) { + *usage_string = dgettext(TEXT_DOMAIN, + "%s is in use by %s. Please see dumpadm(1M)." + "\n"); + } else if (strcmp(what, DM_USE_ZPOOL) == 0) { + *usage_string = dgettext(TEXT_DOMAIN, + "%s is in use by zpool %s. Please see zpool(1M)." + "\n"); + } +} void libdiskmgt_add_str(nvlist_t *attrs, char *name, char *val, int *errp) { @@ -597,3 +893,50 @@ ptr_array_to_desc_array(descriptor_t **ptrs, int *errp) return (da); #endif } +/* + * Build the usage string for the in use data. Return the build string in + * the msg parameter. This function takes care of reallocing all the memory + * for this usage string. Usage string is returned already formatted for + * localization. + */ +static int +build_usage_string(char *dname, char *by, char *data, char **msg, + int *found, int *errp) +{ + int len0; + int len1; + char *use; + char *p; + + *errp = 0; + + dm_get_usage_string(by, data, &use); + if (!use) { + return (-1); + } + + if (*msg) + len0 = strlen(*msg); + else + len0 = 0; + /* LINTED */ + len1 = snprintf(NULL, 0, use, dname, data); + + /* + * If multiple in use details they + * are listed 1 per line for ease of + * reading. dm_find_usage_string + * formats these appropriately. + */ + if ((p = realloc(*msg, len0 + len1 + 1)) == NULL) { + *errp = errno; + free(*msg); + return (-1); + } + *msg = p; + + /* LINTED */ + (void) snprintf(*msg + len0, len1 + 1, use, dname, data); + (*found)++; + return (0); +} diff --git a/usr/src/lib/libdiskmgt/common/findevs.c b/usr/src/lib/libdiskmgt/common/findevs.c index 39a9ddfd16..9c55ee7e2d 100644 --- a/usr/src/lib/libdiskmgt/common/findevs.c +++ b/usr/src/lib/libdiskmgt/common/findevs.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -978,7 +978,7 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args) diskp->removable = get_prop(REMOVABLE_PROP, args->node); if (diskp->removable == -1) { diskp->removable = 0; -#ifdef i386 +#if defined(i386) || defined(__amd64) /* * x86 does not have removable property. Check for common * removable drives, zip & jaz, and mark those correctly. diff --git a/usr/src/lib/libdiskmgt/common/inuse_fs.c b/usr/src/lib/libdiskmgt/common/inuse_fs.c index 7b37beb8c2..c2e751dcb2 100644 --- a/usr/src/lib/libdiskmgt/common/inuse_fs.c +++ b/usr/src/lib/libdiskmgt/common/inuse_fs.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -142,7 +142,6 @@ inuse_fs(char *slice, nvlist_t *attrs, int *errp) libdiskmgt_add_str(attrs, DM_USED_BY, DM_USE_VFSTAB, errp); libdiskmgt_add_str(attrs, DM_USED_NAME, mountp, errp); found = 1; - break; } listp = listp->next; } diff --git a/usr/src/lib/libdiskmgt/common/inuse_svm.c b/usr/src/lib/libdiskmgt/common/inuse_svm.c index 9298907af3..d50ba35515 100644 --- a/usr/src/lib/libdiskmgt/common/inuse_svm.c +++ b/usr/src/lib/libdiskmgt/common/inuse_svm.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -124,35 +124,46 @@ inuse_svm(char *slice, nvlist_t *attrs, int *errp) (void) mutex_lock(&init_lock); if (!initialized) { - /* dynamically load libmeta */ - if (init_svm()) { - /* need to initialize the cluster library to avoid seg faults */ - (mdl_sdssc_bind_library)(); - - /* load the SVM cache */ - *errp = load_svm(); - - if (*errp == 0) { - /* start a thread to monitor the svm config */ - sysevent_handle_t *shp; - const char *subclass_list[1]; - - shp = sysevent_bind_handle(event_handler); - if (shp != NULL) { - subclass_list[0] = EC_SUB_ALL; - if (sysevent_subscribe_event(shp, EC_SVM_CONFIG, - subclass_list, 1) != 0) { - *errp = errno; + /* dynamically load libmeta */ + if (init_svm()) { + /* + * need to initialize the cluster library to + * avoid seg faults + */ + (mdl_sdssc_bind_library)(); + + /* load the SVM cache */ + *errp = load_svm(); + + if (*errp == 0) { + /* start a thread to monitor the svm config */ + sysevent_handle_t *shp; + const char *subclass_list[1]; + /* + * Only start the svmevent thread if + * we are not doing an install + */ + + if (getenv("_LIBDISKMGT_INSTALL") == NULL) { + shp = sysevent_bind_handle( + event_handler); + if (shp != NULL) { + subclass_list[0] = EC_SUB_ALL; + if (sysevent_subscribe_event( + shp, EC_SVM_CONFIG, + subclass_list, 1) != 0) { + *errp = errno; + } + } else { + *errp = errno; + } + } } - } else { - *errp = errno; - } } - } - if (*errp == 0) { - initialized = 1; - } + if (*errp == 0) { + initialized = 1; + } } (void) mutex_unlock(&init_lock); diff --git a/usr/src/lib/libdiskmgt/common/inuse_zpool.c b/usr/src/lib/libdiskmgt/common/inuse_zpool.c new file mode 100644 index 0000000000..9913b7ef22 --- /dev/null +++ b/usr/src/lib/libdiskmgt/common/inuse_zpool.c @@ -0,0 +1,124 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (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 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Attempt to dynamically link in the ZFS libzfs.so.1 so that we can + * see if there are any ZFS zpools on any of the slices. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <strings.h> +#include <sys/param.h> +#include <sys/errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <thread.h> +#include <synch.h> +#include <dlfcn.h> +#include <link.h> +#include <ctype.h> + +#include "libdiskmgt.h" +#include "disks_private.h" + +/* + * Pointers to libzfs.so functions that we dynamically resolve. + */ +static int (*zfsdl_zpool_in_use)(int fd, char **desc, char **name); + +static mutex_t init_lock = DEFAULTMUTEX; +static rwlock_t zpool_lock = DEFAULTRWLOCK; +static int initialized = 0; + +static void *init_zpool(); + +int +inuse_zpool(char *slice, nvlist_t *attrs, int *errp) +{ + int found = 0; + char *desc, *name; + int fd; + + *errp = 0; + if (slice == NULL) { + return (found); + } + + (void) mutex_lock(&init_lock); + + /* + * Dynamically load libzfs + */ + if (!initialized) { + if (!init_zpool()) { + (void) mutex_unlock(&init_lock); + return (found); + } + initialized = 1; + } + (void) mutex_unlock(&init_lock); + (void) rw_rdlock(&zpool_lock); + if ((fd = open(slice, O_RDONLY)) > 0) { + if (zfsdl_zpool_in_use(fd, &desc, &name)) { + libdiskmgt_add_str(attrs, DM_USED_BY, + DM_USE_ZPOOL, errp); + libdiskmgt_add_str(attrs, DM_USED_NAME, + name, errp); + found = 1; + } + } + (void) rw_unlock(&zpool_lock); + + return (found); +} + +/* + * Try to dynamically link the zfs functions we need. + */ +static void* +init_zpool() +{ + void *lh = NULL; + + if ((lh = dlopen("libzfs.so", RTLD_NOW)) == NULL) { + return (lh); + } + /* + * Instantiate the functions needed to get zpool configuration + * data + */ + if ((zfsdl_zpool_in_use = (int (*)(int, char **, char **))dlsym(lh, + "zpool_in_use")) == NULL) { + (void) dlclose(lh); + return (NULL); + } + + return (lh); +} diff --git a/usr/src/lib/libdiskmgt/common/libdiskmgt.h b/usr/src/lib/libdiskmgt/common/libdiskmgt.h index d9c2909539..ee8d1776b7 100644 --- a/usr/src/lib/libdiskmgt/common/libdiskmgt.h +++ b/usr/src/lib/libdiskmgt/common/libdiskmgt.h @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,10 +35,21 @@ extern "C" { #include <libnvpair.h> -/* typedef void *dm_descriptor_t; */ +/* + * Holds all the data regarding the device. + * Private to libdiskmgt. Must use dm_xxx functions to set/get data. + */ typedef uint64_t dm_descriptor_t; typedef enum { + DM_WHO_MKFS = 0, + DM_WHO_ZPOOL, + DM_WHO_FORMAT, + DM_WHO_SWAP, + DM_WHO_DUMP +} dm_who_type_t; + +typedef enum { DM_DRIVE = 0, DM_CONTROLLER, DM_MEDIA, @@ -199,6 +210,7 @@ typedef enum { #define DM_USE_VXVM "vxvm" #define DM_USE_FS "fs" #define DM_USE_VFSTAB "vfstab" +#define DM_USE_ZPOOL "zpool" /* event */ #define DM_EV_NAME "name" @@ -232,6 +244,13 @@ nvlist_t *dm_get_stats(dm_descriptor_t desc, int stat_type, void dm_init_event_queue(void(*callback)(nvlist_t *, int), int *errp); nvlist_t *dm_get_event(int *errp); +void dm_get_slices(char *drive, dm_descriptor_t **slices, + int *errp); +void dm_get_slice_stats(char *slice, nvlist_t **dev_stats, + int *errp); +void dm_get_usage_string(char *who, char *data, char **msg); +int dm_inuse(char *dev_name, char **msg, dm_who_type_t who, + int *errp); #ifdef __cplusplus } diff --git a/usr/src/lib/libdiskmgt/common/media.c b/usr/src/lib/libdiskmgt/common/media.c index 364ff92d2a..ac29898ede 100644 --- a/usr/src/lib/libdiskmgt/common/media.c +++ b/usr/src/lib/libdiskmgt/common/media.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -440,27 +440,6 @@ apply_filter(descriptor_t **media, int filter[], int *errp) cache_free_descriptor(media[i]); } } -#ifdef i386 - /* XXX Work around bug 4725434 */ - else if (!media[i]->p.disk->removable) { - int j; - int match; - - match = 0; - for (j = 0; filter[j] != DM_FILTER_END; j++) { - if (DM_MT_FIXED == filter[j]) { - found[pos++] = media[i]; - match = 1; - break; - } - } - - if (!match) { - cache_free_descriptor(media[i]); - } - } -#endif - (void) close(fd); } found[pos] = NULL; @@ -506,10 +485,6 @@ get_attrs(disk_t *dp, int fd, nvlist_t *attrs) /* The first thing to do is read the media */ if (!media_read_info(fd, &minfo)) { - /* XXX Work around bug 4725434 */ -#ifdef i386 - if (dp->removable) -#endif return (ENODEV); } diff --git a/usr/src/lib/libdiskmgt/common/partition.c b/usr/src/lib/libdiskmgt/common/partition.c index 92e3e9579a..32141fc8ac 100644 --- a/usr/src/lib/libdiskmgt/common/partition.c +++ b/usr/src/lib/libdiskmgt/common/partition.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -101,6 +101,9 @@ partition_get_assocs(descriptor_t *desc, int *errp) struct ipart iparts[FD_NUMPART]; char pname[MAXPATHLEN]; int conv_flag = 0; +#if defined(i386) || defined(__amd64) + int len; +#endif if (get_parts(desc->p.disk, iparts, pname, sizeof (pname)) != 0) { return (libdiskmgt_empty_desc_array(errp)); @@ -114,17 +117,13 @@ partition_get_assocs(descriptor_t *desc, int *errp) return (NULL); } -#ifdef i386 - { +#if defined(i386) || defined(__amd64) /* convert part. name (e.g. c0d0p0) */ - int len; - len = strlen(pname); if (len > 1 && *(pname + (len - 2)) == 'p') { conv_flag = 1; *(pname + (len - 1)) = 0; } - } #endif /* @@ -336,8 +335,7 @@ partition_make_descriptors() int i; char mname[MAXPATHLEN]; int conv_flag = 0; - -#ifdef i386 +#if defined(i386) || defined(__amd64) /* convert part. name (e.g. c0d0p0) */ int len; @@ -473,15 +471,8 @@ get_parts(disk_t *disk, struct ipart *iparts, char *opath, int opath_len) /* First make sure media is inserted and spun up. */ if (!media_read_info(fd, &minfo)) { -#ifdef i386 - /* XXX Work around bug 4725434 */ - if (disk->removable) { -#endif (void) close(fd); return (ENODEV); -#ifdef i386 - } -#endif } if (!partition_has_fdisk(disk, fd)) { @@ -659,7 +650,7 @@ open_disk(disk_t *diskp, char *opath, int len) } if ((dentp = (struct dirent *)malloc(sizeof (struct dirent) + - _PC_NAME_MAX + 1)) == NULL) { + PATH_MAX + 1)) == NULL) { /* out of memory */ (void) close(fd); return (-1); diff --git a/usr/src/lib/libdiskmgt/common/slice.c b/usr/src/lib/libdiskmgt/common/slice.c index 607efeb120..c88c0a31c9 100644 --- a/usr/src/lib/libdiskmgt/common/slice.c +++ b/usr/src/lib/libdiskmgt/common/slice.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -60,6 +60,7 @@ static struct inuse_detectors { } detectors[] = { {inuse_mnt, DM_USE_MOUNT}, {inuse_svm, DM_USE_SVM}, + {inuse_zpool, DM_USE_ZPOOL}, {inuse_lu, DM_USE_LU}, {inuse_dump, DM_USE_DUMP}, {inuse_vxvm, DM_USE_VXVM}, @@ -453,10 +454,6 @@ get_attrs(descriptor_t *dp, int fd, nvlist_t *attrs) /* First make sure media is inserted and spun up. */ if (!media_read_info(fd, &minfo)) { -#ifdef i386 - /* XXX Work around bug 4725434 */ - if (dp->p.disk->removable) -#endif return (ENODEV); } @@ -838,7 +835,7 @@ get_removable_assocs(descriptor_t *desc, char *volm_path, int *errp) struct dirent *dentp; dentp = (struct dirent *)malloc(sizeof (struct dirent) + - _PC_NAME_MAX + 1); + PATH_MAX + 1); if (dentp != NULL) { #ifdef _LP64 while (readdir_r(dirp, dentp, &result) != NULL) { @@ -1092,7 +1089,7 @@ make_volm_dir_descriptors(disk_t *dp, int dirfd, char *volm_path) error = 0; dentp = (struct dirent *)malloc(sizeof (struct dirent) + - _PC_NAME_MAX + 1); + PATH_MAX + 1); if (dentp != NULL) { #ifdef _LP64 while (readdir_r(dirp, dentp, &result) != NULL) { @@ -1284,7 +1281,7 @@ match_removable_name(disk_t *diskp, char *name, int *errp) slice_rdsk2dsk(volm_path, devpath, sizeof (devpath)); dentp = (struct dirent *)malloc(sizeof (struct dirent) + - _PC_NAME_MAX + 1); + PATH_MAX + 1); if (dentp != NULL) { #ifdef _LP64 while (readdir_r(dirp, dentp, &result) != NULL) { @@ -1361,7 +1358,7 @@ num_removable_slices(int fd, struct stat *bufp, char *volm_path) slice_rdsk2dsk(volm_path, devpath, sizeof (devpath)); dentp = (struct dirent *)malloc(sizeof (struct dirent) + - _PC_NAME_MAX + 1); + PATH_MAX + 1); if (dentp != NULL) { #ifdef _LP64 while (readdir_r(dirp, dentp, &result) != NULL) { diff --git a/usr/src/lib/libdiskmgt/spec/diskmgt.spec b/usr/src/lib/libdiskmgt/spec/diskmgt.spec index 2d35464181..e2d364dc7f 100644 --- a/usr/src/lib/libdiskmgt/spec/diskmgt.spec +++ b/usr/src/lib/libdiskmgt/spec/diskmgt.spec @@ -22,7 +22,7 @@ # # CDDL HEADER END # -# ident "%Z%%M% %I% %E% SMI" +# pragma ident "%Z%%M% %I% %E% SMI" # # lib/libdiskmgt/spec/diskmgt.spec @@ -109,3 +109,25 @@ include <libdiskmgt.h> declaration nvlist_t *dm_get_event(int *errp) version SUNWprivate_1.1 end + +function dm_get_slices +include <libdiskmgt.h> +declaration void dm_get_slices(char * drive, dm_descriptor_t **slices, \ + int *errp) +version SUNWprivate_1.1 +end + +function dm_get_slice_stats +include <libdiskmgt.h> +declaration void dm_get_slice_stats(char *slice, nvlist_t **dev_stats, \ + int *errp) +version SUNWprivate_1.1 +end + +function dm_inuse +include <libdiskmgt.h> +declaration void dm_inuse(char * dev_name, char **msg, dm_who_type_t who, + int *errp) +version SUNWprivate_1.1 +end + diff --git a/usr/src/pkgdefs/etc/exception_list_i386 b/usr/src/pkgdefs/etc/exception_list_i386 index b8c682c9ed..0333f2eacc 100644 --- a/usr/src/pkgdefs/etc/exception_list_i386 +++ b/usr/src/pkgdefs/etc/exception_list_i386 @@ -104,6 +104,11 @@ lib/llib-llaadm i386 lib/llib-lmacadm.ln i386 lib/llib-lmacadm i386 # +# Installed in the proto area for building utilties dependent on +# it, but is not shipped. +# +usr/include/libdiskmgt.h i386 +# # The following files are used by the dhcpmgr. # usr/share/lib/locale/com/sun/dhcpmgr/bridge/ResourceBundle.properties i386 diff --git a/usr/src/pkgdefs/etc/exception_list_sparc b/usr/src/pkgdefs/etc/exception_list_sparc index 8f1f4a40e3..4be255ae8b 100644 --- a/usr/src/pkgdefs/etc/exception_list_sparc +++ b/usr/src/pkgdefs/etc/exception_list_sparc @@ -93,6 +93,10 @@ lib/llib-llaadm sparc lib/llib-lmacadm.ln sparc lib/llib-lmacadm sparc # +# Installed in the proto area for building those things +# that are dependent on it. No delivered as part of a pkg. +usr/include/libdiskmgt.h sparc +# # IKE and IPsec support library exceptions. The IKE support # library contains exclusively private interfaces, as does # libipsecutil. My apologies for the glut of header files here. diff --git a/usr/src/tools/findunref/exception_list b/usr/src/tools/findunref/exception_list index 04cc777343..757207e2d0 100644 --- a/usr/src/tools/findunref/exception_list +++ b/usr/src/tools/findunref/exception_list @@ -192,9 +192,9 @@ ./lib/libbsm/common/adt_ucred.h # -# Ignore files provided by Adaptec as part of their software drop. +# Ignore libdiskmgt.h. Used for building but not delivered. # -./uts/intel/io/adpu320/chim/hwm/seqse320.h +./lib/libdiskmgt/common/libdiskmgt.h # # Ignore files originally supplied by ISC (Internet Software Consortium) |
