Provide a file-based implementation for the image API. This almost

copies the logic verbatim from mkimg.c to image.c. The difference
is that in image.c the temporary file is always created, whereas
before we only created a temporary file when writing to stdout.

Cleanup mkimg.c now that the song and dance of using a temporary
file is gone.
This commit is contained in:
marcel 2014-05-07 22:06:54 +00:00
parent ec5097c811
commit 8e16ce11e9
5 changed files with 96 additions and 97 deletions

72
image.c
View File

@ -38,6 +38,18 @@ __FBSDID("$FreeBSD$");
#define BUFFER_SIZE (1024*1024)
static char image_tmpfile[] = "/tmp/mkimg-XXXXXX";
static int image_fd = -1;
static void
cleanup(void)
{
if (image_fd != -1)
close(image_fd);
unlink(image_tmpfile);
}
int
image_copyin(lba_t blk, int fd, uint64_t *sizep)
{
@ -76,17 +88,69 @@ image_copyin(lba_t blk, int fd, uint64_t *sizep)
}
int
image_set_size(lba_t blk __unused)
image_copyout(int fd)
{
char *buffer;
off_t ofs;
ssize_t rdsz, wrsz;
int error;
ofs = lseek(fd, 0L, SEEK_CUR);
buffer = malloc(BUFFER_SIZE);
if (buffer == NULL)
return (errno);
if (lseek(image_fd, 0, SEEK_SET) != 0)
return (errno);
error = 0;
while (1) {
rdsz = read(image_fd, buffer, BUFFER_SIZE);
if (rdsz <= 0) {
error = (rdsz < 0) ? errno : 0;
break;
}
wrsz = (ofs == -1) ?
write(fd, buffer, rdsz) :
sparse_write(fd, buffer, rdsz);
if (wrsz < 0) {
error = errno;
break;
}
}
free(buffer);
return (error);
}
int
image_set_size(lba_t blk)
{
/* TODO */
if (ftruncate(image_fd, blk * secsz) == -1)
return (errno);
return (0);
}
int
image_write(lba_t blk __unused, void *buf __unused, ssize_t len __unused)
image_write(lba_t blk, void *buf, ssize_t len)
{
/* TODO */
blk *= secsz;
if (lseek(image_fd, blk, SEEK_SET) != blk)
return (errno);
len *= secsz;
if (write(image_fd, buf, len) != len)
return (errno);
return (0);
}
int
image_init(void)
{
if (atexit(cleanup) == -1)
return (errno);
image_fd = mkstemp(image_tmpfile);
if (image_fd == -1)
return (errno);
return (0);
}

View File

@ -32,6 +32,8 @@
typedef int64_t lba_t;
int image_copyin(lba_t blk, int fd, uint64_t *sizep);
int image_copyout(int fd);
int image_init(void);
int image_set_size(lba_t blk);
int image_write(lba_t blk, void *buf, ssize_t len);

111
mkimg.c
View File

@ -46,12 +46,6 @@ __FBSDID("$FreeBSD$");
#include "mkimg.h"
#include "scheme.h"
#if !defined(SPARSE_WRITE)
#define sparse_write write
#endif
#define BUFFER_SIZE (1024*1024)
struct partlisthead partlist = STAILQ_HEAD_INITIALIZER(partlist);
u_int nparts = 0;
@ -63,21 +57,6 @@ u_int nsecs = 1;
u_int secsz = 512;
u_int blksz = 0;
static int bcfd = -1;
static int outfd = 0;
static int tmpfd = -1;
static char tmpfname[] = "/tmp/mkimg-XXXXXX";
static void
cleanup(void)
{
if (tmpfd != -1)
close(tmpfd);
unlink(tmpfname);
}
static void
usage(const char *why)
{
@ -229,7 +208,7 @@ parse_part(const char *spec)
}
#if defined(SPARSE_WRITE)
static ssize_t
ssize_t
sparse_write(int fd, const char *buf, size_t sz)
{
const char *p;
@ -269,56 +248,8 @@ sparse_write(int fd, const char *buf, size_t sz)
}
#endif /* SPARSE_WRITE */
static int
fdcopy(int src, lba_t sblk, int dst, lba_t dblk, uint64_t *count)
{
char *buffer;
off_t ofs;
ssize_t rdsz, wrsz;
if (sblk != -1) {
ofs = sblk * secsz;
if (lseek(src, ofs, SEEK_SET) != ofs)
return (errno);
}
if (dblk != -1) {
ofs = dblk * secsz;
if (lseek(dst, ofs, SEEK_SET) != ofs)
return (errno);
} else
ofs = lseek(dst, 0L, SEEK_CUR);
/*
* We can't write a sparse file when ofs holds -1 at this point.
*/
if (count != NULL)
*count = 0;
buffer = malloc(BUFFER_SIZE);
if (buffer == NULL)
return (errno);
while (1) {
rdsz = read(src, buffer, BUFFER_SIZE);
if (rdsz <= 0) {
free(buffer);
return ((rdsz < 0) ? errno : 0);
}
if (count != NULL)
*count += rdsz;
wrsz = (ofs == -1) ?
write(dst, buffer, rdsz) :
sparse_write(dst, buffer, rdsz);
if (wrsz < 0)
break;
}
free(buffer);
return (errno);
}
static void
mkimg(int bfd)
mkimg(void)
{
FILE *fp;
struct part *part;
@ -326,10 +257,6 @@ mkimg(int bfd)
off_t bytesize;
int error, fd;
error = scheme_bootcode(bfd);
if (error)
errc(EX_DATAERR, error, "boot code");
/* First check partition information */
STAILQ_FOREACH(part, &partlist, link) {
error = scheme_check_part(part);
@ -386,8 +313,11 @@ mkimg(int bfd)
int
main(int argc, char *argv[])
{
int bcfd, outfd;
int c, error;
bcfd = -1;
outfd = 1; /* Write to stdout by default */
while ((c = getopt(argc, argv, "b:o:p:s:vH:P:S:T:")) != -1) {
switch (c) {
case 'b': /* BOOT CODE */
@ -398,7 +328,7 @@ main(int argc, char *argv[])
err(EX_UNAVAILABLE, "%s", optarg);
break;
case 'o': /* OUTPUT FILE */
if (outfd != 0)
if (outfd != 1)
usage("multiple output files given");
outfd = open(optarg, O_WRONLY | O_CREAT | O_TRUNC,
S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
@ -471,15 +401,12 @@ main(int argc, char *argv[])
errx(EX_DATAERR, "%d partitions supported; %d given",
scheme_max_parts(), nparts);
if (outfd == 0) {
if (atexit(cleanup) == -1)
err(EX_OSERR, "cannot register cleanup function");
outfd = 1;
tmpfd = mkstemp(tmpfname);
if (tmpfd == -1)
err(EX_OSERR, "cannot create temporary file");
} else
tmpfd = outfd;
if (bcfd != -1) {
error = scheme_bootcode(bcfd);
close(bcfd);
if (error)
errc(EX_DATAERR, error, "boot code");
}
if (verbose) {
fprintf(stderr, "Logical sector size: %u\n", secsz);
@ -488,16 +415,18 @@ main(int argc, char *argv[])
fprintf(stderr, "Number of heads: %u\n", nheads);
}
mkimg(bcfd);
error = image_init();
if (error)
errc(EX_OSERR, error, "cannot initialize");
mkimg();
if (verbose)
fprintf(stderr, "Number of cylinders: %u\n", ncyls);
if (tmpfd != outfd) {
error = fdcopy(tmpfd, 0, outfd, -1, NULL);
if (error)
errc(EX_IOERR, error, "writing to stdout");
}
error = image_copyout(outfd);
if (error)
errc(EX_IOERR, error, "writing image");
return (0);
}

View File

@ -65,4 +65,10 @@ round_block(lba_t n)
return ((n + b - 1) & ~(b - 1));
}
#if !defined(SPARSE_WRITE)
#define sparse_write write
#else
ssize_t sparse_write(int, const char *, size_t);
#endif
#endif /* _MKIMG_MKIMG_H_ */

View File

@ -105,8 +105,6 @@ scheme_bootcode(int fd)
struct stat sb;
int error;
if (fd == -1)
return (0);
if (scheme->bootcode == 0)
return (ENXIO);