Loading fs_mgr/libsnapshot/include/libsnapshot/snapshot.h +7 −4 Original line number Diff line number Diff line Loading @@ -332,10 +332,13 @@ class SnapshotManager final : public ISnapshotManager { // Helper function for second stage init to restorecon on the rollback indicator. static std::string GetGlobalRollbackIndicatorPath(); // Detach dm-user devices from the current snapuserd, and populate // |snapuserd_argv| with the necessary arguments to restart snapuserd // and reattach them. bool DetachSnapuserdForSelinux(std::vector<std::string>* snapuserd_argv); // Populate |snapuserd_argv| with the necessary arguments to restart snapuserd // after loading selinux policy. bool PrepareSnapuserdArgsForSelinux(std::vector<std::string>* snapuserd_argv); // Detach dm-user devices from the first stage snapuserd. Load // new dm-user tables after loading selinux policy. bool DetachFirstStageSnapuserdForSelinux(); // Perform the transition from the selinux stage of snapuserd into the // second-stage of snapuserd. This process involves re-creating the dm-user Loading fs_mgr/libsnapshot/snapshot.cpp +76 −15 Original line number Diff line number Diff line Loading @@ -1746,13 +1746,6 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition, auto misc_name = user_cow_name; DmTable table; table.Emplace<DmTargetUser>(0, target.spec.length, misc_name); if (!dm_.LoadTableAndActivate(user_cow_name, table)) { LOG(ERROR) << "Unable to swap tables for " << misc_name; continue; } std::string source_device_name; if (snapshot_status.old_partition_size() > 0) { source_device_name = GetSourceDeviceName(snapshot); Loading Loading @@ -1780,13 +1773,6 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition, continue; } // Wait for ueventd to acknowledge and create the control device node. std::string control_device = "/dev/dm-user/" + misc_name; if (!WaitForDevice(control_device, 10s)) { LOG(ERROR) << "dm-user control device no found: " << misc_name; continue; } if (transition == InitTransition::SELINUX_DETACH) { if (!UpdateUsesUserSnapshots(lock.get())) { auto message = misc_name + "," + cow_image_device + "," + source_device; Loading @@ -1804,6 +1790,20 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition, continue; } DmTable table; table.Emplace<DmTargetUser>(0, target.spec.length, misc_name); if (!dm_.LoadTableAndActivate(user_cow_name, table)) { LOG(ERROR) << "Unable to swap tables for " << misc_name; continue; } // Wait for ueventd to acknowledge and create the control device node. std::string control_device = "/dev/dm-user/" + misc_name; if (!WaitForDevice(control_device, 10s)) { LOG(ERROR) << "dm-user control device no found: " << misc_name; continue; } uint64_t base_sectors; if (!UpdateUsesUserSnapshots(lock.get())) { base_sectors = Loading Loading @@ -4136,10 +4136,71 @@ bool SnapshotManager::IsSnapuserdRequired() { return status.state() != UpdateState::None && status.using_snapuserd(); } bool SnapshotManager::DetachSnapuserdForSelinux(std::vector<std::string>* snapuserd_argv) { bool SnapshotManager::PrepareSnapuserdArgsForSelinux(std::vector<std::string>* snapuserd_argv) { return PerformInitTransition(InitTransition::SELINUX_DETACH, snapuserd_argv); } bool SnapshotManager::DetachFirstStageSnapuserdForSelinux() { LOG(INFO) << "Detaching first stage snapuserd"; auto lock = LockExclusive(); if (!lock) return false; std::vector<std::string> snapshots; if (!ListSnapshots(lock.get(), &snapshots)) { LOG(ERROR) << "Failed to list snapshots."; return false; } size_t num_cows = 0; size_t ok_cows = 0; for (const auto& snapshot : snapshots) { std::string user_cow_name = GetDmUserCowName(snapshot, GetSnapshotDriver(lock.get())); if (dm_.GetState(user_cow_name) == DmDeviceState::INVALID) { continue; } DeviceMapper::TargetInfo target; if (!GetSingleTarget(user_cow_name, TableQuery::Table, &target)) { continue; } auto target_type = DeviceMapper::GetTargetType(target.spec); if (target_type != "user") { LOG(ERROR) << "Unexpected target type for " << user_cow_name << ": " << target_type; continue; } num_cows++; auto misc_name = user_cow_name; DmTable table; table.Emplace<DmTargetUser>(0, target.spec.length, misc_name); if (!dm_.LoadTableAndActivate(user_cow_name, table)) { LOG(ERROR) << "Unable to swap tables for " << misc_name; continue; } // Wait for ueventd to acknowledge and create the control device node. std::string control_device = "/dev/dm-user/" + misc_name; if (!WaitForDevice(control_device, 10s)) { LOG(ERROR) << "dm-user control device no found: " << misc_name; continue; } ok_cows++; LOG(INFO) << "control device is ready: " << control_device; } if (ok_cows != num_cows) { LOG(ERROR) << "Could not transition all snapuserd consumers."; return false; } return true; } bool SnapshotManager::PerformSecondStageInitTransition() { return PerformInitTransition(InitTransition::SECOND_STAGE); } Loading init/snapuserd_transition.cpp +7 −4 Original line number Diff line number Diff line Loading @@ -226,12 +226,9 @@ void SnapuserdSelinuxHelper::StartTransition() { argv_.emplace_back("snapuserd"); argv_.emplace_back("-no_socket"); if (!sm_->DetachSnapuserdForSelinux(&argv_)) { if (!sm_->PrepareSnapuserdArgsForSelinux(&argv_)) { LOG(FATAL) << "Could not perform selinux transition"; } // Make sure the process is gone so we don't have any selinux audits. KillFirstStageSnapuserd(old_pid_); } void SnapuserdSelinuxHelper::FinishTransition() { Loading Loading @@ -301,6 +298,12 @@ bool SnapuserdSelinuxHelper::TestSnapuserdIsReady() { } void SnapuserdSelinuxHelper::RelaunchFirstStageSnapuserd() { if (!sm_->DetachFirstStageSnapuserdForSelinux()) { LOG(FATAL) << "Could not perform selinux transition"; } KillFirstStageSnapuserd(old_pid_); auto fd = GetRamdiskSnapuserdFd(); if (!fd) { LOG(FATAL) << "Environment variable " << kSnapuserdFirstStageFdVar << " was not set!"; Loading Loading
fs_mgr/libsnapshot/include/libsnapshot/snapshot.h +7 −4 Original line number Diff line number Diff line Loading @@ -332,10 +332,13 @@ class SnapshotManager final : public ISnapshotManager { // Helper function for second stage init to restorecon on the rollback indicator. static std::string GetGlobalRollbackIndicatorPath(); // Detach dm-user devices from the current snapuserd, and populate // |snapuserd_argv| with the necessary arguments to restart snapuserd // and reattach them. bool DetachSnapuserdForSelinux(std::vector<std::string>* snapuserd_argv); // Populate |snapuserd_argv| with the necessary arguments to restart snapuserd // after loading selinux policy. bool PrepareSnapuserdArgsForSelinux(std::vector<std::string>* snapuserd_argv); // Detach dm-user devices from the first stage snapuserd. Load // new dm-user tables after loading selinux policy. bool DetachFirstStageSnapuserdForSelinux(); // Perform the transition from the selinux stage of snapuserd into the // second-stage of snapuserd. This process involves re-creating the dm-user Loading
fs_mgr/libsnapshot/snapshot.cpp +76 −15 Original line number Diff line number Diff line Loading @@ -1746,13 +1746,6 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition, auto misc_name = user_cow_name; DmTable table; table.Emplace<DmTargetUser>(0, target.spec.length, misc_name); if (!dm_.LoadTableAndActivate(user_cow_name, table)) { LOG(ERROR) << "Unable to swap tables for " << misc_name; continue; } std::string source_device_name; if (snapshot_status.old_partition_size() > 0) { source_device_name = GetSourceDeviceName(snapshot); Loading Loading @@ -1780,13 +1773,6 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition, continue; } // Wait for ueventd to acknowledge and create the control device node. std::string control_device = "/dev/dm-user/" + misc_name; if (!WaitForDevice(control_device, 10s)) { LOG(ERROR) << "dm-user control device no found: " << misc_name; continue; } if (transition == InitTransition::SELINUX_DETACH) { if (!UpdateUsesUserSnapshots(lock.get())) { auto message = misc_name + "," + cow_image_device + "," + source_device; Loading @@ -1804,6 +1790,20 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition, continue; } DmTable table; table.Emplace<DmTargetUser>(0, target.spec.length, misc_name); if (!dm_.LoadTableAndActivate(user_cow_name, table)) { LOG(ERROR) << "Unable to swap tables for " << misc_name; continue; } // Wait for ueventd to acknowledge and create the control device node. std::string control_device = "/dev/dm-user/" + misc_name; if (!WaitForDevice(control_device, 10s)) { LOG(ERROR) << "dm-user control device no found: " << misc_name; continue; } uint64_t base_sectors; if (!UpdateUsesUserSnapshots(lock.get())) { base_sectors = Loading Loading @@ -4136,10 +4136,71 @@ bool SnapshotManager::IsSnapuserdRequired() { return status.state() != UpdateState::None && status.using_snapuserd(); } bool SnapshotManager::DetachSnapuserdForSelinux(std::vector<std::string>* snapuserd_argv) { bool SnapshotManager::PrepareSnapuserdArgsForSelinux(std::vector<std::string>* snapuserd_argv) { return PerformInitTransition(InitTransition::SELINUX_DETACH, snapuserd_argv); } bool SnapshotManager::DetachFirstStageSnapuserdForSelinux() { LOG(INFO) << "Detaching first stage snapuserd"; auto lock = LockExclusive(); if (!lock) return false; std::vector<std::string> snapshots; if (!ListSnapshots(lock.get(), &snapshots)) { LOG(ERROR) << "Failed to list snapshots."; return false; } size_t num_cows = 0; size_t ok_cows = 0; for (const auto& snapshot : snapshots) { std::string user_cow_name = GetDmUserCowName(snapshot, GetSnapshotDriver(lock.get())); if (dm_.GetState(user_cow_name) == DmDeviceState::INVALID) { continue; } DeviceMapper::TargetInfo target; if (!GetSingleTarget(user_cow_name, TableQuery::Table, &target)) { continue; } auto target_type = DeviceMapper::GetTargetType(target.spec); if (target_type != "user") { LOG(ERROR) << "Unexpected target type for " << user_cow_name << ": " << target_type; continue; } num_cows++; auto misc_name = user_cow_name; DmTable table; table.Emplace<DmTargetUser>(0, target.spec.length, misc_name); if (!dm_.LoadTableAndActivate(user_cow_name, table)) { LOG(ERROR) << "Unable to swap tables for " << misc_name; continue; } // Wait for ueventd to acknowledge and create the control device node. std::string control_device = "/dev/dm-user/" + misc_name; if (!WaitForDevice(control_device, 10s)) { LOG(ERROR) << "dm-user control device no found: " << misc_name; continue; } ok_cows++; LOG(INFO) << "control device is ready: " << control_device; } if (ok_cows != num_cows) { LOG(ERROR) << "Could not transition all snapuserd consumers."; return false; } return true; } bool SnapshotManager::PerformSecondStageInitTransition() { return PerformInitTransition(InitTransition::SECOND_STAGE); } Loading
init/snapuserd_transition.cpp +7 −4 Original line number Diff line number Diff line Loading @@ -226,12 +226,9 @@ void SnapuserdSelinuxHelper::StartTransition() { argv_.emplace_back("snapuserd"); argv_.emplace_back("-no_socket"); if (!sm_->DetachSnapuserdForSelinux(&argv_)) { if (!sm_->PrepareSnapuserdArgsForSelinux(&argv_)) { LOG(FATAL) << "Could not perform selinux transition"; } // Make sure the process is gone so we don't have any selinux audits. KillFirstStageSnapuserd(old_pid_); } void SnapuserdSelinuxHelper::FinishTransition() { Loading Loading @@ -301,6 +298,12 @@ bool SnapuserdSelinuxHelper::TestSnapuserdIsReady() { } void SnapuserdSelinuxHelper::RelaunchFirstStageSnapuserd() { if (!sm_->DetachFirstStageSnapuserdForSelinux()) { LOG(FATAL) << "Could not perform selinux transition"; } KillFirstStageSnapuserd(old_pid_); auto fd = GetRamdiskSnapuserdFd(); if (!fd) { LOG(FATAL) << "Environment variable " << kSnapuserdFirstStageFdVar << " was not set!"; Loading