18bd3d23cSAlex Hornung /* 28bd3d23cSAlex Hornung * DragonFly specific device routines are added to this file. 38bd3d23cSAlex Hornung */ 48bd3d23cSAlex Hornung 58bd3d23cSAlex Hornung #include <sys/param.h> 68bd3d23cSAlex Hornung #include <sys/types.h> 7*b060a5b0SAlex Hornung #include <sys/stat.h> 88bd3d23cSAlex Hornung 98bd3d23cSAlex Hornung #include <sys/sysctl.h> 108bd3d23cSAlex Hornung 118bd3d23cSAlex Hornung #include <dirent.h> 128bd3d23cSAlex Hornung #include <stdio.h> 138bd3d23cSAlex Hornung #include <stdlib.h> 148bd3d23cSAlex Hornung #include <string.h> 158bd3d23cSAlex Hornung #include <unistd.h> 168bd3d23cSAlex Hornung #include <ctype.h> 178bd3d23cSAlex Hornung #include <fcntl.h> 188bd3d23cSAlex Hornung #include <limits.h> 198bd3d23cSAlex Hornung #include <devattr.h> 208bd3d23cSAlex Hornung 218bd3d23cSAlex Hornung 228bd3d23cSAlex Hornung #define LVM_FAILURE -1 238bd3d23cSAlex Hornung 248bd3d23cSAlex Hornung 258bd3d23cSAlex Hornung int 268bd3d23cSAlex Hornung dragonfly_check_dev(int major, const char *path) 278bd3d23cSAlex Hornung { 288bd3d23cSAlex Hornung struct udev *udev; 298bd3d23cSAlex Hornung struct udev_enumerate *udev_enum; 308bd3d23cSAlex Hornung struct udev_list_entry *udev_le, *udev_le_first; 318bd3d23cSAlex Hornung struct udev_monitor *udev_monitor; 328bd3d23cSAlex Hornung struct udev_device *udev_dev; 33*b060a5b0SAlex Hornung struct stat sb; 348bd3d23cSAlex Hornung const char *subsystem; 358bd3d23cSAlex Hornung const char *driver; 368bd3d23cSAlex Hornung const char *type; 378bd3d23cSAlex Hornung int ret, result; 388bd3d23cSAlex Hornung 398bd3d23cSAlex Hornung result = LVM_FAILURE; 408bd3d23cSAlex Hornung 41*b060a5b0SAlex Hornung /* 42*b060a5b0SAlex Hornung * We do the stat & devname dance to get around paths that are 43*b060a5b0SAlex Hornung * symlinks. udev will only find devices by their real name or 44*b060a5b0SAlex Hornung * devfs alias. 45*b060a5b0SAlex Hornung */ 46*b060a5b0SAlex Hornung stat(path, &sb); 47*b060a5b0SAlex Hornung path = devname(sb.st_rdev, S_IFCHR); 48*b060a5b0SAlex Hornung 498bd3d23cSAlex Hornung if (!strncmp(path, "/dev/", strlen("/dev/"))) { 508bd3d23cSAlex Hornung path += strlen("/dev/"); 518bd3d23cSAlex Hornung } 528bd3d23cSAlex Hornung 538bd3d23cSAlex Hornung udev = udev_new(); 548bd3d23cSAlex Hornung if (udev == NULL) { 558bd3d23cSAlex Hornung fprintf(stderr, "udev_new failed! Need udevd running.\n"); 568bd3d23cSAlex Hornung return LVM_FAILURE; 578bd3d23cSAlex Hornung } 588bd3d23cSAlex Hornung 598bd3d23cSAlex Hornung udev_enum = udev_enumerate_new(udev); 608bd3d23cSAlex Hornung if (udev_enum == NULL) { 618bd3d23cSAlex Hornung fprintf(stderr, "udev_enumerate_new failed!\n"); 628bd3d23cSAlex Hornung goto out2; 638bd3d23cSAlex Hornung } 648bd3d23cSAlex Hornung 658bd3d23cSAlex Hornung ret = udev_enumerate_add_match_expr(udev_enum, "name", __DECONST(char *, path)); 668bd3d23cSAlex Hornung if (ret != 0) { 678bd3d23cSAlex Hornung fprintf(stderr, "udev_enumerate_add_match_expr failed!\n"); 688bd3d23cSAlex Hornung goto out; 698bd3d23cSAlex Hornung } 708bd3d23cSAlex Hornung 718bd3d23cSAlex Hornung ret = udev_enumerate_scan_devices(udev_enum); 728bd3d23cSAlex Hornung if (ret != 0) { 738bd3d23cSAlex Hornung fprintf(stderr, "udev_enumerate_scan_devices failed!\n"); 748bd3d23cSAlex Hornung goto out; 758bd3d23cSAlex Hornung } 768bd3d23cSAlex Hornung 778bd3d23cSAlex Hornung udev_le = udev_enumerate_get_list_entry(udev_enum); 788bd3d23cSAlex Hornung if (udev_le == NULL) { 798bd3d23cSAlex Hornung #if 0 808bd3d23cSAlex Hornung fprintf(stderr, "udev_enumerate_get_list_entry failed for %s!\n", path); 818bd3d23cSAlex Hornung #endif 828bd3d23cSAlex Hornung goto out; 838bd3d23cSAlex Hornung } 848bd3d23cSAlex Hornung 858bd3d23cSAlex Hornung udev_dev = udev_list_entry_get_device(udev_le); 868bd3d23cSAlex Hornung if (udev_dev == NULL) { 878bd3d23cSAlex Hornung fprintf(stderr, "udev_list_entry_get_device failed!\n"); 888bd3d23cSAlex Hornung goto out; 898bd3d23cSAlex Hornung } 908bd3d23cSAlex Hornung 918bd3d23cSAlex Hornung subsystem = udev_device_get_subsystem(udev_dev); 928bd3d23cSAlex Hornung driver = udev_device_get_driver(udev_dev); 938bd3d23cSAlex Hornung type = udev_device_get_property_value(udev_dev, "disk-type"); 948bd3d23cSAlex Hornung 958bd3d23cSAlex Hornung /* If it's neither a disk driver nor a raid driver, stop here */ 968bd3d23cSAlex Hornung if ((subsystem == NULL) || 978bd3d23cSAlex Hornung ((strcmp(subsystem, "disk") != 0) && 988bd3d23cSAlex Hornung (strcmp(subsystem, "raid") != 0))) { 998bd3d23cSAlex Hornung goto outdev; 1008bd3d23cSAlex Hornung } 1018bd3d23cSAlex Hornung 1028bd3d23cSAlex Hornung /* We don't like malloc disks */ 1038bd3d23cSAlex Hornung if (driver && (strcmp(driver, "md") == 0)) { 1048bd3d23cSAlex Hornung goto outdev; 1058bd3d23cSAlex Hornung } 1068bd3d23cSAlex Hornung 1078bd3d23cSAlex Hornung /* Some disk-type checks... */ 1088bd3d23cSAlex Hornung if (type && (strcmp(type, "optical") == 0)) { 1098bd3d23cSAlex Hornung goto outdev; 1108bd3d23cSAlex Hornung } 1118bd3d23cSAlex Hornung 1128bd3d23cSAlex Hornung /* Some disk-type checks... */ 1138bd3d23cSAlex Hornung if (type && (strcmp(type, "floppy") == 0)) { 1148bd3d23cSAlex Hornung goto outdev; 1158bd3d23cSAlex Hornung } 1168bd3d23cSAlex Hornung 1178bd3d23cSAlex Hornung /* Some disk-type checks... */ 1188bd3d23cSAlex Hornung if (type && (strcmp(type, "tape") == 0)) { 1198bd3d23cSAlex Hornung goto outdev; 1208bd3d23cSAlex Hornung } 1218bd3d23cSAlex Hornung 1228bd3d23cSAlex Hornung /* Some disk-type checks... */ 1238bd3d23cSAlex Hornung if (type && (strcmp(type, "memory") == 0)) { 1248bd3d23cSAlex Hornung goto outdev; 1258bd3d23cSAlex Hornung } 1268bd3d23cSAlex Hornung 1278bd3d23cSAlex Hornung result = 0; 1288bd3d23cSAlex Hornung 1298bd3d23cSAlex Hornung outdev: 1308bd3d23cSAlex Hornung udev_device_unref(udev_dev); 1318bd3d23cSAlex Hornung out: 1328bd3d23cSAlex Hornung udev_enumerate_unref(udev_enum); 1338bd3d23cSAlex Hornung out2: 1348bd3d23cSAlex Hornung udev_unref(udev); 1358bd3d23cSAlex Hornung return result; 1368bd3d23cSAlex Hornung } 1378bd3d23cSAlex Hornung 1388bd3d23cSAlex Hornung /* 1398bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for bpf4 (/dev/bpf4)! 1408bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for log (/dev/log)! 1418bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for serno/00000000000000000001 (/dev/serno/00000000000000000001)! 1428bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0 (/dev/serno/00000000000000000001.s0)! 1438bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0a (/dev/serno/00000000000000000001.s0a)! 1448bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0b (/dev/serno/00000000000000000001.s0b)! 1458bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for serno/01000000000000000001 (/dev/serno/01000000000000000001)! 1468bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for sga (/dev/sga)! 1478bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for sgb (/dev/sgb)! 1488bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for bpf4 (/dev/bpf4)! 1498bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for log (/dev/log)! 1508bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for serno/00000000000000000001 (/dev/serno/00000000000000000001)! 1518bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0 (/dev/serno/00000000000000000001.s0)! 1528bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0a (/dev/serno/00000000000000000001.s0a)! 1538bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0b (/dev/serno/00000000000000000001.s0b)! 1548bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for serno/01000000000000000001 (/dev/serno/01000000000000000001)! 1558bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for sga (/dev/sga)! 1568bd3d23cSAlex Hornung udev_enumerate_get_list_entry failed for sgb (/dev/sgb)! 1578bd3d23cSAlex Hornung */ 158