PERFORCE change 52224 for review

Chris Vance cvance at FreeBSD.org
Tue May 4 07:21:43 PDT 2004


http://perforce.freebsd.org/chv.cgi?CH=52224

Change 52224 by cvance at cvance_g5 on 2004/05/04 07:21:29

	Add a flag to supply "extattrctl initattr" with an initial attribute value to 
	store in the newly created attribute backing file. This allows policies like
	SEBSD to apply a default value, and only label files that require a different
	non-default label.
	
	Also added a function to check if the preallocation path is on the same 
	file system as the backing file.  If not, print a warning and continue. 
	This prints a message for a common failure of preallocating attributes
	based on the inode count from a different file system.

Affected files ...

.. //depot/projects/trustedbsd/sedarwin73/extattr_cmds/extattrctl/extattrctl.8#2 edit
.. //depot/projects/trustedbsd/sedarwin73/extattr_cmds/extattrctl/extattrctl.c#2 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin73/extattr_cmds/extattrctl/extattrctl.8#2 (text+ko) ====

@@ -47,6 +47,7 @@
 .Cm initattr
 .Op Fl f
 .Op Fl p Ar path
+.Op Fl i Ar initial_value
 .Ar attrsize
 .Ar attrfile
 .Nm
@@ -89,6 +90,7 @@
 .Cm initattr
 .Op Fl f
 .Op Fl p Ar path
+.Op Fl i Ar initial_value
 .Ar attrsize attrfile
 .Xc
 Create and initialize a file to use as an attribute backing file.
@@ -111,6 +113,13 @@
 for attributes when they are written, preventing low disk space conditions
 from denying attribute service.
 .Pp
+The
+.Fl i Ar initial_value
+argument may be used to assign a initial value for all attributes rather
+than using an empty value. This requires the use of the
+.Fl p 
+flag to preallocate space as well.
+.Pp
 This file should not exist before running
 .Cm initattr .
 .It Cm showattr Ar attrfile

==== //depot/projects/trustedbsd/sedarwin73/extattr_cmds/extattrctl/extattrctl.c#2 (text+ko) ====

@@ -60,7 +60,7 @@
 	    "usage:\n"
 	    "  extattrctl start path\n"
 	    "  extattrctl stop path\n"
-	    "  extattrctl initattr [-f] [-p path] attrsize attrfile\n"
+	    "  extattrctl initattr [-f] [-p path] [-i initial_value ] attrsize attrfile\n"
 	    "  extattrctl showattr attrfile\n"
 	    "  extattrctl enable path attrnamespace attrname attrfile\n"
 	    "  extattrctl disable path attrnamespace attrname\n");
@@ -83,16 +83,45 @@
 }
 
 int
+verify_paths(const char *fs_path, const char *attr_path)
+{
+	int error;
+	struct statfs fs1, fs2;
+	
+	error = statfs(fs_path, &fs1);
+	if (error) {
+		perror("statfs");
+		return (-1);
+	}
+	error = statfs(attr_path, &fs2);
+	if (error) {
+		perror("statfs");
+		return (-1);
+	}
+	
+	if (memcmp(&fs1.f_fsid, &fs2.f_fsid, sizeof(fsid_t)) != 0) {
+		printf("Warning, attribute backing file is not located on \n"
+		    "the same file system as the preallocation path.\n"
+		    "Continuing...\n");
+	}
+	return (0);
+}
+
+
+int
 initattr(int argc, char *argv[])
 {
 	struct hfs_extattr_fileheader	uef;
 	char	*fs_path = NULL;
 	char	*zero_buf = NULL;
+	char	*initial_value = NULL;
 	long	loop, num_inodes;
 	int	ch, i, error, chunksize, overwrite = 0, flags;
+	struct	hfs_extattr_header header;
+	int	headersize;
 
 	optind = 0;
-	while ((ch = getopt(argc, argv, "fp:r:w:")) != -1)
+	while ((ch = getopt(argc, argv, "fi:p:")) != -1)
 		switch (ch) {
 		case 'f':
 			overwrite = 1;
@@ -103,6 +132,12 @@
 				return(-1);
 			}
 			break;
+		case 'i':
+			if ((initial_value = strdup(optarg)) == NULL) {
+				perror("strdup");
+				return(-1);
+			}
+			break;
 		case '?':
 		default:
 			usage();
@@ -114,6 +149,12 @@
 	if (argc != 2)
 		usage();
 
+	if ((initial_value != NULL) && (fs_path == NULL)) {
+		fprintf(stderr,"Error, initial value specified, but -p "
+		    "was not specified\n");
+		usage();
+	}
+
 	if (overwrite)
 		flags = O_CREAT | O_WRONLY;
 	else
@@ -136,8 +177,10 @@
 		if (fwrite(&uef, sizeof(uef), 1, fp) != 1)
 			error = -1;
 		else if (fs_path) {
-			chunksize = sizeof(struct hfs_extattr_header) +
-			    uef.uef_size;
+			if (verify_paths(fs_path, argv[1])) 
+				usage();
+			headersize = sizeof(struct hfs_extattr_header);
+			chunksize = headersize + uef.uef_size;
 			zero_buf = (char *) (malloc(chunksize));
 			if (zero_buf == NULL) {
 				perror("malloc");
@@ -146,6 +189,24 @@
 				return (-1);
 			}
 			memset(zero_buf, 0, chunksize);
+			if (initial_value != NULL) {
+				header.ueh_flags = HFS_EXTATTR_ATTR_FLAG_INUSE;
+
+				/* Include the terminating NULL? */
+				header.ueh_len = strlen(initial_value)+1;
+				if (header.ueh_len > uef.uef_size)
+					header.ueh_len = uef.uef_size;
+
+				/* 
+				 * The kernel doesn't know what to do with 
+				 * HFS generation numbers either...
+				 */
+				header.ueh_i_gen = 0;
+
+				memcpy(zero_buf, &header, headersize);
+				strncpy((char *)(zero_buf+headersize), 
+				    initial_value, uef.uef_size);
+			}
 			num_inodes = num_inodes_by_path(fs_path);
 			for (loop = 0; loop < num_inodes; loop++) {
 				error = fwrite(zero_buf, chunksize, 1, fp);


More information about the p4-projects mailing list