From: James Mckenzie Date: Sat, 28 Nov 2009 02:47:48 +0000 (+0000) Subject: Fix lazy bits of code in atapi passthrough, disks will be unlocked on vm exit:wq X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=3f1e363dc1f5add9a393a3e6d26945c2f4776e98;p=xenclient%2Fioemu-pq.git Fix lazy bits of code in atapi passthrough, disks will be unlocked on vm exit:wq --- diff --git a/master/atapi-succeed-on-lock-door b/master/atapi-succeed-on-lock-door new file mode 100644 index 0000000..fc2928f --- /dev/null +++ b/master/atapi-succeed-on-lock-door @@ -0,0 +1,18 @@ +diff --git a/hw/atapi-pt.c b/hw/atapi-pt.c +index d810262..3774b8e 100644 +--- a/hw/atapi-pt.c ++++ b/hw/atapi-pt.c +@@ -1213,12 +1213,7 @@ static void ide_atapi_pt_cmd(IDEState *s) + { + case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + // we don't allow locking, to prevent a VM from hogging the drive +- if((s->io_buffer[4] & 1) == 0) // unlock +- ide_atapi_cmd_ok(s); +- else // lock +- ide_atapi_pt_set_error(s, SENSE_ILLEGAL_REQUEST, +- ASC_INV_FIELD_IN_CMD_PACKET, 0, 0x70); +- ++ ide_atapi_cmd_ok(s); + pthread_mutex_unlock(&s->atapi_pt.sgio_mutex); + return; + diff --git a/master/do-atapi-locking-properly b/master/do-atapi-locking-properly new file mode 100644 index 0000000..4cf2a7b --- /dev/null +++ b/master/do-atapi-locking-properly @@ -0,0 +1,162 @@ +diff --git a/hw/atapi-pt.c b/hw/atapi-pt.c +index 09cf6bb..f0b71ca 100644 +--- a/hw/atapi-pt.c ++++ b/hw/atapi-pt.c +@@ -29,7 +29,6 @@ static int debug_enabled=-1; + #define IDE_ATAPI_PT_DEBUG_ENABLE_FILE "/etc/debugcdrom" + #define IDE_ATAPI_PT_NEW_CD_FILE "/var/lock/xen-cd-new" + #define IDE_ATAPI_PT_EJECT_CD_FILE "/var/lock/xen-cd-eject" +-#define IDE_ATAPI_PT_EXCLUSIVE_CD_FILE "/var/lock/xen-cd-exclusive" + #define IDE_ATAPI_PT_DEBUG_FILE_TEMPLATE "/var/log/cdrom-%d.log" + + +@@ -386,6 +385,90 @@ static const struct { + { 0x000000, 0x000000, "Unrecognised sense data"} + }; + ++ ++ ++#define IDE_ATAPI_PT_EXCLUSIVE_CD_FILE "/var/lock/xen-cd-exclusive" ++ ++#define ATAPI_PT_LOCK_STATE_UNLOCKED 0 ++#define ATAPI_PT_LOCK_STATE_LOCKED_BY_ME 1 ++#define ATAPI_PT_LOCK_STATE_LOCKED_BY_OTHER 2 ++ ++static int lock_fd = -1, we_have_lock = 0; ++ ++int open_lock_file(void) ++{ ++ lock_fd = open( IDE_ATAPI_PT_EXCLUSIVE_CD_FILE, O_RDWR | O_CREAT, 0666); ++ return (lock_fd<0) ? 1:0; ++} ++ ++ ++int get_atapi_pt_lock_state(void) ++{ ++ struct flock lock = {0}; ++ ++ if (we_have_lock) ++ return ATAPI_PT_LOCK_STATE_LOCKED_BY_ME; ++ ++ if (open_lock_file()) return ATAPI_PT_LOCK_STATE_UNLOCKED; ++ ++ lock.l_type = F_WRLCK; ++ lock.l_whence = SEEK_SET; ++ lock.l_start = 0; ++ lock.l_len = 0; ++ ++ fcntl(lock_fd, F_GETLK, &lock); ++ ++ if (lock.l_type == F_UNLCK) ++ return ATAPI_PT_LOCK_STATE_UNLOCKED; ++ ++ return ATAPI_PT_LOCK_STATE_LOCKED_BY_OTHER; ++} ++ ++int get_atapi_pt_lock(void) ++{ ++ struct flock lock = {0}; ++ ++ if (open_lock_file()) return -1; ++ ++ if (we_have_lock) ++ return 0; ++ ++ lock.l_type = F_WRLCK; ++ lock.l_whence = SEEK_SET; ++ lock.l_start = 0; ++ lock.l_len = 0; ++ ++ if (fcntl(lock_fd, F_SETLK, &lock)) ++ return -1; ++ ++ we_have_lock++; ++ ++ return 0; ++} ++ ++int release_atapi_pt_lock(void) ++{ ++ struct flock lock = {0}; ++ ++ if (open_lock_file()) return -1; ++ ++ if (!we_have_lock) ++ return 0; ++ ++ lock.l_type = F_UNLCK; ++ lock.l_whence = SEEK_SET; ++ lock.l_start = 0; ++ lock.l_len = 0; ++ ++ if (fcntl(lock_fd, F_SETLK, &lock)) ++ return -1; ++ ++ we_have_lock = 0; ++ ++ return 0; ++} ++ ++ + static const char *atapi_sense_to_str(int key, int asc, int ascq) + { + int i; +@@ -1007,8 +1090,7 @@ static int ide_atapi_pt_read_cd_block_size(const uint8_t *io_buffer) + + static void ide_atapi_pt_ejected(void) + { +- /* The media has been ejected, remove exclusivity lock */ +- remove(IDE_ATAPI_PT_EXCLUSIVE_CD_FILE); ++ release_atapi_pt_lock(); + } + + +@@ -1016,7 +1098,6 @@ static void ide_atapi_pt_cmd(IDEState *s) + { + uint8_t cmd_code; + FILE *fp; +- int exclusive_domain; + + if(pthread_mutex_trylock(&s->atapi_pt.sgio_mutex)) { + DEBUG_PRINTF("ide_atapi_pt_cmd() called with existing request processing - ignored!\n"); +@@ -1069,14 +1150,9 @@ static void ide_atapi_pt_cmd(IDEState *s) + s->atapi_pt.din_xfer_len = ide_atapi_pt_get_data_size(ide_atapi_pt_size_buffer, + cmd_code, s->atapi_pt.request); + +- exclusive_domain = 0; +- fp = fopen(IDE_ATAPI_PT_EXCLUSIVE_CD_FILE, "r"); +- if(fp != NULL) { +- fscanf(fp, "%d", &exclusive_domain); +- fclose(fp); +- } + +- if(exclusive_domain != domid && exclusive_domain != 0) ++ ++ if(get_atapi_pt_lock_state() == ATAPI_PT_LOCK_STATE_LOCKED_BY_OTHER) + { + uint8_t sense[18] = {0x70, 0, 2, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0x3a, 1, 0, 0, 0, 0}; + +@@ -1118,17 +1194,14 @@ static void ide_atapi_pt_cmd(IDEState *s) + cmd_code == GPCMD_WRITE_10 || cmd_code == GPCMD_WRITE_12 || cmd_code == GPCMD_WRITE_AND_VERIFY_10 || + cmd_code == GPCMD_WRITE_BUFFER) + { +- int fd; + DEBUG_PRINTF("Claiming exclusive lock while writing\n"); +- fd = open(IDE_ATAPI_PT_EXCLUSIVE_CD_FILE, O_WRONLY | O_CREAT, 0666); +- if(fd < 3) { +- DEBUG_PRINTF("Could not open CD exclusivity lock file for writing\n"); +- } else { +- char buf[8] = "\0\0\0\0\0\0\0\0"; + +- snprintf(buf, sizeof(buf) - 1, "%d", domid); +- write(fd, buf, strlen(buf)); +- close(fd); ++ if(get_atapi_pt_lock()) { ++ DEBUG_PRINTF("Could not open CD exclusivity lock file for writing\n"); ++ memcpy(&s->atapi_pt.sense, sense, 18); ++ ide_atapi_pt_set_error(s, sense[2], sense[12], sense[13], 0x70); ++ pthread_mutex_unlock(&s->atapi_pt.sgio_mutex); ++ return; + } + } + diff --git a/master/series b/master/series index c865ac5..45dfc47 100644 --- a/master/series +++ b/master/series @@ -25,5 +25,7 @@ intel fix-imobile-mouse atapi-pass-through +do-atapi-locking-properly +atapi-succeed-on-lock-door pv_driver_throttling_disabled dont-carp-about-a-missing-battery