Philip Guenther <guent...@gmail.com> writes: > Can we suppress the device form if there's a matching DUID entry?
Okay. The DUID/device dance is not that easy (at least for me). So here is a new patch that should work. For your issue, I choose to convert dumpdates entries to DUID (when possible) at read time so dump now has the following features/drawbacks: - All dumpdates entries (of present devices) will be converted to DUID at the next dump (even those that are not being dumped). - Even a dump -w/W tries to opendev the device (in order to find its UID). Index: dump.h =================================================================== RCS file: /cvs/src/sbin/dump/dump.h,v retrieving revision 1.23 diff -u -p -r1.23 dump.h --- dump.h 3 May 2015 01:44:34 -0000 1.23 +++ dump.h 12 May 2015 08:42:02 -0000 @@ -125,6 +125,7 @@ __dead void dumpabort(int signo); void getfstab(void); char *rawname(char *cp); +char *getduid(char *path); union dinode *getino(ino_t inum, int *mode); /* rdump routines */ Index: itime.c =================================================================== RCS file: /cvs/src/sbin/dump/itime.c,v retrieving revision 1.20 diff -u -p -r1.20 itime.c --- itime.c 3 May 2015 01:44:34 -0000 1.20 +++ itime.c 12 May 2015 08:42:02 -0000 @@ -251,6 +251,11 @@ makedumpdate(struct dumpdates *ddp, char if (sscanf(tbuf, DUMPINFMT, ddp->dd_name, &ddp->dd_level, un_buf) != 3) return(-1); + str = getduid(ddp->dd_name); + if (str != NULL) { + strncpy(ddp->dd_name, str, NAME_MAX+3); + free(str); + } str = strptime(un_buf, "%a %b %e %H:%M:%S %Y", &then); then.tm_isdst = -1; if (str == NULL || (*str != '\n' && *str != '\0')) Index: main.c =================================================================== RCS file: /cvs/src/sbin/dump/main.c,v retrieving revision 1.55 diff -u -p -r1.55 main.c --- main.c 3 May 2015 01:44:34 -0000 1.55 +++ main.c 12 May 2015 08:42:02 -0000 @@ -363,7 +363,13 @@ main(int argc, char *argv[]) } } else if ((dt = fstabsearch(disk)) != NULL) { /* in fstab? */ - disk = rawname(dt->fs_spec); + if (strchr(dt->fs_spec, '/')) { + /* fs_spec is a /dev/something */ + disk = rawname(dt->fs_spec); + } else { + /* fs_spec is a DUID */ + disk = rawname(disk); + } mount_point = dt->fs_file; (void)strlcpy(spcl.c_dev, dt->fs_spec, sizeof(spcl.c_dev)); if (dirlist != 0) { @@ -649,13 +655,52 @@ rawname(char *cp) { static char rawbuf[PATH_MAX]; char *dp = strrchr(cp, '/'); + char *prefix; if (dp == NULL) return (NULL); + if (*(dp + 1) == 'r') { + prefix = ""; + } else { + prefix = "r"; + } *dp = '\0'; - (void)snprintf(rawbuf, sizeof(rawbuf), "%s/r%s", cp, dp + 1); + (void)snprintf(rawbuf, sizeof(rawbuf), "%s/%s%s", cp, prefix, dp + 1); *dp = '/'; return (rawbuf); +} + +char * +getduid(char *path) +{ + int fd; + struct disklabel lab; + u_int64_t zero_uid = 0; + char *duid; + + if ((fd = opendev(path, O_RDONLY | O_NOFOLLOW, 0, NULL)) >= 0) { + if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { + close(fd); + warn("ioctl(DIOCGDINFO)"); + return (NULL); + } + + if (memcmp(lab.d_uid, &zero_uid, sizeof(lab.d_uid)) != 0) { + if (asprintf(&duid, + "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx.%c", + lab.d_uid[0], lab.d_uid[1], lab.d_uid[2], + lab.d_uid[3], lab.d_uid[4], lab.d_uid[5], + lab.d_uid[6], lab.d_uid[7], + path[strlen(path)-1]) == -1) { + close(fd); + warn("Cannot malloc duid"); + return (NULL); + } + return (duid); + } + } + + return (NULL); } /* Index: optr.c =================================================================== RCS file: /cvs/src/sbin/dump/optr.c,v retrieving revision 1.36 diff -u -p -r1.36 optr.c --- optr.c 15 Mar 2015 00:41:27 -0000 1.36 +++ optr.c 12 May 2015 08:42:02 -0000 @@ -337,7 +337,7 @@ fstabsearch(char *key) { struct pfstab *pf; struct fstab *fs; - char *rn; + char *rn, *uid; for (pf = table; pf != NULL; pf = pf->pf_next) { fs = pf->pf_fstab; @@ -347,6 +347,13 @@ fstabsearch(char *key) rn = rawname(fs->fs_spec); if (rn != NULL && strcmp(rn, key) == 0) return (fs); + if (rn != NULL) { + uid = getduid(rn); + } else { + uid = getduid(fs->fs_spec); + } + if (uid != NULL && strcmp(uid, key) == 0) + return (fs); if (key[0] != '/') { if (*fs->fs_spec == '/' && strcmp(fs->fs_spec + 1, key) == 0) @@ -387,7 +394,7 @@ lastdump(int arg) lastname = "??"; ITITERATE(i, dtwalk) { if (strncmp(lastname, dtwalk->dd_name, - sizeof(dtwalk->dd_name)) == 0) + sizeof(dtwalk->dd_name)) == 0) continue; date = (char *)ctime(&dtwalk->dd_ddate); date[16] = '\0'; /* blast away seconds and year */ -- Manuel Giraud