Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 270c98f1 authored by David Anderson's avatar David Anderson Committed by Gerrit Code Review
Browse files

Merge changes from topic "snapuserd-selinux"

* changes:
  libsnapshot: Fix tests that depend on PrepareOneSnapshot().
  libsnapshot: Ensure dm-user devices are destroyed after a merge.
  libsnapshot: Fix tests for mapping snapshots in first-stage init.
  init: Add an selinux transition for snapuserd.
parents 06ee6f17 8302b875
Loading
Loading
Loading
Loading
+27 −7
Original line number Diff line number Diff line
@@ -306,13 +306,17 @@ class SnapshotManager final : public ISnapshotManager {
    // Helper function for second stage init to restorecon on the rollback indicator.
    static std::string GetGlobalRollbackIndicatorPath();

    // Initiate the transition from first-stage to second-stage snapuserd. This
    // process involves re-creating the dm-user table entries for each device,
    // so that they connect to the new daemon. Once all new tables have been
    // activated, we ask the first-stage daemon to cleanly exit.
    //
    // The caller must pass a function which starts snapuserd.
    bool PerformSecondStageTransition();
    // 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);

    // Perform the transition from the selinux stage of snapuserd into the
    // second-stage of snapuserd. This process involves re-creating the dm-user
    // table entries for each device, so that they connect to the new daemon.
    // Once all new tables have been activated, we ask the first-stage daemon
    // to cleanly exit.
    bool PerformSecondStageInitTransition();

    // ISnapshotManager overrides.
    bool BeginUpdate() override;
@@ -626,6 +630,9 @@ class SnapshotManager final : public ISnapshotManager {
    // The reverse of MapPartitionWithSnapshot.
    bool UnmapPartitionWithSnapshot(LockedFile* lock, const std::string& target_partition_name);

    // Unmap a dm-user device through snapuserd.
    bool UnmapDmUserDevice(const std::string& snapshot_name);

    // If there isn't a previous update, return true. |needs_merge| is set to false.
    // If there is a previous update but the device has not boot into it, tries to cancel the
    //   update and delete any snapshots. Return true if successful. |needs_merge| is set to false.
@@ -693,6 +700,19 @@ class SnapshotManager final : public ISnapshotManager {
    // returns true.
    bool WaitForDevice(const std::string& device, std::chrono::milliseconds timeout_ms);

    enum class InitTransition { SELINUX_DETACH, SECOND_STAGE };

    // Initiate the transition from first-stage to second-stage snapuserd. This
    // process involves re-creating the dm-user table entries for each device,
    // so that they connect to the new daemon. Once all new tables have been
    // activated, we ask the first-stage daemon to cleanly exit.
    //
    // If the mode is SELINUX_DETACH, snapuserd_argv must be non-null and will
    // be populated with a list of snapuserd arguments to pass to execve(). It
    // is otherwise ignored.
    bool PerformInitTransition(InitTransition transition,
                               std::vector<std::string>* snapuserd_argv = nullptr);

    std::string gsid_dir_;
    std::string metadata_dir_;
    std::unique_ptr<IDeviceInfo> device_;
+0 −2
Original line number Diff line number Diff line
@@ -32,8 +32,6 @@ static constexpr uint32_t PACKET_SIZE = 512;

static constexpr char kSnapuserdSocket[] = "snapuserd";

static constexpr char kSnapuserdFirstStagePidVar[] = "FIRST_STAGE_SNAPUSERD_PID";

// Ensure that the second-stage daemon for snapuserd is running.
bool EnsureSnapuserdStarted();

+63 −24
Original line number Diff line number Diff line
@@ -1247,6 +1247,10 @@ bool SnapshotManager::CollapseSnapshotDevice(const std::string& name,
        return false;
    }

    if (status.compression_enabled()) {
        UnmapDmUserDevice(name);
    }

    // Cleanup the base device as well, since it is no longer used. This does
    // not block cleanup.
    auto base_name = GetBaseDeviceName(name);
@@ -1291,12 +1295,13 @@ bool SnapshotManager::HandleCancelledUpdate(LockedFile* lock,
    return RemoveAllUpdateState(lock, before_cancel);
}

bool SnapshotManager::PerformSecondStageTransition() {
    LOG(INFO) << "Performing second-stage transition for snapuserd.";
bool SnapshotManager::PerformInitTransition(InitTransition transition,
                                            std::vector<std::string>* snapuserd_argv) {
    LOG(INFO) << "Performing transition for snapuserd.";

    // Don't use EnsuerSnapuserdConnected() because this is called from init,
    // and attempting to do so will deadlock.
    if (!snapuserd_client_) {
    if (!snapuserd_client_ && transition != InitTransition::SELINUX_DETACH) {
        snapuserd_client_ = SnapuserdClient::Connect(kSnapuserdSocket, 10s);
        if (!snapuserd_client_) {
            LOG(ERROR) << "Unable to connect to snapuserd";
@@ -1343,6 +1348,9 @@ bool SnapshotManager::PerformSecondStageTransition() {
        }

        auto misc_name = user_cow_name;
        if (transition == InitTransition::SELINUX_DETACH) {
            misc_name += "-selinux";
        }

        DmTable table;
        table.Emplace<DmTargetUser>(0, target.spec.length, misc_name);
@@ -1378,6 +1386,17 @@ bool SnapshotManager::PerformSecondStageTransition() {
            continue;
        }

        if (transition == InitTransition::SELINUX_DETACH) {
            auto message = misc_name + "," + cow_image_device + "," + backing_device;
            snapuserd_argv->emplace_back(std::move(message));

            // Do not attempt to connect to the new snapuserd yet, it hasn't
            // been started. We do however want to wait for the misc device
            // to have been created.
            ok_cows++;
            continue;
        }

        uint64_t base_sectors =
                snapuserd_client_->InitDmUserCow(misc_name, cow_image_device, backing_device);
        if (base_sectors == 0) {
@@ -2048,11 +2067,36 @@ bool SnapshotManager::UnmapCowDevices(LockedFile* lock, const std::string& name)

    auto& dm = DeviceMapper::Instance();

    auto dm_user_name = GetDmUserCowName(name);
    if (IsCompressionEnabled() && dm.GetState(dm_user_name) != DmDeviceState::INVALID) {
    if (IsCompressionEnabled() && !UnmapDmUserDevice(name)) {
        return false;
    }

    auto cow_name = GetCowName(name);
    if (!dm.DeleteDeviceIfExists(cow_name)) {
        LOG(ERROR) << "Cannot unmap " << cow_name;
        return false;
    }

    std::string cow_image_name = GetCowImageDeviceName(name);
    if (!images_->UnmapImageIfExists(cow_image_name)) {
        LOG(ERROR) << "Cannot unmap image " << cow_image_name;
        return false;
    }
    return true;
}

bool SnapshotManager::UnmapDmUserDevice(const std::string& snapshot_name) {
    auto& dm = DeviceMapper::Instance();

    if (!EnsureSnapuserdConnected()) {
        return false;
    }

    auto dm_user_name = GetDmUserCowName(snapshot_name);
    if (dm.GetState(dm_user_name) == DmDeviceState::INVALID) {
        return true;
    }

    if (!dm.DeleteDeviceIfExists(dm_user_name)) {
        LOG(ERROR) << "Cannot unmap " << dm_user_name;
        return false;
@@ -2069,19 +2113,6 @@ bool SnapshotManager::UnmapCowDevices(LockedFile* lock, const std::string& name)
        LOG(ERROR) << "Timed out waiting for " << control_device << " to unlink";
        return false;
    }
    }

    auto cow_name = GetCowName(name);
    if (!dm.DeleteDeviceIfExists(cow_name)) {
        LOG(ERROR) << "Cannot unmap " << cow_name;
        return false;
    }

    std::string cow_image_name = GetCowImageDeviceName(name);
    if (!images_->UnmapImageIfExists(cow_image_name)) {
        LOG(ERROR) << "Cannot unmap image " << cow_image_name;
        return false;
    }
    return true;
}

@@ -3311,5 +3342,13 @@ bool SnapshotManager::IsSnapuserdRequired() {
    return status.state() != UpdateState::None && status.compression_enabled();
}

bool SnapshotManager::DetachSnapuserdForSelinux(std::vector<std::string>* snapuserd_argv) {
    return PerformInitTransition(InitTransition::SELINUX_DETACH, snapuserd_argv);
}

bool SnapshotManager::PerformSecondStageInitTransition() {
    return PerformInitTransition(InitTransition::SECOND_STAGE);
}

}  // namespace snapshot
}  // namespace android
+160 −142

File changed.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ init_device_sources = [
    "selabel.cpp",
    "selinux.cpp",
    "sigchld_handler.cpp",
    "snapuserd_transition.cpp",
    "switch_root.cpp",
    "uevent_listener.cpp",
    "ueventd.cpp",
Loading