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