diff options
author | adlr@google.com <adlr@google.com@06c00378-0e64-4dae-be16-12b19f9950a1> | 2009-12-04 20:57:17 +0000 |
---|---|---|
committer | adlr@google.com <adlr@google.com@06c00378-0e64-4dae-be16-12b19f9950a1> | 2009-12-04 20:57:17 +0000 |
commit | 3defe6acb3609e70e851a6eff062577d25a2af9d (patch) | |
tree | 341e979027fde117dd8906483db7a5c703a2e1cf /filesystem_copier_action.h | |
parent | c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9 (diff) |
Missed new files in last commit
Review URL: http://codereview.chromium.org/465067
git-svn-id: svn://chrome-svn/chromeos/trunk@336 06c00378-0e64-4dae-be16-12b19f9950a1
Diffstat (limited to 'filesystem_copier_action.h')
-rw-r--r-- | filesystem_copier_action.h | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/filesystem_copier_action.h b/filesystem_copier_action.h new file mode 100644 index 00000000..8f0dc06d --- /dev/null +++ b/filesystem_copier_action.h @@ -0,0 +1,147 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__ +#define CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__ + +#include <sys/stat.h> +#include <sys/types.h> +#include <string> +#include <glib.h> +#include "update_engine/action.h" +#include "update_engine/install_plan.h" + +// This action will only do real work if it's a delta update. It will +// format the install partition as ext3/4, copy the root filesystem into it, +// and then terminate. + +// Implementation notes: This action uses a helper thread, which seems to +// violate the design decision to only have a single thread and use +// asynchronous i/o. The issue is that (to the best of my knowledge), +// there are no linux APIs to crawl a filesystem's metadata asynchronously. +// The suggested way seems to be to open the raw device and parse the ext +// filesystem. That's not a good approach for a number of reasons: +// - ties us to ext filesystem +// - although this wouldn't happen at the time of writing, it may not handle +// changes to the source fs during the copy as gracefully. +// - requires us to have read-access to the source filesystem device, which +// may be a security issue. +// +// Having said this, using a helper thread is not ideal, but it's acceptable: +// we still honor the Action API. That is, all interaction between the action +// and other objects in the system (e.g. the ActionProcessor) happens on the +// main thread. The helper thread is fully encapsulated by the action. + +namespace chromeos_update_engine { + +class FilesystemCopierAction; + +template<> +class ActionTraits<FilesystemCopierAction> { + public: + // Takes the install plan as input + typedef InstallPlan InputObjectType; + // Passes the install plan as output + typedef InstallPlan OutputObjectType; +}; + +class FilesystemCopierAction : public Action<FilesystemCopierAction> { + public: + FilesystemCopierAction() + : thread_should_exit_(0), + is_mounted_(false), + copy_source_("/"), + skipped_copy_(false) {} + typedef ActionTraits<FilesystemCopierAction>::InputObjectType + InputObjectType; + typedef ActionTraits<FilesystemCopierAction>::OutputObjectType + OutputObjectType; + void PerformAction(); + void TerminateProcessing(); + + // Used for testing, so we can copy from somewhere other than root + void set_copy_source(const string& path) { + copy_source_ = path; + } + // Returns true if we detected that a copy was unneeded and thus skipped it. + bool skipped_copy() { return skipped_copy_; } + + // Debugging/logging + static std::string StaticType() { return "FilesystemCopierAction"; } + std::string Type() const { return StaticType(); } + + private: + // These synchronously mount or unmount the given mountpoint + bool Mount(const string& device, const string& mountpoint); + bool Unmount(const string& mountpoint); + + // Performs a recursive file/directory copy from copy_source_ to dest_path_. + // Doesn't return until the copy has completed. Returns true on success + // or false on error. + bool CopySynchronously(); + + // There are helper functions for CopySynchronously. They handle creating + // various types of files. They return true on success. + bool CreateDirSynchronously(const std::string& new_path, + const struct stat& stbuf); + bool CopyFileSynchronously(const std::string& old_path, + const std::string& new_path, + const struct stat& stbuf); + bool CreateHardLinkSynchronously(const std::string& old_path, + const std::string& new_path); + // Note: Here, old_path is an existing symlink that will be copied to + // new_path. Thus, old_path is *not* the same as the old_path from + // the symlink() syscall. + bool CopySymlinkSynchronously(const std::string& old_path, + const std::string& new_path, + const struct stat& stbuf); + bool CreateNodeSynchronously(const std::string& new_path, + const struct stat& stbuf); + + // Returns NULL on success + void* HelperThreadMain(); + static void* HelperThreadMainStatic(void* data) { + FilesystemCopierAction* self = + reinterpret_cast<FilesystemCopierAction*>(data); + return self->HelperThreadMain(); + } + + // Joins the thread and tells the processor that we're done + void CollectThread(); + // GMainLoop callback function: + static gboolean CollectThreadStatic(gpointer data) { + FilesystemCopierAction* self = + reinterpret_cast<FilesystemCopierAction*>(data); + self->CollectThread(); + return FALSE; + } + + pthread_t helper_thread_; + + volatile gint thread_should_exit_; + + static const char* kCompleteFilesystemMarker; + + // Whether or not the destination device is currently mounted. + bool is_mounted_; + + // Where the destination device is mounted. + string dest_path_; + + // The path to copy from. Usually left as the default "/", but tests can + // change it. + string copy_source_; + + // The install plan we're passed in via the input pipe. + InstallPlan install_plan_; + + // Set to true if we detected the copy was unneeded and thus we skipped it. + bool skipped_copy_; + + DISALLOW_COPY_AND_ASSIGN(FilesystemCopierAction); +}; + +} // namespace chromeos_update_engine + +#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__ |