13e1bd7a2Ssjelinek /* 23e1bd7a2Ssjelinek * CDDL HEADER START 33e1bd7a2Ssjelinek * 43e1bd7a2Ssjelinek * The contents of this file are subject to the terms of the 5d25b227dSzl149053 * Common Development and Distribution License (the "License"). 6d25b227dSzl149053 * You may not use this file except in compliance with the License. 73e1bd7a2Ssjelinek * 83e1bd7a2Ssjelinek * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93e1bd7a2Ssjelinek * or http://www.opensolaris.org/os/licensing. 103e1bd7a2Ssjelinek * See the License for the specific language governing permissions 113e1bd7a2Ssjelinek * and limitations under the License. 123e1bd7a2Ssjelinek * 133e1bd7a2Ssjelinek * When distributing Covered Code, include this CDDL HEADER in each 143e1bd7a2Ssjelinek * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153e1bd7a2Ssjelinek * If applicable, add the following below this CDDL HEADER, with the 163e1bd7a2Ssjelinek * fields enclosed by brackets "[]" replaced with your own identifying 173e1bd7a2Ssjelinek * information: Portions Copyright [yyyy] [name of copyright owner] 183e1bd7a2Ssjelinek * 193e1bd7a2Ssjelinek * CDDL HEADER END 203e1bd7a2Ssjelinek */ 213e1bd7a2Ssjelinek /* 22*8eb14f40SSharath M Srinivasan * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 233e1bd7a2Ssjelinek * Use is subject to license terms. 243e1bd7a2Ssjelinek */ 253e1bd7a2Ssjelinek 263e1bd7a2Ssjelinek 273e1bd7a2Ssjelinek 283e1bd7a2Ssjelinek /* 293e1bd7a2Ssjelinek * This file contains miscellaneous device validation routines. 303e1bd7a2Ssjelinek */ 313e1bd7a2Ssjelinek 323e1bd7a2Ssjelinek #include "global.h" 333e1bd7a2Ssjelinek #include <sys/mnttab.h> 343e1bd7a2Ssjelinek #include <sys/mntent.h> 353e1bd7a2Ssjelinek #include <sys/autoconf.h> 363e1bd7a2Ssjelinek 373e1bd7a2Ssjelinek #include <signal.h> 383e1bd7a2Ssjelinek #include <malloc.h> 393e1bd7a2Ssjelinek #include <unistd.h> 403e1bd7a2Ssjelinek #include <string.h> 413e1bd7a2Ssjelinek #include <errno.h> 423e1bd7a2Ssjelinek #include <fcntl.h> 43d25b227dSzl149053 #include <libgen.h> 443e1bd7a2Ssjelinek #include <sys/ioctl.h> 453e1bd7a2Ssjelinek #include <sys/fcntl.h> 463e1bd7a2Ssjelinek #include <sys/stat.h> 473e1bd7a2Ssjelinek #include <sys/swap.h> 483e1bd7a2Ssjelinek #include <sys/sysmacros.h> 49d25b227dSzl149053 #include <sys/mkdev.h> 50d25b227dSzl149053 #include <sys/modctl.h> 513e1bd7a2Ssjelinek #include <ctype.h> 523e1bd7a2Ssjelinek #include <libdiskmgt.h> 533e1bd7a2Ssjelinek #include <libnvpair.h> 543e1bd7a2Ssjelinek #include "misc.h" 553e1bd7a2Ssjelinek #include "checkdev.h" 56*8eb14f40SSharath M Srinivasan #include <sys/efi_partition.h> 573e1bd7a2Ssjelinek 583e1bd7a2Ssjelinek /* Function prototypes */ 593e1bd7a2Ssjelinek #ifdef __STDC__ 603e1bd7a2Ssjelinek 613e1bd7a2Ssjelinek static struct swaptable *getswapentries(void); 623e1bd7a2Ssjelinek static void freeswapentries(struct swaptable *); 633e1bd7a2Ssjelinek static int getpartition(char *pathname); 643e1bd7a2Ssjelinek static int checkpartitions(int bm_mounted); 653e1bd7a2Ssjelinek 663e1bd7a2Ssjelinek #else /* __STDC__ */ 673e1bd7a2Ssjelinek 683e1bd7a2Ssjelinek static struct swaptable *getswapentries(); 693e1bd7a2Ssjelinek static void freeswapentries(); 703e1bd7a2Ssjelinek static int getpartition(); 713e1bd7a2Ssjelinek static int checkpartitions(); 723e1bd7a2Ssjelinek 733e1bd7a2Ssjelinek #endif /* __STDC__ */ 743e1bd7a2Ssjelinek 753e1bd7a2Ssjelinek extern char *getfullname(); 763e1bd7a2Ssjelinek 773e1bd7a2Ssjelinek static struct swaptable * 783e1bd7a2Ssjelinek getswapentries(void) 793e1bd7a2Ssjelinek { 803e1bd7a2Ssjelinek register struct swaptable *st; 813e1bd7a2Ssjelinek register struct swapent *swapent; 823e1bd7a2Ssjelinek int i, num; 833e1bd7a2Ssjelinek char fullpathname[MAXPATHLEN]; 843e1bd7a2Ssjelinek 853e1bd7a2Ssjelinek /* 863e1bd7a2Ssjelinek * get the number of swap entries 873e1bd7a2Ssjelinek */ 883e1bd7a2Ssjelinek if ((num = swapctl(SC_GETNSWP, (void *)NULL)) == -1) { 893e1bd7a2Ssjelinek err_print("swapctl error "); 903e1bd7a2Ssjelinek fullabort(); 913e1bd7a2Ssjelinek } 923e1bd7a2Ssjelinek if (num == 0) 933e1bd7a2Ssjelinek return (NULL); 943e1bd7a2Ssjelinek if ((st = (swaptbl_t *)malloc(num * sizeof (swapent_t) + sizeof (int))) 953e1bd7a2Ssjelinek == NULL) { 963e1bd7a2Ssjelinek err_print("getswapentries: malloc failed.\n"); 973e1bd7a2Ssjelinek fullabort(); 983e1bd7a2Ssjelinek } 993e1bd7a2Ssjelinek swapent = st->swt_ent; 1003e1bd7a2Ssjelinek for (i = 0; i < num; i++, swapent++) { 1013e1bd7a2Ssjelinek if ((swapent->ste_path = malloc(MAXPATHLEN)) == NULL) { 1023e1bd7a2Ssjelinek err_print("getswapentries: malloc failed.\n"); 1033e1bd7a2Ssjelinek fullabort(); 1043e1bd7a2Ssjelinek } 1053e1bd7a2Ssjelinek } 1063e1bd7a2Ssjelinek st->swt_n = num; 1073e1bd7a2Ssjelinek if ((num = swapctl(SC_LIST, (void *)st)) == -1) { 1083e1bd7a2Ssjelinek err_print("swapctl error "); 1093e1bd7a2Ssjelinek fullabort(); 1103e1bd7a2Ssjelinek } 1113e1bd7a2Ssjelinek swapent = st->swt_ent; 1123e1bd7a2Ssjelinek for (i = 0; i < num; i++, swapent++) { 1133e1bd7a2Ssjelinek if (*swapent->ste_path != '/') { 1143e1bd7a2Ssjelinek (void) snprintf(fullpathname, sizeof (fullpathname), 1153e1bd7a2Ssjelinek "/dev/%s", swapent->ste_path); 1163e1bd7a2Ssjelinek (void) strcpy(swapent->ste_path, fullpathname); 1173e1bd7a2Ssjelinek } 1183e1bd7a2Ssjelinek } 1193e1bd7a2Ssjelinek return (st); 1203e1bd7a2Ssjelinek } 1213e1bd7a2Ssjelinek 1223e1bd7a2Ssjelinek static void 1233e1bd7a2Ssjelinek freeswapentries(st) 1243e1bd7a2Ssjelinek struct swaptable *st; 1253e1bd7a2Ssjelinek { 1263e1bd7a2Ssjelinek register struct swapent *swapent; 1273e1bd7a2Ssjelinek int i; 1283e1bd7a2Ssjelinek 1293e1bd7a2Ssjelinek swapent = st->swt_ent; 1303e1bd7a2Ssjelinek for (i = 0; i < st->swt_n; i++, swapent++) 1313e1bd7a2Ssjelinek free(swapent->ste_path); 1323e1bd7a2Ssjelinek free(st); 1333e1bd7a2Ssjelinek 1343e1bd7a2Ssjelinek } 1353e1bd7a2Ssjelinek 1363e1bd7a2Ssjelinek /* 1373e1bd7a2Ssjelinek * function getpartition: 1383e1bd7a2Ssjelinek */ 1393e1bd7a2Ssjelinek static int 1403e1bd7a2Ssjelinek getpartition(pathname) 1413e1bd7a2Ssjelinek char *pathname; 1423e1bd7a2Ssjelinek { 1433e1bd7a2Ssjelinek int mfd; 1443e1bd7a2Ssjelinek struct dk_cinfo dkinfo; 1453e1bd7a2Ssjelinek struct stat stbuf; 1463e1bd7a2Ssjelinek char raw_device[MAXPATHLEN]; 1473e1bd7a2Ssjelinek int found = -1; 1483e1bd7a2Ssjelinek 1493e1bd7a2Ssjelinek /* 1503e1bd7a2Ssjelinek * Map the block device name to the raw device name. 1513e1bd7a2Ssjelinek * If it doesn't appear to be a device name, skip it. 1523e1bd7a2Ssjelinek */ 1533e1bd7a2Ssjelinek if (match_substr(pathname, "/dev/") == 0) 1543e1bd7a2Ssjelinek return (found); 1553e1bd7a2Ssjelinek (void) strcpy(raw_device, "/dev/r"); 1563e1bd7a2Ssjelinek (void) strcat(raw_device, pathname + strlen("/dev/")); 1573e1bd7a2Ssjelinek /* 1583e1bd7a2Ssjelinek * Determine if this appears to be a disk device. 1593e1bd7a2Ssjelinek * First attempt to open the device. If if fails, skip it. 1603e1bd7a2Ssjelinek */ 1613e1bd7a2Ssjelinek if ((mfd = open(raw_device, O_RDWR | O_NDELAY)) < 0) { 1623e1bd7a2Ssjelinek return (found); 1633e1bd7a2Ssjelinek } 1643e1bd7a2Ssjelinek /* 1653e1bd7a2Ssjelinek * Must be a character device 1663e1bd7a2Ssjelinek */ 1673e1bd7a2Ssjelinek if (fstat(mfd, &stbuf) == -1 || !S_ISCHR(stbuf.st_mode)) { 1683e1bd7a2Ssjelinek (void) close(mfd); 1693e1bd7a2Ssjelinek return (found); 1703e1bd7a2Ssjelinek } 1713e1bd7a2Ssjelinek /* 1723e1bd7a2Ssjelinek * Attempt to read the configuration info on the disk. 1733e1bd7a2Ssjelinek */ 1743e1bd7a2Ssjelinek if (ioctl(mfd, DKIOCINFO, &dkinfo) < 0) { 1753e1bd7a2Ssjelinek (void) close(mfd); 1763e1bd7a2Ssjelinek return (found); 1773e1bd7a2Ssjelinek } 1783e1bd7a2Ssjelinek /* 1793e1bd7a2Ssjelinek * Finished with the opened device 1803e1bd7a2Ssjelinek */ 1813e1bd7a2Ssjelinek (void) close(mfd); 1823e1bd7a2Ssjelinek 1833e1bd7a2Ssjelinek /* 1843e1bd7a2Ssjelinek * If it's not the disk we're interested in, it doesn't apply. 1853e1bd7a2Ssjelinek */ 1863e1bd7a2Ssjelinek if (cur_disk->disk_dkinfo.dki_ctype != dkinfo.dki_ctype || 1873e1bd7a2Ssjelinek cur_disk->disk_dkinfo.dki_cnum != dkinfo.dki_cnum || 1883e1bd7a2Ssjelinek cur_disk->disk_dkinfo.dki_unit != dkinfo.dki_unit || 1893e1bd7a2Ssjelinek strcmp(cur_disk->disk_dkinfo.dki_dname, 1903e1bd7a2Ssjelinek dkinfo.dki_dname) != 0) { 1913e1bd7a2Ssjelinek return (found); 1923e1bd7a2Ssjelinek } 1933e1bd7a2Ssjelinek 1943e1bd7a2Ssjelinek /* 1953e1bd7a2Ssjelinek * Extract the partition that is mounted. 1963e1bd7a2Ssjelinek */ 1973e1bd7a2Ssjelinek return (PARTITION(stbuf.st_rdev)); 1983e1bd7a2Ssjelinek } 1993e1bd7a2Ssjelinek 2003e1bd7a2Ssjelinek /* 2013e1bd7a2Ssjelinek * This Routine checks to see if there are partitions used for swapping overlaps 2023e1bd7a2Ssjelinek * a given portion of a disk. If the start parameter is < 0, it means 2033e1bd7a2Ssjelinek * that the entire disk should be checked 2043e1bd7a2Ssjelinek */ 2053e1bd7a2Ssjelinek int 2063e1bd7a2Ssjelinek checkswap(start, end) 2073e1bd7a2Ssjelinek diskaddr_t start, end; 2083e1bd7a2Ssjelinek { 2093e1bd7a2Ssjelinek struct swaptable *st; 2103e1bd7a2Ssjelinek struct swapent *swapent; 2113e1bd7a2Ssjelinek int i; 2123e1bd7a2Ssjelinek int found = 0; 2133e1bd7a2Ssjelinek struct dk_map32 *map; 2143e1bd7a2Ssjelinek int part; 2153e1bd7a2Ssjelinek 2163e1bd7a2Ssjelinek /* 2173e1bd7a2Ssjelinek * If we are only checking part of the disk, the disk must 2183e1bd7a2Ssjelinek * have a partition map to check against. If it doesn't, 2193e1bd7a2Ssjelinek * we hope for the best. 2203e1bd7a2Ssjelinek */ 2213e1bd7a2Ssjelinek if (cur_parts == NULL) 2223e1bd7a2Ssjelinek return (0); 2233e1bd7a2Ssjelinek 2243e1bd7a2Ssjelinek /* 2253e1bd7a2Ssjelinek * check for swap entries 2263e1bd7a2Ssjelinek */ 2273e1bd7a2Ssjelinek st = getswapentries(); 2283e1bd7a2Ssjelinek /* 2293e1bd7a2Ssjelinek * if there are no swap entries return. 2303e1bd7a2Ssjelinek */ 2313e1bd7a2Ssjelinek if (st == (struct swaptable *)NULL) 2323e1bd7a2Ssjelinek return (0); 2333e1bd7a2Ssjelinek swapent = st->swt_ent; 2343e1bd7a2Ssjelinek for (i = 0; i < st->swt_n; i++, swapent++) { 2353e1bd7a2Ssjelinek if ((part = getpartition(swapent->ste_path)) != -1) { 2363e1bd7a2Ssjelinek if (start == UINT_MAX64) { 2373e1bd7a2Ssjelinek found = -1; 2383e1bd7a2Ssjelinek break; 2393e1bd7a2Ssjelinek } 2403e1bd7a2Ssjelinek map = &cur_parts->pinfo_map[part]; 2413e1bd7a2Ssjelinek if ((start >= (int)(map->dkl_cylno * spc() + 2423e1bd7a2Ssjelinek map->dkl_nblk)) || (end < (int)(map->dkl_cylno 2433e1bd7a2Ssjelinek * spc()))) { 2443e1bd7a2Ssjelinek continue; 2453e1bd7a2Ssjelinek } 2463e1bd7a2Ssjelinek found = -1; 2473e1bd7a2Ssjelinek break; 2483e1bd7a2Ssjelinek }; 2493e1bd7a2Ssjelinek } 2503e1bd7a2Ssjelinek freeswapentries(st); 2513e1bd7a2Ssjelinek /* 2523e1bd7a2Ssjelinek * If we found trouble and we're running from a command file, 2533e1bd7a2Ssjelinek * quit before doing something we really regret. 2543e1bd7a2Ssjelinek */ 2553e1bd7a2Ssjelinek 2563e1bd7a2Ssjelinek if (found && option_f) { 2573e1bd7a2Ssjelinek err_print( 2583e1bd7a2Ssjelinek "Operation on disks being used for swapping must be interactive.\n"); 2593e1bd7a2Ssjelinek cmdabort(SIGINT); 2603e1bd7a2Ssjelinek } 2613e1bd7a2Ssjelinek 2623e1bd7a2Ssjelinek return (found); 2633e1bd7a2Ssjelinek 2643e1bd7a2Ssjelinek 2653e1bd7a2Ssjelinek } 2663e1bd7a2Ssjelinek /* 2673e1bd7a2Ssjelinek * Determines if there are partitions that are a part of an SVM, VxVM, zpool 2683e1bd7a2Ssjelinek * volume or a live upgrade device, overlapping a given portion of a disk. 2693e1bd7a2Ssjelinek * Mounts and swap devices are checked in legacy format code. 2703e1bd7a2Ssjelinek */ 2713e1bd7a2Ssjelinek int 2723e1bd7a2Ssjelinek checkdevinuse(char *cur_disk_path, diskaddr_t start, diskaddr_t end, int print, 2733e1bd7a2Ssjelinek int check_label) 2743e1bd7a2Ssjelinek { 2753e1bd7a2Ssjelinek 2763e1bd7a2Ssjelinek int error; 2773e1bd7a2Ssjelinek int found = 0; 2783e1bd7a2Ssjelinek int check = 0; 2793e1bd7a2Ssjelinek int i; 2803e1bd7a2Ssjelinek int bm_inuse = 0; 2813e1bd7a2Ssjelinek int part = 0; 2823e1bd7a2Ssjelinek uint64_t slice_start, slice_size; 2833e1bd7a2Ssjelinek dm_descriptor_t *slices = NULL; 2843e1bd7a2Ssjelinek nvlist_t *attrs = NULL; 2853e1bd7a2Ssjelinek char *usage; 2863e1bd7a2Ssjelinek char *name; 2873e1bd7a2Ssjelinek 2883e1bd7a2Ssjelinek /* 28982d71480Ssjelinek * If the user does not want to do in use checking, return immediately. 29082d71480Ssjelinek * Normally, this is handled in libdiskmgt. For format, there is more 29182d71480Ssjelinek * processing required, so we want to bypass the in use checking 29282d71480Ssjelinek * here. 29382d71480Ssjelinek */ 29482d71480Ssjelinek 29582d71480Ssjelinek if (NOINUSE_SET) 29682d71480Ssjelinek return (0); 29782d71480Ssjelinek 29882d71480Ssjelinek /* 299d25b227dSzl149053 * Skip if it is not a real disk 300d25b227dSzl149053 * 301d25b227dSzl149053 * There could be two kinds of strings in cur_disk_path 302d25b227dSzl149053 * One starts with c?t?d?, while the other is a absolute path of a 303d25b227dSzl149053 * block device file. 304d25b227dSzl149053 */ 305d25b227dSzl149053 306d25b227dSzl149053 if (*cur_disk_path != 'c') { 307d25b227dSzl149053 struct stat stbuf; 308d25b227dSzl149053 char majorname[16]; 309d25b227dSzl149053 major_t majornum; 310d25b227dSzl149053 311d25b227dSzl149053 (void) stat(cur_disk_path, &stbuf); 312d25b227dSzl149053 majornum = major(stbuf.st_rdev); 313d25b227dSzl149053 (void) modctl(MODGETNAME, majorname, sizeof (majorname), 314d25b227dSzl149053 &majornum); 315d25b227dSzl149053 316d25b227dSzl149053 if (strcmp(majorname, "sd")) 317d25b227dSzl149053 if (strcmp(majorname, "ssd")) 318d25b227dSzl149053 if (strcmp(majorname, "cmdk")) 319d25b227dSzl149053 return (0); 320d25b227dSzl149053 } 321d25b227dSzl149053 322d25b227dSzl149053 /* 323d25b227dSzl149053 * Truncate the characters following "d*", such as "s*" or "p*" 324d25b227dSzl149053 */ 325d25b227dSzl149053 cur_disk_path = basename(cur_disk_path); 326d25b227dSzl149053 name = strrchr(cur_disk_path, 'd'); 327d25b227dSzl149053 if (name) { 328d25b227dSzl149053 name++; 329*8eb14f40SSharath M Srinivasan for (; (*name <= '9') && (*name >= '0'); name++) { 330*8eb14f40SSharath M Srinivasan } 331d25b227dSzl149053 *name = (char)0; 332d25b227dSzl149053 } 333d25b227dSzl149053 334d25b227dSzl149053 335d25b227dSzl149053 /* 3363e1bd7a2Ssjelinek * For format, we get basic 'in use' details from libdiskmgt. After 3373e1bd7a2Ssjelinek * that we must do the appropriate checking to see if the 'in use' 3383e1bd7a2Ssjelinek * details require a bit of additional work. 3393e1bd7a2Ssjelinek */ 3403e1bd7a2Ssjelinek 3413e1bd7a2Ssjelinek dm_get_slices(cur_disk_path, &slices, &error); 3423e1bd7a2Ssjelinek if (error) { 3432b237d4bSny155746 /* 3442b237d4bSny155746 * If ENODEV, it actually means the device is not in use. 3452b237d4bSny155746 * We will return 0 without displaying error. 3462b237d4bSny155746 */ 3472b237d4bSny155746 if (error != ENODEV) { 3482b237d4bSny155746 err_print("Error occurred with device in use" 3492b237d4bSny155746 "checking: %s\n", strerror(error)); 3503e1bd7a2Ssjelinek return (found); 3513e1bd7a2Ssjelinek } 3522b237d4bSny155746 } 3533e1bd7a2Ssjelinek if (slices == NULL) 3543e1bd7a2Ssjelinek return (found); 3553e1bd7a2Ssjelinek 3563e1bd7a2Ssjelinek for (i = 0; slices[i] != NULL; i++) { 3573e1bd7a2Ssjelinek /* 3583e1bd7a2Ssjelinek * If we are checking the whole disk 3593e1bd7a2Ssjelinek * then any and all in use data is 3603e1bd7a2Ssjelinek * relevant. 3613e1bd7a2Ssjelinek */ 3623e1bd7a2Ssjelinek if (start == UINT_MAX64) { 3633e1bd7a2Ssjelinek name = dm_get_name(slices[i], &error); 3643e1bd7a2Ssjelinek if (error != 0 || !name) { 3653e1bd7a2Ssjelinek err_print("Error occurred with device " 366*8eb14f40SSharath M Srinivasan "in use checking: %s\n", strerror(error)); 3673e1bd7a2Ssjelinek continue; 3683e1bd7a2Ssjelinek } 3693e1bd7a2Ssjelinek if (dm_inuse(name, &usage, DM_WHO_FORMAT, &error) || 3703e1bd7a2Ssjelinek error) { 3713e1bd7a2Ssjelinek if (error != 0) { 3723e1bd7a2Ssjelinek dm_free_name(name); 3733e1bd7a2Ssjelinek name = NULL; 374*8eb14f40SSharath M Srinivasan err_print("Error occurred with " 375*8eb14f40SSharath M Srinivasan "device in use checking: " 376*8eb14f40SSharath M Srinivasan "%s\n", strerror(error)); 3773e1bd7a2Ssjelinek continue; 3783e1bd7a2Ssjelinek } 3793e1bd7a2Ssjelinek dm_free_name(name); 3803e1bd7a2Ssjelinek name = NULL; 3813e1bd7a2Ssjelinek /* 3823e1bd7a2Ssjelinek * If this is a dump device, then it is 3833e1bd7a2Ssjelinek * a failure. You cannot format a slice 3843e1bd7a2Ssjelinek * that is a dedicated dump device. 3853e1bd7a2Ssjelinek */ 3863e1bd7a2Ssjelinek 3873e1bd7a2Ssjelinek if (strstr(usage, DM_USE_DUMP)) { 3883e1bd7a2Ssjelinek if (print) { 3893e1bd7a2Ssjelinek err_print(usage); 3903e1bd7a2Ssjelinek free(usage); 3913e1bd7a2Ssjelinek } 3923e1bd7a2Ssjelinek dm_free_descriptors(slices); 3933e1bd7a2Ssjelinek return (1); 3943e1bd7a2Ssjelinek } 3953e1bd7a2Ssjelinek /* 3963e1bd7a2Ssjelinek * We really found a device that is in use. 3973e1bd7a2Ssjelinek * Set 'found' for the return value, and set 3983e1bd7a2Ssjelinek * 'check' to indicate below that we must 3993e1bd7a2Ssjelinek * get the partition number to set bm_inuse 4003e1bd7a2Ssjelinek * in the event we are trying to label this 4013e1bd7a2Ssjelinek * device. check_label is set when we are 4023e1bd7a2Ssjelinek * checking modifications for in use slices 4033e1bd7a2Ssjelinek * on the device. 4043e1bd7a2Ssjelinek */ 4053e1bd7a2Ssjelinek found ++; 4063e1bd7a2Ssjelinek check = 1; 4073e1bd7a2Ssjelinek if (print) { 4083e1bd7a2Ssjelinek err_print(usage); 4093e1bd7a2Ssjelinek free(usage); 4103e1bd7a2Ssjelinek } 4113e1bd7a2Ssjelinek } 4123e1bd7a2Ssjelinek } else { 4133e1bd7a2Ssjelinek /* 4143e1bd7a2Ssjelinek * Before getting the in use data, verify that the 4153e1bd7a2Ssjelinek * current slice is within the range we are checking. 4163e1bd7a2Ssjelinek */ 4173e1bd7a2Ssjelinek attrs = dm_get_attributes(slices[i], &error); 4183e1bd7a2Ssjelinek if (error) { 4193e1bd7a2Ssjelinek err_print("Error occurred with device in use " 4203e1bd7a2Ssjelinek "checking: %s\n", strerror(error)); 4213e1bd7a2Ssjelinek continue; 4223e1bd7a2Ssjelinek } 4233e1bd7a2Ssjelinek if (attrs == NULL) { 4243e1bd7a2Ssjelinek continue; 4253e1bd7a2Ssjelinek } 4263e1bd7a2Ssjelinek 4273e1bd7a2Ssjelinek (void) nvlist_lookup_uint64(attrs, DM_START, 4283e1bd7a2Ssjelinek &slice_start); 4293e1bd7a2Ssjelinek (void) nvlist_lookup_uint64(attrs, DM_SIZE, 4303e1bd7a2Ssjelinek &slice_size); 4313e1bd7a2Ssjelinek if (start >= (slice_start + slice_size) || 4323e1bd7a2Ssjelinek (end < slice_start)) { 4333e1bd7a2Ssjelinek nvlist_free(attrs); 4343e1bd7a2Ssjelinek attrs = NULL; 4353e1bd7a2Ssjelinek continue; 4363e1bd7a2Ssjelinek } 4373e1bd7a2Ssjelinek name = dm_get_name(slices[i], &error); 4383e1bd7a2Ssjelinek if (error != 0 || !name) { 4393e1bd7a2Ssjelinek err_print("Error occurred with device " 440*8eb14f40SSharath M Srinivasan "in use checking: %s\n", strerror(error)); 4413e1bd7a2Ssjelinek nvlist_free(attrs); 4423e1bd7a2Ssjelinek attrs = NULL; 4433e1bd7a2Ssjelinek continue; 4443e1bd7a2Ssjelinek } 4453e1bd7a2Ssjelinek if (dm_inuse(name, &usage, 4463e1bd7a2Ssjelinek DM_WHO_FORMAT, &error) || error) { 4473e1bd7a2Ssjelinek if (error != 0) { 4483e1bd7a2Ssjelinek dm_free_name(name); 4493e1bd7a2Ssjelinek name = NULL; 450*8eb14f40SSharath M Srinivasan err_print("Error occurred with " 451*8eb14f40SSharath M Srinivasan "device in use checking: " 452*8eb14f40SSharath M Srinivasan "%s\n", strerror(error)); 4533e1bd7a2Ssjelinek nvlist_free(attrs); 4543e1bd7a2Ssjelinek attrs = NULL; 4553e1bd7a2Ssjelinek continue; 4563e1bd7a2Ssjelinek } 4573e1bd7a2Ssjelinek dm_free_name(name); 4583e1bd7a2Ssjelinek name = NULL; 4593e1bd7a2Ssjelinek /* 4603e1bd7a2Ssjelinek * If this is a dump device, then it is 4613e1bd7a2Ssjelinek * a failure. You cannot format a slice 4623e1bd7a2Ssjelinek * that is a dedicated dump device. 4633e1bd7a2Ssjelinek */ 4643e1bd7a2Ssjelinek if (strstr(usage, DM_USE_DUMP)) { 4653e1bd7a2Ssjelinek if (print) { 4663e1bd7a2Ssjelinek err_print(usage); 4673e1bd7a2Ssjelinek free(usage); 4683e1bd7a2Ssjelinek } 4693e1bd7a2Ssjelinek dm_free_descriptors(slices); 4703e1bd7a2Ssjelinek nvlist_free(attrs); 4713e1bd7a2Ssjelinek return (1); 4723e1bd7a2Ssjelinek } 4733e1bd7a2Ssjelinek /* 4743e1bd7a2Ssjelinek * We really found a device that is in use. 4753e1bd7a2Ssjelinek * Set 'found' for the return value, and set 4763e1bd7a2Ssjelinek * 'check' to indicate below that we must 4773e1bd7a2Ssjelinek * get the partition number to set bm_inuse 4783e1bd7a2Ssjelinek * in the event we are trying to label this 4793e1bd7a2Ssjelinek * device. check_label is set when we are 4803e1bd7a2Ssjelinek * checking modifications for in use slices 4813e1bd7a2Ssjelinek * on the device. 4823e1bd7a2Ssjelinek */ 4833e1bd7a2Ssjelinek found ++; 4843e1bd7a2Ssjelinek check = 1; 4853e1bd7a2Ssjelinek if (print) { 4863e1bd7a2Ssjelinek err_print(usage); 4873e1bd7a2Ssjelinek free(usage); 4883e1bd7a2Ssjelinek } 4893e1bd7a2Ssjelinek } 4903e1bd7a2Ssjelinek } 4913e1bd7a2Ssjelinek /* 4923e1bd7a2Ssjelinek * If check is set it means we found a slice(the current slice) 4933e1bd7a2Ssjelinek * on this device in use in some way. We potentially want 4943e1bd7a2Ssjelinek * to check this slice when labeling is 4953e1bd7a2Ssjelinek * requested. We set bm_inuse with this partition value 4963e1bd7a2Ssjelinek * for use later if check_label was set when called. 4973e1bd7a2Ssjelinek */ 4983e1bd7a2Ssjelinek if (check) { 4993e1bd7a2Ssjelinek name = dm_get_name(slices[i], &error); 5003e1bd7a2Ssjelinek if (error != 0 || !name) { 5013e1bd7a2Ssjelinek err_print("Error occurred with device " 502*8eb14f40SSharath M Srinivasan "in use checking: %s\n", strerror(error)); 5033e1bd7a2Ssjelinek nvlist_free(attrs); 5043e1bd7a2Ssjelinek attrs = NULL; 5053e1bd7a2Ssjelinek continue; 5063e1bd7a2Ssjelinek } 5073e1bd7a2Ssjelinek part = getpartition(name); 5083e1bd7a2Ssjelinek dm_free_name(name); 5093e1bd7a2Ssjelinek name = NULL; 5103e1bd7a2Ssjelinek if (part != -1) { 5113e1bd7a2Ssjelinek bm_inuse |= 1 << part; 5123e1bd7a2Ssjelinek } 5133e1bd7a2Ssjelinek check = 0; 5143e1bd7a2Ssjelinek } 5153e1bd7a2Ssjelinek /* 5163e1bd7a2Ssjelinek * If we have attributes then we have successfully 5173e1bd7a2Ssjelinek * found the slice we were looking for and we also 5183e1bd7a2Ssjelinek * know this means we are not searching the whole 5193e1bd7a2Ssjelinek * disk so break out of the loop 5203e1bd7a2Ssjelinek * now. 5213e1bd7a2Ssjelinek */ 5223e1bd7a2Ssjelinek if (attrs) { 5233e1bd7a2Ssjelinek nvlist_free(attrs); 5243e1bd7a2Ssjelinek break; 5253e1bd7a2Ssjelinek } 5263e1bd7a2Ssjelinek } 5273e1bd7a2Ssjelinek 5283e1bd7a2Ssjelinek if (slices) { 5293e1bd7a2Ssjelinek dm_free_descriptors(slices); 5303e1bd7a2Ssjelinek } 5313e1bd7a2Ssjelinek 5323e1bd7a2Ssjelinek /* 5333e1bd7a2Ssjelinek * The user is trying to label the disk. We have to do special 5343e1bd7a2Ssjelinek * checking here to ensure they are not trying to modify a slice 5353e1bd7a2Ssjelinek * that is in use in an incompatible way. 5363e1bd7a2Ssjelinek */ 5373e1bd7a2Ssjelinek if (check_label && bm_inuse) { 5383e1bd7a2Ssjelinek /* 5393e1bd7a2Ssjelinek * !0 indicates that we found a 5403e1bd7a2Ssjelinek * problem. In this case, we have overloaded 5413e1bd7a2Ssjelinek * the use of checkpartitions to work for 5423e1bd7a2Ssjelinek * in use devices. bm_inuse is representative 5433e1bd7a2Ssjelinek * of the slice that is in use, not that 5443e1bd7a2Ssjelinek * is mounted as is in the case of the normal 5453e1bd7a2Ssjelinek * use of checkpartitions. 5463e1bd7a2Ssjelinek * 5473e1bd7a2Ssjelinek * The call to checkpartitions will return !0 if 5483e1bd7a2Ssjelinek * we are trying to shrink a device that we have found 5493e1bd7a2Ssjelinek * to be in use above. 5503e1bd7a2Ssjelinek */ 5513e1bd7a2Ssjelinek return (checkpartitions(bm_inuse)); 5523e1bd7a2Ssjelinek } 5533e1bd7a2Ssjelinek 5543e1bd7a2Ssjelinek return (found); 5553e1bd7a2Ssjelinek } 5563e1bd7a2Ssjelinek /* 5573e1bd7a2Ssjelinek * This routine checks to see if there are mounted partitions overlapping 5583e1bd7a2Ssjelinek * a given portion of a disk. If the start parameter is < 0, it means 5593e1bd7a2Ssjelinek * that the entire disk should be checked. 5603e1bd7a2Ssjelinek */ 5613e1bd7a2Ssjelinek int 5623e1bd7a2Ssjelinek checkmount(start, end) 5633e1bd7a2Ssjelinek diskaddr_t start, end; 5643e1bd7a2Ssjelinek { 5653e1bd7a2Ssjelinek FILE *fp; 5663e1bd7a2Ssjelinek int found = 0; 5673e1bd7a2Ssjelinek struct dk_map32 *map; 5683e1bd7a2Ssjelinek int part; 5693e1bd7a2Ssjelinek struct mnttab mnt_record; 5703e1bd7a2Ssjelinek struct mnttab *mp = &mnt_record; 5713e1bd7a2Ssjelinek 5723e1bd7a2Ssjelinek /* 5733e1bd7a2Ssjelinek * If we are only checking part of the disk, the disk must 5743e1bd7a2Ssjelinek * have a partition map to check against. If it doesn't, 5753e1bd7a2Ssjelinek * we hope for the best. 5763e1bd7a2Ssjelinek */ 5773e1bd7a2Ssjelinek if (cur_parts == NULL) 5783e1bd7a2Ssjelinek return (0); 5793e1bd7a2Ssjelinek 5803e1bd7a2Ssjelinek /* 5813e1bd7a2Ssjelinek * Lock out interrupts because of the mntent protocol. 5823e1bd7a2Ssjelinek */ 5833e1bd7a2Ssjelinek enter_critical(); 5843e1bd7a2Ssjelinek /* 5853e1bd7a2Ssjelinek * Open the mount table. 5863e1bd7a2Ssjelinek */ 5873e1bd7a2Ssjelinek fp = fopen(MNTTAB, "r"); 5883e1bd7a2Ssjelinek if (fp == NULL) { 5893e1bd7a2Ssjelinek err_print("Unable to open mount table.\n"); 5903e1bd7a2Ssjelinek fullabort(); 5913e1bd7a2Ssjelinek } 5923e1bd7a2Ssjelinek /* 5933e1bd7a2Ssjelinek * Loop through the mount table until we run out of entries. 5943e1bd7a2Ssjelinek */ 5953e1bd7a2Ssjelinek while ((getmntent(fp, mp)) != -1) { 5963e1bd7a2Ssjelinek 5973e1bd7a2Ssjelinek if ((part = getpartition(mp->mnt_special)) == -1) 5983e1bd7a2Ssjelinek continue; 5993e1bd7a2Ssjelinek 6003e1bd7a2Ssjelinek /* 6013e1bd7a2Ssjelinek * It's a mount on the disk we're checking. If we are 6023e1bd7a2Ssjelinek * checking whole disk, then we found trouble. We can 6033e1bd7a2Ssjelinek * quit searching. 6043e1bd7a2Ssjelinek */ 6053e1bd7a2Ssjelinek if (start == UINT_MAX64) { 6063e1bd7a2Ssjelinek found = -1; 6073e1bd7a2Ssjelinek break; 6083e1bd7a2Ssjelinek } 6093e1bd7a2Ssjelinek 6103e1bd7a2Ssjelinek /* 6113e1bd7a2Ssjelinek * If the partition overlaps the zone we're checking, 6123e1bd7a2Ssjelinek * then we found trouble. We can quit searching. 6133e1bd7a2Ssjelinek */ 6143e1bd7a2Ssjelinek map = &cur_parts->pinfo_map[part]; 6153e1bd7a2Ssjelinek if ((start >= (int)(map->dkl_cylno * spc() + map->dkl_nblk)) || 6163e1bd7a2Ssjelinek (end < (int)(map->dkl_cylno * spc()))) { 6173e1bd7a2Ssjelinek continue; 6183e1bd7a2Ssjelinek } 6193e1bd7a2Ssjelinek found = -1; 6203e1bd7a2Ssjelinek break; 6213e1bd7a2Ssjelinek } 6223e1bd7a2Ssjelinek /* 6233e1bd7a2Ssjelinek * Close down the mount table. 6243e1bd7a2Ssjelinek */ 6253e1bd7a2Ssjelinek (void) fclose(fp); 6263e1bd7a2Ssjelinek exit_critical(); 6273e1bd7a2Ssjelinek 6283e1bd7a2Ssjelinek /* 6293e1bd7a2Ssjelinek * If we found trouble and we're running from a command file, 6303e1bd7a2Ssjelinek * quit before doing something we really regret. 6313e1bd7a2Ssjelinek */ 6323e1bd7a2Ssjelinek 6333e1bd7a2Ssjelinek if (found && option_f) { 6343e1bd7a2Ssjelinek err_print("Operation on mounted disks must be interactive.\n"); 6353e1bd7a2Ssjelinek cmdabort(SIGINT); 6363e1bd7a2Ssjelinek } 6373e1bd7a2Ssjelinek /* 6383e1bd7a2Ssjelinek * Return the result. 6393e1bd7a2Ssjelinek */ 6403e1bd7a2Ssjelinek return (found); 6413e1bd7a2Ssjelinek } 6423e1bd7a2Ssjelinek 6433e1bd7a2Ssjelinek int 6443e1bd7a2Ssjelinek check_label_with_swap() 6453e1bd7a2Ssjelinek { 6463e1bd7a2Ssjelinek int i; 6473e1bd7a2Ssjelinek struct swaptable *st; 6483e1bd7a2Ssjelinek struct swapent *swapent; 6493e1bd7a2Ssjelinek int part; 6503e1bd7a2Ssjelinek int bm_swap = 0; 6513e1bd7a2Ssjelinek 6523e1bd7a2Ssjelinek /* 6533e1bd7a2Ssjelinek * If we are only checking part of the disk, the disk must 6543e1bd7a2Ssjelinek * have a partition map to check against. If it doesn't, 6553e1bd7a2Ssjelinek * we hope for the best. 6563e1bd7a2Ssjelinek */ 6573e1bd7a2Ssjelinek if (cur_parts == NULL) 6583e1bd7a2Ssjelinek return (0); /* Will be checked later */ 6593e1bd7a2Ssjelinek 6603e1bd7a2Ssjelinek /* 6613e1bd7a2Ssjelinek * Check for swap entries 6623e1bd7a2Ssjelinek */ 6633e1bd7a2Ssjelinek st = getswapentries(); 6643e1bd7a2Ssjelinek /* 6653e1bd7a2Ssjelinek * if there are no swap entries return. 6663e1bd7a2Ssjelinek */ 6673e1bd7a2Ssjelinek if (st == (struct swaptable *)NULL) 6683e1bd7a2Ssjelinek return (0); 6693e1bd7a2Ssjelinek swapent = st->swt_ent; 6703e1bd7a2Ssjelinek for (i = 0; i < st->swt_n; i++, swapent++) 6713e1bd7a2Ssjelinek if ((part = getpartition(swapent->ste_path)) != -1) 6723e1bd7a2Ssjelinek bm_swap |= (1 << part); 6733e1bd7a2Ssjelinek freeswapentries(st); 6743e1bd7a2Ssjelinek 6753e1bd7a2Ssjelinek return (checkpartitions(bm_swap)); 6763e1bd7a2Ssjelinek } 6773e1bd7a2Ssjelinek 6783e1bd7a2Ssjelinek /* 6793e1bd7a2Ssjelinek * Check the new label with the existing label on the disk, 6803e1bd7a2Ssjelinek * to make sure that any mounted partitions are not being 6813e1bd7a2Ssjelinek * affected by writing the new label. 6823e1bd7a2Ssjelinek */ 6833e1bd7a2Ssjelinek int 6843e1bd7a2Ssjelinek check_label_with_mount() 6853e1bd7a2Ssjelinek { 6863e1bd7a2Ssjelinek FILE *fp; 6873e1bd7a2Ssjelinek int part; 6883e1bd7a2Ssjelinek struct mnttab mnt_record; 6893e1bd7a2Ssjelinek struct mnttab *mp = &mnt_record; 6903e1bd7a2Ssjelinek int bm_mounted = 0; 6913e1bd7a2Ssjelinek 6923e1bd7a2Ssjelinek 6933e1bd7a2Ssjelinek /* 6943e1bd7a2Ssjelinek * If we are only checking part of the disk, the disk must 6953e1bd7a2Ssjelinek * have a partition map to check against. If it doesn't, 6963e1bd7a2Ssjelinek * we hope for the best. 6973e1bd7a2Ssjelinek */ 6983e1bd7a2Ssjelinek if (cur_parts == NULL) 6993e1bd7a2Ssjelinek return (0); /* Will be checked later */ 7003e1bd7a2Ssjelinek 7013e1bd7a2Ssjelinek /* 7023e1bd7a2Ssjelinek * Lock out interrupts because of the mntent protocol. 7033e1bd7a2Ssjelinek */ 7043e1bd7a2Ssjelinek enter_critical(); 7053e1bd7a2Ssjelinek /* 7063e1bd7a2Ssjelinek * Open the mount table. 7073e1bd7a2Ssjelinek */ 7083e1bd7a2Ssjelinek fp = fopen(MNTTAB, "r"); 7093e1bd7a2Ssjelinek if (fp == NULL) { 7103e1bd7a2Ssjelinek err_print("Unable to open mount table.\n"); 7113e1bd7a2Ssjelinek fullabort(); 7123e1bd7a2Ssjelinek } 7133e1bd7a2Ssjelinek /* 7143e1bd7a2Ssjelinek * Loop through the mount table until we run out of entries. 7153e1bd7a2Ssjelinek */ 7163e1bd7a2Ssjelinek while ((getmntent(fp, mp)) != -1) { 7173e1bd7a2Ssjelinek if ((part = getpartition(mp->mnt_special)) != -1) 7183e1bd7a2Ssjelinek bm_mounted |= (1 << part); 7193e1bd7a2Ssjelinek } 7203e1bd7a2Ssjelinek /* 7213e1bd7a2Ssjelinek * Close down the mount table. 7223e1bd7a2Ssjelinek */ 7233e1bd7a2Ssjelinek (void) fclose(fp); 7243e1bd7a2Ssjelinek exit_critical(); 7253e1bd7a2Ssjelinek 7263e1bd7a2Ssjelinek return (checkpartitions(bm_mounted)); 7273e1bd7a2Ssjelinek 7283e1bd7a2Ssjelinek } 7293e1bd7a2Ssjelinek 7303e1bd7a2Ssjelinek /* 7313e1bd7a2Ssjelinek * This Routine checks if any partitions specified 7323e1bd7a2Ssjelinek * are affected by writing the new label 7333e1bd7a2Ssjelinek */ 7343e1bd7a2Ssjelinek static int 7353e1bd7a2Ssjelinek checkpartitions(int bm_mounted) 7363e1bd7a2Ssjelinek { 7373e1bd7a2Ssjelinek struct dk_map32 *n; 7383e1bd7a2Ssjelinek struct dk_map *o; 7393e1bd7a2Ssjelinek struct dk_allmap old_map; 7403e1bd7a2Ssjelinek int i, found = 0; 741*8eb14f40SSharath M Srinivasan struct partition64 o_efi; 7423e1bd7a2Ssjelinek 7433e1bd7a2Ssjelinek /* 7443e1bd7a2Ssjelinek * Now we need to check that the current partition list and the 7453e1bd7a2Ssjelinek * previous partition list (which there must be if we actually 7463e1bd7a2Ssjelinek * have partitions mounted) overlap in any way on the mounted 7473e1bd7a2Ssjelinek * partitions 7483e1bd7a2Ssjelinek */ 7493e1bd7a2Ssjelinek 7503e1bd7a2Ssjelinek /* 751*8eb14f40SSharath M Srinivasan * Check if the user wants to online-label an 752*8eb14f40SSharath M Srinivasan * existing EFI label. 753*8eb14f40SSharath M Srinivasan */ 754*8eb14f40SSharath M Srinivasan if (cur_label == L_TYPE_EFI) { 755*8eb14f40SSharath M Srinivasan for (i = 0; i < EFI_NUMPAR; i++) { 756*8eb14f40SSharath M Srinivasan if (bm_mounted & (1 << i)) { 757*8eb14f40SSharath M Srinivasan o_efi.p_partno = i; 758*8eb14f40SSharath M Srinivasan if (ioctl(cur_file, DKIOCPARTITION, &o_efi) 759*8eb14f40SSharath M Srinivasan == -1) { 760*8eb14f40SSharath M Srinivasan err_print("Unable to get information " 761*8eb14f40SSharath M Srinivasan "for EFI partition %d.\n", i); 762*8eb14f40SSharath M Srinivasan return (-1); 763*8eb14f40SSharath M Srinivasan } 764*8eb14f40SSharath M Srinivasan 765*8eb14f40SSharath M Srinivasan /* 766*8eb14f40SSharath M Srinivasan * Partition can grow or remain same. 767*8eb14f40SSharath M Srinivasan */ 768*8eb14f40SSharath M Srinivasan if (o_efi.p_start == cur_parts->etoc-> 769*8eb14f40SSharath M Srinivasan efi_parts[i].p_start && o_efi.p_size 770*8eb14f40SSharath M Srinivasan <= cur_parts->etoc->efi_parts[i].p_size) { 771*8eb14f40SSharath M Srinivasan continue; 772*8eb14f40SSharath M Srinivasan } 773*8eb14f40SSharath M Srinivasan 774*8eb14f40SSharath M Srinivasan found = -1; 775*8eb14f40SSharath M Srinivasan } 776*8eb14f40SSharath M Srinivasan if (found) 777*8eb14f40SSharath M Srinivasan break; 778*8eb14f40SSharath M Srinivasan } 779*8eb14f40SSharath M Srinivasan 780*8eb14f40SSharath M Srinivasan } else { 781*8eb14f40SSharath M Srinivasan 782*8eb14f40SSharath M Srinivasan /* 7833e1bd7a2Ssjelinek * Get the "real" (on-disk) version of the partition table 7843e1bd7a2Ssjelinek */ 7853e1bd7a2Ssjelinek if (ioctl(cur_file, DKIOCGAPART, &old_map) == -1) { 7863e1bd7a2Ssjelinek err_print("Unable to get current partition map.\n"); 7873e1bd7a2Ssjelinek return (-1); 7883e1bd7a2Ssjelinek } 7893e1bd7a2Ssjelinek for (i = 0; i < NDKMAP; i++) { 7903e1bd7a2Ssjelinek if (bm_mounted & (1 << i)) { 7913e1bd7a2Ssjelinek /* 7923e1bd7a2Ssjelinek * This partition is mounted 7933e1bd7a2Ssjelinek */ 7943e1bd7a2Ssjelinek o = &old_map.dka_map[i]; 7953e1bd7a2Ssjelinek n = &cur_parts->pinfo_map[i]; 7963e1bd7a2Ssjelinek #ifdef DEBUG 7973e1bd7a2Ssjelinek fmt_print( 7983e1bd7a2Ssjelinek "checkpartitions :checking partition '%c' \n", i + PARTITION_BASE); 7993e1bd7a2Ssjelinek #endif 8003e1bd7a2Ssjelinek /* 8013e1bd7a2Ssjelinek * If partition is identical, we're fine. 802*8eb14f40SSharath M Srinivasan * If the partition grows, we're also fine, 803*8eb14f40SSharath M Srinivasan * because the routines in partition.c check 804*8eb14f40SSharath M Srinivasan * for overflow. It will (ultimately) be up 805*8eb14f40SSharath M Srinivasan * to the routines in partition.c to warn 806*8eb14f40SSharath M Srinivasan * about creation of overlapping partitions. 8073e1bd7a2Ssjelinek */ 8083e1bd7a2Ssjelinek if (o->dkl_cylno == n->dkl_cylno && 8093e1bd7a2Ssjelinek o->dkl_nblk <= n->dkl_nblk) { 8103e1bd7a2Ssjelinek #ifdef DEBUG 8113e1bd7a2Ssjelinek if (o->dkl_nblk < n->dkl_nblk) { 8123e1bd7a2Ssjelinek fmt_print( 8133e1bd7a2Ssjelinek "- new partition larger by %d blocks", n->dkl_nblk-o->dkl_nblk); 8143e1bd7a2Ssjelinek } 8153e1bd7a2Ssjelinek fmt_print("\n"); 8163e1bd7a2Ssjelinek #endif 8173e1bd7a2Ssjelinek continue; 8183e1bd7a2Ssjelinek } 8193e1bd7a2Ssjelinek #ifdef DEBUG 820*8eb14f40SSharath M Srinivasan fmt_print("- changes; old (%d,%d)->new " 821*8eb14f40SSharath M Srinivasan "(%d,%d)\n", o->dkl_cylno, o->dkl_nblk, n->dkl_cylno, n->dkl_nblk); 8223e1bd7a2Ssjelinek #endif 8233e1bd7a2Ssjelinek found = -1; 8243e1bd7a2Ssjelinek } 8253e1bd7a2Ssjelinek if (found) 8263e1bd7a2Ssjelinek break; 8273e1bd7a2Ssjelinek } 828*8eb14f40SSharath M Srinivasan } 8293e1bd7a2Ssjelinek 8303e1bd7a2Ssjelinek /* 8313e1bd7a2Ssjelinek * If we found trouble and we're running from a command file, 8323e1bd7a2Ssjelinek * quit before doing something we really regret. 8333e1bd7a2Ssjelinek */ 8343e1bd7a2Ssjelinek 8353e1bd7a2Ssjelinek if (found && option_f) { 8363e1bd7a2Ssjelinek err_print("Operation on mounted disks or \ 8373e1bd7a2Ssjelinek disks currently being used for swapping must be interactive.\n"); 8383e1bd7a2Ssjelinek cmdabort(SIGINT); 8393e1bd7a2Ssjelinek } 8403e1bd7a2Ssjelinek /* 8413e1bd7a2Ssjelinek * Return the result. 8423e1bd7a2Ssjelinek */ 8433e1bd7a2Ssjelinek return (found); 8443e1bd7a2Ssjelinek } 845