Skip to content

Commit

Permalink
Merge pull request #121 from joseivanlopez/merge_SP2_features
Browse files Browse the repository at this point in the history
Merge pre-SLE-15-SP2
  • Loading branch information
joseivanlopez committed Mar 27, 2019
2 parents 7bda5f1 + 8449c51 commit 1db4a58
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 333 deletions.
6 changes: 6 additions & 0 deletions package/yast2-update.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Tue Mar 26 16:29:07 UTC 2019 - José Iván López González <jlopez@suse.com>

- Remove code related to device name translations.
- 4.2.0

-------------------------------------------------------------------
Thu Jan 24 18:49:24 UTC 2019 - lslezak@suse.cz

Expand Down
2 changes: 1 addition & 1 deletion package/yast2-update.spec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


Name: yast2-update
Version: 4.1.8
Version: 4.2.0
Release: 0

BuildRoot: %{_tmppath}/%{name}-%{version}-build
Expand Down
306 changes: 40 additions & 266 deletions src/modules/RootPart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,6 @@ def main
# include Installation::destdir.
@activated = []


# Link to SDB article concerning renaming of devices.
@sdb = Builtins.sformat(
_(
"See the SDB article at %1 for details\nabout how to solve this problem."
),
"http://support.novell.com/techcenter/sdb/en/2003/03/fhassel_update_not_possible.html"
)

# translation from new to old device names
# such as /dev/sdc4 -> /dev/hdb4
@backward_translation = {}
Expand Down Expand Up @@ -626,90 +617,6 @@ def update_mount_options(options)
options
end

# Translates FS or Cryptotab (old devices to new ones).
# Such as /dev/hda5 to /dev/sda5.
#
# @param list <map> of definitions to translate
# @param string key name in map to translate
# @param string key name in map to keep the old value
# @return [Array<Hash>] of translated definitions
#
# @see #https://bugzilla.novell.com/show_bug.cgi?id=258222
def TranslateFsOrCryptoTab(translate, key_to_translate, key_preserve_as)
translate = deep_copy(translate)
# Check whether there is any hardware information that could be used
check_command = Builtins.sformat(
"/usr/bin/find '%1/var/lib/hardware/'",
String.Quote(Installation.destdir)
)
cmd = Convert.to_map(
SCR.Execute(path(".target.bash_output"), check_command)
)

if Ops.get(cmd, "exit") != nil
files = Builtins.splitstring(Ops.get_string(cmd, "stdout", ""), "\n")
files_count = Builtins.size(files)
if files_count == nil || Ops.less_or_equal(files_count, 2)
Builtins.y2error(
"There are only %1 files in /var/lib/hardware/, translation needn't work!",
files_count
)
else
Builtins.y2milestone(
"There are %1 files in /var/lib/hardware/",
files_count
)
end
end

# first find a list of values for translation
old_names = []
Builtins.foreach(translate) do |m|
old_names = Builtins.add(
old_names,
Ops.get_string(m, key_to_translate, "")
)
end

# translate them
# storage-ng
new_names = old_names
=begin
new_names = Storage.GetTranslatedDevices(
Installation.installedVersion,
Installation.updateVersion,
old_names
)
=end

i = 0

# replace old values with translated ones
while Ops.less_than(i, Builtins.size(translate))
default_val = Ops.get_string(translate, [i, key_to_translate], "")
new_val = Ops.get(new_names, i, default_val)

Ops.set(translate, [i, key_to_translate], new_val)
Ops.set(translate, [i, key_preserve_as], default_val)
Ops.set(@backward_translation, new_val, default_val)

Ops.set(
translate,
[i, "mntops"],
update_mount_options(Ops.get_string(translate, [i, "mntops"], ""))
)

i = Ops.add(i, 1)
end

Builtins.y2milestone(
"Current backward translations: %1",
@backward_translation
)

deep_copy(translate)
end

# Register a new fstab agent and read the configuration
# from Installation::destdir
def readFsTab(fstab)
Expand Down Expand Up @@ -884,37 +791,6 @@ def read_fstab_and_cryptotab(fstab, crtab, root_device_current)
)
end

fstab_has_separate_var = (
fstab_ref = arg_ref(fstab.value);
_FstabHasSeparateVar_result = FstabHasSeparateVar(fstab_ref);
fstab.value = fstab_ref.value;
_FstabHasSeparateVar_result
)
# mount /var
if fstab_has_separate_var
Builtins.y2warning("Separate /var partition!")
MountVarIfRequired(fstab.value, root_device_current, false)
else
Builtins.y2milestone("No separate /var partition found")
end

Builtins.y2milestone("fstab: %1", fstab.value)
fstab.value = TranslateFsOrCryptoTab(fstab.value, "spec", "spec_old")
Builtins.y2milestone("fstab: (translated) %1", fstab.value)

Builtins.y2milestone("crtab: %1", crtab.value)
crtab.value = TranslateFsOrCryptoTab(crtab.value, "file", "file_old")
Builtins.y2milestone("crtab: (translated) %1", crtab.value)

# umount /var
if fstab_has_separate_var
SCR.Execute(
path(".target.umount"),
Ops.add(Installation.destdir, "/var")
)
@activated = Builtins.remove(@activated, 0)
end

true
end

Expand Down Expand Up @@ -1254,32 +1130,24 @@ def MountFSTab(fstab, message)
end

# Mount /var partition
# @param [String] device string device holding the /var subtree
# @return [String] nil on success, error description on fail
#
# @param device [String] name of the device holding /var
# @return [String, nil] nil on success, error description on fail
def MountVarPartition(device)
mount_err = FsckAndMount("/var", device, "")
err_message = nil
if mount_err != nil
Builtins.y2error(-1, "failed to mount /var")
err_message = Ops.add(
Ops.add(
Ops.add(
Ops.add(
Builtins.sformat(
# error message
_("The /var partition %1 could not be mounted.\n"),
device
),
"\n"
),
mount_err
),
"\n\n"
),
@sdb
)
end
err_message

return nil unless mount_err

log.error("failed to mount /var")

# TRANSLATORS: error message when /var partition cannot be mounted. %{device}
# is replaced by a device name (e.g., /dev/sda2) and %{error} is replaced by
# error details.
format(
_("The /var partition %{device} could not be mounted.\n\n%{error}"),
device: device,
error: mount_err
)
end

# <-- BNC #448577, Cannot find /var partition automatically
Expand Down Expand Up @@ -1440,7 +1308,7 @@ def MountUserDefinedVarPartition
manual_mount_successful
end

def MountVarIfRequired(fstab, root_device_current, manual_var_mount)
def MountVarIfRequired(fstab, manual_var_mount)
fstab = deep_copy(fstab)
var_device_fstab = (
fstab_ref = arg_ref(fstab);
Expand All @@ -1458,40 +1326,26 @@ def MountVarIfRequired(fstab, root_device_current, manual_var_mount)
return nil
end

# BNC #494240: all methods except kernel names should be stable enough
if !mounted_by_kernel_name?(var_device_fstab)
log.info "Device #{var_device_fstab} is not mounted by kernel name, mounting..."
return MountVarPartition(var_device_fstab)
end

# Mounting virtual devices by kernel name (e.g. /dev/md0 or /dev/system/swap_lv)
# is also considered to be safe
if virtual_device?(var_device_fstab)
log.info "Device #{var_device_fstab} is not a partition, mounting..."
return MountVarPartition(var_device_fstab)
end
filesystem = find_filesystem_by_fstab_spec(var_device_fstab)

# At this point, var_device_fstab points either to a device that is not
# longer available or to a plain partition.
#
# In the second case the name may not be reliable since the disk may have
# changed its name (e.g. it used to be recognized as /dev/sda or /dev/hdb in
# the system to update but it became /dev/sdb in the new system).
new_name = update_var_dev_name(var_device_fstab, fstab, root_device_current)
if new_name
if new_name != var_device_fstab
log.info "Partition #{var_device_fstab} seems to have turned into #{new_name}"
end
log.info "Device #{new_name} is a partition, mounting..."
return MountVarPartition(new_name)
end
# Try to mount /var if any filesystem matches the fstab specification
return MountVarPartition(var_device_fstab) if filesystem

# BNC #448577: cannot find /var partition automatically, so ask the user
return nil if manual_var_mount && MountUserDefinedVarPartition()

# Everything else failed, return error message
log.error "Unable to mount /var partition"
_("Unable to mount /var partition with this disk configuration.\n") + @sdb

_("Unable to mount /var partition with this disk configuration.\n")
end

# Finds a filesystem that matches the given fstab spec
#
# @param spec [String]
# @return [Y2Storage::Filesystem, nil]
def find_filesystem_by_fstab_spec(spec)
probed.blk_filesystems.find { |f| f.match_fstab_spec?(spec) }
end

def has_pam_mount
Expand Down Expand Up @@ -1603,7 +1457,7 @@ def MountPartitions(root_device_current)
message = _("No fstab found.")
success = false
else
tmp_msg = MountVarIfRequired(fstab, root_device_current, true)
tmp_msg = MountVarIfRequired(fstab, true)
if tmp_msg != nil
Builtins.y2error("failed to mount /var!")
message = tmp_msg
Expand All @@ -1622,21 +1476,16 @@ def MountPartitions(root_device_current)
check_root_device_result
)
Builtins.y2error("fstab has wrong root device!")
# message part 1
message = Ops.add(
Ops.add(
_(
"The root partition in /etc/fstab has an invalid root device.\n"
),
# message part 2
Builtins.sformat(
_("It is currently mounted as %1 but listed as %2.\n"),
root_device_current,
tmp
)
),
@sdb

# TRANSLATORS: Error message, where %{root} and %{tmp} are replaced by
# device names (e.g., /dev/sda1 and /dev/sda2).
message = format(
_("The root partition in /etc/fstab has an invalid root device.\n" \
"It is currently mounted as %{root} but listed as %{tmp}."),
root: root_device_current,
tmp: tmp
)

success = false
else
Builtins.y2milestone("cryptotab %1", crtab)
Expand Down Expand Up @@ -2304,81 +2153,6 @@ def udev_uuid(device_spec)
device.udev_full_uuid
end

# Whether the given fstab spec corresponds to a device mounted by its kernel
# device name.
#
# @param spec [String] content of the first column of an /etc/fstab entry
# @return [Boolean]
def mounted_by_kernel_name?(spec)
mount_by = Y2Storage::Filesystems::MountByType.from_fstab_spec(spec)
mount_by.is?(:device)
end

# Whether the device referenced by the given fstab spec is a virtual device
# (basically anything that is not a partition).
#
# This is somehow the inverse of the old Storage.DeviceRealDisk
#
# @param spec [String] content of the first column of an /etc/fstab entry
# @return [Boolean] true if the device was found and is not a partition
def virtual_device?(spec)
filesystem = fs_by_devicename(probed, spec)
# If 'filesystem' is nil, either the device is not longer there or it's a
# partition that now has a new name (names of virtual devices should be stable).
return false unless filesystem

# If this is not based on a block device (so far that means this is NFS),
# then it's virtual.
return true unless filesystem.respond_to?(:plain_blk_devices)

# To be more faithful to the original check on Storage.DeviceRealDisk
# let's consider everything but a partition to be virtual.
filesystem.plain_blk_devices.none? { |dev| dev.is?(:partition) }
end

# This method tries to infer the /var device name from its partition number
# and the name of the root device.
#
# @param var_name [String] spec of the /var partition in the old /etc/fstab
# @param fstab [Array<Hash>] content of the old /etc/fstab
# @param root_current_name [String] current kernel device name of the root partition
# @return [String, nil] new name of the device (best guess), nil if we know
# the current name is outdated but we cannot infer the new one
def update_var_dev_name(var_name, fstab, root_current_name)
root_entry = fstab.find { |entry| entry["file"] == "/" }
root_spec = root_entry ? root_entry["spec"] : nil
root_device = probed.find_by_name(root_current_name)

# If /var was mounted by partition kernel name but the root device was
# not, we cannot apply the upcoming logic to make up the new /var device
# name. Let's simply use the one we already know.
if root_spec.nil? || !mounted_by_kernel_name?(root_spec) || !root_device.is?(:partition)
return var_name
end

# Regular expresion to break a partition name. Second capture gets the
# partition number (as string). First capture gets the rest.
regexp = /(.*[^\d])(\d*)$/
var_name_no_number, var_name_number = regexp.match(var_name).captures
root_spec_no_number = regexp.match(root_spec)[1]

# If /var and / were partitions in the same disk...
if var_name_no_number == root_spec_no_number
root_current_no_number = regexp.match(root_current_name)[1]
return root_current_no_number + var_name_number
end

# If both partitions were not in the same disk, we assume '/' is in one
# disk and '/var' in the other one. Of course that logic only works if
# there are exactly two disks.
return nil if probed.disk_devices.size != 2

root_disk = root_device.partitionable
other_disk = probed.disk_devices.find { |dev| dev != root_disk }
partition = other_disk.partitions.find { |part| part.number == var_name_number.to_i }
partition.name
end

# @see #mount_regular_fstab_entry?(
ALLOWED_FS = [
"ext",
Expand Down
Loading

0 comments on commit 1db4a58

Please sign in to comment.