Print this page
4833 Remove volrmmount
4845 rm(u)mount don't always print mount/unmount errors
4846 HAL partition names don't match real parition names
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
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