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;
+}

Reply via email to