Print this page
6581 cmd/format should be able label virtio BLKDEV drives
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Toomas Soome <tsoome@me.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/format/auto_sense.c
          +++ new/usr/src/cmd/format/auto_sense.c
↓ open down ↓ 16 lines elided ↑ open up ↑
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2011 Gary Mills
  23   23   *
  24   24   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  25   25   * Use is subject to license terms.
  26   26   * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
       27 + * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
  27   28   */
  28   29  
  29   30  /*
  30   31   * This file contains functions to implement automatic configuration
  31   32   * of scsi disks.
  32   33   */
  33   34  #include "global.h"
  34   35  
  35   36  #include <fcntl.h>
  36   37  #include <stdlib.h>
↓ open down ↓ 166 lines elided ↑ open up ↑
 203  204  static struct disk_type *new_scsi_disk_type(
 204  205                                  int             fd,
 205  206                                  char            *disk_name,
 206  207                                  struct dk_label *label);
 207  208  static struct disk_info *find_scsi_disk_info(
 208  209                                  struct dk_cinfo *dkinfo);
 209  210  
 210  211  static struct disk_type *new_direct_disk_type(int fd, char *disk_name,
 211  212      struct dk_label *label);
 212  213  
 213      -static struct disk_info *find_direct_disk_info(struct dk_cinfo *dkinfo);
 214  214  static int efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc);
 215  215  static int auto_label_init(struct dk_label *label);
 216      -static struct ctlr_type *find_direct_ctlr_type(void);
 217      -static struct ctlr_info *find_direct_ctlr_info(struct dk_cinfo  *dkinfo);
 218      -static  struct disk_info *find_direct_disk_info(struct dk_cinfo *dkinfo);
 219      -static struct ctlr_type *find_vbd_ctlr_type(void);
 220      -static struct ctlr_info *find_vbd_ctlr_info(struct dk_cinfo *dkinfo);
 221      -static struct disk_info *find_vbd_disk_info(struct dk_cinfo *dkinfo);
      216 +static struct ctlr_type *find_ctlr_type(ushort_t);
      217 +static struct ctlr_info *find_ctlr_info(struct dk_cinfo *, ushort_t);
      218 +static struct disk_info *find_disk_info(struct dk_cinfo *, ushort_t);
 222  219  
 223  220  static char             *get_sun_disk_name(
 224  221                                  char            *disk_name,
 225  222                                  struct scsi_inquiry *inquiry);
 226  223  static char             *strcopy(
 227  224                                  char    *dst,
 228  225                                  char    *src,
 229  226                                  int     n);
 230  227  static  int             adjust_disk_geometry(diskaddr_t capacity, uint_t *cyl,
 231  228                                  uint_t *nsect, uint_t *nhead);
↓ open down ↓ 25 lines elided ↑ open up ↑
 257  254          struct ctlr_info *ctlr;
 258  255          struct dk_cinfo dkinfo;
 259  256          struct partition_info *part;
 260  257  
 261  258          if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
 262  259                  if (option_msg && diag_msg) {
 263  260                          err_print("DKIOCINFO failed\n");
 264  261                  }
 265  262                  return (NULL);
 266  263          }
 267      -        if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_DIRECT)) {
 268      -                ctlr = find_direct_ctlr_info(&dkinfo);
 269      -                disk_info = find_direct_disk_info(&dkinfo);
 270      -        } else if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_VBD)) {
 271      -                ctlr = find_vbd_ctlr_info(&dkinfo);
 272      -                disk_info = find_vbd_disk_info(&dkinfo);
      264 +        if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_DIRECT ||
      265 +            cur_ctype->ctype_ctype == DKC_VBD ||
      266 +            cur_ctype->ctype_ctype == DKC_BLKDEV)) {
      267 +                ctlr = find_ctlr_info(&dkinfo, cur_ctype->ctype_ctype);
      268 +                disk_info = find_disk_info(&dkinfo, cur_ctype->ctype_ctype);
 273  269          } else {
 274  270                  ctlr = find_scsi_ctlr_info(&dkinfo);
 275  271                  disk_info = find_scsi_disk_info(&dkinfo);
 276  272          }
 277  273  
 278  274          /*
 279  275           * get vendor, product, revision and capacity info.
 280  276           */
 281  277          if (get_disk_info(fd, label, disk_info) == -1) {
 282  278                  return ((struct disk_type *)NULL);
↓ open down ↓ 88 lines elided ↑ open up ↑
 371  367          int error;
 372  368  
 373  369          dk_ioc->dki_data_64 = (uint64_t)(uintptr_t)data;
 374  370          error = ioctl(fd, cmd, (void *)dk_ioc);
 375  371          dk_ioc->dki_data = data;
 376  372  
 377  373          return (error);
 378  374  }
 379  375  
 380  376  static struct ctlr_type *
 381      -find_direct_ctlr_type()
      377 +find_ctlr_type(ushort_t type)
 382  378  {
 383  379          struct  mctlr_list      *mlp;
 384  380  
 385      -        mlp = controlp;
      381 +        assert(type == DKC_DIRECT ||
      382 +            type == DKC_VBD ||
      383 +            type == DKC_BLKDEV);
 386  384  
 387      -        while (mlp != NULL) {
 388      -                if (mlp->ctlr_type->ctype_ctype == DKC_DIRECT) {
 389      -                        return (mlp->ctlr_type);
 390      -                }
 391      -                mlp = mlp->next;
 392      -        }
 393      -
 394      -        impossible("no DIRECT controller type");
 395      -
 396      -        return ((struct ctlr_type *)NULL);
 397      -}
 398      -
 399      -static struct ctlr_type *
 400      -find_vbd_ctlr_type()
 401      -{
 402      -        struct  mctlr_list      *mlp;
 403      -
 404  385          mlp = controlp;
 405  386  
 406  387          while (mlp != NULL) {
 407      -                if (mlp->ctlr_type->ctype_ctype == DKC_VBD) {
      388 +                if (mlp->ctlr_type->ctype_ctype == type) {
 408  389                          return (mlp->ctlr_type);
 409  390                  }
 410  391                  mlp = mlp->next;
 411  392          }
 412  393  
 413      -        impossible("no VBD controller type");
      394 +        impossible("no DIRECT/VBD/BLKDEV controller type");
 414  395  
 415  396          return ((struct ctlr_type *)NULL);
 416  397  }
 417  398  
 418  399  static struct ctlr_info *
 419      -find_direct_ctlr_info(
 420      -        struct dk_cinfo         *dkinfo)
      400 +find_ctlr_info(struct dk_cinfo *dkinfo, ushort_t type)
 421  401  {
 422  402          struct ctlr_info        *ctlr;
 423  403  
 424      -        if (dkinfo->dki_ctype != DKC_DIRECT)
 425      -                return (NULL);
      404 +        assert(type == DKC_DIRECT ||
      405 +            type == DKC_VBD ||
      406 +            type == DKC_BLKDEV);
 426  407  
 427  408          for (ctlr = ctlr_list; ctlr != NULL; ctlr = ctlr->ctlr_next) {
 428  409                  if (ctlr->ctlr_addr == dkinfo->dki_addr &&
 429  410                      ctlr->ctlr_space == dkinfo->dki_space &&
 430      -                    ctlr->ctlr_ctype->ctype_ctype == DKC_DIRECT) {
      411 +                    ctlr->ctlr_ctype->ctype_ctype == dkinfo->dki_ctype) {
 431  412                          return (ctlr);
 432  413                  }
 433  414          }
 434  415  
 435      -        impossible("no DIRECT controller info");
      416 +        impossible("no DIRECT/VBD/BLKDEV controller info");
 436  417          /*NOTREACHED*/
      418 +        return ((struct ctlr_info *)NULL);
 437  419  }
 438  420  
 439      -static struct ctlr_info *
 440      -find_vbd_ctlr_info(
 441      -        struct dk_cinfo         *dkinfo)
 442      -{
 443      -        struct ctlr_info        *ctlr;
 444      -
 445      -        if (dkinfo->dki_ctype != DKC_VBD)
 446      -                return (NULL);
 447      -
 448      -        for (ctlr = ctlr_list; ctlr != NULL; ctlr = ctlr->ctlr_next) {
 449      -                if (ctlr->ctlr_addr == dkinfo->dki_addr &&
 450      -                    ctlr->ctlr_space == dkinfo->dki_space &&
 451      -                    ctlr->ctlr_ctype->ctype_ctype == DKC_VBD) {
 452      -                        return (ctlr);
 453      -                }
 454      -        }
 455      -
 456      -        impossible("no VBD controller info");
 457      -        /*NOTREACHED*/
 458      -}
 459      -
 460  421  static  struct disk_info *
 461      -find_direct_disk_info(
 462      -        struct dk_cinfo         *dkinfo)
      422 +find_disk_info(struct dk_cinfo *dkinfo, ushort_t type)
 463  423  {
 464  424          struct disk_info        *disk;
 465  425          struct dk_cinfo         *dp;
 466  426  
 467      -        for (disk = disk_list; disk != NULL; disk = disk->disk_next) {
 468      -                assert(dkinfo->dki_ctype == DKC_DIRECT);
 469      -                dp = &disk->disk_dkinfo;
 470      -                if (dp->dki_ctype == dkinfo->dki_ctype &&
 471      -                    dp->dki_cnum == dkinfo->dki_cnum &&
 472      -                    dp->dki_unit == dkinfo->dki_unit &&
 473      -                    strcmp(dp->dki_dname, dkinfo->dki_dname) == 0) {
 474      -                        return (disk);
 475      -                }
 476      -        }
      427 +        assert(type == DKC_DIRECT ||
      428 +            type == DKC_VBD ||
      429 +            type == DKC_BLKDEV);
 477  430  
 478      -        impossible("No DIRECT disk info instance\n");
 479      -        /*NOTREACHED*/
 480      -}
 481      -
 482      -static  struct disk_info *
 483      -find_vbd_disk_info(
 484      -        struct dk_cinfo         *dkinfo)
 485      -{
 486      -        struct disk_info        *disk;
 487      -        struct dk_cinfo         *dp;
 488      -
 489  431          for (disk = disk_list; disk != NULL; disk = disk->disk_next) {
 490      -                assert(dkinfo->dki_ctype == DKC_VBD);
 491  432                  dp = &disk->disk_dkinfo;
 492  433                  if (dp->dki_ctype == dkinfo->dki_ctype &&
 493  434                      dp->dki_cnum == dkinfo->dki_cnum &&
 494  435                      dp->dki_unit == dkinfo->dki_unit &&
 495  436                      strcmp(dp->dki_dname, dkinfo->dki_dname) == 0) {
 496  437                          return (disk);
 497  438                  }
 498  439          }
 499  440  
 500      -        impossible("No VBD disk info instance\n");
      441 +        impossible("No DIRECT/VBD/BLKDEV disk info instance\n");
 501  442          /*NOTREACHED*/
      443 +        return ((struct disk_info *)NULL);
 502  444  }
 503  445  
 504  446  /*
 505  447   * To convert EFI to SMI labels, we need to get label geometry.
 506  448   * Unfortunately at this time there is no good way to do so.
 507  449   * DKIOCGGEOM will fail if disk is EFI labeled. So we hack around
 508  450   * it and clear EFI label, do a DKIOCGGEOM and put the EFI label
 509  451   * back on disk.
 510  452   * This routine gets the label geometry and initializes the label
 511  453   * It uses cur_file as opened device.
↓ open down ↓ 172 lines elided ↑ open up ↑
 684  626          if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
 685  627                  if (option_msg && diag_msg) {
 686  628                          err_print("DKIOCINFO failed\n");
 687  629                  }
 688  630                  return (NULL);
 689  631          }
 690  632  
 691  633          /*
 692  634           * Find the ctlr_info for this disk.
 693  635           */
 694      -        ctlr = find_direct_ctlr_info(&dkinfo);
      636 +        ctlr = find_ctlr_info(&dkinfo, dkinfo.dki_ctype);
 695  637  
 696  638          /*
 697  639           * Allocate a new disk type for the direct controller.
 698  640           */
 699  641          disk = (struct disk_type *)zalloc(sizeof (struct disk_type));
 700  642  
 701  643          /*
 702  644           * Find the disk_info instance for this disk.
 703  645           */
 704      -        disk_info = find_direct_disk_info(&dkinfo);
      646 +        disk_info = find_disk_info(&dkinfo, dkinfo.dki_ctype);
 705  647  
 706  648          /*
 707  649           * The controller and the disk should match.
 708  650           */
 709  651          assert(disk_info->disk_ctlr == ctlr);
 710  652  
 711  653          /*
 712  654           * Link the disk into the list of disks
 713  655           */
 714  656          dp = ctlr->ctlr_ctype->ctype_dlist;
↓ open down ↓ 1288 lines elided ↑ open up ↑
2003 1945          disk_info->disk_parts = part;
2004 1946  
2005 1947          return (disk);
2006 1948  }
2007 1949  
2008 1950  
2009 1951  /*
2010 1952   * Delete a disk type from disk type list.
2011 1953   */
2012 1954  int
2013      -delete_disk_type(
2014      -                struct disk_type *disk_type)
     1955 +delete_disk_type(struct disk_type *disk_type)
2015 1956  {
2016 1957          struct ctlr_type        *ctlr;
2017 1958          struct disk_type        *dp, *disk;
2018 1959  
2019      -        if (cur_ctype->ctype_ctype == DKC_DIRECT)
2020      -                ctlr = find_direct_ctlr_type();
2021      -        else if (cur_ctype->ctype_ctype == DKC_VBD)
2022      -                ctlr = find_vbd_ctlr_type();
     1960 +        if (cur_ctype->ctype_ctype == DKC_DIRECT ||
     1961 +            cur_ctype->ctype_ctype == DKC_VBD ||
     1962 +            cur_ctype->ctype_ctype == DKC_BLKDEV)
     1963 +                ctlr = find_ctlr_type(cur_ctype->ctype_ctype);
2023 1964          else
2024 1965                  ctlr = find_scsi_ctlr_type();
2025 1966          if (ctlr == NULL || ctlr->ctype_dlist == NULL) {
2026 1967                  return (-1);
2027 1968          }
2028 1969  
2029 1970          disk = ctlr->ctype_dlist;
2030 1971          if (disk == disk_type) {
2031 1972                  ctlr->ctype_dlist = disk->dtype_next;
2032 1973                  if (cur_label == L_TYPE_EFI)
↓ open down ↓ 117 lines elided ↑ open up ↑
2150 2091  
2151 2092  /*
2152 2093   * adjust disk geometry.
2153 2094   * This is used when disk reports a disk geometry page having
2154 2095   * no of physical cylinders is < 3 which is the minimum required
2155 2096   * by Solaris (2 for storing labels and at least one as a data
2156 2097   * cylinder )
2157 2098   */
2158 2099  int
2159 2100  adjust_disk_geometry(diskaddr_t capacity, uint_t *cyl, uint_t *nhead,
2160      -        uint_t *nsect)
     2101 +    uint_t *nsect)
2161 2102  {
2162 2103          uint_t  lcyl = *cyl;
2163 2104          uint_t  lnhead = *nhead;
2164 2105          uint_t  lnsect = *nsect;
2165 2106  
2166 2107          assert(lcyl < SUN_MIN_CYL);
2167 2108  
2168 2109          /*
2169 2110           * reduce nsect by 2 for each iteration  and re-calculate
2170 2111           * the number of cylinders.
↓ open down ↓ 118 lines elided ↑ open up ↑
2289 2230  #endif /* defined(_SUNOS_VTOC_8) */
2290 2231  
2291 2232  /*
2292 2233   * Calculate CHS values based on the capacity data.
2293 2234   *
2294 2235   * NOTE: This function is same as cmlb_convert_geomerty() function in
2295 2236   * cmlb kernel module.
2296 2237   */
2297 2238  static void
2298 2239  compute_chs_values(diskaddr_t total_capacity, diskaddr_t usable_capacity,
2299      -        uint_t *pcylp, uint_t *nheadp, uint_t *nsectp)
     2240 +    uint_t *pcylp, uint_t *nheadp, uint_t *nsectp)
2300 2241  {
2301 2242  
2302 2243          /* Unlabeled SCSI floppy device */
2303 2244          if (total_capacity < 160) {
2304 2245                  /* Less than 80K */
2305 2246                  *nheadp = 1;
2306 2247                  *pcylp = total_capacity;
2307 2248                  *nsectp = 1;
2308 2249                  return;
2309 2250          } else if (total_capacity <= 0x1000) {
↓ open down ↓ 56 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX