On 07/10/14 16:28, Alexander Hall wrote: > Anyway, I worked on your diff a bit more: > > - keep having -U and -u separate (as discussed) > - use Uflag instead of duidflag > - bail out if the duid is all 0. > - allow specifying the drive to dump by <duid>.<part> on the > command line. Subject to race conditions, but no more than the > current code. > > Do you think this makes sense, and can you please test if this works > for you?
Works for me. I think it's good, but I'd suggest some more changes: - if the user already gives us the duid, don't read the disklabel - added messages regarding duid-handling A new diff for main.c follows below. In the new diff, we only use opendev when isduid returns true, so I think we could replace it with diskmap(4), but I don't feel like figuring that out right now. Also, should we abort if the user specifies an all-zero duid on the command line? =================================================================== RCS file: sbin/dump/RCS/main.c,v retrieving revision 1.1 retrieving revision 1.4 diff -u -p -r1.1 -r1.4 --- sbin/dump/main.c 2014/06/24 21:35:37 1.1 +++ sbin/dump/main.c 2014/07/10 23:41:03 1.4 @@ -54,6 +54,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <util.h> #include "dump.h" #include "pathnames.h" @@ -94,8 +95,9 @@ main(int argc, char *argv[]) ino_t maxino; time_t t; int dirlist; - char *toplevel, *str, *mount_point = NULL; + char *toplevel, *str, *mount_point = NULL, *realpath; int just_estimate = 0; + u_int64_t zero_uid = 0; spcl.c_date = (int64_t)time(NULL); @@ -112,7 +114,7 @@ main(int argc, char *argv[]) usage(); obsolete(&argc, &argv); - while ((ch = getopt(argc, argv, "0123456789aB:b:cd:f:h:ns:ST:uWw")) != -1) + while ((ch = getopt(argc, argv, "0123456789aB:b:cd:f:h:ns:ST:UuWw")) != -1) switch (ch) { /* dump level */ case '0': case '1': case '2': case '3': case '4': @@ -180,6 +182,10 @@ main(int argc, char *argv[]) lastlevel = '?'; break; + case 'U': + Uflag = 1; /* use duids */ + break; + case 'u': /* update /etc/dumpdates */ uflag = 1; break; @@ -213,6 +219,18 @@ main(int argc, char *argv[]) for (i = 0; i < argc; i++) { struct stat sb; + /* Convert potential duid into a device name */ + if (isduid(argv[i], 0) && (diskfd = opendev(argv[i], + O_RDONLY | O_NOFOLLOW, 0, &realpath)) >= 0) { + duid = argv[i]; + argv[i] = strdup(realpath); + if (argv[i] == NULL) { + msg("Cannot malloc realpath\n"); + exit(X_STARTUP); + } + (void)close(diskfd); + msg("DUID %s maps to %s\n", duid, realpath); + } if (lstat(argv[i], &sb) == -1) { msg("Cannot lstat %s: %s\n", argv[i], strerror(errno)); exit(X_STARTUP); @@ -370,6 +388,28 @@ main(int argc, char *argv[]) (void)gethostname(spcl.c_host, sizeof(spcl.c_host)); spcl.c_level = level - '0'; spcl.c_type = TS_TAPE; + + if ((diskfd = open(disk, O_RDONLY)) < 0) { + msg("Cannot open %s\n", disk); + exit(X_STARTUP); + } + if (Uflag && duid == NULL) { + if (ioctl(diskfd, DIOCGDINFO, (char *)&lab) < 0) + err(1, "ioctl (DIOCGDINFO)"); + if (memcmp(lab.d_uid, &zero_uid, sizeof(lab.d_uid)) == 0) { + msg("Cannot find DUID of disk %s\n", disk); + exit(X_STARTUP); + } + 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], + disk[strlen(disk)-1]) == -1) { + msg("Cannot malloc duid\n"); + exit(X_STARTUP); + } + msg("DUID of %s: %s\n", disk, duid); + } if (!Tflag) getdumptime(); /* /etc/dumpdates snarfed */ @@ -387,10 +427,6 @@ main(int argc, char *argv[]) else msgtail("to %s\n", tape); - if ((diskfd = open(disk, O_RDONLY)) < 0) { - msg("Cannot open %s\n", disk); - exit(X_STARTUP); - } if (ioctl(diskfd, DIOCGPDINFO, (char *)&lab) < 0) err(1, "ioctl (DIOCGPDINFO)"); sync();