Есть странная проблема. Может кто объяснит с прувлинком.
Описываю в JCL PDSE c DISP=SHR без указания мембера. Вызываю фтп и оно кладет туда набор. Но, если перед этим из программы я открываю другой мембер по имени, не по DD - фтп пробиться уже не может, занято моей прогой. А теперь самое смешное. Даже после fclose() фтп всё равно считает что набор занят. (программа то висит всё время)
Вот сижу и думаю. Почему после закрытия мембера доступ не освобождается. И почему я в PDSE не могу работать параллельно с 2мя разными мемберами...
А что именно указывается в ftp put/get ? 'набор_данных(мембер)' или мембер после cd 'набор_данных' ? ftp вызывается из программы? Задание (JCL) покажите, последовательность команд ftp, и вообще, не надо байты экономить, поподробнее ситуацию опишите плиз)))
sprintf(ftp_cmd, "get %s.%d spool%d (replace", jobid, i, i); rc = FAPI_SCMD(&fcai,ftp_cmd,FAPI_MODE_WAIT); << здесь фтп работает >>
sprintf(memdsname,"'%s(%s)'", outdsname, member); fp_out=fopen(memdsname,"wb,type=record"); << сразу после этой строки нет >>
EMC SCMD >get J0491736.1 spool1 (replace|W EMC FTP unable to obtain SHARED use of A.A.A.OUTPUT(SPOOL1) which is held by: 0030 PGMTEST EXCL on SYSDSN EMC Allocation of A.A.A.OUTPUT(SPOOL1) failed (error code 0210 info code 0000 S99ERSN 00000000)
Больше всего это похоже на то, что fopen() по имени(а не по DD) лочит всю библиотеку, а не мембер. Если бы я сделал DD на мембер и открыл по DD, возможно всё бы сработало.
Workaround я сделал через USS /tmp чтобы отдельный PDSE не заводить. (до этого отверг PREFIX.* так как политики SMS разные даже на моих LPAR) Так что вопрос строго научный.
Почему после закрытия мембера доступ не освобождается.
На сколько я понимаю, то Блокировка снимается с набора данных при его de-распределении (deallocation) deallocation может быть выполнен: - при CLOSE с опцией FREE, или в - JCL параметре DD указана опция FREE со значением CLOSE - ну или выполняя соответствующий Dynamic allocation Иначе набор данных будет освобождён при job step termination
D GRS,RES=(SYSDSN,dsname) - покажет кто выдал ENQ на НД.
Как вариант, использовать последовательность (взято из примера CCNGOS4): dyninit(&ip); <Заполнение структуры ip> dynalloc(&ip); f=fopen("DD:NAMEDD","wb"); <работа с файлом> fflush(f); fclose(f); dynfree(&ip);
FREE=CLOSE интересно, может где и пригодиться. Но не здесь так фтп должен работать в параллели, а в мембер собираются все его наработки. (вы ведь знаете, что закрытый PDS мембер при повторном открытии нельзя удлинить)
Quote
You cannot open a PDS or PDSE member using the modes a, ab, a+, a+b, w+, w+b, or wb+. If you want to perform the equivalent of the w+ or wb+ mode, you must first open the file as w or wb, write to it, and then close it. Then you can perform updates by reopening the file in r+ or rb+ mode. You can use the C library functions ftell() or fgetpos() to obtain file positions for later updates to the member. Normally, opening a file in r+ or rb+ mode enables you to extend a file by writing to the end; however, with these modes you cannot extend a member. To do so, you must copy the contents of the old member plus any extensions to a new member. You can remove the old member by using the remove() function and then rename the new member to the old name by using rename().
И если закрыть хоть раз FREE=CLOSE, то придется аллокейт делать перед следующим открытием. Тогда лучше сразу с dynalloc работать.
Quote
The data set is unallocated after it is closed if the assembler CLOSE macro instruction specifies DISP, REWIND, or FREE. If the data set is reopened after the system has unallocated it, the job step abnormally terminates, unless the data set is dynamically allocated in the interval.
Пугает эта фраза
Quote
Note: Specifying FREE will not release the enqueue on the data set until the last step that requires the data set completes processing.
О fopen("dd:OUTPUT(member)"):
Quote
//MYDD DD DSN=userid.MY.DATA(A),DISP=SHR
You can specify members on calls to fopen() and freopen(). You can specify members when you are opening a data set by its data set name or by a ddname. When you use a ddname and a member name, the definition of the ddname must not also specify a member. For example, using the DD statement above, the following will fail:
You can specify members on calls to fopen() and freopen(). You can specify members when you are opening a data set by its data set name or by a ddname. When you use a ddname and a member name, the definition of the ddname must not also specify a member. For example, using the DD statement above, the following will fail:
fp = fopen("dd:MYDD(B)","r");
так а кто мешает писать: //MYDD DD DSN=userid.MY.DATA,DISP=SHR ? смысл процитированной фразы - указывать мембер можно либо в DD, либо в fopen, но нльзя и ТАМ И ТАМ...
Сообщение отредактировал Gregory - Чт, 29.09.2011, 19:23
Осталось непонятно. При предыдущем подходе набор лочился по аналогии с мембером? Напомню между JCL DD и fopen(имя) нет никакой связи как бы. То-есть теперь через DD есть явное SHR. А там как бы ничего не было. Вот система не зная что я хочу и залочила его так же как и мембер на запись. Может в этом и собака? В fopen() есть куча z/OS опций, но DISP как раз и нету.
При предыдущем подходе набор лочился по аналогии с мембером? Напомню между JCL DD и fopen(имя) нет никакой связи как бы. То-есть теперь через DD есть явное SHR. А там как бы ничего не было. Вот система не зная что я хочу и залочила его так же как и мембер на запись. Может в этом и собака?
IMHO этого следовало ожидать. Система выдает ENQ для DD в любом случае. Если в fopen указывается DD то никакое динамическое распредение в программе не нужно: - когда в DD указан PDS/PDSE и мембер, fopen выбирает BSAM; - когда в DD указан только PDS/PDSE а мембер указан в fopen выбирает BPAM;
А если в fopen указывается имя набора данных, требуется динамическое распределение, в этом случае DD вообще не нужен, а если какой-то DD есть он все равно НЕ будет использоваться.
Сама fopen ENQ выдавать в принципе не может, потому что ENQ для qname SYSDSN требуется авторизация, а программа (вместе с библитечными подпрограммами) таковой не является:
Quote
qname addr ... Some names, such as those beginning with certain letter combinations (SYSZ for example), are used to protect system resources by requiring that the issuing program be in supervisor state, or system key, or APF-authorized.
Программа выдает DYNALLOC, а вот он выдает ENQ. Как-то так... Еще раз замечу что это все IMHO.
Сообщение отредактировал Gregory - Пт, 30.09.2011, 11:20
Я скажу по другому. В любом случае имя делится на 2 части и каждая лочится отдельно. Библиотека себе, мембер себе. В работающем случае мы явно указали доступ SHR к библиотеке. Если явно не указано, то берется из мембера. Мембер на запись - библиотека OLD, мембер на чтение - библиотека SHR.
Вывод. Следующая запись тоже залочит весь набор, а не только мембер: //MYDD DD DSN=userid.MY.DATA(MEMBER1),DISP=OLD fp_out=fopen("DD:MYDD","wb,type=record");
Следующая глава почти так и показывает. (хоть и ссылается на много систем) DFSMS Using Data Sets 3.8.9.3 Multiple System Sharing of PDSEs