.title MOUNTDEV Mount a disk systemwide .ident /V2.03B/ .sbttl Documentation ; ; This procedure recives a device name, then mounts the disk ; systemwide. If the disk is Files-11 1, or foreign, the disk ; is mounted /NOWRITE if available to the cluster. ; ; Calling format: ; ; STATUS=MOUNTDEV('devname') ; ; Requires LOG_IO, PHY_IO, SYSPRV, SYSNAM, VOLPRO to run ; ; Eric F. Richards ; 05-Mar-86 ; Gould OSD VAXcluster VMS V4.3 ; ; Note to the reader and potential hacker: ; Be VERY careful about changing the order of things in here, ; or putting in new features. All local variables are maintained ; on the stack, and some of them have multiple meanings. If this ; warning does not keep you out of the source... you're on your own. ; .sbttl Macros and other definitions .page .disable traceback, debug ; hands off w/ the debugger .library /sys$library:lib/ ; use alternate macro library $dcdef ; define device class codes $devdef ; define devchar flags $iodef ; define I/O function codes $hm1def ; define Files-11 1 Homeblock codes $hm2def ; define Files-11 2 Homeblock codes $ssdef ; define system service status codes $mntdef ; define mount item-list codes $dvidef ; define $GETDVI item codes dsknam = 4 ; AP offset for disk name numargs = 1 ; number of arguments needed .macro clrsp space, fill=#0 ; macro for clearing space subl space, sp ; on stack for a data area. movc5 #0, (sp), fill, - ; data area is init'd to space, (sp) ; nulls by this macro .endm clrsp ; that's it! ; ; The following assumtions must be true for this program to work ; assume hm2$s_format eq hm1$s_format assume hm2$t_format eq hm1$t_format assume hm2$s_volname eq hm1$s_volname2 assume hm2$t_volname eq hm1$t_volname2 assume hm2$c_level2 ge hm1$c_level1 ; .sbttl Main Code .page .psect $code, exe, long, nowrt, pic, shr .entry MOUNTDEV, ^m cmpb #numargs, (ap) ; do we have enough arguments? bleq 40$ ; if so, skip this movzwl #ss$_insfarg, r0 ; set return error status 30$: ret ; exit with that status 40$: clrl -(sp) ; clear a spot for the channel movl sp, r11 ; save its address clrq -(sp) ; build an I/O status block movl sp, r8 ; save a pointer to it $assign_s chan=(r11), - ; assign a channel to the device devnam=@dsknam(ap) ; here is the device name blbc r0, 30$ ; on error get out ; ; We now have a channel to the device - for cleanup, be sure to ; deassign the channel before returning. ; .sbttl GETDVI lookup on device for characteristics .page ; ; Do a $GETDVI to make sure the volume is online, available, ; available to cluster, and a DISK. These characteristics ; will decide whether we mount, or mount/nowrite the disk. ; If some "unusual" characteristic shows up, return with an error. ; clrl -(sp) ; make room for DVI$_DEVCHAR2 bit field movl sp, r10 ; save a pointer to it clrl -(sp) ; make room for DVI$_DEVCHAR as well movl sp, r3 ; save a pointer to that, too clrl -(sp) ; make room for DEVCLASS code movl sp, r5 ; save a pointer to that clrq -(sp) ; mark end of $GETDVI list pushl r5 ; get addrss of DEVCLASS code loc pushl #!4 ; set request code, size is LONGWORD pushl #0 ; no length needed here pushl r10 ; write the DEVCHAR2 array here pushl #!4 ; set request code, size pushl #0 ; no length needed here pushl r3 ; write the DEVCHAR array here pushl #!4 ; set request code, size movl sp, r0 ; save a pointer to the list $getdviw_s chan=(r11), - ; get the requested information itmlst=(r0), - ; use this item list iosb=(r8) ; write I/O status here blbs r0, 60$ ; on error fubar out movl r0, r6 ; save error status 50$: brw 120$ ; and get outta here 60$: movzwl (r8), r6 ; get error status from I/O SB blbc r6, 50$ ; on error get out movzwl #ss$_ivdevnam, r6 ; assume invalid device cmpl #dc$_disk, (r5) ; is this device a disk bneq 50$ ; return if not movzwl #ss$_devnotdism, r6 ; assume marked for dismount bbs #dev$v_dmt, (r3), 50$ ; go home if so movzwl #ss$_devmount, r6 ; assume mounted bbs #dev$v_mnt, (r3), 50$ ; go home if so movzwl #ss$_devforeign, r6 ; assume mounted foreign bbs #dev$v_for, (r3), 50$ ; go home if so movl r3, sp ; unwind stack, save DEVCHAR, devchar2 .sbttl Make disk drive available and read homeblock .page ; ; execute a PACKACK to the disk. This software enables it so ; that we can read the homeblock before mounting it. The info ; in the homeblock will give us the label, and format for ; determining more MOUNT information. Note that we allow the ; status SS$_ILLIOFUNC to pass through, because some devices ; don't have PACKACK as a valid function code. ; $qiow_s chan=(r11), - ; issue a PACKACK to the disk func= - ; ...to prep it for being mounted #io$_packack!io$m_inherlog, - ; also make sure error isn't logged iosb=(r8) ; error codes go here blbc r0, 70$ ; on error get out movzwl (r8), r0 ; get error code from I/O Status block blbs r0, 80$ ; on no error here skip this ; ; This is in case we get SS$_ILLIOFUNC returned. we ignore that error ; 70$: cmpw #ss$_illiofunc, r0 ; Illegal I/O function? beql 80$ ; if so, it's not a "real" error movl r0, r6 ; else, save error status brb 120$ ; deassign channel and leave 80$: ; ; Now, we have a channel assigned as well as having the volume ; valid bit set. the channel must be deassigned before returning ; from this routine, and the bit must be cleared IF the device ; is not mounted successfully. ; clrsp #hm2$c_level2 ; make room for homeblock movl sp, r9 ; save a pointer to this buffer $qiow_s chan=(r11), - ; read the homeblock func=#io$_readlblk, - ; from the disk iosb=(r8), - ; check IOSB for error codes p1=(r9), - ; p1=address of buffer p2=#hm2$c_level2, - ; p2=size of transfer p3=#1 ; p3=logical block to begin read blbs r0, 90$ ; on error get out movl r0, r6 ; set error code in "save" register brb 100$ ; and keep it there 90$: movzwl (r8), r6 ; get error code from I/O Status block ; ; Now, let's put the drive back the way we found it (or pretty close). ; We have no idea on what assumptions $MOUNT makes, or whether or not ; we will eventually mount the disk successfully, so clear the valid ; bit. THEN, and only then, handle any errors that occurred while the ; channel was assigned. ; 100$: $qiow_s chan=(r11), - ; clear the software valid bit func= - ; ...just in case $MOUNT makes #io$_available!io$m_inherlog, - ; ...lots of assumptions about things iosb=(r8) ; error codes go here blbc r6, 120$ ; if previous error, don't save status blbc r0, 110$ ; on error check our one legal error movzwl (r8), r0 ; get status from IOSB blbs r0, 120$ ; if success, continue ; ; If not a legal I/O function, let the error slide ; 110$: cmpw #ss$_illiofunc, r0 ; Illegal I/O function? beql 120$ ; if so, ignore error movl r0, r6 ; else, save error status 120$: $dassgn_s chan=(r11) ; we can deassign the channel now blbs r6, 130$ ; ...if errors in r6... movl r6, r0 ; move into r0 to return to caller 130$: blbs r0, 140$ ; if no error in r0, continue on ret ; get out here if screwed up! 140$: .sbttl Build item list and call MOUNT service .page ; ; Build item list for $MOUNT service. we will always mount the disk ; /SYSTEM. we have to find out if it is native (ODS2), almost ; native (ODS1), or foreign. If it is foreign, we want to MOUNT/FOREIGN ; the disk. We also want to check to make sure that if the volume ; is ODS1 or /FOREIGN and available to a cluster, then we want to ; mount it /NOWRITE ; flags = mnt$m_system!mnt$m_noassist!mnt$m_message ; movl #flags, (r8) ; initial mnt flags in old IOSB ; ; The following two lines turn out to be a NOP -- unfortunately, ; the information is available on the local node, but NOT from ; $GETDVI! ; bbc #dev$v_swl, (r3), 145$ ; write lock the dev if other bisl #mnt$m_nowrite, (r8) ; ...cluster nodes have 145$: cmpc5 s^#ods2len, b^ods2, #^a/ /, - ; is this a Files-11 2... #hm2$s_format, hm2$t_format(r9) ; ...structure volume? beql 160$ ; if so, we're all set! cmpc5 s^#ods1len, b^ods1, #^a/ /, - ; is this a Files-11 1... #hm1$s_format, hm1$t_format(r9) ; ...structure volume? beql 150$ ; if not, skip this: bisl #mnt$m_foreign, (r8) ; set the /FOREIGN switch 150$: bbc #dev$v_clu, (r10), 160$ ; available to cluster? bisl #mnt$m_nowrite, (r8) ; if so, set /NOWRITE switch 160$: movl dsknam(ap), r1 ; descriptor of device name ; ; Build the list, now that we know what we need ; clrq -(sp) ; mark end of mount list pushl 4(r1) ; address of string is here pushl #mnt$_devnam@16 ; this is the device name movw (r1), (sp) ; this is the device length ; ; This gets weird. Here we check if the volume is going to be ; mounted FOREIGN. If it is, we don't set the volume length ; to anything other than the default. If it is ODS1 or ODS2, ; we truncate the volume name so that it doesn't include spaces ; pushl #0 ; don't return a volname length pushal hm2$t_volname(r9) ; here is the volname pushl #!hm2$s_volname ; request code, length bbs #mnt$v_foreign, (r8), 170$ ; skip if this is a foreign dev locc #^a/ /, #hm2$s_volname, @4(sp) ; determine the "real" length beql 170$ ; if none, assume 12 chrs subw r0, (sp) ; set "real" len in item list 170$: pushl #0 ; don't return anything here pushl r8 ; address of the flags is here! pushl #!4 ; this is the flags array movl sp, r0 ; save pointer to the itemlist $mount_s itmlst=(r0) ; mount the disk ret ; ...all done! .sbttl Local Constants .page ;;; .psect $pdata, nowrt, noexe, long, pic, shr .align long ods2: .ascii /DECFILE11B/ ; this is the format for ODS2 ods2len = . - ods2 ; ...structure volumes .align long ods1: .ascii /DECFILE11A/ ; this is the format for ODS1 ods1len = . - ods1 ; ...structure volumes .end ; th-th-that's all, folks!