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