On Mon, Sep 02, 2013 at 08:20:11AM -0400, John Hynes wrote:
> On Mon, Sep 2, 2013 at 8:07 AM, Kenneth R Westerback <kwesterb...@rogers.com
> > wrote:
> 
> > On Mon, Sep 02, 2013 at 07:50:41AM -0400, John Hynes wrote:
> > > Greetings All,
> > >
> > > I have a softraid device, sd3, which was created as follows:
> > >
> > > bioctl -c 1 -l /dev/sd0a,/dev/sd1a,/dev/sd2a softraid0
> > >
> > > The chunk sd2a failed.  bioctl shows the RAID1 as degraded, and chunk
> > sd2a
> > > as OFFLINE.
> > >
> > > In order to rebuild, I'd need to set up the new sd2.  After replacing and
> > > zeroing the drive, I replaced the MBR with fdisk -yi /dev/sd2, which
> > worked
> > > fine.  Next, I copied the disklabel from sd0 to sd2, but disklabel
> > refused
> > > to write the new label, saying:
> > >
> > > disklabel: ioctl DIOCWDINFO: Open partition would move or shrink
> > > disklabel: unable to write label
> >
> > How exactly are you copying the disklabel? Is sd2 the same size as sd0?
> >
> 
> disklabel sd0 > disklabel.sd2; disklabel -R sd2 disklabel.sd0
> 
> The "new" sd2 is identical to the old, which is identical to the other
> disks.

Further information should be elicited by running a kernel with the diff
below. Which should at least tell us the (first) partition being rejected,
and whether it is the size or location that is problematic.

Coincidentally I'm working in this exact code, so there are some bonus
fixes in there.

.... Ken


Index: subr_disk.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_disk.c,v
retrieving revision 1.151
diff -u -p -r1.151 subr_disk.c
--- subr_disk.c 8 Aug 2013 23:25:06 -0000       1.151
+++ subr_disk.c 2 Sep 2013 13:40:03 -0000
@@ -645,22 +645,30 @@ setdisklabel(struct disklabel *olp, stru
 
        /* XXX missing check if other dos partitions will be overwritten */
 
-       while (openmask != 0) {
-               i = ffs(openmask) - 1;
-               openmask &= ~(1 << i);
-               if (nlp->d_npartitions <= i)
-                       return (EBUSY);
+       for (i = 0; i < MAXPARTITIONS; i++) {
                opp = &olp->d_partitions[i];
                npp = &nlp->d_partitions[i];
-               if (DL_GETPOFFSET(npp) != DL_GETPOFFSET(opp) ||
-                   DL_GETPSIZE(npp) < DL_GETPSIZE(opp))
-                       return (EBUSY);
+               if (openmask & (1 << i)) {
+                       if (DL_GETPOFFSET(npp) != DL_GETPOFFSET(opp)) {
+                               printf("Can't move open partition '%c'"
+                                   " from offset %lld to offset %lld\n",
+                                   'a' + i, DL_GETPOFFSET(opp),
+                                   DL_GETPOFFSET(npp));
+                               return (EBUSY); 
+                       }
+                       if (DL_GETPSIZE(npp) < DL_GETPSIZE(opp)) {
+                               printf("Can't shrink open partition '%c'"
+                                   "from %lld sectors to %lld sectors\n",
+                                   'a' + i, DL_GETPSIZE(opp),
+                                   DL_GETPSIZE(npp));
+                               return (EBUSY);
+                       }
+               }
                /*
                 * Copy internally-set partition information
                 * if new label doesn't include it.             XXX
                 */
                if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
-                       npp->p_fstype = opp->p_fstype;
                        npp->p_fragblock = opp->p_fragblock;
                        npp->p_cpg = opp->p_cpg;
                }

Reply via email to