On Mon, Mar 12, 2018 at 11:38:14AM +0100, Stefan Sperling wrote:
> I haven't had any feedback on the previous diff. However, I felt it
> was a bit of a hack, so I tried to come up with a cleaner solution.

Anyone? Can this go in now? I hope to get this tested across
many sparc64 machines during the 6.4 release cycle.

> The diff below opens the softraid boot chunk early on and keeps the
> handle open until a kernel has been loaded from the softraid volume.
> This means sr_strategy() does not have to worry about obtaining a
> handle from the firmware anymore.
> 
> Also consolidate some repeated lines of code in sr_strategy().
> 
> Tested on a T5220 ldom guest (CRYPTO) and a v240 machine (RAID1).
> 
> Index: boot.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/boot.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 boot.c
> --- boot.c    11 Sep 2016 17:53:26 -0000      1.27
> +++ boot.c    12 Mar 2018 10:26:23 -0000
> @@ -248,6 +248,8 @@ loadfile(int fd, char *args)
>       close(fd);
>  
>  #ifdef SOFTRAID
> +     if (bootdev_dip)
> +             OF_close(bootdev_dip->sr_handle);
>       sr_clear_keys();
>  #endif
>       chain(entry, args, ssym, esym);
> @@ -283,12 +285,11 @@ fail:
>  }
>  
>  #ifdef SOFTRAID
> -/* Set bootdev_dip to the software boot volume, if specified. */
> +/* Set bootdev_dip to the softraid boot volume, if specified. */
>  static int
>  srbootdev(const char *bootline)
>  {
>       struct sr_boot_volume *bv;
> -     struct diskinfo *dip;
>       int unit;
>  
>       bootdev_dip = NULL;
> @@ -320,9 +321,23 @@ srbootdev(const char *bootline)
>                               return EPERM;
>  
>               if (bv->sbv_diskinfo == NULL) {
> +                     struct sr_boot_chunk *bc;
> +                     struct diskinfo *dip, *bc_dip;
> +                     int sr_handle;
> +
> +                     /* All reads will come from the boot chunk. */
> +                     bc = sr_vol_boot_chunk(bv);
> +                     if (bc == NULL)
> +                             return ENXIO;
> +                     bc_dip = (struct diskinfo *)bc->sbc_diskinfo;
> +                     sr_handle = OF_open(bc_dip->path);
> +                     if (sr_handle == -1)
> +                             return EIO;
> +
>                       dip = alloc(sizeof(struct diskinfo));
>                       bzero(dip, sizeof(*dip));
>                       dip->sr_vol = bv;
> +                     dip->sr_handle = sr_handle;
>                       bv->sbv_diskinfo = dip;
>               }
>  
> @@ -331,7 +346,8 @@ srbootdev(const char *bootline)
>  
>               /* Attempt to read disklabel. */
>               bv->sbv_part = 'c';
> -             if (sr_getdisklabel(bv, &dip->disklabel)) {
> +             if (sr_getdisklabel(bv, &bootdev_dip->disklabel)) {
> +                     OF_close(bootdev_dip->sr_handle);
>                       free(bv->sbv_diskinfo, sizeof(struct diskinfo));
>                       bv->sbv_diskinfo = NULL;
>                       bootdev_dip = NULL;
> Index: disk.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/disk.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 disk.h
> --- disk.h    26 Nov 2014 20:30:41 -0000      1.1
> +++ disk.h    12 Mar 2018 10:26:23 -0000
> @@ -36,7 +36,10 @@
>  struct diskinfo {
>       char path[256];
>       struct disklabel disklabel;
> +
> +     /* Used during softraid boot. */
>       struct sr_boot_volume *sr_vol;
> +     int sr_handle; /* open handle for reading from boot chunk */
>  
>       TAILQ_ENTRY(diskinfo) list;
>  };
> Index: ofdev.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/ofdev.c,v
> retrieving revision 1.25
> diff -u -p -r1.25 ofdev.c
> --- ofdev.c   1 Oct 2015 16:08:20 -0000       1.25
> +++ ofdev.c   12 Mar 2018 10:26:23 -0000
> @@ -125,8 +125,8 @@ strategy(void *devdata, int rw, daddr32_
>  #ifdef SOFTRAID
>       /* Intercept strategy for softraid volumes. */
>       if (dev->type == OFDEV_SOFTRAID)
> -             return sr_strategy(bootdev_dip->sr_vol, rw,
> -                 blk, size, buf, rsize);
> +             return sr_strategy(bootdev_dip->sr_vol, bootdev_dip->sr_handle,
> +                 rw, blk, size, buf, rsize);
>  #endif
>       if (dev->type != OFDEV_DISK)
>               panic("strategy");
> Index: softraid_sparc64.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/softraid_sparc64.c,v
> retrieving revision 1.2
> diff -u -p -r1.2 softraid_sparc64.c
> --- softraid_sparc64.c        11 Sep 2016 17:53:26 -0000      1.2
> +++ softraid_sparc64.c        12 Mar 2018 10:26:23 -0000
> @@ -306,9 +306,25 @@ srprobe(void)
>       free(md, SR_META_SIZE * DEV_BSIZE);
>  }
>  
> +struct sr_boot_chunk *
> +sr_vol_boot_chunk(struct sr_boot_volume *bv)
> +{
> +     struct sr_boot_chunk *bc = NULL;
> +
> +     if (bv->sbv_level == 1 || bv->sbv_level == 'C' ) { /* RAID1 or CRYPTO */
> +             /* Select first online chunk. */
> +             SLIST_FOREACH(bc, &bv->sbv_chunks, sbc_link)
> +                     if (bc->sbc_state == BIOC_SDONLINE)
> +                             break;
> +     }
> +
> +     return bc;
> +}
> +
> +
>  int
> -sr_strategy(struct sr_boot_volume *bv, int rw, daddr32_t blk, size_t size,
> -    void *buf, size_t *rsize)
> +sr_strategy(struct sr_boot_volume *bv, int sr_handle, int rw, daddr32_t blk,
> +    size_t size, void *buf, size_t *rsize)
>  {
>       struct diskinfo *sr_dip, *dip;
>       struct partition *pp;
> @@ -320,7 +336,6 @@ sr_strategy(struct sr_boot_volume *bv, i
>       u_char iv[8];
>       u_char *bp;
>       int err;
> -     int ihandle;
>  
>       /* We only support read-only softraid. */
>       if (rw != F_READ)
> @@ -331,55 +346,28 @@ sr_strategy(struct sr_boot_volume *bv, i
>       blk +=
>           DL_GETPOFFSET(&sr_dip->disklabel.d_partitions[bv->sbv_part - 'a']);
>  
> +     bc = sr_vol_boot_chunk(bv);
> +     if (bc == NULL)
> +             return ENXIO;
> +
> +     dip = (struct diskinfo *)bc->sbc_diskinfo;
> +     pp = &dip->disklabel.d_partitions[bc->sbc_part - 'a'];
> +     bzero(&ofdev, sizeof(ofdev));
> +     ofdev.handle = sr_handle;
> +     ofdev.type = OFDEV_DISK;
> +     ofdev.bsize = DEV_BSIZE;
> +     ofdev.partoff = DL_GETPOFFSET(pp);
> +
>       if (bv->sbv_level == 0) {
>               return ENOTSUP;
>       } else if (bv->sbv_level == 1) {
> -
> -             /* Select first online chunk. */
> -             SLIST_FOREACH(bc, &bv->sbv_chunks, sbc_link)
> -                     if (bc->sbc_state == BIOC_SDONLINE)
> -                             break;
> -             if (bc == NULL)
> -                     return EIO;
> -
> -             dip = (struct diskinfo *)bc->sbc_diskinfo;
> -             pp = &dip->disklabel.d_partitions[bc->sbc_part - 'a'];
>               blk += bv->sbv_data_blkno;
>  
>               /* XXX - If I/O failed we should try another chunk... */
> -             ihandle = OF_open(dip->path);
> -             if (ihandle == -1)
> -                     return EIO;
> -             bzero(&ofdev, sizeof(ofdev));
> -             ofdev.handle = ihandle;
> -             ofdev.type = OFDEV_DISK;
> -             ofdev.bsize = DEV_BSIZE;
> -             ofdev.partoff = DL_GETPOFFSET(pp);
>               err = strategy(&ofdev, rw, blk, size, buf, rsize);
> -             OF_close(ihandle);
>               return err;
>  
>       } else if (bv->sbv_level == 'C') {
> -
> -             /* Select first online chunk. */
> -             SLIST_FOREACH(bc, &bv->sbv_chunks, sbc_link)
> -                     if (bc->sbc_state == BIOC_SDONLINE)
> -                             break;
> -             if (bc == NULL)
> -                     return EIO;
> -
> -             dip = (struct diskinfo *)bc->sbc_diskinfo;
> -             pp = &dip->disklabel.d_partitions[bc->sbc_part - 'a'];
> -
> -             ihandle = OF_open(dip->path);
> -             if (ihandle == -1)
> -                     return EIO;
> -             bzero(&ofdev, sizeof(ofdev));
> -             ofdev.handle = ihandle;
> -             ofdev.type = OFDEV_DISK;
> -             ofdev.bsize = DEV_BSIZE;
> -             ofdev.partoff = DL_GETPOFFSET(pp);
> -
>               /* XXX - select correct key. */
>               aes_xts_setkey(&ctx, (u_char *)bv->sbv_keys, 64);
>  
> @@ -395,7 +383,6 @@ sr_strategy(struct sr_boot_volume *bv, i
>                               printf("Read from crypto volume failed "
>                                   "(read %d bytes): %s\n", *rsize,
>                                   strerror(err));
> -                             OF_close(ihandle);
>                               return err;
>                       }
>                       bcopy(&blkno, iv, sizeof(blkno));
> @@ -404,7 +391,6 @@ sr_strategy(struct sr_boot_volume *bv, i
>                               aes_xts_decrypt(&ctx, bp + j);
>               }
>               *rsize = nsect * DEV_BSIZE;
> -             OF_close(ihandle);
>               return err;
>  
>       } else
> Index: softraid_sparc64.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/softraid_sparc64.h,v
> retrieving revision 1.3
> diff -u -p -r1.3 softraid_sparc64.h
> --- softraid_sparc64.h        11 Sep 2016 17:53:26 -0000      1.3
> +++ softraid_sparc64.h        12 Mar 2018 10:26:23 -0000
> @@ -21,8 +21,9 @@
>  
>  void srprobe(void);
>  
> +struct sr_boot_chunk *sr_vol_boot_chunk(struct sr_boot_volume *);
>  const char *sr_getdisklabel(struct sr_boot_volume *, struct disklabel *);
> -int  sr_strategy(struct sr_boot_volume *, int, daddr32_t, size_t,
> +int  sr_strategy(struct sr_boot_volume *, int, int, daddr32_t, size_t,
>           void *, size_t *);
>  
>  #endif /* _SOFTRAID_SPARC64_H */
> Index: vers.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/vers.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 vers.c
> --- vers.c    18 Sep 2016 16:36:09 -0000      1.10
> +++ vers.c    12 Mar 2018 10:26:23 -0000
> @@ -1 +1 @@
> -const char version[] = "1.9";
> +const char version[] = "1.10";
> 

Reply via email to