Userland part of ISO9660 multi-session support. mount_cd9660(8) will

now by default mount the last data track (thus last session), as
opposed to the very first session it has been mounting previously.
This is consistent with the ISO9660 multi-session idea, and the way
other operating systems are working.

There's support to mount arbitrary sessions using the -s option.  This
way, you can simulate multi-session CDs on something like vn devices
that don't support CDIO* ioctl commands.  You can also force the
historic behaviour with

	mount -t cd9660 -o -s=0 /dev/cd0a /cdrom
This commit is contained in:
Joerg Wunsch 1997-04-29 15:56:40 +00:00
parent 3e1cf43148
commit d6ef03d3fa
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=25286
2 changed files with 103 additions and 11 deletions

View File

@ -42,8 +42,9 @@
.Nd mount an ISO-9660 filesystem
.Sh SYNOPSIS
.Nm mount_cd9660
.Op Fl egr
.Op Fl egrv
.Op Fl o Ar options
.Op Fl s startsector
.Ar special | node
.Sh DESCRIPTION
The
@ -75,11 +76,31 @@ See the
man page for possible options and their meanings.
.It Fl r
Do not use any Rockridge extensions included in the filesystem.
.It Fl s Ar startsector
Start the filesystem at
.Ar startsector .
Normally, if the underlying device is a CD-ROM drive,
.Nm
will try to figure out the last track from the CD-ROM containing
data, and start the filesystem there. If the device is not a CD-ROM,
or the table of contents cannot be examined, the filesystem will be
started at sector 0. This option can be used to override the behaviour.
Note that
.Ar startsector
is measured in CD-ROM blocks, with 2048 bytes each. This is the same
as for example the
.Cm info
command of
.Xr cdcontrol 8
is printing.
.It Fl v
Be verbose about the starting sector decisions made.
.El
.Sh SEE ALSO
.Xr mount 2 ,
.Xr unmount 2 ,
.Xr fstab 5 ,
.Xr cdcontrol 8 ,
.Xr mount 8
.Sh BUGS
POSIX device node mapping is currently not supported.

View File

@ -49,9 +49,11 @@ static char copyright[] =
static char sccsid[] = "@(#)mount_cd9660.c 8.7 (Berkeley) 5/1/95";
*/
static const char rcsid[] =
"$Id: mount_cd9660.c,v 1.10 1997/03/11 12:29:02 peter Exp $";
"$Id: mount_cd9660.c,v 1.11 1997/03/29 03:32:35 imp Exp $";
#endif /* not lint */
#include <sys/cdio.h>
#include <sys/file.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/../isofs/cd9660/cd9660_mount.h>
@ -74,21 +76,22 @@ struct mntopt mopts[] = {
{ NULL }
};
void usage __P((void));
int get_ssector(const char *dev);
void usage(void);
int
main(argc, argv)
int argc;
char **argv;
main(int argc, char **argv)
{
struct iso_args args;
int ch, mntflags, opts;
char *dev, *dir;
struct vfsconf vfc;
int error;
int error, verbose;
mntflags = opts = 0;
while ((ch = getopt(argc, argv, "ego:r")) != -1)
mntflags = opts = verbose = 0;
memset(&args, 0, sizeof args);
args.ssector = -1;
while ((ch = getopt(argc, argv, "ego:rs:v")) != -1)
switch (ch) {
case 'e':
opts |= ISOFSMNT_EXTATT;
@ -102,6 +105,12 @@ main(argc, argv)
case 'r':
opts |= ISOFSMNT_NORRIP;
break;
case 's':
args.ssector = atoi(optarg);
break;
case 'v':
verbose++;
break;
case '?':
default:
usage();
@ -125,6 +134,26 @@ main(argc, argv)
args.export.ex_root = DEFAULT_ROOTUID;
args.flags = opts;
if (args.ssector == -1) {
/*
* The start of the session has not been specified on
* the command line. If we can successfully read the
* TOC of a CD-ROM, use the last data track we find.
* Otherwise, just use 0, in order to mount the very
* first session. This is compatible with the
* historic behaviour of mount_cd9660(8). If the user
* has specified -s <ssector> above, we don't get here
* and leave the user's will.
*/
if ((args.ssector = get_ssector(dev)) == -1) {
if (verbose)
printf("could not determine starting sector, "
"using very first session\n");
args.ssector = 0;
} else if (verbose)
printf("using starting sector %d\n", args.ssector);
}
error = getvfsbyname("cd9660", &vfc);
if (error && vfsisloadable("cd9660")) {
if (vfsload("cd9660"))
@ -141,9 +170,51 @@ main(argc, argv)
}
void
usage()
usage(void)
{
(void)fprintf(stderr,
"usage: mount_cd9660 [-egrt] [-o options] special node\n");
"usage: mount_cd9660 [-egrv] [-o options] [-s startsector] special node\n");
exit(EX_USAGE);
}
int
get_ssector(const char *dev)
{
struct ioc_toc_header h;
struct ioc_read_toc_entry t;
struct cd_toc_entry toc_buffer[100];
int fd, ntocentries, i;
if ((fd = open(dev, O_RDONLY)) == -1)
return -1;
if (ioctl(fd, CDIOREADTOCHEADER, &h) == -1) {
close(fd);
return -1;
}
ntocentries = h.ending_track - h.starting_track + 1;
if (ntocentries > 100) {
/* unreasonable, only 100 allowed */
close(fd);
return -1;
}
t.address_format = CD_LBA_FORMAT;
t.starting_track = 0;
t.data_len = ntocentries * sizeof(struct cd_toc_entry);
t.data = toc_buffer;
if (ioctl(fd, CDIOREADTOCENTRYS, (char *) &t) == -1) {
close(fd);
return -1;
}
close(fd);
for (i = ntocentries - 1; i >= 0; i--)
if ((toc_buffer[i].control & 4) != 0)
/* found a data track */
break;
if (i < 0)
return -1;
return ntohl(toc_buffer[i].addr.lba);
}