diff --git a/share/man/man9/disk.9 b/share/man/man9/disk.9 index c0eb2e5381d7..e65dc889b50e 100644 --- a/share/man/man9/disk.9 +++ b/share/man/man9/disk.9 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 30, 2012 +.Dd August 3, 2017 .Dt DISK 9 .Os .Sh NAME @@ -45,6 +45,8 @@ .Fn disk_destroy "struct disk *disk" .Ft int .Fn disk_resize "struct disk *disk" "int flags" +.Ft void +.Fn disk_add_alias "struct disk *disk" "const char *alias" .Sh DESCRIPTION The disk storage API permits kernel device drivers providing access to disk-like storage devices to advertise the device to other kernel @@ -69,6 +71,20 @@ function, fill in the fields and call .Fn disk_create when the device is ready to service requests. +.Fn disk_add_alias +adds an alias for the disk and must be called before +.Fn disk_create , +but may be called multiple times. +For each alias added, a device node will be created with +.Xr make_dev_alias 9 +in the same way primary device nodes are created with +.Xr make_dev 9 +for +.Va d_name +and +.Va d_unit . +Care should be taken to ensure that only one driver creates aliases +for any given name. .Fn disk_resize can be called by the driver after modifying .Va d_mediasize @@ -227,7 +243,13 @@ structure for this disk device. .El .Sh SEE ALSO .Xr GEOM 4 , -.Xr devfs 5 +.Xr devfs 5 , +.Xr MAKE_DEV 9 .Sh AUTHORS This manual page was written by .An Robert Watson . +.Sh BUGS +Disk aliases are not a general purpose aliasing mechanism, but are +intended only to ease the transition from one name to another. +They can be used to ensure that nvd0 and nda0 are the same thing. +They cannot be used to implement the diskX concept from macOS. diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c index 8dfe99b53c29..7a3567755678 100644 --- a/sys/geom/geom_disk.c +++ b/sys/geom/geom_disk.c @@ -676,6 +676,7 @@ g_disk_create(void *arg, int flag) struct g_provider *pp; struct disk *dp; struct g_disk_softc *sc; + struct disk_alias *dap; char tmpstr[80]; if (flag == EV_CANCEL) @@ -704,6 +705,10 @@ g_disk_create(void *arg, int flag) sc->dp = dp; gp = g_new_geomf(&g_disk_class, "%s%d", dp->d_name, dp->d_unit); gp->softc = sc; + LIST_FOREACH(dap, &dp->d_aliases, da_next) { + snprintf(tmpstr, sizeof(tmpstr), "%s%d", dap->da_alias, dp->d_unit); + g_geom_add_alias(gp, tmpstr); + } pp = g_new_providerf(gp, "%s", gp->name); devstat_remove_entry(pp->stat); pp->stat = NULL; @@ -791,6 +796,7 @@ g_disk_destroy(void *ptr, int flag) struct disk *dp; struct g_geom *gp; struct g_disk_softc *sc; + struct disk_alias *dap, *daptmp; g_topology_assert(); dp = ptr; @@ -802,6 +808,8 @@ g_disk_destroy(void *ptr, int flag) dp->d_geom = NULL; g_wither_geom(gp, ENXIO); } + LIST_FOREACH_SAFE(dap, &dp->d_aliases, da_next, daptmp) + g_free(dap); g_free(dp); } @@ -834,8 +842,11 @@ g_disk_ident_adjust(char *ident, size_t size) struct disk * disk_alloc(void) { + struct disk *dp; - return (g_malloc(sizeof(struct disk), M_WAITOK | M_ZERO)); + dp = g_malloc(sizeof(struct disk), M_WAITOK | M_ZERO); + LIST_INIT(&dp->d_aliases); + return (dp); } void @@ -884,6 +895,18 @@ disk_destroy(struct disk *dp) g_post_event(g_disk_destroy, dp, M_WAITOK, NULL); } +void +disk_add_alias(struct disk *dp, const char *name) +{ + struct disk_alias *dap; + + dap = (struct disk_alias *)g_malloc( + sizeof(struct disk_alias) + strlen(name) + 1, M_WAITOK); + strcpy((char *)(dap + 1), name); + dap->da_alias = (const char *)(dap + 1); + LIST_INSERT_HEAD(&dp->d_aliases, dap, da_next); +} + void disk_gone(struct disk *dp) { diff --git a/sys/geom/geom_disk.h b/sys/geom/geom_disk.h index 642a51296051..bffb27ef6cb4 100644 --- a/sys/geom/geom_disk.h +++ b/sys/geom/geom_disk.h @@ -66,6 +66,11 @@ typedef enum { DISK_INIT_DONE } disk_init_level; +struct disk_alias { + LIST_ENTRY(disk_alias) da_next; + const char *da_alias; +}; + struct disk { /* Fields which are private to geom_disk */ struct g_geom *d_geom; @@ -109,6 +114,9 @@ struct disk { /* Fields private to the driver */ void *d_drv1; + + /* Fields private to geom_disk, to be moved on next version bump */ + LIST_HEAD(,disk_alias) d_aliases; }; #define DISKFLAG_RESERVED 0x1 /* Was NEEDSGIANT */ @@ -132,6 +140,7 @@ void disk_attr_changed(struct disk *dp, const char *attr, int flag); void disk_media_changed(struct disk *dp, int flag); void disk_media_gone(struct disk *dp, int flag); int disk_resize(struct disk *dp, int flag); +void disk_add_alias(struct disk *disk, const char *); #define DISK_VERSION_00 0x58561059 #define DISK_VERSION_01 0x5856105a