| 571 | } |
| 572 | |
| 573 | static int |
| 574 | parse_dir_md(char **conf) |
| 575 | { |
| 576 | struct stat sb; |
| 577 | struct thread *td; |
| 578 | struct md_ioctl *mdio; |
| 579 | char *path, *tok; |
| 580 | int error, fd, len; |
| 581 | |
| 582 | td = curthread; |
| 583 | |
| 584 | error = parse_token(conf, &tok); |
| 585 | if (error) |
| 586 | return (error); |
| 587 | |
| 588 | len = strlen(tok); |
| 589 | mdio = malloc(sizeof(*mdio) + len + 1, M_TEMP, M_WAITOK | M_ZERO); |
| 590 | path = (void *)(mdio + 1); |
| 591 | bcopy(tok, path, len); |
| 592 | free(tok, M_TEMP); |
| 593 | |
| 594 | /* Get file status. */ |
| 595 | error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &sb, NULL); |
| 596 | if (error) |
| 597 | goto out; |
| 598 | |
| 599 | /* Open /dev/mdctl so that we can attach/detach. */ |
| 600 | error = kern_openat(td, AT_FDCWD, "/dev/" MDCTL_NAME, UIO_SYSSPACE, |
| 601 | O_RDWR, 0); |
| 602 | if (error) |
| 603 | goto out; |
| 604 | |
| 605 | fd = td->td_retval[0]; |
| 606 | mdio->md_version = MDIOVERSION; |
| 607 | mdio->md_type = MD_VNODE; |
| 608 | |
| 609 | if (root_mount_mddev != -1) { |
| 610 | mdio->md_unit = root_mount_mddev; |
| 611 | (void)kern_ioctl(td, fd, MDIOCDETACH, (void *)mdio); |
| 612 | /* Ignore errors. We don't care. */ |
| 613 | root_mount_mddev = -1; |
| 614 | } |
| 615 | |
| 616 | mdio->md_file = (void *)(mdio + 1); |
| 617 | mdio->md_options = MD_AUTOUNIT | MD_READONLY; |
| 618 | mdio->md_mediasize = sb.st_size; |
| 619 | mdio->md_unit = 0; |
| 620 | error = kern_ioctl(td, fd, MDIOCATTACH, (void *)mdio); |
| 621 | if (error) |
| 622 | goto out; |
| 623 | |
| 624 | if (mdio->md_unit > 9) { |
| 625 | printf("rootmount: too many md units\n"); |
| 626 | mdio->md_file = NULL; |
| 627 | mdio->md_options = 0; |
| 628 | mdio->md_mediasize = 0; |
| 629 | error = kern_ioctl(td, fd, MDIOCDETACH, (void *)mdio); |
| 630 | /* Ignore errors. We don't care. */ |
no test coverage detected