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 /*
228eb14f40SSharath 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"
568eb14f40SSharath M Srinivasan #include <sys/efi_partition.h>
573e1bd7a2Ssjelinek
583e1bd7a2Ssjelinek /* Function prototypes */
593e1bd7a2Ssjelinek static struct swaptable *getswapentries(void);
603e1bd7a2Ssjelinek static void freeswapentries(struct swaptable *);
613e1bd7a2Ssjelinek static int getpartition(char *pathname);
623e1bd7a2Ssjelinek static int checkpartitions(int bm_mounted);
633e1bd7a2Ssjelinek
643e1bd7a2Ssjelinek static struct swaptable *
getswapentries(void)653e1bd7a2Ssjelinek getswapentries(void)
663e1bd7a2Ssjelinek {
67*b12aaafbSToomas Soome struct swaptable *st;
68*b12aaafbSToomas Soome struct swapent *swapent;
693e1bd7a2Ssjelinek int i, num;
703e1bd7a2Ssjelinek char fullpathname[MAXPATHLEN];
713e1bd7a2Ssjelinek
723e1bd7a2Ssjelinek /*
733e1bd7a2Ssjelinek * get the number of swap entries
743e1bd7a2Ssjelinek */
75*b12aaafbSToomas Soome if ((num = swapctl(SC_GETNSWP, NULL)) == -1) {
763e1bd7a2Ssjelinek err_print("swapctl error ");
773e1bd7a2Ssjelinek fullabort();
783e1bd7a2Ssjelinek }
793e1bd7a2Ssjelinek if (num == 0)
803e1bd7a2Ssjelinek return (NULL);
813e1bd7a2Ssjelinek if ((st = (swaptbl_t *)malloc(num * sizeof (swapent_t) + sizeof (int)))
823e1bd7a2Ssjelinek == NULL) {
833e1bd7a2Ssjelinek err_print("getswapentries: malloc failed.\n");
843e1bd7a2Ssjelinek fullabort();
853e1bd7a2Ssjelinek }
863e1bd7a2Ssjelinek swapent = st->swt_ent;
873e1bd7a2Ssjelinek for (i = 0; i < num; i++, swapent++) {
883e1bd7a2Ssjelinek if ((swapent->ste_path = malloc(MAXPATHLEN)) == NULL) {
893e1bd7a2Ssjelinek err_print("getswapentries: malloc failed.\n");
903e1bd7a2Ssjelinek fullabort();
913e1bd7a2Ssjelinek }
923e1bd7a2Ssjelinek }
933e1bd7a2Ssjelinek st->swt_n = num;
943e1bd7a2Ssjelinek if ((num = swapctl(SC_LIST, (void *)st)) == -1) {
953e1bd7a2Ssjelinek err_print("swapctl error ");
963e1bd7a2Ssjelinek fullabort();
973e1bd7a2Ssjelinek }
983e1bd7a2Ssjelinek swapent = st->swt_ent;
993e1bd7a2Ssjelinek for (i = 0; i < num; i++, swapent++) {
1003e1bd7a2Ssjelinek if (*swapent->ste_path != '/') {
1013e1bd7a2Ssjelinek (void) snprintf(fullpathname, sizeof (fullpathname),
1023e1bd7a2Ssjelinek "/dev/%s", swapent->ste_path);
1033e1bd7a2Ssjelinek (void) strcpy(swapent->ste_path, fullpathname);
1043e1bd7a2Ssjelinek }
1053e1bd7a2Ssjelinek }
1063e1bd7a2Ssjelinek return (st);
1073e1bd7a2Ssjelinek }
1083e1bd7a2Ssjelinek
1093e1bd7a2Ssjelinek static void
freeswapentries(struct swaptable * st)110*b12aaafbSToomas Soome freeswapentries(struct swaptable *st)
1113e1bd7a2Ssjelinek {
112*b12aaafbSToomas Soome struct swapent *swapent;
1133e1bd7a2Ssjelinek int i;
1143e1bd7a2Ssjelinek
1153e1bd7a2Ssjelinek swapent = st->swt_ent;
1163e1bd7a2Ssjelinek for (i = 0; i < st->swt_n; i++, swapent++)
1173e1bd7a2Ssjelinek free(swapent->ste_path);
1183e1bd7a2Ssjelinek free(st);
1193e1bd7a2Ssjelinek
1203e1bd7a2Ssjelinek }
1213e1bd7a2Ssjelinek
1223e1bd7a2Ssjelinek /*
1233e1bd7a2Ssjelinek * function getpartition:
1243e1bd7a2Ssjelinek */
1253e1bd7a2Ssjelinek static int
getpartition(char * pathname)126*b12aaafbSToomas Soome getpartition(char *pathname)
1273e1bd7a2Ssjelinek {
1283e1bd7a2Ssjelinek int mfd;
1293e1bd7a2Ssjelinek struct dk_cinfo dkinfo;
1303e1bd7a2Ssjelinek struct stat stbuf;
1313e1bd7a2Ssjelinek char raw_device[MAXPATHLEN];
1323e1bd7a2Ssjelinek int found = -1;
1333e1bd7a2Ssjelinek
1343e1bd7a2Ssjelinek /*
1353e1bd7a2Ssjelinek * Map the block device name to the raw device name.
1363e1bd7a2Ssjelinek * If it doesn't appear to be a device name, skip it.
1373e1bd7a2Ssjelinek */
1383e1bd7a2Ssjelinek if (match_substr(pathname, "/dev/") == 0)
1393e1bd7a2Ssjelinek return (found);
1403e1bd7a2Ssjelinek (void) strcpy(raw_device, "/dev/r");
1413e1bd7a2Ssjelinek (void) strcat(raw_device, pathname + strlen("/dev/"));
1423e1bd7a2Ssjelinek /*
1433e1bd7a2Ssjelinek * Determine if this appears to be a disk device.
1443e1bd7a2Ssjelinek * First attempt to open the device. If if fails, skip it.
1453e1bd7a2Ssjelinek */
1463e1bd7a2Ssjelinek if ((mfd = open(raw_device, O_RDWR | O_NDELAY)) < 0) {
1473e1bd7a2Ssjelinek return (found);
1483e1bd7a2Ssjelinek }
1493e1bd7a2Ssjelinek /*
1503e1bd7a2Ssjelinek * Must be a character device
1513e1bd7a2Ssjelinek */
1523e1bd7a2Ssjelinek if (fstat(mfd, &stbuf) == -1 || !S_ISCHR(stbuf.st_mode)) {
1533e1bd7a2Ssjelinek (void) close(mfd);
1543e1bd7a2Ssjelinek return (found);
1553e1bd7a2Ssjelinek }
1563e1bd7a2Ssjelinek /*
1573e1bd7a2Ssjelinek * Attempt to read the configuration info on the disk.
1583e1bd7a2Ssjelinek */
1593e1bd7a2Ssjelinek if (ioctl(mfd, DKIOCINFO, &dkinfo) < 0) {
1603e1bd7a2Ssjelinek (void) close(mfd);
1613e1bd7a2Ssjelinek return (found);
1623e1bd7a2Ssjelinek }
1633e1bd7a2Ssjelinek /*
1643e1bd7a2Ssjelinek * Finished with the opened device
1653e1bd7a2Ssjelinek */
1663e1bd7a2Ssjelinek (void) close(mfd);
1673e1bd7a2Ssjelinek
1683e1bd7a2Ssjelinek /*
1693e1bd7a2Ssjelinek * If it's not the disk we're interested in, it doesn't apply.
1703e1bd7a2Ssjelinek */
1713e1bd7a2Ssjelinek if (cur_disk->disk_dkinfo.dki_ctype != dkinfo.dki_ctype ||
1723e1bd7a2Ssjelinek cur_disk->disk_dkinfo.dki_cnum != dkinfo.dki_cnum ||
1733e1bd7a2Ssjelinek cur_disk->disk_dkinfo.dki_unit != dkinfo.dki_unit ||
174*b12aaafbSToomas Soome strcmp(cur_disk->disk_dkinfo.dki_dname, dkinfo.dki_dname) != 0) {
1753e1bd7a2Ssjelinek return (found);
1763e1bd7a2Ssjelinek }
1773e1bd7a2Ssjelinek
1783e1bd7a2Ssjelinek /*
1793e1bd7a2Ssjelinek * Extract the partition that is mounted.
1803e1bd7a2Ssjelinek */
1813e1bd7a2Ssjelinek return (PARTITION(stbuf.st_rdev));
1823e1bd7a2Ssjelinek }
1833e1bd7a2Ssjelinek
1843e1bd7a2Ssjelinek /*
1853e1bd7a2Ssjelinek * This Routine checks to see if there are partitions used for swapping overlaps
1863e1bd7a2Ssjelinek * a given portion of a disk. If the start parameter is < 0, it means
1873e1bd7a2Ssjelinek * that the entire disk should be checked
1883e1bd7a2Ssjelinek */
1893e1bd7a2Ssjelinek int
checkswap(diskaddr_t start,diskaddr_t end)190*b12aaafbSToomas Soome checkswap(diskaddr_t start, diskaddr_t end)
1913e1bd7a2Ssjelinek {
1923e1bd7a2Ssjelinek struct swaptable *st;
1933e1bd7a2Ssjelinek struct swapent *swapent;
1943e1bd7a2Ssjelinek int i;
1953e1bd7a2Ssjelinek int found = 0;
1963e1bd7a2Ssjelinek struct dk_map32 *map;
1973e1bd7a2Ssjelinek int part;
1983e1bd7a2Ssjelinek
1993e1bd7a2Ssjelinek /*
2003e1bd7a2Ssjelinek * If we are only checking part of the disk, the disk must
2013e1bd7a2Ssjelinek * have a partition map to check against. If it doesn't,
2023e1bd7a2Ssjelinek * we hope for the best.
2033e1bd7a2Ssjelinek */
2043e1bd7a2Ssjelinek if (cur_parts == NULL)
2053e1bd7a2Ssjelinek return (0);
2063e1bd7a2Ssjelinek
2073e1bd7a2Ssjelinek /*
2083e1bd7a2Ssjelinek * check for swap entries
2093e1bd7a2Ssjelinek */
2103e1bd7a2Ssjelinek st = getswapentries();
2113e1bd7a2Ssjelinek /*
2123e1bd7a2Ssjelinek * if there are no swap entries return.
2133e1bd7a2Ssjelinek */
214*b12aaafbSToomas Soome if (st == NULL)
2153e1bd7a2Ssjelinek return (0);
2163e1bd7a2Ssjelinek swapent = st->swt_ent;
2173e1bd7a2Ssjelinek for (i = 0; i < st->swt_n; i++, swapent++) {
2183e1bd7a2Ssjelinek if ((part = getpartition(swapent->ste_path)) != -1) {
2193e1bd7a2Ssjelinek if (start == UINT_MAX64) {
2203e1bd7a2Ssjelinek found = -1;
2213e1bd7a2Ssjelinek break;
2223e1bd7a2Ssjelinek }
2233e1bd7a2Ssjelinek map = &cur_parts->pinfo_map[part];
2243e1bd7a2Ssjelinek if ((start >= (int)(map->dkl_cylno * spc() +
225*b12aaafbSToomas Soome map->dkl_nblk)) ||
226*b12aaafbSToomas Soome (end < (int)(map->dkl_cylno * spc()))) {
2273e1bd7a2Ssjelinek continue;
2283e1bd7a2Ssjelinek }
2293e1bd7a2Ssjelinek found = -1;
2303e1bd7a2Ssjelinek break;
2313e1bd7a2Ssjelinek };
2323e1bd7a2Ssjelinek }
2333e1bd7a2Ssjelinek freeswapentries(st);
2343e1bd7a2Ssjelinek /*
2353e1bd7a2Ssjelinek * If we found trouble and we're running from a command file,
2363e1bd7a2Ssjelinek * quit before doing something we really regret.
2373e1bd7a2Ssjelinek */
2383e1bd7a2Ssjelinek
2393e1bd7a2Ssjelinek if (found && option_f) {
2403e1bd7a2Ssjelinek err_print(
2413e1bd7a2Ssjelinek "Operation on disks being used for swapping must be interactive.\n");
2423e1bd7a2Ssjelinek cmdabort(SIGINT);
2433e1bd7a2Ssjelinek }
2443e1bd7a2Ssjelinek
2453e1bd7a2Ssjelinek return (found);
2463e1bd7a2Ssjelinek
2473e1bd7a2Ssjelinek
2483e1bd7a2Ssjelinek }
2493e1bd7a2Ssjelinek /*
2503e1bd7a2Ssjelinek * Determines if there are partitions that are a part of an SVM, VxVM, zpool
2513e1bd7a2Ssjelinek * volume or a live upgrade device, overlapping a given portion of a disk.
2523e1bd7a2Ssjelinek * Mounts and swap devices are checked in legacy format code.
2533e1bd7a2Ssjelinek */
2543e1bd7a2Ssjelinek int
checkdevinuse(char * cur_disk_path,diskaddr_t start,diskaddr_t end,int print,int check_label)2553e1bd7a2Ssjelinek checkdevinuse(char *cur_disk_path, diskaddr_t start, diskaddr_t end, int print,
2563e1bd7a2Ssjelinek int check_label)
2573e1bd7a2Ssjelinek {
2583e1bd7a2Ssjelinek
2593e1bd7a2Ssjelinek int error;
2603e1bd7a2Ssjelinek int found = 0;
2613e1bd7a2Ssjelinek int check = 0;
2623e1bd7a2Ssjelinek int i;
2633e1bd7a2Ssjelinek int bm_inuse = 0;
2643e1bd7a2Ssjelinek int part = 0;
2653e1bd7a2Ssjelinek uint64_t slice_start, slice_size;
2663e1bd7a2Ssjelinek dm_descriptor_t *slices = NULL;
2673e1bd7a2Ssjelinek nvlist_t *attrs = NULL;
2683e1bd7a2Ssjelinek char *usage;
2693e1bd7a2Ssjelinek char *name;
2703e1bd7a2Ssjelinek
2713e1bd7a2Ssjelinek /*
27282d71480Ssjelinek * If the user does not want to do in use checking, return immediately.
27382d71480Ssjelinek * Normally, this is handled in libdiskmgt. For format, there is more
27482d71480Ssjelinek * processing required, so we want to bypass the in use checking
27582d71480Ssjelinek * here.
27682d71480Ssjelinek */
27782d71480Ssjelinek
27882d71480Ssjelinek if (NOINUSE_SET)
27982d71480Ssjelinek return (0);
28082d71480Ssjelinek
28182d71480Ssjelinek /*
282d25b227dSzl149053 * Skip if it is not a real disk
283d25b227dSzl149053 *
284d25b227dSzl149053 * There could be two kinds of strings in cur_disk_path
285d25b227dSzl149053 * One starts with c?t?d?, while the other is a absolute path of a
286d25b227dSzl149053 * block device file.
287d25b227dSzl149053 */
288d25b227dSzl149053
289d25b227dSzl149053 if (*cur_disk_path != 'c') {
290d25b227dSzl149053 struct stat stbuf;
291d25b227dSzl149053 char majorname[16];
292d25b227dSzl149053 major_t majornum;
293d25b227dSzl149053
294d25b227dSzl149053 (void) stat(cur_disk_path, &stbuf);
295d25b227dSzl149053 majornum = major(stbuf.st_rdev);
296d25b227dSzl149053 (void) modctl(MODGETNAME, majorname, sizeof (majorname),
297d25b227dSzl149053 &majornum);
298d25b227dSzl149053
299d25b227dSzl149053 if (strcmp(majorname, "sd"))
300d25b227dSzl149053 if (strcmp(majorname, "ssd"))
301d25b227dSzl149053 if (strcmp(majorname, "cmdk"))
302d25b227dSzl149053 return (0);
303d25b227dSzl149053 }
304d25b227dSzl149053
305d25b227dSzl149053 /*
306d25b227dSzl149053 * Truncate the characters following "d*", such as "s*" or "p*"
307d25b227dSzl149053 */
308d25b227dSzl149053 cur_disk_path = basename(cur_disk_path);
309d25b227dSzl149053 name = strrchr(cur_disk_path, 'd');
310d25b227dSzl149053 if (name) {
311d25b227dSzl149053 name++;
3128eb14f40SSharath M Srinivasan for (; (*name <= '9') && (*name >= '0'); name++) {
3138eb14f40SSharath M Srinivasan }
314d25b227dSzl149053 *name = (char)0;
315d25b227dSzl149053 }
316d25b227dSzl149053
317d25b227dSzl149053
318d25b227dSzl149053 /*
3193e1bd7a2Ssjelinek * For format, we get basic 'in use' details from libdiskmgt. After
3203e1bd7a2Ssjelinek * that we must do the appropriate checking to see if the 'in use'
3213e1bd7a2Ssjelinek * details require a bit of additional work.
3223e1bd7a2Ssjelinek */
3233e1bd7a2Ssjelinek
3243e1bd7a2Ssjelinek dm_get_slices(cur_disk_path, &slices, &error);
3253e1bd7a2Ssjelinek if (error) {
3262b237d4bSny155746 /*
3272b237d4bSny155746 * If ENODEV, it actually means the device is not in use.
3282b237d4bSny155746 * We will return 0 without displaying error.
3292b237d4bSny155746 */
3302b237d4bSny155746 if (error != ENODEV) {
3312b237d4bSny155746 err_print("Error occurred with device in use"
3322b237d4bSny155746 "checking: %s\n", strerror(error));
3333e1bd7a2Ssjelinek return (found);
3343e1bd7a2Ssjelinek }
3352b237d4bSny155746 }
3363e1bd7a2Ssjelinek if (slices == NULL)
3373e1bd7a2Ssjelinek return (found);
3383e1bd7a2Ssjelinek
3394d7452f8SToomas Soome for (i = 0; slices[i] != 0; i++) {
3403e1bd7a2Ssjelinek /*
3413e1bd7a2Ssjelinek * If we are checking the whole disk
3423e1bd7a2Ssjelinek * then any and all in use data is
3433e1bd7a2Ssjelinek * relevant.
3443e1bd7a2Ssjelinek */
3453e1bd7a2Ssjelinek if (start == UINT_MAX64) {
3463e1bd7a2Ssjelinek name = dm_get_name(slices[i], &error);
3473e1bd7a2Ssjelinek if (error != 0 || !name) {
3483e1bd7a2Ssjelinek err_print("Error occurred with device "
3498eb14f40SSharath M Srinivasan "in use checking: %s\n", strerror(error));
3503e1bd7a2Ssjelinek continue;
3513e1bd7a2Ssjelinek }
3523e1bd7a2Ssjelinek if (dm_inuse(name, &usage, DM_WHO_FORMAT, &error) ||
3533e1bd7a2Ssjelinek error) {
3543e1bd7a2Ssjelinek if (error != 0) {
3553e1bd7a2Ssjelinek dm_free_name(name);
3563e1bd7a2Ssjelinek name = NULL;
3578eb14f40SSharath M Srinivasan err_print("Error occurred with "
3588eb14f40SSharath M Srinivasan "device in use checking: "
3598eb14f40SSharath M Srinivasan "%s\n", strerror(error));
3603e1bd7a2Ssjelinek continue;
3613e1bd7a2Ssjelinek }
3623e1bd7a2Ssjelinek dm_free_name(name);
3633e1bd7a2Ssjelinek name = NULL;
3643e1bd7a2Ssjelinek /*
3653e1bd7a2Ssjelinek * If this is a dump device, then it is
3663e1bd7a2Ssjelinek * a failure. You cannot format a slice
3673e1bd7a2Ssjelinek * that is a dedicated dump device.
3683e1bd7a2Ssjelinek */
3693e1bd7a2Ssjelinek
3703e1bd7a2Ssjelinek if (strstr(usage, DM_USE_DUMP)) {
3713e1bd7a2Ssjelinek if (print) {
3723e1bd7a2Ssjelinek err_print(usage);
3733e1bd7a2Ssjelinek free(usage);
3743e1bd7a2Ssjelinek }
3753e1bd7a2Ssjelinek dm_free_descriptors(slices);
3763e1bd7a2Ssjelinek return (1);
3773e1bd7a2Ssjelinek }
3783e1bd7a2Ssjelinek /*
3793e1bd7a2Ssjelinek * We really found a device that is in use.
3803e1bd7a2Ssjelinek * Set 'found' for the return value, and set
3813e1bd7a2Ssjelinek * 'check' to indicate below that we must
3823e1bd7a2Ssjelinek * get the partition number to set bm_inuse
3833e1bd7a2Ssjelinek * in the event we are trying to label this
3843e1bd7a2Ssjelinek * device. check_label is set when we are
3853e1bd7a2Ssjelinek * checking modifications for in use slices
3863e1bd7a2Ssjelinek * on the device.
3873e1bd7a2Ssjelinek */
3883e1bd7a2Ssjelinek found ++;
3893e1bd7a2Ssjelinek check = 1;
3903e1bd7a2Ssjelinek if (print) {
3913e1bd7a2Ssjelinek err_print(usage);
3923e1bd7a2Ssjelinek free(usage);
3933e1bd7a2Ssjelinek }
3943e1bd7a2Ssjelinek }
3953e1bd7a2Ssjelinek } else {
3963e1bd7a2Ssjelinek /*
3973e1bd7a2Ssjelinek * Before getting the in use data, verify that the
3983e1bd7a2Ssjelinek * current slice is within the range we are checking.
3993e1bd7a2Ssjelinek */
4003e1bd7a2Ssjelinek attrs = dm_get_attributes(slices[i], &error);
4013e1bd7a2Ssjelinek if (error) {
4023e1bd7a2Ssjelinek err_print("Error occurred with device in use "
4033e1bd7a2Ssjelinek "checking: %s\n", strerror(error));
4043e1bd7a2Ssjelinek continue;
4053e1bd7a2Ssjelinek }
4063e1bd7a2Ssjelinek if (attrs == NULL) {
4073e1bd7a2Ssjelinek continue;
4083e1bd7a2Ssjelinek }
4093e1bd7a2Ssjelinek
4103e1bd7a2Ssjelinek (void) nvlist_lookup_uint64(attrs, DM_START,
4113e1bd7a2Ssjelinek &slice_start);
4123e1bd7a2Ssjelinek (void) nvlist_lookup_uint64(attrs, DM_SIZE,
4133e1bd7a2Ssjelinek &slice_size);
4143e1bd7a2Ssjelinek if (start >= (slice_start + slice_size) ||
4153e1bd7a2Ssjelinek (end < slice_start)) {
4163e1bd7a2Ssjelinek nvlist_free(attrs);
4173e1bd7a2Ssjelinek attrs = NULL;
4183e1bd7a2Ssjelinek continue;
4193e1bd7a2Ssjelinek }
4203e1bd7a2Ssjelinek name = dm_get_name(slices[i], &error);
4213e1bd7a2Ssjelinek if (error != 0 || !name) {
4223e1bd7a2Ssjelinek err_print("Error occurred with device "
4238eb14f40SSharath M Srinivasan "in use checking: %s\n", strerror(error));
4243e1bd7a2Ssjelinek nvlist_free(attrs);
4253e1bd7a2Ssjelinek attrs = NULL;
4263e1bd7a2Ssjelinek continue;
4273e1bd7a2Ssjelinek }
4283e1bd7a2Ssjelinek if (dm_inuse(name, &usage,
4293e1bd7a2Ssjelinek DM_WHO_FORMAT, &error) || error) {
4303e1bd7a2Ssjelinek if (error != 0) {
4313e1bd7a2Ssjelinek dm_free_name(name);
4323e1bd7a2Ssjelinek name = NULL;
4338eb14f40SSharath M Srinivasan err_print("Error occurred with "
4348eb14f40SSharath M Srinivasan "device in use checking: "
4358eb14f40SSharath M Srinivasan "%s\n", strerror(error));
4363e1bd7a2Ssjelinek nvlist_free(attrs);
4373e1bd7a2Ssjelinek attrs = NULL;
4383e1bd7a2Ssjelinek continue;
4393e1bd7a2Ssjelinek }
4403e1bd7a2Ssjelinek dm_free_name(name);
4413e1bd7a2Ssjelinek name = NULL;
4423e1bd7a2Ssjelinek /*
4433e1bd7a2Ssjelinek * If this is a dump device, then it is
4443e1bd7a2Ssjelinek * a failure. You cannot format a slice
4453e1bd7a2Ssjelinek * that is a dedicated dump device.
4463e1bd7a2Ssjelinek */
4473e1bd7a2Ssjelinek if (strstr(usage, DM_USE_DUMP)) {
4483e1bd7a2Ssjelinek if (print) {
4493e1bd7a2Ssjelinek err_print(usage);
4503e1bd7a2Ssjelinek free(usage);
4513e1bd7a2Ssjelinek }
4523e1bd7a2Ssjelinek dm_free_descriptors(slices);
4533e1bd7a2Ssjelinek nvlist_free(attrs);
4543e1bd7a2Ssjelinek return (1);
4553e1bd7a2Ssjelinek }
4563e1bd7a2Ssjelinek /*
4573e1bd7a2Ssjelinek * We really found a device that is in use.
4583e1bd7a2Ssjelinek * Set 'found' for the return value, and set
4593e1bd7a2Ssjelinek * 'check' to indicate below that we must
4603e1bd7a2Ssjelinek * get the partition number to set bm_inuse
4613e1bd7a2Ssjelinek * in the event we are trying to label this
4623e1bd7a2Ssjelinek * device. check_label is set when we are
4633e1bd7a2Ssjelinek * checking modifications for in use slices
4643e1bd7a2Ssjelinek * on the device.
4653e1bd7a2Ssjelinek */
4663e1bd7a2Ssjelinek found ++;
4673e1bd7a2Ssjelinek check = 1;
4683e1bd7a2Ssjelinek if (print) {
4693e1bd7a2Ssjelinek err_print(usage);
4703e1bd7a2Ssjelinek free(usage);
4713e1bd7a2Ssjelinek }
4723e1bd7a2Ssjelinek }
4733e1bd7a2Ssjelinek }
4743e1bd7a2Ssjelinek /*
4753e1bd7a2Ssjelinek * If check is set it means we found a slice(the current slice)
4763e1bd7a2Ssjelinek * on this device in use in some way. We potentially want
4773e1bd7a2Ssjelinek * to check this slice when labeling is
4783e1bd7a2Ssjelinek * requested. We set bm_inuse with this partition value
4793e1bd7a2Ssjelinek * for use later if check_label was set when called.
4803e1bd7a2Ssjelinek */
4813e1bd7a2Ssjelinek if (check) {
4823e1bd7a2Ssjelinek name = dm_get_name(slices[i], &error);
4833e1bd7a2Ssjelinek if (error != 0 || !name) {
4843e1bd7a2Ssjelinek err_print("Error occurred with device "
4858eb14f40SSharath M Srinivasan "in use checking: %s\n", strerror(error));
4863e1bd7a2Ssjelinek nvlist_free(attrs);
4873e1bd7a2Ssjelinek attrs = NULL;
4883e1bd7a2Ssjelinek continue;
4893e1bd7a2Ssjelinek }
4903e1bd7a2Ssjelinek part = getpartition(name);
4913e1bd7a2Ssjelinek dm_free_name(name);
4923e1bd7a2Ssjelinek name = NULL;
4933e1bd7a2Ssjelinek if (part != -1) {
4943e1bd7a2Ssjelinek bm_inuse |= 1 << part;
4953e1bd7a2Ssjelinek }
4963e1bd7a2Ssjelinek check = 0;
4973e1bd7a2Ssjelinek }
4983e1bd7a2Ssjelinek /*
4993e1bd7a2Ssjelinek * If we have attributes then we have successfully
5003e1bd7a2Ssjelinek * found the slice we were looking for and we also
5013e1bd7a2Ssjelinek * know this means we are not searching the whole
5023e1bd7a2Ssjelinek * disk so break out of the loop
5033e1bd7a2Ssjelinek * now.
5043e1bd7a2Ssjelinek */
5053e1bd7a2Ssjelinek if (attrs) {
5063e1bd7a2Ssjelinek nvlist_free(attrs);
5073e1bd7a2Ssjelinek break;
5083e1bd7a2Ssjelinek }
5093e1bd7a2Ssjelinek }
5103e1bd7a2Ssjelinek
5113e1bd7a2Ssjelinek if (slices) {
5123e1bd7a2Ssjelinek dm_free_descriptors(slices);
5133e1bd7a2Ssjelinek }
5143e1bd7a2Ssjelinek
5153e1bd7a2Ssjelinek /*
5163e1bd7a2Ssjelinek * The user is trying to label the disk. We have to do special
5173e1bd7a2Ssjelinek * checking here to ensure they are not trying to modify a slice
5183e1bd7a2Ssjelinek * that is in use in an incompatible way.
5193e1bd7a2Ssjelinek */
5203e1bd7a2Ssjelinek if (check_label && bm_inuse) {
5213e1bd7a2Ssjelinek /*
5223e1bd7a2Ssjelinek * !0 indicates that we found a
5233e1bd7a2Ssjelinek * problem. In this case, we have overloaded
5243e1bd7a2Ssjelinek * the use of checkpartitions to work for
5253e1bd7a2Ssjelinek * in use devices. bm_inuse is representative
5263e1bd7a2Ssjelinek * of the slice that is in use, not that
5273e1bd7a2Ssjelinek * is mounted as is in the case of the normal
5283e1bd7a2Ssjelinek * use of checkpartitions.
5293e1bd7a2Ssjelinek *
5303e1bd7a2Ssjelinek * The call to checkpartitions will return !0 if
5313e1bd7a2Ssjelinek * we are trying to shrink a device that we have found
5323e1bd7a2Ssjelinek * to be in use above.
5333e1bd7a2Ssjelinek */
5343e1bd7a2Ssjelinek return (checkpartitions(bm_inuse));
5353e1bd7a2Ssjelinek }
5363e1bd7a2Ssjelinek
5373e1bd7a2Ssjelinek return (found);
5383e1bd7a2Ssjelinek }
5393e1bd7a2Ssjelinek /*
5403e1bd7a2Ssjelinek * This routine checks to see if there are mounted partitions overlapping
5413e1bd7a2Ssjelinek * a given portion of a disk. If the start parameter is < 0, it means
5423e1bd7a2Ssjelinek * that the entire disk should be checked.
5433e1bd7a2Ssjelinek */
5443e1bd7a2Ssjelinek int
checkmount(diskaddr_t start,diskaddr_t end)545*b12aaafbSToomas Soome checkmount(diskaddr_t start, diskaddr_t end)
5463e1bd7a2Ssjelinek {
5473e1bd7a2Ssjelinek FILE *fp;
5483e1bd7a2Ssjelinek int found = 0;
5493e1bd7a2Ssjelinek struct dk_map32 *map;
5503e1bd7a2Ssjelinek int part;
5513e1bd7a2Ssjelinek struct mnttab mnt_record;
5523e1bd7a2Ssjelinek struct mnttab *mp = &mnt_record;
5533e1bd7a2Ssjelinek
5543e1bd7a2Ssjelinek /*
5553e1bd7a2Ssjelinek * If we are only checking part of the disk, the disk must
5563e1bd7a2Ssjelinek * have a partition map to check against. If it doesn't,
5573e1bd7a2Ssjelinek * we hope for the best.
5583e1bd7a2Ssjelinek */
5593e1bd7a2Ssjelinek if (cur_parts == NULL)
5603e1bd7a2Ssjelinek return (0);
5613e1bd7a2Ssjelinek
5623e1bd7a2Ssjelinek /*
5633e1bd7a2Ssjelinek * Lock out interrupts because of the mntent protocol.
5643e1bd7a2Ssjelinek */
5653e1bd7a2Ssjelinek enter_critical();
5663e1bd7a2Ssjelinek /*
5673e1bd7a2Ssjelinek * Open the mount table.
5683e1bd7a2Ssjelinek */
5693e1bd7a2Ssjelinek fp = fopen(MNTTAB, "r");
5703e1bd7a2Ssjelinek if (fp == NULL) {
5713e1bd7a2Ssjelinek err_print("Unable to open mount table.\n");
5723e1bd7a2Ssjelinek fullabort();
5733e1bd7a2Ssjelinek }
5743e1bd7a2Ssjelinek /*
5753e1bd7a2Ssjelinek * Loop through the mount table until we run out of entries.
5763e1bd7a2Ssjelinek */
5773e1bd7a2Ssjelinek while ((getmntent(fp, mp)) != -1) {
5783e1bd7a2Ssjelinek
5793e1bd7a2Ssjelinek if ((part = getpartition(mp->mnt_special)) == -1)
5803e1bd7a2Ssjelinek continue;
5813e1bd7a2Ssjelinek
5823e1bd7a2Ssjelinek /*
5833e1bd7a2Ssjelinek * It's a mount on the disk we're checking. If we are
5843e1bd7a2Ssjelinek * checking whole disk, then we found trouble. We can
5853e1bd7a2Ssjelinek * quit searching.
5863e1bd7a2Ssjelinek */
5873e1bd7a2Ssjelinek if (start == UINT_MAX64) {
5883e1bd7a2Ssjelinek found = -1;
5893e1bd7a2Ssjelinek break;
5903e1bd7a2Ssjelinek }
5913e1bd7a2Ssjelinek
5923e1bd7a2Ssjelinek /*
5933e1bd7a2Ssjelinek * If the partition overlaps the zone we're checking,
5943e1bd7a2Ssjelinek * then we found trouble. We can quit searching.
5953e1bd7a2Ssjelinek */
5963e1bd7a2Ssjelinek map = &cur_parts->pinfo_map[part];
5973e1bd7a2Ssjelinek if ((start >= (int)(map->dkl_cylno * spc() + map->dkl_nblk)) ||
5983e1bd7a2Ssjelinek (end < (int)(map->dkl_cylno * spc()))) {
5993e1bd7a2Ssjelinek continue;
6003e1bd7a2Ssjelinek }
6013e1bd7a2Ssjelinek found = -1;
6023e1bd7a2Ssjelinek break;
6033e1bd7a2Ssjelinek }
6043e1bd7a2Ssjelinek /*
6053e1bd7a2Ssjelinek * Close down the mount table.
6063e1bd7a2Ssjelinek */
6073e1bd7a2Ssjelinek (void) fclose(fp);
6083e1bd7a2Ssjelinek exit_critical();
6093e1bd7a2Ssjelinek
6103e1bd7a2Ssjelinek /*
6113e1bd7a2Ssjelinek * If we found trouble and we're running from a command file,
6123e1bd7a2Ssjelinek * quit before doing something we really regret.
6133e1bd7a2Ssjelinek */
6143e1bd7a2Ssjelinek
6153e1bd7a2Ssjelinek if (found && option_f) {
6163e1bd7a2Ssjelinek err_print("Operation on mounted disks must be interactive.\n");
6173e1bd7a2Ssjelinek cmdabort(SIGINT);
6183e1bd7a2Ssjelinek }
6193e1bd7a2Ssjelinek /*
6203e1bd7a2Ssjelinek * Return the result.
6213e1bd7a2Ssjelinek */
6223e1bd7a2Ssjelinek return (found);
6233e1bd7a2Ssjelinek }
6243e1bd7a2Ssjelinek
6253e1bd7a2Ssjelinek int
check_label_with_swap(void)626*b12aaafbSToomas Soome check_label_with_swap(void)
6273e1bd7a2Ssjelinek {
6283e1bd7a2Ssjelinek int i;
6293e1bd7a2Ssjelinek struct swaptable *st;
6303e1bd7a2Ssjelinek struct swapent *swapent;
6313e1bd7a2Ssjelinek int part;
6323e1bd7a2Ssjelinek int bm_swap = 0;
6333e1bd7a2Ssjelinek
6343e1bd7a2Ssjelinek /*
6353e1bd7a2Ssjelinek * If we are only checking part of the disk, the disk must
6363e1bd7a2Ssjelinek * have a partition map to check against. If it doesn't,
6373e1bd7a2Ssjelinek * we hope for the best.
6383e1bd7a2Ssjelinek */
6393e1bd7a2Ssjelinek if (cur_parts == NULL)
6403e1bd7a2Ssjelinek return (0); /* Will be checked later */
6413e1bd7a2Ssjelinek
6423e1bd7a2Ssjelinek /*
6433e1bd7a2Ssjelinek * Check for swap entries
6443e1bd7a2Ssjelinek */
6453e1bd7a2Ssjelinek st = getswapentries();
6463e1bd7a2Ssjelinek /*
6473e1bd7a2Ssjelinek * if there are no swap entries return.
6483e1bd7a2Ssjelinek */
649*b12aaafbSToomas Soome if (st == NULL)
6503e1bd7a2Ssjelinek return (0);
6513e1bd7a2Ssjelinek swapent = st->swt_ent;
6523e1bd7a2Ssjelinek for (i = 0; i < st->swt_n; i++, swapent++)
6533e1bd7a2Ssjelinek if ((part = getpartition(swapent->ste_path)) != -1)
6543e1bd7a2Ssjelinek bm_swap |= (1 << part);
6553e1bd7a2Ssjelinek freeswapentries(st);
6563e1bd7a2Ssjelinek
6573e1bd7a2Ssjelinek return (checkpartitions(bm_swap));
6583e1bd7a2Ssjelinek }
6593e1bd7a2Ssjelinek
6603e1bd7a2Ssjelinek /*
6613e1bd7a2Ssjelinek * Check the new label with the existing label on the disk,
6623e1bd7a2Ssjelinek * to make sure that any mounted partitions are not being
6633e1bd7a2Ssjelinek * affected by writing the new label.
6643e1bd7a2Ssjelinek */
6653e1bd7a2Ssjelinek int
check_label_with_mount(void)666*b12aaafbSToomas Soome check_label_with_mount(void)
6673e1bd7a2Ssjelinek {
6683e1bd7a2Ssjelinek FILE *fp;
6693e1bd7a2Ssjelinek int part;
6703e1bd7a2Ssjelinek struct mnttab mnt_record;
6713e1bd7a2Ssjelinek struct mnttab *mp = &mnt_record;
6723e1bd7a2Ssjelinek int bm_mounted = 0;
6733e1bd7a2Ssjelinek
6743e1bd7a2Ssjelinek
6753e1bd7a2Ssjelinek /*
6763e1bd7a2Ssjelinek * If we are only checking part of the disk, the disk must
6773e1bd7a2Ssjelinek * have a partition map to check against. If it doesn't,
6783e1bd7a2Ssjelinek * we hope for the best.
6793e1bd7a2Ssjelinek */
6803e1bd7a2Ssjelinek if (cur_parts == NULL)
6813e1bd7a2Ssjelinek return (0); /* Will be checked later */
6823e1bd7a2Ssjelinek
6833e1bd7a2Ssjelinek /*
6843e1bd7a2Ssjelinek * Lock out interrupts because of the mntent protocol.
6853e1bd7a2Ssjelinek */
6863e1bd7a2Ssjelinek enter_critical();
6873e1bd7a2Ssjelinek /*
6883e1bd7a2Ssjelinek * Open the mount table.
6893e1bd7a2Ssjelinek */
6903e1bd7a2Ssjelinek fp = fopen(MNTTAB, "r");
6913e1bd7a2Ssjelinek if (fp == NULL) {
6923e1bd7a2Ssjelinek err_print("Unable to open mount table.\n");
6933e1bd7a2Ssjelinek fullabort();
6943e1bd7a2Ssjelinek }
6953e1bd7a2Ssjelinek /*
6963e1bd7a2Ssjelinek * Loop through the mount table until we run out of entries.
6973e1bd7a2Ssjelinek */
6983e1bd7a2Ssjelinek while ((getmntent(fp, mp)) != -1) {
6993e1bd7a2Ssjelinek if ((part = getpartition(mp->mnt_special)) != -1)
7003e1bd7a2Ssjelinek bm_mounted |= (1 << part);
7013e1bd7a2Ssjelinek }
7023e1bd7a2Ssjelinek /*
7033e1bd7a2Ssjelinek * Close down the mount table.
7043e1bd7a2Ssjelinek */
7053e1bd7a2Ssjelinek (void) fclose(fp);
7063e1bd7a2Ssjelinek exit_critical();
7073e1bd7a2Ssjelinek
7083e1bd7a2Ssjelinek return (checkpartitions(bm_mounted));
7093e1bd7a2Ssjelinek
7103e1bd7a2Ssjelinek }
7113e1bd7a2Ssjelinek
7123e1bd7a2Ssjelinek /*
7133e1bd7a2Ssjelinek * This Routine checks if any partitions specified
7143e1bd7a2Ssjelinek * are affected by writing the new label
7153e1bd7a2Ssjelinek */
7163e1bd7a2Ssjelinek static int
checkpartitions(int bm_mounted)7173e1bd7a2Ssjelinek checkpartitions(int bm_mounted)
7183e1bd7a2Ssjelinek {
7193e1bd7a2Ssjelinek struct dk_map32 *n;
7203e1bd7a2Ssjelinek struct dk_map *o;
7213e1bd7a2Ssjelinek struct dk_allmap old_map;
7223e1bd7a2Ssjelinek int i, found = 0;
7238eb14f40SSharath M Srinivasan struct partition64 o_efi;
7243e1bd7a2Ssjelinek
7253e1bd7a2Ssjelinek /*
7263e1bd7a2Ssjelinek * Now we need to check that the current partition list and the
7273e1bd7a2Ssjelinek * previous partition list (which there must be if we actually
7283e1bd7a2Ssjelinek * have partitions mounted) overlap in any way on the mounted
7293e1bd7a2Ssjelinek * partitions
7303e1bd7a2Ssjelinek */
7313e1bd7a2Ssjelinek
7323e1bd7a2Ssjelinek /*
7338eb14f40SSharath M Srinivasan * Check if the user wants to online-label an
7348eb14f40SSharath M Srinivasan * existing EFI label.
7358eb14f40SSharath M Srinivasan */
7368eb14f40SSharath M Srinivasan if (cur_label == L_TYPE_EFI) {
7378eb14f40SSharath M Srinivasan for (i = 0; i < EFI_NUMPAR; i++) {
7388eb14f40SSharath M Srinivasan if (bm_mounted & (1 << i)) {
7398eb14f40SSharath M Srinivasan o_efi.p_partno = i;
7408eb14f40SSharath M Srinivasan if (ioctl(cur_file, DKIOCPARTITION, &o_efi)
7418eb14f40SSharath M Srinivasan == -1) {
7428eb14f40SSharath M Srinivasan err_print("Unable to get information "
7438eb14f40SSharath M Srinivasan "for EFI partition %d.\n", i);
7448eb14f40SSharath M Srinivasan return (-1);
7458eb14f40SSharath M Srinivasan }
7468eb14f40SSharath M Srinivasan
7478eb14f40SSharath M Srinivasan /*
7488eb14f40SSharath M Srinivasan * Partition can grow or remain same.
7498eb14f40SSharath M Srinivasan */
7508eb14f40SSharath M Srinivasan if (o_efi.p_start == cur_parts->etoc->
7518eb14f40SSharath M Srinivasan efi_parts[i].p_start && o_efi.p_size
7528eb14f40SSharath M Srinivasan <= cur_parts->etoc->efi_parts[i].p_size) {
7538eb14f40SSharath M Srinivasan continue;
7548eb14f40SSharath M Srinivasan }
7558eb14f40SSharath M Srinivasan
7568eb14f40SSharath M Srinivasan found = -1;
7578eb14f40SSharath M Srinivasan }
7588eb14f40SSharath M Srinivasan if (found)
7598eb14f40SSharath M Srinivasan break;
7608eb14f40SSharath M Srinivasan }
7618eb14f40SSharath M Srinivasan
7628eb14f40SSharath M Srinivasan } else {
7638eb14f40SSharath M Srinivasan
7648eb14f40SSharath M Srinivasan /*
7653e1bd7a2Ssjelinek * Get the "real" (on-disk) version of the partition table
7663e1bd7a2Ssjelinek */
7673e1bd7a2Ssjelinek if (ioctl(cur_file, DKIOCGAPART, &old_map) == -1) {
7683e1bd7a2Ssjelinek err_print("Unable to get current partition map.\n");
7693e1bd7a2Ssjelinek return (-1);
7703e1bd7a2Ssjelinek }
7713e1bd7a2Ssjelinek for (i = 0; i < NDKMAP; i++) {
7723e1bd7a2Ssjelinek if (bm_mounted & (1 << i)) {
7733e1bd7a2Ssjelinek /*
7743e1bd7a2Ssjelinek * This partition is mounted
7753e1bd7a2Ssjelinek */
7763e1bd7a2Ssjelinek o = &old_map.dka_map[i];
7773e1bd7a2Ssjelinek n = &cur_parts->pinfo_map[i];
7783e1bd7a2Ssjelinek #ifdef DEBUG
7793e1bd7a2Ssjelinek fmt_print(
7803e1bd7a2Ssjelinek "checkpartitions :checking partition '%c' \n", i + PARTITION_BASE);
7813e1bd7a2Ssjelinek #endif
7823e1bd7a2Ssjelinek /*
7833e1bd7a2Ssjelinek * If partition is identical, we're fine.
7848eb14f40SSharath M Srinivasan * If the partition grows, we're also fine,
7858eb14f40SSharath M Srinivasan * because the routines in partition.c check
7868eb14f40SSharath M Srinivasan * for overflow. It will (ultimately) be up
7878eb14f40SSharath M Srinivasan * to the routines in partition.c to warn
7888eb14f40SSharath M Srinivasan * about creation of overlapping partitions.
7893e1bd7a2Ssjelinek */
7903e1bd7a2Ssjelinek if (o->dkl_cylno == n->dkl_cylno &&
7913e1bd7a2Ssjelinek o->dkl_nblk <= n->dkl_nblk) {
7923e1bd7a2Ssjelinek #ifdef DEBUG
7933e1bd7a2Ssjelinek if (o->dkl_nblk < n->dkl_nblk) {
7943e1bd7a2Ssjelinek fmt_print(
7953e1bd7a2Ssjelinek "- new partition larger by %d blocks", n->dkl_nblk-o->dkl_nblk);
7963e1bd7a2Ssjelinek }
7973e1bd7a2Ssjelinek fmt_print("\n");
7983e1bd7a2Ssjelinek #endif
7993e1bd7a2Ssjelinek continue;
8003e1bd7a2Ssjelinek }
8013e1bd7a2Ssjelinek #ifdef DEBUG
8028eb14f40SSharath M Srinivasan fmt_print("- changes; old (%d,%d)->new "
8038eb14f40SSharath M Srinivasan "(%d,%d)\n", o->dkl_cylno, o->dkl_nblk, n->dkl_cylno, n->dkl_nblk);
8043e1bd7a2Ssjelinek #endif
8053e1bd7a2Ssjelinek found = -1;
8063e1bd7a2Ssjelinek }
8073e1bd7a2Ssjelinek if (found)
8083e1bd7a2Ssjelinek break;
8093e1bd7a2Ssjelinek }
8108eb14f40SSharath M Srinivasan }
8113e1bd7a2Ssjelinek
8123e1bd7a2Ssjelinek /*
8133e1bd7a2Ssjelinek * If we found trouble and we're running from a command file,
8143e1bd7a2Ssjelinek * quit before doing something we really regret.
8153e1bd7a2Ssjelinek */
8163e1bd7a2Ssjelinek
8173e1bd7a2Ssjelinek if (found && option_f) {
8183e1bd7a2Ssjelinek err_print("Operation on mounted disks or \
8193e1bd7a2Ssjelinek disks currently being used for swapping must be interactive.\n");
8203e1bd7a2Ssjelinek cmdabort(SIGINT);
8213e1bd7a2Ssjelinek }
8223e1bd7a2Ssjelinek /*
8233e1bd7a2Ssjelinek * Return the result.
8243e1bd7a2Ssjelinek */
8253e1bd7a2Ssjelinek return (found);
8263e1bd7a2Ssjelinek }
827