blob: 6dbde413f46346ad9572d7f697d121ab8708244c [file] [log] [blame]
Darin Petkov698d0412010-10-13 10:59:44 -07001// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
adlr@google.com3defe6a2009-12-04 20:57:17 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__
6#define CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__
7
8#include <sys/stat.h>
9#include <sys/types.h>
Darin Petkov698d0412010-10-13 10:59:44 -070010
adlr@google.com3defe6a2009-12-04 20:57:17 +000011#include <string>
Andrew de los Reyesc7020782010-04-28 10:46:04 -070012#include <vector>
Darin Petkov698d0412010-10-13 10:59:44 -070013
Andrew de los Reyesc7020782010-04-28 10:46:04 -070014#include <gio/gio.h>
adlr@google.com3defe6a2009-12-04 20:57:17 +000015#include <glib.h>
Darin Petkov698d0412010-10-13 10:59:44 -070016#include <gtest/gtest_prod.h> // for FRIEND_TEST
17
adlr@google.com3defe6a2009-12-04 20:57:17 +000018#include "update_engine/action.h"
19#include "update_engine/install_plan.h"
Darin Petkov698d0412010-10-13 10:59:44 -070020#include "update_engine/omaha_hash_calculator.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000021
22// This action will only do real work if it's a delta update. It will
Andrew de los Reyesc7020782010-04-28 10:46:04 -070023// copy the root partition to install partition, and then terminate.
adlr@google.com3defe6a2009-12-04 20:57:17 +000024
25namespace chromeos_update_engine {
26
27class FilesystemCopierAction;
28
29template<>
30class ActionTraits<FilesystemCopierAction> {
31 public:
32 // Takes the install plan as input
33 typedef InstallPlan InputObjectType;
34 // Passes the install plan as output
35 typedef InstallPlan OutputObjectType;
36};
37
38class FilesystemCopierAction : public Action<FilesystemCopierAction> {
39 public:
Darin Petkovc2e4a7d2010-12-02 14:47:06 -080040 explicit FilesystemCopierAction(bool copying_kernel_install_path);
41
adlr@google.com3defe6a2009-12-04 20:57:17 +000042 typedef ActionTraits<FilesystemCopierAction>::InputObjectType
43 InputObjectType;
44 typedef ActionTraits<FilesystemCopierAction>::OutputObjectType
45 OutputObjectType;
46 void PerformAction();
47 void TerminateProcessing();
48
49 // Used for testing, so we can copy from somewhere other than root
Darin Petkovc2e4a7d2010-12-02 14:47:06 -080050 void set_copy_source(const std::string& path) { copy_source_ = path; }
adlr@google.com3defe6a2009-12-04 20:57:17 +000051
52 // Debugging/logging
53 static std::string StaticType() { return "FilesystemCopierAction"; }
54 std::string Type() const { return StaticType(); }
55
56 private:
Darin Petkov698d0412010-10-13 10:59:44 -070057 friend class FilesystemCopierActionTest;
58 FRIEND_TEST(FilesystemCopierActionTest, RunAsRootDetermineFilesystemSizeTest);
59
Darin Petkovc2e4a7d2010-12-02 14:47:06 -080060 // Ping-pong buffers generally cycle through the following states:
61 // Empty->Reading->Full->Writing->Empty.
62 enum BufferState {
63 kBufferStateEmpty,
64 kBufferStateReading,
65 kBufferStateFull,
66 kBufferStateWriting
67 };
Darin Petkov698d0412010-10-13 10:59:44 -070068
Darin Petkovc2e4a7d2010-12-02 14:47:06 -080069 // Callbacks from glib when the read/write operation is done.
70 void AsyncReadReadyCallback(GObject *source_object, GAsyncResult *res);
71 static void StaticAsyncReadReadyCallback(GObject *source_object,
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);
Darin Petkov698d0412010-10-13 10:59:44 -070088
89 // Determine, if possible, the source file system size to avoid copying the
90 // whole partition. Currently this supports only the root file system assuming
91 // it's ext3-compatible.
92 void DetermineFilesystemSize(int fd);
93
94 // Returns the number of bytes to read based on the size of the buffer and the
95 // filesystem size.
96 int64_t GetBytesToRead();
97
Andrew de los Reyesf9185172010-05-03 11:07:05 -070098 // If true, this action is copying to the kernel_install_path from
99 // the install plan, otherwise it's copying just to the install_path.
100 const bool copying_kernel_install_path_;
Darin Petkov698d0412010-10-13 10:59:44 -0700101
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700102 // The path to copy from. If empty (the default), the source is from the
103 // passed in InstallPlan.
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -0800104 std::string copy_source_;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000105
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700106 // If non-NULL, these are GUnixInputStream objects for the opened
107 // source/destination partitions.
108 GInputStream* src_stream_;
109 GOutputStream* dst_stream_;
Darin Petkov698d0412010-10-13 10:59:44 -0700110
Darin Petkovc2e4a7d2010-12-02 14:47:06 -0800111 // Ping-pong buffers for storing data we read/write. Only one buffer is being
112 // read at a time and only one buffer is being written at a time.
113 std::vector<char> buffer_[2];
Darin Petkov698d0412010-10-13 10:59:44 -0700114
Darin Petkovc2e4a7d2010-12-02 14:47:06 -0800115 // The state of each buffer.
116 BufferState buffer_state_[2];
Darin Petkov698d0412010-10-13 10:59:44 -0700117
Darin Petkovc2e4a7d2010-12-02 14:47:06 -0800118 // Number of valid elements in |buffer_| if its state is kBufferStateFull.
119 std::vector<char>::size_type buffer_valid_size_[2];
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700120
Darin Petkovc2e4a7d2010-12-02 14:47:06 -0800121 // The cancellable objects for the in-flight async calls.
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.
Andrew de los Reyesc7020782010-04-28 10:46:04 -0700127
adlr@google.com3defe6a2009-12-04 20:57:17 +0000128 // The install plan we're passed in via the input pipe.
129 InstallPlan install_plan_;
Darin Petkov698d0412010-10-13 10:59:44 -0700130
131 // Calculates the hash of the copied data.
132 OmahaHashCalculator hasher_;
133
134 // Copies and hashes this many bytes from the head of the input stream. This
135 // field is initialized when the action is started and decremented as more
136 // bytes get copied.
137 int64_t filesystem_size_;
138
adlr@google.com3defe6a2009-12-04 20:57:17 +0000139 DISALLOW_COPY_AND_ASSIGN(FilesystemCopierAction);
140};
141
142} // namespace chromeos_update_engine
143
144#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__