Print this page
    
4846 HAL partition names don't match real partition names
    
      
        | Split | Close | 
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/hal/hald/solaris/devinfo_storage.c
          +++ new/usr/src/cmd/hal/hald/solaris/devinfo_storage.c
   1    1  /***************************************************************************
   2    2   *
   3    3   * devinfo_storage.c : storage devices
   4    4   *
   5    5   * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
   6    6   * Copyright 2013 Garrett D'Amore <garrett@damore.org>
        7 + * Copyright 2014 Andrew Stormont.
   7    8   *
   8    9   * Licensed under the Academic Free License version 2.1
   9   10   *
  10   11   **************************************************************************/
  11   12  
  12   13  #ifdef HAVE_CONFIG_H
  13   14  #  include <config.h>
  14   15  #endif
  15   16  
  16   17  #include <stdio.h>
  17   18  #include <string.h>
  18   19  #include <strings.h>
  19   20  #include <ctype.h>
  20   21  #include <libdevinfo.h>
  21   22  #include <sys/types.h>
  22   23  #include <sys/mkdev.h>
  23   24  #include <sys/stat.h>
  24   25  #include <sys/mntent.h>
  25   26  #include <sys/mnttab.h>
  26   27  
  27   28  #include "../osspec.h"
  28   29  #include "../logger.h"
  29   30  #include "../hald.h"
  30   31  #include "../hald_dbus.h"
  31   32  #include "../device_info.h"
  32   33  #include "../util.h"
  33   34  #include "../hald_runner.h"
  34   35  #include "hotplug.h"
  35   36  #include "devinfo.h"
  36   37  #include "devinfo_misc.h"
  37   38  #include "devinfo_storage.h"
  38   39  #include "osspec_solaris.h"
  39   40  
  40   41  #ifdef sparc
  41   42  #define WHOLE_DISK      "s2"
  42   43  #else
  43   44  #define WHOLE_DISK      "p0"
  44   45  #endif
  45   46  
  46   47  /* some devices,especially CDROMs, may take a while to be probed (values in ms) */
  47   48  #define DEVINFO_PROBE_STORAGE_TIMEOUT   60000
  48   49  #define DEVINFO_PROBE_VOLUME_TIMEOUT    60000
  49   50  
  50   51  typedef struct devinfo_storage_minor {
  51   52          char    *devpath;
  52   53          char    *devlink;
  53   54          char    *slice;
  54   55          dev_t   dev;
  55   56          int     dosnum; /* dos disk number or -1 */
  56   57  } devinfo_storage_minor_t;
  57   58  
  58   59  HalDevice *devinfo_ide_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
  59   60  static HalDevice *devinfo_ide_host_add(HalDevice *parent, di_node_t node, char *devfs_path);
  60   61  static HalDevice *devinfo_ide_device_add(HalDevice *parent, di_node_t node, char *devfs_path);
  61   62  static HalDevice *devinfo_ide_storage_add(HalDevice *parent, di_node_t node, char *devfs_path);
  62   63  HalDevice *devinfo_scsi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
  63   64  static HalDevice *devinfo_scsi_storage_add(HalDevice *parent, di_node_t node, char *devfs_path);
  64   65  HalDevice *devinfo_blkdev_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
  65   66  static HalDevice *devinfo_blkdev_storage_add(HalDevice *parent, di_node_t node, char *devfs_path);
  66   67  HalDevice *devinfo_floppy_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
  67   68  static void devinfo_floppy_add_volume(HalDevice *parent, di_node_t node);
  68   69  static HalDevice *devinfo_lofi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
  69   70  static void devinfo_lofi_add_minor(HalDevice *parent, di_node_t node, char *minor_path, char *devlink, dev_t dev);
  70   71  static void devinfo_storage_minors(HalDevice *parent, di_node_t node, gchar *devfs_path, gboolean);
  71   72  static struct devinfo_storage_minor *devinfo_storage_new_minor(char *maindev_path, char *slice,
  72   73      char *devlink, dev_t dev, int dosnum);
  73   74  static void devinfo_storage_free_minor(struct devinfo_storage_minor *m);
  74   75  HalDevice *devinfo_volume_add(HalDevice *parent, di_node_t node, devinfo_storage_minor_t *m);
  75   76  static void devinfo_volume_preprobing_done(HalDevice *d, gpointer userdata1, gpointer userdata2);
  76   77  static void devinfo_volume_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token);
  77   78  static void devinfo_storage_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token);
  78   79  static void devinfo_storage_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2);
  79   80  const gchar *devinfo_volume_get_prober (HalDevice *d, int *timeout);
  80   81  const gchar *devinfo_storage_get_prober (HalDevice *d, int *timeout);
  81   82  
  82   83  static char *devinfo_scsi_dtype2str(int dtype);
  83   84  static char *devinfo_volume_get_slice_name (char *devlink);
  84   85  static gboolean dos_to_dev(char *path, char **devpath, int *partnum);
  85   86  static gboolean is_dos_path(char *path, int *partnum);
  86   87  
  87   88  static void devinfo_storage_set_nicknames (HalDevice *d);
  88   89  
  89   90  DevinfoDevHandler devinfo_ide_handler = {
  90   91          devinfo_ide_add,
  91   92          NULL,
  92   93          NULL,
  93   94          NULL,
  94   95          NULL,
  95   96          NULL
  96   97  };
  97   98  DevinfoDevHandler devinfo_scsi_handler = {
  98   99          devinfo_scsi_add,
  99  100          NULL,
 100  101          NULL,
 101  102          NULL,
 102  103          NULL,
 103  104          NULL
 104  105  };
 105  106  DevinfoDevHandler devinfo_blkdev_handler = {
 106  107          devinfo_blkdev_add,
 107  108          NULL,
 108  109          NULL,
 109  110          NULL,
 110  111          NULL,
 111  112          NULL
 112  113  };
 113  114  DevinfoDevHandler devinfo_floppy_handler = {
 114  115          devinfo_floppy_add,
 115  116          NULL,
 116  117          NULL,
 117  118          NULL,
 118  119          NULL,
 119  120          NULL
 120  121  };
 121  122  DevinfoDevHandler devinfo_lofi_handler = {
 122  123          devinfo_lofi_add,
 123  124          NULL,
 124  125          NULL,
 125  126          NULL,
 126  127          NULL,
 127  128          NULL
 128  129  };
 129  130  DevinfoDevHandler devinfo_storage_handler = {
 130  131          NULL,
 131  132          NULL,
 132  133          devinfo_storage_hotplug_begin_add,
 133  134          NULL,
 134  135          devinfo_storage_probing_done,
 135  136          devinfo_storage_get_prober
 136  137  };
 137  138  DevinfoDevHandler devinfo_volume_handler = {
 138  139          NULL,
 139  140          NULL,
 140  141          devinfo_volume_hotplug_begin_add,
 141  142          NULL,
 142  143          NULL,
 143  144          devinfo_volume_get_prober
 144  145  };
 145  146  
 146  147  /* IDE */
 147  148  
 148  149  HalDevice *
 149  150  devinfo_ide_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
 150  151  {
 151  152          char    *s;
 152  153  
 153  154          if ((device_type != NULL) && (strcmp(device_type, "ide") == 0)) {
 154  155                  return (devinfo_ide_host_add(parent, node, devfs_path));
 155  156          }
 156  157  
 157  158          if ((di_prop_lookup_strings (DDI_DEV_T_ANY, node, "class", &s) > 0) &&
 158  159              (strcmp (s, "dada") == 0)) {
 159  160                  return (devinfo_ide_device_add(parent, node, devfs_path));
 160  161          }
 161  162  
 162  163          return (NULL);
 163  164  }
 164  165  
 165  166  static HalDevice *
 166  167  devinfo_ide_host_add(HalDevice *parent, di_node_t node, char *devfs_path)
 167  168  {
 168  169          HalDevice *d;
 169  170  
 170  171          d = hal_device_new ();
 171  172  
 172  173          devinfo_set_default_properties (d, parent, node, devfs_path);
 173  174          hal_device_property_set_string (d, "info.product", "IDE host controller");
 174  175          hal_device_property_set_string (d, "info.subsystem", "ide_host");
 175  176          hal_device_property_set_int (d, "ide_host.number", 0); /* XXX */
 176  177  
 177  178          devinfo_add_enqueue (d, devfs_path, &devinfo_ide_handler);
 178  179  
 179  180          return (d);
 180  181  }
 181  182  
 182  183  static HalDevice *
 183  184  devinfo_ide_device_add(HalDevice *parent, di_node_t node, char *devfs_path)
 184  185  {
 185  186          HalDevice *d;
 186  187  
 187  188          d = hal_device_new();
 188  189  
 189  190          devinfo_set_default_properties (d, parent, node, devfs_path);
 190  191          hal_device_property_set_string (parent, "info.product", "IDE device");
 191  192          hal_device_property_set_string (parent, "info.subsystem", "ide");
 192  193          hal_device_property_set_int (parent, "ide.host", 0); /* XXX */
 193  194          hal_device_property_set_int (parent, "ide.channel", 0);
 194  195  
 195  196          devinfo_add_enqueue (d, devfs_path, &devinfo_ide_handler);
 196  197  
 197  198          return (devinfo_ide_storage_add (d, node, devfs_path));
 198  199  }
 199  200  
 200  201  static HalDevice *
 201  202  devinfo_ide_storage_add(HalDevice *parent, di_node_t node, char *devfs_path)
 202  203  {
 203  204          HalDevice *d;
 204  205          char    *s;
 205  206          int     *i;
 206  207          char    *driver_name;
 207  208          char    udi[HAL_PATH_MAX];
 208  209  
 209  210          if ((driver_name = di_driver_name (node)) == NULL) {
 210  211                  return (NULL);
 211  212          }
 212  213  
 213  214          d = hal_device_new ();
 214  215  
 215  216          devinfo_set_default_properties (d, parent, node, devfs_path);
 216  217          hal_device_property_set_string (d, "info.category", "storage");
 217  218  
 218  219          hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
 219  220                  "%s/%s%d", hal_device_get_udi (parent), driver_name, di_instance (node));
 220  221          hal_device_set_udi (d, udi);
 221  222          hal_device_property_set_string (d, "info.udi", udi);
 222  223          PROP_STR(d, node, s, "devid", "info.product");
 223  224  
 224  225          hal_device_add_capability (d, "storage");
 225  226          hal_device_property_set_string (d, "storage.bus", "ide");
 226  227          hal_device_property_set_int (d, "storage.lun", 0);
 227  228          hal_device_property_set_string (d, "storage.drive_type", "disk");
 228  229  
 229  230          PROP_BOOL(d, node, i, "hotpluggable", "storage.hotpluggable");
 230  231          PROP_BOOL(d, node, i, "removable-media", "storage.removable");
 231  232  
 232  233          hal_device_property_set_bool (d, "storage.media_check_enabled", FALSE);
 233  234  
 234  235          /* XXX */
 235  236          hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
 236  237  
 237  238          hal_device_add_capability (d, "block");
 238  239  
 239  240          devinfo_storage_minors (d, node, (char *)devfs_path, FALSE);
 240  241  
 241  242          return (d);
 242  243  }
 243  244  
 244  245  /* SCSI */
 245  246  
 246  247  HalDevice *
 247  248  devinfo_scsi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
 248  249  {
 249  250          int     *i;
 250  251          char    *driver_name;
 251  252          HalDevice *d;
 252  253          char    udi[HAL_PATH_MAX];
 253  254  
 254  255          driver_name = di_driver_name (node);
 255  256          if ((driver_name == NULL) || (strcmp (driver_name, "sd") != 0)) {
 256  257                  return (NULL);
 257  258          }
 258  259  
 259  260          d = hal_device_new ();
 260  261  
 261  262          devinfo_set_default_properties (d, parent, node, devfs_path);
 262  263          hal_device_property_set_string (d, "info.subsystem", "scsi");
 263  264  
 264  265          hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
 265  266                  "%s/%s%d", hal_device_get_udi (parent), di_node_name(node), di_instance (node));
 266  267          hal_device_set_udi (d, udi);
 267  268          hal_device_property_set_string (d, "info.udi", udi);
 268  269  
 269  270          hal_device_property_set_int (d, "scsi.host", 
 270  271                  hal_device_property_get_int (parent, "scsi_host.host"));
 271  272          hal_device_property_set_int (d, "scsi.bus", 0);
 272  273          PROP_INT(d, node, i, "target", "scsi.target");
 273  274          PROP_INT(d, node, i, "lun", "scsi.lun");
 274  275          hal_device_property_set_string (d, "info.product", "SCSI Device");
 275  276  
 276  277          devinfo_add_enqueue (d, devfs_path, &devinfo_scsi_handler);
 277  278  
 278  279          return (devinfo_scsi_storage_add (d, node, devfs_path));
 279  280  }
 280  281  
 281  282  static HalDevice *
 282  283  devinfo_scsi_storage_add(HalDevice *parent, di_node_t node, char *devfs_path)
 283  284  {
 284  285          HalDevice *d;
 285  286          int     *i;
 286  287          char    *s;
 287  288          char    udi[HAL_PATH_MAX];
 288  289  
 289  290          d = hal_device_new ();
 290  291  
 291  292          devinfo_set_default_properties (d, parent, node, devfs_path);
 292  293          hal_device_property_set_string (d, "info.category", "storage");
 293  294  
 294  295          hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
 295  296                  "%s/sd%d", hal_device_get_udi (parent), di_instance (node));
 296  297          hal_device_set_udi (d, udi);
 297  298          hal_device_property_set_string (d, "info.udi", udi);
 298  299          PROP_STR(d, node, s, "inquiry-product-id", "info.product");
 299  300  
 300  301          hal_device_add_capability (d, "storage");
 301  302  
 302  303          hal_device_property_set_int (d, "storage.lun",
 303  304                  hal_device_property_get_int (parent, "scsi.lun"));
 304  305          PROP_BOOL(d, node, i, "hotpluggable", "storage.hotpluggable");
 305  306          PROP_BOOL(d, node, i, "removable-media", "storage.removable");
 306  307          hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
 307  308  
 308  309          /*
 309  310           * We have to enable polling not only for drives with removable media,
 310  311           * but also for hotpluggable devices, because when a disk is
 311  312           * unplugged while busy/mounted, there is not sysevent generated.
 312  313           * Instead, the HBA driver (scsa2usb, scsa1394) will notify sd driver
 313  314           * and the latter will report DKIO_DEV_GONE via DKIOCSTATE ioctl.
 314  315           * So we have to enable media check so that hald-addon-storage notices
 315  316           * the "device gone" condition and unmounts all associated volumes.
 316  317           */
 317  318          hal_device_property_set_bool (d, "storage.media_check_enabled",
 318  319              ((di_prop_lookup_ints(DDI_DEV_T_ANY, node, "removable-media", &i) >= 0) ||
 319  320              (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "hotpluggable", &i) >= 0)));
 320  321  
 321  322          if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "inquiry-device-type",
 322  323              &i) > 0) {
 323  324                  s = devinfo_scsi_dtype2str (*i);
 324  325                  hal_device_property_set_string (d, "storage.drive_type", s);
 325  326  
 326  327                  if (strcmp (s, "cdrom") == 0) {
 327  328                          hal_device_add_capability (d, "storage.cdrom");
 328  329                          hal_device_property_set_bool (d, "storage.no_partitions_hint", TRUE);
 329  330                          hal_device_property_set_bool (d, "storage.requires_eject", TRUE);
 330  331                  }
 331  332          }
 332  333  
 333  334          hal_device_add_capability (d, "block");
 334  335  
 335  336          devinfo_storage_minors (d, node, devfs_path, FALSE);
 336  337  
 337  338          return (d);
 338  339  }
 339  340  
 340  341  static char *
 341  342  devinfo_scsi_dtype2str(int dtype)
 342  343  {
 343  344          char *dtype2str[] = {
 344  345                  "disk"  ,         /* DTYPE_DIRECT         0x00 */
 345  346                  "tape"  ,         /* DTYPE_SEQUENTIAL     0x01 */
 346  347                  "printer",         /* DTYPE_PRINTER        0x02 */
 347  348                  "processor",         /* DTYPE_PROCESSOR      0x03 */
 348  349                  "worm"  ,         /* DTYPE_WORM           0x04 */
 349  350                  "cdrom" ,         /* DTYPE_RODIRECT       0x05 */
 350  351                  "scanner",         /* DTYPE_SCANNER        0x06 */
 351  352                  "cdrom" ,         /* DTYPE_OPTICAL        0x07 */
 352  353                  "changer",         /* DTYPE_CHANGER        0x08 */
 353  354                  "comm"  ,         /* DTYPE_COMM           0x09 */
 354  355                  "scsi"  ,         /* DTYPE_???            0x0A */
 355  356                  "scsi"  ,         /* DTYPE_???            0x0B */
 356  357                  "array_ctrl",         /* DTYPE_ARRAY_CTRL     0x0C */
 357  358                  "esi"   ,         /* DTYPE_ESI            0x0D */
 358  359                  "disk"            /* DTYPE_RBC            0x0E */
 359  360          };
 360  361  
 361  362          if (dtype < NELEM(dtype2str)) {
 362  363                  return (dtype2str[dtype]);
 363  364          } else {
 364  365                  return ("scsi");
 365  366          }
 366  367  
 367  368  }
 368  369  
 369  370  /* blkdev */
 370  371  
 371  372  HalDevice *
 372  373  devinfo_blkdev_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
 373  374  {
 374  375          int     *i;
 375  376          char    *driver_name;
 376  377          HalDevice *d;
 377  378          char    udi[HAL_PATH_MAX];
 378  379  
 379  380          driver_name = di_driver_name (node);
 380  381          if ((driver_name == NULL) || (strcmp (driver_name, "blkdev") != 0)) {
 381  382                  return (NULL);
 382  383          }
 383  384  
 384  385          d = hal_device_new ();
 385  386  
 386  387          devinfo_set_default_properties (d, parent, node, devfs_path);
 387  388          hal_device_property_set_string (d, "info.subsystem", "pseudo");
 388  389  
 389  390          hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
 390  391                  "%s/%s%d", hal_device_get_udi (parent), di_node_name(node), di_instance (node));
 391  392          hal_device_set_udi (d, udi);
 392  393          hal_device_property_set_string (d, "info.udi", udi);
 393  394          hal_device_property_set_string (d, "info.product", "Block Device");
 394  395  
 395  396          devinfo_add_enqueue (d, devfs_path, &devinfo_blkdev_handler);
 396  397  
 397  398          return (devinfo_blkdev_storage_add (d, node, devfs_path));
 398  399  }
 399  400  
 400  401  static HalDevice *
 401  402  devinfo_blkdev_storage_add(HalDevice *parent, di_node_t node, char *devfs_path)
 402  403  {
 403  404          HalDevice *d;
 404  405          char    *driver_name;
 405  406          int     *i;
 406  407          char    *s;
 407  408          char    udi[HAL_PATH_MAX];
 408  409  
 409  410          d = hal_device_new ();
 410  411  
 411  412          devinfo_set_default_properties (d, parent, node, devfs_path);
 412  413          hal_device_property_set_string (d, "info.category", "storage");
 413  414  
 414  415          hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
 415  416                  "%s/blkdev%d", hal_device_get_udi (parent), di_instance (node));
 416  417          hal_device_set_udi (d, udi);
 417  418          hal_device_property_set_string (d, "info.udi", udi);
 418  419  
 419  420          hal_device_add_capability (d, "storage");
 420  421  
 421  422          hal_device_property_set_int (d, "storage.lun", 0);
 422  423  
 423  424          PROP_BOOL(d, node, i, "hotpluggable", "storage.hotpluggable");
 424  425          PROP_BOOL(d, node, i, "removable-media", "storage.removable");
 425  426  
 426  427          hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
 427  428          hal_device_property_set_bool (d, "storage.media_check_enabled", TRUE);
 428  429          hal_device_property_set_string (d, "storage.drive_type", "disk");
 429  430  
 430  431          hal_device_add_capability (d, "block");
 431  432  
 432  433          devinfo_storage_minors (d, node, devfs_path, FALSE);
 433  434  
 434  435          return (d);
 435  436  }
 436  437  
 437  438  /* floppy */
 438  439  
 439  440  HalDevice *
 440  441  devinfo_floppy_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
 441  442  {
 442  443          char    *driver_name;
 443  444          char    *raw;
 444  445          char    udi[HAL_PATH_MAX];
 445  446          di_devlink_handle_t devlink_hdl;
 446  447          int     major;
 447  448          di_minor_t minor;
 448  449          dev_t   dev;
 449  450          HalDevice *d = NULL;
 450  451          char    *minor_path = NULL;
 451  452          char    *devlink = NULL;
 452  453  
 453  454          driver_name = di_driver_name (node);
 454  455          if ((driver_name == NULL) || (strcmp (driver_name, "fd") != 0)) {
 455  456                  return (NULL);
 456  457          }
 457  458  
 458  459          /*
 459  460           * The only minor node we're interested in is /dev/diskette*
 460  461           */
 461  462          major = di_driver_major(node);
 462  463          if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
 463  464                  return (NULL);
 464  465          }
 465  466          minor = DI_MINOR_NIL;
 466  467          while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
 467  468                  dev = di_minor_devt(minor);
 468  469                  if ((major != major(dev)) ||
 469  470                      (di_minor_type(minor) != DDM_MINOR) ||
 470  471                      (di_minor_spectype(minor) != S_IFBLK) ||
 471  472                      ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
 472  473                          continue;
 473  474                  }
 474  475                  if ((devlink = get_devlink(devlink_hdl, "diskette.+" , minor_path)) != NULL) {
 475  476                          break;
 476  477                  }
 477  478                  di_devfs_path_free (minor_path);
 478  479                  minor_path = NULL;
 479  480                  free(devlink);
 480  481                  devlink = NULL;
 481  482          }
 482  483          di_devlink_fini (&devlink_hdl);
 483  484  
 484  485          if ((devlink == NULL) || (minor_path == NULL)) {
 485  486                  HAL_INFO (("floppy devlink not found %s", devfs_path));
 486  487                  goto out;
 487  488          }
 488  489  
 489  490          d = hal_device_new ();
 490  491  
 491  492          devinfo_set_default_properties (d, parent, node, devfs_path);
 492  493          hal_device_property_set_string (d, "info.category", "storage");
 493  494          hal_device_add_capability (d, "storage");
 494  495          hal_device_property_set_string (d, "storage.bus", "platform");
 495  496          hal_device_property_set_bool (d, "storage.hotpluggable", FALSE);
 496  497          hal_device_property_set_bool (d, "storage.removable", TRUE);
 497  498          hal_device_property_set_bool (d, "storage.requires_eject", TRUE);
 498  499          hal_device_property_set_bool (d, "storage.media_check_enabled", FALSE);
 499  500          hal_device_property_set_string (d, "storage.drive_type", "floppy");
 500  501  
 501  502          hal_device_add_capability (d, "block");
 502  503          hal_device_property_set_bool (d, "block.is_volume", FALSE);
 503  504          hal_device_property_set_int (d, "block.major", major(dev));
 504  505          hal_device_property_set_int (d, "block.minor", minor(dev));
 505  506          hal_device_property_set_string (d, "block.device", devlink);
 506  507          raw = dsk_to_rdsk (devlink);
 507  508          hal_device_property_set_string (d, "block.solaris.raw_device", raw);
 508  509          free (raw);
 509  510  
 510  511          devinfo_add_enqueue (d, devfs_path, &devinfo_storage_handler);
 511  512  
 512  513          /* trigger initial probe-volume */
 513  514          devinfo_floppy_add_volume(d, node);
 514  515  
 515  516  out:
 516  517          di_devfs_path_free (minor_path);
 517  518          free(devlink);
 518  519  
 519  520          return (d);
 520  521  }
 521  522  
 522  523  static void
 523  524  devinfo_floppy_add_volume(HalDevice *parent, di_node_t node)
 524  525  {
 525  526          char    *devlink;
 526  527          char    *devfs_path;
 527  528          int     minor, major;
 528  529          dev_t   dev;
 529  530          struct devinfo_storage_minor *m;
 530  531  
 531  532          devfs_path = (char *)hal_device_property_get_string (parent, "solaris.devfs_path");
 532  533          devlink = (char *)hal_device_property_get_string (parent, "block.device");
 533  534          major = hal_device_property_get_int (parent, "block.major");
 534  535          minor = hal_device_property_get_int (parent, "block.minor");
 535  536          dev = makedev (major, minor);
 536  537  
 537  538          m = devinfo_storage_new_minor (devfs_path, WHOLE_DISK, devlink, dev, -1);
 538  539          devinfo_volume_add (parent, node, m);
 539  540          devinfo_storage_free_minor (m);
 540  541  }
 541  542  
 542  543  /*
 543  544   * After reprobing storage, reprobe its volumes.
 544  545   */
 545  546  static void
 546  547  devinfo_floppy_rescan_probing_done (HalDevice *d, guint32 exit_type, gint return_code,
 547  548      char **error, gpointer userdata1, gpointer userdata2)
 548  549  {
 549  550          void *end_token = (void *) userdata1;
 550  551          const char *devfs_path;
 551  552          di_node_t node;
 552  553          HalDevice *v;
 553  554  
 554  555          if (!hal_device_property_get_bool (d, "storage.removable.media_available")) {
 555  556                  HAL_INFO (("no floppy media", hal_device_get_udi (d)));
 556  557  
 557  558                  /* remove child (can only be single volume) */
 558  559                  if (((v = hal_device_store_match_key_value_string (hald_get_gdl(),
 559  560                      "info.parent", hal_device_get_udi (d))) != NULL) &&
 560  561                      ((devfs_path = hal_device_property_get_string (v,
 561  562                      "solaris.devfs_path")) != NULL)) {
 562  563                          devinfo_remove_enqueue ((char *)devfs_path, NULL);
 563  564                  }
 564  565          } else {
 565  566                  HAL_INFO (("floppy media found", hal_device_get_udi (d)));
 566  567  
 567  568                  if ((devfs_path = hal_device_property_get_string(d, "solaris.devfs_path")) == NULL) {
 568  569                          HAL_INFO (("no devfs_path", hal_device_get_udi (d)));
 569  570                          hotplug_event_process_queue ();
 570  571                          return;
 571  572                  }
 572  573                  if ((node = di_init (devfs_path, DINFOCPYALL)) == DI_NODE_NIL) {
 573  574                          HAL_INFO (("di_init %s failed %d", devfs_path, errno));
 574  575                          hotplug_event_process_queue ();
 575  576                          return;
 576  577                  }
 577  578  
 578  579                  devinfo_floppy_add_volume (d, node);
 579  580  
 580  581                  di_fini (node);
 581  582          }
 582  583  
 583  584          hotplug_event_process_queue ();
 584  585  }
 585  586          
 586  587  /* lofi */
 587  588  
 588  589  HalDevice *
 589  590  devinfo_lofi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
 590  591  {
 591  592          return (devinfo_lofi_add_major(parent,node, devfs_path, device_type, FALSE, NULL));
 592  593  }
 593  594  
 594  595  HalDevice *
 595  596  devinfo_lofi_add_major(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type,
 596  597      gboolean rescan, HalDevice *lofi_d)
 597  598  {
 598  599          char    *driver_name;
 599  600          HalDevice *d = NULL;
 600  601          char    udi[HAL_PATH_MAX];
 601  602          di_devlink_handle_t devlink_hdl;
 602  603          int     major;
 603  604          di_minor_t minor;
 604  605          dev_t   dev;
 605  606          char    *minor_path = NULL;
 606  607          char    *devlink = NULL;
 607  608  
 608  609          driver_name = di_driver_name (node);
 609  610          if ((driver_name == NULL) || (strcmp (driver_name, "lofi") != 0)) {
 610  611                  return (NULL);
 611  612          }
 612  613  
 613  614          if (!rescan) {
 614  615                  d = hal_device_new ();
 615  616  
 616  617                  devinfo_set_default_properties (d, parent, node, devfs_path);
 617  618                  hal_device_property_set_string (d, "info.subsystem", "pseudo");
 618  619  
 619  620                  hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
 620  621                          "%s/%s%d", hal_device_get_udi (parent), di_node_name(node), di_instance (node));
 621  622                  hal_device_set_udi (d, udi);
 622  623                  hal_device_property_set_string (d, "info.udi", udi);
 623  624  
 624  625                  devinfo_add_enqueue (d, devfs_path, &devinfo_lofi_handler);
 625  626          } else {
 626  627                  d = lofi_d;
 627  628          }
 628  629  
 629  630          /*
 630  631           * Unlike normal storage, as in devinfo_storage_minors(), where
 631  632           * sd instance -> HAL storage, sd minor node -> HAL volume,
 632  633           * lofi always has one instance, lofi minor -> HAL storage.
 633  634           * lofi storage never has slices, but it can have
 634  635           * embedded pcfs partitions that fstyp would recognize
 635  636           */
 636  637          major = di_driver_major(node);
 637  638          if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
 638  639                  return (d);
 639  640          }
 640  641          minor = DI_MINOR_NIL;
 641  642          while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
 642  643                  dev = di_minor_devt(minor);
 643  644                  if ((major != major(dev)) ||
 644  645                      (di_minor_type(minor) != DDM_MINOR) ||
 645  646                      (di_minor_spectype(minor) != S_IFBLK) ||
 646  647                      ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
 647  648                          continue;
 648  649                  }
 649  650                  if ((devlink = get_devlink(devlink_hdl, NULL, minor_path)) == NULL) {
 650  651                          di_devfs_path_free (minor_path);
 651  652                          continue;
 652  653                  }
 653  654  
 654  655                  if (!rescan ||
 655  656                      (hal_device_store_match_key_value_string (hald_get_gdl (),
 656  657                      "solaris.devfs_path", minor_path) == NULL)) {
 657  658                          devinfo_lofi_add_minor(d, node, minor_path, devlink, dev);
 658  659                  }
 659  660  
 660  661                  di_devfs_path_free (minor_path);
 661  662                  free(devlink);
 662  663          }
 663  664          di_devlink_fini (&devlink_hdl);
 664  665  
 665  666          return (d);
 666  667  }
 667  668  
 668  669  static void
 669  670  devinfo_lofi_add_minor(HalDevice *parent, di_node_t node, char *minor_path, char *devlink, dev_t dev)
 670  671  {
 671  672          HalDevice *d;
 672  673          char    *raw;
 673  674          char    *doslink;
 674  675          char    dospath[64];
 675  676          struct devinfo_storage_minor *m;
 676  677          int     i;
 677  678  
 678  679          /* add storage */
 679  680          d = hal_device_new ();
 680  681  
 681  682          devinfo_set_default_properties (d, parent, node, minor_path);
 682  683          hal_device_property_set_string (d, "info.category", "storage");
 683  684          hal_device_add_capability (d, "storage");
 684  685          hal_device_property_set_string (d, "storage.bus", "lofi");
 685  686          hal_device_property_set_bool (d, "storage.hotpluggable", TRUE);
 686  687          hal_device_property_set_bool (d, "storage.removable", FALSE);
 687  688          hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
 688  689          hal_device_property_set_string (d, "storage.drive_type", "disk");
 689  690          hal_device_add_capability (d, "block");
 690  691          hal_device_property_set_int (d, "block.major", major(dev));
 691  692          hal_device_property_set_int (d, "block.minor", minor(dev));
 692  693          hal_device_property_set_string (d, "block.device", devlink);
 693  694          raw = dsk_to_rdsk (devlink);
 694  695          hal_device_property_set_string (d, "block.solaris.raw_device", raw);
  
    | ↓ open down ↓ | 678 lines elided | ↑ open up ↑ | 
 695  696          free (raw);
 696  697          hal_device_property_set_bool (d, "block.is_volume", FALSE);
 697  698  
 698  699          devinfo_add_enqueue (d, minor_path, &devinfo_storage_handler);
 699  700  
 700  701          /* add volumes: one on main device and a few pcfs candidates */
 701  702          m = devinfo_storage_new_minor(minor_path, WHOLE_DISK, devlink, dev, -1);
 702  703          devinfo_volume_add (d, node, m);
 703  704          devinfo_storage_free_minor (m);
 704  705  
 705      -        doslink = (char *)calloc (1, strlen (devlink) + sizeof (":NNN") + 1);
      706 +        doslink = (char *)calloc (1, strlen (devlink) + sizeof ("pNN") + 1);
 706  707          if (doslink != NULL) {
 707  708                  for (i = 1; i < 16; i++) {
 708      -                        snprintf(dospath, sizeof (dospath), WHOLE_DISK":%d", i);
 709      -                        sprintf(doslink, "%s:%d", devlink, i);
      709 +                        snprintf(dospath, sizeof (dospath), "p%d", i);
      710 +                        sprintf(doslink, "%sp%d", devlink, i);
 710  711                          m = devinfo_storage_new_minor(minor_path, dospath, doslink, dev, i);
 711  712                          devinfo_volume_add (d, node, m);
 712  713                          devinfo_storage_free_minor (m);
 713  714                  }
 714  715                  free (doslink);
 715  716          }
 716  717  }
 717  718  
 718  719  void
 719  720  devinfo_lofi_remove_minor(char *parent_devfs_path, char *name)
 720  721  {
 721  722          GSList *i;
 722  723          GSList *devices;
 723  724          HalDevice *d = NULL;
 724  725          const char *devfs_path;
 725  726  
 726  727          devices = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
 727  728                  "block.solaris.raw_device", name);
 728  729          for (i = devices; i != NULL; i = g_slist_next (i)) {
 729  730                  if (hal_device_has_capability (HAL_DEVICE (i->data), "storage")) {
 730  731                          d = HAL_DEVICE (i->data);
 731  732                          break;
 732  733                  }
 733  734          }
 734  735          g_slist_free (devices);
 735  736  
 736  737          if (d == NULL) {
 737  738                  HAL_INFO (("device not found %s", name));
 738  739                  return;
 739  740          }
 740  741  
 741  742          if ((devfs_path = hal_device_property_get_string (d,
 742  743              "solaris.devfs_path")) == NULL) {
 743  744                  HAL_INFO (("devfs_path not found %s", hal_device_get_udi (d)));
 744  745                  return;
 745  746          }
 746  747  
 747  748          if (d != NULL) {
 748  749                  devinfo_remove_branch ((char *)devfs_path, d);
 749  750          }
 750  751  }
 751  752  
 752  753  /* common storage */
 753  754  
 754  755  static void
 755  756  devinfo_storage_free_minor(struct devinfo_storage_minor *m)
 756  757  {
 757  758          if (m != NULL) {
 758  759                  free (m->slice);
 759  760                  free (m->devlink);
 760  761                  free (m->devpath);
 761  762                  free (m);
 762  763          }
 763  764  }
 764  765  
 765  766  static struct devinfo_storage_minor *
 766  767  devinfo_storage_new_minor(char *maindev_path, char *slice, char *devlink, dev_t dev, int dosnum)
 767  768  {
 768  769          struct devinfo_storage_minor *m;
 769  770          int pathlen;
 770  771          char *devpath;
 771  772  
 772  773          m = (struct devinfo_storage_minor *)calloc (sizeof (struct devinfo_storage_minor), 1);
 773  774          if (m != NULL) {
 774  775                  /*
 775  776                   * For volume's devfs_path we'll use minor_path/slice instead of
 776  777                   * minor_path which we use for parent storage device.
 777  778                   */
 778  779                  pathlen = strlen (maindev_path) + strlen (slice) + 2;
 779  780                  devpath = (char *)calloc (1, pathlen);
 780  781                  snprintf(devpath, pathlen, "%s/%s", maindev_path, slice);
 781  782  
 782  783                  m->devpath = devpath;
 783  784                  m->devlink = strdup (devlink);
 784  785                  m->slice = strdup (slice);
 785  786                  m->dev = dev;
 786  787                  m->dosnum = dosnum;
 787  788                  if ((m->devpath == NULL) || (m->devlink == NULL)) {
 788  789                          devinfo_storage_free_minor (m);
 789  790                          m = NULL;
 790  791                  }
 791  792          }
 792  793          return (m);
 793  794  }
 794  795  
 795  796  /*
 796  797   * Storage minor nodes are potential "volume" objects.
 797  798   * This function also completes building the parent object (main storage device).
 798  799   */
 799  800  static void
 800  801  devinfo_storage_minors(HalDevice *parent, di_node_t node, gchar *devfs_path, gboolean rescan)
 801  802  {
 802  803          di_devlink_handle_t devlink_hdl;
 803  804          gboolean is_cdrom;
 804  805          const char *whole_disk;
 805  806          int     major;
 806  807          di_minor_t minor;
 807  808          dev_t   dev;
 808  809          char    *minor_path = NULL;
 809  810          char    *maindev_path = NULL;
 810  811          char    *devpath, *devlink;
 811  812          int     doslink_len;
 812  813          char    *doslink;
 813  814          char    dospath[64];
 814  815          char    *slice;
 815  816          int     pathlen;
 816  817          int     i;
 817  818          char    *raw;
 818  819          boolean_t maindev_is_d0;
 819  820          GQueue  *mq;
 820  821          HalDevice *volume;
 821  822          struct devinfo_storage_minor *m;
 822  823          struct devinfo_storage_minor *maindev = NULL;
 823  824  
 824  825          /* for cdroms whole disk is always s2 */
 825  826          is_cdrom = hal_device_has_capability (parent, "storage.cdrom");
 826  827          whole_disk = is_cdrom ? "s2" : WHOLE_DISK;
 827  828  
 828  829          major = di_driver_major(node);
 829  830  
 830  831          /* the "whole disk" p0/s2/d0 node must come first in the hotplug queue
 831  832           * so we put other minor nodes on the local queue and move to the
 832  833           * hotplug queue up in the end
 833  834           */
 834  835          if ((mq = g_queue_new()) == NULL) {
 835  836                  goto err;
 836  837          }
 837  838          if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
 838  839                  g_queue_free (mq);
 839  840                  goto err;
 840  841          }
 841  842          minor = DI_MINOR_NIL;
 842  843          while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
 843  844                  dev = di_minor_devt(minor);
 844  845                  if ((major != major(dev)) ||
 845  846                      (di_minor_type(minor) != DDM_MINOR) ||
 846  847                      (di_minor_spectype(minor) != S_IFBLK) ||
 847  848                      ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
 848  849                          continue;
 849  850                  }
 850  851                  if ((devlink = get_devlink(devlink_hdl, NULL, minor_path)) == NULL) {
 851  852                          di_devfs_path_free (minor_path);
  
    | ↓ open down ↓ | 132 lines elided | ↑ open up ↑ | 
 852  853                          continue;
 853  854                  }
 854  855  
 855  856                  slice = devinfo_volume_get_slice_name (devlink);
 856  857                  if (strlen (slice) < 2) {
 857  858                          free (devlink);
 858  859                          di_devfs_path_free (minor_path);
 859  860                          continue;
 860  861                  }
 861  862  
 862      -                /* ignore p1..N - we'll use p0:N instead */
 863      -                if ((strlen (slice) > 1) && (slice[0] == 'p') && isdigit(slice[1]) &&
 864      -                    ((atol(&slice[1])) > 0)) {
 865      -                        free (devlink);
 866      -                        di_devfs_path_free (minor_path);
 867      -                        continue;
 868      -                }
 869      -
 870  863                  m = devinfo_storage_new_minor(minor_path, slice, devlink, dev, -1);
 871  864                  if (m == NULL) {
 872  865                          free (devlink);
 873  866                          di_devfs_path_free (minor_path);
 874  867                          continue;
 875  868                  }
 876  869  
 877  870                  /* main device is either s2/p0 or d0, the latter taking precedence */
 878  871                  if ((strcmp (slice, "d0") == 0) ||
 879  872                      (((strcmp (slice, whole_disk) == 0) && (maindev == NULL)))) {
 880  873                          if (maindev_path != NULL) {
 881  874                                  di_devfs_path_free (maindev_path);
 882  875                          }
 883  876                          maindev_path = minor_path;
 884  877                          maindev = m;
 885  878                          g_queue_push_head (mq, maindev);
 886  879                  } else {
 887  880                          di_devfs_path_free (minor_path);
 888  881                          g_queue_push_tail (mq, m);
 889  882                  }
 890  883  
 891  884                  free (devlink);
 892  885          }
 893  886          di_devlink_fini (&devlink_hdl);
 894  887  
 895  888          if (maindev == NULL) {
 896  889                  /* shouldn't typically happen */
 897  890                  while (!g_queue_is_empty (mq)) {
 898  891                          devinfo_storage_free_minor (g_queue_pop_head (mq));
 899  892                  }
 900  893                  goto err;
 901  894          }
 902  895  
 903  896          /* first enqueue main storage device */
 904  897          if (!rescan) {
 905  898                  hal_device_property_set_int (parent, "block.major", major);
 906  899                  hal_device_property_set_int (parent, "block.minor", minor(maindev->dev));
 907  900                  hal_device_property_set_string (parent, "block.device", maindev->devlink);
  
    | ↓ open down ↓ | 28 lines elided | ↑ open up ↑ | 
 908  901                  raw = dsk_to_rdsk (maindev->devlink);
 909  902                  hal_device_property_set_string (parent, "block.solaris.raw_device", raw);
 910  903                  free (raw);
 911  904                  hal_device_property_set_bool (parent, "block.is_volume", FALSE);
 912  905                  hal_device_property_set_string (parent, "solaris.devfs_path", maindev_path);
 913  906                  devinfo_add_enqueue (parent, maindev_path, &devinfo_storage_handler);
 914  907          }
 915  908  
 916  909          /* add virtual dos volumes to enable pcfs probing */
 917  910          if (!is_cdrom) {
 918      -                doslink_len = strlen (maindev->devlink) + sizeof (":NNN") + 1;
      911 +                doslink_len = strlen (maindev->devlink) + sizeof ("pNN") + 1;
 919  912                  if ((doslink = (char *)calloc (1, doslink_len)) != NULL) {
 920  913                          for (i = 1; i < 16; i++) {
 921      -                                snprintf(dospath, sizeof (dospath), "%s:%d", maindev->slice, i);
 922      -                                snprintf(doslink, doslink_len, "%s:%d", maindev->devlink, i);
      914 +                                snprintf(dospath, sizeof (dospath), "%sp%d", maindev->slice, i);
      915 +                                snprintf(doslink, doslink_len, "%sp%d", maindev->devlink, i);
 923  916                                  m = devinfo_storage_new_minor(maindev_path, dospath, doslink, maindev->dev, i);
 924  917                                  g_queue_push_tail (mq, m);
 925  918                          }
 926  919                          free (doslink);
 927  920                  }
 928  921          }
 929  922  
 930  923          maindev_is_d0 = (strcmp (maindev->slice, "d0") == 0);
 931  924  
 932  925          /* enqueue all volumes */
 933  926          while (!g_queue_is_empty (mq)) {
 934  927                  m = g_queue_pop_head (mq);
 935  928  
 936  929                  /* if main device is d0, we'll throw away s2/p0 */
 937  930                  if (maindev_is_d0 && (strcmp (m->slice, whole_disk) == 0)) {
 938  931                          devinfo_storage_free_minor (m);
 939  932                          continue;
 940  933                  }
 941  934                  /* don't do p0 on cdrom */
 942  935                  if (is_cdrom && (strcmp (m->slice, "p0") == 0)) {
 943  936                          devinfo_storage_free_minor (m);
 944  937                          continue;
 945  938                  }
 946  939                  if (rescan) {
 947  940                          /* in rescan mode, don't reprobe existing volumes */
 948  941                          /* XXX detect volume removal? */
 949  942                          volume = hal_device_store_match_key_value_string (hald_get_gdl (),
 950  943                              "solaris.devfs_path", m->devpath);
 951  944                          if ((volume == NULL) || !hal_device_has_capability(volume, "volume")) {
 952  945                                  devinfo_volume_add (parent, node, m);
 953  946                          } else {
 954  947                                  HAL_INFO(("rescan volume exists %s", m->devpath));
 955  948                          }
 956  949                  } else {
 957  950                          devinfo_volume_add (parent, node, m);
 958  951                  }
 959  952                  devinfo_storage_free_minor (m);
 960  953          }
 961  954  
 962  955          if (maindev_path != NULL) {
 963  956                  di_devfs_path_free (maindev_path);
 964  957          }
 965  958  
 966  959          return;
 967  960  
 968  961  err:
 969  962          if (maindev_path != NULL) {
 970  963                  di_devfs_path_free (maindev_path);
 971  964          }
 972  965          if (!rescan) {
 973  966                  devinfo_add_enqueue (parent, devfs_path, &devinfo_storage_handler);
 974  967          }
 975  968  }
 976  969  
 977  970  HalDevice *
 978  971  devinfo_volume_add(HalDevice *parent, di_node_t node, devinfo_storage_minor_t *m)
 979  972  {
 980  973          HalDevice *d;
 981  974          char    *raw;
 982  975          char    udi[HAL_PATH_MAX];
 983  976          char    *devfs_path = m->devpath;
 984  977          char    *devlink = m->devlink;
 985  978          dev_t   dev = m->dev;
 986  979          int     dosnum = m->dosnum;
 987  980          char    *slice = m->slice;
 988  981  
 989  982          HAL_INFO (("volume_add: devfs_path=%s devlink=%s", devfs_path, devlink));
 990  983          d = hal_device_new ();
 991  984  
 992  985          devinfo_set_default_properties (d, parent, node, devfs_path);
 993  986          hal_device_property_set_string (d, "info.category", "volume");
 994  987  
 995  988          hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
 996  989                  "%s/%s", hal_device_get_udi (parent), slice);
 997  990          hal_device_set_udi (d, udi);
 998  991          hal_device_property_set_string (d, "info.udi", udi);
 999  992          hal_device_property_set_string (d, "info.product", slice);
1000  993  
1001  994          hal_device_add_capability (d, "volume");
1002  995          hal_device_add_capability (d, "block");
1003  996          hal_device_property_set_int (d, "block.major", major (dev));
1004  997          hal_device_property_set_int (d, "block.minor", minor (dev));
1005  998          hal_device_property_set_string (d, "block.device", devlink);
1006  999          raw = dsk_to_rdsk (devlink);
1007 1000          hal_device_property_set_string (d, "block.solaris.raw_device", raw);
1008 1001          free (raw);
1009 1002          hal_device_property_set_string (d, "block.solaris.slice", slice);
1010 1003          hal_device_property_set_bool (d, "block.is_volume", TRUE); /* XXX */
1011 1004  
1012 1005          hal_device_property_set_string (d, "block.storage_device", hal_device_get_udi (parent));
1013 1006  
1014 1007          /* set volume defaults */
1015 1008          hal_device_property_set_string (d, "volume.fstype", "");
1016 1009          hal_device_property_set_string (d, "volume.fsusage", "");
1017 1010          hal_device_property_set_string (d, "volume.fsversion", "");
1018 1011          hal_device_property_set_string (d, "volume.uuid", "");
1019 1012          hal_device_property_set_string (d, "volume.label", "");
1020 1013          hal_device_property_set_string (d, "volume.mount_point", "");
1021 1014          hal_device_property_set_bool (d, "volume.is_mounted", FALSE);
1022 1015          if (strcmp (hal_device_property_get_string (parent, "storage.drive_type"), "cdrom") == 0) {
1023 1016                  hal_device_property_set_bool (d, "volume.is_disc", TRUE);
1024 1017                  hal_device_add_capability (d, "volume.disc");
1025 1018          } else {
1026 1019                  hal_device_property_set_bool (d, "volume.is_disc", FALSE);
1027 1020          }
1028 1021  
1029 1022          if (dosnum > 0) {
1030 1023                  hal_device_property_set_bool (d, "volume.is_partition", TRUE);
1031 1024                  hal_device_property_set_int (d, "volume.partition.number", dosnum);
1032 1025          } else {
1033 1026                  hal_device_property_set_bool (d, "volume.is_partition", FALSE);
1034 1027          }
1035 1028  
1036 1029          /* prober may override these */
1037 1030          hal_device_property_set_int (d, "volume.block_size", 512);
1038 1031  
1039 1032          devinfo_add_enqueue (d, devfs_path, &devinfo_volume_handler);
1040 1033  
1041 1034          return (d);
1042 1035  }
1043 1036  
1044 1037  static void
1045 1038  devinfo_volume_preprobing_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
1046 1039  {
1047 1040          void *end_token = (void *) userdata1;
1048 1041          char *whole_disk;
1049 1042          char *block_device;
1050 1043          const char *storage_udi;
1051 1044          HalDevice *storage_d;
1052 1045          const char *slice;
1053 1046          int dos_num;
1054 1047  
1055 1048          if (hal_device_property_get_bool (d, "info.ignore")) {
1056 1049                  HAL_INFO (("Preprobing merged info.ignore==TRUE %s", hal_device_get_udi (d)));
1057 1050                  goto skip;
1058 1051          }
1059 1052  
1060 1053          /*
1061 1054           * Optimizations: only probe if there's a chance to find something
1062 1055           */
1063 1056          block_device = (char *)hal_device_property_get_string (d, "block.device");
1064 1057          storage_udi = hal_device_property_get_string (d, "block.storage_device");
1065 1058          slice = hal_device_property_get_string(d, "block.solaris.slice");
1066 1059          if ((block_device == NULL) || (storage_udi == NULL) ||
1067 1060              (slice == NULL) || (strlen (slice) < 2)) {
1068 1061                  HAL_INFO (("Malformed volume properties %s", hal_device_get_udi (d)));
1069 1062                  goto skip;
1070 1063          }
1071 1064          storage_d = hal_device_store_match_key_value_string (hald_get_gdl (), "info.udi", storage_udi);
1072 1065          if (storage_d == NULL) {
1073 1066                  HAL_INFO (("Storage device not found %s", hal_device_get_udi (d)));
1074 1067                  goto skip;
1075 1068          }
1076 1069  
1077 1070          whole_disk = hal_device_has_capability (storage_d,
1078 1071              "storage.cdrom") ? "s2" : WHOLE_DISK;
1079 1072  
1080 1073          if (is_dos_path(block_device, &dos_num)) {
1081 1074                  /* don't probe more dos volumes than probe-storage found */
1082 1075                  if ((hal_device_property_get_bool (storage_d, "storage.no_partitions_hint") ||
1083 1076                      (dos_num > hal_device_property_get_int (storage_d, "storage.solaris.num_dos_partitions")))) {
1084 1077                              HAL_INFO (("%d > %d %s", dos_num, hal_device_property_get_int (storage_d,
1085 1078                                  "storage.solaris.num_dos_partitions"), hal_device_get_udi (storage_d)));
1086 1079                          goto skip;
1087 1080                  }
1088 1081          } else {
1089 1082                  /* if no VTOC slices found, don't probe slices except s2 */
1090 1083                  if ((slice[0] == 's') && (isdigit(slice[1])) && ((strcmp (slice, whole_disk)) != 0) &&
1091 1084                      !hal_device_property_get_bool (storage_d, "storage.solaris.vtoc_slices")) {
1092 1085                          HAL_INFO (("Not probing slice %s", hal_device_get_udi (d)));
1093 1086                          goto skip;
1094 1087                  }
1095 1088          }
1096 1089  
1097 1090          HAL_INFO(("Probing udi=%s", hal_device_get_udi (d)));
1098 1091          hald_runner_run (d,
1099 1092                          "hald-probe-volume", NULL,
1100 1093                          DEVINFO_PROBE_VOLUME_TIMEOUT,
1101 1094                          devinfo_callouts_probing_done,
1102 1095                          (gpointer) end_token, userdata2);
1103 1096  
1104 1097          return;
1105 1098  
1106 1099  skip:
1107 1100          hal_device_store_remove (hald_get_tdl (), d);
1108 1101          g_object_unref (d);
1109 1102          hotplug_event_end (end_token);
1110 1103  }
1111 1104  
1112 1105  static void
1113 1106  devinfo_volume_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token)
1114 1107  {
1115 1108          HAL_INFO(("Preprobing volume udi=%s", hal_device_get_udi (d)));
1116 1109  
1117 1110          if (parent == NULL) {
1118 1111                  HAL_INFO (("no parent %s", hal_device_get_udi (d)));
1119 1112                  goto skip;
1120 1113          }
1121 1114  
1122 1115          if (hal_device_property_get_bool (parent, "info.ignore")) {
1123 1116                  HAL_INFO (("Ignoring volume: parent's info.ignore is TRUE"));
1124 1117                  goto skip;
1125 1118          }
1126 1119  
1127 1120          /* add to TDL so preprobing callouts and prober can access it */
1128 1121          hal_device_store_add (hald_get_tdl (), d);
1129 1122  
1130 1123          /* Process preprobe fdi files */
1131 1124          di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE);
1132 1125  
1133 1126          /* Run preprobe callouts */
1134 1127          hal_util_callout_device_preprobe (d, devinfo_volume_preprobing_done, end_token, handler);
1135 1128  
1136 1129          return;
1137 1130  
1138 1131  skip:
1139 1132          g_object_unref (d);
1140 1133          hotplug_event_end (end_token);
1141 1134  }
1142 1135  
1143 1136  void
1144 1137  devinfo_storage_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token)
1145 1138  {
1146 1139          const char *drive_type;
1147 1140          const char *p_udi;
1148 1141          HalDevice *p_d;
1149 1142          HalDevice *phys_d = NULL;
1150 1143          const char *phys_bus;
1151 1144          const char *bus;
1152 1145          static const char *busses[] = { "usb", "ide", "scsi", "ieee1394",
1153 1146                                          "pseudo" };
1154 1147          int i;
1155 1148  
1156 1149          HAL_INFO (("Preprobing udi=%s", hal_device_get_udi (d)));
1157 1150  
1158 1151          if (parent == NULL) {
1159 1152                  HAL_INFO (("no parent %s", hal_device_get_udi (d)));
1160 1153                  goto error;
1161 1154          }
1162 1155  
1163 1156          /*
1164 1157           * figure out physical device and bus, except for floppy
1165 1158           */
1166 1159          drive_type = hal_device_property_get_string (d, "storage.drive_type");
1167 1160          if ((drive_type != NULL) && (strcmp (drive_type, "floppy") == 0)) {
1168 1161                  goto skip_bus;
1169 1162          }
1170 1163  
1171 1164          p_d = parent;
1172 1165          for (;;) {
1173 1166                  bus = hal_device_property_get_string (p_d, "info.subsystem");
1174 1167                  if (bus != NULL) {
1175 1168                          for (i = 0; i < NELEM(busses); i++) {
1176 1169                                  if (strcmp(bus, busses[i]) == 0) {
1177 1170                                          phys_d = p_d;
1178 1171                                          phys_bus = busses[i];
1179 1172                                          break;
1180 1173                                  }
1181 1174                          }
1182 1175                  }
1183 1176                  /* up the tree */
1184 1177                  p_udi = hal_device_property_get_string (p_d, "info.parent");
1185 1178                  if (p_udi == NULL) {
1186 1179                          break;
1187 1180                  }
1188 1181                  p_d = hal_device_store_find (hald_get_gdl (), p_udi);
1189 1182          }
1190 1183          if (phys_d == NULL) {
1191 1184                  HAL_INFO (("no physical device %s", hal_device_get_udi (d)));
1192 1185          } else {
1193 1186                  hal_device_property_set_string (d, "storage.physical_device", hal_device_get_udi (phys_d));
1194 1187                  hal_device_property_set_string (d, "storage.bus", phys_bus);
1195 1188          }
1196 1189  
1197 1190  skip_bus:
1198 1191  
1199 1192          /* add to TDL so preprobing callouts and prober can access it */
1200 1193          hal_device_store_add (hald_get_tdl (), d);
1201 1194  
1202 1195          /* Process preprobe fdi files */
1203 1196          di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE);
1204 1197  
1205 1198          /* Run preprobe callouts */
1206 1199          hal_util_callout_device_preprobe (d, devinfo_callouts_preprobing_done, end_token, handler);
1207 1200  
1208 1201          return;
1209 1202  
1210 1203  error:
1211 1204          g_object_unref (d);
1212 1205          hotplug_event_end (end_token);
1213 1206  }
1214 1207  
1215 1208  static void
1216 1209  devinfo_storage_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2)
1217 1210  {
1218 1211          void *end_token = (void *) userdata1;
1219 1212  
1220 1213          HAL_INFO (("devinfo_storage_probing_done %s", hal_device_get_udi (d)));
1221 1214  
1222 1215          /* Discard device if probing reports failure */
1223 1216          if (exit_type != HALD_RUN_SUCCESS || return_code != 0) {
1224 1217                  HAL_INFO (("devinfo_storage_probing_done returning exit_type=%d return_code=%d", exit_type, return_code));
1225 1218                  hal_device_store_remove (hald_get_tdl (), d);
1226 1219                  g_object_unref (d);
1227 1220                  hotplug_event_end (end_token);
1228 1221                  return;
1229 1222          }
1230 1223  
1231 1224          devinfo_storage_set_nicknames (d);
1232 1225  
1233 1226          /* Merge properties from .fdi files */
1234 1227          di_search_and_merge (d, DEVICE_INFO_TYPE_INFORMATION);
1235 1228          di_search_and_merge (d, DEVICE_INFO_TYPE_POLICY);
1236 1229  
1237 1230          hal_util_callout_device_add (d, devinfo_callouts_add_done, end_token, NULL);
1238 1231  }
1239 1232  
1240 1233  const gchar *
1241 1234  devinfo_storage_get_prober (HalDevice *d, int *timeout)
1242 1235  {
1243 1236          *timeout = DEVINFO_PROBE_STORAGE_TIMEOUT;
1244 1237          return "hald-probe-storage";
1245 1238  }
1246 1239  
1247 1240  const gchar *
1248 1241  devinfo_volume_get_prober (HalDevice *d, int *timeout)
1249 1242  {
1250 1243          *timeout = DEVINFO_PROBE_VOLUME_TIMEOUT;
1251 1244          return "hald-probe-volume";
1252 1245  }
1253 1246  
1254 1247  /*
1255 1248   * After reprobing storage, reprobe its volumes.
1256 1249   */
1257 1250  static void
1258 1251  devinfo_storage_rescan_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2)
1259 1252  {
1260 1253          void *end_token = (void *) userdata1;
1261 1254          const char *devfs_path_orig = NULL;
1262 1255          char *devfs_path = NULL;
1263 1256          char *p;
1264 1257          di_node_t node;
1265 1258  
1266 1259          HAL_INFO (("devinfo_storage_rescan_probing_done %s", hal_device_get_udi (d)));
1267 1260  
1268 1261          devfs_path_orig = hal_device_property_get_string (d, "solaris.devfs_path");
1269 1262          if (devfs_path_orig == NULL) {
1270 1263                  HAL_INFO (("device has no solaris.devfs_path"));
1271 1264                  hotplug_event_process_queue ();
1272 1265                  return;
1273 1266          }
1274 1267  
1275 1268          /* strip trailing minor part if any */
1276 1269          if (strrchr(devfs_path_orig, ':') != NULL) {
1277 1270                  if ((devfs_path = strdup (devfs_path_orig)) != NULL) {
1278 1271                          p = strrchr(devfs_path, ':');
1279 1272                          *p = '\0';
1280 1273                  }
1281 1274          } else {
1282 1275                  devfs_path = (char *)devfs_path_orig;
1283 1276          }
1284 1277  
1285 1278          if ((node = di_init (devfs_path, DINFOCPYALL)) == DI_NODE_NIL) {
1286 1279                  HAL_INFO (("di_init %s failed %d %s", devfs_path, errno, hal_device_get_udi (d)));
1287 1280                  hotplug_event_process_queue ();
1288 1281                  return;
1289 1282          } else {
1290 1283                  devinfo_storage_minors (d, node, (char *)devfs_path, TRUE);
1291 1284                  di_fini (node);
1292 1285          }
1293 1286  
1294 1287          if (devfs_path != devfs_path_orig) {
1295 1288                  free (devfs_path);
1296 1289          }
1297 1290  
1298 1291          hotplug_event_process_queue ();
1299 1292  }
1300 1293  
1301 1294  /*
1302 1295   * For removable media devices, check for "storage.removable.media_available".
1303 1296   * For non-removable media devices, assume media is always there.
1304 1297   *
1305 1298   * If media is gone, enqueue remove events for all children volumes.
1306 1299   * If media is there, first reprobe storage, then probe for new volumes (but leave existing volumes alone).
1307 1300   */
1308 1301  gboolean
1309 1302  devinfo_storage_device_rescan (HalDevice *d)
1310 1303  {
1311 1304          GSList *i;
1312 1305          GSList *volumes;
1313 1306          HalDevice *v;
1314 1307          gchar *v_devfs_path;
1315 1308          const char *drive_type;
1316 1309          gboolean is_floppy;
1317 1310          gboolean media_available;
1318 1311  
1319 1312          HAL_INFO (("devinfo_storage_device_rescan udi=%s", hal_device_get_udi (d)));
1320 1313  
1321 1314          if (hal_device_property_get_bool (d, "block.is_volume")) {
1322 1315                  HAL_INFO (("nothing to do for volume"));
1323 1316                  return (FALSE);
1324 1317          }
1325 1318  
1326 1319          drive_type = hal_device_property_get_string (d, "storage.drive_type");
1327 1320          is_floppy = (drive_type != NULL) && (strcmp (drive_type, "floppy") == 0);
1328 1321                  
1329 1322          media_available = !hal_device_property_get_bool (d, "storage.removable") ||
1330 1323              hal_device_property_get_bool (d, "storage.removable.media_available");
1331 1324  
1332 1325          if (!media_available && !is_floppy) {
1333 1326                  HAL_INFO (("media gone %s", hal_device_get_udi (d)));
1334 1327  
1335 1328                  volumes = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
1336 1329                      "block.storage_device", hal_device_get_udi (d));
1337 1330                  for (i = volumes; i != NULL; i = g_slist_next (i)) {
1338 1331                          v = HAL_DEVICE (i->data);
1339 1332                          v_devfs_path = (gchar *)hal_device_property_get_string (v, "solaris.devfs_path");
1340 1333                          HAL_INFO (("child volume %s", hal_device_get_udi (v)));
1341 1334                          if ((v_devfs_path != NULL) && hal_device_has_capability (v, "volume")) {
1342 1335                                  HAL_INFO (("removing volume %s", hal_device_get_udi (v)));
1343 1336                                  devinfo_remove_enqueue (v_devfs_path, NULL);
1344 1337                          } else {
1345 1338                                  HAL_INFO (("not a volume %s", hal_device_get_udi (v)));
1346 1339                          }
1347 1340                  }
1348 1341                  g_slist_free (volumes);
1349 1342  
1350 1343                  hotplug_event_process_queue ();
1351 1344          } else if (is_floppy) {
1352 1345                  HAL_INFO (("rescanning floppy %s", hal_device_get_udi (d)));
1353 1346                  
1354 1347                  hald_runner_run (d,
1355 1348                                   "hald-probe-storage --only-check-for-media", NULL,
1356 1349                                   DEVINFO_PROBE_STORAGE_TIMEOUT,
1357 1350                                   devinfo_floppy_rescan_probing_done,
1358 1351                                   NULL, NULL);
1359 1352          } else {
1360 1353                  HAL_INFO (("media available %s", hal_device_get_udi (d)));
1361 1354  
1362 1355                  hald_runner_run (d,
1363 1356                                   "hald-probe-storage --only-check-for-media", NULL,
1364 1357                                   DEVINFO_PROBE_STORAGE_TIMEOUT,
1365 1358                                   devinfo_storage_rescan_probing_done,
1366 1359                                   NULL, NULL);
1367 1360          }
1368 1361  
1369 1362          return TRUE;
1370 1363  }
1371 1364  
1372 1365  static char *
1373 1366  devinfo_volume_get_slice_name (char *devlink)
1374 1367  {
1375 1368          char    *part, *slice, *disk;
1376 1369          char    *s = NULL;
1377 1370          char    *p;
1378 1371  
1379 1372          if ((p = strstr(devlink, "/lofi/")) != 0) {
1380 1373                  return (p + sizeof ("/lofi/") - 1);
1381 1374          }
1382 1375  
1383 1376          part = strrchr(devlink, 'p');
1384 1377          slice = strrchr(devlink, 's');
1385 1378          disk = strrchr(devlink, 'd');
1386 1379  
1387 1380          if ((part != NULL) && (part > slice) && (part > disk)) {
1388 1381                  s = part;
1389 1382          } else if ((slice != NULL) && (slice > disk)) {
1390 1383                  s = slice;
1391 1384          } else {
1392 1385                  s = disk;
1393 1386          }
1394 1387          if ((s != NULL) && isdigit(s[1])) {
1395 1388                  return (s);
  
    | ↓ open down ↓ | 463 lines elided | ↑ open up ↑ | 
1396 1389          } else {
1397 1390                  return ("");
1398 1391          }
1399 1392  }
1400 1393  
1401 1394  static gboolean
1402 1395  is_dos_path(char *path, int *partnum)
1403 1396  {
1404 1397          char *p;
1405 1398  
1406      -        if ((p = strrchr (path, ':')) == NULL) {
     1399 +        if ((p = strrchr (path, 'p')) == NULL) {
1407 1400                  return (FALSE);
1408 1401          }
1409 1402          return ((*partnum = atoi(p + 1)) != 0);
1410 1403  }
1411 1404  
1412 1405  static gboolean
1413 1406  dos_to_dev(char *path, char **devpath, int *partnum)
1414 1407  {
1415 1408          char *p;
1416 1409  
1417      -        if ((p = strrchr (path, ':')) == NULL) {
     1410 +        if ((p = strrchr (path, 'p')) == NULL) {
1418 1411                  return (FALSE);
1419 1412          }
1420 1413          if ((*partnum = atoi(p + 1)) == 0) {
1421 1414                  return (FALSE);
1422 1415          }
1423 1416          p[0] = '\0';
1424 1417          *devpath = strdup(path);
1425      -        p[0] = ':';
     1418 +        p[0] = 'p';
1426 1419          return (*devpath != NULL);
1427 1420  }
1428 1421  
1429 1422  static void
1430 1423  devinfo_storage_cleanup_mountpoint_cb (HalDevice *d, guint32 exit_type, 
1431 1424                         gint return_code, gchar **error,
1432 1425                         gpointer data1, gpointer data2)
1433 1426  {
1434 1427          char *mount_point = (char *) data1;
1435 1428  
1436 1429          HAL_INFO (("Cleaned up mount point '%s'", mount_point));
1437 1430          g_free (mount_point);
1438 1431  }
1439 1432  
1440 1433  
1441 1434  void
1442 1435  devinfo_storage_mnttab_event (HalDevice *hal_volume)
1443 1436  {
1444 1437          FILE *fp = NULL;
1445 1438          struct extmnttab m;
1446 1439          HalDevice *d;
1447 1440          unsigned int major;
1448 1441          unsigned int minor;
1449 1442          GSList *volumes = NULL;
1450 1443          GSList *v;
1451 1444          char *mount_point;
1452 1445          dbus_bool_t is_partition;
1453 1446          const char *fstype;
1454 1447          int partition_number;
1455 1448  
1456 1449          if (hal_volume != NULL) {
1457 1450                  volumes = g_slist_append (NULL, hal_volume);
1458 1451          } else {
1459 1452                  volumes = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.category", "volume");
1460 1453          }
1461 1454          if (volumes == NULL) {
1462 1455                  return;
1463 1456          }
1464 1457  
1465 1458          if ((fp = fopen(MNTTAB, "r")) == NULL) {
1466 1459                  HAL_ERROR (("Open failed %s errno %d", MNTTAB, errno));
1467 1460                  return;
1468 1461          }
1469 1462  
1470 1463          while (getextmntent(fp, &m, 1) == 0) {
1471 1464                  for (v = volumes; v != NULL; v = g_slist_next (v)) {
1472 1465                          d = HAL_DEVICE (v->data);
1473 1466                          major = hal_device_property_get_int (d, "block.major");
1474 1467                          minor = hal_device_property_get_int (d, "block.minor");
1475 1468  
1476 1469                          /*
1477 1470                           * special handling for pcfs, which encodes logical
1478 1471                           * drive number into the 6 upper bits of the minor
1479 1472                           */
1480 1473                          is_partition = hal_device_property_get_bool (d, "volume.is_partition");
1481 1474                          partition_number = hal_device_property_get_int (d, "volume.partition.number");
1482 1475                          fstype = hal_device_property_get_string (d, "volume.fstype");
1483 1476  
1484 1477                          if (is_partition && (partition_number > 0) && (strcmp (fstype, "pcfs") == 0)) {
1485 1478                                  minor |= partition_number << 12;
1486 1479                          }
1487 1480  
1488 1481                          if (m.mnt_major != major || m.mnt_minor != minor) {
1489 1482                                  continue;
1490 1483                          }
1491 1484  
1492 1485                          /* this volume matches the mnttab entry */
1493 1486                          device_property_atomic_update_begin ();
1494 1487                          hal_device_property_set_bool (d, "volume.is_mounted", TRUE);
1495 1488                          hal_device_property_set_bool (d, "volume.is_mounted_read_only",
1496 1489                                                        hasmntopt ((struct mnttab *)&m, "ro") ? TRUE : FALSE);
1497 1490                          hal_device_property_set_string (d, "volume.mount_point", m.mnt_mountp);
1498 1491                          device_property_atomic_update_end ();
1499 1492  
1500 1493                          HAL_INFO (("set %s to be mounted at %s",
1501 1494                                     hal_device_get_udi (d), m.mnt_mountp));
1502 1495                          volumes = g_slist_delete_link (volumes, v);
1503 1496                  }
1504 1497          }
1505 1498  
1506 1499          /* all remaining volumes are not mounted */
1507 1500          for (v = volumes; v != NULL; v = g_slist_next (v)) {
1508 1501                  d = HAL_DEVICE (v->data);
1509 1502                  mount_point = g_strdup (hal_device_property_get_string (d, "volume.mount_point"));
1510 1503                  if (mount_point == NULL || strlen (mount_point) == 0) {
1511 1504                          g_free (mount_point);
1512 1505                          continue;
1513 1506                  }
1514 1507  
1515 1508                  device_property_atomic_update_begin ();
1516 1509                  hal_device_property_set_bool (d, "volume.is_mounted", FALSE);
1517 1510                  hal_device_property_set_bool (d, "volume.is_mounted_read_only", FALSE);
1518 1511                  hal_device_property_set_string (d, "volume.mount_point", "");
1519 1512                  device_property_atomic_update_end ();
1520 1513  
1521 1514                  HAL_INFO (("set %s to unmounted", hal_device_get_udi (d)));
1522 1515  
1523 1516                  /* cleanup if was mounted by us */
1524 1517                  if (hal_util_is_mounted_by_hald (mount_point)) {
1525 1518                          char *cleanup_stdin;
1526 1519                          char *extra_env[2];
1527 1520  
1528 1521                          HAL_INFO (("Cleaning up '%s'", mount_point));
1529 1522  
1530 1523                          extra_env[0] = g_strdup_printf ("HALD_CLEANUP=%s", mount_point);
1531 1524                          extra_env[1] = NULL;
1532 1525                          cleanup_stdin = "\n";
1533 1526  
1534 1527                          hald_runner_run_method (d, 
1535 1528                                                  "hal-storage-cleanup-mountpoint", 
1536 1529                                                  extra_env, 
1537 1530                                                  cleanup_stdin, TRUE,
1538 1531                                                  0,
1539 1532                                                  devinfo_storage_cleanup_mountpoint_cb,
1540 1533                                                  g_strdup (mount_point), NULL);
1541 1534  
1542 1535                          g_free (extra_env[0]);
1543 1536                  }
1544 1537  
1545 1538                  g_free (mount_point);
1546 1539          }
1547 1540          g_slist_free (volumes);
1548 1541  
1549 1542          (void) fclose (fp);
1550 1543  }
1551 1544  
1552 1545  static void
1553 1546  devinfo_volume_force_unmount_cb (HalDevice *d, guint32 exit_type, 
1554 1547                    gint return_code, gchar **error,
1555 1548                    gpointer data1, gpointer data2)
1556 1549  {
1557 1550          void *end_token = (void *) data1;
1558 1551  
1559 1552          HAL_INFO (("devinfo_volume_force_unmount_cb for udi='%s', exit_type=%d, return_code=%d", hal_device_get_udi (d), exit_type, return_code));
1560 1553  
1561 1554          if (exit_type == HALD_RUN_SUCCESS && error != NULL && 
1562 1555              error[0] != NULL && error[1] != NULL) {
1563 1556                  char *exp_name = NULL;
1564 1557                  char *exp_detail = NULL;
1565 1558  
1566 1559                  exp_name = error[0];
1567 1560                  if (error[0] != NULL) {
1568 1561                          exp_detail = error[1];
1569 1562                  }
1570 1563                  HAL_INFO (("failed with '%s' '%s'", exp_name, exp_detail));
1571 1564          }
1572 1565  
1573 1566          hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
1574 1567  }
1575 1568  
1576 1569  static void
1577 1570  devinfo_volume_force_unmount (HalDevice *d, void *end_token)
1578 1571  {
1579 1572          const char *device_file;
1580 1573          const char *mount_point;
1581 1574          char *unmount_stdin;
1582 1575          char *extra_env[2];
1583 1576          extra_env[0] = "HAL_METHOD_INVOKED_BY_UID=0";
1584 1577          extra_env[1] = NULL;
1585 1578  
1586 1579          device_file = hal_device_property_get_string (d, "block.device");
1587 1580          mount_point = hal_device_property_get_string (d, "volume.mount_point");
1588 1581  
1589 1582          if (mount_point == NULL || strlen (mount_point) == 0 || !hal_util_is_mounted_by_hald (mount_point)) {
1590 1583                  hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
1591 1584                  return;
1592 1585          }
1593 1586  
1594 1587          HAL_INFO (("devinfo_volume_force_unmount for udi='%s'", hal_device_get_udi (d)));
1595 1588                  
1596 1589          unmount_stdin = "\n";
1597 1590                  
1598 1591          hald_runner_run_method (d, 
1599 1592                                  "hal-storage-unmount", 
1600 1593                                  extra_env, 
1601 1594                                  unmount_stdin, TRUE,
1602 1595                                  0,
1603 1596                                  devinfo_volume_force_unmount_cb,
1604 1597                                  end_token, NULL);
1605 1598  }
1606 1599  
1607 1600  void
1608 1601  devinfo_volume_hotplug_begin_remove (HalDevice *d, char *devfs_path, void *end_token)
1609 1602  {
1610 1603          if (hal_device_property_get_bool (d, "volume.is_mounted")) {
1611 1604                  devinfo_volume_force_unmount (d, end_token);
1612 1605          } else {
1613 1606                  hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
1614 1607          }
1615 1608  }
1616 1609  
1617 1610  
1618 1611  enum {
1619 1612          LEGACY_CDROM,
1620 1613          LEGACY_FLOPPY,
1621 1614          LEGACY_RMDISK
1622 1615  };
1623 1616  
1624 1617  static const char *legacy_media_str[] = {
1625 1618          "cdrom",
1626 1619          "floppy",
1627 1620          "rmdisk"
1628 1621  };
1629 1622  
1630 1623  struct enum_nick {
1631 1624          const char *type;
1632 1625          GSList  *nums;
1633 1626  };
1634 1627  
1635 1628  static int
1636 1629  devinfo_storage_get_legacy_media(HalDevice *d)
1637 1630  {
1638 1631          const char *drive_type;
1639 1632  
1640 1633          if (hal_device_has_capability (d, "storage.cdrom")) {
1641 1634                  return (LEGACY_CDROM);
1642 1635          } else if (((drive_type = hal_device_property_get_string (d,
1643 1636              "storage.drive_type")) != NULL) && (strcmp (drive_type, "floppy") == 0)) {
1644 1637                  return (LEGACY_FLOPPY);
1645 1638          } else if (hal_device_property_get_bool (d, "storage.removable") ||
1646 1639                     hal_device_property_get_bool (d, "storage.hotpluggable")) {
1647 1640                  return (LEGACY_RMDISK);
1648 1641          } else {
1649 1642                  return (-1);
1650 1643          }
1651 1644  }
1652 1645  
1653 1646  static gboolean
1654 1647  devinfo_storage_foreach_nick (HalDeviceStore *store, HalDevice *d, gpointer user_data)
1655 1648  {
1656 1649          struct enum_nick *en = (struct enum_nick *) user_data;
1657 1650          const char *media_type;
1658 1651          int media_num;
1659 1652  
1660 1653          media_type = hal_device_property_get_string (d, "storage.solaris.legacy.media_type");
1661 1654          media_num = hal_device_property_get_int (d, "storage.solaris.legacy.media_num");
1662 1655          if ((media_type != NULL) && (strcmp (media_type, en->type) == 0) &&
1663 1656              (media_num >= 0)) {
1664 1657                  en->nums = g_slist_prepend (en->nums, GINT_TO_POINTER(media_num));
1665 1658          }
1666 1659          return TRUE;
1667 1660  }
1668 1661  
1669 1662  static void
1670 1663  devinfo_storage_append_nickname (HalDevice *d, const char *media_type, int media_num)
1671 1664  {
1672 1665          char buf[64];
1673 1666  
1674 1667          if (media_num == 0) {
1675 1668                  hal_device_property_strlist_append (d, "storage.solaris.nicknames", media_type);
1676 1669          }
1677 1670          snprintf(buf, sizeof (buf), "%s%d", media_type, media_num);
1678 1671          hal_device_property_strlist_append (d, "storage.solaris.nicknames", buf);
1679 1672  }
1680 1673  
1681 1674  static void
1682 1675  devinfo_storage_set_nicknames (HalDevice *d)
1683 1676  {
1684 1677          int media;
1685 1678          const char *media_type;
1686 1679          int media_num;
1687 1680          GSList *i;
1688 1681          struct enum_nick en;
1689 1682          char buf[64];
1690 1683  
1691 1684          if ((media = devinfo_storage_get_legacy_media (d)) < 0) {
1692 1685                  return;
1693 1686          }
1694 1687          media_type = legacy_media_str[media];
1695 1688  
1696 1689          /* enumerate all storage devices of this media type */
1697 1690          en.type = media_type;
1698 1691          en.nums = NULL;
1699 1692          hal_device_store_foreach (hald_get_gdl (), devinfo_storage_foreach_nick, &en);
1700 1693  
1701 1694          /* find a free number */
1702 1695          for (media_num = 0; ; media_num++) {
1703 1696                  for (i = en.nums; i != NULL; i = g_slist_next (i)) {
1704 1697                          if (GPOINTER_TO_INT (i->data) == media_num) {
1705 1698                                  break;
1706 1699                          }
1707 1700                  }
1708 1701                  if (i == NULL) {
1709 1702                          break;
1710 1703                  }
1711 1704          }
1712 1705          g_slist_free (en.nums);
1713 1706  
1714 1707          hal_device_property_set_string (d, "storage.solaris.legacy.media_type", media_type);
1715 1708          hal_device_property_set_int (d, "storage.solaris.legacy.media_num", media_num);
1716 1709  
1717 1710          /* primary nickname, and also vold-style symdev */
1718 1711          snprintf(buf, sizeof (buf), "%s%d", media_type, media_num);
1719 1712          hal_device_property_set_string (d, "storage.solaris.legacy.symdev", buf);
1720 1713          devinfo_storage_append_nickname(d, media_type, media_num);
1721 1714  
1722 1715          /* additional nicknames */
1723 1716          if (media == LEGACY_CDROM) {
1724 1717                  devinfo_storage_append_nickname(d, "cd", media_num);
1725 1718                  devinfo_storage_append_nickname(d, "sr", media_num);
1726 1719          } else if (media == LEGACY_FLOPPY) {
1727 1720                  devinfo_storage_append_nickname(d, "fd", media_num);
1728 1721                  devinfo_storage_append_nickname(d, "diskette", media_num);
1729 1722                  devinfo_storage_append_nickname(d, "rdiskette", media_num);
1730 1723          }
1731 1724  }
  
    | ↓ open down ↓ | 296 lines elided | ↑ open up ↑ | 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX