diff options
author | sjelinek <none@none> | 2005-10-27 09:01:18 -0700 |
---|---|---|
committer | sjelinek <none@none> | 2005-10-27 09:01:18 -0700 |
commit | 3e1bd7a2aaeb6188caef90679b98088cfef1edc6 (patch) | |
tree | f96d6ce4a25ea39514dd8b1fd2a23978cabc5055 /usr/src/cmd/format | |
parent | 108322fb1c3ed341aba9c80c9774df0ed9e35768 (diff) | |
download | illumos-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/Makefile | 6 | ||||
-rw-r--r-- | usr/src/cmd/format/analyze.c | 4 | ||||
-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.c | 6 | ||||
-rw-r--r-- | usr/src/cmd/format/main.c | 10 | ||||
-rw-r--r-- | usr/src/cmd/format/menu_cache.c | 5 | ||||
-rw-r--r-- | usr/src/cmd/format/menu_command.c | 56 | ||||
-rw-r--r-- | usr/src/cmd/format/menu_developer.c | 5 | ||||
-rw-r--r-- | usr/src/cmd/format/menu_fdisk.c | 2 | ||||
-rw-r--r-- | usr/src/cmd/format/menu_scsi.c | 13 | ||||
-rw-r--r-- | usr/src/cmd/format/modify_partition.c | 2 |
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" |