iPXE
downloader.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdlib.h>
28#include <string.h>
29#include <errno.h>
30#include <syslog.h>
31#include <ipxe/iobuf.h>
32#include <ipxe/xfer.h>
33#include <ipxe/open.h>
34#include <ipxe/job.h>
35#include <ipxe/umalloc.h>
36#include <ipxe/image.h>
37#include <ipxe/xferbuf.h>
38#include <ipxe/downloader.h>
39
40/** @file
41 *
42 * Image downloader
43 *
44 */
45
46/** A downloader */
47struct downloader {
48 /** Reference count for this object */
49 struct refcnt refcnt;
50
51 /** Job control interface */
52 struct interface job;
53 /** Data transfer interface */
55
56 /** Image to contain downloaded file */
57 struct image *image;
58 /** Data transfer buffer */
60};
61
62/**
63 * Free downloader object
64 *
65 * @v refcnt Downloader reference counter
66 */
67static void downloader_free ( struct refcnt *refcnt ) {
68 struct downloader *downloader =
70
73 free ( downloader );
74}
75
76/**
77 * Terminate download
78 *
79 * @v downloader Downloader
80 * @v rc Reason for termination
81 */
82static void downloader_finished ( struct downloader *downloader, int rc ) {
84 struct image *image = downloader->image;
85
86 /* Log download status */
87 if ( rc == 0 ) {
88 syslog ( LOG_NOTICE, "Downloaded \"%s\"\n", image->name );
89 } else {
90 syslog ( LOG_ERR, "Download of \"%s\" failed: %s\n",
91 image->name, strerror ( rc ) );
92 }
93
94 /* Transfer ownership from data transfer buffer to image */
95 image->data = buffer->data;
96 image->len = buffer->len;
98
99 /* Shut down interfaces */
102}
103
104/****************************************************************************
105 *
106 * Job control interface
107 *
108 */
109
110/**
111 * Report progress of download job
112 *
113 * @v downloader Downloader
114 * @v progress Progress report to fill in
115 * @ret ongoing_rc Ongoing job status code (if known)
116 */
118 struct job_progress *progress ) {
119 int rc;
120
121 /* Allow data transfer to provide an accurate description */
122 if ( ( rc = job_progress ( &downloader->xfer, progress ) ) != 0 )
123 return rc;
124
125 /* This is not entirely accurate, since downloaded data may
126 * arrive out of order (e.g. with multicast protocols), but
127 * it's a reasonable first approximation.
128 */
129 if ( ! progress->total ) {
130 progress->completed = downloader->buffer.pos;
131 progress->total = downloader->buffer.len;
132 }
133
134 return 0;
135}
136
137/****************************************************************************
138 *
139 * Data transfer interface
140 *
141 */
142
143/**
144 * Handle received data
145 *
146 * @v downloader Downloader
147 * @v iobuf Datagram I/O buffer
148 * @v meta Data transfer metadata
149 * @ret rc Return status code
150 */
152 struct io_buffer *iobuf,
153 struct xfer_metadata *meta ) {
154 int rc;
155
156 /* Add data to buffer */
157 if ( ( rc = xferbuf_deliver ( &downloader->buffer, iob_disown ( iobuf ),
158 meta ) ) != 0 )
159 goto err_deliver;
160
161 return 0;
162
163 err_deliver:
165 return rc;
166}
167
168/**
169 * Get underlying data transfer buffer
170 *
171 * @v downloader Downloader
172 * @ret xferbuf Data transfer buffer, or NULL on error
173 */
174static struct xfer_buffer *
176
177 /* Provide direct access to underlying data transfer buffer */
178 return &downloader->buffer;
179}
180
181/**
182 * Redirect data transfer interface
183 *
184 * @v downloader Downloader
185 * @v type New location type
186 * @v args Remaining arguments depend upon location type
187 * @ret rc Return status code
188 */
190 va_list args ) {
191 va_list tmp;
192 struct uri *uri;
193 int rc;
194
195 /* Intercept redirects to a LOCATION_URI and update the image URI */
196 if ( type == LOCATION_URI ) {
197
198 /* Extract URI argument */
199 va_copy ( tmp, args );
200 uri = va_arg ( tmp, struct uri * );
201 va_end ( tmp );
202
203 /* Set image URI */
204 if ( ( rc = image_set_uri ( downloader->image, uri ) ) != 0 )
205 goto err;
206 }
207
208 /* Redirect to new location */
209 if ( ( rc = xfer_vreopen ( &downloader->xfer, type, args ) ) != 0 )
210 goto err;
211
212 return 0;
213
214 err:
216 return rc;
217}
218
219/** Downloader data transfer interface operations */
226
227/** Downloader data transfer interface descriptor */
230
231/****************************************************************************
232 *
233 * Job control interface
234 *
235 */
236
237/** Downloader job control interface operations */
242
243/** Downloader job control interface descriptor */
245 INTF_DESC ( struct downloader, job, downloader_job_op );
246
247/****************************************************************************
248 *
249 * Instantiator
250 *
251 */
252
253/**
254 * Instantiate a downloader
255 *
256 * @v job Job control interface
257 * @v image Image to fill with downloaded file
258 * @ret rc Return status code
259 *
260 * Instantiates a downloader object to download the content of the
261 * specified image from its URI.
262 */
263int create_downloader ( struct interface *job, struct image *image ) {
264 struct downloader *downloader;
265 int rc;
266
267 /* Allocate and initialise structure */
268 downloader = zalloc ( sizeof ( *downloader ) );
269 if ( ! downloader )
270 return -ENOMEM;
273 &downloader->refcnt );
275 &downloader->refcnt );
278
279 /* Instantiate child objects and attach to our interfaces */
280 if ( ( rc = xfer_open_uri ( &downloader->xfer, image->uri ) ) != 0 )
281 goto err;
282
283 /* Attach parent interface, mortalise self, and return */
286 return 0;
287
288 err:
291 return rc;
292}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
static struct interface_descriptor downloader_job_desc
Downloader job control interface descriptor.
Definition downloader.c:244
static void downloader_free(struct refcnt *refcnt)
Free downloader object.
Definition downloader.c:67
static struct xfer_buffer * downloader_buffer(struct downloader *downloader)
Get underlying data transfer buffer.
Definition downloader.c:175
static int downloader_deliver(struct downloader *downloader, struct io_buffer *iobuf, struct xfer_metadata *meta)
Handle received data.
Definition downloader.c:151
static struct interface_descriptor downloader_xfer_desc
Downloader data transfer interface descriptor.
Definition downloader.c:228
static int downloader_vredirect(struct downloader *downloader, int type, va_list args)
Redirect data transfer interface.
Definition downloader.c:189
static int downloader_progress(struct downloader *downloader, struct job_progress *progress)
Report progress of download job.
Definition downloader.c:117
static struct interface_operation downloader_xfer_operations[]
Downloader data transfer interface operations.
Definition downloader.c:220
int create_downloader(struct interface *job, struct image *image)
Instantiate a downloader.
Definition downloader.c:263
static struct interface_operation downloader_job_op[]
Downloader job control interface operations.
Definition downloader.c:238
static void downloader_finished(struct downloader *downloader, int rc)
Terminate download.
Definition downloader.c:82
Image downloader.
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t meta
Metadata flags.
Definition ena.h:3
Error codes.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOMEM
Not enough space.
Definition errno.h:535
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define LOG_ERR
Error: error conditions.
Definition syslog.h:36
#define LOG_NOTICE
Notice: normal but significant conditions.
Definition syslog.h:42
int image_set_uri(struct image *image, struct uri *uri)
Set image URI.
Definition image.c:153
Executable images.
static struct image * image_get(struct image *image)
Increment reference count on an image.
Definition image.h:240
static void image_put(struct image *image)
Decrement reference count on an image.
Definition image.h:250
User memory allocation.
String functions.
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
I/O buffers.
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
Job control interfaces.
unsigned long tmp
Definition linux_pci.h:65
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
Definition open.c:225
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition open.c:68
Data transfer interface opening.
@ LOCATION_URI
Location is a URI.
Definition open.h:28
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
#define va_copy(dest, src)
Definition stdarg.h:11
#define va_arg(ap, type)
Definition stdarg.h:9
#define va_end(ap)
Definition stdarg.h:10
__builtin_va_list va_list
Definition stdarg.h:7
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A downloader.
Definition downloader.c:47
struct interface xfer
Data transfer interface.
Definition downloader.c:54
struct image * image
Image to contain downloaded file.
Definition downloader.c:57
struct xfer_buffer buffer
Data transfer buffer.
Definition downloader.c:59
struct refcnt refcnt
Reference count for this object.
Definition downloader.c:49
struct interface job
Job control interface.
Definition downloader.c:52
An executable image.
Definition image.h:24
const void * data
Read-only data.
Definition image.h:51
char * name
Name.
Definition image.h:38
size_t len
Length of raw file image.
Definition image.h:56
struct uri * uri
URI of image.
Definition image.h:32
An object interface descriptor.
Definition interface.h:56
An object interface operation.
Definition interface.h:18
An object interface.
Definition interface.h:125
A persistent I/O buffer.
Definition iobuf.h:38
Job progress.
Definition job.h:16
unsigned long total
Total operation size.
Definition job.h:31
unsigned long completed
Amount of operation completed so far.
Definition job.h:24
A reference counter.
Definition refcnt.h:27
A Uniform Resource Identifier.
Definition uri.h:65
A data transfer buffer.
Definition xferbuf.h:19
size_t len
Size of data.
Definition xferbuf.h:23
size_t pos
Current offset within data.
Definition xferbuf.h:25
Data transfer metadata.
Definition xfer.h:23
System logger.
#define syslog(priority, fmt,...)
Write message to system log.
Definition syslog.h:94
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
int xfer_vredirect(struct interface *intf, int type, va_list args)
Send redirection event.
Definition xfer.c:63
Data transfer interfaces.
void xferbuf_free(struct xfer_buffer *xferbuf)
Free data transfer buffer.
Definition xferbuf.c:74
void xferbuf_detach(struct xfer_buffer *xferbuf)
Detach data from data transfer buffer.
Definition xferbuf.c:62
int xferbuf_deliver(struct xfer_buffer *xferbuf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Add received data to data transfer buffer.
Definition xferbuf.c:175
Data transfer buffer.
static void xferbuf_umalloc_init(struct xfer_buffer *xferbuf)
Initialise umalloc()-based data transfer buffer.
Definition xferbuf.h:67