Discussion:
Adding functions to libutil, part 2
(too old to reply)
Reinoud Zandijk
2024-06-20 20:46:06 UTC
Permalink
Dear folks,

I'd like to add a function implementing fsck/fsutil.c's blockcheck()
char *blockcheck(const char *origname);

as

char *canonical_rdev(char *buf, size_t buflen, const char *origname,
int *flags);

that returns a canonical raw device name when passed a device name in one of
the following ways:
/dev/ld0
name="UUID"
name="ROOT.x"
/dev/dk1
/some/mountpoint
some/file/name

or a softlink to any of these. It could return various flags that might be of
interest. At a minimum it needs to return if the device is the root device as
the current users of blockcheck() rely on it.
Usable flags could be:
IS_ROOT (is a byproduct)
NOTEXISTING (saves a stat)
NODEV (no device)
with a possibly interesting
IS_UNIQUE (no aliases exist in /dev/)

The goal is to have a uniform code that accepts all ways to specify a raw
device. Currently every program has its own logic and oddities/omissions like
fsck_ffs does accept files but fsck_msdos only grocks raw devices etc.

If it fails, a second call can be made prepending `/dev/' to the name so `dk0'
could be accepted then too. Thus could be made a feature but the current code
does not take that into account.

What are your thoughts about this?

With regards,
Reinoud



The current blockcheck() is called from:
sbin/fsck/fsutil.h
sbin/fsck/fsck.c
sbin/fsck/fsutil.c
sbin/fsck/preen.c
sbin/fsck_ext2fs/main.c
sbin/fsck_ffs/main.c
sbin/fsck_lfs/main.c
sbin/fsck_v7fs/fsck_v7fs.c
usr.sbin/quotacheck/quotacheck.c


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Michael van Elst
2024-06-21 06:24:53 UTC
Permalink
Post by Reinoud Zandijk
that returns a canonical raw device name when passed a device name in one of
/dev/ld0
name="UUID"
name="ROOT.x"
/dev/dk1
/some/mountpoint
some/file/name
That looks like many distinct functions to me.

1. resolve a symbolic path (like NAME="") into a device path
This is what getfsspec() does.

2. determine the underlying device of a filesystem object.
This is what stat() does.

3. determine the raw (character) device name for a device path.
This is what getdiskrawname() does.

4. determine the device name for a configured mountpoint (before mounting):
This is what getfsfile() does.

It doesn't account for just specifying the device name (not path)
as supported by many programs through opendisk().



N.B.

There is no name="UUID" (it's _the_ wedge name, not a UUID).
There is no name="ROOT.x" but just ROOT.x.
Post by Reinoud Zandijk
The goal is to have a uniform code that accepts all ways to specify a raw
device. Currently every program has its own logic and oddities/omissions like
fsck_ffs does accept files but fsck_msdos only grocks raw devices etc.
Actually we have 'mount' which resolves the device name and 'mount_*' that
gets passed the resolved name.

We have 'fsck' which resolves the device name and 'fsck_*' that gets passed
the resolved name.

We don't have anything similar for newfs (there is no newfs_ffs).
We don't have anything similar for dump (there is no dump_ffs).
We don't have anything similar for dumpfs (there is no dumpfs_ffs).

We also have 'df' where 'df -W' prints the original symbolic path
(but just for NAME=) because a resolved symbol path cannot be
reversed.

I fear your one-size-fits-all function just grows the zoo of interfaces
(and its results is by no means 'canonical' either).


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Reinoud Zandijk
2024-06-21 09:59:10 UTC
Permalink
Hi Michael, thanks for your feedback,
Post by Michael van Elst
Post by Reinoud Zandijk
that returns a canonical raw device name when passed a device name in one of
/dev/ld0
name="UUID"
name="ROOT.x"
/dev/dk1
/some/mountpoint
some/file/name
That looks like many distinct functions to me.
1. resolve a symbolic path (like NAME="") into a device path
This is what getfsspec() does.
2. determine the underlying device of a filesystem object.
This is what stat() does.
3. determine the raw (character) device name for a device path.
This is what getdiskrawname() does.
This is what getfsfile() does.
It doesn't account for just specifying the device name (not path)
as supported by many programs through opendisk().
As its precursor blockcheck(), in sbin/fsck/fsutils.c it uses all these
functions from libutil to get to the end result and iterating when needed. And
indeed its ROOT.x :) that was a typo from me and all handled by
getfsspecname() anyway.
Post by Michael van Elst
Post by Reinoud Zandijk
The goal is to have a uniform code that accepts all ways to specify a raw
device. Currently every program has its own logic and oddities/omissions like
fsck_ffs does accept files but fsck_msdos only grocks raw devices etc.
Actually we have 'mount' which resolves the device name and 'mount_*' that
gets passed the resolved name.
We have 'fsck' which resolves the device name and 'fsck_*' that gets passed
the resolved name.
If they were never intended to be used separately then shouldn't they be in
libexec?
Post by Michael van Elst
We don't have anything similar for newfs (there is no newfs_ffs).
We don't have anything similar for dump (there is no dump_ffs).
We don't have anything similar for dumpfs (there is no dumpfs_ffs).
That is an omission stemming from the time only FFS was around IMHO; for
othogonality we could split them one day if someone is bored enough...
Post by Michael van Elst
We also have 'df' where 'df -W' prints the original symbolic path
(but just for NAME=) because a resolved symbol path cannot be
reversed.
'df -W' just uses getmntinfo() and mount(8) only calls getfsspecname() before
passing it on. The rest is for the mount programs to figure out. The fsck(8)
uses its blockcheck() function to preparse everything before it then passes it
to the relevant fsck_* program. This new function is nothing more as a generic
subtitute of that functionality and decouple it from fsck specific things like
perr() etc.
Post by Michael van Elst
I fear your one-size-fits-all function just grows the zoo of interfaces
(and its results is by no means 'canonical' either).
That name grew as its meant to be the place to support all forms of device
specifications in one place and from the optional extra possible functionality
(not yet implemented) that it looks up its resulting st_rdev in /dev/ so if
for whatever reason a device node is symlinked or used elsewhere it will
always return the same one in /dev/. Bit esotheric maybe but people can do
strange things with fstabs, softlinks or bluntly hardlinking.

One of the ideas that seem to be behind the origional blockcheck() and thus
also canonical_rdev() is just that; to get some sanity in the zoo of functions
and to support all the possible name specifications that all have their
separate functions in libutil in one place; its to glue all these libutil
functions together.

If used together with an enhanced getdiskinfo() (see part 1) that fabricates
geometry for files all tools will automatically gain the posibility to work on
files too but maybe thats a bit off topic and a bridge to far for now. I've
done simular things for all udf tools too as i needed to emulate specific
device types in makefs anyway and the actual code doing the works has no idea
its writing to a file instead of a device.

Does this make sense for you?

With regards,
Reinoud


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Reinoud Zandijk
2024-06-21 14:04:55 UTC
Permalink
Hi Micheal,
Post by Michael van Elst
Post by Reinoud Zandijk
Post by Michael van Elst
We also have 'df' where 'df -W' prints the original symbolic path
(but just for NAME=) because a resolved symbol path cannot be
reversed.
'df -W' just uses getmntinfo() and mount(8) only calls getfsspecname() before
passing it on.
It's fetches (part of) the unresolved spec that was saved as f_mntfromlabel
and prepends NAME=.
If getfsspecname() has been called names will be translated to raw /dev/rdk*
devices and those always have a name; the name itself is lost when calling the
mount_* programs.

With regards,
Reinoud


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Michael van Elst
2024-06-21 11:27:33 UTC
Permalink
Post by Reinoud Zandijk
Post by Michael van Elst
We have 'fsck' which resolves the device name and 'fsck_*' that gets passed
the resolved name.
If they were never intended to be used separately then shouldn't they be in
libexec?
Well, that's history for you :)
Post by Reinoud Zandijk
Post by Michael van Elst
We also have 'df' where 'df -W' prints the original symbolic path
(but just for NAME=) because a resolved symbol path cannot be
reversed.
'df -W' just uses getmntinfo() and mount(8) only calls getfsspecname() before
passing it on.
It's fetches (part of) the unresolved spec that was saved as f_mntfromlabel
and prepends NAME=.




--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...