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();