On Wed, 27 Nov 2013, Cody Cutler wrote:
> hello, the following is my attempt to add duid support to dump.
> thanks!

>From a quick glance, you should be able to use opendev(3) to open the disk 
device (rather than using open), in which case you'll get DUID handling for 
free. This also avoids the TOCTOU issues associated with attempting to map a 
DUID back to a name. Even if this is not possible, then it would be 
preferable to use opendev(3) to get the realname (as is done in fsck(8) from 
memory), rather than the hand rolled version below.

> Index: Makefile
> ===================================================================
> RCS file: /cvs/src/sbin/dump/Makefile,v
> retrieving revision 1.11
> diff -p -u -r1.11 Makefile
> --- Makefile  6 Jan 2013 21:59:28 -0000       1.11
> +++ Makefile  26 Nov 2013 17:59:50 -0000
> @@ -12,6 +12,8 @@
>  #    TDEBUG                  trace out the process forking
>
>  PROG=        dump
> +LDADD=       -lutil
> +DPADD=       ${LIBUTIL}
>  LINKS=       ${BINDIR}/dump ${BINDIR}/rdump
>  CFLAGS+=-DRDUMP
>  SRCS=        itime.c main.c optr.c dumprmt.c tape.c traverse.c
> Index: dump.h
> ===================================================================
> RCS file: /cvs/src/sbin/dump/dump.h,v
> retrieving revision 1.17
> diff -p -u -r1.17 dump.h
> --- dump.h    11 Jun 2013 16:42:04 -0000      1.17
> +++ dump.h    26 Nov 2013 17:59:50 -0000
> @@ -86,6 +86,7 @@ int tp_bshift;      /* log2(TP_BSIZE) */
>  /* operator interface functions */
>  void broadcast(char *message);
>  time_t       do_stats(void);
> +int  duidtorawname(char *duid, char *buf, size_t s);
>  void lastdump(int arg);      /* int should be char */
>  void msg(const char *fmt, ...)
>      __attribute__((__format__ (printf, 1, 2)));
> Index: main.c
> ===================================================================
> RCS file: /cvs/src/sbin/dump/main.c,v
> retrieving revision 1.46
> diff -p -u -r1.46 main.c
> --- main.c    16 Apr 2013 18:17:39 -0000      1.46
> +++ main.c    26 Nov 2013 17:59:50 -0000
> @@ -31,6 +31,7 @@
>   */
>
>  #include <sys/param.h>
> +#include <sys/dkio.h>
>  #include <sys/mount.h>
>  #include <sys/stat.h>
>  #include <sys/time.h>
> @@ -51,6 +52,7 @@
>  #include <string.h>
>  #include <time.h>
>  #include <unistd.h>
> +#include <util.h>
>
>  #include "dump.h"
>  #include "pathnames.h"
> @@ -78,6 +80,7 @@ static void usage(void);
>  int
>  main(int argc, char *argv[])
>  {
> +     char dbuf[MAXPATHLEN];
>       ino_t ino;
>       int dirty;
>       union dinode *dp;
> @@ -204,7 +207,9 @@ main(int argc, char *argv[])
>       for (i = 0; i < argc; i++) {
>               struct stat sb;
>
> -             if (lstat(argv[i], &sb) == -1) {
> +             if (isduid(argv[i], 0))
> +                     break;
> +             else if (lstat(argv[i], &sb) == -1) {
>                       msg("Cannot lstat %s: %s\n", argv[i], strerror(errno));
>                       exit(X_STARTUP);
>               }
> @@ -321,6 +326,10 @@ main(int argc, char *argv[])
>        *      the special name missing the leading '/',
>        *      the file system name with or without the leading '/'.
>        */
> +     if (isduid(disk, 0)) {
> +             duidtorawname(disk, dbuf, sizeof(dbuf));
> +             disk = dbuf;
> +     }
>       if (!statfs(disk, &fsbuf) && !strcmp(fsbuf.f_mntonname, disk)) {
>               /* mounted disk? */
>               disk = rawname(fsbuf.f_mntfromname);
> @@ -604,17 +613,42 @@ sig(int signo)
>       }
>  }
>
> +int
> +duidtorawname(char *duid, char *buf, size_t s)
> +{
> +     struct dk_diskmap dk;
> +     int fd, ret;
> +
> +     if ((fd = open("/dev/diskmap", O_RDONLY)) < 0)
> +             return 0;
> +
> +     strlcpy(buf, duid, s);
> +     dk.fd = fd;
> +     dk.device = buf;
> +     dk.flags = 0;
> +     // buf is filled with raw dev
> +     ret = ioctl(fd, DIOCMAP, &dk);
> +     close(fd);
> +
> +     return (ret < 0) ? 0 : 1;
> +}
> +
>  char *
>  rawname(char *cp)
>  {
>       static char rawbuf[MAXPATHLEN];
> -     char *dp = strrchr(cp, '/');
> -
> -     if (dp == NULL)
> -             return (NULL);
> -     *dp = '\0';
> -     (void)snprintf(rawbuf, sizeof(rawbuf), "%s/r%s", cp, dp + 1);
> -     *dp = '/';
> +     char *dp;
> +
> +     if (isduid(cp, 0)) {
> +             duidtorawname(cp, rawbuf, sizeof(rawbuf));
> +     } else {
> +             dp = strrchr(cp, '/');
> +             if (dp == NULL)
> +                     return (NULL);
> +             *dp = '\0';
> +             (void)snprintf(rawbuf, sizeof(rawbuf), "%s/r%s", cp, dp + 1);
> +             *dp = '/';
> +     }
>       return (rawbuf);
>  }



-- 

    "Action without study is fatal. Study without action is futile."
        -- Mary Ritter Beard

Reply via email to