Skip to content

Commit 1f9fa71

Browse files
committed
PROTOTYPE implementation of full device path
1 parent 881bafe commit 1f9fa71

1 file changed

Lines changed: 110 additions & 11 deletions

File tree

src/linux.c

Lines changed: 110 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ struct device HIDDEN
602602
}
603603

604604
int HIDDEN
605+
/* FIXME Rename */
605606
make_blockdev_path(uint8_t *buf, ssize_t size, struct device *dev)
606607
{
607608
ssize_t off = 0;
@@ -635,23 +636,25 @@ make_mac_path(uint8_t *buf, ssize_t size, const char * const ifname)
635636
{
636637
struct ifreq ifr;
637638
struct ethtool_drvinfo drvinfo = { 0, };
638-
int fd = -1, rc;
639+
int fd = -1, rc, i;
640+
unsigned int n = 0;
639641
ssize_t ret = -1, sz, off = 0;
640-
char busname[PATH_MAX+1] = "";
641-
struct device dev;
642+
struct device devbuf;
643+
struct device *dev = &devbuf;
642644

643-
memset(&dev, 0, sizeof (dev));
644-
dev.interface_type = network;
645-
dev.ifname = strdupa(ifname);
646-
if (!dev.ifname)
645+
memset(dev, 0, sizeof (*dev));
646+
dev->interface_type = network;
647+
dev->ifname = strdupa(ifname);
648+
if (!dev->ifname)
647649
return -1;
650+
dev->driver = "";
648651

649652
/*
650653
* find the device link, which looks like:
651654
* ../../devices/$PCI_STUFF/net/$IFACE
652655
*/
653-
rc = sysfs_readlink(&dev.link, "class/net/%s", ifname);
654-
if (rc < 0 || !dev.link)
656+
rc = sysfs_readlink(&(dev->link), "class/net/%s", ifname);
657+
if (rc < 0 || !dev->link)
655658
goto err;
656659

657660
memset(&ifr, 0, sizeof (ifr));
@@ -668,13 +671,106 @@ make_mac_path(uint8_t *buf, ssize_t size, const char * const ifname)
668671
if (rc < 0)
669672
goto err;
670673

671-
strncpy(busname, drvinfo.bus_info, PATH_MAX);
674+
/*
675+
* FIXME: copy/paste of device_get()
676+
*/
677+
size_t nmemb = (sizeof(dev_probes)
678+
/ sizeof(dev_probes[0])) + 1;
679+
680+
dev->probes = calloc(nmemb, sizeof(struct dev_probe *));
681+
if (!dev->probes) {
682+
efi_error("could not allocate %zd bytes",
683+
nmemb * sizeof(struct dev_probe *));
684+
goto err;
685+
}
686+
687+
const char *current = dev->link;
688+
bool needs_root = true;
689+
int last_successful_probe = -1;
690+
691+
debug("searching for device nodes in %s", dev->link);
692+
for (i = 0;
693+
dev_probes[i] && dev_probes[i]->parse && *current;
694+
i++) {
695+
struct dev_probe *probe = dev_probes[i];
696+
int pos;
697+
698+
if (!needs_root &&
699+
(probe->flags & DEV_PROVIDES_ROOT)) {
700+
debug("not testing %s because flags is 0x%x",
701+
probe->name, probe->flags);
702+
continue;
703+
}
704+
705+
debug("trying %s", probe->name);
706+
pos = probe->parse(dev, current, dev->link);
707+
if (pos < 0) {
708+
efi_error("parsing %s failed", probe->name);
709+
goto err;
710+
} else if (pos > 0) {
711+
char match[pos+1];
712+
713+
strncpy(match, current, pos);
714+
match[pos] = '\0';
715+
debug("%s matched '%s'", probe->name, match);
716+
dev->flags |= probe->flags;
717+
718+
if (probe->flags & DEV_PROVIDES_ROOT ||
719+
probe->flags & DEV_ABBREV_ONLY)
720+
needs_root = false;
721+
722+
/* FIXME: useless code */
723+
if (probe->create)
724+
print_dev_dp_node(dev, probe);
725+
726+
dev->probes[n++] = dev_probes[i];
727+
current += pos;
728+
if (current[0] == '\0')
729+
debug("finished");
730+
else
731+
debug("current:'%s'", current);
732+
last_successful_probe = i;
733+
734+
if (!*current || !strncmp(current, "net/", 4))
735+
break;
736+
737+
continue;
738+
}
739+
740+
debug("dev_probes[%d]: %p dev->interface_type: %d\n",
741+
i+1, dev_probes[i+1], dev->interface_type);
742+
if (dev_probes[i+1] == NULL && dev->interface_type == unknown) {
743+
pos = 0;
744+
rc = sscanf(current, "%*[^/]/%n", &pos);
745+
if (rc < 0) {
746+
slash_err:
747+
efi_error("Cannot parse device link segment \"%s\"", current);
748+
goto err;
749+
}
750+
751+
while (current[pos] == '/')
752+
pos += 1;
753+
754+
if (!current[pos])
755+
goto slash_err;
756+
757+
debug("Cannot parse device link segment '%s'", current);
758+
debug("Skipping to '%s'", current + pos);
759+
debug("This means we can only create abbreviated paths");
760+
dev->flags |= DEV_ABBREV_ONLY;
761+
i = last_successful_probe;
762+
current += pos;
763+
764+
if (!*current || !strncmp(current, "net/", 4))
765+
break;
766+
}
767+
}
672768

673769
rc = ioctl(fd, SIOCGIFHWADDR, &ifr);
674770
if (rc < 0)
675771
goto err;
676772

677-
sz = pci_parser.create(&dev, buf, size, off);
773+
sz = make_blockdev_path(buf, size, dev);
678774
if (sz < 0)
679775
goto err;
680776
off += sz;
@@ -687,10 +783,13 @@ make_mac_path(uint8_t *buf, ssize_t size, const char * const ifname)
687783
goto err;
688784

689785
off += sz;
786+
690787
ret = off;
691788
err:
692789
if (fd >= 0)
693790
close(fd);
791+
if (dev->probes)
792+
free(dev->probes);
694793
return ret;
695794
}
696795

0 commit comments

Comments
 (0)