Date: Mon, 20 Feb 2012 22:19:27 +0100 From: Martin Matuska <mm@FreeBSD.org> To: Jung-uk Kim <jkim@FreeBSD.org> Cc: src-committers@freebsd.org, Eitan Adler <eadler@FreeBSD.org>, svn-src-all@freebsd.org, Hiroki Sato <hrs@FreeBSD.org>, Ed Schouten <ed@FreeBSD.org>, Nathan Whitehorn <nwhitehorn@FreeBSD.org>, svn-src-head@freebsd.org Subject: Re: svn commit: r230795 - in head/usr.sbin/makefs: . cd9660 Message-ID: <4F42B8DF.7040400@FreeBSD.org> In-Reply-To: <201201310032.q0V0Wb4i009706@svn.freebsd.org> References: <201201310032.q0V0Wb4i009706@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Thanks for the patch, I see it has been adopted by NetBSD. I have seen there has been recently activity in makefs. IMO makefs should be moved to vendor/contrib (originates fron NetBSD) the same way libarchive was moved. Or are we doing the main (or our very own) development of makefs? If we are, it wouldn't be bad to give a statement to clarify this. Dňa 31. 1. 2012 1:32, Jung-uk Kim wrote / napísal(a): > Author: jkim > Date: Tue Jan 31 00:32:37 2012 > New Revision: 230795 > URL: http://svn.freebsd.org/changeset/base/230795 > > Log: > Allow contents of multiple directories to be merged to the current image. > Note this patch was submitted to NetBSD and they already adopted it. > > http://mail-index.netbsd.org/source-changes/2012/01/28/msg031078.html > > MFC after: 1 week > > Modified: > head/usr.sbin/makefs/cd9660.c > head/usr.sbin/makefs/cd9660.h > head/usr.sbin/makefs/cd9660/cd9660_write.c > head/usr.sbin/makefs/ffs.c > head/usr.sbin/makefs/makefs.8 > head/usr.sbin/makefs/makefs.c > head/usr.sbin/makefs/makefs.h > head/usr.sbin/makefs/walk.c > > Modified: head/usr.sbin/makefs/cd9660.c > ============================================================================== > --- head/usr.sbin/makefs/cd9660.c Tue Jan 31 00:12:51 2012 (r230794) > +++ head/usr.sbin/makefs/cd9660.c Tue Jan 31 00:32:37 2012 (r230795) > @@ -472,8 +472,6 @@ cd9660_makefs(const char *image, const c > return; > } > > - diskStructure.rootFilesystemPath = dir; > - > if (diskStructure.verbose_level > 0) > printf("cd9660_makefs: image %s directory %s root %p\n", > image, dir, root); > @@ -1568,24 +1566,15 @@ cd9660_generate_path_table(void) > } > > void > -cd9660_compute_full_filename(cd9660node *node, char *buf, int level) > +cd9660_compute_full_filename(cd9660node *node, char *buf) > { > - cd9660node *parent; > - > - parent = (node->rr_real_parent == NULL ? > - node->parent : node->rr_real_parent); > - if (parent != NULL) { > - cd9660_compute_full_filename(parent, buf, level + 1); > - strcat(buf, node->node->name); > - } else { > - /* We are at the root */ > - strcat(buf, diskStructure.rootFilesystemPath); > - if (buf[strlen(buf) - 1] == '/') > - buf[strlen(buf) - 1] = '\0'; > - } > + int len; > > - if (level != 0) > - strcat(buf, "/"); > + len = CD9660MAXPATH + 1; > + len = snprintf(buf, len, "%s/%s/%s", node->node->root, > + node->node->path, node->node->name); > + if (len > CD9660MAXPATH) > + errx(1, "Pathname too long."); > } > > /* NEW filename conversion method */ > > Modified: head/usr.sbin/makefs/cd9660.h > ============================================================================== > --- head/usr.sbin/makefs/cd9660.h Tue Jan 31 00:12:51 2012 (r230794) > +++ head/usr.sbin/makefs/cd9660.h Tue Jan 31 00:32:37 2012 (r230795) > @@ -244,8 +244,6 @@ typedef struct _iso9660_disk { > > cd9660node *rootNode; > > - const char *rootFilesystemPath; > - > /* Important sector numbers here */ > /* primaryDescriptor.type_l_path_table*/ > int64_t primaryBigEndianTableSector; > @@ -345,7 +343,7 @@ int cd9660_setup_boot_volume_descriptor( > int cd9660_write_image(const char *image); > int cd9660_copy_file(FILE *, off_t, const char *); > > -void cd9660_compute_full_filename(cd9660node *, char *, int); > +void cd9660_compute_full_filename(cd9660node *, char *); > int cd9660_compute_record_size(cd9660node *); > > /* Debugging functions */ > > Modified: head/usr.sbin/makefs/cd9660/cd9660_write.c > ============================================================================== > --- head/usr.sbin/makefs/cd9660/cd9660_write.c Tue Jan 31 00:12:51 2012 (r230794) > +++ head/usr.sbin/makefs/cd9660/cd9660_write.c Tue Jan 31 00:32:37 2012 (r230795) > @@ -296,7 +296,7 @@ cd9660_write_file(FILE *fd, cd9660node * > inode->flags |= FI_WRITTEN; > if (writenode->node->contents == NULL) > cd9660_compute_full_filename(writenode, > - temp_file_name, 0); > + temp_file_name); > ret = cd9660_copy_file(fd, writenode->fileDataSector, > (writenode->node->contents != NULL) ? > writenode->node->contents : temp_file_name); > > Modified: head/usr.sbin/makefs/ffs.c > ============================================================================== > --- head/usr.sbin/makefs/ffs.c Tue Jan 31 00:12:51 2012 (r230794) > +++ head/usr.sbin/makefs/ffs.c Tue Jan 31 00:32:37 2012 (r230795) > @@ -780,8 +780,8 @@ ffs_populate_dir(const char *dir, fsnode > cur->inode->flags |= FI_WRITTEN; > > if (cur->contents == NULL) { > - if (snprintf(path, sizeof(path), "%s/%s", dir, > - cur->name) >= sizeof(path)) > + if (snprintf(path, sizeof(path), "%s/%s/%s", cur->root, > + cur->path, cur->name) >= (int)sizeof(path)) > errx(1, "Pathname too long."); > } > > > Modified: head/usr.sbin/makefs/makefs.8 > ============================================================================== > --- head/usr.sbin/makefs/makefs.8 Tue Jan 31 00:12:51 2012 (r230794) > +++ head/usr.sbin/makefs/makefs.8 Tue Jan 31 00:32:37 2012 (r230795) > @@ -35,7 +35,7 @@ > .\" > .\" $FreeBSD$ > .\" > -.Dd January 10, 2009 > +.Dd January 30, 2012 > .Dt MAKEFS 8 > .Os > .Sh NAME > @@ -58,6 +58,7 @@ > .Op Fl t Ar fs-type > .Ar image-file > .Ar directory | manifest > +.Op Ar extra-directory ... > .Sh DESCRIPTION > The utility > .Nm > @@ -67,6 +68,15 @@ from the directory tree > .Ar directory > or from the mtree manifest > .Ar manifest . > +If optional directory tree > +.Ar extra-directory > +is passed, then the directory tree of each argument will be merged > +into the > +.Ar directory > +or > +.Ar manifest > +first before creating > +.Ar image-file . > No special devices or privileges are required to perform this task. > .Pp > The options are as follows: > > Modified: head/usr.sbin/makefs/makefs.c > ============================================================================== > --- head/usr.sbin/makefs/makefs.c Tue Jan 31 00:12:51 2012 (r230794) > +++ head/usr.sbin/makefs/makefs.c Tue Jan 31 00:32:37 2012 (r230795) > @@ -87,7 +87,7 @@ main(int argc, char *argv[]) > fstype_t *fstype; > fsinfo_t fsoptions; > fsnode *root; > - int ch, len; > + int ch, i, len; > char *subtree; > char *specfile; > > @@ -241,7 +241,7 @@ main(int argc, char *argv[]) > argc -= optind; > argv += optind; > > - if (argc != 2) > + if (argc < 2) > usage(); > > /* -x must be accompanied by -F */ > @@ -260,7 +260,7 @@ main(int argc, char *argv[]) > case S_IFDIR: /* walk the tree */ > subtree = argv[1]; > TIMER_START(start); > - root = walk_dir(subtree, NULL); > + root = walk_dir(subtree, ".", NULL, NULL); > TIMER_RESULTS(start, "walk_dir"); > break; > case S_IFREG: /* read the manifest file */ > @@ -274,6 +274,17 @@ main(int argc, char *argv[]) > /* NOTREACHED */ > } > > + /* append extra directory */ > + for (i = 2; i < argc; i++) { > + if (stat(argv[i], &sb) == -1) > + err(1, "Can't stat `%s'", argv[i]); > + if (!S_ISDIR(sb.st_mode)) > + errx(1, "%s: not a directory", argv[i]); > + TIMER_START(start); > + root = walk_dir(argv[i], ".", NULL, root); > + TIMER_RESULTS(start, "walk_dir2"); > + } > + > if (specfile) { /* apply a specfile */ > TIMER_START(start); > apply_specfile(specfile, subtree, root, fsoptions.onlyspec); > @@ -282,7 +293,7 @@ main(int argc, char *argv[]) > > if (debug & DEBUG_DUMP_FSNODES) { > printf("\nparent: %s\n", subtree); > - dump_fsnodes(".", root); > + dump_fsnodes(root); > putchar('\n'); > } > > @@ -336,7 +347,7 @@ usage(void) > "usage: %s [-t fs-type] [-o fs-options] [-d debug-mask] [-B endian]\n" > "\t[-S sector-size] [-M minimum-size] [-m maximum-size] [-s image-size]\n" > "\t[-b free-blocks] [-f free-files] [-F mtree-specfile] [-x]\n" > -"\t[-N userdb-dir] image-file directory | manifest\n", > +"\t[-N userdb-dir] image-file directory | manifest [extra-directory ...]\n", > prog); > exit(1); > } > > Modified: head/usr.sbin/makefs/makefs.h > ============================================================================== > --- head/usr.sbin/makefs/makefs.h Tue Jan 31 00:12:51 2012 (r230794) > +++ head/usr.sbin/makefs/makefs.h Tue Jan 31 00:32:37 2012 (r230795) > @@ -94,6 +94,8 @@ typedef struct _fsnode { > fsinode *inode; /* actual inode data */ > char *symlink; /* symlink target */ > char *contents; /* file to provide contents */ > + const char *root; /* root path */ > + char *path; /* directory name */ > char *name; /* file name */ > int flags; /* misc flags */ > } fsnode; > @@ -147,11 +149,11 @@ typedef struct { > > > void apply_specfile(const char *, const char *, fsnode *, int); > -void dump_fsnodes(const char *, fsnode *); > +void dump_fsnodes(fsnode *); > const char * inode_type(mode_t); > fsnode * read_mtree(const char *, fsnode *); > int set_option(option_t *, const char *, const char *); > -fsnode * walk_dir(const char *, fsnode *); > +fsnode * walk_dir(const char *, const char *, fsnode *, fsnode *); > void free_fsnodes(fsnode *); > > void ffs_prep_opts(fsinfo_t *); > > Modified: head/usr.sbin/makefs/walk.c > ============================================================================== > --- head/usr.sbin/makefs/walk.c Tue Jan 31 00:12:51 2012 (r230794) > +++ head/usr.sbin/makefs/walk.c Tue Jan 31 00:32:37 2012 (r230795) > @@ -57,40 +57,70 @@ __FBSDID("$FreeBSD$"); > > static void apply_specdir(const char *, NODE *, fsnode *, int); > static void apply_specentry(const char *, NODE *, fsnode *); > -static fsnode *create_fsnode(const char *, struct stat *); > +static fsnode *create_fsnode(const char *, const char *, const char *, > + struct stat *); > static fsinode *link_check(fsinode *); > > > /* > * walk_dir -- > - * build a tree of fsnodes from `dir', with a parent fsnode of `parent' > - * (which may be NULL for the root of the tree). > + * build a tree of fsnodes from `root' and `dir', with a parent > + * fsnode of `parent' (which may be NULL for the root of the tree). > + * append the tree to a fsnode of `join' if it is not NULL. > * each "level" is a directory, with the "." entry guaranteed to be > * at the start of the list, and without ".." entries. > */ > fsnode * > -walk_dir(const char *dir, fsnode *parent) > +walk_dir(const char *root, const char *dir, fsnode *parent, fsnode *join) > { > - fsnode *first, *cur, *prev; > + fsnode *first, *cur, *prev, *last; > DIR *dirp; > struct dirent *dent; > char path[MAXPATHLEN + 1]; > struct stat stbuf; > + char *name, *rp; > + int dot, len; > > + assert(root != NULL); > assert(dir != NULL); > > + len = snprintf(path, sizeof(path), "%s/%s", root, dir); > + if (len >= (int)sizeof(path)) > + errx(1, "Pathname too long."); > if (debug & DEBUG_WALK_DIR) > - printf("walk_dir: %s %p\n", dir, parent); > - if ((dirp = opendir(dir)) == NULL) > - err(1, "Can't opendir `%s'", dir); > - first = prev = NULL; > + printf("walk_dir: %s %p\n", path, parent); > + if ((dirp = opendir(path)) == NULL) > + err(1, "Can't opendir `%s'", path); > + rp = path + strlen(root) + 1; > + if (join != NULL) { > + first = cur = join; > + while (cur->next != NULL) > + cur = cur->next; > + prev = cur; > + } else > + first = prev = NULL; > + last = prev; > while ((dent = readdir(dirp)) != NULL) { > - if (strcmp(dent->d_name, "..") == 0) > - continue; > + name = dent->d_name; > + dot = 0; > + if (name[0] == '.') > + switch (name[1]) { > + case '\0': /* "." */ > + if (join != NULL) > + continue; > + dot = 1; > + break; > + case '.': /* ".." */ > + if (name[2] == '\0') > + continue; > + /* FALLTHROUGH */ > + default: > + dot = 0; > + } > if (debug & DEBUG_WALK_DIR_NODE) > - printf("scanning %s/%s\n", dir, dent->d_name); > - if (snprintf(path, sizeof(path), "%s/%s", dir, dent->d_name) > - >= sizeof(path)) > + printf("scanning %s/%s/%s\n", root, dir, name); > + if (snprintf(path + len, sizeof(path) - len, "/%s", name) >= > + (int)sizeof(path) - len) > errx(1, "Pathname too long."); > if (lstat(path, &stbuf) == -1) > err(1, "Can't lstat `%s'", path); > @@ -102,22 +132,51 @@ walk_dir(const char *dir, fsnode *parent > } > #endif > > - cur = create_fsnode(dent->d_name, &stbuf); > + if (join != NULL) { > + cur = join->next; > + for (;;) { > + if (cur == NULL || strcmp(cur->name, name) == 0) > + break; > + if (cur == last) { > + cur = NULL; > + break; > + } > + cur = cur->next; > + } > + if (cur != NULL) { > + if (S_ISDIR(cur->type) && > + S_ISDIR(stbuf.st_mode)) { > + if (debug & DEBUG_WALK_DIR_NODE) > + printf("merging %s with %p\n", > + path, cur->child); > + cur->child = walk_dir(root, rp, cur, > + cur->child); > + continue; > + } > + errx(1, "Can't merge %s `%s' with existing %s", > + inode_type(stbuf.st_mode), path, > + inode_type(cur->type)); > + } > + } > + > + cur = create_fsnode(root, dir, name, &stbuf); > cur->parent = parent; > - if (strcmp(dent->d_name, ".") == 0) { > + if (dot) { > /* ensure "." is at the start of the list */ > cur->next = first; > first = cur; > if (! prev) > prev = cur; > + cur->first = first; > } else { /* not "." */ > if (prev) > prev->next = cur; > prev = cur; > if (!first) > first = cur; > + cur->first = first; > if (S_ISDIR(cur->type)) { > - cur->child = walk_dir(path, cur); > + cur->child = walk_dir(root, rp, cur, NULL); > continue; > } > } > @@ -147,22 +206,27 @@ walk_dir(const char *dir, fsnode *parent > err(1, "Memory allocation error"); > } > } > - for (cur = first; cur != NULL; cur = cur->next) > - cur->first = first; > + assert(first != NULL); > + if (join == NULL) > + for (cur = first->next; cur != NULL; cur = cur->next) > + cur->first = first; > if (closedir(dirp) == -1) > - err(1, "Can't closedir `%s'", dir); > + err(1, "Can't closedir `%s/%s'", root, dir); > return (first); > } > > static fsnode * > -create_fsnode(const char *name, struct stat *stbuf) > +create_fsnode(const char *root, const char *path, const char *name, > + struct stat *stbuf) > { > fsnode *cur; > > if ((cur = calloc(1, sizeof(fsnode))) == NULL || > + (cur->path = strdup(path)) == NULL || > (cur->name = strdup(name)) == NULL || > (cur->inode = calloc(1, sizeof(fsinode))) == NULL) > err(1, "Memory allocation error"); > + cur->root = root; > cur->type = stbuf->st_mode & S_IFMT; > cur->inode->nlink = 1; > cur->inode->st = *stbuf; > @@ -211,6 +275,7 @@ free_fsnodes(fsnode *node) > free(cur->inode); > if (cur->symlink) > free(cur->symlink); > + free(cur->path); > free(cur->name); > free(cur); > } > @@ -388,14 +453,16 @@ apply_specdir(const char *dir, NODE *spe > stbuf.st_mtimensec = stbuf.st_atimensec = > stbuf.st_ctimensec = start_time.tv_nsec; > #endif > - curfsnode = create_fsnode(curnode->name, &stbuf); > + curfsnode = create_fsnode(".", ".", curnode->name, > + &stbuf); > curfsnode->parent = dirnode->parent; > curfsnode->first = dirnode; > curfsnode->next = dirnode->next; > dirnode->next = curfsnode; > if (curfsnode->type == S_IFDIR) { > /* for dirs, make "." entry as well */ > - curfsnode->child = create_fsnode(".", &stbuf); > + curfsnode->child = create_fsnode(".", ".", ".", > + &stbuf); > curfsnode->child->parent = curfsnode; > curfsnode->child->first = curfsnode->child; > } > @@ -503,19 +570,18 @@ apply_specentry(const char *dir, NODE *s > > /* > * dump_fsnodes -- > - * dump the fsnodes from `cur', based in the directory `dir' > + * dump the fsnodes from `cur' > */ > void > -dump_fsnodes(const char *dir, fsnode *root) > +dump_fsnodes(fsnode *root) > { > fsnode *cur; > char path[MAXPATHLEN + 1]; > > - assert (dir != NULL); > - printf("dump_fsnodes: %s %p\n", dir, root); > + printf("dump_fsnodes: %s %p\n", root->path, root); > for (cur = root; cur != NULL; cur = cur->next) { > - if (snprintf(path, sizeof(path), "%s/%s", dir, cur->name) > - >= sizeof(path)) > + if (snprintf(path, sizeof(path), "%s/%s", cur->path, > + cur->name) >= (int)sizeof(path)) > errx(1, "Pathname too long."); > > if (debug & DEBUG_DUMP_FSNODES_VERBOSE) > @@ -534,10 +600,10 @@ dump_fsnodes(const char *dir, fsnode *ro > > if (cur->child) { > assert (cur->type == S_IFDIR); > - dump_fsnodes(path, cur->child); > + dump_fsnodes(cur->child); > } > } > - printf("dump_fsnodes: finished %s\n", dir); > + printf("dump_fsnodes: finished %s/%s\n", root->path, root->name); > } > >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4F42B8DF.7040400>