Print this page
4833 Remove volrmmount
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.


  25  */
  26 
  27 /*
  28  * rmf_misc.c :
  29  *      Miscelleneous routines for rmformat.
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <stdio.h>
  34 #include <sys/mnttab.h>
  35 #include <volmgt.h>
  36 #include <sys/dkio.h>
  37 #include <sys/fdio.h>
  38 #include <sys/vtoc.h>
  39 #include <sys/termios.h>
  40 #include <sys/mount.h>
  41 #include <ctype.h>
  42 #include <signal.h>
  43 #include <sys/wait.h>
  44 #include <dirent.h>


  70 static struct   uscsi_cmd uscmd;
  71 static char     ucdb[16];
  72 uchar_t         uscsi_status, rqstatus, rqresid;
  73 int             total_devices_found = 0;
  74 int             removable_found = 0;
  75 
  76 extern char     *global_intr_msg;
  77 extern int      vol_running;
  78 extern char     *dev_name;
  79 extern int32_t  m_flag;
  80 
  81 /*
  82  * ON-private functions from libvolmgt
  83  */
  84 int     _dev_mounted(char *path);
  85 
  86 /*
  87  * Function prototypes.
  88  */
  89 static int              my_umount(char *mountp);
  90 static int              my_volrmmount(char *real_name);
  91 static int              vol_name_to_dev_node(char *vname, char *found);
  92 static int              vol_lookup(char *supplied, char *found);
  93 static device_t         *get_device(char *user_supplied, char *node);
  94 static char             *get_physical_name(char *path);
  95 static int              lookup_device(char *supplied, char *found);
  96 static void             fini_device(device_t *dev);
  97 static int              is_cd(char *node);
  98 void                    *my_zalloc(size_t size);
  99 void                    err_msg(char *fmt, ...);
 100 int                     inquiry(int fd, uchar_t *inq);
 101 struct uscsi_cmd        *get_uscsi_cmd(void);
 102 int                     uscsi(int fd, struct uscsi_cmd *scmd);
 103 int                     get_mode_page(int fd, int page_no, int pc, int buf_len,
 104                             uchar_t *buffer);
 105 int                     mode_sense(int fd, uchar_t pc, int dbd, int page_len,
 106                             uchar_t *buffer);
 107 uint16_t                read_scsi16(void *addr);
 108 int                     check_device(device_t *dev, int cond);
 109 static void             get_media_info(device_t *t_dev, char *sdev,
 110                             char *pname, char *sn);


 244         if ((nm = volmgt_symname(device_name)) == NULL) {
 245                 DPRINTF("path not managed\n");
 246                 real_name = media_findname(device_name);
 247         } else {
 248                 DPRINTF1("path managed as %s\n", nm);
 249                 real_name = media_findname(nm);
 250                 DPRINTF1("real name %s\n", real_name);
 251         }
 252 
 253         if (real_name == NULL)
 254                 return (-1);
 255 
 256         /*
 257          * To find out whether the device has been mounted by
 258          * volume manager...
 259          *
 260          * Convert the real name to a block device address.
 261          * Do a partial match with the mnttab entries.
 262          * Make sure the match is in the beginning to avoid if
 263          * anybody puts a label similiar to volume manager path names.
 264          * Then use "volrmmount -e <dev_name>" if -U flag is set.
 265          */
 266 
 267         nl = strlen("/vol/dev/");
 268 
 269         if (strncmp(real_name, "/vol/dev/", nl) != 0)
 270                         return (0);
 271         if (real_name[nl] == 'r') {
 272                 (void) snprintf(tmp_path_name, PATH_MAX, "%s%s", "/vol/dev/",
 273                     &real_name[nl + 1]);
 274         } else {
 275                 (void) snprintf(tmp_path_name, PATH_MAX, "%s", real_name);
 276         }
 277         DPRINTF1("%s \n", tmp_path_name);
 278         ret_val = stat(tmp_path_name, &stat_buf);
 279         if (ret_val < 0) {
 280                 PERROR("Could not stat");
 281                 return (-1);
 282         }
 283 
 284         fp = fopen("/etc/mnttab", "r");


 299                 if (errno != 0) {
 300                         PERROR("Error with mnttab");
 301                         (void) fclose(fp);
 302                         return (-1);
 303                 }
 304                 /* Is it a probable entry? */
 305                 DPRINTF1(" %s \n", mntp->mnt_special);
 306                 if (strstr(mntp->mnt_special, tmp_path_name) !=
 307                     mntp->mnt_special) {
 308                         /* Skip to next entry */
 309                         continue;
 310                 } else {
 311                         DPRINTF1("Found!! %s\n", mntp->mnt_special);
 312                         ret_val = 1;
 313                         break;
 314                 }
 315         }
 316 
 317         if (ret_val == 1) {
 318                 if (flag) {
 319                         if (my_volrmmount(real_name) < 0) {
 320                                 ret_val = -1;
 321                         }
 322                 } else {
 323                         ret_val = -1;
 324                 }
 325         }
 326         (void) fclose(fp);
 327         free(mntp);
 328         return (ret_val);
 329 }
 330 
 331 /*
 332  * This routine checks if a device has mounted partitions. The
 333  * device name is assumed to be /dev/rdsk/cNtNdNsN. So, this can
 334  * be used for SCSI and PCMCIA cards.
 335  * Returns
 336  *       0 : if not mounted
 337  *       1 : if successfully unmounted
 338  *      -1 : Any error or umount failed
 339  */


1051                         /* Turn off the privileges */
1052                         (void) __priv_bracket(PRIV_OFF);
1053                         exit(-1);
1054                 }
1055         }
1056 
1057         /* wait for the umount command to exit */
1058         rval = 0;
1059         if (waitpid(pid, &rval, 0) == pid) {
1060                 if (WIFEXITED(rval)) {
1061                         if (WEXITSTATUS(rval) == 0) {
1062                                 DPRINTF("umount : Success\n");
1063                                 return (1);
1064                         }
1065                 }
1066         }
1067         return (-1);
1068 }
1069 
1070 static int
1071 my_volrmmount(char *real_name)
1072 {
1073         int pid, rval;
1074 
1075         /* Turn on the privileges. */
1076         (void) __priv_bracket(PRIV_ON);
1077 
1078         pid = fork();
1079 
1080         /* Turn off the privileges. */
1081         (void) __priv_bracket(PRIV_OFF);
1082 
1083         /* create a child to unmount the path */
1084         if (pid < 0) {
1085                 PERROR("fork failed");
1086                 exit(0);
1087         }
1088 
1089         if (pid == 0) {
1090                 /* the child */
1091                 /* get rid of those nasty err messages */
1092                 DPRINTF1("call_unmount_prog: calling %s \n",
1093                     "/usr/bin/volrmmount");
1094 
1095                 /* Turn on the privileges. */
1096                 (void) __priv_bracket(PRIV_ON);
1097                 if (execl("/usr/bin/volrmmount", "/usr/bin/volrmmount", "-e",
1098                     real_name, NULL) < 0) {
1099                         PERROR("volrmmount exec failed");
1100                         /* Turn off the privileges */
1101                         (void) __priv_bracket(PRIV_OFF);
1102                         exit(-1);
1103                 }
1104         } else if (waitpid(pid, &rval, 0) == pid) {
1105                 if (WIFEXITED(rval)) {
1106                         if (WEXITSTATUS(rval) == 0) {
1107                                 DPRINTF("volrmmount: Success\n");
1108                                 return (1);
1109                         }
1110                 }
1111         }
1112         return (-1);
1113 }
1114 
1115 int
1116 find_device(int defer, char *tmpstr)
1117 {
1118         DIR *dir;
1119         struct dirent *dirent;
1120         char sdev[PATH_MAX], dev[PATH_MAX], *pname;
1121         device_t *t_dev;
1122         int removable = 0;
1123         int device_type = 0;
1124         int hotpluggable = 0;
1125         struct dk_minfo mediainfo;
1126         static int found = 0;
1127 


1143 #else /* x86 */
1144                 if (vol_running) {
1145                         if (!(strstr(sdev, "s2") || strstr(sdev, "p0"))) {
1146                                 continue;
1147                         }
1148                 } else {
1149                         if (!strstr(sdev, "p0")) {
1150                                 continue;
1151                         }
1152                 }
1153 #endif
1154                 if (!lookup_device(sdev, dev)) {
1155                         continue;
1156                 }
1157                 if ((t_dev = get_device(NULL, dev)) == NULL) {
1158                         continue;
1159                 }
1160                 total_devices_found++;
1161 
1162                 if ((!defer) && !found) {
1163                         char *sn, *tmpbuf;
1164                         /*
1165                          * dev_name is an optional command line input.
1166                          */
1167                         if (dev_name) {
1168                                 if (strstr(dirent->d_name, tmpstr)) {
1169                                         found = 1;
1170                                 } else if (!vol_running) {
1171                                         continue;
1172                                 }
1173                         }
1174                         /*
1175                          * volmgt_symname() returns NULL if the device
1176                          * is not managed by volmgt.
1177                          */
1178                         sn = volmgt_symname(sdev);
1179 
1180                         if (vol_running && (sn != NULL)) {
1181                                 if (strstr(sn, "dev") == NULL) {
1182                                         tmpbuf = (char *)my_zalloc(PATH_MAX);
1183                                         (void) strcpy(tmpbuf,


   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  *
  21  *

  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  *
  25  * Copyright 2014 Andrew Stormont.
  26  */
  27 
  28 /*
  29  * rmf_misc.c :
  30  *      Miscelleneous routines for rmformat.
  31  */
  32 
  33 #include <sys/types.h>
  34 #include <stdio.h>
  35 #include <sys/mnttab.h>
  36 #include <volmgt.h>
  37 #include <sys/dkio.h>
  38 #include <sys/fdio.h>
  39 #include <sys/vtoc.h>
  40 #include <sys/termios.h>
  41 #include <sys/mount.h>
  42 #include <ctype.h>
  43 #include <signal.h>
  44 #include <sys/wait.h>
  45 #include <dirent.h>


  71 static struct   uscsi_cmd uscmd;
  72 static char     ucdb[16];
  73 uchar_t         uscsi_status, rqstatus, rqresid;
  74 int             total_devices_found = 0;
  75 int             removable_found = 0;
  76 
  77 extern char     *global_intr_msg;
  78 extern int      vol_running;
  79 extern char     *dev_name;
  80 extern int32_t  m_flag;
  81 
  82 /*
  83  * ON-private functions from libvolmgt
  84  */
  85 int     _dev_mounted(char *path);
  86 
  87 /*
  88  * Function prototypes.
  89  */
  90 static int              my_umount(char *mountp);
  91 static int              my_rmmount(char *real_name);
  92 static int              vol_name_to_dev_node(char *vname, char *found);
  93 static int              vol_lookup(char *supplied, char *found);
  94 static device_t         *get_device(char *user_supplied, char *node);
  95 static char             *get_physical_name(char *path);
  96 static int              lookup_device(char *supplied, char *found);
  97 static void             fini_device(device_t *dev);
  98 static int              is_cd(char *node);
  99 void                    *my_zalloc(size_t size);
 100 void                    err_msg(char *fmt, ...);
 101 int                     inquiry(int fd, uchar_t *inq);
 102 struct uscsi_cmd        *get_uscsi_cmd(void);
 103 int                     uscsi(int fd, struct uscsi_cmd *scmd);
 104 int                     get_mode_page(int fd, int page_no, int pc, int buf_len,
 105                             uchar_t *buffer);
 106 int                     mode_sense(int fd, uchar_t pc, int dbd, int page_len,
 107                             uchar_t *buffer);
 108 uint16_t                read_scsi16(void *addr);
 109 int                     check_device(device_t *dev, int cond);
 110 static void             get_media_info(device_t *t_dev, char *sdev,
 111                             char *pname, char *sn);


 245         if ((nm = volmgt_symname(device_name)) == NULL) {
 246                 DPRINTF("path not managed\n");
 247                 real_name = media_findname(device_name);
 248         } else {
 249                 DPRINTF1("path managed as %s\n", nm);
 250                 real_name = media_findname(nm);
 251                 DPRINTF1("real name %s\n", real_name);
 252         }
 253 
 254         if (real_name == NULL)
 255                 return (-1);
 256 
 257         /*
 258          * To find out whether the device has been mounted by
 259          * volume manager...
 260          *
 261          * Convert the real name to a block device address.
 262          * Do a partial match with the mnttab entries.
 263          * Make sure the match is in the beginning to avoid if
 264          * anybody puts a label similiar to volume manager path names.
 265          * Then use "rmmount -u <dev_name>" if -U flag is set.
 266          */
 267 
 268         nl = strlen("/vol/dev/");
 269 
 270         if (strncmp(real_name, "/vol/dev/", nl) != 0)
 271                         return (0);
 272         if (real_name[nl] == 'r') {
 273                 (void) snprintf(tmp_path_name, PATH_MAX, "%s%s", "/vol/dev/",
 274                     &real_name[nl + 1]);
 275         } else {
 276                 (void) snprintf(tmp_path_name, PATH_MAX, "%s", real_name);
 277         }
 278         DPRINTF1("%s \n", tmp_path_name);
 279         ret_val = stat(tmp_path_name, &stat_buf);
 280         if (ret_val < 0) {
 281                 PERROR("Could not stat");
 282                 return (-1);
 283         }
 284 
 285         fp = fopen("/etc/mnttab", "r");


 300                 if (errno != 0) {
 301                         PERROR("Error with mnttab");
 302                         (void) fclose(fp);
 303                         return (-1);
 304                 }
 305                 /* Is it a probable entry? */
 306                 DPRINTF1(" %s \n", mntp->mnt_special);
 307                 if (strstr(mntp->mnt_special, tmp_path_name) !=
 308                     mntp->mnt_special) {
 309                         /* Skip to next entry */
 310                         continue;
 311                 } else {
 312                         DPRINTF1("Found!! %s\n", mntp->mnt_special);
 313                         ret_val = 1;
 314                         break;
 315                 }
 316         }
 317 
 318         if (ret_val == 1) {
 319                 if (flag) {
 320                         if (my_rmmount(real_name) < 0) {
 321                                 ret_val = -1;
 322                         }
 323                 } else {
 324                         ret_val = -1;
 325                 }
 326         }
 327         (void) fclose(fp);
 328         free(mntp);
 329         return (ret_val);
 330 }
 331 
 332 /*
 333  * This routine checks if a device has mounted partitions. The
 334  * device name is assumed to be /dev/rdsk/cNtNdNsN. So, this can
 335  * be used for SCSI and PCMCIA cards.
 336  * Returns
 337  *       0 : if not mounted
 338  *       1 : if successfully unmounted
 339  *      -1 : Any error or umount failed
 340  */


1052                         /* Turn off the privileges */
1053                         (void) __priv_bracket(PRIV_OFF);
1054                         exit(-1);
1055                 }
1056         }
1057 
1058         /* wait for the umount command to exit */
1059         rval = 0;
1060         if (waitpid(pid, &rval, 0) == pid) {
1061                 if (WIFEXITED(rval)) {
1062                         if (WEXITSTATUS(rval) == 0) {
1063                                 DPRINTF("umount : Success\n");
1064                                 return (1);
1065                         }
1066                 }
1067         }
1068         return (-1);
1069 }
1070 
1071 static int
1072 my_rmmount(char *real_name)
1073 {
1074         int pid, rval;
1075 
1076         /* Turn on the privileges. */
1077         (void) __priv_bracket(PRIV_ON);
1078 
1079         pid = fork();
1080 
1081         /* Turn off the privileges. */
1082         (void) __priv_bracket(PRIV_OFF);
1083 
1084         /* create a child to unmount the path */
1085         if (pid < 0) {
1086                 PERROR("fork failed");
1087                 exit(0);
1088         }
1089 
1090         if (pid == 0) {
1091                 /* the child */
1092                 /* get rid of those nasty err messages */
1093                 DPRINTF1("call_unmount_prog: calling %s\n",
1094                     "/usr/bin/rmmount");
1095 
1096                 /* Turn on the privileges. */
1097                 (void) __priv_bracket(PRIV_ON);
1098                 if (execl("/usr/bin/rmmount", "/usr/bin/rmmount", "-u",
1099                     real_name, NULL) < 0) {
1100                         PERROR("rmmount exec failed");
1101                         /* Turn off the privileges */
1102                         (void) __priv_bracket(PRIV_OFF);
1103                         exit(-1);
1104                 }
1105         } else if (waitpid(pid, &rval, 0) == pid) {
1106                 if (WIFEXITED(rval)) {
1107                         if (WEXITSTATUS(rval) == 0) {
1108                                 DPRINTF("rmmount: Success\n");
1109                                 return (1);
1110                         }
1111                 }
1112         }
1113         return (-1);
1114 }
1115 
1116 int
1117 find_device(int defer, char *tmpstr)
1118 {
1119         DIR *dir;
1120         struct dirent *dirent;
1121         char sdev[PATH_MAX], dev[PATH_MAX], *pname;
1122         device_t *t_dev;
1123         int removable = 0;
1124         int device_type = 0;
1125         int hotpluggable = 0;
1126         struct dk_minfo mediainfo;
1127         static int found = 0;
1128 


1144 #else /* x86 */
1145                 if (vol_running) {
1146                         if (!(strstr(sdev, "s2") || strstr(sdev, "p0"))) {
1147                                 continue;
1148                         }
1149                 } else {
1150                         if (!strstr(sdev, "p0")) {
1151                                 continue;
1152                         }
1153                 }
1154 #endif
1155                 if (!lookup_device(sdev, dev)) {
1156                         continue;
1157                 }
1158                 if ((t_dev = get_device(NULL, dev)) == NULL) {
1159                         continue;
1160                 }
1161                 total_devices_found++;
1162 
1163                 if ((!defer) && !found) {
1164                         char *sn, *tmpbuf = NULL;
1165                         /*
1166                          * dev_name is an optional command line input.
1167                          */
1168                         if (dev_name) {
1169                                 if (strstr(dirent->d_name, tmpstr)) {
1170                                         found = 1;
1171                                 } else if (!vol_running) {
1172                                         continue;
1173                                 }
1174                         }
1175                         /*
1176                          * volmgt_symname() returns NULL if the device
1177                          * is not managed by volmgt.
1178                          */
1179                         sn = volmgt_symname(sdev);
1180 
1181                         if (vol_running && (sn != NULL)) {
1182                                 if (strstr(sn, "dev") == NULL) {
1183                                         tmpbuf = (char *)my_zalloc(PATH_MAX);
1184                                         (void) strcpy(tmpbuf,