summaryrefslogtreecommitdiff
path: root/usr/src/cmd/format
diff options
context:
space:
mode:
authorsjelinek <none@none>2005-10-27 09:01:18 -0700
committersjelinek <none@none>2005-10-27 09:01:18 -0700
commit3e1bd7a2aaeb6188caef90679b98088cfef1edc6 (patch)
treef96d6ce4a25ea39514dd8b1fd2a23978cabc5055 /usr/src/cmd/format
parent108322fb1c3ed341aba9c80c9774df0ed9e35768 (diff)
downloadillumos-joyent-3e1bd7a2aaeb6188caef90679b98088cfef1edc6.tar.gz
PSARC 2004/776 device checking for fs utilities
PSARC 2005/461 Device in use checking environment variables 5084421 libdiskmgt needs to detect in use ZFS data 5085739 remove workaround for bug 4725434 6194015 Device in use checking for Solaris utilities-PSARC/2004/776 6261853 libdiskmgt does not work correctly in all cases on amd64 6268374 libdiskmgt allocates incorrect size for readdir_r() dirent argument 6291309 PSARC/2005/461 - libdiskmgt should enable bypassing of inuse checking 6301815 PSARC/2005/461-Need Sun private libdiskmgt flag for use during install to disable sysevent starting --HG-- rename : usr/src/cmd/format/checkmount.c => usr/src/cmd/format/checkdev.c rename : usr/src/cmd/format/checkmount.h => usr/src/cmd/format/checkdev.h
Diffstat (limited to 'usr/src/cmd/format')
-rw-r--r--usr/src/cmd/format/Makefile6
-rw-r--r--usr/src/cmd/format/analyze.c4
-rw-r--r--usr/src/cmd/format/checkdev.c (renamed from usr/src/cmd/format/checkmount.c)268
-rw-r--r--usr/src/cmd/format/checkdev.h (renamed from usr/src/cmd/format/checkmount.h)11
-rw-r--r--usr/src/cmd/format/disk_generic.c6
-rw-r--r--usr/src/cmd/format/main.c10
-rw-r--r--usr/src/cmd/format/menu_cache.c5
-rw-r--r--usr/src/cmd/format/menu_command.c56
-rw-r--r--usr/src/cmd/format/menu_developer.c5
-rw-r--r--usr/src/cmd/format/menu_fdisk.c2
-rw-r--r--usr/src/cmd/format/menu_scsi.c13
-rw-r--r--usr/src/cmd/format/modify_partition.c2
12 files changed, 343 insertions, 45 deletions
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"