package fs::wild_device; use diagnostics; use strict; use devices; use common; sub analyze { my ($dev) = @_; if ($dev =~ m!^/u?dev/(.*)!) { 'dev', $dev; } elsif ($dev !~ m!^/! && (-e "/dev/$dev" || -e "/dev/$dev")) { 'dev', "/dev/$dev"; } elsif ($dev =~ /^LABEL=(.*)/) { 'label', $1; } elsif ($dev =~ /^UUID=(.*)/) { 'uuid', $1; } elsif (member($dev, qw(none rootfs))) { 'virtual'; } elsif ($dev =~ m!^(\S+):/(\w|$)!) { 'nfs'; } elsif ($dev =~ m!^//\w!) { 'smb'; } elsif ($dev =~ m!^https?://!) { 'dav'; } } sub to_subpart { my ($dev) = @_; my $part = { device => $dev, faked_device => 1 }; #- default if (my ($kind, $val) = analyze($dev)) { if ($kind eq 'label') { $part->{device_LABEL} = $val; } elsif ($kind eq 'uuid') { $part->{device_UUID} = $val; } elsif ($kind eq 'dev') { my %part = (faked_device => 0); if (my $rdev = (stat "$dev")[6]) { ($part{major}, $part{minor}) = unmakedev($rdev); } my $symlink = $dev !~ m!mapper/! ? readlink("$dev") : undef; $dev =~ s!/u?dev/!!; if ($symlink && $symlink !~ m!^/!) { my $keep = 1; if ($symlink =~ m!/! || $dev =~ m!/!) { $symlink = MDK::Common::File::concat_symlink("/dev/" . dirname($dev), $symlink); $symlink =~ s!^/dev/!! or $keep = 0; } if ($keep) { $part{device_LABEL} = $1 if $dev =~ m!^disk/by-label/(.*)!; $part{device_UUID} = $1 if $dev =~ m!^disk/by-uuid/(.*)!; $part{device_alias} = $dev; $dev = $symlink; } } if (my $part_number = devices::part_number(\%part)) { $part{part_number} = $part_number; } $part{device} = $dev; return \%part; } } else { if ($dev =~ m!^/! && -f "$dev") { #- it must be a loopback file or directory to bind } else { log::l("part_from_wild_device_name: unknown device $dev"); } } $part; } sub _prefer_device_UUID { my ($part) = @_; $part->{prefer_device_UUID} || !$::no_uuid_by_default && devices::should_prefer_UUID($part->{device}); } sub from_part { my ($prefix, $part) = @_; if ($part->{prefer_device_LABEL}) { 'LABEL=' . $part->{device_LABEL}; } elsif ($part->{device_alias}) { "/dev/$part->{device_alias}"; } elsif (!$part->{prefer_device} && $part->{device_UUID} && _prefer_device_UUID($part)) { 'UUID=' . $part->{device_UUID}; } else { my $faked_device = exists $part->{faked_device} ? $part->{faked_device} : do { #- in case $part has been created without using fs::wild_device::to_subpart() my ($kind) = analyze($part->{device}); $kind ? $kind ne 'dev' : $part->{device} =~ m!^/!; }; if ($faked_device) { $part->{device}; } elsif ($part->{device} =~ m!^/dev/!) { log::l("ERROR: i have a full device $part->{device}, this should not happen. use fs::wild_device::to_subpart() instead of creating bad part data-structures!"); $part->{device}; } else { my $dev = "/dev/$part->{device}"; eval { devices::make("$prefix$dev") }; $dev; } } } 1;