OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__ | 5 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__ |
6 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__ | 6 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__ |
7 | 7 |
8 #include <sys/stat.h> | 8 #include <sys/stat.h> |
9 #include <sys/types.h> | 9 #include <sys/types.h> |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 class ActionTraits<FilesystemCopierAction> { | 30 class ActionTraits<FilesystemCopierAction> { |
31 public: | 31 public: |
32 // Takes the install plan as input | 32 // Takes the install plan as input |
33 typedef InstallPlan InputObjectType; | 33 typedef InstallPlan InputObjectType; |
34 // Passes the install plan as output | 34 // Passes the install plan as output |
35 typedef InstallPlan OutputObjectType; | 35 typedef InstallPlan OutputObjectType; |
36 }; | 36 }; |
37 | 37 |
38 class FilesystemCopierAction : public Action<FilesystemCopierAction> { | 38 class FilesystemCopierAction : public Action<FilesystemCopierAction> { |
39 public: | 39 public: |
40 explicit FilesystemCopierAction(bool copying_kernel_install_path) | 40 explicit FilesystemCopierAction(bool copying_kernel_install_path); |
41 : copying_kernel_install_path_(copying_kernel_install_path), | 41 |
42 src_stream_(NULL), | |
43 dst_stream_(NULL), | |
44 canceller_(NULL), | |
45 read_in_flight_(false), | |
46 buffer_valid_size_(0), | |
47 filesystem_size_(kint64max) {} | |
48 typedef ActionTraits<FilesystemCopierAction>::InputObjectType | 42 typedef ActionTraits<FilesystemCopierAction>::InputObjectType |
49 InputObjectType; | 43 InputObjectType; |
50 typedef ActionTraits<FilesystemCopierAction>::OutputObjectType | 44 typedef ActionTraits<FilesystemCopierAction>::OutputObjectType |
51 OutputObjectType; | 45 OutputObjectType; |
52 void PerformAction(); | 46 void PerformAction(); |
53 void TerminateProcessing(); | 47 void TerminateProcessing(); |
54 | 48 |
55 // Used for testing, so we can copy from somewhere other than root | 49 // Used for testing, so we can copy from somewhere other than root |
56 void set_copy_source(const std::string& path) { | 50 void set_copy_source(const std::string& path) { copy_source_ = path; } |
57 copy_source_ = path; | |
58 } | |
59 | 51 |
60 // Debugging/logging | 52 // Debugging/logging |
61 static std::string StaticType() { return "FilesystemCopierAction"; } | 53 static std::string StaticType() { return "FilesystemCopierAction"; } |
62 std::string Type() const { return StaticType(); } | 54 std::string Type() const { return StaticType(); } |
63 | 55 |
64 private: | 56 private: |
65 friend class FilesystemCopierActionTest; | 57 friend class FilesystemCopierActionTest; |
66 FRIEND_TEST(FilesystemCopierActionTest, RunAsRootDetermineFilesystemSizeTest); | 58 FRIEND_TEST(FilesystemCopierActionTest, RunAsRootDetermineFilesystemSizeTest); |
67 | 59 |
68 // Callback from glib when the copy operation is done. | 60 // Ping-pong buffers generally cycle through the following states: |
69 void AsyncReadyCallback(GObject *source_object, GAsyncResult *res); | 61 // Empty->Reading->Full->Writing->Empty. |
70 static void StaticAsyncReadyCallback(GObject *source_object, | 62 enum BufferState { |
71 GAsyncResult *res, | 63 kBufferStateEmpty, |
72 gpointer user_data) { | 64 kBufferStateReading, |
73 reinterpret_cast<FilesystemCopierAction*>(user_data)->AsyncReadyCallback( | 65 kBufferStateFull, |
74 source_object, res); | 66 kBufferStateWriting |
75 } | 67 }; |
76 | 68 |
77 // Cleans up all the variables we use for async operations and tells | 69 // Callbacks from glib when the read/write operation is done. |
78 // the ActionProcessor we're done w/ success as passed in. | 70 void AsyncReadReadyCallback(GObject *source_object, GAsyncResult *res); |
79 // was_cancelled should be true if TerminateProcessing() was called. | 71 static void StaticAsyncReadReadyCallback(GObject *source_object, |
80 void Cleanup(bool success, bool was_cancelled); | 72 GAsyncResult *res, |
| 73 gpointer user_data); |
| 74 |
| 75 void AsyncWriteReadyCallback(GObject *source_object, GAsyncResult *res); |
| 76 static void StaticAsyncWriteReadyCallback(GObject *source_object, |
| 77 GAsyncResult *res, |
| 78 gpointer user_data); |
| 79 |
| 80 // Based on the state of the ping-pong buffers spawns appropriate read/write |
| 81 // actions asynchronously. |
| 82 void SpawnAsyncActions(); |
| 83 |
| 84 // Cleans up all the variables we use for async operations and tells the |
| 85 // ActionProcessor we're done w/ success as passed in. |cancelled_| should be |
| 86 // true if TerminateProcessing() was called. |
| 87 void Cleanup(bool success); |
81 | 88 |
82 // Determine, if possible, the source file system size to avoid copying the | 89 // Determine, if possible, the source file system size to avoid copying the |
83 // whole partition. Currently this supports only the root file system assuming | 90 // whole partition. Currently this supports only the root file system assuming |
84 // it's ext3-compatible. | 91 // it's ext3-compatible. |
85 void DetermineFilesystemSize(int fd); | 92 void DetermineFilesystemSize(int fd); |
86 | 93 |
87 // Returns the number of bytes to read based on the size of the buffer and the | 94 // Returns the number of bytes to read based on the size of the buffer and the |
88 // filesystem size. | 95 // filesystem size. |
89 int64_t GetBytesToRead(); | 96 int64_t GetBytesToRead(); |
90 | 97 |
91 // If true, this action is copying to the kernel_install_path from | 98 // If true, this action is copying to the kernel_install_path from |
92 // the install plan, otherwise it's copying just to the install_path. | 99 // the install plan, otherwise it's copying just to the install_path. |
93 const bool copying_kernel_install_path_; | 100 const bool copying_kernel_install_path_; |
94 | 101 |
95 // The path to copy from. If empty (the default), the source is from the | 102 // The path to copy from. If empty (the default), the source is from the |
96 // passed in InstallPlan. | 103 // passed in InstallPlan. |
97 std::string copy_source_; | 104 std::string copy_source_; |
98 | 105 |
99 // If non-NULL, these are GUnixInputStream objects for the opened | 106 // If non-NULL, these are GUnixInputStream objects for the opened |
100 // source/destination partitions. | 107 // source/destination partitions. |
101 GInputStream* src_stream_; | 108 GInputStream* src_stream_; |
102 GOutputStream* dst_stream_; | 109 GOutputStream* dst_stream_; |
103 | 110 |
104 // If non-NULL, the cancellable object for the in-flight async call. | 111 // Ping-pong buffers for storing data we read/write. Only one buffer is being |
105 GCancellable* canceller_; | 112 // read at a time and only one buffer is being written at a time. |
| 113 std::vector<char> buffer_[2]; |
106 | 114 |
107 // True if we're waiting on a read to complete; false if we're | 115 // The state of each buffer. |
108 // waiting on a write. | 116 BufferState buffer_state_[2]; |
109 bool read_in_flight_; | |
110 | 117 |
111 // The buffer for storing data we read/write. | 118 // Number of valid elements in |buffer_| if its state is kBufferStateFull. |
112 std::vector<char> buffer_; | 119 std::vector<char>::size_type buffer_valid_size_[2]; |
113 | 120 |
114 // Number of valid elements in buffer_. | 121 // The cancellable objects for the in-flight async calls. |
115 std::vector<char>::size_type buffer_valid_size_; | 122 GCancellable* canceller_[2]; |
| 123 |
| 124 bool read_done_; // true if reached EOF on the input stream. |
| 125 bool failed_; // true if the action has failed. |
| 126 bool cancelled_; // true if the action has been cancelled. |
116 | 127 |
117 // The install plan we're passed in via the input pipe. | 128 // The install plan we're passed in via the input pipe. |
118 InstallPlan install_plan_; | 129 InstallPlan install_plan_; |
119 | 130 |
120 // Calculates the hash of the copied data. | 131 // Calculates the hash of the copied data. |
121 OmahaHashCalculator hasher_; | 132 OmahaHashCalculator hasher_; |
122 | 133 |
123 // Copies and hashes this many bytes from the head of the input stream. This | 134 // Copies and hashes this many bytes from the head of the input stream. This |
124 // field is initialized when the action is started and decremented as more | 135 // field is initialized when the action is started and decremented as more |
125 // bytes get copied. | 136 // bytes get copied. |
126 int64_t filesystem_size_; | 137 int64_t filesystem_size_; |
127 | 138 |
128 DISALLOW_COPY_AND_ASSIGN(FilesystemCopierAction); | 139 DISALLOW_COPY_AND_ASSIGN(FilesystemCopierAction); |
129 }; | 140 }; |
130 | 141 |
131 } // namespace chromeos_update_engine | 142 } // namespace chromeos_update_engine |
132 | 143 |
133 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__ | 144 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__ |
OLD | NEW |