Index: cgdconfig.8
===================================================================
RCS file: /cvsroot/src/sbin/cgdconfig/cgdconfig.8,v
retrieving revision 1.44
diff -B -b -u -r1.44 cgdconfig.8
--- cgdconfig.8	29 Dec 2018 18:34:01 -0000	1.44
+++ cgdconfig.8	11 Nov 2019 15:28:18 -0000
@@ -41,7 +41,7 @@
 .Op Ar paramsfile
 .Nm
 .Fl C
-.Op Fl enpv
+.Op Fl enpvj
 .Op Fl f Ar configfile
 .Nm
 .Fl G
@@ -89,6 +89,9 @@
 .Bl -tag -width configfilexxxx
 .It Fl C
 Configure all the devices listed in the cgd configuration file.
+.It Fl j
+When used with -C, gracefully skip cgd device configuration if
+the backing device is detached.
 .It Fl e
 Echo the passphrase.
 .It Fl f Ar configfile
Index: cgdconfig.c
===================================================================
RCS file: /cvsroot/src/sbin/cgdconfig/cgdconfig.c,v
retrieving revision 1.50
diff -B -b -u -r1.50 cgdconfig.c
--- cgdconfig.c	10 Apr 2019 06:11:37 -0000	1.50
+++ cgdconfig.c	11 Nov 2019 15:28:18 -0000
@@ -95,6 +95,11 @@
 #define	PFLAG_STDIN		0x04
 int	pflag = PFLAG_GETPASS;
 
+/* if jflag is set, do_all configure ignores lines */
+/* with detached backing devices */
+
+int	jflag = 0;
+
 static int	configure(int, char **, struct params *, int);
 static int	configure_stdin(struct params *, int argc, char **);
 static int	generate(struct params *, int, char **, const char *);
@@ -125,6 +130,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);
 
@@ -203,7 +209,7 @@
 	p = params_new();
 	kg = NULL;
 
-	while ((ch = getopt(argc, argv, "CGUV:b:ef:gi:k:lno:spuv")) != -1)
+	while ((ch = getopt(argc, argv, "CGUV:b:ef:gi:k:lno:spuvj")) != -1)
 		switch (ch) {
 		case 'C':
 			set_action(&action, ACTION_CONFIGALL);
@@ -232,6 +238,9 @@
 				p = params_combine(p, tp);
 			}
 			break;
+		case 'j':
+			jflag = 1;
+			break;
 		case 'e':
 			pflag = PFLAG_GETPASS_ECHO;
 			break;
@@ -589,6 +598,18 @@
 		return -1;
 	}
 
+	/* if called from do_all, then ignore if device is not attached */
+	if (jflag && (flags == CONFIG_FLAGS_FROMALL)) {
+		ret = verify_attached(dev);
+
+		/* device unattached */
+		if (ret == 0) {
+			VPRINTF(1, ("skipping %s: device is not attached\n", dev));
+			return 0;
+		}
+		/* pass-through success and errors */
+	}
+
 	/*
 	 * loop over configuring the disk and checking to see if it
 	 * verifies properly.  We open and close the disk device each
@@ -1282,3 +1303,19 @@
 	if (setrlimit(RLIMIT_CORE, &rlp) == -1)
 		err(EXIT_FAILURE, "Can't disable cores");
 }
+
+static int 
+verify_attached(const char * opath)
+{
+	int fd;
+
+	if ((fd = open(opath,O_RDWR)) == -1) {
+		if (errno == ENXIO) {
+			return 0;
+		}
+		return -1;
+	}
+	close(fd);
+
+	return 1;
+}