1 /***************************************************************************
2 *
3 * devinfo_storage.c : storage devices
4 *
5 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
6 * Copyright 2013 Garrett D'Amore <garrett@damore.org>
7 *
8 * Licensed under the Academic Free License version 2.1
9 *
10 **************************************************************************/
11
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <strings.h>
19 #include <ctype.h>
20 #include <libdevinfo.h>
21 #include <sys/types.h>
22 #include <sys/mkdev.h>
23 #include <sys/stat.h>
24 #include <sys/mntent.h>
25 #include <sys/mnttab.h>
26
685 hal_device_property_set_bool (d, "storage.hotpluggable", TRUE);
686 hal_device_property_set_bool (d, "storage.removable", FALSE);
687 hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
688 hal_device_property_set_string (d, "storage.drive_type", "disk");
689 hal_device_add_capability (d, "block");
690 hal_device_property_set_int (d, "block.major", major(dev));
691 hal_device_property_set_int (d, "block.minor", minor(dev));
692 hal_device_property_set_string (d, "block.device", devlink);
693 raw = dsk_to_rdsk (devlink);
694 hal_device_property_set_string (d, "block.solaris.raw_device", raw);
695 free (raw);
696 hal_device_property_set_bool (d, "block.is_volume", FALSE);
697
698 devinfo_add_enqueue (d, minor_path, &devinfo_storage_handler);
699
700 /* add volumes: one on main device and a few pcfs candidates */
701 m = devinfo_storage_new_minor(minor_path, WHOLE_DISK, devlink, dev, -1);
702 devinfo_volume_add (d, node, m);
703 devinfo_storage_free_minor (m);
704
705 doslink = (char *)calloc (1, strlen (devlink) + sizeof (":NNN") + 1);
706 if (doslink != NULL) {
707 for (i = 1; i < 16; i++) {
708 snprintf(dospath, sizeof (dospath), WHOLE_DISK":%d", i);
709 sprintf(doslink, "%s:%d", devlink, i);
710 m = devinfo_storage_new_minor(minor_path, dospath, doslink, dev, i);
711 devinfo_volume_add (d, node, m);
712 devinfo_storage_free_minor (m);
713 }
714 free (doslink);
715 }
716 }
717
718 void
719 devinfo_lofi_remove_minor(char *parent_devfs_path, char *name)
720 {
721 GSList *i;
722 GSList *devices;
723 HalDevice *d = NULL;
724 const char *devfs_path;
725
726 devices = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
727 "block.solaris.raw_device", name);
728 for (i = devices; i != NULL; i = g_slist_next (i)) {
729 if (hal_device_has_capability (HAL_DEVICE (i->data), "storage")) {
842 while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
843 dev = di_minor_devt(minor);
844 if ((major != major(dev)) ||
845 (di_minor_type(minor) != DDM_MINOR) ||
846 (di_minor_spectype(minor) != S_IFBLK) ||
847 ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
848 continue;
849 }
850 if ((devlink = get_devlink(devlink_hdl, NULL, minor_path)) == NULL) {
851 di_devfs_path_free (minor_path);
852 continue;
853 }
854
855 slice = devinfo_volume_get_slice_name (devlink);
856 if (strlen (slice) < 2) {
857 free (devlink);
858 di_devfs_path_free (minor_path);
859 continue;
860 }
861
862 /* ignore p1..N - we'll use p0:N instead */
863 if ((strlen (slice) > 1) && (slice[0] == 'p') && isdigit(slice[1]) &&
864 ((atol(&slice[1])) > 0)) {
865 free (devlink);
866 di_devfs_path_free (minor_path);
867 continue;
868 }
869
870 m = devinfo_storage_new_minor(minor_path, slice, devlink, dev, -1);
871 if (m == NULL) {
872 free (devlink);
873 di_devfs_path_free (minor_path);
874 continue;
875 }
876
877 /* main device is either s2/p0 or d0, the latter taking precedence */
878 if ((strcmp (slice, "d0") == 0) ||
879 (((strcmp (slice, whole_disk) == 0) && (maindev == NULL)))) {
880 if (maindev_path != NULL) {
881 di_devfs_path_free (maindev_path);
882 }
883 maindev_path = minor_path;
884 maindev = m;
885 g_queue_push_head (mq, maindev);
886 } else {
887 di_devfs_path_free (minor_path);
888 g_queue_push_tail (mq, m);
889 }
898 devinfo_storage_free_minor (g_queue_pop_head (mq));
899 }
900 goto err;
901 }
902
903 /* first enqueue main storage device */
904 if (!rescan) {
905 hal_device_property_set_int (parent, "block.major", major);
906 hal_device_property_set_int (parent, "block.minor", minor(maindev->dev));
907 hal_device_property_set_string (parent, "block.device", maindev->devlink);
908 raw = dsk_to_rdsk (maindev->devlink);
909 hal_device_property_set_string (parent, "block.solaris.raw_device", raw);
910 free (raw);
911 hal_device_property_set_bool (parent, "block.is_volume", FALSE);
912 hal_device_property_set_string (parent, "solaris.devfs_path", maindev_path);
913 devinfo_add_enqueue (parent, maindev_path, &devinfo_storage_handler);
914 }
915
916 /* add virtual dos volumes to enable pcfs probing */
917 if (!is_cdrom) {
918 doslink_len = strlen (maindev->devlink) + sizeof (":NNN") + 1;
919 if ((doslink = (char *)calloc (1, doslink_len)) != NULL) {
920 for (i = 1; i < 16; i++) {
921 snprintf(dospath, sizeof (dospath), "%s:%d", maindev->slice, i);
922 snprintf(doslink, doslink_len, "%s:%d", maindev->devlink, i);
923 m = devinfo_storage_new_minor(maindev_path, dospath, doslink, maindev->dev, i);
924 g_queue_push_tail (mq, m);
925 }
926 free (doslink);
927 }
928 }
929
930 maindev_is_d0 = (strcmp (maindev->slice, "d0") == 0);
931
932 /* enqueue all volumes */
933 while (!g_queue_is_empty (mq)) {
934 m = g_queue_pop_head (mq);
935
936 /* if main device is d0, we'll throw away s2/p0 */
937 if (maindev_is_d0 && (strcmp (m->slice, whole_disk) == 0)) {
938 devinfo_storage_free_minor (m);
939 continue;
940 }
941 /* don't do p0 on cdrom */
942 if (is_cdrom && (strcmp (m->slice, "p0") == 0)) {
1386
1387 if ((part != NULL) && (part > slice) && (part > disk)) {
1388 s = part;
1389 } else if ((slice != NULL) && (slice > disk)) {
1390 s = slice;
1391 } else {
1392 s = disk;
1393 }
1394 if ((s != NULL) && isdigit(s[1])) {
1395 return (s);
1396 } else {
1397 return ("");
1398 }
1399 }
1400
1401 static gboolean
1402 is_dos_path(char *path, int *partnum)
1403 {
1404 char *p;
1405
1406 if ((p = strrchr (path, ':')) == NULL) {
1407 return (FALSE);
1408 }
1409 return ((*partnum = atoi(p + 1)) != 0);
1410 }
1411
1412 static gboolean
1413 dos_to_dev(char *path, char **devpath, int *partnum)
1414 {
1415 char *p;
1416
1417 if ((p = strrchr (path, ':')) == NULL) {
1418 return (FALSE);
1419 }
1420 if ((*partnum = atoi(p + 1)) == 0) {
1421 return (FALSE);
1422 }
1423 p[0] = '\0';
1424 *devpath = strdup(path);
1425 p[0] = ':';
1426 return (*devpath != NULL);
1427 }
1428
1429 static void
1430 devinfo_storage_cleanup_mountpoint_cb (HalDevice *d, guint32 exit_type,
1431 gint return_code, gchar **error,
1432 gpointer data1, gpointer data2)
1433 {
1434 char *mount_point = (char *) data1;
1435
1436 HAL_INFO (("Cleaned up mount point '%s'", mount_point));
1437 g_free (mount_point);
1438 }
1439
1440
1441 void
1442 devinfo_storage_mnttab_event (HalDevice *hal_volume)
1443 {
1444 FILE *fp = NULL;
1445 struct extmnttab m;
|
1 /***************************************************************************
2 *
3 * devinfo_storage.c : storage devices
4 *
5 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
6 * Copyright 2013 Garrett D'Amore <garrett@damore.org>
7 * Copyright 2014 Andrew Stormont.
8 *
9 * Licensed under the Academic Free License version 2.1
10 *
11 **************************************************************************/
12
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
16
17 #include <stdio.h>
18 #include <string.h>
19 #include <strings.h>
20 #include <ctype.h>
21 #include <libdevinfo.h>
22 #include <sys/types.h>
23 #include <sys/mkdev.h>
24 #include <sys/stat.h>
25 #include <sys/mntent.h>
26 #include <sys/mnttab.h>
27
686 hal_device_property_set_bool (d, "storage.hotpluggable", TRUE);
687 hal_device_property_set_bool (d, "storage.removable", FALSE);
688 hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
689 hal_device_property_set_string (d, "storage.drive_type", "disk");
690 hal_device_add_capability (d, "block");
691 hal_device_property_set_int (d, "block.major", major(dev));
692 hal_device_property_set_int (d, "block.minor", minor(dev));
693 hal_device_property_set_string (d, "block.device", devlink);
694 raw = dsk_to_rdsk (devlink);
695 hal_device_property_set_string (d, "block.solaris.raw_device", raw);
696 free (raw);
697 hal_device_property_set_bool (d, "block.is_volume", FALSE);
698
699 devinfo_add_enqueue (d, minor_path, &devinfo_storage_handler);
700
701 /* add volumes: one on main device and a few pcfs candidates */
702 m = devinfo_storage_new_minor(minor_path, WHOLE_DISK, devlink, dev, -1);
703 devinfo_volume_add (d, node, m);
704 devinfo_storage_free_minor (m);
705
706 doslink = (char *)calloc (1, strlen (devlink) + sizeof ("pNN") + 1);
707 if (doslink != NULL) {
708 for (i = 1; i < 16; i++) {
709 snprintf(dospath, sizeof (dospath), "p%d", i);
710 sprintf(doslink, "%sp%d", devlink, i);
711 m = devinfo_storage_new_minor(minor_path, dospath, doslink, dev, i);
712 devinfo_volume_add (d, node, m);
713 devinfo_storage_free_minor (m);
714 }
715 free (doslink);
716 }
717 }
718
719 void
720 devinfo_lofi_remove_minor(char *parent_devfs_path, char *name)
721 {
722 GSList *i;
723 GSList *devices;
724 HalDevice *d = NULL;
725 const char *devfs_path;
726
727 devices = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
728 "block.solaris.raw_device", name);
729 for (i = devices; i != NULL; i = g_slist_next (i)) {
730 if (hal_device_has_capability (HAL_DEVICE (i->data), "storage")) {
843 while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
844 dev = di_minor_devt(minor);
845 if ((major != major(dev)) ||
846 (di_minor_type(minor) != DDM_MINOR) ||
847 (di_minor_spectype(minor) != S_IFBLK) ||
848 ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
849 continue;
850 }
851 if ((devlink = get_devlink(devlink_hdl, NULL, minor_path)) == NULL) {
852 di_devfs_path_free (minor_path);
853 continue;
854 }
855
856 slice = devinfo_volume_get_slice_name (devlink);
857 if (strlen (slice) < 2) {
858 free (devlink);
859 di_devfs_path_free (minor_path);
860 continue;
861 }
862
863 m = devinfo_storage_new_minor(minor_path, slice, devlink, dev, -1);
864 if (m == NULL) {
865 free (devlink);
866 di_devfs_path_free (minor_path);
867 continue;
868 }
869
870 /* main device is either s2/p0 or d0, the latter taking precedence */
871 if ((strcmp (slice, "d0") == 0) ||
872 (((strcmp (slice, whole_disk) == 0) && (maindev == NULL)))) {
873 if (maindev_path != NULL) {
874 di_devfs_path_free (maindev_path);
875 }
876 maindev_path = minor_path;
877 maindev = m;
878 g_queue_push_head (mq, maindev);
879 } else {
880 di_devfs_path_free (minor_path);
881 g_queue_push_tail (mq, m);
882 }
891 devinfo_storage_free_minor (g_queue_pop_head (mq));
892 }
893 goto err;
894 }
895
896 /* first enqueue main storage device */
897 if (!rescan) {
898 hal_device_property_set_int (parent, "block.major", major);
899 hal_device_property_set_int (parent, "block.minor", minor(maindev->dev));
900 hal_device_property_set_string (parent, "block.device", maindev->devlink);
901 raw = dsk_to_rdsk (maindev->devlink);
902 hal_device_property_set_string (parent, "block.solaris.raw_device", raw);
903 free (raw);
904 hal_device_property_set_bool (parent, "block.is_volume", FALSE);
905 hal_device_property_set_string (parent, "solaris.devfs_path", maindev_path);
906 devinfo_add_enqueue (parent, maindev_path, &devinfo_storage_handler);
907 }
908
909 /* add virtual dos volumes to enable pcfs probing */
910 if (!is_cdrom) {
911 doslink_len = strlen (maindev->devlink) + sizeof ("pNN") + 1;
912 if ((doslink = (char *)calloc (1, doslink_len)) != NULL) {
913 for (i = 1; i < 16; i++) {
914 snprintf(dospath, sizeof (dospath), "%sp%d", maindev->slice, i);
915 snprintf(doslink, doslink_len, "%sp%d", maindev->devlink, i);
916 m = devinfo_storage_new_minor(maindev_path, dospath, doslink, maindev->dev, i);
917 g_queue_push_tail (mq, m);
918 }
919 free (doslink);
920 }
921 }
922
923 maindev_is_d0 = (strcmp (maindev->slice, "d0") == 0);
924
925 /* enqueue all volumes */
926 while (!g_queue_is_empty (mq)) {
927 m = g_queue_pop_head (mq);
928
929 /* if main device is d0, we'll throw away s2/p0 */
930 if (maindev_is_d0 && (strcmp (m->slice, whole_disk) == 0)) {
931 devinfo_storage_free_minor (m);
932 continue;
933 }
934 /* don't do p0 on cdrom */
935 if (is_cdrom && (strcmp (m->slice, "p0") == 0)) {
1379
1380 if ((part != NULL) && (part > slice) && (part > disk)) {
1381 s = part;
1382 } else if ((slice != NULL) && (slice > disk)) {
1383 s = slice;
1384 } else {
1385 s = disk;
1386 }
1387 if ((s != NULL) && isdigit(s[1])) {
1388 return (s);
1389 } else {
1390 return ("");
1391 }
1392 }
1393
1394 static gboolean
1395 is_dos_path(char *path, int *partnum)
1396 {
1397 char *p;
1398
1399 if ((p = strrchr (path, 'p')) == NULL) {
1400 return (FALSE);
1401 }
1402 return ((*partnum = atoi(p + 1)) != 0);
1403 }
1404
1405 static gboolean
1406 dos_to_dev(char *path, char **devpath, int *partnum)
1407 {
1408 char *p;
1409
1410 if ((p = strrchr (path, 'p')) == NULL) {
1411 return (FALSE);
1412 }
1413 if ((*partnum = atoi(p + 1)) == 0) {
1414 return (FALSE);
1415 }
1416 p[0] = '\0';
1417 *devpath = strdup(path);
1418 p[0] = 'p';
1419 return (*devpath != NULL);
1420 }
1421
1422 static void
1423 devinfo_storage_cleanup_mountpoint_cb (HalDevice *d, guint32 exit_type,
1424 gint return_code, gchar **error,
1425 gpointer data1, gpointer data2)
1426 {
1427 char *mount_point = (char *) data1;
1428
1429 HAL_INFO (("Cleaned up mount point '%s'", mount_point));
1430 g_free (mount_point);
1431 }
1432
1433
1434 void
1435 devinfo_storage_mnttab_event (HalDevice *hal_volume)
1436 {
1437 FILE *fp = NULL;
1438 struct extmnttab m;
|