tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

patch - cgdconfig do_all mode gracefully ignore detached devices



Hello NetBSD,

When using cgdconfig in do_all mode (-C|-U), it will attempt to configure/unconfigure all devices specified in cgd.conf regardless of whether the device is attached or not (our use case is USB drives).  The below diff gracefully skips over devices if they are not attached or not configured.  This only affects do_all mode.  Any interest? Ok?

Thanks and regards,
Jason


Index: cgdconfig.c
===================================================================
RCS file: /cvsroot/src/sbin/cgdconfig/cgdconfig.c,v
retrieving revision 1.50
diff -b -u -r1.50 cgdconfig.c
--- cgdconfig.c	10 Apr 2019 06:11:37 -0000	1.50
+++ cgdconfig.c	9 Nov 2019 16:53:33 -0000
@@ -55,6 +55,7 @@
 #include <sys/disklabel_gpt.h>
 #include <sys/mman.h>
 #include <sys/param.h>
+#include <sys/sysctl.h>
 #include <sys/resource.h>
 #include <sys/statvfs.h>
 #include <sys/bitops.h>
@@ -125,6 +126,7 @@
 static int	 verify_reenter(struct params *);
 static int	 verify_mbr(int);
 static int	 verify_gpt(int);
+static int	 verify_attached(const char * opath);
 
 __dead static void	 usage(void);
 
@@ -481,9 +483,17 @@
 		usage();
 
 	/* if called from do_all(), then ensure that 2 or 3 args exist */
-	if (flags == CONFIG_FLAGS_FROMALL && (argc < 2 || argc > 3))
+	/* if called from do_all(), then ensure device is configured */
+        if (flags == CONFIG_FLAGS_FROMALL) {
+		if (argc < 2 || argc > 3)
 		return -1;
 
+		if (! verify_attached(argv[0]) ) {
+			VPRINTF(1, ("skipping %s: device is not configured\n", argv[0]));
+			return 0;
+		}
+	}
+
 	fd = opendisk1(*argv, O_RDWR, buf, sizeof(buf), 1, prog_open);
 	if (fd == -1) {
 		int saved_errno = errno;
@@ -540,6 +550,12 @@
 		return -1;
 	}
 
+	/* if called from do_all, then ignore if device is not attached */
+	if ( (flags == CONFIG_FLAGS_FROMALL) && (! verify_attached(argv[1])) ) {
+		VPRINTF(1, ("skipping %s: device is not attached\n", argv[1]));
+		return 0;
+	}
+
 	if ((
 	  fd = opendisk1(*argv, O_RDWR, cgdname, sizeof(cgdname), 1, prog_open)
 	    ) != -1) {
@@ -1282,3 +1298,89 @@
 	if (setrlimit(RLIMIT_CORE, &rlp) == -1)
 		err(EXIT_FAILURE, "Can't disable cores");
 }
+
+static int 
+verify_attached(const char * opath)
+/* check if opath backing device is attached  */
+/* returns 1 if backing device is attached       */
+/* otherwise return 0 */
+{
+	const int mib[2] = { CTL_HW, HW_DISKNAMES };
+	char * p = NULL;
+	char * tok = NULL;
+	char * path = NULL;
+	char * b = NULL;
+	size_t len;
+	int ch;
+	int attachedp;
+	int max,pmax;
+
+	attachedp = 0;
+
+	if (opath == NULL) {
+		return 0;
+	}
+
+	path = (char *)strdup(opath);
+
+	if (path == NULL) {
+		perror("strdup");
+		goto verify_attached_done;
+	}
+
+	if ((b = strrchr(path, '/')) != NULL) {
+		b++;
+	} else {
+		b = path;
+	}
+
+	max = getmaxpartitions();
+
+	if (max == -1) {
+		perror("getmaxpartitions");
+		return 0;
+	}
+
+	pmax = 'a' + max;
+
+	ch = b[strlen(b) - 1];
+
+	/* if suffixed with parition ident, truncate */
+	if ( (ch >= 'a') && (ch <= pmax) ) {
+		b[strlen(b) - 1] = 0;
+	}
+
+	/* get attached disk devices length */
+	if (sysctl(mib, 2, NULL, &len, NULL, 0) == -1) {
+		perror("sysctl");
+		goto verify_attached_done;
+	}
+
+	p = (char *)calloc(len, sizeof(char));
+
+	if (p == NULL) {
+		perror("calloc");
+		goto verify_attached_done;
+	}
+
+	/* get attached disk devices */
+	if (sysctl(mib, 2, p, &len, NULL, 0) == -1) {
+		perror("sysctl");
+		goto verify_attached_done;	
+	}	
+
+	/* iterate over device list for match */
+	while ((tok = strsep(&p, " ")) != NULL) {
+		if (strcmp(tok, b) == 0) {
+			attachedp = 1;
+			break;
+		}	
+	}
+
+verify_attached_done:
+
+	free(p);
+	free(path);
+
+	return attachedp;
+}


Home | Main Index | Thread Index | Old Index