forked from coreos/update_engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfilesystem_copier_action.h
152 lines (116 loc) · 5.4 KB
/
filesystem_copier_action.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Copyright (c) 2012 The Chromium OS 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 <vector>
#include <gio/gio.h>
#include <glib.h>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
#include "update_engine/action.h"
#include "update_engine/install_plan.h"
#include "update_engine/omaha_hash_calculator.h"
// This action will only do real work if it's a delta update. It will
// copy the root partition to install partition, and then terminate.
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(bool copying_kernel_install_path, bool verify_hash);
typedef ActionTraits<FilesystemCopierAction>::InputObjectType
InputObjectType;
typedef ActionTraits<FilesystemCopierAction>::OutputObjectType
OutputObjectType;
void PerformAction();
void TerminateProcessing();
// Used for testing. Return true if Cleanup() has not yet been called due
// to a callback upon the completion or cancellation of the copier action.
// A test should wait until IsCleanupPending() returns false before
// terminating the glib main loop.
bool IsCleanupPending() const;
// Used for testing, so we can copy from somewhere other than root
void set_copy_source(const std::string& path) { copy_source_ = path; }
// Debugging/logging
static std::string StaticType() { return "FilesystemCopierAction"; }
std::string Type() const { return StaticType(); }
private:
friend class FilesystemCopierActionTest;
FRIEND_TEST(FilesystemCopierActionTest, RunAsRootDetermineFilesystemSizeTest);
// Ping-pong buffers generally cycle through the following states:
// Empty->Reading->Full->Writing->Empty. In hash verification mode the state
// is never set to Writing.
enum BufferState {
kBufferStateEmpty,
kBufferStateReading,
kBufferStateFull,
kBufferStateWriting
};
// Callbacks from glib when the read/write operation is done.
void AsyncReadReadyCallback(GObject *source_object, GAsyncResult *res);
static void StaticAsyncReadReadyCallback(GObject *source_object,
GAsyncResult *res,
gpointer user_data);
void AsyncWriteReadyCallback(GObject *source_object, GAsyncResult *res);
static void StaticAsyncWriteReadyCallback(GObject *source_object,
GAsyncResult *res,
gpointer user_data);
// Based on the state of the ping-pong buffers spawns appropriate read/write
// actions asynchronously.
void SpawnAsyncActions();
// Cleans up all the variables we use for async operations and tells the
// ActionProcessor we're done w/ |code| as passed in. |cancelled_| should be
// true if TerminateProcessing() was called.
void Cleanup(ActionExitCode code);
// Determine, if possible, the source file system size to avoid copying the
// whole partition. Currently this supports only the root file system assuming
// it's ext3-compatible.
void DetermineFilesystemSize(int fd);
// If true, this action is copying to the kernel_install_path from
// the install plan, otherwise it's copying just to the install_path.
const bool copying_kernel_install_path_;
// If true, this action is running in applied update hash verification mode --
// it computes a hash for the target install path and compares it against the
// expected value.
const bool verify_hash_;
// The path to copy from. If empty (the default), the source is from the
// passed in InstallPlan.
std::string copy_source_;
// If non-NULL, these are GUnixInputStream objects for the opened
// source/destination partitions.
GInputStream* src_stream_;
GOutputStream* dst_stream_;
// Ping-pong buffers for storing data we read/write. Only one buffer is being
// read at a time and only one buffer is being written at a time.
std::vector<char> buffer_[2];
// The state of each buffer.
BufferState buffer_state_[2];
// Number of valid elements in |buffer_| if its state is kBufferStateFull.
std::vector<char>::size_type buffer_valid_size_[2];
// The cancellable objects for the in-flight async calls.
GCancellable* canceller_[2];
bool read_done_; // true if reached EOF on the input stream.
bool failed_; // true if the action has failed.
bool cancelled_; // true if the action has been cancelled.
// The install plan we're passed in via the input pipe.
InstallPlan install_plan_;
// Calculates the hash of the copied data.
OmahaHashCalculator hasher_;
// Copies and hashes this many bytes from the head of the input stream. This
// field is initialized when the action is started and decremented as more
// bytes get copied.
int64_t filesystem_size_;
DISALLOW_COPY_AND_ASSIGN(FilesystemCopierAction);
};
} // namespace chromeos_update_engine
#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__