Just like on amd64 with vmctl(8), I want to be able to easily create
disk images.

ldomctl(8) currently advises to use dd(1), those files are not sparse
either so creating big images may take a lot of time and the process
tends to be error prone.

`ldomctl create-vdisk -s size file' behaves like
`vmctl create -s size file' except that size is parsed by scan_scaled(3)
and not assumed to be megabytes, e.g.

        $ ldomctl create-vdisk -s 8G ~/guest01.img
        t4-2$ ./obj/ldomctl create-vdisk -s 8G ~/guest01.img
        t4-2$ ls -l ~/guest01.img
        -rw-------  1 kn  kn  8589934592 Nov 30 01:42 /home/kn/guest01.img
        t4-2$ du ~/guest01.img
        96   /home/kn/guest01.img  

Feedback? OK?


Index: ldom.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/ldomctl/ldom.conf.5,v
retrieving revision 1.7
diff -u -p -r1.7 ldom.conf.5
--- ldom.conf.5 28 Nov 2019 18:40:42 -0000      1.7
+++ ldom.conf.5 29 Nov 2019 23:56:07 -0000
@@ -59,8 +59,9 @@ for a list of OpenPROM variables.
 The specified file is used to back a virtual disk of the guest
 domain.
 .Ar file
-can be a block device node or a disk image file created with
-.Xr dd 1 .
+can be a block device node or a disk image file created with the
+.Cm create-vdisk
+command.
 This keyword can be used multiple times.
 .It Ic vnet Op Brq Ar keyword Ns = Ns Ar value ...
 Assign a
Index: ldomctl.8
===================================================================
RCS file: /cvs/src/usr.sbin/ldomctl/ldomctl.8,v
retrieving revision 1.18
diff -u -p -r1.18 ldomctl.8
--- ldomctl.8   28 Nov 2019 18:03:33 -0000      1.18
+++ ldomctl.8   29 Nov 2019 23:47:01 -0000
@@ -34,6 +34,16 @@ information about domains running on the
 .Pp
 The following commands are available:
 .Bl -tag -width Ds
+.It Cm create-vdisk Fl s Ar size Ar file
+Create a virtual disk image with the specified
+.Ar file
+path and
+.Ar size ,
+in bytes.
+.Ar size
+can be specified with a human-readable scale, using the format described in
+.Xr scan_scaled 3 ,
+e.g. 512M.
 .It Cm console Ar domain
 Using
 .Xr cu 1
@@ -119,8 +129,8 @@ openbsd [next]
 .Pp
 Create a virtual disk image for each guest domain:
 .Bd -literal -offset indent
-# dd if=/dev/zero of=/home/puffy/vdisk0 bs=1m count=8192
-# dd if=/dev/zero of=/home/salmah/vdisk0 bs=1m count=8192
+# ldomctl create-vdisk -s 8G /home/puffy/vdisk0
+# ldomctl create-vdisk -s 8G /home/salmah/vdisk0
 .Ed
 .Pp
 The minirootfs install media can be used to boot guest domains:
Index: ldomctl.c
===================================================================
RCS file: /cvs/src/usr.sbin/ldomctl/ldomctl.c,v
retrieving revision 1.27
diff -u -p -r1.27 ldomctl.c
--- ldomctl.c   28 Nov 2019 18:40:42 -0000      1.27
+++ ldomctl.c   30 Nov 2019 00:40:49 -0000
@@ -18,12 +18,15 @@
 
 #include <sys/types.h>
 #include <sys/ioctl.h>
+#include <sys/stat.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <util.h>
 
 #include "ds.h"
 #include "hvctl.h"
@@ -53,6 +56,7 @@ void list(int argc, char **argv);
 void list_io(int argc, char **argv);
 void xselect(int argc, char **argv);
 void delete(int argc, char **argv);
+void create_vdisk(int argc, char **argv);
 void guest_start(int argc, char **argv);
 void guest_stop(int argc, char **argv);
 void guest_panic(int argc, char **argv);
@@ -67,6 +71,7 @@ struct command commands[] = {
        { "list-io",    list_io },
        { "select",     xselect },
        { "delete",     delete },
+       { "create-vdisk", create_vdisk },
        { "start",      guest_start },
        { "stop",       guest_stop },
        { "panic",      guest_panic },
@@ -117,6 +122,9 @@ main(int argc, char **argv)
        if (cmdp->cmd_name == NULL)
                usage();
 
+       if (strcmp(argv[0], "create-vdisk") == 0)
+               goto skip_hv;
+
        hv_open();
 
        /*
@@ -153,6 +161,7 @@ main(int argc, char **argv)
                        add_guest(prop->d.arc.node);
        }
 
+skip_hv:
        (cmdp->cmd_func)(argc, argv);
 
        exit(EXIT_SUCCESS);
@@ -165,6 +174,7 @@ usage(void)
            "\t%1$s download directory\n"
            "\t%1$s dump|list|list-io\n"
            "\t%1$s init-system file\n"
+           "\t%1$s create-vdisk -s size file\n"
            "\t%1$s console|panic|start|status|stop [domain]\n", getprogname());
        exit(EXIT_FAILURE);
 }
@@ -347,6 +357,48 @@ delete(int argc, char **argv)
                ds_conn_handle(dc);
 
        mdstore_delete(dc, argv[1]);
+}
+
+void
+create_vdisk(int argc, char **argv)
+{
+       int ch, fd, save_errno;
+       long long imgsize;
+       const char *imgfile_path;
+
+       while ((ch = getopt(argc, argv, "s:")) != -1) {
+               switch (ch) {
+               case 's':
+                       if (scan_scaled(optarg, &imgsize) == -1)
+                               err(1, "invalid size: %s", optarg);
+                       break;
+               default:
+                       usage();
+               }
+       }
+       argc -= optind;
+       argv += optind;
+
+       if (argc != 1)
+               usage();
+
+       imgfile_path = argv[0];
+
+       /* Refuse to overwrite an existing image */
+       if ((fd = open(imgfile_path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
+           S_IRUSR | S_IWUSR)) == -1)
+               err(1, "ftruncate");
+
+       /* Extend to desired size */
+       if (ftruncate(fd, (off_t)imgsize) == -1) {
+               save_errno = errno;
+               close(fd);
+               unlink(imgfile_path);
+               errno = save_errno;
+               err(1, "ftruncate");
+       }
+
+       close(fd);
 }
 
 void

Reply via email to